diff --git a/ef/Compiler/CodeGenerator/Backend.cpp b/ef/Compiler/CodeGenerator/Backend.cpp new file mode 100644 index 000000000000..9cf8ea0ae0bf --- /dev/null +++ b/ef/Compiler/CodeGenerator/Backend.cpp @@ -0,0 +1,194 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +// Backend.cpp +// +// Scott M. Silver +// +// Translate a ControlGraph into native code + + +#if defined(DEBUG) && (defined(WIN32) || defined(USE_MESA)) && defined(IGVISUALIZE) +#define USE_VISUALIZER +#endif + +#ifdef USE_VISUALIZER +#define IGVISUALIZE_ONLY(x) x +#include "IGVisualizer.h" +#else +#define IGVISUALIZE_ONLY(x) +#endif + +#include "Backend.h" +#include "ControlGraph.h" +#include "JavaVM.h" + +#define INCLUDE_EMITTER +#include "CpuInfo.h" +#include "RegisterAllocator.h" +#include "CodeGenerator.h" +#include "CGScheduler.h" +#include "NativeFormatter.h" + +#include "FieldOrMethod.h" +#include "LogModule.h" + +#if DEBUG_laurentm +#include "ControlNodeScheduler.h" +#endif + +static void +explodeImmediatePrimitives(ControlGraph &cg); + +#ifdef DEBUG_LOG +static void +printInstructions(LogModuleObject inLogObject, ControlNode& inControlNode); + +static void +printInstructions(LogModuleObject inLogObject, ControlNode& inControlNode) +{ + InstructionList& instructions = inControlNode.getInstructions(); + + for(InstructionList::iterator i = instructions.begin(); !instructions.done(i); i = instructions.advance(i)) + { + instructions.get(i).printDebug(inLogObject); + UT_OBJECTLOG(inLogObject, PR_LOG_ALWAYS, ("\n")); + } +} +#endif + +UT_DEFINE_LOG_MODULE(Backend); + +void* +translateControlGraphToNative(ControlGraph& inControlGraph, Method& inMethod) +{ + VirtualRegisterManager vrMan(inControlGraph.pool); + MdEmitter emitter(inControlGraph.pool, vrMan); + CodeGenerator codeGenerator(inControlGraph.pool, emitter); + + // break out constants + explodeImmediatePrimitives(inControlGraph); + + // * generate code + DoublyLinkedList::iterator j; + for (j = inControlGraph.controlNodes.begin(); !inControlGraph.controlNodes.done(j); j = inControlGraph.controlNodes.advance(j)) + { + ControlNode &cn = inControlGraph.controlNodes.get(j); + + codeGenerator.generate(cn); + +#ifdef PRINT_INSTRUCTIONS_BEFORE_REGALLOC + cn.printRef(UT_LOG_MODULE(Backend)); + + UT_SET_LOG_LEVEL(Backend, PR_LOG_DEBUG); + printInstructions(UT_LOG_MODULE(Backend), cn); +#endif + } + + // If the debugger is enabled, generate pc2bci table + if (VM::debugger.getEnabled()) { + // Use an arbitrary number - needs to be set appropriately later + inMethod.getPC2Bci().setSize(1000); + } + + // * register allocation + if (!inControlGraph.dfsListIsValid()) + inControlGraph.dfsSearch(); + if (!inControlGraph.lndListIsValid()) + inControlGraph.lndSearch(); + + RegisterAllocator registerAllocator(inControlGraph.pool, inControlGraph.dfsList, inControlGraph.lndList, inControlGraph.nNodes, vrMan, emitter); + registerAllocator.allocateRegisters(); + +#ifdef PRINT_INSTRUCTIONS_AFTER_REGALLOC + for (j = inControlGraph.controlNodes.begin(); !inControlGraph.controlNodes.done(j); j = inControlGraph.controlNodes.advance(j)) + { + ControlNode &cn = inControlGraph.controlNodes.get(j); + + printInstructions(UT_LOG_MODULE(Backend), cn); + } +#endif + + +#ifdef NEW_CG_SCHEDULER + ControlNodeScheduler cns(inControlGraph.pool, inControlGraph.dfsList, inControlGraph.nNodes); + ControlNode** scheduledNodes = cns.getScheduledNodes(); +#else // NEW_CG_SCHEDULER + ControlGraphScheduler cgs(inControlGraph, emitter); + ControlNode** scheduledNodes = cgs.scheduleNodes(); +#endif // NEW_CG_SCHEDULER + + // * output to memory + NativeFormatter formatter(emitter, scheduledNodes, inControlGraph.nNodes); + + void* func = formatter.format(inMethod); + + IGVISUALIZE_ONLY(codeGenerator.visualize();) + return (func); +} + + +// +// Transform all immediate operations into +// operations which no longer intern a constant +// +// For example: +// +// vi2 = AddI_I 6, vi1 +// +// becomes +// +// vi1 = Const_I 6 +// vi3 = Add_I vi1, vi2 +// +static void +explodeImmediatePrimitives(ControlGraph &cg) +{ + cg.dfsSearch(); + ControlNode **dfsList = cg.dfsList; + ControlNode **pcn = dfsList + cg.nNodes; + + while (pcn != dfsList) + { + ControlNode &cn = **--pcn; + + // Search the primitives backwards; explode primitives as necessary + DoublyLinkedList &primitives = cn.getPrimitives(); + DoublyLinkedList::iterator primIter = primitives.end(); + while (!primitives.done(primIter)) + { + Primitive &p = primitives.get(primIter); + primIter = primitives.retreat(primIter); + + // loop through all consumers of p; if a consumer is constant create + // a new PrimConst node, and attach it to p + DataConsumer* input; + for (input = p.getInputsBegin(); input < p.getInputsEnd(); input++) + { + if (input->isConstant() && isRegOrMemKind(input->getKind())) + { + PrimConst *prim = new(cn.getPrimitivePool()) + PrimConst(input->getKind(), input->getConstant(), + p.getBytecodeIndex()); + + input->setVariable(*prim); + cn.appendPrimitive(*prim); + } + } + } + } +} diff --git a/ef/Compiler/CodeGenerator/Backend.h b/ef/Compiler/CodeGenerator/Backend.h new file mode 100644 index 000000000000..8b2b0c05af24 --- /dev/null +++ b/ef/Compiler/CodeGenerator/Backend.h @@ -0,0 +1,32 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +// Backend.h +// +// Scott M. Silver +// +// Translate a ControlGraph into native code + +#ifndef _H_BACKEND +#define _H_BACKEND + +struct Method; +class ControlGraph; + +void* translateControlGraphToNative(ControlGraph& inControlGraph, Method& inMethod); + +#endif diff --git a/ef/Compiler/CodeGenerator/Burg.h b/ef/Compiler/CodeGenerator/Burg.h new file mode 100644 index 000000000000..bc93bf3d4620 --- /dev/null +++ b/ef/Compiler/CodeGenerator/Burg.h @@ -0,0 +1,56 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +/* + Burg.h +*/ + +// Burg needs these +#include +#include + +// Stuff that we use for burg +#include "CodeGenerator.h" +#include "Primitives.h" + +typedef Primitive* NODEPTR_TYPE; + +#define OP_LABEL(p) p->getOperation() +#define STATE_LABEL(p) p->getBurgState() +#define SET_STATE_LABEL(p, state) p->setBurgState(state) +#define LEFT_CHILD(p) CodeGenerator::getExpressionLeftChild(p) +#define RIGHT_CHILD(p) CodeGenerator::getExpressionRightChild(p) +#define PANIC printf + +extern short *burm_nts[]; +extern char *burm_string[]; +extern char * burm_opname[]; +extern char burm_arity[]; +extern short burm_cost[][4]; +extern char *burm_ntname[]; + +// burgs exported functions + +int burm_rule(int state, int goalnt); +int burm_state(int op, int l, int r); + +int burm_label(NODEPTR_TYPE n); +NODEPTR_TYPE * burm_kids(NODEPTR_TYPE p, int rulenumber, NODEPTR_TYPE *kids); +NODEPTR_TYPE burm_child(NODEPTR_TYPE p, int index); +int burm_op_label(NODEPTR_TYPE p); +int burm_state_label(NODEPTR_TYPE p); + diff --git a/ef/Compiler/CodeGenerator/CGScheduler.cpp b/ef/Compiler/CodeGenerator/CGScheduler.cpp new file mode 100644 index 000000000000..d0b3692b0fed --- /dev/null +++ b/ef/Compiler/CodeGenerator/CGScheduler.cpp @@ -0,0 +1,222 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#include "Fundamentals.h" +#include "CGScheduler.h" +#include "ControlGraph.h" +#include "InstructionEmitter.h" +#include "GraphUtils.h" + + +inline static bool +isPredecessor(ControlNode& pred, ControlNode& node) +{ + ControlEdge* limit = pred.getSuccessorsEnd(); + + for (ControlEdge* ptr = pred.getSuccessorsBegin(); ptr < limit; ptr++) + if (&ptr->getTarget() == &node) + return true; + return false; +} + +ControlNode** ControlGraphScheduler:: +scheduleNodes() +{ + ControlNode** orderedNodes = orderNodes(); + addAbsoluteBranches(orderedNodes); + + return orderedNodes; +} + +// addAbsoluteBranches +// Given an ordering of ControlNodes in the graph add necessary +// implicit branches demanded by the ordering (ie to satisfy the ControlEdges) +void ControlGraphScheduler:: +addAbsoluteBranches(ControlNode** orderedNodes) +{ + Uint32 nNodes = cg.nNodes; + + // for each ControlNode in orderedNodes, determine for each sequential pairing + // if a falls through to b then don't add an absolute branch from a->b, otherwise + // if the edge a->b does not exist, then add an absolute branch to where a should + // connect. + for (Uint32 n = 0; n < nNodes; n++) + { + ControlNode* thisNode = orderedNodes[n]; + ControlNode* nextNode = (n < (nNodes - 1)) ? orderedNodes[n+1] : (ControlNode *) 0; + ControlEdge* branchEdge; + + switch(thisNode->getControlKind()) + { + case ckIf: + case ckBlock: + case ckExc: + case ckAExc: + case ckCatch: + case ckBegin: + branchEdge = &thisNode->nthSuccessor(0); + break; + + // these three ControlNodes never have any implicit branches + case ckSwitch: + case ckReturn: + case ckEnd: + case ckThrow: + branchEdge = NULL; + break; + + default: + assert(false); + } + + if (branchEdge != NULL && nextNode != NULL && &branchEdge->getTarget() != nextNode) + emitter.pushAbsoluteBranch(branchEdge->getSource(), branchEdge->getTarget()); + } +} + +ControlNode** ControlGraphScheduler:: +orderNodes() +{ + Uint32 nNodes = cg.nNodes - 1; + Uint32 myGeneration = ControlNode::getNextGeneration(); + ControlNode** nodes = new ControlNode*[nNodes]; + ControlNode** n_ptr = nodes; + + SearchStackEntry *ceStack = new SearchStackEntry[nNodes]; + SearchStackEntry *ceSp = ceStack; + + ControlEdge beginEdge; + beginEdge.setTarget(cg.getBeginNode()); + cg.getEndNode().generation = myGeneration; + + ControlEdge* n = &beginEdge; + ControlEdge* l = &beginEdge + 1; + + while(true) + { + if (n == l) + { + if (ceSp == ceStack) + break; + --ceSp; + n = ceSp->next; + l = ceSp->limit; + } + else + { + ControlNode& node = n++->getTarget(); + if (node.generation != myGeneration) + { + node.generation = myGeneration; + node.schedulePos = Uint32(n_ptr - nodes); + *n_ptr++ = &node; + ceSp->next = n; + ceSp->limit = l; + ceSp++; + n = node.getSuccessorsBegin(); + l = node.getSuccessorsEnd(); + } + } + } +#ifndef WIN32 // ***** Visual C++ has a bug in the code for delete[]. + delete ceStack; +#endif + + Uint32* cnStack = new Uint32[nNodes]; + Uint32* cnSp = cnStack; + + ControlNode** orderedNodes = new(cg.pool) ControlNode*[nNodes + 1]; + n_ptr = orderedNodes; + Uint32 next; + +#if DEBUG + fill_n(orderedNodes, nNodes, (ControlNode *) 0); +#endif + + myGeneration = ControlNode::getNextGeneration(); + orderedNodes[nNodes] = &cg.getEndNode(); + orderedNodes[nNodes]->generation = myGeneration; + *n_ptr++ = nodes[0]; + *cnSp++ = 0; + next = 1; + + while (true) + { + if (next == 0) + { + if (cnSp == cnStack) + break; + next = *--cnSp; + } + else + { + ControlNode& node = *nodes[next]; + + if (node.generation == myGeneration) + { + next = 0; + } + else + { + // if (node.hasControlKind(ckIf)) + const DoublyLinkedList& edges = node.getPredecessors(); + if (!edges.done(edges.advance(edges.begin()))) // more than one predecessor + { + for (DoublyLinkedList::iterator i = edges.begin(); !edges.done(i); i = edges.advance(i)) + { + ControlNode& source = edges.get(i).getSource(); + if ((source.dfsNum > node.dfsNum) && (source.generation != myGeneration)) + { + *cnSp++ = next; + next = source.schedulePos; + while (isPredecessor(*nodes[next - 1], *nodes[next]) && + (nodes[next - 1]->generation != myGeneration) && (next != node.schedulePos)) + next--; + break; + } + } + if (next == node.schedulePos) + { + node.generation = myGeneration; + *n_ptr++ = &node; + if (++next >= nNodes) + next = 0; + } + } + else + { + node.generation = myGeneration; + *n_ptr++ = &node; + if (++next >= nNodes) + next = 0; + } + } + + } + } + //delete cnStack; + //delete [] nodes; + +#if DEBUG + for (Uint32 i = 0; i < nNodes + 1; i++) + assert(orderedNodes[i]); +#endif + + return orderedNodes; +} + diff --git a/ef/Compiler/CodeGenerator/CGScheduler.h b/ef/Compiler/CodeGenerator/CGScheduler.h new file mode 100644 index 000000000000..bf219218e1f4 --- /dev/null +++ b/ef/Compiler/CodeGenerator/CGScheduler.h @@ -0,0 +1,44 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#ifndef _CG_SCHEDULER_H_ +#define _CG_SCHEDULER_H_ + +#include "Fundamentals.h" +#include "Pool.h" + +class ControlGraph; +class ControlNode; +class InstructionEmitter; + +class ControlGraphScheduler +{ +protected: + ControlGraph& cg; + InstructionEmitter& emitter; + + ControlNode** orderNodes(); + void addAbsoluteBranches(ControlNode** orderedNodes); + +public: + ControlGraphScheduler(ControlGraph& mCg, InstructionEmitter& mEmitter) : cg(mCg), emitter(mEmitter) {} + + ControlNode** scheduleNodes(); +}; + +#endif /* _CG_SCHEDULER_H_ */ diff --git a/ef/Compiler/CodeGenerator/CodeGenerator.cpp b/ef/Compiler/CodeGenerator/CodeGenerator.cpp new file mode 100644 index 000000000000..c027fd396dba --- /dev/null +++ b/ef/Compiler/CodeGenerator/CodeGenerator.cpp @@ -0,0 +1,458 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +// CodeGenerator.cpp +// +// Scott M. Silver +// Peter Desantis +// +// A code generator is a loose organization of code which +// finds roots in a given control node of BURG-labellable expression +// trees. The trees are labelled, and an emit routine is called +// for each labelled tree. + +#define INCLUDE_EMITTER +#include "CpuInfo.h" + +#include "Vector.h" +#include "Primitives.h" +#include "CodeGenerator.h" +#include "Burg.h" +#include "Scheduler.h" +#include "ControlNodes.h" +#include "InstructionEmitter.h" + +#ifdef USE_VISUALIZER +#include "IGVisualizer.h" +#endif + + +// sFakeRegPrimitives +// +// A table of primitives which are used as the children +// of primitives which are defined to be leaves in a +// control node. They are indexed by DataKind, ie +// vkInt, etc... +//Primitive sFakeReg_V(coReg_V); // no such register +Primitive sFakeReg_I(coReg_I, 0); +Primitive sFakeReg_L(coReg_L, 0); +Primitive sFakeReg_F(coReg_F, 0); +Primitive sFakeReg_D(coReg_D, 0); +Primitive sFakeReg_P(coReg_A, 0); +Primitive sFakeReg_C(coReg_C, 0); +Primitive sFakeReg_M(coReg_M, 0); // no such register +//Primitive sFakeReg_T(coReg_T); // no such register + +Primitive* sFakeRegPrimitives[nValueKinds] = +{ + NULL, // no such register + &sFakeReg_I, + &sFakeReg_L, + &sFakeReg_F, + &sFakeReg_D, + &sFakeReg_P, + &sFakeReg_C, + &sFakeReg_M, + NULL // no such register +}; + + +// This needs to be here because of header include problems. +CodeGenerator::CodeGenerator(Pool& inPool, MdEmitter& inEmitter) : + mPool(inPool), + mEmitter(inEmitter) +#ifdef USE_VISUALIZER + ,mVisualizer(*(new IGVisualizer())) +#endif +{ +} + + +// generate +// +// Emit argumetns for the begin node. +// Find all roots of trees in inControlNode +// Label each root +// Call the emitter to emit for each root +void CodeGenerator:: +generate(ControlNode& inControlNode) +{ + Vector roots; + + // First find all the roots in this control node + findRoots(inControlNode, roots); + + if (inControlNode.hasControlKind(ckBegin)) + mEmitter.emitArguments(inControlNode.getBeginExtra()); + else + { + // for each root label, and emit code + RootPair* curRoot; + + for (curRoot = roots.begin(); curRoot < roots.end(); curRoot++) + { + label(*(curRoot->root)); + emit(curRoot->root, 1); + } + } + + // schedule and output instructions + LinearInstructionScheduler scheduler; + scheduler.schedule(roots, inControlNode); + +#ifdef IGVISUALIZE + mVisualizer.addRoots(roots); +#endif +} + + +#ifdef IGVISUALIZE +void CodeGenerator:: +visualize() +{ + mVisualizer.visualize(); +} +#endif + + +// label +// +// Label the treee rooted at inPrimitive +void CodeGenerator:: +label(Primitive& inPrimitive) +{ + + burm_label(&inPrimitive); +} + + +// emit +// +// Actually traverse the primitives and emit instructions +// once labelled. +void CodeGenerator:: +emit(Primitive* p, int goalnt) +{ + int eruleno = burm_rule(p->getBurgState(), goalnt); + short* nts = burm_nts[eruleno]; + Primitive* kids[10]; + int i; + + if (eruleno == 0) + { + trespass("BURG matching -- no cover"); + } + + burm_kids(p, eruleno, kids); + + for (i = 0; nts[i]; i++) + emit(kids[i], nts[i]); + + mEmitter.emitPrimitive(*p, eruleno); +} + + + +// instructionUseToInstruction +// +// Move to the definer of this use. +// +// There are three cases. +// +// 1. If there is a defining Instruction +// in the Use, then that is the defining Instruction. +// +// 2. If the Use is Store or Cond Use, then if there is a +// defining Instruction then it will be attached to the +// DP at ID 0. +// +// 3. If the Use is a Register Use, then there must be some +// VR associated with the Use. The Instruction which defines +// the VR is the defining Instruction for this Use. +// +// It is possible that the result of 2 or 3 could be NULL after +// emitting for a given ControlNode. This means that the resource +// (outgoing edge) has not been defined, and is in another ControlNode. +// (or there was a programmer error, how do we detect which one) +Instruction* CodeGenerator:: +instructionUseToInstruction(InstructionUse& inIUse) +{ + Instruction* nextInsn; + + if (inIUse.src != NULL) + nextInsn = inIUse.src; + else + { + switch (inIUse.kind) + { + case udStore: case udCond: + if (inIUse.name.dp != NULL) + { + if (inIUse.name.dp->getInstructionAnnotation() != NULL) + nextInsn = inIUse.name.dp->getInstructionAnnotation(); + else + nextInsn = NULL; + } + else + nextInsn = NULL; + break; + case udRegister: + //assert(inIUse.name.vr); can't check this because it's a VR Pointer + nextInsn = inIUse.name.vr.getVirtualRegister().getDefiningInstruction(); + break; + case udNone: + nextInsn = NULL; + break; + case udOrder: + nextInsn = inIUse.name.instruction; + break; + case udUninitialized: + assert(false); + default: + assert(false); + } + } + + return (nextInsn); +} + + + +// getExpressionLeftChild +// +// The BURG implementation of LEFT_CHILD +Primitive* CodeGenerator:: +getExpressionLeftChild(Primitive* inPrimitive) +{ + assert(inPrimitive); + + bool hasIncomingStore = inPrimitive->hasCategory(pcLd) || inPrimitive->hasCategory(pcSt) || inPrimitive->hasCategory(pcCall); + + DataConsumer* leftConsumer = &inPrimitive->nthInput(hasIncomingStore); + + return (consumerToPrimitive(inPrimitive, leftConsumer)); +} + + +// getExpressionRightChild +// +// Grab the right child of inPrimitive, skip over store edges +// [The BURG implementation of RIGHT_CHILD] +Primitive* CodeGenerator:: +getExpressionRightChild(Primitive* inPrimitive) +{ + assert(inPrimitive); + + DataConsumer* rightConsumer; + + bool hasIncomingStore = inPrimitive->hasCategory(pcLd) || inPrimitive->hasCategory(pcSt) || inPrimitive->hasCategory(pcCall); + + rightConsumer = &inPrimitive->nthInput(1 + hasIncomingStore); + + return (consumerToPrimitive(inPrimitive, rightConsumer)); +} + + +// consumerToPrimitive +// +// Takes a consumer of a value and finds the primitive which produces +// the value that is consumed. +// +// an example: +// +// isLeaf +// +// child parent +// P2 pr <-> co P1 +// +// co: inConsumer +// P1: inPrimitive +// +// co is a leaf edge if +// +// 1. co and pr (or P1 and P2) are in different control nodes -> return fake reg primitive +// 2. P2 is a root -> return fake reg primitive +// +// else +// +// return P2 +Primitive* CodeGenerator:: +consumerToPrimitive(Primitive* inPrimitive, DataConsumer* inConsumer) +{ + // if it's already a fake reg primitive it has no children + if (inPrimitive->getOperation() >= coReg_V && inPrimitive->getOperation() <= coReg_I) + return NULL; + else if (inConsumer->isConstant()) + return (sFakeRegPrimitives[inConsumer->getKind()]); + + DataNode& consumerChildNode = inConsumer->getVariable(); + Primitive* consumerChildPrimitive; + + // extract P2 as above + if (!consumerChildNode.hasCategory(pcPhi)) + consumerChildPrimitive = &Primitive::cast(consumerChildNode); + else + return (sFakeRegPrimitives[inConsumer->getKind()]); // phi node + + // now perform the check to see if this edge connects to a "leaf" edge + if (consumerChildPrimitive->getContainer() != inPrimitive->getContainer() || + isRoot(*consumerChildPrimitive)) + { + return (sFakeRegPrimitives[inConsumer->getKind()]); + } + else + return (consumerChildPrimitive); +} + + +// search through all primitives in a control node +// return a vector of all the roots of expression trees +void CodeGenerator:: +findRoots(ControlNode& inControlNode, Vector& outRoots) +{ + DoublyLinkedList& primitives = inControlNode.getPrimitives(); + + for (DoublyLinkedList::iterator i = primitives.begin(); !primitives.done(i); i = primitives.advance(i)) + { + Primitive& prim = primitives.get(i); + + RootKind root = isRoot(prim); + + if ((root == rkRoot) || (root == rkPrimary)) + { + RootPair newRoot; + newRoot.root = &prim; + //prim.setRoot(true); + if(root == rkPrimary) + newRoot.isPrimary = true; + else + newRoot.isPrimary = false; + outRoots.append(newRoot); + } + + // root member of prim defaults to false + } +} + + +// 1. is a primitive which is a pcIfCond (if or switch) OR +// 2. is a primitive which is a pcResult OR +// 3. is a primitive all of whose outputs are in a different control node from its own OR +// 4. is an interior primitive whose inputs are shared by two primitives in the same (cse) +// 5. is a primitive connected to another pcCall/pcSysCall primitive +// In cases 1 2 3 the root is primary +RootKind CodeGenerator:: +isRoot(Primitive& inPrimitive) +{ + bool isAtleastRoot = false; + // 1 or 2 + if (inPrimitive.hasCategory(pcIfCond) || inPrimitive.hasCategory(pcResult) || + inPrimitive.hasCategory(pcSwitch)) + goto isRoot_rkPrimary; + + // 3 + DataNode* curEdge; + + isAtleastRoot = inPrimitive.hasCategory(pcSt) || inPrimitive.hasCategory(pcCall) || inPrimitive.hasCategory(pcSysCall); + + // all dp's primitive's containers hooked to curEdge must not be in same control node as inPrimitive's container + for (curEdge = inPrimitive.getOutgoingEdgesBegin(); curEdge < inPrimitive.getOutgoingEdgesEnd(); curEdge++) + { + const DoublyLinkedList& consumers = curEdge->getConsumers(); + + for ( DoublyLinkedList::iterator curConsumer = consumers.begin(); + !consumers.done(curConsumer); + curConsumer = consumers.advance(curConsumer)) + { + ControlNode* curConsumerContainer; // container of parentNode + DataNode* node; // parentNode (node which consume's inPrimitive's input) + + node = &consumers.get(curConsumer).getNode(); + + // can ignore LdV because it has another incoming edge + isAtleastRoot |= ((node->getOutgoingEdgesEnd() - node->getOutgoingEdgesBegin() > 1) || + (node->hasCategory(pcCall) || node->hasCategory(pcSysCall))); + + if (node->hasCategory(pcCall)) + { + DataNode* calleeAddress = &node->nthInput(1).getVariable(); + if (&inPrimitive == calleeAddress) + { + isAtleastRoot = false; + goto isRoot_rkNotRoot; + } + } + + curConsumerContainer = node->getContainer(); + + if (!node->hasCategory(pcPhi) && curConsumerContainer == inPrimitive.getContainer()) + { + // If there are any consumers in the current container, then the primitive is a root + // iff it produces a cse----look for another consumer in the primitive's container + + // Continue looking through the curEdge + curConsumer = consumers.advance(curConsumer); + for ( ; + !consumers.done(curConsumer); + curConsumer = consumers.advance(curConsumer)) + { + node = &consumers.get(curConsumer).getNode(); + + if (node->hasCategory(pcCall) || node->hasCategory(pcSysCall)) + goto isRoot_rkRoot; + + curConsumerContainer = node->getContainer(); + + if (curConsumerContainer == inPrimitive.getContainer()) // cse found. + goto isRoot_rkRoot; + } + curEdge++; + // Now continue looking through the other edges + for (;curEdge < inPrimitive.getOutgoingEdgesEnd(); curEdge++) + { + const DoublyLinkedList& consumers = curEdge->getConsumers(); + + for ( DoublyLinkedList::iterator thisConsumer = consumers.begin(); + !consumers.done(thisConsumer); + thisConsumer = consumers.advance(thisConsumer)) + { + node = &consumers.get(thisConsumer).getNode(); + if (node->hasCategory(pcCall) || node->hasCategory(pcSysCall)) + goto isRoot_rkRoot; + + curConsumerContainer = node->getContainer(); + + if (curConsumerContainer == inPrimitive.getContainer()) // cse found + goto isRoot_rkRoot; + } + } + // We did not find a cse => not a root + goto isRoot_rkNotRoot; + } + } + } + +// if we passed through the above loop, 3. must have been met (fall through to rkPrimary) +isRoot_rkPrimary: + return (rkPrimary); +isRoot_rkRoot: + return (rkRoot); +isRoot_rkNotRoot: + return (isAtleastRoot ? rkRoot : rkNotRoot); +} + + diff --git a/ef/Compiler/CodeGenerator/CodeGenerator.h b/ef/Compiler/CodeGenerator/CodeGenerator.h new file mode 100644 index 000000000000..228cebf2aba3 --- /dev/null +++ b/ef/Compiler/CodeGenerator/CodeGenerator.h @@ -0,0 +1,104 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +// CodeGenerator.h +// +// Scott M. Silver +// + +#ifndef CODEGENERATOR_H +#define CODEGENERATOR_H + +#include "Vector.h" +#include "CpuInfo.h" + +class Primitive; +class ControlNode; +class Pool; +class DataConsumer; +class Instruction; +struct InstructionUse; +#ifdef IGVISUALIZE +class IGVisualizer; +#endif + +struct RenumberData +{ + int neededVisits; + int timesVisited; + bool renumbered; +}; + +// RootPair +struct RootPair +{ + Primitive* root; // root of a BURG labellable subtree + bool isPrimary; // if this root is not reachable by any other root in + // this ControlNode + RenumberData data; +}; + +enum RootKind +{ + rkNotRoot, + rkRoot, + rkPrimary +}; + +class CodeGenerator +{ +protected: + Pool& mPool; + MdEmitter& mEmitter; + +protected: + void label(Primitive& inPrimitive); + void emit(Primitive* p, int goalnt); + + // roots, leaves + void findRoots(ControlNode& inControlNode, Vector& outRoots); + static RootKind isRoot(Primitive& inPrimitive); + +public: + CodeGenerator(Pool& inPool, MdEmitter& inEmitter); + void generate(ControlNode& inControlNode); + + // for BURG labeler + static Primitive* consumerToPrimitive(Primitive* inPrimitive, DataConsumer* inConsumer); + static Primitive* getExpressionLeftChild(Primitive* inPrimitive); + static Primitive* getExpressionRightChild(Primitive* inPrimitive); + + static Instruction* instructionUseToInstruction(InstructionUse& inIUse); + + // visualization +#ifdef IGVISUALIZE +public: + void visualize(); +protected: + IGVisualizer& mVisualizer; +#endif +}; + +#endif // CODEGENERATOR_H + + + + + + + + diff --git a/ef/Compiler/CodeGenerator/ControlNodeScheduler.cpp b/ef/Compiler/CodeGenerator/ControlNodeScheduler.cpp new file mode 100644 index 000000000000..bc5b253711c1 --- /dev/null +++ b/ef/Compiler/CodeGenerator/ControlNodeScheduler.cpp @@ -0,0 +1,748 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#include "Fundamentals.h" +#include "Pool.h" +#include "ControlNodes.h" +#include "ControlNodeScheduler.h" +#include "FastBitSet.h" + +// ---------------------------------------------------------------------------- +// LoopHierarchySet + +// +// Create a new set of LoopHierachyNodes. Allocate the LoopHierarchyNode array of +// length nLoops and the indexes array of length nNodes in the given pool. +// +LoopHierarchySet::LoopHierarchySet(Pool& pool, LoopHierarchyNode* nodesArray, Uint32 nNodes) : nodes(nodesArray) +{ + indexes = new(pool) Int32[nNodes]; + nextFree = 0; + + fill(indexes, &indexes[nNodes], -1); +} + +// +// Return the set's element corresponding to the ControlNode dfsNum equals nodeIndex. +// +LoopHierarchyNode& LoopHierarchySet::operator [] (const Uint32 nodeIndex) +{ + Int32 index = indexes[nodeIndex]; + + // If index is -1 then this node is not part of the set yet. + if (index == -1) { + index = nextFree++; + indexes[nodeIndex] = index; + } + + return nodes[index]; +} + +// ---------------------------------------------------------------------------- +// ControlNodeScheduler + +// +// Return true if node is ready. We will call a node N ready if each of its +// incoming edges E: A->N are long. +// +inline bool nodeIsReady(ControlNode& node) +{ + const DoublyLinkedList& predecessors = node.getPredecessors(); + for (DoublyLinkedList::iterator i = predecessors.begin(); !predecessors.done(i); i = predecessors.advance(i)) + if (!predecessors.get(i).longFlag) + return false; + return true; +} + +// +// Return true if node is ready with respect to 'respect'. We will call a node N +// ready with respect to node P if, for each of N's incoming edges E: A->N, either +// E is long or A equals P. +// +inline bool nodeIsReadyWithRespectTo(ControlNode& node, ControlNode& respect) +{ + const DoublyLinkedList& predecessors = node.getPredecessors(); + for (DoublyLinkedList::iterator i = predecessors.begin(); !predecessors.done(i); i = predecessors.advance(i)) { + ControlEdge& edge = predecessors.get(i); + if (!edge.longFlag && (&edge.getSource() != &respect)) + return false; + } + return true; +} + +// +// Schedule the working nodes in loopToSchedule. +// +void ControlNodeScheduler::scheduleLoop(LoopHierarchyNode& loopToSchedule) +{ +#if defined(DEBUG_SCHEDULER) + fprintf(stdout, "ControlNodeScheduler: Will schedule loop headed by N%d\n", loopToSchedule.header); +#endif + + // + // Determine the nodes in a region. + // + + FastBitSet& REG = loopToSchedule.nodes; // REG is the region of nodes contained in this loop. + FastBitSet Rlocal(nNodes); // Rlocal is the set of nodes in REG that are not contained in any subloop of REG. + FastBitSet Rsubheaders(nNodes); // Rsubheaders is the set of headers of immediate subloops of REG. + FastBitSet Rcombined(nNodes); // Rcombined is the union of Rlocal and Rsubheaders. + FastBitSet R(nNodes); // R is the intersection of Rcombined and the set of all working nodes. + FastBitSet RR(nNodes); // RR is the intersection of REG and the set of all working nodes. + + Rlocal = REG; + DoublyLinkedList& subLoops = loopToSchedule.getSuccessors(); + for (DoublyLinkedList::iterator i = subLoops.begin(); !subLoops.done(i); i = subLoops.advance(i)) { + LoopHierarchyNode& subLoop = subLoops.get(i); + Rsubheaders.set(subLoop.header); + Rlocal -= subLoop.nodes; + } + + Rcombined = Rlocal; + Rcombined |= Rsubheaders; + + R = Rcombined; + RR = REG; + + FastBitSet nonWorkingNodes(nNodes); + for (Int32 j = REG.firstOne(); j != -1; j = REG.nextOne(j)) + if (!dfsList[j]->workingNode) + nonWorkingNodes.set(j); + + R -= nonWorkingNodes; + RR -= nonWorkingNodes; + + // + // Initialize long edge flag for each edge E: A->B for which at least one of A or B is in R + // + + Uint32 generation = ControlNode::getNextGeneration(); + + for (Int32 j = R.firstOne(); j != -1; j = R.nextOne(j)) { + ControlNode& node = *dfsList[j]; + + ControlEdge* limit = node.getSuccessorsEnd(); + for (ControlEdge* edge = node.getSuccessorsBegin(); edge != limit; edge++) + if (edge->getTarget().generation != generation) + initializeLongEdgeFlag(*edge, loopToSchedule, RR, Rlocal); + + const DoublyLinkedList& predecessors = node.getPredecessors(); + for (DoublyLinkedList::iterator p = predecessors.begin(); !predecessors.done(p); p = predecessors.advance(p)) { + ControlEdge& edge = predecessors.get(p); + if (edge.getSource().generation != generation) + initializeLongEdgeFlag(edge, loopToSchedule, RR, Rlocal); + } + + node.generation = generation; + } + + // + // Linear scheduling. + // + + FastBitSet W(nNodes); // W is the set of nodes in the region remaining to be scheduled. + W = R; // Initially W contains all nodes in R except the loop header. + W.clear(loopToSchedule.header); // + + Clique** cliqueStack = new(pool) Clique*[nNodes]; // Stack of Cliques waiting to be scheduled. + Clique** cliqueStackPointer = cliqueStack; // Stack pointer. + + Int32 P = loopToSchedule.header; // P is the last node scheduled. It is initially the loop header. + Int32 N; // Next node to schedule. + + Clique* currentClique = new(pool) Clique(); + currentClique->addLast(scheduledNodes[P]); // The loop header is always the first node of the first clique. + nodesAlreadyScheduled.set(P); + + loopToSchedule.cliques.addLast(*currentClique); + + while (!W.empty() || (cliqueStackPointer != cliqueStack)) { + // Alternative 1. + // If there exists a node N in W such that there exists at least one short edge from P to N + // and node N is ready with respect to P, then we pick any such node N to be the next node. + ControlNode& nodeP = *dfsList[P]; + + ControlEdge* limit = nodeP.getSuccessorsEnd(); + for (ControlEdge* edge = nodeP.getSuccessorsBegin(); edge != limit; edge++) { + ControlNode& target = edge->getTarget(); + if (!edge->longFlag && nodeIsReadyWithRespectTo(target, nodeP) && W.test(target.dfsNum)) { + N = target.dfsNum; + goto foundNextNode; + } + } + + // Alternative 2. + // Otherwise, if the stack isn't empty, we pop a clique Ck from the stack, make it become the next clique of + // this region, make every edge from P to any node A remaining in W into a long edge, set P to be the + // last node of Ck, and continue with alternative 1 above. + if (cliqueStackPointer != cliqueStack) { + Clique* nextClique = *--cliqueStackPointer; + loopToSchedule.cliques.addLast(*nextClique); + + for (ControlEdge* edge = nodeP.getSuccessorsBegin(); edge != limit; edge++) + if (W.test(edge->getTarget().dfsNum)) + edge->longFlag = true; + + P = nextClique->last().dfsNum; + currentClique = nextClique; + continue; + } + + // Alternative 3. + // Otherwise, there must exist a node N in W such that node N is ready with respect to P. + // We pick any such node N to be the next node. + for (N = W.firstOne(); N != -1; N = W.nextOne(N)) + if (nodeIsReadyWithRespectTo(*dfsList[N], *dfsList[P])) + goto foundNextNode; + + PR_ASSERT(false); // Shouldn't happen. + + foundNextNode: + + + // After we have picked node N, we remove N from the set W and make every edge + // from P to any node A remaining in W into a long edge. + W.clear(N); + + for (ControlEdge* e = nodeP.getSuccessorsBegin(); e != limit; e++) + if (W.test(e->getTarget().dfsNum)) + e->longFlag = true; + + // If N is not the header of a subloop. + if (!Rsubheaders.test(N)) { + ControlNode& nodeN = *dfsList[N]; + bool nodePhasEdgeToNodeN = false; + + for (ControlEdge* edge = nodeP.getSuccessorsBegin(); edge != limit; edge++) { + if (&edge->getTarget() == &nodeN) { + // If there exists some edge from P to N then we append node N to the current + // clique in our region's schedule + nodePhasEdgeToNodeN = true; + currentClique->addLast(scheduledNodes[N]); + nodesAlreadyScheduled.set(N); + break; + } + } + + if (!nodePhasEdgeToNodeN) { + // There is node edge from P to N. We start a new clique in this region + // and make N this clique's first node. + Clique* newClique = new(pool) Clique(); + + newClique->addLast(scheduledNodes[N]); + loopToSchedule.cliques.addLast(*newClique); + nodesAlreadyScheduled.set(N); + currentClique = newClique; + } + + P = N; + } else { // N is the header of a subloop. + LoopHierarchyNode* subLoop = NULL; + + // Find the clique of the subloop that contains node N. + DoublyLinkedList& subLoops = loopToSchedule.getSuccessors(); + for (DoublyLinkedList::iterator i = subLoops.begin(); !subLoops.done(i); i = subLoops.advance(i)) { + subLoop = &subLoops.get(i); + if (subLoop->header == N) + break; + } + PR_ASSERT(subLoop); + + Clique* subLoopClique = NULL; + for (DoublyLinkedList::iterator c = subLoop->cliques.begin(); !subLoop->cliques.done(c); c = subLoop->cliques.advance(c)) { + bool foundClique = false; + subLoopClique = &subLoop->cliques.get(c); + + for (DoublyLinkedList::iterator n = subLoopClique->begin(); !subLoopClique->done(n); n = subLoopClique->advance(n)) + if (subLoopClique->get(n).dfsNum == N) { + foundClique = true; + break; + } + + if (foundClique) + break; + } + PR_ASSERT(subLoopClique); + + ControlNode& nodeN = *dfsList[N]; + bool nodePhasEdgeToNodeN = false; + + // If N is the first node of the subloop's clique and there exists some edge from P to N then we append + // the entire clique to the current clique. Otherwise, we start a new clique and make the subloop's + // clique become this new clique's beginning. + for (ControlEdge* edge = nodeP.getSuccessorsBegin(); edge != limit; edge++) + if (&edge->getTarget() == &nodeN) { + nodePhasEdgeToNodeN = true; + break; + } + + if (!((subLoopClique->first().dfsNum == N) && nodePhasEdgeToNodeN)) { + currentClique = new(pool) Clique(); + loopToSchedule.cliques.addLast(*currentClique); + } + + for (DoublyLinkedList::iterator s = subLoopClique->begin(); !subLoopClique->done(s);) { + ScheduledNode& node = subLoopClique->get(s); + s = subLoopClique->advance(s); + node.remove(); + currentClique->addLast(node); + } + + subLoopClique->remove(); + + // If the subloop contained more than one clique, we push all remaining cliques onto the stack. + // We are carefull to keep the scheduling order. + for (DoublyLinkedList::iterator t = subLoop->cliques.end(); !subLoop->cliques.done(t);) { + Clique& slc = subLoop->cliques.get(t); + t = subLoop->cliques.retreat(t); + + slc.remove(); + *cliqueStackPointer++ = &slc; + } + + // The last node scheduled is the last node of the current clique. + P = currentClique->last().dfsNum; + } + } + + // + // Loop scheduling + // + + // Find the last clique in this region such that the last node N of this clique satisfies the following properties: + // 1.There exists an edge from N to H. + // 2.There are no short edges E: N->A for which A is outside R. + // 3.N is not a switch node. + // 4.N is not H. + for (DoublyLinkedList::iterator c = loopToSchedule.cliques.end(); !loopToSchedule.cliques.done(c); c = loopToSchedule.cliques.retreat(c)) { + Clique& clique = loopToSchedule.cliques.get(c); + ControlNode& lastNode = *dfsList[clique.last().dfsNum]; + + bool hasEdgeToHeader = false; + bool noShortEdgeOutsiteR = true; + + ControlEdge* limit = lastNode.getSuccessorsEnd(); + for (ControlEdge* edge = lastNode.getSuccessorsBegin(); edge != limit; edge++) { + if (edge->getTarget().dfsNum == loopToSchedule.header) + hasEdgeToHeader = true; + if (!edge->longFlag && R.test(edge->getTarget().dfsNum)) + noShortEdgeOutsiteR = false; + } + + if (hasEdgeToHeader && noShortEdgeOutsiteR && (!lastNode.hasControlKind(ckSwitch)) && (lastNode.dfsNum != loopToSchedule.header)) { + // We found this clique. We remove the last node N of this clique and prepend it to this + // subloop's first clique. Now as long as this clique ends with some node N' that satisfies + // all of the properties below, we remove N' from the end of this clique and prepend it + // to this subloop's first clique. + // + // 1.There are no short edges E: N'->A for which A is outside R. + // 2.N' is not a switch node. + // 3.N' is not the loop's header. + ScheduledNode& sNode = scheduledNodes[lastNode.dfsNum]; + sNode.remove(); + loopToSchedule.cliques.first().addFirst(sNode); + + for (DoublyLinkedList::iterator n = clique.end(); !clique.done(n);) { + ControlNode& node = *dfsList[clique.get(n).dfsNum]; + n = clique.retreat(n); + + bool noShortEdgeOutsiteR = true; + ControlEdge* limit = node.getSuccessorsEnd(); + for (ControlEdge* edge = node.getSuccessorsBegin(); edge != limit; edge++) + if (!edge->longFlag && R.test(edge->getTarget().dfsNum)) { + noShortEdgeOutsiteR = false; + break; + } + if (noShortEdgeOutsiteR && (!node.hasControlKind(ckSwitch)) && (node.dfsNum != loopToSchedule.header)) { + // The condition is satisfied. + ScheduledNode& sNode = scheduledNodes[lastNode.dfsNum]; + sNode.remove(); + loopToSchedule.cliques.first().addFirst(sNode); + } + else + break; + } + + if (clique.empty()) + clique.remove(); + break; + } + } + +#if defined(DEBUG_SCHEDULER) + fprintf(stdout, "done scheduled nodes: [ "); + for (DoublyLinkedList::iterator x = loopToSchedule.cliques.begin(); !loopToSchedule.cliques.done(x); x = loopToSchedule.cliques.advance(x)) { + fprintf(stdout, "[ "); + Clique& clique = loopToSchedule.cliques.get(x); + for (DoublyLinkedList::iterator z = clique.begin(); !clique.done(z); z = clique.advance(z)) + fprintf(stdout, "N%d ", clique.get(z).dfsNum); + fprintf(stdout, "] "); + } + fprintf(stdout, "]\n"); +#endif +} + +// +// Set the long edge flag to the given edge in region. +// +void ControlNodeScheduler::initializeLongEdgeFlag(ControlEdge& edge, LoopHierarchyNode& inLoop, FastBitSet& RR, FastBitSet& Rlocal) +{ + Int32 A = edge.getSource().dfsNum; + + if (!RR.test(A)) { // Condition 1 - A is outside RR. + edge.longFlag = true; + return; + } + + Int32 B = edge.getTarget().dfsNum; + + if (A >= B) { // Condition 3 - edge is a backward edge. + edge.longFlag = true; + return; + } + + if (edge.getSource().hasControlKind(ckSwitch)) { // Condition 4 - A is a switch node. + edge.longFlag = true; + return; + } + + if (!Rlocal.test(A)) { // Condition 5 - A is in a subloop. + + DoublyLinkedList& subLoops = inLoop.getSuccessors(); + for (DoublyLinkedList::iterator l = subLoops.begin(); !subLoops.done(l); l = subLoops.advance(l)) { + + LoopHierarchyNode& subLoop = subLoops.get(l); + if (subLoop.nodes.test(A)) { // subLoop is the largest inLoop's subloop that contains A. + for (DoublyLinkedList::iterator c = subLoop.cliques.begin(); !subLoop.cliques.done(c); c = subLoop.cliques.advance(c)) + if (subLoop.cliques.get(c).last().dfsNum == A) { // A is the last node of this clique. + edge.longFlag = false; + return; + } + + // If we get there then A is not the last node of some cliques + edge.longFlag = true; + return; + } + } + } + + if (!Rlocal.test(B)) { // Condition 6 - B is in a subloop. + + DoublyLinkedList& subLoops = inLoop.getSuccessors(); + for (DoublyLinkedList::iterator l = subLoops.begin(); !subLoops.done(l); l = subLoops.advance(l)) { + + LoopHierarchyNode& subLoop = subLoops.get(l); + if (subLoop.nodes.test(B)) { // subLoop is the largest inLoop's subloop that contains B. + for (DoublyLinkedList::iterator c = subLoop.cliques.begin(); !subLoop.cliques.done(c); c = subLoop.cliques.advance(c)) + if (subLoop.cliques.get(c).last().dfsNum == B) { // B is the last node of this clique. + edge.longFlag = false; + return; + } + + // If we get there then B is not the last node of some cliques + edge.longFlag = true; + return; + } + } + } + + // Condition 2 - edge is any exception or return edge. + switch (edge.getSource().getControlKind()) { + case ckCatch: case ckEnd: + edge.longFlag = true; + return; + default: + break; + } + + switch (edge.getTarget().getControlKind()) { + case ckCatch: case ckEnd: + edge.longFlag = true; + return; + default: + break; + } + + edge.longFlag = false; // Condition 7. +} + +// +// Fill the dominatorsMatrix with the dominators of all the nodes in this graph. +// Each row is a bitset of the dominators' dfsNum for the ControlNode which dfsNum is the row index. +// dominatorsMatrix must have (nNodes + 1) rows & nNodes columns. (One extra row is used for +// temporary calculations). +// +void ControlNodeScheduler::findDominators() +{ + // Initially each ControlNode is dominated by all the other ControlNodes. + dominatorsMatrix.set(); + + // The Begin Node is initialized independently as it is only dominated by itself. + dominatorsMatrix.clearRow(0); + dominatorsMatrix.set(0, 0); + + bool changed; // loop condition. + + do { + changed = false; + + for (Uint32 n = 1; n < nNodes; n++) { + dominatorsMatrix.setRow(nNodes); + + // The dominators of a ControlNode are the intersection of the dominators of its + // predecessors plus itself. + const DoublyLinkedList& predecessors = dfsList[n]->getPredecessors(); + for (DoublyLinkedList::iterator i = predecessors.begin(); !predecessors.done(i); i = predecessors.advance(i)) + dominatorsMatrix.andRows(predecessors.get(i).getSource().dfsNum, nNodes); + dominatorsMatrix.set(nNodes, n); + + if (!dominatorsMatrix.compareRows(nNodes, n)) { + changed = true; + dominatorsMatrix.copyRows(nNodes, n); + } + } + } while(changed); +} + +// +// Find the loop headers in the given array of ControlNodes & return the number +// of headers found. +// +Uint32 ControlNodeScheduler::findLoopHeaders() +{ + Uint32 nLoopHeaders = 0; // Number of loop headers in this graph. + + findDominators(); + + for (Uint32 n = 0; n < nNodes; n++) { + ControlNode& node = *dfsList[n]; + Uint32 nodeIndex = node.dfsNum; + + const DoublyLinkedList& predecessors = node.getPredecessors(); + for (DoublyLinkedList::iterator i = predecessors.begin(); !predecessors.done(i); i = predecessors.advance(i)) { + Uint32 predecessorIndex = predecessors.get(i).getSource().dfsNum; + + // A loop header is a node with an incoming backward edge. This edge's source must be dominated + // by itself (called regular backward edge). + if ((predecessorIndex >= nodeIndex) && dominatorsMatrix.test(predecessorIndex, nodeIndex)) { + loopHeaders.set(nodeIndex); + nLoopHeaders++; + break; + } + } + } + + if (!loopHeaders.test(0)) { + // The begin node is always considered to be a loop header (even if it's not). + loopHeaders.set(0); + nLoopHeaders++; + } + + return nLoopHeaders; +} + +// +// Build the LoopHierarchyTree, find the nodes for each loop and return the top of the tree. +// +LoopHierarchyNode& ControlNodeScheduler::buildLoopHierarchyTree() +{ + Uint32* nodeStack = new(pool) Uint32[nNodes]; // Stack of nodes to look at. + + Uint32 nLoopHeaders = findLoopHeaders(); + + LoopHierarchyNode* loopNodes = new(pool) LoopHierarchyNode[nLoopHeaders]; + LoopHierarchySet loopSet(pool, loopNodes, nNodes); // Set of the loop headers in this graph. + + // If the BeginNode is considered to be a loop then its body + // contains all the nodes in this graph. + LoopHierarchyNode& beginNode = loopSet[0]; + beginNode.header = 0; + beginNode.nodes.sizeTo(pool, nNodes); + beginNode.nodes.set(0, nNodes - 1); + + for (Int32 h = loopHeaders.nextOne(0); h != -1; h = loopHeaders.nextOne(h)) { + // + // Place this loop in the tree. + // + + FastBitSet dominators(dominatorsMatrix.getRow(h), nNodes); + + Int32 parent = h; + + do // parent must be a loop header && this node must be included in the parent's loop nodes. + parent = dominators.previousOne(parent); + while (!(loopHeaders.test(parent) && loopSet[parent].nodes.test(h))); + + loopSet[parent].addSuccessor(loopSet[h]); + + // + // Find this loop's nodes. + // + + Uint32* stackPointer = nodeStack; + LoopHierarchyNode& loop = loopSet[h]; + + // Initialize the loop header's variables. + loop.header = h; + loop.nodes.sizeToAndClear(pool, nNodes); + loop.nodes.set(h); + + // Push the tails of this loop. Each tail must be dominated by the loop header. + const DoublyLinkedList& headerPredecessors = dfsList[h]->getPredecessors(); + for (DoublyLinkedList::iterator i = headerPredecessors.begin(); !headerPredecessors.done(i); i = headerPredecessors.advance(i)) { + Uint32 predecessorIndex = headerPredecessors.get(i).getSource().dfsNum; + + if ((predecessorIndex > Uint32(h)) && dominatorsMatrix.test(predecessorIndex, h)) { + loop.nodes.set(predecessorIndex); + *stackPointer++ = predecessorIndex; + } + } + + while (stackPointer != nodeStack) { + Uint32 n = *--stackPointer; + + const DoublyLinkedList& predecessors = dfsList[n]->getPredecessors(); + for (DoublyLinkedList::iterator i = predecessors.begin(); !predecessors.done(i); i = predecessors.advance(i)) { + Uint32 predecessorIndex = predecessors.get(i).getSource().dfsNum; + if (!loop.nodes.test(predecessorIndex)) { + loop.nodes.set(predecessorIndex); + *stackPointer++ = predecessorIndex; + } + } + } + } + + return loopSet[0]; +} + +// +// Return an array of scheduled nodes. This array has nNodes elements. +// +ControlNode** ControlNodeScheduler::getScheduledNodes() +{ + // Initialize the ScheduledNodes. + scheduledNodes = new(pool) ScheduledNode[nNodes]; + for (Uint32 i = 0; i < nNodes; i++) { + ScheduledNode& node = scheduledNodes[i]; + node.dfsNum = i; + } + + nodesAlreadyScheduled.sizeToAndClear(nNodes); + + // + // Determine main nodes (called working nodes). + // + + Uint32 generation = ControlNode::getNextGeneration(); + Uint32* nodeStack = new(pool) Uint32[nNodes]; // Stack of nodes to look at. + Uint32* stackPointer = nodeStack; + *stackPointer++ = 0; // Push the beginNode. + + while (stackPointer != nodeStack) { + Uint32 n = *--stackPointer; + ControlNode& node = *dfsList[n]; + + node.workingNode = true; + + ControlEdge* limit = node.getSuccessorsEnd(); + for (ControlEdge* edge = node.getSuccessorsBegin(); edge != limit; edge++) { + ControlNode& successor = edge->getTarget(); + + if (successor.generation != generation) { + switch(successor.getControlKind()) { + case ckCatch: + case ckEnd: + // We are not following the exception edges. + break; + + default: + successor.generation = generation; + *stackPointer++ = successor.dfsNum; + break; + } + } + } + } + + // + // Schedule the loops from the inside out. + // + + struct EdgeStack + { + DoublyLinkedList* linkedList; + DoublyLinkedList::iterator position; + }; + + LoopHierarchyNode& top = buildLoopHierarchyTree(); + + EdgeStack *edgeStack = new(pool) EdgeStack[nNodes]; + DoublyLinkedList edgeToBeginNodeList; + edgeToBeginNodeList.addLast(top); + + DoublyLinkedList* currentList = &edgeToBeginNodeList; + DoublyLinkedList::iterator currentIterator = edgeToBeginNodeList.begin(); + EdgeStack *edgeStackPointer = edgeStack; + + while (true) { + if (currentList->done(currentIterator)) { + if (edgeStackPointer == edgeStack) + break; + + --edgeStackPointer; + currentList = edgeStackPointer->linkedList; + currentIterator = edgeStackPointer->position; + + // At this point all the loops below this one in the loop hierarchy tree have + // been scheduled. + LoopHierarchyNode& loopToSchedule = currentList->get(currentIterator->prev); + + scheduleLoop(loopToSchedule); + } else { + LoopHierarchyNode& loop = currentList->get(currentIterator); + currentIterator = currentList->advance(currentIterator); + + edgeStackPointer->linkedList = currentList; + edgeStackPointer->position = currentIterator; + edgeStackPointer++; + + currentList = &loop.getSuccessors(); + currentIterator = currentList->begin(); + } + } + + + // FIXME: need to schedule the remaining nodes (exceptions). + + // Summarize the scheduling. + ControlNode** result = new(pool) ControlNode*[nNodes]; + ControlNode** ptr = result; + + for (DoublyLinkedList::iterator c = top.cliques.begin(); !top.cliques.done(c); c = top.cliques.advance(c)) { + Clique& clique = top.cliques.get(c); + for (DoublyLinkedList::iterator s = clique.begin(); !clique.done(s); s = clique.advance(s)) + *ptr++ = dfsList[clique.get(s).dfsNum]; + } + + // Add the endNode. + *ptr++ = dfsList[nNodes - 1]; + + PR_ASSERT(ptr == &result[nNodes]); + + return result; +} diff --git a/ef/Compiler/CodeGenerator/ControlNodeScheduler.h b/ef/Compiler/CodeGenerator/ControlNodeScheduler.h new file mode 100644 index 000000000000..4487e7602b12 --- /dev/null +++ b/ef/Compiler/CodeGenerator/ControlNodeScheduler.h @@ -0,0 +1,97 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#ifndef _CONTROL_NODE_SCHEDULER_H_ +#define _CONTROL_NODE_SCHEDULER_H_ + +#include "Fundamentals.h" +#include "Pool.h" + +class ControlNode; + +struct ScheduledNode : public DoublyLinkedEntry +{ + // A ScheduledNode must be a linked in the execution order to other ScheduledNode. + // As ControlNode is already a linked to other ControlNode in the graph we create + // an instance of this class for each ControlNode of the graph and copy the field dfsNum. + Int32 dfsNum; +}; + +class Clique : public DoublyLinkedList, public DoublyLinkedEntry +{ + // A Clique is a linked list of ScheduledNode and also an entry in a linked list (list of Cliques in a loop). +}; + +class LoopHierarchyNode : public DoublyLinkedEntry +{ +private: + DoublyLinkedList successors; + +public: + Int32 header; // Loop header's dfsNum. + FastBitSet nodes; // Nodes contained in this loop. + DoublyLinkedList cliques; // Linked list of Clique in this loop. + + inline void addSuccessor(LoopHierarchyNode& successor) {successors.addLast(successor);} + inline DoublyLinkedList& getSuccessors() {return successors;} +}; + +class LoopHierarchySet +{ +private: + LoopHierarchyNode* nodes; // Array of loop nodes in the loop hierarchy tree. + Int32* indexes; // Array of indexes of nodes in the dfs order. + Uint32 nextFree; // Next available slot in nodes. + + LoopHierarchySet (const LoopHierarchySet &); // Copying forbidden + void operator = (const LoopHierarchySet &); // Copying forbidden + +public: + LoopHierarchySet(Pool& pool, LoopHierarchyNode* nodesArray, Uint32 nNodes); + + LoopHierarchyNode& operator[] (const Uint32 nodeIndex); +}; + +class ControlNodeScheduler +{ +private: + Pool& pool; + + ControlNode** dfsList; // List of ControlNodes in depth first search order (from the ControlGraph). + const Uint32 nNodes; // Number of ControlNodes in this graph. + + FastBitMatrix dominatorsMatrix; // Matrix of dominators for all the ControlNodes. + FastBitSet loopHeaders; // BitSet of the loop headers in the graph. + FastBitSet nodesAlreadyScheduled; // BitSet of the ControlNodes currently scheduled. + + ScheduledNode* scheduledNodes; // Array of ScheduledNodes. Used to chain the nodes in the Cliques. + + LoopHierarchyNode& buildLoopHierarchyTree(); + Uint32 findLoopHeaders(); + void scheduleLoop(LoopHierarchyNode& loopToSchedule); + void initializeLongEdgeFlag(ControlEdge& edge, LoopHierarchyNode& inLoop, FastBitSet& RR, FastBitSet& Rlocal); + void findDominators(); + +public: + ControlNodeScheduler(Pool& p, ControlNode** nodes, Uint32 n) : + pool(p), dfsList(nodes), nNodes(n), dominatorsMatrix(n + 1, n), loopHeaders(n) {} + + ControlNode** getScheduledNodes(); // Return the array of ControlNode in a scheduled order. +}; + +#endif /* _CONTROL_NODE_SCHEDULER_H_ */ diff --git a/ef/Compiler/CodeGenerator/ExceptionTable.cpp b/ef/Compiler/CodeGenerator/ExceptionTable.cpp new file mode 100644 index 000000000000..cde8aec92de9 --- /dev/null +++ b/ef/Compiler/CodeGenerator/ExceptionTable.cpp @@ -0,0 +1,181 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +// +// simon +// + +#include "JavaVM.h" +#include "ExceptionTable.h" +#include "CatchAssert.h" +#include "LogModule.h" + +UT_DEFINE_LOG_MODULE(ExceptionTable); + +//----------------------------------------------------------------------------------------------------------- +// ExceptionTableBuilder + +// METHOD addEntry +// In/Out: index -- created handler must be at or after stated index +// In newEntry -- entry to add to exception table +// Assumptions: entries must be added in ascending scheduled node order +void ExceptionTableBuilder:: +addEntry(Uint32& index, ExceptionTableEntry& newEntry) +{ + Uint32 tableSize = eTable.size(); + + // iterate through exception table trying to find an existing entry we can coalesce with + for(; index < tableSize; index++) + { + ExceptionTableEntry& ete = eTable[index]; + + // can't coalesce if handler, type or policy differ + if( (ete.pHandler != newEntry.pHandler) || + (ete.pExceptionType != newEntry.pExceptionType)) + continue; + + // we require that the above noted assumption has been met + assert(ete.pEnd <= newEntry.pStart); + + // extend range of existing exception table entry (coalesce) if possible + if(ete.pEnd == newEntry.pStart) + { + ete.pEnd = newEntry.pEnd; // coalesce ranges +#ifdef DEBUG_LOG + UT_LOG(ExceptionTable, PR_LOG_ALWAYS, ("merge")); + newEntry.print(UT_LOG_MODULE(ExceptionTable)); +#endif + return; // index will point to index of table entry that was extended + } + } + + // coalesce wasn't possible, so insert + eTable.append(newEntry); + +#ifdef DEBUG_LOG + UT_LOG(ExceptionTable, PR_LOG_ALWAYS, ("add ")); + newEntry.print(UT_LOG_MODULE(ExceptionTable)); +#endif + // index will be correctly set from end of 'for' loop +} + +//----------------------------------------------------------------------------------------------------------- + +#ifdef DEBUG +// check important assumption that array is sorted and valid +// if it is not then nested trys will probably fail +void ExceptionTableBuilder:: +checkInOrder() +{ + if(eTable.begin() == eTable.end()) + return; + + ExceptionTableEntry *curr, *next, *last; + curr= eTable.begin(); + last = eTable.end() - 1; + + while(curr < last) { + next = curr + 1; + assert(curr->pStart <= curr->pEnd); // sanity check + assert(curr->pStart <= next->pStart); // ensure that items are sorted by pStart field + curr = next; + } +} +#endif // DEBUG + +//----------------------------------------------------------------------------------------------------------- +// Constructor +// builds an exception table in the specified pool +ExceptionTable:: +ExceptionTable(ExceptionTableBuilder eBuilder, Pool& inPool) +{ + numberofEntries = eBuilder.getNumberofEntries(); + + start = eBuilder.start; + if(numberofEntries == 0) + { + mEntries = NULL; + } + else + { + Uint32 i; + mEntries = new(inPool) ExceptionTableEntry[numberofEntries]; + for(i = 0; i < numberofEntries; i++) + mEntries[i] = eBuilder.getEntry(i); + Uint32 sz = eBuilder.getNumberofAPoints(); + asynchPoints = new(inPool) Uint32[sz]; + for(i = 0; i < sz; i++) + asynchPoints[i] = eBuilder.getAEntry(i); + } +} + +// In: thrown object +// In: PC/EIP of +// Out: pointer to an ExceptionTableEntry that matches the thrown object (or NULL if no match) +ExceptionTableEntry* +ExceptionTable:: +findCatchHandler(const Uint8* pc, const JavaObject& inObject) +{ + const Class& clazz = inObject.getClass(); + + // scan through the handler list in _reverse_ looking for a match + // reverse scanning is needed to properly respect nested try blocks + if(numberofEntries > 0) + for(Int32 i = numberofEntries - 1; i >= 0; i--) + { + ExceptionTableEntry* tableEntry = mEntries + i; + if( (pc >= start + tableEntry->pStart) && + (pc < start + tableEntry->pEnd) && + clazz.implements( *(tableEntry->pExceptionType) ) ) + return tableEntry; + } + + return NULL; +} + +//----------------------------------------------------------------------------------------------------------- +// DEBUG code +#ifdef DEBUG_LOG + + +void ExceptionTable:: +print(LogModuleObject &f) +{ + if(numberofEntries == 0) + { + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("The exception table is empty.\n")); + } + else + { + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("(begin-offset, end-offset) -> handler-offset (exception caught)\n")); + for(Uint32 i = 0; i < numberofEntries; i++) + mEntries[i].print(f); + } +} + +void ExceptionTable:: +printShort(LogModuleObject &f) +{ + if(numberofEntries != 0) + for(Uint32 i = 0; i < numberofEntries; i++) + { + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("\t")); + mEntries[i].print(f,start); + } +} + +#endif // DEBUG diff --git a/ef/Compiler/CodeGenerator/ExceptionTable.h b/ef/Compiler/CodeGenerator/ExceptionTable.h new file mode 100644 index 000000000000..32966fb530ba --- /dev/null +++ b/ef/Compiler/CodeGenerator/ExceptionTable.h @@ -0,0 +1,142 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +// +// simon +// + +#ifndef _EXCEPTION_TABLE_ +#define _EXCEPTION_TABLE_ + +#include "Fundamentals.h" +#include "Vector.h" +#include "JavaObject.h" +#include "LogModule.h" + +//----------------------------------------------------------------------------------------------------------- +// ExceptionTableEntry +class ExceptionTableEntry +{ +public: + Uint32 pStart; + Uint32 pEnd; // offset to byte _after_ beginning of section + const Class* pExceptionType; // points to type of the handler + Uint32 pHandler; + +#ifdef DEBUG_LOG + void print(LogModuleObject &f,Uint8* s) + { + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("(%x,%x) -> %x (",Uint32(s+pStart), Uint32(s+pEnd), Uint32(s+pHandler))); + pExceptionType->printRef(f); + UT_OBJECTLOG(f, PR_LOG_ALWAYS, (")\n")); + } + void print(LogModuleObject &f) + { + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("(%d,%d) -> %d (",Uint32(pStart), Uint32(pEnd), Uint32(pHandler))); + pExceptionType->printRef(f); + UT_OBJECTLOG(f, PR_LOG_ALWAYS, (")\n")); + } +#endif +}; + +//----------------------------------------------------------------------------------------------------------- +// ExceptionTableBuilder +class ExceptionTableBuilder +{ +private: + Vector eTable; + Vector asynchPoints; + + Uint8* start; // points to start of method + +public: + ExceptionTableBuilder(Uint8* s) : eTable(), asynchPoints() { start = s; }; + + void addEntry(Uint32& index, ExceptionTableEntry& ete); + const ExceptionTableEntry& getEntry(Uint32 index) const { assert(index < eTable.size()); return (eTable[index]); } + Uint32 getNumberofEntries() const { return (eTable.size()); } + void addAEntry(Uint32 s) { + asynchPoints.append(s); + } + inline int getAEntry(int i) { + return asynchPoints[i]; + } + inline int getNumberofAPoints() { + return asynchPoints.size(); + } + + friend class ExceptionTable; + + DEBUG_ONLY(void checkInOrder()); +}; + +//----------------------------------------------------------------------------------------------------------- +// ExceptionTable +class ControlNode; + +class ExceptionTable +{ +private: + Uint32 numberofEntries; + ExceptionTableEntry* mEntries; + int numberofAPoints; + Uint32* asynchPoints; // array of offsets for where the asynch. points are + Uint8* start; // points to start of method + static ClassFileSummary* excClass; // points to the class of RuntimeException +public: + ExceptionTable(ExceptionTableBuilder eBuilder, Pool& inPool); + ExceptionTableEntry* findCatchHandler(const Uint8* pc, const JavaObject& inObject); + Uint32 getNumberofEntries() { return numberofEntries; } + ExceptionTable(ExceptionTable& et) { + numberofEntries = et.numberofEntries; + mEntries = et.mEntries; + numberofAPoints = et.numberofAPoints; + asynchPoints = et.asynchPoints; + start = et.start; + } + ExceptionTable& operator=(Uint8* newstart) + { + start = newstart; + return *this; + } + + inline Uint8* getStart() { return start; } + inline Uint32* getAsynchPoints() { return asynchPoints; } + inline int getNrOfAsynchPoints() { return numberofAPoints; } + static void staticInit(ClassCentral ¢ral); + +#ifdef DEBUG_LOG + void print(LogModuleObject &f); + void printShort(LogModuleObject &f); + void printFormatted(LogModuleObject &f, ControlNode** inNodes, Uint32 numNodes, bool isHTML); +#endif // DEBUG_LOG +}; + +struct ExceptionTableCache +{ + ExceptionTable eTable; + JavaObject* exc; + ExceptionTableCache(ExceptionTable* et, Uint8* i, JavaObject* ex) : eTable(*et) + { + eTable = i; // relocates the table + exc = ex; + } +}; + +//----------------------------------------------------------------------------------------------------------- + +#endif // _EXCEPTION_TABLE_ diff --git a/ef/Compiler/CodeGenerator/FormatStructures.h b/ef/Compiler/CodeGenerator/FormatStructures.h new file mode 100644 index 000000000000..45ddbb57de20 --- /dev/null +++ b/ef/Compiler/CodeGenerator/FormatStructures.h @@ -0,0 +1,111 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +// +// File: FormatStructures.h +// +// Authors: Simon Holmes a Court +// +// To avoid circular include problems, data structures used in the md emitter, md formatter +// and native formatter may be found here. +// + +#ifndef _FORMAT_STRUCTURES_ +#define _FORMAT_STRUCTURES_ + +#include "Fundamentals.h" +#include "LogModule.h" + +struct Method; +class VirtualRegisterManager; +struct MethodDescriptor; + +//----------------------------------------------------------------------------------------------------------- +// FormattedCodeInfo +struct FormattedCodeInfo +{ + Method* method; // runtime descriptor of the method we're formatting + Uint8* methodStart; // ptr to beginning of allocated memory for the method + Uint8* methodEnd; // ptr to (FIX byte after?) end of allocated memory for the method + + Uint32 prologSize; + Uint32 epilogSize; + Uint32 bodySize; // prologSize + epilogSize + formatted size of on the instructions in all ControlNodes + Uint32 preMethodSize; + Uint32 postMethodSize; +}; + +//----------------------------------------------------------------------------------------------------------- +// TVector +#ifdef GENERATE_FOR_PPC +#define USE_TVECTOR +#endif + +#ifdef USE_TVECTOR + extern void* _MD_createTVector(const MethodDescriptor& inMethodDescriptor, void* inFunctionMemory); + #define M_MD_createTVector(inMethodDescriptor, inFunctionMemory) (_MD_createTVector(inMethodDescriptor, inFunctionMemory)) +#else + #define M_MD_createTVector(inMethodDescriptor, inFunctionMemory) (inFunctionMemory) +#endif + +//----------------------------------------------------------------------------------------------------------- +// StackFrameInfo +class StackFrameInfo +{ +protected: + Uint8 numSavedGPRs; + Uint8 numSavedFPRs; + Uint8 numMonitorSlots; + + Uint32 localStore_bytes; + + DEBUG_ONLY(bool hasBeenInited;) + +public: + StackFrameInfo() { DEBUG_ONLY(hasBeenInited = false); }; + void init(VirtualRegisterManager& /*inVRManager*/) { DEBUG_ONLY(hasBeenInited = true); } + Uint32 getNumSavedGPRWords() { assert(hasBeenInited); return numSavedGPRs; } + Uint32 getNumSavedFPRWords() { assert(hasBeenInited); return numSavedFPRs; } + Uint32 getNumMonitorSlots() { assert(hasBeenInited); return numMonitorSlots; } + + Uint32 getRegisterOffset() { assert(hasBeenInited); return numMonitorSlots; } + + Uint32 getLocalStoreSizeBytes() { assert(hasBeenInited); return localStore_bytes; } + + // x86 only right now! + // returns the offset (off EBP) to the beginning of the registers + Uint32 getCalleeSavedBeginOffset() + { + return localStore_bytes + 4; + } + + // returns the offset (off EBP) to the stack pointer before any arguments are pushed + + Uint32 getStackPointerOffset() + { + return localStore_bytes + (4 * numSavedGPRs) + (4 * numSavedFPRs) + (4 * numMonitorSlots); + } + +#ifdef DEBUG_LOG + void print(LogModuleObject &f) + { + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("Policy: g%d:f%d:l%d\n", getNumSavedGPRWords(), getNumSavedFPRWords(), getLocalStoreSizeBytes())); + } +#endif // DEBUG_LOG +}; + +#endif // _FORMAT_STRUCTURES_ diff --git a/ef/Compiler/CodeGenerator/HTMLMethodDump.cpp b/ef/Compiler/CodeGenerator/HTMLMethodDump.cpp new file mode 100644 index 000000000000..b134b5a788a8 --- /dev/null +++ b/ef/Compiler/CodeGenerator/HTMLMethodDump.cpp @@ -0,0 +1,508 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +// +// File: HTMLMethodDump.cpp +// Author: Simon Holmes a Court +// + +#include "Fundamentals.h" + +#ifdef DEBUG_LOG + +#include "LogModule.h" +#include "HTMLMethodDump.h" +#include "NativeFormatter.h" +#include "FieldOrMethod.h" +#include "ExceptionTable.h" +#include "ControlGraph.h" +#include + +//----------------------------------------------------------------------------------------------------------- +// Native Formatter method +UT_DEFINE_LOG_MODULE(MethodToHtml); + +void dumpDissasembly(LogModuleObject &f, Uint8* start, Uint8* end) +{ + if (end <= start) // this happens for the last node, or nodes without code + return; + + Uint8* curAddr = start; + while ((curAddr != NULL) && (curAddr < end)) + curAddr = (Uint8*) disassemble1(f, curAddr); +} + +static void dumpHTMLByteCode(MethodToHTML output, Method* inMethod) +{ + UT_OBJECTLOG(output.mFile, PR_LOG_ALWAYS, ("\n
\n")); + output.heading("ByteCode"); + UT_OBJECTLOG(output.mFile, PR_LOG_ALWAYS, ("\n
\n
\n"));
+	inMethod->dumpBytecodeDisassembly(output.mFile);
+	UT_OBJECTLOG(output.mFile, PR_LOG_ALWAYS, ("
\n")); +} + +static void dumpHTMLExceptionTable(MethodToHTML output, ExceptionTable& inExceptionTable, ControlNode** nodes, Uint32 nNodes) +{ + UT_OBJECTLOG(output.mFile, PR_LOG_ALWAYS, ("\n
\n")); + output.heading("Exception Table"); + UT_OBJECTLOG(output.mFile, PR_LOG_ALWAYS, ("\n
\n
"));
+	inExceptionTable.print(output.mFile);
+	UT_OBJECTLOG(output.mFile, PR_LOG_ALWAYS, ("
\n")); + + inExceptionTable.printFormatted(output.mFile, nodes, nNodes, true); +} + +void NativeFormatter:: +dumpMethodToHTML(FormattedCodeInfo& fci, ExceptionTable& inExceptionTable) +{ + // create and prepare the output file + MethodToHTML output; + output.mFile.setLogLevel(PR_LOG_ALWAYS); + output.mFile.setOptions(PR_LOG_OPTION_NIL); + + assert(fci.method); + +#if defined(XP_PC) || defined(LINUX) + if (*fci.methodStart == 0xcc) + fci.methodStart++; +#endif + + // get clean name + const char* oldname = fci.method->getName(); + char* name = new char[strlen(oldname) + 1]; + strcpy(name, oldname); + char* q = name; + while(*q) + { + switch(*q) + { + case ':': case '<': case '>': case '/': case ' ': + *q = '_'; + } + q++; + } + + const char* filename = fci.method->getHTMLName(); + + // open file a clean filename + output.openFile(filename); + output.pageBegin(name); + + // stats + const char* className = fci.method->getDeclaringClass()->getName(); + + output.statsBegin(); + output.bigstatsLine("Name", name); + output.statsLine("Class/Name/Sig", className, name, fci.method->getSignatureString()); + output.statsLine("Fully qualified name", fci.method->toString()); + output.statsLine("HTML File Name", filename); + + output.statsLine("Native Code Bytes", fci.methodEnd - fci.methodStart); + + time_t currentTime; // output the time + time(¤tTime); + output.statsLine("Created", ctime(¤tTime)); + + output.statsEnd(); + + // disassemble bytecode + dumpHTMLByteCode(output, fci.method); + + // disassemble + output.heading("Generated Code"); + output.disassemblyTableBegin(); + + // dump prolog + Uint8* curOffset; + curOffset = fci.methodStart; + output.disassemblyRowBegin("Pre"); + dumpDissasembly(output.mFile, curOffset, curOffset + fci.preMethodSize); + curOffset += fci.preMethodSize; + output.disassemblyColumnSeparator(0xeeeeee); + output.disassemblyColumnSeparator(0xdddddd); + output.disassemblyRowEnd(); + + output.disassemblyRowBegin("Pro"); + dumpDissasembly(output.mFile, curOffset, curOffset + fci.prologSize); + curOffset += fci.prologSize; + output.disassemblyColumnSeparator(0xeeeeee); + output.disassemblyColumnSeparator(0xdddddd); + output.disassemblyRowEnd(); + + // dump methods + nodes[0]->controlGraph.dfsSearch(); + nodes[0]->controlGraph.assignProducerNumbers(1); + + // now go through and print out the high level representation (w/o prolog etc) + for (Uint32 n = 0; n < nNodes; n++) + { + ControlNode& node = *nodes[n]; + output.disassemblyRowBegin(node.dfsNum); + + // actual disassembly + Uint8* nodeStart; + Uint8* nodeEnd; + + nodeStart = curOffset; + + if (n != (nNodes - 1)) + nodeEnd = fci.methodStart + nodes[n+1]->getNativeOffset(); + else // last node + nodeEnd = fci.methodEnd; + + curOffset = nodeEnd; + + dumpDissasembly(output.mFile, nodeStart, nodeEnd); + output.disassemblyColumnSeparator(0xeeeeee); + + // intended disassembly + InstructionList& instructions = node.getInstructions(); + for(InstructionList::iterator i = instructions.begin(); !instructions.done(i); i = instructions.advance(i)) + { + instructions.get(i).printPretty(output.mFile); + UT_OBJECTLOG(output.mFile, PR_LOG_ALWAYS, ("\n")); + } + + // primitive graph + output.disassemblyColumnSeparator(0xdddddd); + node.printPretty(output.mFile, 0); + + output.disassemblyRowEnd(); + } + + output.disassemblyTableEnd(); + + // exception table + dumpHTMLExceptionTable(output, inExceptionTable, nodes, nNodes); + + output.pageEnd(); + output.closeFile(); + + // add this file reference to the index file + FileIndex::insertFile(filename, name, className); + FileIndex::output(); // FIX FIX FIX for now we output this file EVERY time we generate code +} + +//----------------------------------------------------------------------------------------------------------- +FileIndex FileIndex::sFileIndex; + +void FileIndex:: +outputHelper() +{ + // open the index file + FILE* f = fopen("index.html","w"); + assert(f); + + // print the header + fprintf(f, "\n\nGenerated Code Index\n\n" + "\n\n" ); + + // output links + ClassNode* c = classes; + while(c) + { + fprintf(f, "\n
%s
\n", c->className); + FileNode* n = c->files; + while(n) + { + fprintf(f, "\t%s
\n", n->fileName, n->methodName); + n = n->next; + } + c = c->next; + } + + // output footers + fprintf(f, "\n\n\n"); + fclose(f); +} + +ClassNode* FileIndex:: +findClassName(const char* className) +{ + if(classes == NULL) + { + classes = new ClassNode(className); + return classes; + } + + // search for a class object if there is one + ClassNode* foundClass = classes; + while(true) + { + if(strncmp(foundClass->className, className, 512) == 0) + return foundClass; + + // no match, if end, make new node + if(foundClass->next == NULL) + { + foundClass->next = new ClassNode(className); + return foundClass->next; + } + else + foundClass = foundClass->next; + } +} + +void FileIndex:: +insertFileHelper(const char* inFileName, const char* inMethodName, const char* inClassName) +{ + ClassNode* classnode = findClassName(inClassName); + FileNode* firstNode = classnode->files; + FileNode* newNode = new FileNode(inFileName, inMethodName); + + if(firstNode == NULL) + { + classnode->files = newNode; + return; + } + + // is it before the first? + if(strncmp(inMethodName, firstNode->methodName, 512) < 0) + { + classnode->files = newNode; + newNode->next = firstNode; + return; + } + + // otherwise iterate through until we are after a node and then insert + FileNode* node = firstNode; + while(true) + { + if( node->next == NULL || // at end + (strncmp(inMethodName, node->next->methodName, 512) < 0) ) // lexically before next name + { + FileNode* tempNode = node->next; + node->next = newNode; + newNode->next = tempNode; + return; + } + node = node->next; + } +} + +//----------------------------------------------------------------------------------------------------------- +// Debugging Code for outputting Exception Tables +static void tableBegin(LogModuleObject &f, bool isHTML) +{ + if(isHTML) + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("
\n\n")); +} +static void tableEnd(LogModuleObject &f, bool isHTML) +{ + isHTML ? UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("
\n
\n")) : UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("\n\n\n")); +} +static void heading(LogModuleObject &f, Uint32 num, bool isHTML) +{ + if(isHTML) + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("%d", num)); + else + UT_OBJECTLOG(f, PR_LOG_ALWAYS, (" %02d ", num)); +} +static void rowBegin(LogModuleObject &f, bool isHTML) +{ + if(isHTML) + { + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("Node")); + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("Offset")); + } + else + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("N ")); +} +static void nodeRowBegin(LogModuleObject &f, Uint32 node, Uint32 offset, bool isHTML) +{ + if(isHTML) + { + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("N%d", node)); + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("%d ", offset)); + } + else + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("N%02d: %4d ", node, offset)); +} +static void rowEnd(LogModuleObject &f, bool isHTML) +{ + isHTML ? UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("\n")) : UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("\n")); +} +static void printInside(LogModuleObject &f, bool isHTML) +{ + isHTML ? UT_OBJECTLOG(f, PR_LOG_ALWAYS, (" ")) : UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("| ")); +} +static void printOutside(LogModuleObject &f, Uint32 col, bool isHTML) +{ + if(isHTML) + if(col&1) + UT_OBJECTLOG(f, PR_LOG_ALWAYS, (" ")); + else + UT_OBJECTLOG(f, PR_LOG_ALWAYS, (" ")); + else + UT_OBJECTLOG(f, PR_LOG_ALWAYS, (" ")); +} + +void ExceptionTable:: +printFormatted(LogModuleObject &f, ControlNode** inNodes, Uint32 numNodes, bool isHTML) +{ + Uint32 col; + if(numberofEntries == 0) + return; + + // print headers + tableBegin(f, isHTML); + rowBegin(f, isHTML); + for(col = 0; col < numberofEntries; col++) + heading(f, col, isHTML); + rowEnd(f, isHTML); + + // print table + for (Uint32 i = 0; i < numNodes; i++) + { + ControlNode* node = inNodes[i]; + Uint32 pc = node->getNativeOffset(); + nodeRowBegin(f, node->dfsNum, pc, isHTML); + + for(col = 0; col < numberofEntries; col++) + if (pc >= mEntries[col].pStart && pc < mEntries[col].pEnd) + printInside(f, isHTML); + else + printOutside(f, col, isHTML); + + rowEnd(f, isHTML); + } + tableEnd(f, isHTML); +} + +//----------------------------------------------------------------------------------------------------------- +// Debugging Code for outputting HTML pages + +void MethodToHTML:: +openFile(const char* fileName) +{ + // open the file + if (!mFile.setLogFile(fileName)) + trespass("opening log file failed"); +} + +void MethodToHTML:: +closeFile() +{ +// assert(mFile); +// fclose(mFile); +} + +void MethodToHTML:: +pageBegin(const char* name) +{ + UT_OBJECTLOG(mFile, PR_LOG_ALWAYS, ("\n\n%s\n\n", name)); + UT_OBJECTLOG(mFile, PR_LOG_ALWAYS, ("\n\n")); +} + +// Heading +void MethodToHTML:: +heading(const char* label) +{ + UT_OBJECTLOG(mFile, PR_LOG_ALWAYS, ("%s
\n", label)); +} + +// Stats +void MethodToHTML:: +statsBegin() +{ + UT_OBJECTLOG(mFile, PR_LOG_ALWAYS, ("\n\n\n\n")); +} + +void MethodToHTML:: +statsLine(const char* label, const char* value) +{ + UT_OBJECTLOG(mFile, PR_LOG_ALWAYS, ("\n", label, value)); +} + +void MethodToHTML:: +bigstatsLine(const char* label, const char* value) +{ + UT_OBJECTLOG(mFile, PR_LOG_ALWAYS, ("\n\n" + "\n\n", label, value)); +} + +void MethodToHTML:: +statsLine(const char* label, const int value) +{ + UT_OBJECTLOG(mFile, PR_LOG_ALWAYS, ("\n", label, value)); +} + +void MethodToHTML:: +statsLine(const char* label, const char* value1, const char* value2, const char* value3) +{ + UT_OBJECTLOG(mFile, PR_LOG_ALWAYS, ("\n", label, value1, value2, value3)); +} + + +void MethodToHTML:: +statsEnd() +{ + UT_OBJECTLOG(mFile, PR_LOG_ALWAYS, ("
%s%s
%s%s
%s%d
%s%s %s %s
\n
\n
 \n
 \n\ngo to index\n
 \n
 \n\n")); +} + +// disassembly +void MethodToHTML:: +disassemblyTableBegin() +{ + UT_OBJECTLOG(mFile, PR_LOG_ALWAYS, ("\n\n")); + UT_OBJECTLOG(mFile, PR_LOG_ALWAYS, ("\n")); + UT_OBJECTLOG(mFile, PR_LOG_ALWAYS, ("\n")); + UT_OBJECTLOG(mFile, PR_LOG_ALWAYS, ("\n")); + UT_OBJECTLOG(mFile, PR_LOG_ALWAYS, ("\n" )); +} + +void MethodToHTML:: +disassemblyRowBegin(Uint32 nodeNum) +{ + UT_OBJECTLOG(mFile, PR_LOG_ALWAYS, ("\n\n\n\n\n\n\n\n\n\n\n\n")); +} + +void MethodToHTML:: +disassemblyTableEnd() +{ + UT_OBJECTLOG(mFile, PR_LOG_ALWAYS, ("
Node
Disassembly
Intended Code
Primitives
N%d" + "
", nodeNum, nodeNum));
+}
+
+void MethodToHTML::
+disassemblyRowBegin(const char* label)
+{
+	UT_OBJECTLOG(mFile, PR_LOG_ALWAYS, ("\n\n\n
%s" + "
", label, label));
+}
+
+void MethodToHTML::
+disassemblyColumnSeparator(Uint32 color)
+{
+	UT_OBJECTLOG(mFile, PR_LOG_ALWAYS, (" 
", color));
+}
+
+void MethodToHTML::
+disassemblyRowEnd()
+{
+	UT_OBJECTLOG(mFile, PR_LOG_ALWAYS, (" 
\n\n")); +} + +void MethodToHTML:: +pageEnd() +{ + UT_OBJECTLOG(mFile, PR_LOG_ALWAYS, ("\n\n\n")); +} + +//----------------------------------------------------------------------------------------------------------- + +#endif // DEBUG_LOG diff --git a/ef/Compiler/CodeGenerator/HTMLMethodDump.h b/ef/Compiler/CodeGenerator/HTMLMethodDump.h new file mode 100644 index 000000000000..d798ae6582ad --- /dev/null +++ b/ef/Compiler/CodeGenerator/HTMLMethodDump.h @@ -0,0 +1,108 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +// +// File: HTMLMethodDump.h +// Author: Simon Holmes a Court +// + +#ifdef DEBUG_LOG +#include + +void dumpDissasembly(LogModuleObject &f, Uint8* start, Uint8* end); + +//----------------------------------------------------------------------------------------------------------- +// Debugging Code for outputting HTML index +struct FileNode +{ + const char* fileName; + const char* methodName; + FileNode* next; + + FileNode(const char* inFileName, const char* inMethodName) : + fileName(inFileName), methodName(inMethodName), next(NULL) {}; +}; + +struct ClassNode +{ + const char* className; + FileNode* files; // pointers to files + ClassNode* next; + + ClassNode(const char* inClassName) : className(inClassName), files(NULL), next(NULL) {}; +}; + +// Object to store references to all the HTML files generated + +class FileIndex +{ +private: + ClassNode* classes; + + FileIndex() : classes(NULL) {}; + ClassNode* findClassName(const char* className); + void insertFileHelper(const char* fileName, const char* methodName, const char* className); + void outputHelper(); + // FIX no destructor -- memory leak + +public: +// static inline FileIndex& getFileIndex() { return (FileIndex::sFileIndex); }; + static FileIndex sFileIndex; + + static void output() { FileIndex::sFileIndex.outputHelper(); } + static void insertFile(const char* f, const char* m, const char* c) { FileIndex::sFileIndex.insertFileHelper(f, m, c); } +}; + +//----------------------------------------------------------------------------------------------------------- +// MethodToHTML +UT_EXTERN_LOG_MODULE(MethodToHtml); + +class MethodToHTML +{ +public: + LogModuleObject &mFile; + + MethodToHTML() : mFile(UT_LOG_MODULE(MethodToHtml)) {} + + // file stuff + void openFile(const char* fileName); + void closeFile(); + + // html to begin and end a page + void pageBegin(const char* name); + void pageEnd(); + void heading(const char* label); + + // statistics + void statsBegin(); + void statsLine(const char* label, const char* value); + void statsLine(const char* label, const char* value1, const char* value2, const char* value3); + void statsLine(const char* label, const int value); + void bigstatsLine(const char* label, const char* value); + void statsEnd(); + + // dissassembly table + void disassemblyTableBegin(); + void disassemblyRowBegin(Uint32 nodeNum); + void disassemblyRowBegin(const char* label); + void disassemblyColumnSeparator(Uint32 color); + void disassemblyRowEnd(); + void disassemblyTableEnd(); +}; + +#endif // DEBUG_LOG + diff --git a/ef/Compiler/CodeGenerator/IGVisualizer.cpp b/ef/Compiler/CodeGenerator/IGVisualizer.cpp new file mode 100644 index 000000000000..66dd98ab51a6 --- /dev/null +++ b/ef/Compiler/CodeGenerator/IGVisualizer.cpp @@ -0,0 +1,915 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +/* + The instruction graph visulizer. + IGVisualizer.cpp + + Peter DeSantis +*/ + +#if defined(DEBUG) && (defined(WIN32) || defined(USE_MESA)) && defined(IGVISUALIZE) + +#include +#include +#include +#include + +#include "CodeGenerator.h" +#include "IGVisualizer.h" +#include "Instruction.h" +#include "Primitives.h" +#include "Vector.h" + +// To allow glut callbacks to access member data +IGVisualizer* IGVisualizer::self = NULL; + +IGVisualizer:: +IGVisualizer() + + +{ + font = GLUT_STROKE_ROMAN; + + zoomFactor = 2; + cumZoom = 1; + + + objectCenterX = 0; + objectCenterY = 0; + mouseCenterX = 0; + mouseCenterY = 0; + + nodeLocX = 0; + nodeLocY = 0; + + xWindowDim = 800; // Dimension of window + yWindowDim = 600; + + xDimGL = 10000; + yDimGL = 10000; + + centerX = 0; + centerY = 0; + + INSTRUCTIONWIDTH = 1400; // The size of the instruction itself + INSTRUCTIONHEIGHT = 500 ; + FRAMEWIDTH = 1450; // Frame is the area around an instruction + FRAMEHEIGHT = 750; + BORDERWIDTH = 20; // Border around an instruction + SPACEBETWEENTREES = 130; + + ARGUMENTREGISTERS = 4; // VR <= AURGUMENTMENTREGISTERS + + self = this; + + roots = new Vector; +} + +IGVisualizer :: +~IGVisualizer() +{ + delete roots; +} + + +/* + Add all the roots you want to be visualized before calling visualize +*/ + +void IGVisualizer :: +addRoots(Vector& inRoots) +{ + + RootPair* curRoot; + VisualInstructionRoot* vRoot = NULL; + for(curRoot = inRoots.begin(); curRoot < inRoots.end(); curRoot++) + { + DataNode* curOutput; + Instruction* nextInsn; + + + if(curRoot->root->getOutgoingEdgesEnd() > curRoot->root->getOutgoingEdgesBegin()) + { + // now walk through all vr's assigned to this producer + VirtualRegister* curVR; + for (curOutput = curRoot->root->getOutgoingEdgesBegin(); + curOutput < curRoot->root->getOutgoingEdgesEnd(); + curOutput++) + { + switch (curOutput->kind) + { + case vkCond: + case vkMemory: + nextInsn = curOutput->getInstructionAnnotation(); + break; + default: + curVR = curOutput->getVirtualRegisterAnnotation(); + assert (curVR); + nextInsn = curVR->getDefineInstruction(); + break; + } + + assert (nextInsn); + + vRoot = new VisualInstructionRoot; + vRoot->root = nextInsn; + vRoot->exploringAsRoot = false; + vRoot->locAsCSE = new Vector; + vRoot->currentCSE = NULL; + vRoot->locAsRoot = NULL; + + roots->append(*vRoot); + } + } + + if (curRoot->root->getInstructionRoot() != NULL) { + nextInsn = curRoot->root->getInstructionRoot(); + + vRoot = new VisualInstructionRoot; + vRoot->root = nextInsn; + vRoot->exploringAsRoot = false; + vRoot->locAsCSE = new Vector; + vRoot->currentCSE = NULL; + vRoot->locAsRoot = NULL; + + roots->append(*vRoot); + + } + + } +} + +/* + Internal routine which visualizes the set of roots +*/ +void IGVisualizer :: +visualizeRoots() +{ + + int bottom = 0; + int left = 0; + + VisualInstructionRoot* curRoot; + for(curRoot = self->roots->begin(); curRoot < self->roots->end(); curRoot++) + { + curRoot->exploringAsRoot = true; + curRoot->locAsRoot = &DrawTree(*(curRoot->root), bottom, left); + bottom = curRoot->locAsRoot->top + self->SPACEBETWEENTREES; + curRoot->exploringAsRoot = false; + } + +} + +VisualInstructionRoot* IGVisualizer :: +isInRoots(Instruction* subRoot) +{ + VisualInstructionRoot* curRoot; + for(curRoot = self->roots->begin(); curRoot < self->roots->end(); curRoot++) + if(curRoot->root == subRoot) + return curRoot; + return NULL; +} + + + + +/* + Internal routine to draw the tree rooted a root so that root's bottom is at yBottom + and the tree rooted at root extends to xLeft. +*/ +TreeLocation& IGVisualizer :: +DrawTree(Instruction& root, int yBottom, int xLeft) +{ + Instruction* subRoot; + InstructionUse* curUse; + TreeLocation* loc; + TreeLocation* myLocation = new TreeLocation; + Vector subTreeLocations; + VisualInstructionRoot* vRoot; + int left = xLeft; + int top = yBottom + self->FRAMEHEIGHT; + + if(root.next == NULL) + { + assert(root.prev == NULL); + assert(root.getInstructionDefineEnd() == root.getInstructionDefineBegin() +1); + assert(root.getInstructionUseEnd() == root.getInstructionUseBegin() +1); + + // Instruction has been removed from the list + curUse = root.getInstructionUseBegin(); + subRoot = CodeGenerator::instructionUseToInstruction(*curUse); + if(subRoot != NULL) + { + vRoot = isInRoots(subRoot); + if(vRoot != NULL) // CSE + { + loc = new TreeLocation; + loc->rootMiddle = (float)self->FRAMEWIDTH/2 + left; + loc->right = self->FRAMEWIDTH + left; + loc->top = yBottom + self->FRAMEHEIGHT; + loc->bottom = yBottom; + DrawSubExpressionNode(subRoot, loc->rootMiddle, loc->bottom); + vRoot->locAsCSE->append(*loc); + loc = new TreeLocation; + loc->rootMiddle = (float)self->FRAMEWIDTH/2 + left; + loc->right = self->FRAMEWIDTH + left; + loc->top = yBottom + self->FRAMEHEIGHT; + loc->bottom = yBottom; + return *loc; + } else + { + PrimitiveOperation op = subRoot->getPrimitive()->getOperation(); + switch (op) + { + case(poPhi_M): + case(poPhi_I): + case(poPhi_L): + case(poPhi_F): + case(poPhi_D): + case(poPhi_A): + case(poPhi_C): + loc = new TreeLocation; + loc->rootMiddle = (float)self->FRAMEWIDTH/2 + left; + loc->right = self->FRAMEWIDTH + left; + loc->top = yBottom + self->FRAMEHEIGHT; + loc->bottom = yBottom; + DrawDummyNode(loc->rootMiddle, loc->bottom); + return *loc; + break; + default: + return DrawTree(*subRoot, yBottom, left); + break; + } + + } + } else { // This input is not defined + loc = new TreeLocation; + loc->rootMiddle = (float)self->FRAMEWIDTH/2 + left; + loc->right = self->FRAMEWIDTH + left; + loc->top = yBottom + self->FRAMEHEIGHT; + loc->bottom = yBottom; + if( (curUse->kind == udRegister) && ((*(curUse->name.vr)).index <= self->ARGUMENTREGISTERS) ) + { + DrawArgumentNode(loc->rootMiddle, loc->bottom); + } else + DrawDummyNode(loc->rootMiddle, loc->bottom); + return *loc; + } + + } + + assert(root.prev != NULL); + + + + // Draw your sub trees + for(curUse = root.getInstructionUseBegin(); curUse < root.getInstructionUseEnd(); curUse++) + { + subRoot = CodeGenerator::instructionUseToInstruction(*curUse); + + if(subRoot != NULL) + { + vRoot = isInRoots(subRoot); + if(vRoot != NULL) // CSE + { + loc = new TreeLocation; + loc->rootMiddle = (float)self->FRAMEWIDTH/2 + left; + loc->right = self->FRAMEWIDTH + left; + loc->top = yBottom + (2 * self->FRAMEHEIGHT); + loc->bottom = yBottom + self->FRAMEHEIGHT; + DrawSubExpressionNode(subRoot, loc->rootMiddle, loc->bottom); + vRoot->locAsCSE->append(*loc); + loc = new TreeLocation; + loc->rootMiddle = (float)self->FRAMEWIDTH/2 + left; + loc->right = self->FRAMEWIDTH + left; + loc->top = yBottom + (2 * self->FRAMEHEIGHT); + loc->bottom = yBottom + self->FRAMEHEIGHT; + } else + { + PrimitiveOperation op = subRoot->getPrimitive()->getOperation(); + switch (op) + { + case(poPhi_M): + case(poPhi_I): + case(poPhi_L): + case(poPhi_F): + case(poPhi_D): + case(poPhi_A): + case(poPhi_C): + loc = new TreeLocation; + loc->rootMiddle = (float)self->FRAMEWIDTH/2 + left; + loc->right = self->FRAMEWIDTH + left; + loc->top = yBottom + (2 * self->FRAMEHEIGHT); + loc->bottom = yBottom + self->FRAMEHEIGHT; + DrawDummyNode(loc->rootMiddle, loc->bottom); + break; + default: + loc = &DrawTree(*subRoot, yBottom + self->FRAMEHEIGHT, left); + break; + } + + }//loc = &DrawTree(*subRoot, yBottom + self->FRAMEHEIGHT, left); + } + else // This input is not defined + { + loc = new TreeLocation; + loc->rootMiddle = (float)self->FRAMEWIDTH/2 + left; + loc->right = self->FRAMEWIDTH + left; + loc->top = yBottom + (2 * self->FRAMEHEIGHT); + loc->bottom = yBottom + self->FRAMEHEIGHT; + if( (curUse->kind == udRegister) && ((*(curUse->name.vr)).index <= self->ARGUMENTREGISTERS) ) + { + DrawArgumentNode(loc->rootMiddle, loc->bottom); + } else + DrawDummyNode(loc->rootMiddle, loc->bottom); + } + + if(loc->top > top) + top = loc->top; + + left = loc->right; + subTreeLocations.append(*loc); + } + + + + + + if(subTreeLocations.size() == 0) + { + myLocation->rootMiddle = (float)self->FRAMEWIDTH/2 + xLeft; + myLocation->right = self->FRAMEWIDTH + xLeft; + myLocation->top = yBottom + self->FRAMEHEIGHT; + myLocation->bottom = yBottom; + } else { + myLocation->rootMiddle = subTreeLocations.front().rootMiddle + (0.5f)*(subTreeLocations.back().rootMiddle - subTreeLocations.front().rootMiddle); + myLocation->right = subTreeLocations.back().right; + myLocation->top = top; + myLocation->bottom = yBottom; + } + + DrawNode(myLocation->rootMiddle, yBottom, &root, subTreeLocations); + + return *myLocation; + +} + +/* + Dum routine reads a file to a stream, returns size + printPretty should use strings +*/ + +int fileToString(char *fileName, char *string, int len) +{ + + FILE* file = fopen(fileName, "r"); + assert(file); + + char c = fgetc(file); + int i = 0; + while(!feof(file) && i < (len-1)) + { + + if(c == 9) + c = ' '; + string[i] = c; + i++; + c = fgetc(file); + } + + string[i] = '\0'; + fclose(file); + return i; +} + + + + + + +/* + Write instruction Name and label Registers +*/ + +void IGVisualizer :: +LabelNode(Instruction* inst) +{ + FILE* file; + char fileName[] = "shitFile"; + + file = fopen(fileName, "w" ); + char prettyString[50]; + + + // Label instruction ***************************************** + glColor3f(0.0, 0.0, 0.0); + + glPushMatrix(); // 1 + glTranslated(3*(float)self->BORDERWIDTH, (float)self->INSTRUCTIONHEIGHT/2.5, 0.0); + + int len, i; + + inst->printPretty(file); + fclose(file); + len = fileToString(fileName, prettyString, 50); + + for (i = 0; i < len; i++) + { + glutStrokeCharacter(self->font, prettyString[i]); + } + glPopMatrix(); // 1 + + + + // Label Outputs ********************************************* + glColor3f(0.5f, 0.2f, 0.4f); + + char registerName[50]; + float distanceBetween; + int vrn, j; + InstructionDefine* curDefine; + + int numberOfOutputs, numberOfInputs; + + numberOfOutputs= inst->getInstructionDefineEnd() - inst->getInstructionDefineBegin();; + assert(numberOfOutputs <= 1); + + distanceBetween = (float)self->INSTRUCTIONWIDTH/(numberOfOutputs+1); + + glPushMatrix(); // 2 + glTranslatef(0.0, 3*(float)self->BORDERWIDTH, 0.0); + + j=1; + for(curDefine = inst->getInstructionDefineBegin(); curDefine < inst->getInstructionDefineEnd(); curDefine++) + { + + glPushMatrix(); // 3 + glTranslatef(j*distanceBetween-100, 0.0, 0.0); + + if(curDefine->kind == udRegister) + { + vrn = (*(curDefine->name.vr)).index; + sprintf(registerName, "R%d", vrn); + } else if (curDefine->kind == udCond) + sprintf(registerName, "Cond"); + else + sprintf(registerName, "Store"); + len = strlen(registerName); + for (i = 0; i < len; i++) + { + glutStrokeCharacter(self->font, registerName[i]); + } + glPopMatrix(); // 3 + j++; + } + + + glPopMatrix(); // 2 + + // Label Inputs ********************************************** + glColor3f(1.0f, 0.0f, 0.2f); + + InstructionUse* curUse; + numberOfInputs = inst->getInstructionUseEnd() - inst->getInstructionUseBegin(); + distanceBetween = (float)self->INSTRUCTIONWIDTH/(numberOfInputs+1); + + glPushMatrix(); // 4 + glTranslatef(0.0, self->INSTRUCTIONHEIGHT - 100 - 3*(float)self->BORDERWIDTH, 0.0); + j=1; + for(curUse = inst->getInstructionUseBegin(); curUse < inst->getInstructionUseEnd(); curUse++) + { + + glPushMatrix(); // 5 + glTranslatef(j*distanceBetween-100, 0.0, 0.0); + + if(curUse->kind == udRegister) + { + vrn = (*(curUse->name.vr)).index; + sprintf(registerName, "R%d", vrn); + } else if (curUse->kind == udCond) + sprintf(registerName, "Cond"); + else + sprintf(registerName, "Store"); + + len = strlen(registerName); + for (i = 0; i < len; i++) + { + glutStrokeCharacter(self->font, registerName[i]); + } + + glPopMatrix(); // 5 + j++; + } + glPopMatrix(); // 4 + + +} + + +/* + Draw a single instruction with its bottom line centered at (xMiddle, yBottom) +*/ +void IGVisualizer :: +DrawNode(double xMiddle, int yBottom, Instruction* inst, Vector& subTrees) +{ + + glPushMatrix(); // 1 + + glTranslatef((float)xMiddle - self->INSTRUCTIONWIDTH/2, (float)yBottom, 0); + + // Draw Instruction body ************************************* + glColor3f(0.0, 1.0, 1.0); + glRecti(0, 0, self->INSTRUCTIONWIDTH, self->INSTRUCTIONHEIGHT); + + glColor3f(1.0, 1.0, 1.0); + glRecti(self->BORDERWIDTH, self->BORDERWIDTH, self->INSTRUCTIONWIDTH-self->BORDERWIDTH, self->INSTRUCTIONHEIGHT-self->BORDERWIDTH); + + + LabelNode(inst); + + // Connect Inputs ************************************************* + TreeLocation* loc; + int numberOfInputs = subTrees.size(); + int distToNextLayer = self->FRAMEHEIGHT - self->INSTRUCTIONHEIGHT; + float jag = ((float)distToNextLayer/(numberOfInputs + 1)); + float diffMid; + float distanceBetween = (float)self->INSTRUCTIONWIDTH/(numberOfInputs+1); + + glPushMatrix(); // 2 + glTranslatef(0.0, (float)self->INSTRUCTIONHEIGHT, 0.0); + + int j=1; + for(loc = subTrees.begin(); loc < subTrees.end(); loc++) + { + + glPushMatrix(); // 3 + glTranslatef(j*distanceBetween, 0.0, 0.0); + + diffMid = loc->rootMiddle - (float)xMiddle - (j*distanceBetween - ((0.5f)*self->INSTRUCTIONWIDTH)); + + glBegin(GL_LINES); + glVertex2f(0.0f, 0.0f); + glVertex2f(0.0f, j*jag); + glVertex2f(0.0f, j*jag); + glVertex2f(diffMid, j*jag); + glVertex2f(diffMid, j*jag); + glVertex2f(diffMid, (numberOfInputs + 1)*jag); + glEnd(); + + glPopMatrix(); // 3 + j++; + } + glPopMatrix(); // 2 + + + glPopMatrix(); // 1 + + + +} + +/* + Draw a node as a subexpression +*/ +void IGVisualizer :: +DrawSubExpressionNode(Instruction* inst, double xMiddle, double yBottom) +{ + glPushMatrix(); // 1 + + glTranslatef((float)xMiddle - self->INSTRUCTIONWIDTH/2, (float)yBottom, 0); + + // Draw Instruction body ************************************* + glColor3f(1.0, 1.0, 0.0); + glRecti(0, 0, self->INSTRUCTIONWIDTH, self->INSTRUCTIONHEIGHT); + + glColor3f(1.0, 1.0, 1.0); + glRecti(self->BORDERWIDTH, self->BORDERWIDTH, self->INSTRUCTIONWIDTH-self->BORDERWIDTH, self->INSTRUCTIONHEIGHT-self->BORDERWIDTH); + + + + // Draw the node + LabelNode(inst); + + glPopMatrix(); // 1 + + +} + + + +/* + Draw a dummy "unknown" instruction with its bottom line centered at (xMiddle, yBottom) +*/ +void IGVisualizer :: +DrawDummyNode(double xMiddle, int yBottom) +{ + char unknownMess[] = " ??? "; + + glPushMatrix(); // 1 + + glTranslatef((float)xMiddle - self->INSTRUCTIONWIDTH/2, (float)yBottom, 0); + + // Draw Instruction body ************************************* + glColor3f(1.0, 0.0, 0.0); + glRecti(0, 0, self->INSTRUCTIONWIDTH, self->INSTRUCTIONHEIGHT); + + glColor3f(1.0, 1.0, 1.0); + glRecti(5 * self->BORDERWIDTH, 5 * self->BORDERWIDTH, self->INSTRUCTIONWIDTH-(5*self->BORDERWIDTH), self->INSTRUCTIONHEIGHT-(5*self->BORDERWIDTH)); + + // Write Message ****************************************** + glColor3f(1.0, 0.0, 0.0); + glPushMatrix(); // 2 + glTranslated(3*(float)self->BORDERWIDTH, (float)self->INSTRUCTIONHEIGHT/2.5, 0.0); + + int len, i; + len = (int) strlen(unknownMess); + for (i = 0; i < len; i++) + { + glutStrokeCharacter(self->font, unknownMess[i]); + } + glPopMatrix(); // 2 + + glPopMatrix(); //1 + +} + + + + +/* + Draw an argument node +*/ +void IGVisualizer :: +DrawArgumentNode(double xMiddle, int yBottom) +{ + char unknownMess[] = " Argument "; + + glPushMatrix(); // 1 + + glTranslatef((float)xMiddle - self->INSTRUCTIONWIDTH/2, (float)yBottom, 0); + + // Draw Instruction body ************************************* + glColor3f(0.0f, 1.0f, 0.3f); + glRecti(0, 0, self->INSTRUCTIONWIDTH, self->INSTRUCTIONHEIGHT); + + glColor3f(1.0f, 1.0f, 1.0f); + glRecti(5 * self->BORDERWIDTH, 5 * self->BORDERWIDTH, self->INSTRUCTIONWIDTH-(5*self->BORDERWIDTH), self->INSTRUCTIONHEIGHT-(5*self->BORDERWIDTH)); + + // Write Message ****************************************** + glColor3f(0.0f, 1.0f, 0.3f); + glPushMatrix(); // 2 + glTranslated(3*(float)self->BORDERWIDTH, (float)self->INSTRUCTIONHEIGHT/2.5, 0.0); + + int len, i; + len = (int) strlen(unknownMess); + for (i = 0; i < len; i++) + { + glutStrokeCharacter(self->font, unknownMess[i]); + } + glPopMatrix(); // 2 + + glPopMatrix(); //1 + +} + + + + + +/* + This is the window system specific stuff for setting up the window for gl. + Visualize is called only once and it enters a non-returning display loop. +*/ + + + +enum subMenuFields +{ + findAsRoot, + findNextRef +}; + +void IGVisualizer :: visualize() +{ + int zoomMenu, rootMenu; + char* argv ="myProgram"; + int argc = 1; + + // Initialization + glutInit(&argc, &argv); + glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB); + glutInitWindowSize(xWindowDim, yWindowDim); + glutCreateWindow("Instruction Graph Viewer Dulux"); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluOrtho2D(-xDimGL, xDimGL, -yDimGL, yDimGL); + + glMatrixMode(GL_MODELVIEW); + glEnable(GL_LINE_SMOOTH); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glLineWidth(1.0); + + glClearColor(0.0f, 0.0f, 0.0f, 1.0f); + glColor3f(1.0f, 1.0f, 1.0f); + + // Add callbacks + glutDisplayFunc(display); + glutMouseFunc(mouse); + glutKeyboardFunc(keyboard); + glutReshapeFunc(reshape); + + // Create the menu + zoomMenu = glutCreateMenu(selectZoom); + glutAddMenuEntry("X 2", 2); + glutAddMenuEntry("X 5", 5); + rootMenu = glutCreateMenu(selectRoot); + glutAddMenuEntry("Goto Definition", findAsRoot); + glutAddMenuEntry("Goto Next Reference", findNextRef); + glutCreateMenu(mainMenu); + glutAddSubMenu("ZoomFactor", zoomMenu); + glutAddSubMenu("Explore Subexpression", rootMenu); + glutAddMenuEntry("Exit", 0); + glutAttachMenu(GLUT_RIGHT_BUTTON); + + glutMainLoop(); +} + + +/* + The callback routines +*/ + +void IGVisualizer :: +display() +{ + glClear(GL_COLOR_BUFFER_BIT); + + glPushMatrix(); // 1 + glScaled(self->cumZoom, self->cumZoom, 1); + glTranslated(self->centerX - self->objectCenterX + self->mouseCenterX, self->centerY - self->objectCenterY + self->mouseCenterY, 0); + + visualizeRoots(); + + glPopMatrix(); // 1 + + glutSwapBuffers(); +} + +void IGVisualizer :: +selectZoom(int msg) +{ + self->zoomFactor = float(msg); + glutPostRedisplay(); +} + + +void IGVisualizer :: +selectRoot(int msg) +{ + VisualInstructionRoot* vRoot = findRootAtLoc(self->nodeLocX, self->nodeLocY); + if(vRoot != NULL) + { + //printf("FOUND ONE\n"); + switch(msg) { + case findAsRoot: + self->objectCenterX = vRoot->locAsRoot->rootMiddle; + self->objectCenterY = vRoot->locAsRoot->bottom; + self->mouseCenterX = 0; + self->mouseCenterY = 0; + break; + case findNextRef: + if(vRoot->currentCSE == NULL) + if(vRoot->locAsCSE->size() != 0) + vRoot->currentCSE = vRoot->locAsCSE->begin(); + else + return; + else { + vRoot->currentCSE++; + if(vRoot->currentCSE == vRoot->locAsCSE->end()) + vRoot->currentCSE = vRoot->locAsCSE->begin(); + } + self->objectCenterX = vRoot->currentCSE->rootMiddle; + self->objectCenterY = vRoot->currentCSE->bottom; + self->mouseCenterX = 0; + self->mouseCenterY = 0; + break; + } + + + } + glutPostRedisplay(); +} + + +VisualInstructionRoot* IGVisualizer :: +findRootAtLoc(double x, double y) +{ + + VisualInstructionRoot* vRoot; + TreeLocation* tree; + for(vRoot = self->roots->begin(); vRoot < self->roots->end(); vRoot++) + { + if(isInNode(x, y, vRoot->locAsRoot->rootMiddle, vRoot->locAsRoot->bottom)) + return vRoot; + for(tree = vRoot->locAsCSE->begin(); tree < vRoot->locAsCSE->end(); tree++) + if(isInNode(x, y, tree->rootMiddle, tree->bottom)) + return vRoot; + } + + return NULL; +} + +bool IGVisualizer :: +isInNode(double x, double y, double middle, int bottom) +{ + if((x < (middle + (.5*self->INSTRUCTIONWIDTH))) && (x > (middle - (.5*self->INSTRUCTIONWIDTH)))) + if((y > bottom) && (y < (bottom + self->INSTRUCTIONHEIGHT))) + return true; + return false; +} + + + + +void IGVisualizer :: +mainMenu(int msg) +{ + switch(msg) { + case 0: + exit(0); + break; + } + + glutPostRedisplay(); +} + +void IGVisualizer :: +mouse(int button, int state, int x, int y) +{ + + if(button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) + { + double transX = -(x - (.5 * (self->xWindowDim)))*((2*self->xDimGL/self->xWindowDim)/self->cumZoom); + double transY = (y - (.5 * (self->yWindowDim)))*((2*self->yDimGL/self->yWindowDim)/self->cumZoom); + self->mouseCenterX = self->mouseCenterX + transX; + self->mouseCenterY = self->mouseCenterY + transY; + } + + glutPostRedisplay(); +} + +void IGVisualizer :: +keyboard(unsigned char key, int x, int y) +{ + switch(key){ + case '+': + self->cumZoom = self->cumZoom * self->zoomFactor; + break; + case '-': + self->cumZoom = self->cumZoom / self->zoomFactor; + break; + case 's': + double transX = (x - (.5 * (self->xWindowDim)))*((2*self->xDimGL/self->xWindowDim)/self->cumZoom); + double transY = -(y - (.5 * (self->yWindowDim)))*((2*self->yDimGL/self->yWindowDim)/self->cumZoom); + + //printf("mouse center**%f, %f**\n", self->mouseCenterX, self->mouseCenterY); + //printf("strans **%f, %f**\n", transX, transY); + //printf("obj center **%f, %f**\n", self->objectCenterX, self->objectCenterY); + + self->nodeLocX = transX - self->mouseCenterX + self->objectCenterX; + self->nodeLocY = transY - self->mouseCenterY + self->objectCenterY; + + //printf("node center **%f, %f**\n", self->nodeLocX, self->nodeLocY); + break; + } + glutPostRedisplay(); +} + +void IGVisualizer :: +reshape(int width, int height) +{ + self->xWindowDim = width; + self->yWindowDim = height; + + glViewport(0, 0, width, height); + glutPostRedisplay(); +} + +#endif diff --git a/ef/Compiler/CodeGenerator/IGVisualizer.h b/ef/Compiler/CodeGenerator/IGVisualizer.h new file mode 100644 index 000000000000..2ca87c4d962d --- /dev/null +++ b/ef/Compiler/CodeGenerator/IGVisualizer.h @@ -0,0 +1,106 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +/* + The instruction graph visulizer. + IGVisualizer.h + + Peter DeSantis +*/ + +#ifndef IGVISUALIZER +#define IGVISUALIZER +#if defined(DEBUG) && (defined(WIN32) || defined(USE_MESA)) && defined(IGVISUALIZE) + +#include "CodeGenerator.h" +class Instruction; +class Vector; + +struct TreeLocation +{ + float rootMiddle; + int right; + int top; + int bottom; +}; + +struct VisualInstructionRoot +{ + Instruction* root; + bool exploringAsRoot; + Vector* locAsCSE; + TreeLocation* currentCSE; + TreeLocation* locAsRoot; +}; + +class IGVisualizer +{ + +private: + void *font; + float zoomFactor; + double cumZoom; + double centerX, centerY; + double objectCenterX, objectCenterY; + double mouseCenterX, mouseCenterY; + double xDimGL, yDimGL; + double nodeLocX, nodeLocY; + + + int xWindowDim, yWindowDim; + + int INSTRUCTIONWIDTH, INSTRUCTIONHEIGHT; + int FRAMEWIDTH, FRAMEHEIGHT; + + int SPACEBETWEENTREES; + int BORDERWIDTH; + uint ARGUMENTREGISTERS; + static IGVisualizer* self; + + Vector* roots; + + static void visualizeRoots(); + static TreeLocation& DrawTree(Instruction& root, int yBottom, int xLeft); + static void DrawNode(double xMiddle, int yBottom, Instruction* inst, Vector& subTrees); + static void DrawDummyNode(double xMiddle, int yBottom); + static void DrawArgumentNode(double xMiddle, int yBottom); + static VisualInstructionRoot* isInRoots(Instruction* root); + static void DrawSubExpressionNode(Instruction* inst, double xMIddle, double yBottom); + static void LabelNode(Instruction* inst); + static VisualInstructionRoot* findRootAtLoc(double x, double y); + static bool isInNode(double x, double y, double middle, int bottom); + +public: + static void selectZoom(int msg); + static void selectRoot(int msg); + static void mainMenu(int msg); + static void mouse(int button, int state, int x, int y); + static void keyboard(unsigned char key, int x, int y); + static void reshape(int width, int height); + static void tick(void); + static void display(); + + void addRoots(Vector& roots); + void visualize(); + IGVisualizer(); + ~IGVisualizer(); + +}; + + +#endif //#if defined(DEBUG) && defined(WIN32) && defined(IGVISUALIZE) +#endif // IGVISUALIZER diff --git a/ef/Compiler/CodeGenerator/Instruction.cpp b/ef/Compiler/CodeGenerator/Instruction.cpp new file mode 100644 index 000000000000..5f058536bfef --- /dev/null +++ b/ef/Compiler/CodeGenerator/Instruction.cpp @@ -0,0 +1,316 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +/* + Instruction.cpp + + Scott M. Silver +*/ + +#include "Instruction.h" +#include "Pool.h" +#include "InstructionEmitter.h" + + +Instruction:: +Instruction(DataNode* inSrcPrimitive) +{ + //DEBUG_ONLY(initialize()); + DEBUG_ONLY(mDebug = 0xDEADBEEF); + mSrcPrimitive = inSrcPrimitive; +} + + + +// unlinkRegisters +// +// remove all references to VirtualRegister +// for this Instruction. +void Instruction:: +unlinkRegisters() +{ + InstructionUse* use_limit = getInstructionUseEnd(); + for(InstructionUse* use_ptr = getInstructionUseBegin(); use_ptr < use_limit; use_ptr++) + if (use_ptr->kind == udRegister) + use_ptr->name.vr.uninitialize(); + + InstructionDefine* def_limit = getInstructionDefineEnd(); + for(InstructionDefine* def_ptr = getInstructionDefineBegin(); def_ptr < def_limit; def_ptr++) + if (def_ptr->kind == udRegister) + def_ptr->name.vr.uninitialize(); +} + +//#ifdef DEBUG +void Instruction:: +initialize() +{ + // clear out use's + InstructionUse* curUse; + + for ( curUse = getInstructionUseBegin(); + curUse < getInstructionUseEnd(); + curUse++) + { + curUse[0].name.dp = NULL; + curUse[0].src = NULL; + curUse[0].kind = udUninitialized; + } + + InstructionDefine* curDefine; + + for ( curDefine = getInstructionDefineBegin(); + curDefine < getInstructionDefineEnd(); + curDefine++) + { + curDefine[0].name.dp = NULL; + curDefine[0].kind = udUninitialized; + } +} +//#endif + + +// addUse +// +// +void Instruction:: +addUse(Uint8 inWhichInput, VirtualRegister& inVR, VirtualRegisterKind constraint) +{ + InstructionUse* instructionUseBegin = getInstructionUseBegin(); + + assert(instructionUseBegin != NULL && getInstructionUseEnd() - inWhichInput > instructionUseBegin); + + instructionUseBegin[inWhichInput].name.vr.initialize(inVR, constraint); + instructionUseBegin[inWhichInput].src = inVR.getDefiningInstruction(); + instructionUseBegin[inWhichInput].kind = udRegister; +} + + +void Instruction:: +addUse(Uint8 inWhichInput, DataNode& inProducer) +{ + InstructionUse* instructionUseBegin = getInstructionUseBegin(); + + assert(instructionUseBegin != NULL && getInstructionUseEnd() - inWhichInput > instructionUseBegin); + assert(inProducer.hasKind(vkCond) || inProducer.hasKind(vkMemory)); + + instructionUseBegin[inWhichInput].name.dp = &inProducer; + + if (inProducer.hasKind(vkCond)) + instructionUseBegin[inWhichInput].kind = udCond; + else + instructionUseBegin[inWhichInput].kind = udStore; +} + + +void Instruction:: +addUse(Uint8 inWhichInput, UseDefineKind inKind) +{ + InstructionUse* instructionUseBegin = getInstructionUseBegin(); + + assert(instructionUseBegin != NULL && getInstructionUseEnd() - inWhichInput > instructionUseBegin); + + instructionUseBegin[inWhichInput].name.dp = NULL; + instructionUseBegin[inWhichInput].kind = inKind; +} + + +void Instruction:: +addUse(Uint8 inWhichInput, InstructionDefine& inUseOrder) +{ + InstructionUse* instructionUseBegin = getInstructionUseBegin(); + + assert(instructionUseBegin != NULL && getInstructionUseEnd() - inWhichInput > instructionUseBegin); + + instructionUseBegin[inWhichInput].name.instruction = inUseOrder.name.instruction; + instructionUseBegin[inWhichInput].kind = udOrder; +} + + +void Instruction:: +addDefine( Uint8 inWhichOutput, VirtualRegister& inVR, VirtualRegisterKind constraint) +{ + InstructionDefine* instructionDefineBegin = getInstructionDefineBegin(); + + assert(instructionDefineBegin != NULL && getInstructionDefineEnd() - inWhichOutput > instructionDefineBegin); + + instructionDefineBegin[inWhichOutput].name.vr.initialize(inVR, constraint); + instructionDefineBegin[inWhichOutput].kind = udRegister; +} + + +void Instruction:: +addDefine(Uint8 inWhichOutput, DataNode& inProducer) +{ + InstructionDefine* instructionDefineBegin = getInstructionDefineBegin(); + + assert(instructionDefineBegin != NULL && getInstructionDefineEnd() - inWhichOutput > instructionDefineBegin); + assert(inProducer.hasKind(vkCond) || inProducer.hasKind(vkMemory)); + + if (inProducer.hasKind(vkCond)) + instructionDefineBegin[inWhichOutput].kind = udCond; + else + instructionDefineBegin[inWhichOutput].kind = udStore; +} + + +void Instruction:: +addDefine(Uint8 inWhichOutput, UseDefineKind inKind) +{ + InstructionDefine* instructionDefineBegin = getInstructionDefineBegin(); + + assert(instructionDefineBegin != NULL && getInstructionDefineEnd() - inWhichOutput > instructionDefineBegin); + + instructionDefineBegin[inWhichOutput].name.dp = NULL; + instructionDefineBegin[inWhichOutput].kind = inKind; +} + + +void Instruction:: +addDefine(Uint8 inWhichOutput, InstructionDefine& /*inDefineOrder*/) +{ + InstructionDefine* instructionDefineBegin = getInstructionDefineBegin(); + + assert(instructionDefineBegin != NULL && getInstructionDefineEnd() - inWhichOutput > instructionDefineBegin); + + //instructionDefineBegin[inWhichOutput].name.instruction = this; + instructionDefineBegin[inWhichOutput].kind = udOrder; +} + +void Instruction:: +standardUseDefine(InstructionEmitter& inEmitter) +{ + InstructionUse* instructionUseBegin = getInstructionUseBegin(); + Uint8 curIndex; + + standardDefine(inEmitter); + + InstructionUse* curUse; + + if (instructionUseBegin != NULL) + { + for (curUse = instructionUseBegin, curIndex = 0; curUse < getInstructionUseEnd(); curUse++, curIndex++) + { + addStandardUse(inEmitter, curIndex); + } + } +} + + +VirtualRegister* Instruction:: +addStandardUse(InstructionEmitter& inEmitter, Uint8 curIndex) +{ + assert (mSrcPrimitive != NULL); + return inEmitter.useProducer(mSrcPrimitive->nthInputVariable(curIndex), *this, curIndex); +} + +void Instruction:: +standardDefine(InstructionEmitter& inEmitter) +{ + InstructionDefine* instructionDefineBegin = getInstructionDefineBegin(); + Uint8 curIndex; + + assert (mSrcPrimitive != NULL); + + if (instructionDefineBegin != NULL) + { + InstructionDefine* curDefine; + + for (curDefine = instructionDefineBegin, curIndex = 0; curDefine < getInstructionDefineEnd(); curDefine++, curIndex++) + { + assert(curIndex == 0); + inEmitter.defineProducer(*mSrcPrimitive, *this, curIndex); + //inEmitter.defineProducer(nthOutputProducer(*mSrcPrimitive, curIndex), *this, curIndex); + } + } + else + { + mSrcPrimitive->setInstructionRoot(this); + } +} + +#ifdef DEBUG_LOG +void Instruction:: +printDebug(LogModuleObject &f) +{ + printPretty(f); + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("\n")); + // clear out use's + InstructionUse* curUse; + int i; + + i=0; + for ( curUse = getInstructionUseBegin(); + curUse < getInstructionUseEnd(); + curUse++) + { + switch (curUse[0].kind) + { + case udRegister: + { + VirtualRegister& vReg = curUse[0].getVirtualRegister();\ + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("u[%d]: %scolor = %d index = %d \n", i, vReg.isPreColored() ? "pre" : "", vReg.isPreColored() ? + vReg.getPreColor() : vReg.getColor(), vReg.getRegisterIndex())); + } + break; + default: + break; + } + i++; + } + + InstructionDefine* curDefine; + + i=0; + for ( curDefine = getInstructionDefineBegin(); + curDefine < getInstructionDefineEnd(); + curDefine++) + { + switch (curDefine[0].kind) + { + case udRegister: + { + VirtualRegister& vReg = curDefine[0].getVirtualRegister(); + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("d[%d]: %scolor = %d index = %d\n", i, vReg.isPreColored() ? "pre" : "", + vReg.isPreColored() ? vReg.getPreColor() : vReg.getColor(), vReg.getRegisterIndex())); + } + break; + default: + break; + } + i++; + } +} +#endif + +InsnUseXDefineYFromPool:: +InsnUseXDefineYFromPool(DataNode* inSrcPrimitive, Pool& inPool, Uint8 inX, Uint8 inY) : + Instruction(inSrcPrimitive) +{ + mX = inX; + mY = inY; + if (inX > 0) + mInsnUse = new(inPool) InstructionUse[inX]; + else + mInsnUse = NULL; + + if (inY > 0) + mDefineResource = new(inPool) InstructionDefine[inY]; + else + mDefineResource = NULL; + + initialize(); +} diff --git a/ef/Compiler/CodeGenerator/Instruction.h b/ef/Compiler/CodeGenerator/Instruction.h new file mode 100644 index 000000000000..9468c2aa4e44 --- /dev/null +++ b/ef/Compiler/CodeGenerator/Instruction.h @@ -0,0 +1,272 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +// +// Instruction.h +// +// Scott M. Silver +// Peter Desantis +// Laurent Morichetti +// +// Interface for schedulable and formattable instructions. + +// Summary +// +// Instructions are medium weight representations of actual native instructions +// on a machine. They are manipulated for register allocation, scheduling +// and eventually to output themselves to memory. +// +// The ideas is that subclasses of Instruction (or one of the "helper" subclasses) +// are the basic unit of "cross-platform" manipulation. They contain +// all resources consumed or created (ie registers, memory, etc). +// +// Each instruction must implement a series of "interface" methods which +// are essentially queries, so that subsequent users of Instructions can +// make intelligent decision. (eg. whether an instruction is a call, so +// the register allocator can save non-volatiles) + +#ifndef INSTRUCTION_H +#define INSTRUCTION_H + +#include "prtypes.h" +#include "Primitives.h" +#include "CpuInfo.h" + +class Instruction; +class VirtualRegister; +class InstructionEmitter; + +#ifdef __MWERKS__ +#pragma mark - +#pragma mark ¥ÊInstructionUse/Define ¥ +#endif + +// InstructionUseOrDefine is a class which represents the +// use or definition of a resource (either a store, cond, or +// register resource). Assigned to each use and define +// is a ResourceName which is the "name" of the resource +// being use, eg a virtual register. In addition InstructionUse's +// (not defines) contain (if available) the definer of the resource +// they are using. This is so that resources can be defined multiple +// times, but (data) dependencies remain accurate. +typedef enum +{ + udNone = 0, + udUninitialized, + udStore, + udCond, + udOrder, + udRegister +} UseDefineKind; + +struct ResourceName +{ + VirtualRegisterPtr vr; + DataNode* dp; + Instruction* instruction; +}; + +struct InstructionUseOrDefine +{ + UseDefineKind kind; + ResourceName name; + + inline PRUint32 getRegisterIndex() { assert(isVirtualRegister()); return getVirtualRegister().getRegisterIndex(); } + inline VirtualRegister& getVirtualRegister() { assert(isVirtualRegister()); return (name.vr.getVirtualRegister()); } + inline VirtualRegisterPtr& getVirtualRegisterPtr() { assert(isVirtualRegister()); return (name.vr); } + inline bool isVirtualRegister() { return (kind >= udRegister); } +}; + +struct InstructionUse : InstructionUseOrDefine +{ + Instruction* src; + + Instruction& getDefiningInstruction() { return (*src); } + void setDefiningInstruction(Instruction& inInstruction) { src = &inInstruction; } +}; + +struct InstructionDefine : InstructionUseOrDefine +{ +}; + +#ifdef __MWERKS__ +#pragma mark - +#pragma mark ¥ÊInstructionFlags ¥ +#endif + +// This is a bitmap of interesting things an instruction might do +typedef Uint16 InstructionFlags; +enum +{ + ifNone = 0x0000, // default + ifModCC = 0x0001, // defines a condition edge (eg. cmp) + ifModStore = 0x0002, // modifies the store (eg. st) + ifCopy = 0x0004, // copies its uses to its defines (eg mov) + ifExternalInsn = 0x0008, // used by the register allocator to keep track of uses/defines outside of a function + ifCall = 0x0010, // makes a call - indicates that non-volatile registers should be saved before this instruction (eg call) + ifSpecialCall = 0x0020 // FIX-ME Laurent!!! If you ad a new flag please document it!!! +}; + +#ifdef __MWERKS__ +#pragma mark - +#pragma mark ¥ÊInstruction ¥ +#endif + +class Instruction : + public DoublyLinkedEntry // Inserted into a list of scheduled instructions +{ +public: + Instruction(DataNode* inSrcPrimitive); + + void addUse(Uint8 inWhichInput, VirtualRegister& inVR, VRClass cl = vrcInteger); + void addUse(Uint8 inWhichInput, DataNode& inProducer); + void addUse(Uint8 inWhichInput, UseDefineKind inKind); + void addUse(Uint8 inWhichInput, InstructionDefine& inUseOrder); + + void addDefine(Uint8 inWhichOutput, DataNode& inProducer); + void addDefine(Uint8 inWhichOutput, VirtualRegister& inProducer, VRClass cl = vrcInteger); + void addDefine(Uint8 inWhichOutput, UseDefineKind inKind); + void addDefine(Uint8 inWhichOutput, InstructionDefine& inDefineOrder); + + virtual InstructionUse* getInstructionUseBegin() = 0; + virtual InstructionUse* getInstructionUseEnd() = 0; + + virtual InstructionDefine* getInstructionDefineBegin() = 0; + virtual InstructionDefine* getInstructionDefineEnd() = 0; + + void standardUseDefine(InstructionEmitter& inEmitter); + + virtual PRUint32* getExtraRegisterInterferenceBegin() { return NULL; } // what?? laurent-try again. other registers defined by this instruction. + virtual PRUint32* getExtraRegisterInterferenceEnd() { return NULL; } + + inline const Uint16 getLineNumber() const { return (mSrcPrimitive->getLineNumber()); } + inline DataNode* getPrimitive() const { return( mSrcPrimitive); } + virtual InstructionFlags getFlags() const { return (ifNone); } + + virtual size_t getFormattedSize(MdFormatter& /*inFormatter*/) { return (0); } + virtual void formatToMemory(void * /*inStart*/, Uint32 /*inCurOffset*/, MdFormatter& /*inFormatter*/) { } + + virtual bool switchUseToSpill(Uint8 /*inWhichUse*/, VirtualRegister& /*inVR*/) { return false; } + virtual bool switchDefineToSpill(Uint8 /*inWhichDefine*/, VirtualRegister& /*inVR*/) { return false; } + + void unlinkRegisters(); // uninitialize the VirtualRegisterPtr for each use and define + virtual bool canSwitchToFormat(Uint32 /*mask*/) { return false; } + virtual void switchToFormat(Uint32 /*mask*/) {} + +protected: + void standardDefine(InstructionEmitter& inEmitter); + VirtualRegister* addStandardUse(InstructionEmitter& inEmitter, Uint8 curIndex); + +protected: + void initialize(); + +public: +#ifdef DEBUG_LOG + virtual void printPretty(LogModuleObject &f) { UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("none")); } + virtual void printDebug(LogModuleObject &f); +#endif +#ifdef DEBUG + int mDebug; +#endif + +#ifdef DEBUG // added by simon, FIX should remove + virtual void checkIntegrity() { }; + virtual void printArgs() { }; +#endif // DEBUG + + +protected: + DataNode* mSrcPrimitive; // the primitive from which this Instruction was generated +}; + +typedef DoublyLinkedList InstructionList; + + +// Comparator function for SortedDoublyLinkedList. To get the desired effects, we want to comparison function to +// return 1 if instruction a is of a great or equal line number then b. (ensures that later scheduled +// instructions of the same lineNumber end up later in the list. Also if the two instructions are the +// same, we want to return a 0. (Avoids duplicate scheduling)/ +inline int instructionCompare(const Instruction* a, const Instruction* b) +{ + assert(a != NULL && b != NULL); + + if(a->getLineNumber() < b->getLineNumber()) + return -1; + if(a == b) + return 0; + return 1; +} + +class Pool; + +class InsnUseXDefineYFromPool : + public Instruction +{ +public: + InsnUseXDefineYFromPool(DataNode* inSrcPrimitive, Pool& inPool, Uint8 inX, Uint8 inY); + + virtual InstructionUse* getInstructionUseBegin() { return (mInsnUse); } + virtual InstructionUse* getInstructionUseEnd() { return (&mInsnUse[0] + mX); } + virtual InstructionDefine* getInstructionDefineBegin() { return (mDefineResource); } + virtual InstructionDefine* getInstructionDefineEnd() { return (&mDefineResource[0] + mY); } + +protected: + + Uint8 mX; + Uint8 mY; + InstructionUse* mInsnUse; + InstructionDefine* mDefineResource; +}; + +#ifdef __MWERKS__ +#pragma mark - +#pragma mark ¥ÊInsnExternalUse/Define ¥ +#endif + +class InsnExternalUse : public InsnUseXDefineYFromPool +{ +protected: + InstructionUse externalUse; + +public: + InsnExternalUse(DataNode* inSrcPrimitive, Pool& inPool, Uint8 inUse) : + InsnUseXDefineYFromPool(inSrcPrimitive, inPool, inUse, 0) {} + + virtual InstructionFlags getFlags() const { return (ifExternalInsn); } + +#ifdef DEBUG_LOG + virtual void printPretty(LogModuleObject &f) { UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("(external use)")); } +#endif +}; + +class InsnExternalDefine : public InsnUseXDefineYFromPool +{ +protected: + InstructionDefine externalDef; + +public: + InsnExternalDefine(DataNode* inSrcPrimitive, Pool& inPool, Uint8 inDefine) : + InsnUseXDefineYFromPool(inSrcPrimitive, inPool, 0, inDefine) {} + + virtual InstructionFlags getFlags() const { return (ifExternalInsn); } + +#ifdef DEBUG_LOG + virtual void printPretty(LogModuleObject &f) { UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("(external def)")); } +#endif +}; + +#endif // INSTRUCTION_H diff --git a/ef/Compiler/CodeGenerator/InstructionEmitter.cpp b/ef/Compiler/CodeGenerator/InstructionEmitter.cpp new file mode 100644 index 000000000000..b300fced2b87 --- /dev/null +++ b/ef/Compiler/CodeGenerator/InstructionEmitter.cpp @@ -0,0 +1,258 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +// InstructionEmitter.cp +// +// Scott M. Silver +// + +#include "InstructionEmitter.h" +#include "Primitives.h" +#include "Instruction.h" +#include "ControlNodes.h" + +// define a temporary platform specific register +VirtualRegister& InstructionEmitter:: +defineTemporary(Instruction& inDefineInsn, Uint8 inWhichOutput, VirtualRegisterKind constraint) +{ + // newRegister stores inDefineInsn in the vr + VirtualRegister& vr = mVRAllocator.newVirtualRegister(constraint); + + vr.setDefiningInstruction(inDefineInsn); + + // make this instruction's output this register + inDefineInsn.addDefine(inWhichOutput, vr, constraint); + + return vr; +} + +// reuse register, basically update who defines this register +// and note that the passed in instruction redefines it +VirtualRegister& InstructionEmitter:: +redefineTemporary(Instruction& inDefineInsn, VirtualRegister& inReuseRegister, Uint8 inWhichOutput, VirtualRegisterKind constraint) +{ + inReuseRegister.setDefiningInstruction(inDefineInsn); + + inDefineInsn.addDefine(inWhichOutput, inReuseRegister, constraint); + + return (inReuseRegister); +} + +InstructionDefine& InstructionEmitter:: +defineTemporaryOrder(Instruction& inDefineInsn, Uint8 inWhichOutput) +{ + InstructionDefine& newOrder = *new(mPool) InstructionDefine(); + newOrder.name.instruction = &inDefineInsn; + + inDefineInsn.addDefine(inWhichOutput, newOrder); + + return (newOrder); +} + +InstructionDefine& InstructionEmitter:: +redefineTemporaryOrder(Instruction& inDefineInsn, InstructionDefine& inReuseOrder, Uint8 inWhichOutput) +{ + inReuseOrder.name.instruction = &inDefineInsn; + + inDefineInsn.addDefine(inWhichOutput, inReuseOrder); + + return (inReuseOrder); +} + +void InstructionEmitter:: +useTemporaryOrder(Instruction& inDefineInsn, InstructionDefine& inOrder, Uint8 inWhichInput) +{ + inDefineInsn.addUse(inWhichInput, inOrder); +} + + + +// inID is used to indicate which of the two assigned registers to a producer +// you wish to use, eg for 32 bit types, etc +VirtualRegister* InstructionEmitter:: +defineProducer(DataNode& inProducer, Instruction& inDefineInsn, Uint8 inWhichOutput, VirtualRegisterKind constraint, VirtualRegisterID inID) +{ + return defineProducerInternal(inProducer, &inDefineInsn, inWhichOutput, NULL, constraint, inID); +} + +void InstructionEmitter:: +defineProducerWithExistingVirtualRegister(VirtualRegister& inVr, DataNode& inProducer, Instruction& inDefineInsn, Uint8 inWhichOutput, VirtualRegisterKind constraint) +{ + defineProducerInternal(inProducer, &inDefineInsn, inWhichOutput, &inVr, constraint, vidLow); +} + +inline VirtualRegister* +getVirtualRegisterAnnotationByID(DataNode& inDataNode, VirtualRegisterID inID) +{ + if (inID == vidLow) + return (inDataNode.getLowVirtualRegisterAnnotation()); + else if (inID == vidHigh) + return (inDataNode.getHighVirtualRegisterAnnotation()); + else + { + assert(false); + return (NULL); + } +} + + +// inDefineInsn default to NULL +// inWhichOutput default to 0xFF +VirtualRegister* InstructionEmitter:: +defineProducerInternal(DataNode& inProducer, Instruction* inDefineInsn, Uint8 inWhichOutput, VirtualRegister* inVr, VirtualRegisterKind constraint, VirtualRegisterID inID) +{ + bool reallyDefiningProducer; + + reallyDefiningProducer = (inDefineInsn != NULL); + + switch (inProducer.getKind()) + { + default: + assert(false); + break; + case vkCond: + // fix-me should we set the fact that this instruction + // touches a condition code here? + if (reallyDefiningProducer) + { + inProducer.annotate(*inDefineInsn); + inDefineInsn->addDefine(inWhichOutput, inProducer); + return (NULL); + } + break; + case vkMemory: + if (reallyDefiningProducer) + { + inProducer.annotate(*inDefineInsn); + inDefineInsn->addDefine(inWhichOutput, inProducer); + return (NULL); + } + break; + case vkDouble: + case vkInt: + case vkFloat: + case vkAddr: + assert(inID == vidLow); + case vkLong: + { + VirtualRegister* vr; + + // check to see if a VR was assigned to inProducer + if (getVirtualRegisterAnnotationByID(inProducer, inID) == NULL) + { + // allocate a new VR + if (inVr == NULL) + vr = &mVRAllocator.newVirtualRegister(constraint); + else + vr = inVr; + + vr->setDefiningInstruction(*inDefineInsn); + + + // attach to inProducer + if (inID == vidLow) + inProducer.annotateLow(*vr, constraint); + else if (inID == vidHigh) + inProducer.annotateHigh(*vr, constraint); + else + assert(false); + } + else + { + // there is already a VR attached to this producer + // make sure user did not try to specify a VR, this is + // programmer error + assert(inVr == NULL); + + vr = getVirtualRegisterAnnotationByID(inProducer, inID); + + vr->setDefiningInstruction(*inDefineInsn); + } + + if (reallyDefiningProducer) + { + inDefineInsn->addDefine(inWhichOutput, *vr, constraint); + vr->setClass(constraint); + } + + return (vr); + } + break; + } + + // NEVER REACHED + return (NULL); +} + + +VirtualRegister* InstructionEmitter:: +useProducer(DataNode& inProducer, Instruction& inUseInstruction, Uint8 inWhichInput, VirtualRegisterKind constraint, VirtualRegisterID inID) +{ + // find out if there is a register assigned to this {producer, id} + // fix-me check cast + switch (inProducer.getKind()) + { + default: + assert(false); + break; + case vkCond: + inUseInstruction.addUse(inWhichInput, inProducer); + break; + case vkMemory: + // now mark our dependence on VR + inUseInstruction.addUse(inWhichInput, inProducer); + break; + case vkDouble: + case vkInt: + case vkFloat: + case vkLong: + case vkAddr: + VirtualRegister* vr; + + // make sure there is a register assigned to this already + // if not assign a new one with a NULL defining instruction + if (getVirtualRegisterAnnotationByID(inProducer, inID) == NULL) + vr = defineProducerInternal(inProducer, NULL, 0, NULL, constraint, inID); // define NULL instruction for this producer + else + vr = getVirtualRegisterAnnotationByID(inProducer, inID); + + // now mark our dependence on VR + inUseInstruction.addUse(inWhichInput, *vr, constraint); + return vr; + } + return NULL; +} + +void InstructionEmitter:: +useTemporaryVR(Instruction& inInstruction, VirtualRegister& inVR, Uint8 inWhichInput, VirtualRegisterKind constraint) +{ + inInstruction.addUse(inWhichInput, inVR, constraint); +} + +Instruction& InstructionEmitter:: +pushAbsoluteBranch(ControlNode& inSrc, ControlNode& inTarget) +{ + InstructionList& instructions = inSrc.getInstructions(); + + Instruction& branchInsn = emitAbsoluteBranch(*(instructions.get(instructions.end())).getPrimitive(), inTarget); + + instructions.addLast(branchInsn); + + return (branchInsn); +} + + diff --git a/ef/Compiler/CodeGenerator/InstructionEmitter.h b/ef/Compiler/CodeGenerator/InstructionEmitter.h new file mode 100644 index 000000000000..5e9a4bb898a4 --- /dev/null +++ b/ef/Compiler/CodeGenerator/InstructionEmitter.h @@ -0,0 +1,71 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +/* + InstructionEmitter.h + + Scott M. Silver +*/ + +#ifndef _H_INSTRUCTIONEMITTER_ +#define _H_INSTRUCTIONEMITTER_ + +#include "Instruction.h" +#include "VirtualRegister.h" +#include "Primitives.h" +#include "Value.h" + +class Pool; +struct InstructionDefine; + +typedef uint16 NamedRule; + +enum VirtualRegisterID { vidLow, vidHigh }; + +class InstructionEmitter +{ +public: + InstructionEmitter(Pool& inPool, VirtualRegisterManager& vrMan) : + mPool(inPool), + mVRAllocator(vrMan) { } + + VirtualRegister& defineTemporary(Instruction& inDefineInsn, Uint8 inWhichOutput, VirtualRegisterKind constraint = IntegerRegister); + VirtualRegister& redefineTemporary(Instruction& inDefineInsn, VirtualRegister& inReuseRegister, Uint8 inWhichOutput, VirtualRegisterKind constraint = IntegerRegister); + void useTemporaryVR(Instruction& inInstruction, VirtualRegister& inVR, uint8 inWhichInput, VirtualRegisterKind constraint = IntegerRegister); + + InstructionDefine& defineTemporaryOrder(Instruction& inDefineInsn, Uint8 inWhichOutput); + InstructionDefine& redefineTemporaryOrder(Instruction& inDefineInsn, InstructionDefine& inReuseOrder, Uint8 inWhichOutput); + void useTemporaryOrder(Instruction& inDefineInsn, InstructionDefine& inOrder, Uint8 inWhichInput); + + VirtualRegister* defineProducer(DataNode& inProducer, Instruction& inDefineInsn, Uint8 inWhichOutput, VirtualRegisterKind constraint = IntegerRegister, VirtualRegisterID inID = vidLow); + void defineProducerWithExistingVirtualRegister(VirtualRegister& inVr, DataNode& inProducer, Instruction& inDefineInsn, Uint8 inWhichOutput, VirtualRegisterKind constraint = IntegerRegister); + VirtualRegister* useProducer(DataNode& inProducer, Instruction& inUseInstruction, Uint8 inWhichInput, VirtualRegisterKind constraint = IntegerRegister, VirtualRegisterID inID = vidLow); + Instruction& pushAbsoluteBranch(ControlNode& inSrc, ControlNode& inTarget); + + +private: + VirtualRegister* defineProducerInternal(DataNode& inProducer, Instruction* inDefineInsn = NULL, uint8 inWhichOutput = 0, VirtualRegister* inVr = NULL, VirtualRegisterKind constraint = IntegerRegister, VirtualRegisterID inID = vidLow); + + virtual Instruction& emitAbsoluteBranch(DataNode& inDataNode, ControlNode& inTarget) = 0; + +protected: + Pool& mPool; + +public: + VirtualRegisterManager& mVRAllocator; +}; +#endif // _H_INSTRUCTIONEMITTER_ diff --git a/ef/Compiler/CodeGenerator/Makefile b/ef/Compiler/CodeGenerator/Makefile new file mode 100644 index 000000000000..683534d34c3f --- /dev/null +++ b/ef/Compiler/CodeGenerator/Makefile @@ -0,0 +1,86 @@ +#!gmake +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +####################################################################### +# (1) Directory specific info # +####################################################################### + +DEPTH = ../.. + +DIRS = md +SUBMODULES = $(DIRS) + +CPPSRCS = Backend.cpp \ + CGScheduler.cpp \ + CodeGenerator.cpp \ + IGVisualizer.cpp \ + Instruction.cpp \ + InstructionEmitter.cpp \ + NativeCodeCache.cpp \ + NativeFormatter.cpp \ + HTMLMethodDump.cpp \ + Scheduler.cpp \ + ExceptionTable.cpp \ + $(NULL) + +LOCAL_EXPORTS = Backend.h \ + Burg.h \ + CGScheduler.h \ + CodeGenerator.h \ + ControlNodeScheduler.h \ + ExceptionTable.h \ + FormatStructures.h \ + HTMLMethodDump.h \ + IGVisualizer.h \ + Instruction.h \ + InstructionEmitter.h \ + NativeCodeCache.h \ + NativeFormatter.h \ + Scheduler.h \ + $(NULL) + +MODULE_NAME = EF + +####################################################################### +# (2) Include "component" configuration information. # +####################################################################### + +include $(DEPTH)/config/config.mk + +####################################################################### +# (3) Include "local" platform-dependent assignments (OPTIONAL). # +####################################################################### + + + +####################################################################### +# (4) Execute "component" rules. (OPTIONAL) # +####################################################################### + +include $(DEPTH)/config/rules.mk + +####################################################################### +# (7) Execute "local" rules. (OPTIONAL). # +####################################################################### + +# Special rules for Instruction.cpp for gcc +ifneq ($(OS_ARCH),WINNT) + +$(OBJDIR)/Instruction$(OBJ_SUFFIX): Instruction.cpp + $(CCC) -c $(filter-out $(EXC_FLAGS),$(CFLAGS)) $< -o $@ + +endif diff --git a/ef/Compiler/CodeGenerator/NativeCodeCache.cpp b/ef/Compiler/CodeGenerator/NativeCodeCache.cpp new file mode 100644 index 000000000000..3a8dc4e83f9f --- /dev/null +++ b/ef/Compiler/CodeGenerator/NativeCodeCache.cpp @@ -0,0 +1,371 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +// NativeCodeCache +// +// Scott M. Silver +// + +#include "NativeCodeCache.h" +#include "StringUtils.h" +#include "ClassWorld.h" +#include "FieldOrMethod.h" +#include "NativeMethodDispatcher.h" +#include "JavaVM.h" + +UT_DEFINE_LOG_MODULE(NativeCodeCache); + +#ifdef _WIN32 +Uint8* CacheEntry::asynchVersion(Pool& pool, Uint8*& ip) +{ + Uint8* src = start.getFunctionAddress(); + Int32 sz = end-src; + Uint8* dest = new(pool) Uint8[sz]; + Uint32* asynchPoints = eTable->getAsynchPoints(); + int numberofAPoints = eTable->getNrOfAsynchPoints(); + // loop through code and for each byte corresponding to an asynchronous + // checkpoint, insert 'int 3' (0xCC). + memcpy((void*)dest,(const void*)src,sz); + for (int j=0; jtoString()); + + mIndexByDescriptor.get(key, &existingEntry); + + if (!existingEntry) + { + CacheEntry& cacheEntry = *new(mPool) CacheEntry(inMethodDescriptor); + cacheEntry.start = inWhere; + cacheEntry.end = inEnd; + cacheEntry.eTable = pExceptionTable; + cacheEntry.policy = inPolicy; + + mIndexByDescriptor.add(key, &cacheEntry); + mIndexByRange.append(&cacheEntry); + } + else + { + existingEntry->start = inWhere; + existingEntry->end = inEnd; + existingEntry->eTable = pExceptionTable; + existingEntry->policy = inPolicy; + } +} + + +// lookupByRange +// +// Purpose: used for stack crawling / debugging purposes +// In: pointer to memory +// Out: pointer to cache entry if in code cache (NULL otherwise) +// +// Notes: currently we do a linear search of a vector of methods, eventually +// we'll want a better search strategy +CacheEntry* NativeCodeCache:: +lookupByRange(Uint8* inAddress) +{ + for(CacheEntry** ce= mIndexByRange.begin(); ce < mIndexByRange.end(); ce++) + { +#ifdef GENERATE_FOR_X86 + if ((*ce)->stub <= inAddress && (*ce)->stub + 10 > inAddress) + return *ce; + else +#endif + if(((*ce)->start.getFunctionAddress() <= inAddress) && (inAddress < (*ce)->end)) + return *ce; + } + return NULL; +} + +// lookupByDescriptor +// +// Looks up method inMethodDescriptor, if inMethodDescriptor +// is not in the cache, this generates a new "stub" function +// (which will compile inMethodDescriptor and backpatch the caller) +// Since we have two entries in the CacheEntry, one for stub and +// the other for function, we return the function if it exists +// otherwise we return the stub. +// inLookupOnly - do not create a stub if the lookup fails +addr NativeCodeCache:: +lookupByDescriptor(const MethodDescriptor& inMethodDescriptor, bool /*inhibitBackpatch*/, bool inLookupOnly) +{ + Method *method = inMethodDescriptor.method; + TemporaryStringCopy key(method->toString()); + + CacheEntry* cacheEntry = NULL; + + mIndexByDescriptor.get(key, &cacheEntry); + + // short circuit if inLookupOnly + if (inLookupOnly && !cacheEntry) + return (functionAddress(NULL)); + + if (!cacheEntry) + { + CacheEntry& newEntry = *new(mPool) CacheEntry(inMethodDescriptor); + + newEntry.stub = (unsigned char*) generateCompileStub(*this, newEntry); + newEntry.start.setTVector(NULL); + newEntry.end = NULL; + newEntry.eTable = NULL; + + // FIX set shouldBackPatch to always false. Note that this + // means that we compile evry function every time + newEntry.shouldBackPatch = false; + + //newEntry.shouldBackPatch = !method->getDynamicallyDispatched(); + + cacheEntry = &newEntry; + mIndexByDescriptor.add(key, cacheEntry); + mIndexByRange.append(cacheEntry); + } + + bool inhibitBackpatching = false; + inhibitBackpatching = VM::theVM.getInhibitBackpatching(); + + if (cacheEntry->start.getFunctionAddress() && !inhibitBackpatching) + return (functionAddress((void (*)())cacheEntry->start.getFunctionAddress())); + else + { + if (!cacheEntry->stub) + cacheEntry->stub = (unsigned char*) generateCompileStub(*this, *cacheEntry); + return (functionAddress((void (*)())cacheEntry->stub)); + } +} + + +UT_DEFINE_LOG_MODULE(NativeCodeCacheMonitor); + +// compileOrLoadMethod +// +// If the method pointed to by inCacheEntry is a native method, resolve and load +// the native code library. Otherwise compile the method's bytecode into +// native code. Either way, return a pointer to the resulting native code. +// Sets shouldBackPatch to true if it is neccessary to back-patch the method. +static void* +compileOrLoadMethod(const CacheEntry* inCacheEntry, bool &shouldBackPatch) +{ + Method* method; + + // if this function is already compiled then just return it + if (inCacheEntry->start.getFunctionAddress() != NULL) + { + shouldBackPatch = inCacheEntry->shouldBackPatch; + goto ExitReturnFunc; + } + else + { + NativeCodeCache::enter(); + // maybe we slept while someone else was compiling, if so + // don't do any work. + if (inCacheEntry->start.getFunctionAddress() != NULL) + goto ExitReturnFunc; + + method = inCacheEntry->descriptor.method; + + // If this is a native method, then resolve it appropriately + if (method->getModifiers() & CR_METHOD_NATIVE) + { + addr a = NativeMethodDispatcher::resolve(*method); + + if (!a) + { + NativeCodeCache::exit(); + UT_LOG(NativeCodeCache, PR_LOG_ERROR, ("\tCould not resolve native method %s\n", method->getName())); + runtimeError(RuntimeError::linkError); + } + else + UT_LOG(NativeCodeCache, PR_LOG_DEBUG, ("\tResolved native method %s\n", method->getName())); + + + NativeCodeCache &cache = NativeCodeCache::getCache(); + void* code = generateNativeStub(cache, *inCacheEntry, addressFunction(a)); + + PlatformTVector tVector; + tVector.setTVector((Uint8*)code); + int codeLength = 0; // We don't know the length of native methods yet + + /*ExceptionTable* pExceptionTable = NULL; */ // FIX native methods don't have exception tables yet + StackFrameInfo policy; // FIX we don't know the stack layout policies yet, so pass in junk + + cache.mapMemoryToMethod(inCacheEntry->descriptor, tVector, (Uint8*)code + codeLength, NULL, policy); + } + else + method->compile(); + } + +ExitReturnFunc: + NativeCodeCache::exit(); + assert(inCacheEntry->start.getFunctionAddress()); + shouldBackPatch = inCacheEntry->shouldBackPatch; + EventBroadcaster::broadcastEvent(gCompileOrLoadBroadcaster, kEndCompileOrLoad, inCacheEntry->descriptor.method); + return (inCacheEntry->start.getFunctionAddress()); +/* +ExitMonitorThrowCompileException: + PR_CExitMonitor((void*)inCacheEntry); + assert(false); + return (NULL); +*/ +} + + +// compileAndBackPatchMethod +// +// compile the method pointed to by inCacheEntry and then back patch +// the caller. +// +// inLastPC = address of next native instruction to be executed +// if the callee executed and returned. (where callee is the method that +// is to be compiled) +extern "C" void* +compileAndBackPatchMethod(const CacheEntry* inCacheEntry, void* inLastPC, void* inUserDefined) +{ + bool shouldBackPatch; + + void *nativeCode = compileOrLoadMethod(inCacheEntry, shouldBackPatch); + + if (VM::theVM.getInhibitBackpatching()) + shouldBackPatch = false; + +#ifdef DEBUG + if (VM::theVM.getTraceAllMethods()) + { + Method *method = inCacheEntry->descriptor.method; + printFrame(method); + } +#endif + + /* Back-patch method only if method was resolved statically */ + return (shouldBackPatch) ? + (backPatchMethod(nativeCode, inLastPC, inUserDefined)) : nativeCode; +} + + +#ifdef DEBUG_LOG +// C-entry point so we can call this from +// the MSVC debugger +void NS_EXTERN +printMethodTable() +{ + NativeCodeCache::getCache().printMethodTable(UT_LOG_MODULE(NativeCodeCache)); +} + +// printMethodTable +// +// Print out all the methods currently in the cache, with their +// ExceptionTables +void NativeCodeCache:: +printMethodTable(LogModuleObject &f) +{ + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("\n__________________Method Table___________________\n")); + for(CacheEntry** ce= mIndexByRange.begin(); ce < mIndexByRange.end(); ce++) + { + Uint8* pStart = (*ce)->start.getFunctionAddress(); + Uint8* pEnd = (*ce)->end; + const char* pName= (*ce)->descriptor.method->toString(); + ExceptionTable* eTable= (*ce)->eTable; + + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("[%#010x-%#010x] %s\n", Uint32(pStart), Uint32(pEnd), pName)); + if(eTable) + eTable->printShort(f); + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("\n")); + } + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("\n\n")); +} + +UT_EXTERN_LOG_MODULE(StackWalker); + +#include "StackWalker.h" + +// printFrame +// +// Print a frame of a given method (which is +// the caller). This can be called from a debugger +static void printFrame(Method *method) +{ + UT_SET_LOG_LEVEL(StackWalker, PR_LOG_DEBUG); + + Frame frame; + frame.moveToPrevFrame(); + frame.moveToPrevFrame(); + + // Indent the frame according to stack depth + int stackDepth = Frame::getStackDepth(); + int i; + + // Discount the stack frames used for internal EF native code + stackDepth -= 7; + if (stackDepth < 0) + stackDepth = 0; + + for (i = 0; i < stackDepth; i++) + UT_LOG(StackWalker, PR_LOG_ALWAYS, (" ")); + + Frame::printWithArgs(UT_LOG_MODULE(StackWalker), (Uint8*)(frame.getBase()), method); + UT_LOG(StackWalker, PR_LOG_ALWAYS, ("\n")); +} + +#endif // DEBUG_LOG diff --git a/ef/Compiler/CodeGenerator/NativeCodeCache.h b/ef/Compiler/CodeGenerator/NativeCodeCache.h new file mode 100644 index 000000000000..b67065ccce3f --- /dev/null +++ b/ef/Compiler/CodeGenerator/NativeCodeCache.h @@ -0,0 +1,177 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +/* + NativeCodeCache +*/ + +#ifndef _NATIVE_CODE_CACHE_ +#define _NATIVE_CODE_CACHE_ + +#include "ExceptionTable.h" +#include "FormatStructures.h" +#include "Pool.h" +#include "Attributes.h" +#include "InfoItem.h" +#include "HashTable.h" +#include "FieldOrMethod.h" + +#include "LogModule.h" +#include "prmon.h" + +//----------------------------------------------------------------------------------------------------------- +// This is the key for entries in the cache +// Currently it retainst he "fully qualified" name +// of the method. +struct MethodDescriptor +{ + MethodDescriptor(Method& inMethod) : + method(&inMethod) { }; + + Method *method; // interned full name string describing this method + + void operator=(const MethodDescriptor& inCopy) { method = inCopy.method; } +}; + +//----------------------------------------------------------------------------------------------------------- +struct PlatformTVector +{ + Uint8* mTVector; + + void + setTVector(Uint8* inTVector) { mTVector = inTVector; } + + Uint8* + getFunctionAddress() const + { + #ifdef GENERATING_FOR_POWERPC + if (mTVEctor != NULL) + return (*(Uint8***)mTVector); + else + return (NULL); + #elif defined(GENERATING_FOR_X86) + return (mTVector); + #else + return (mTVector); // FIX-ME This probably is not right + #endif + } + + Uint8* + getEnvironment() const + { + #ifdef GENERATING_FOR_POWERPC + return (*((Uint8***)mTVector + 1)); + #else + assert(false); + return (NULL); + #endif + } +}; + +//----------------------------------------------------------------------------------------------------------- +// An entry in the CodeCache +// Not intended for use outside of NativeCode Cache +struct CacheEntry +{ + CacheEntry(const MethodDescriptor& inMethodDescriptor) : + descriptor(inMethodDescriptor), stub(0) { } + + MethodDescriptor descriptor; // unique descriptor of the method + PlatformTVector start; // default entry into the function + Uint8* end; // pointer to byte _after_ end of function + Uint8* stub; // if non-NULL this is the address of the stub function + ExceptionTable* eTable; // pointer to the exception table + mutable bool shouldBackPatch; // If true, specifies that the call site must be backpatched on compile + + // FIX for now the restore policy will be kept in the NativeCodeCache, later we may want to store the restore policies elsewhere + StackFrameInfo policy; // specifies how to restore registers as stack frames are popped + Uint8* asynchVersion(Pool& pool, Uint8*& ip); +}; + +//----------------------------------------------------------------------------------------------------------- +class NativeCodeCache +{ + PRMonitor* _mon; +public: + NativeCodeCache() : + mIndexByDescriptor(mPool), + mIndexByRange() + { _mon = PR_NewMonitor(); } + + Uint8* acquireMemory(const size_t inBytes); + + void mapMemoryToMethod( const MethodDescriptor& inMethodDescriptor, + PlatformTVector inWhere, + Uint8* inEnd, + ExceptionTable* pExceptionTable, + StackFrameInfo& inPolicy ); + + addr lookupByDescriptor(const MethodDescriptor& inDescriptor, bool inhibitBackpatch, bool inLookupOnly = false); + CacheEntry* lookupByRange(Uint8* inAddress); + +protected: + HashTable mIndexByDescriptor; // hashtable of entrypoints to methods + Vector mIndexByRange; // maps range -> method +public: + Pool mPool; // resource for our cache + static inline NativeCodeCache& getCache() { return (NativeCodeCache::sNativeCodeCache); } + + static NativeCodeCache sNativeCodeCache; + + #ifdef DEBUG + void printMethodTable(LogModuleObject &f); + #endif + + static void enter() { + PR_EnterMonitor(sNativeCodeCache._mon); + } + + static void exit() { + PR_ExitMonitor(sNativeCodeCache._mon); + } +}; + +// inCacheEntry: reference to actual CacheEntry in memory +// inCache: the cache in question +// creates a bit of code which when called compiles the method +// described by inCacheEntry.descriptor and then calls "compileAndBackPatchMethod" +// then jump to the method returned by compileAndBackPatchMethod + +extern void* +generateCompileStub(NativeCodeCache& inCache, const CacheEntry& inCacheEntry); + +extern void* +generateNativeStub(NativeCodeCache& inCache, const CacheEntry& inCacheEntry, void *nativeFunction); + +extern void * +generateJNIGlue(NativeCodeCache& inCache, + const CacheEntry& inCacheEntry, + void *nativeFunction); + +extern "C" void * +compileAndBackPatchMethod(const CacheEntry* inCacheEntry, void* inLastPC, void* inUserDefined); + +// atomically backpatch a caller of a stub generated with generateCompileStub +// inMethodAddress the address of the callee +// inLastPC the next PC to be executed up return from the callee +// inUserDefined is a (probably) per platform piece of data that will be passed +// on to the backPatchMethod function. +void* backPatchMethod(void* inMethodAddress, void* inLastPC, void* inUserDefined); + +void NS_EXTERN printMethodTable(); + +#endif // _NATIVE_CODE_CACHE_ diff --git a/ef/Compiler/CodeGenerator/NativeFormatter.cpp b/ef/Compiler/CodeGenerator/NativeFormatter.cpp new file mode 100644 index 000000000000..d3c870a5e9d0 --- /dev/null +++ b/ef/Compiler/CodeGenerator/NativeFormatter.cpp @@ -0,0 +1,374 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +// +// NativeFormatter.cpp +// +// Scott M. Silver +// +// Actually output native code for a function to memory (from the NativeCodeCache). +// +// Summary +// +// A NativeFormatter takes an InstructionEmitter (a per/method data structure) and a Method +// (a runtime representation of a method) and actually outputs the native representation +// of the function out to memory. Memory is acquired from the NativeCodeCache. +// +// Each function has the following structural layout: +// +// ControlNodes Formatted Correlation +// PreMethod +// ckBegin Prolog +// ckReturn Epilog +// ckEnd PostMethod +// +// Prolog and Epilog are normal entry and exit points from a function. Note that even +// if a function does not return a value a ckReturn node must exist. +// PreMethod and PostMethod are invented pieces of code/data which may be used +// for debuggers or stack inspection (eg. MacsBug symbols, TraceBack tables, etc...) + +#include "NativeFormatter.h" +#include "ControlGraph.h" +#include "InstructionEmitter.h" +#include "NativeCodeCache.h" +#include "ExceptionTable.h" + +#ifdef DEBUG + +#include "JavaVM.h" // to insert breakpoints in jitted code + +#endif + +UT_DEFINE_LOG_MODULE(ExceptionMatrix); + +//----------------------------------------------------------------------------------------------------------- +// format +// +// Actually output the native instructions of a method out to memory +// acquired from the cache. +// +// outInfo: Normally temporal information about the formatting the function +// mainly used for debugging purposes +void* NativeFormatter:: +format(Method& inMethod, FormattedCodeInfo* outInfo) +{ + // now setup a FormattedCodeInfo with collected data about the method + FormattedCodeInfo fci; + fci.method = &inMethod; + + // Need policy before any formatting can be done + mFormatter.initStackFrameInfo(); + + mFormatter.calculatePrologEpilog(inMethod, fci.prologSize, fci.epilogSize); + mFormatter.calculatePrePostMethod(inMethod, fci.preMethodSize, fci.postMethodSize); + + // potentially shortens or lengthens branches + fci.bodySize = resolveBranches(fci.prologSize, fci.epilogSize); + + // actually grab some memory for this method + Uint32 methodSize = fci.preMethodSize + fci.bodySize + fci.postMethodSize; + +#ifdef DEBUG +#if defined(XP_PC) || defined(LINUX) + DebugDesc *bps; + Uint32 nbps; + nbps = VM::theVM.getExecBreakPoints(bps); + bool hasInt3 = false; + bool foundBreakPoint = false; + + for (Uint32 index = 0; index < nbps; index++) + if (inMethod.isSelf(bps[index].className, bps[index].methodName, bps[index].sig)) { + methodSize++; // for int 3 + fci.methodStart = NativeCodeCache::getCache().acquireMemory(methodSize); + *fci.methodStart++ = 0xcc; + hasInt3 = true; + foundBreakPoint = true; + break; + } + + if (!foundBreakPoint) + fci.methodStart = NativeCodeCache::getCache().acquireMemory(methodSize); + +#else + fci.methodStart = NativeCodeCache::getCache().acquireMemory(methodSize); +#endif +#else + fci.methodStart = NativeCodeCache::getCache().acquireMemory(methodSize); +#endif + + // build the exception table + // FIX FIX FIX + // for now just grab some memory + Pool* tempPool = new Pool(); + ExceptionTable& eTable = buildExceptionTable(fci.methodStart, tempPool); + DEBUG_LOG_ONLY(eTable.print(UT_LOG_MODULE(ExceptionMatrix))); + DEBUG_LOG_ONLY(eTable.printFormatted(UT_LOG_MODULE(ExceptionMatrix), nodes, nNodes, false)); + + // fci is now valid + mFormatter.beginFormatting(fci); + + // dump out the function to memory + outputNativeToMemory(fci.methodStart, fci); + + // make an entry point for this function + MethodDescriptor md(inMethod); + + mFormatter.endFormatting(fci); + +#if defined(DEBUG) && (defined(XP_PC) || defined(LINUX)) + if (hasInt3) + fci.methodStart--; +#endif + + PlatformTVector functionDescriptor; + functionDescriptor.setTVector(mFormatter.createTransitionVector(fci)); + + fci.methodEnd = fci.methodStart + methodSize; +#ifdef WIN32 + // temporarily check this invariant + assert((fci.methodStart + methodSize) == (functionDescriptor.getFunctionAddress() + methodSize)); +#endif + + // Eventually we may wish to have choose different GPR/FPR save procedures and local store sizes for + // different nodes in the control graph. Correspondingly the restore policies in an exception unwind + // can vary by control node -- ie they are not necessarily the same across the whole method. + // For now we will give each method the same info, but we reserve the right later to make this optimisation. + + // FIX for mow, NativeCodeCache::mapMemoryToMethod caches a copy of the policy + StackFrameInfo& policy = mFormatter.getStackFrameInfo(); + NativeCodeCache::getCache().mapMemoryToMethod(md, functionDescriptor, fci.methodEnd, &eTable, policy); + + if (outInfo) + *outInfo = fci; + +#ifdef DEBUG_LOG + // debugging stuff + if(VM::theVM.getEmitHTML()) + dumpMethodToHTML(fci, eTable); +#endif + + // return the entry point + return (fci.methodStart); +} + +// outputNativeToMemory +// actually ouput this method to memory starting at inWhere. +// inInfo contains some precalculated information about the method +// which is useful in its formatting. +void NativeFormatter:: +outputNativeToMemory(void* inWhere, const FormattedCodeInfo& inInfo) +{ + Uint32 curOffset; + char* nextMemory = (char*) inWhere; + + assert(nodes[0]->hasControlKind(ckBegin)); + assert(nodes[nNodes-1]->hasControlKind(ckEnd)); + + // first output the PreMethod + mFormatter.formatPreMethodToMemory(nextMemory, inInfo); + nextMemory += inInfo.preMethodSize; + + mFormatter.formatPrologToMemory(nextMemory); + nextMemory += inInfo.prologSize; + curOffset = inInfo.prologSize; + + for (Uint32 n = 0; n < nNodes; n++) + { + InstructionList& instructions = nodes[n]->getInstructions(); + for(InstructionList::iterator i = instructions.begin(); !instructions.done(i); i = instructions.advance(i)) + { + Instruction& curInstruction = instructions.get(i); + + curInstruction.formatToMemory(nextMemory, curOffset, mFormatter); + curOffset += curInstruction.getFormattedSize(mFormatter); + nextMemory += curInstruction.getFormattedSize(mFormatter); + } + + if (nodes[n]->hasControlKind(ckReturn)) + { mFormatter.formatEpilogToMemory(nextMemory); + curOffset += inInfo.epilogSize; + nextMemory += inInfo.epilogSize; + } + } + + // Now end with the PostMethod + mFormatter.formatPostMethodToMemory(nextMemory, inInfo); + //nextMemory += inInfo.preMethodSize; +} + + +// accumulateSize +// +// Accumulate the size of the the formatted (ie in-memory) representation +// of each Instruction in this ControlNode. ckBegin and ckReturn nodes +// include the prolog and epilog size, respectively. +Uint32 NativeFormatter:: +accumulateSize(ControlNode& inNode, Uint32 inPrologSize, Uint32 inEpilogSize) +{ + Uint32 accum; + + InstructionList& instructions = inNode.getInstructions(); + + accum = 0; + for(InstructionList::iterator i = instructions.begin(); !instructions.done(i); i = instructions.advance(i)) + accum += instructions.get(i).getFormattedSize(mFormatter); + + if (inNode.hasControlKind(ckReturn)) + accum += inEpilogSize; + else if (inNode.hasControlKind(ckBegin)) + accum += inPrologSize; + + return (accum); +} + +// resolveBranches +// +// for each node in the scheduled ControlNodes +// assign a native offset to each ControlNode. +// decisions to make short/long branches would normally be made +// here. returns the size of the formatted method. including +// epilog and prolog. The PreMethod and PostMethod are not +// considered here. +Uint32 NativeFormatter:: +resolveBranches(Uint32 inPrologSize, Uint32 inEpilogSize) +{ + Uint32 accumSize; + + accumSize = 0; + for (Uint32 i = 0; i < nNodes; i++) + { + ControlNode& node = *nodes[i]; + Uint32 formattedSize; + + node.setNativeOffset(accumSize); + // fix-me this should be a function of the list, ie the list + // should maintain the size of the instructions in it + formattedSize = accumulateSize(node, inPrologSize, inEpilogSize); + accumSize += formattedSize; + } + + // make long/short branch decisions here + return (accumSize); +} + +// buildExceptionTable +// In: start of method +// pool to create table in +// Out: the Exception Table + +// #define DEBUG_GENERATE_EXCEPTION_MATRIX + +// Debugging code to print out a matrix of exception handlers +// Ugly -- farm out to a class, time permitting +#ifdef DEBUG_GENERATE_EXCEPTION_MATRIX + +#define DEBUG_SET_UP_EXCEPTION_MATRIX \ + UT_LOG(ExceptionMatrix, PR_LOG_ALWAYS, ("\n\nBuilding Exception Table\n")); \ + assert(nNodes < 100); /* dumb check */ \ + int _exceptionMatrix[100][100]; \ + Uint32 _rows, _cols; \ + for(_rows = 0; _rows < nNodes; _rows++) \ + for(_cols = 0; _cols < nNodes; _cols++) \ + _exceptionMatrix[_rows][_cols] = 0; \ + Uint32 _addorder = 1; + +#define DEBUG_ADD_ENTRY_TO_EXCEPTION_MATRIX \ + _exceptionMatrix[node->dfsNum][e->getTarget().dfsNum] = _addorder++; + +#define DEBUG_PRINT_EXCEPTION_MATRIX \ + /* print header */ \ + UT_LOG(ExceptionMatrix, PR_LOG_ALWAYS, ("\n\nException Matrix\n ")); \ + for(_cols = 0; _cols < nNodes; _cols++) \ + UT_LOG(ExceptionMatrix, PR_LOG_ALWAYS, ("N%02d ", nodes[_cols]->dfsNum)); \ + UT_LOG(ExceptionMatrix, PR_LOG_ALWAYS, ("\n")); \ + /* print rows */ \ + for(_rows = 0; _rows < nNodes; _rows++) \ + { \ + UT_LOG(ExceptionMatrix, PR_LOG_ALWAYS, (" N%02d: ", nodes[_rows]->dfsNum)); \ + for(_cols = 0; _cols < nNodes; _cols++) \ + { \ + _addorder = _exceptionMatrix[nodes[_rows]->dfsNum][nodes[_cols]->dfsNum]; \ + if(_addorder != 0) \ + UT_LOG(ExceptionMatrix, PR_LOG_ALWAYS, (" %02d ", _addorder)); \ + else \ + UT_LOG(ExceptionMatrix, PR_LOG_ALWAYS, (" - ")); \ + } \ + UT_LOG(ExceptionMatrix, PR_LOG_ALWAYS, ("\n")); \ + } \ + UT_LOG(ExceptionMatrix, PR_LOG_ALWAYS, ("\n\n\n")); + +#else + +#define DEBUG_SET_UP_EXCEPTION_MATRIX +#define DEBUG_ADD_ENTRY_TO_EXCEPTION_MATRIX +#define DEBUG_PRINT_EXCEPTION_MATRIX + +#endif // DEBUG_GENERATE_EXCEPTION_MATRIX + +ExceptionTable& NativeFormatter:: +buildExceptionTable(Uint8* methodStart, Pool* inPool) +{ + Uint32 i; + + DEBUG_SET_UP_EXCEPTION_MATRIX; + ExceptionTableBuilder eBuilder(methodStart); + + for (i = 0; i < nNodes; i++) // iterate through nodes in scheduled order + { + ControlNode* node = nodes[i]; + ControlKind kind = node->getControlKind(); + if(kind == ckExc || kind == ckAExc || kind == ckThrow) + { // has exception + ControlNode::ExceptionExtra& excExtra = node->getExceptionExtra(); + const Class **exceptionClass = excExtra.handlerFilters + excExtra.nHandlers; + + if (kind == ckAExc) + eBuilder.addAEntry(node->getNativeOffset()); + // iterate through exception edges + Uint32 startIndex = 0; // start extending exceptions from beginning of table + ControlEdge *e = node->getSuccessorsEnd(); + for (Uint32 exceptNum = 0; exceptNum < excExtra.nHandlers; exceptNum++) + { + e--; // move to previous handler edge + exceptionClass--; // move to previous handler filter + + assert(&(e->getSource()) == node); + + if(e->getTarget().getControlKind() != ckEnd) // only interested in exceptions handled locally + { +// assert(e->getTarget().getControlKind() == ckCatch); // targets of exception edges must be End or Catch nodes + ExceptionTableEntry ete; // container for exception info passing + ete.pStart = node->getNativeOffset(); + ete.pEnd = nodes[i+1]->getNativeOffset(); // points to byte after 'node' + ete.pHandler = e->getTarget().getNativeOffset(); + ete.pExceptionType = *exceptionClass; + UT_LOG(ExceptionMatrix, PR_LOG_ALWAYS, ("N%02d->N%02d ", node->dfsNum, e->getTarget().dfsNum)); + eBuilder.addEntry(startIndex, ete); // note that startIndex is passed by reference + DEBUG_ADD_ENTRY_TO_EXCEPTION_MATRIX; + } + } + } + } + + DEBUG_PRINT_EXCEPTION_MATRIX; + DEBUG_ONLY(eBuilder.checkInOrder()); + + // copy table into new (efficient) storage and insert into NativeCodeCache + ExceptionTable* eTable = new(*inPool) ExceptionTable(eBuilder, *inPool); + return (*eTable); +} + diff --git a/ef/Compiler/CodeGenerator/NativeFormatter.h b/ef/Compiler/CodeGenerator/NativeFormatter.h new file mode 100644 index 000000000000..7cde0f1ac826 --- /dev/null +++ b/ef/Compiler/CodeGenerator/NativeFormatter.h @@ -0,0 +1,63 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +// +// File: NativeFormatter.h +// Author: smsilver +// + +#ifndef H_NATIVEFORMATTER +#define H_NATIVEFORMATTER + +class ControlNode; +class Instruction; +class Pool; +class ExceptionTable; +struct MethodDescriptor; + +#include "FormatStructures.h" +#include "LogModule.h" + +#define INCLUDE_EMITTER +#include "CpuInfo.h" +#undef INCLUDE_EMITTER + +class NativeFormatter +{ +protected: + MdEmitter& mEmitter; + MdFormatter mFormatter; + ControlNode** nodes; + Uint32 nNodes; + + void outputNativeToMemory(void* inWhere, const FormattedCodeInfo& inInfo); + Uint32 accumulateSize(ControlNode& inNode, Uint32 inPrologSize, Uint32 inEpilogSize); + Uint32 resolveBranches(Uint32 inPrologSize, Uint32 inEpilogSize); + ExceptionTable& buildExceptionTable(Uint8* methodMemoryStart, Pool* inPool); + +public: + NativeFormatter(MdEmitter& inEmitter, ControlNode** mNodes, uint32 mNNodes) : + mEmitter(inEmitter), mFormatter(mEmitter), nodes(mNodes), nNodes(mNNodes) {} + + void* format(Method& inMethod, FormattedCodeInfo* outInfo = NULL); + +#ifdef DEBUG_LOG + void dumpMethodToHTML(FormattedCodeInfo& fci, ExceptionTable& inExceptionTable); // see HTMLMethodDump.cpp for implementation +#endif +}; + +#endif // H_NATIVEFORMATTER diff --git a/ef/Compiler/CodeGenerator/Scheduler.cpp b/ef/Compiler/CodeGenerator/Scheduler.cpp new file mode 100644 index 000000000000..ffe407406c4c --- /dev/null +++ b/ef/Compiler/CodeGenerator/Scheduler.cpp @@ -0,0 +1,374 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +// LinearInstructionScheduler.cpp +// +// Peter DeSantis 28 April 1997 + +#include "Scheduler.h" +#include "Vector.h" +#include "ControlNodes.h" +#include "Primitives.h" +#include "DoublyLinkedList.h" +#include "Instruction.h" + +void swapRootToEnd(Vector& inRoots, RootPair* inSwapToEnd); + + +// schedule [no real purpose currently] FIX-ME +// Calls the appropriate internal routine(s). +void LinearInstructionScheduler:: +schedule(Vector& roots, ControlNode& controlNode) +{ + linearSchedule(roots, controlNode); +} + + +// The primary goal of linear scheduling is to schedule all the instructions +// which are derived from one line of src code one after another. There are numerous +// ways to meet this objective. The simpliest method is to do a simple prioritived +// topological sort of the control node. The priority is that from any node the +// algorith follows the edges in increasing linenumber order. (Each instruction has +// a line number associated with it which corresponds to src code line number.) As the +// topological sort backtracks it inserts the instruction which it is leaving into +// the list of instructions in the control node. The instructions have to be inserted +// in an ordered fashion such that each new instruction is added at the end of the +// section with the same associated line numbers. Currently this is done in the +// simpliest n^2 fashion. If scheduling is determined to take significant time this +// running time can be improved by using a binary search insertion routine. + + + +/* + priorityTopoEmit + does a priority topological sort of the instructions rooted at root and fills the + controlnode's list ordered list of instructions. +*/ +void LinearInstructionScheduler:: +priorityTopoEmit(Instruction* inInstruction, ControlNode& controlNode) +{ + if (controlNode.haveScheduledInstruction(*inInstruction)) + return; + + InstructionUse* conditionCodeUse = NULL; + InstructionUse* curUse; + Instruction* curInstruction; + + for (curUse = inInstruction->getInstructionUseBegin(); + curUse < inInstruction->getInstructionUseEnd(); + curUse++) + { + if(curUse->kind == udCond) + { + assert(conditionCodeUse == NULL); // Instructions only allowed to use one condition code + conditionCodeUse = curUse; + } else { + curInstruction = CodeGenerator::instructionUseToInstruction(*curUse); + + // Only need to schedule if it hasn't been scheduled and it is in coltrolNode + if (curInstruction != NULL + && curInstruction->getPrimitive()->getContainer() == inInstruction->getPrimitive()->getContainer()) + { + priorityTopoEmit(curInstruction, controlNode); + } + } + } + + if(conditionCodeUse != NULL) + { + curInstruction = CodeGenerator::instructionUseToInstruction(*conditionCodeUse); + + if (curInstruction != NULL + && curInstruction->getPrimitive()->getContainer() == inInstruction->getPrimitive()->getContainer()) + { + priorityTopoEmit(curInstruction, controlNode); + } + } + + // Now insert the instruction into the controlnodes list of instructions + controlNode.addScheduledInstruction(*inInstruction); + +} + + +// swapRootToEnd +// +// Swaps the passed in root to the end of the root vector +void +swapRootToEnd(Vector& inRoots, RootPair* inSwapToEnd) +{ + RootPair oldRoot; + RootPair* end = inRoots.end() - 1; + + oldRoot = *end; + *end = *inSwapToEnd; + *inSwapToEnd = oldRoot; +} + +/* + linearSchedule + Does a prioritized linear search which fills in controlNode->instructions from the + back to the front. +*/ +void LinearInstructionScheduler:: +linearSchedule(Vector& roots, ControlNode& controlNode) +{ + // FIX-ME move this stuff to the function that builds up roots + if (controlNode.hasControlKind(ckReturn)) + { + // Enforce the register allocator requirement that code emitted for + // Result nodes be placed at the end of the block + // The register allocator has no "global scope" uses, so basically it + // would be sufficient to place the ExternalUse instruction emitted for + // each Result node at the end, however we just go ahead and make sure + // all of the code for a Result is last thing scheduled in a node. + // Hopefully the register allocator will have globally scoped uses + // in the future. FIX-ME. + RootPair* curRoot; + RootPair* resultRoot = NULL; + + // find poResult + for (curRoot = roots.begin(); curRoot < roots.end(); curRoot++) + if (curRoot->root->hasCategory(pcResult)) + { + assert(!resultRoot); // verify there is only one Result node (is this true?) + resultRoot = curRoot; +#ifndef DEBUG + break; +#endif + } + + // it is not necessary that there be a pcResult + if (resultRoot) + swapRootToEnd(roots, resultRoot); + } + else if (controlNode.hasControlKind(ckExc)) + { + // Satisfy constraint that an exception producing primitive + // must be the last excecuted in the ControlNode + RootPair* curRoot; + RootPair* exceptionRoot = NULL; + + // find poResult + for (curRoot = roots.begin(); curRoot < roots.end(); curRoot++) + if (curRoot->root->canRaiseException()) + { + assert(!exceptionRoot); // verify there is only one exception generating root + exceptionRoot = curRoot; +#ifndef DEBUG + break; +#endif + } + + assert(exceptionRoot); + swapRootToEnd(roots, exceptionRoot); + } + + renumberCN(roots, controlNode); + + RootPair* curRoot; + Primitive* anchoredPrimitive; + + // take care of any anchored primitives last, so find out the anchored primitive + if (controlNode.hasControlKind(ckIf) || controlNode.hasControlKind(ckSwitch)) + anchoredPrimitive = &controlNode.getControlPrimExtra(); + else + anchoredPrimitive = NULL; + + //For each primary root, rum topologicalEmit + for(curRoot = roots.begin(); curRoot < roots.end(); curRoot++) + { + if(curRoot->isPrimary && (curRoot->root != anchoredPrimitive)) + { + if (curRoot->root->getInstructionRoot() != NULL) + priorityTopoEmit(curRoot->root->getInstructionRoot(), controlNode); + + // FIX-ME no longer need curOutput + DataNode* curOutput = curRoot->root; + + // although exception edges are not explicit + // we need to consider them as real outgoing edges + if ((curOutput->hasConsumers() || curOutput->canRaiseException()) && !curOutput->hasKind(vkVoid)) + { + // now walk through all vr's assigned to this producer + VirtualRegister* curVR; + Instruction* nextInsn; + + switch (curOutput->getKind()) + { + case vkCond: + case vkMemory: + nextInsn = curOutput->getInstructionAnnotation(); + if (nextInsn) + priorityTopoEmit(nextInsn, controlNode); + break; + case vkLong: + curVR = curOutput->getHighVirtualRegisterAnnotation(); + assert(curVR); + nextInsn = curVR->getDefiningInstruction(); + if (nextInsn) + priorityTopoEmit(nextInsn, controlNode); + // FALL THROUGH for low vr + case vkAddr: + case vkInt: + case vkFloat: + case vkDouble: + curVR = curOutput->getLowVirtualRegisterAnnotation(); + assert(curVR); + nextInsn = curVR->getDefiningInstruction(); + if (nextInsn) + priorityTopoEmit(nextInsn, controlNode); + break; + case vkTuple: + case vkVoid: + break; + default: + trespass("unknown or unhandled output"); + } + } + } + } + + if (anchoredPrimitive) + priorityTopoEmit(anchoredPrimitive->getInstructionRoot(), controlNode); +} + + +/* + Compute the debugLineNumbers for each Primitive in the CN. + The debugLineNumber assures that the stable sort will not invalidate the scheduled instruction + ordering. Debug line numbers are the minimum integer values which maintain the following + properties: lineNumber(P) <= debugLineNumber(P) and for every Primitive P' which + defines an edge consumed by P, debugLineNumber(P) >= debugLineNumber(P'). +*/ + +void LinearInstructionScheduler:: +renumberCN(Vector& roots, ControlNode& /*controlNode*/) +{ + + RootPair* curRoot; + + int rootsToRenumber = roots.size(); + int rootsRenumbered = 0; + + const DoublyLinkedList* consumers; + DoublyLinkedList :: iterator curConsumer; + + // Initialize all root's renumberData + for(curRoot = roots.begin(); curRoot < roots.end(); curRoot++) + { + if(curRoot->isPrimary) + curRoot->data.renumbered = false; + else { + curRoot->data.renumbered = false; + curRoot->data.timesVisited = 0; + curRoot->data.neededVisits = 0; + + if (curRoot->root->getOutgoingEdgesEnd() > curRoot->root->getOutgoingEdgesBegin()) + { + DataNode* curOutput; + for (curOutput = curRoot->root->getOutgoingEdgesBegin(); + curOutput < curRoot->root->getOutgoingEdgesEnd(); + curOutput++) + { + consumers = &curOutput->getConsumers(); + for(curConsumer = consumers->begin(); !consumers->done(curConsumer); + curConsumer = consumers->advance(curConsumer)) + curRoot->data.neededVisits++; + } + } + } + } + + // Renumber Primary Roots + for(curRoot = roots.begin(); curRoot < roots.end(); curRoot++) + { + if(curRoot->isPrimary) + { + curRoot->root->setDebugLineNumber(curRoot->root->getLineNumber()); + renumberPrimitive(roots, *(curRoot->root)); + rootsRenumbered++; + curRoot->data.renumbered = true; + } + } + + curRoot = roots.begin(); + while ( rootsRenumbered != rootsToRenumber ) + { + while(curRoot->data.renumbered) + { + curRoot++; + if(curRoot == roots.end()) + curRoot = roots.begin(); + } + + if(curRoot->data.timesVisited != curRoot->data.neededVisits) + { + renumberPrimitive(roots, *(curRoot->root)); + rootsRenumbered++; + curRoot->data.renumbered = true; + } + + curRoot++; + if(curRoot == roots.end()) + curRoot = roots.begin(); + } +} + + +void LinearInstructionScheduler:: +renumberPrimitive(Vector& roots, Primitive& p) +{ + DataConsumer* curConsumer; + + for (curConsumer = p.getInputsBegin(); + curConsumer < p.getInputsEnd(); + curConsumer++) + { + if(curConsumer->isVariable()) + { + DataNode& possibleChild = curConsumer->getNode(); + + if (!possibleChild.hasCategory(pcPhi)) + { + Primitive &child = Primitive::cast(possibleChild); + if(child.getDebugLineNumber() == 0) + child.setDebugLineNumber(child.getLineNumber()); + + if(child.getDebugLineNumber() < p.getDebugLineNumber()) + child.setDebugLineNumber(p.getDebugLineNumber()); + + RootPair* curRoot; + bool isRoot = false; + for(curRoot = roots.begin(); curRoot < roots.end(); curRoot++) + { + if(curRoot->root == &child) + { + isRoot = true; + curRoot->data.timesVisited++; + break; + } + } + + if(!isRoot) + renumberPrimitive(roots, child); + } + } + } +} + + diff --git a/ef/Compiler/CodeGenerator/Scheduler.h b/ef/Compiler/CodeGenerator/Scheduler.h new file mode 100644 index 000000000000..b6d1c9db4d65 --- /dev/null +++ b/ef/Compiler/CodeGenerator/Scheduler.h @@ -0,0 +1,51 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +// LinearInstructionScheduler.h +// +// Peter DeSantis +// Scott M. Silver + + +// General Idea: +// preserves the src code ordering +// instructions. It is the result of a topological sort of the control node from each primary +// root. A primary root is one which is not reachable by any other root in the control node. +// When there is more than outgoing edge from a node, they are searched in increasing order of +// their srcLine fields. + +#ifndef SCHEDULER_H +#define SCHEDULER_H + +#include "CodeGenerator.h" +#include "Vector.h" + +class LinearInstructionScheduler +{ +public: + void schedule(Vector& roots, ControlNode& controlNode); + +protected: + void priorityTopoEmit(Instruction* inInstruction, ControlNode& controlNode); + void renumberCN(Vector& roots, ControlNode& controlNode); + void renumberPrimitive(Vector& roots, Primitive& p); + void linearSchedule(Vector& roots, ControlNode& controlNode); +}; + +#endif //SCHEDULER_H + + diff --git a/ef/Compiler/CodeGenerator/md/CpuInfo.h b/ef/Compiler/CodeGenerator/md/CpuInfo.h new file mode 100644 index 000000000000..f14206f9dcb1 --- /dev/null +++ b/ef/Compiler/CodeGenerator/md/CpuInfo.h @@ -0,0 +1,46 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#if !defined(_CPU_INFO_H_) || defined(INCLUDE_EMITTER) +#define _CPU_INFO_H_ + +#ifdef GENERATE_FOR_PPC + #include "PPC601Cpu.h" +#elif defined(GENERATE_FOR_X86) + #include "x86Win32Cpu.h" +#elif defined(GENERATE_FOR_SPARC) + //#include "SparcCpu.h" +#elif defined(GENERATE_FOR_HPPA) + #include "HPPACpu.h" +#endif + +#ifndef CPU_IS_SUPPORTED +#error "Processor not supported" +#endif + +#define NUMBER_OF_CALLER_SAVED_GR (LAST_CALLER_SAVED_GR - FIRST_CALLER_SAVED_GR + 1) +#define NUMBER_OF_CALLEE_SAVED_GR (LAST_CALLEE_SAVED_GR - FIRST_CALLEE_SAVED_GR + 1) +#define NUMBER_OF_CALLER_SAVED_FPR (LAST_CALLER_SAVED_FPR - FIRST_CALLER_SAVED_FPR + 1) +#define NUMBER_OF_CALLEE_SAVED_FPR (LAST_CALLEE_SAVED_FPR - FIRST_CALLEE_SAVED_FPR + 1) + +#define NUMBER_OF_GREGISTERS (LAST_GREGISTER - FIRST_GREGISTER + 1) +#define NUMBER_OF_FPREGISTERS (LAST_FPREGISTER - FIRST_FPREGISTER + 1) +#define NUMBER_OF_REGISTERS (NUMBER_OF_GREGISTERS + NUMBER_OF_FPREGISTERS + NUMBER_OF_SPECIAL_REGISTERS) + + +#endif /* _CPU_INFO_H_ */ diff --git a/ef/Compiler/CodeGenerator/md/Makefile b/ef/Compiler/CodeGenerator/md/Makefile new file mode 100644 index 000000000000..95910384527e --- /dev/null +++ b/ef/Compiler/CodeGenerator/md/Makefile @@ -0,0 +1,53 @@ +#!gmake +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +####################################################################### +# (1) Directory specific info # +####################################################################### + +DEPTH = ../../.. + +DIRS = $(CPU_ARCH) $(GENERIC) + +SUBMODULES = $(DIRS) + +LOCAL_EXPORTS = CpuInfo.h + +####################################################################### +# (2) Include "component" configuration information. # +####################################################################### + +include $(DEPTH)/config/config.mk + +####################################################################### +# (3) Include "local" platform-dependent assignments (OPTIONAL). # +####################################################################### + + + +####################################################################### +# (4) Execute "component" rules. (OPTIONAL) # +####################################################################### + +include $(DEPTH)/config/rules.mk + +####################################################################### +# (7) Execute "local" rules. (OPTIONAL). # +####################################################################### + + + diff --git a/ef/Compiler/CodeGenerator/md/generic/Generic_Support.cpp b/ef/Compiler/CodeGenerator/md/generic/Generic_Support.cpp new file mode 100644 index 000000000000..3a2aae44b200 --- /dev/null +++ b/ef/Compiler/CodeGenerator/md/generic/Generic_Support.cpp @@ -0,0 +1,47 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +/* + Generic_Support +*/ + +#include "NativeCodeCache.h" +#include +#include "Fundamentals.h" + +void* backPatchMethod(void* /*inMethodAddress*/, void* /*inLastPC*/, void* /*inUserDefined*/) +{ + trespass("not implemented"); + return (NULL); +} + +static void dummyStub(); + +static void dummyStub() +{ + printf("dummyStub #1\n"); +} + +void* +generateCompileStub(NativeCodeCache& /*inCache*/, const CacheEntry& /*inCacheEntry*/) +{ +#ifndef GENERATE_FOR_PPC + return ((void*) dummyStub); +#else + return (*(void**) dummyStub); +#endif +} diff --git a/ef/Compiler/CodeGenerator/md/generic/Makefile b/ef/Compiler/CodeGenerator/md/generic/Makefile new file mode 100644 index 000000000000..d2e627a34937 --- /dev/null +++ b/ef/Compiler/CodeGenerator/md/generic/Makefile @@ -0,0 +1,60 @@ +#!gmake +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +####################################################################### +# (1) Directory specific info # +####################################################################### + +DEPTH = ../../../.. + +CPPSRCS = Generic_Support.cpp \ + $(NULL) + +####################################################################### +# (2) Include "global" configuration information. (OPTIONAL) # +####################################################################### + + +####################################################################### +# (3) Include "component" configuration information. (OPTIONAL) # +####################################################################### + + +####################################################################### +# (4) Include "local" platform-dependent assignments (OPTIONAL). # +####################################################################### + + + +####################################################################### +# (5) Execute "global" rules. (OPTIONAL) # +####################################################################### + + +####################################################################### +# (6) Execute "component" rules. (OPTIONAL) # +####################################################################### + + +include $(DEPTH)/config/rules.mk + +####################################################################### +# (7) Execute "local" rules. (OPTIONAL). # +####################################################################### + + + diff --git a/ef/Compiler/CodeGenerator/md/hppa/HPPACpu.h b/ef/Compiler/CodeGenerator/md/hppa/HPPACpu.h new file mode 100644 index 000000000000..f5d423dd771b --- /dev/null +++ b/ef/Compiler/CodeGenerator/md/hppa/HPPACpu.h @@ -0,0 +1,60 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#ifndef _HPPA_CPU_H_ +#define _HPPA_CPU_H_ + +#define FIRST_CALLER_SAVED_GR 0 +#define LAST_CALLER_SAVED_GR 12 +#define FIRST_CALLEE_SAVED_GR 13 +#define LAST_CALLEE_SAVED_GR 28 +#define FIRST_CALLER_SAVED_FPR 29 +#define LAST_CALLER_SAVED_FPR 56 +#define FIRST_CALLEE_SAVED_FPR 57 +#define LAST_CALLEE_SAVED_FPR 76 + +#define FIRST_GREGISTER 0 +#define LAST_GREGISTER 28 +#define FIRST_FPREGISTER 29 +#define LAST_FPREGISTER 76 +#define NUMBER_OF_SPECIAL_REGISTERS 3 + +#define HAS_GR_PAIRS +#define HAS_FPR_PAIRS + +#define DOUBLE_WORD_GR_ALIGNMENT + +#undef SOFT_FLOAT + +#undef SINGLE_WORD_FPR_ALIGNMENT +#define SINGLE_WORD_FPR_SIZE 1 + +#define DOUBLE_WORD_FPR_ALIGNMENT +#define DOUBLE_WORD_FPR_SIZE 2 + +#define QUAD_WORD_FPR_ALIGNMENT +#define QUAD_WORD_FPR_SIZE 4 + +#define CPU_IS_SUPPORTED + +#if defined(INCLUDE_EMITTER) +#include "HPPAEmitter.h" +typedef HPPAEmitter MdEmitter; +#endif /* INCLUDE_EMITTER */ + +#endif /* _HPPA_CPU_H_ */ diff --git a/ef/Compiler/CodeGenerator/md/hppa/HPPAEmitter.cpp b/ef/Compiler/CodeGenerator/md/hppa/HPPAEmitter.cpp new file mode 100644 index 000000000000..6246d0c24c90 --- /dev/null +++ b/ef/Compiler/CodeGenerator/md/hppa/HPPAEmitter.cpp @@ -0,0 +1,1170 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#include "Fundamentals.h" +#include "prlog.h" +#include "prbit.h" + +#include "HPPAEmitter.h" +#include "HPPAInstruction.h" +#include "HPPAMul.h" +#include "HPPAFuncs.h" +#include "ControlGraph.h" +#include "hppa.nad.burg.h" +#include "NativeCodeCache.h" + +bool HPPAEmitter::initSpecialCallDone = false; + +/* + *----------------------------------------------------------------------- + * + * canUseDepi1 -- + * + * Return true if a DEPI can be used instead of an OR. If mask contains + * only one sequence of consecutives ONES then a depi can be emitted. + * e.g.: 0...01...10...0 | 0...01...1 | 1...10...0 + * + *----------------------------------------------------------------------- + */ +inline static bool +canUseDepi1(PRUint32 mask) +{ + // If bits are consecutives mask & -mask will generate one bit at the first bit found. + // By adding it to the consecutive bits it will generate one bit after the last found. + mask += mask & -mask; + // Test that only one bit is set. + return (mask & (mask - 1)) == 0; +} + +/* + *----------------------------------------------------------------------- + * + * canUseExtruOrDepi01 -- + * + * Return true if a DEPI or an EXTRU can be used instead of an AND. + * If mask contains only one sequence of consecutives ZEROS then a depi + * or an extru can be emitted. + * e.g.: 1...10...01...1 | 0...01...1 | 1...10...0 + * + *----------------------------------------------------------------------- + */ +inline static bool +canUseExtruOrDepi0(PRUint32 mask) +{ + // Same as canUseDepi1, with ~mask. + return canUseDepi1(~mask); +} + +void HPPAEmitter:: +emitPrimitive(Primitive& inPrimitive, NamedRule inRule) +{ + switch (inRule) + { + case emConst_I: + emitConst(inPrimitive, (*static_cast(&inPrimitive)).value); + break; + case emArg_I: + case emArg_L: + case emArg_F: + case emArg_D: + case emArg_A: + PR_ASSERT(false); + break; + case emResult_M: + case emArg_M: + break; + case emResult_I: + emitResult(inPrimitive); + break; + case emIfLt: + emitCondBranch(inPrimitive, hcL); + break; + case emIfULt: + emitCondBranch(inPrimitive, hcLu); + break; + case emIfEq: + case emIfUEq: + emitCondBranch(inPrimitive, hcE); + break; + case emIfLe: + emitCondBranch(inPrimitive, hcLe); + break; + case emIfULe: + emitCondBranch(inPrimitive, hcLeu); + break; + case emIfGt: + emitCondBranch(inPrimitive, hcG); + break; + case emIfUGt: + emitCondBranch(inPrimitive, hcGu); + break; + case emIfLgt: + case emIfNe: + emitCondBranch(inPrimitive, hcNe); + break; + case emIfGe: + emitCondBranch(inPrimitive, hcGe); + break; + case emIfUGe: + emitCondBranch(inPrimitive, hcGeu); + break; + case emIfOrd: + case emIfUnord: + PR_ASSERT(false); // Shouldn't happen with int edges... + break; + case emOr_I: + emitInstruction(inPrimitive, OR); + break; + case emOrI_I: + emitOrImm (inPrimitive, inPrimitive.nthInputConstant(1)); + break; + case emAnd_I: + emitInstruction(inPrimitive, AND); + break; + case emAndI_I: + emitAndImm (inPrimitive, inPrimitive.nthInputConstant(1)); + break; + case emXor_I: + emitInstruction(inPrimitive, XOR); + break; + case emXorI_I: + emitXorImm (inPrimitive, inPrimitive.nthInputConstant(1)); + break; + case emShAdd_IIndirect: + emitShAddIndirect(inPrimitive); + break; + case emAdd_I: + case emAdd_A: + emitInstruction(inPrimitive, ADDL); + break; + case emAddI_I: + case emAddI_A: + emitAddImm(inPrimitive, inPrimitive.nthInputConstant(1)); + break; + + UNIMP_CODE(BINARY_PRIMITIVE_SET(emMul, siSMul)); + case emDivI_I: + emitDivImm(inPrimitive, inPrimitive.nthInputConstant(1)); + break; + case emMulI_I: + emitMulImm(inPrimitive, inPrimitive.nthInputConstant(1)); + break; + case emModE_I: + emitSpecialCall(inPrimitive, RemI); + break; + case emShlI_I: + emitShlImm(inPrimitive, inPrimitive.nthInputConstant(1)); + break; + case emChkNull: + emitChkNull(inPrimitive); + break; + case emLimitR: + emitLimitR(inPrimitive); + break; + case emLimit: + emitLimit(inPrimitive); + break; + + case emLdC_IRegisterIndirect: + emitLoad(inPrimitive, HPPA_REGISTER_INDIRECT | HPPA_LOAD_CONSTANT); + break; + case emLd_IRegisterIndirect: + emitLoad(inPrimitive, HPPA_REGISTER_INDIRECT); + break; + case emLdC_I: + emitLoad(inPrimitive, HPPA_LOAD_CONSTANT); + break; + case emLd_I: + emitLoad(inPrimitive); + break; + case emSt_I: + emitStore(inPrimitive); + break; + case emStI_I: + emitStoreImm(inPrimitive); + break; + case emStI_IRegisterIndirect: + emitStoreImm(inPrimitive, HPPA_REGISTER_INDIRECT); + break; + case emSt_IRegisterIndirect: + emitStore(inPrimitive, HPPA_REGISTER_INDIRECT); + break; + + case emCallI_I: + case emCallI_L: + case emCallI_F: + case emCallI_D: + case emCallI_P: + UNIMP_CODE(emit_Call(inPrimitive)); + break; + + default: + //PR_ASSERT(false) + break; + } +} + +Instruction& HPPAEmitter:: +genInstruction(DataNode* inPrimitive, Pool& inPool, HPPAInstructionKind kind, HPPAInstructionFlags flags) +{ + PR_ASSERT(HPPA_isValidInsn(kind)); + + switch(hiInfo[kind].format) + { + case 1: + PR_ASSERT(hasIM14(flags)); + return *new(inPool) HPPAFormat1(inPrimitive, inPool, kind, flags); + + case 6: + return *new(inPool) HPPAFormat6(inPrimitive, inPool, kind); + + default: + PR_ASSERT(false); + } +} + +void HPPAEmitter:: +emitSpecialCall(Primitive& inPrimitive, HPPASpecialCallKind kind) +{ + Instruction& call = *new(mPool) HPPASpecialCall(&inPrimitive, mPool, kind, HPPA_NULLIFICATION); + HPPASpecialCallInfo& callInfo = hscInfo[kind]; + + for (PRUint8 i = 0; i < callInfo.nUses; i++) + { + Instruction& copy = *new(mPool) HPPACopy(&inPrimitive, mPool); + useProducer(inPrimitive.nthInputVariable(i), copy, 0); + VirtualRegister& vReg = defineTemporary(copy, 0); + vReg.preColorRegister(registerNumberToColor[arg0 - i]); + useTemporaryVR(call, vReg, i); + } + for (PRUint8 j = 0; j < callInfo.nDefines; j++) + { + Instruction& copy = *new(mPool) HPPACopy(&inPrimitive, mPool); + VirtualRegister& vReg = defineTemporary(call, j); + vReg.preColorRegister(registerNumberToColor[ret1 - j]); + useTemporaryVR(copy, vReg, 0); + defineProducer(nthOutputProducer(inPrimitive, j), copy, 0); + } +} + +void HPPAEmitter:: +emitShAddIndirect(Primitive& inPrimitive) +{ + // Need to get immediate argument from poShl_I producer's primitive + DataNode& immSource = inPrimitive.nthInput(1).getProducer().getNode(); + DataNode& shiftedProducer = immSource.nthInputVariable(0); + DataNode& addedProducer = inPrimitive.nthInputVariable(0); + DataNode& resultProducer = inPrimitive; + PRUint8 shiftBy = immSource.nthInputConstant(1).i; + + if (shiftBy == 0) + { + Instruction& addl = *new(mPool) HPPAAddl(&inPrimitive, mPool); + useProducer(addedProducer, addl, 0); + useProducer(shiftedProducer, addl, 1); + defineProducer(resultProducer, addl, 0); + } + else if (shiftBy <= 3) + { + Instruction& shiftAdd = genInstruction(&inPrimitive, mPool, shiftAddl[shiftBy]); + useProducer(shiftedProducer, shiftAdd, 0); + useProducer(addedProducer, shiftAdd, 1); + defineProducer(resultProducer, shiftAdd, 0); + } + else + { + Instruction& shift = *new(mPool) HPPAZdep(&inPrimitive, mPool, 31 - shiftBy, 32 - shiftBy); + useProducer(shiftedProducer, shift, 0); + defineProducer(immSource, shift, 0); + + Instruction& addl = *new(mPool) HPPAAddl(&inPrimitive, mPool); + useProducer(addedProducer, addl, 0); + useProducer(immSource, addl, 1); + defineProducer(resultProducer, addl, 0); + } +} + +void HPPAEmitter:: +emitStore(Primitive& inPrimitive, HPPAInstructionFlags flags) +{ + if (flags & HPPA_REGISTER_INDIRECT) + { + // Need to get immediate argument from poAdd_A producer's primitive + DataNode& immSource = inPrimitive.nthInput(1).getProducer().getNode(); + PRUint16 im14; + + if (extractIM14(immSource.nthInputConstant(1), im14)) + { + Instruction& store = *new(mPool) HPPAStore(&inPrimitive, mPool, STW, buildIM14(im14) | flags); + + useProducer(inPrimitive.nthInputVariable(0), store, 0); + useProducer(immSource.nthInputVariable(0), store, 1); + useProducer(inPrimitive.nthInputVariable(2), store, 2); + defineProducer(inPrimitive, store, 0); + } + else + { + emitAddImm(immSource, immSource.nthInputConstant(1)); + emitStore(inPrimitive, flags & ~HPPA_REGISTER_INDIRECT); + } + } + else + { + Instruction& store = *new(mPool) HPPAStore(&inPrimitive, mPool, STW, buildIM14(0) | flags); + store.standardUseDefine(*this); + } +} + +void HPPAEmitter:: +emitStoreToImm(Primitive& inPrimitive, HPPAInstructionFlags flags) +{ + PR_ASSERT((flags & HPPA_REGISTER_INDIRECT) == 0); + Instruction& store = *new(mPool) HPPAStore(&inPrimitive, mPool, STW, buildIM14(0) | flags); + VirtualRegister& constantVR = genLoadConstant(inPrimitive, inPrimitive.nthInputConstant(1)); + useProducer(inPrimitive.nthInputVariable(0), store, 0); + useTemporaryVR(store, constantVR, 1); + useProducer(inPrimitive.nthInputVariable(2), store, 2); + defineProducer(inPrimitive, store, 0); +} + +void HPPAEmitter:: +emitStoreImm(Primitive& inPrimitive, HPPAInstructionFlags flags) +{ + if (flags & HPPA_REGISTER_INDIRECT) + { + // Need to get immediate argument from poAdd_A producer's primitive + DataNode& immSource = inPrimitive.nthInput(1).getProducer().getNode(); + PRUint16 im14; + + if (extractIM14(immSource.nthInputConstant(1), im14)) + { + Instruction& store = *new(mPool) HPPAStore(&inPrimitive, mPool, STW, buildIM14(im14) | flags); + VirtualRegister& constantVR = genLoadConstant(inPrimitive, inPrimitive.nthInputConstant(2)); + + useProducer(inPrimitive.nthInputVariable(0), store, 0); + useProducer(immSource.nthInputVariable(0), store, 1); + useTemporaryVR(store, constantVR, 2); + defineProducer(inPrimitive, store, 0); + } + else + { + emitAddImm(immSource, immSource.nthInputConstant(1)); + emitStoreImm(inPrimitive, flags & ~HPPA_REGISTER_INDIRECT); + } + } + else + { + Instruction& store = *new(mPool) HPPAStore(&inPrimitive, mPool, STW, buildIM14(0) | flags); + VirtualRegister& constantVR = genLoadConstant(inPrimitive, inPrimitive.nthInputConstant(2)); + + useProducer(inPrimitive.nthInputVariable(0), store, 0); + useProducer(inPrimitive.nthInputVariable(1), store, 1); + useTemporaryVR(store, constantVR, 2); + defineProducer(inPrimitive, store, 0); + } +} + +void HPPAEmitter:: +emitStoreImmToImm(Primitive& inPrimitive, HPPAInstructionFlags flags) +{ + PR_ASSERT((flags & HPPA_REGISTER_INDIRECT) == 0); + Instruction& store = *new(mPool) HPPAStore(&inPrimitive, mPool, STW, buildIM14(0) | flags); + VirtualRegister& addressVR = genLoadConstant(inPrimitive, inPrimitive.nthInputConstant(1)); + VirtualRegister& constantVR = genLoadConstant(inPrimitive, inPrimitive.nthInputConstant(2)); + useProducer(inPrimitive.nthInputVariable(0), store, 0); + useTemporaryVR(store, addressVR, 1); + useTemporaryVR(store, constantVR, 2); + defineProducer(inPrimitive, store, 0); +} + +void HPPAEmitter:: +emitLoad(Primitive& inPrimitive, HPPAInstructionFlags flags) +{ + if (flags & HPPA_REGISTER_INDIRECT) + { + // Need to get immediate argument from poAdd_A producer's primitive + DataNode& immSource = inPrimitive.nthInput((flags & HPPA_LOAD_CONSTANT) ? 0 : 1).getProducer().getNode(); + PRUint16 im14; + + if (extractIM14(immSource.nthInputConstant(1), im14)) + { + Instruction& load = *new(mPool) HPPALoad(&inPrimitive, mPool, LDW, buildIM14(im14) | flags); + + useProducer(immSource.nthInputVariable(0), load, (flags & HPPA_LOAD_CONSTANT) ? 0 : 1); + if (!(flags & HPPA_LOAD_CONSTANT)) + useProducer(inPrimitive.nthInputVariable(0), load, 0); + + + defineProducer(inPrimitive, load, 0); + if (flags & HPPA_LOAD_VOLATILE) + defineProducer(nthOutputProducer(inPrimitive, 1), load, 1); + } + else + { + emitAddImm(immSource, immSource.nthInputConstant(1)); + emitLoad(inPrimitive, flags & ~HPPA_REGISTER_INDIRECT); + } + } + else + { + Instruction& load = *new(mPool) HPPALoad(&inPrimitive, mPool, LDW, buildIM14(0) | flags); + load.standardUseDefine(*this); + } +} + +void HPPAEmitter:: +emitLoadFromImm(Primitive& inPrimitive, HPPAInstructionFlags flags) +{ + PR_ASSERT((flags & HPPA_REGISTER_INDIRECT) == 0); + Instruction& load = *new(mPool) HPPALoad(&inPrimitive, mPool, LDW, buildIM14(0) | flags); + VirtualRegister& constantVR = genLoadConstant(inPrimitive, inPrimitive.nthInputConstant((flags & HPPA_LOAD_CONSTANT) ? 0 : 1)); + + if (!(flags & HPPA_LOAD_CONSTANT)) + useProducer(inPrimitive.nthInputVariable(0), load, 0); + useTemporaryVR(load, constantVR,(flags & HPPA_LOAD_CONSTANT) ? 0 : 1); + + defineProducer(inPrimitive, load, 0); + if (flags & HPPA_LOAD_VOLATILE) + defineProducer(nthOutputProducer(inPrimitive, 1), load, 1); +} + +VirtualRegister& HPPAEmitter:: +genLoadConstant(DataNode& inPrimitive, const Value& value, bool checkIM14) +{ + // It is possible to use the instruction zdepi to generate a constant. + // also zvdepi might be used if the constant is shifted after. + + PRUint16 im14; + if (checkIM14 && extractIM14(value, im14)) + { + Instruction& ldi = *new(mPool) HPPALdi(&inPrimitive, mPool, buildIM14(im14)); + return defineTemporary(ldi, 0); + } + else + { + Instruction& ldil = *new(mPool) HPPALdil(&inPrimitive, mPool, buildIM21(HPPA_LEFT(value.i))); + VirtualRegister& constantVR = defineTemporary(ldil, 0); + + if (HPPA_RIGHT(value.i) != 0) + { + Instruction& ldo = *new(mPool) HPPALdo(&inPrimitive, mPool, buildIM14(HPPA_RIGHT(value.i))); + useTemporaryVR(ldo, constantVR, 0); + redefineTemporary(ldo, constantVR, 0); + } + return constantVR; + } +} + +void HPPAEmitter:: +emitLimitR(Primitive& inPrimitive) +{ + ControlNode& endNode = inPrimitive.getContainer()->controlGraph.getEndNode(); + PRUint8 constant; + + if (extractIM5(inPrimitive.nthInputConstant(0), constant)) + { + Instruction& compare = *new(mPool) HPPACondBranch(&inPrimitive, mPool, endNode, COMIBF, hcLe, buildIM5(constant) | HPPA_NULLIFICATION); + useProducer(inPrimitive.nthInputVariable(1), compare, 0); + inPrimitive.setInstructionRoot(&compare); + } + else + { + Instruction& compare = *new(mPool) HPPACondBranch(&inPrimitive, mPool, endNode, COMBF, hcLe, HPPA_NULLIFICATION); + VirtualRegister& constantVR = genLoadConstant(inPrimitive, inPrimitive.nthInputConstant(0)); + + useProducer(inPrimitive.nthInputVariable(1), compare, 0); + useTemporaryVR(compare, constantVR, 1); + inPrimitive.setInstructionRoot(&compare); + } +} + +void HPPAEmitter:: +emitLimit(Primitive& inPrimitive) +{ + ControlNode& endNode = inPrimitive.getContainer()->controlGraph.getEndNode(); + Instruction& compare = *new(mPool) HPPACondBranch(&inPrimitive, mPool, endNode, COMBF, hcL, HPPA_NULLIFICATION); + compare.standardUseDefine(*this); +} + +void HPPAEmitter:: +emitChkNull(Primitive& inPrimitive) +{ + ControlNode& endNode = inPrimitive.getContainer()->controlGraph.getEndNode(); + Instruction& compare = *new(mPool) HPPACondBranch(&inPrimitive, mPool, endNode, COMIBT, hcE, buildIM5(0) | HPPA_NULLIFICATION); + compare.standardUseDefine(*this); +} + +void HPPAEmitter:: +emitResult(Primitive& inPrimitive) +{ + VirtualRegister* returnVr; + if (inPrimitive.nthInputIsConstant(0)) + { + returnVr = &genLoadConstant(inPrimitive, inPrimitive.nthInputConstant(0)); + } + else + { + Instruction& copy = *new(mPool) HPPACopy(&inPrimitive, mPool); + returnVr = &defineTemporary(copy, 0); + useProducer(inPrimitive.nthInputVariable(0), copy, 0); + } + + returnVr->preColorRegister(registerNumberToColor[ret0]); + + InsnExternalUse& externalUse = *new(mPool) InsnExternalUse(&inPrimitive, mPool, 1); + useTemporaryVR(externalUse, *returnVr, 0); + inPrimitive.setInstructionRoot(&externalUse); +} + +VirtualRegister& HPPAEmitter:: +genShiftAdd(Primitive& inPrimitive, const PRUint8 shiftBy, VirtualRegister& shiftedReg, VirtualRegister& addedReg) +{ + // will emit (shiftedReg << shiftBy) + addedReg + if (shiftBy == 0) + { + Instruction& addl = *new(mPool) HPPAAddl(&inPrimitive, mPool); + useTemporaryVR(addl, shiftedReg, 0); + useTemporaryVR(addl, addedReg, 1); + return defineTemporary(addl, 0); + } + else if (shiftBy <= 3) + { + Instruction& shiftAdd = genInstruction(&inPrimitive, mPool, shiftAddl[shiftBy]); + useTemporaryVR(shiftAdd, shiftedReg, 0); + useTemporaryVR(shiftAdd, addedReg, 1); + return defineTemporary(shiftAdd, 0); + } + else + { + Instruction& shift = *new(mPool) HPPAZdep(&inPrimitive, mPool, 31 - shiftBy, 32 - shiftBy); + useTemporaryVR(shift, shiftedReg, 0); + VirtualRegister& vReg = defineTemporary(shift, 0); + Instruction& addl = *new(mPool) HPPAAddl(&inPrimitive, mPool); + useTemporaryVR(addl, vReg, 0); + useTemporaryVR(addl, addedReg, 1); + return defineTemporary(addl, 0); + } +} + +VirtualRegister& HPPAEmitter:: +genShiftSub(Primitive& inPrimitive, const PRUint8 shiftBy, VirtualRegister& shiftedReg, VirtualRegister& subtractedReg, bool neg) +{ + // will emit (shiftedReg << shiftBy) - subtractedReg OR subtractedReg - (shiftedReg << shiftBy) if neg is true. + PRUint8 shiftedPos = neg ? 1 : 0; + PRUint8 subPos = neg ? 0 : 1; + + if (shiftBy == 0) + { + Instruction& sub = *new(mPool) HPPASub(&inPrimitive, mPool); + useTemporaryVR(sub, shiftedReg, shiftedPos); + useTemporaryVR(sub, subtractedReg, subPos); + return defineTemporary(sub, 0); + } + else + { + Instruction& shift = *new(mPool) HPPAZdep(&inPrimitive, mPool, 31 - shiftBy, 32 - shiftBy); + useTemporaryVR(shift, shiftedReg, 0); + VirtualRegister& vReg = defineTemporary(shift, 0); + Instruction& sub = *new(mPool) HPPASub(&inPrimitive, mPool); + useTemporaryVR(sub, vReg, shiftedPos); + useTemporaryVR(sub, subtractedReg, subPos); + return defineTemporary(sub, 0); + } +} + +void HPPAEmitter:: +emitMulImm(Primitive& inPrimitive, const Value& value) +{ + enum MethodType + { + mRegular, + mOpposite, + mAddMultiplicand + }; + + MulAlgorithm algorithm, tempAlgorithm; + VirtualRegister* accum; + VirtualRegister* multiplicand; + MethodType methodType = mRegular; + PRUint8 mulCost = 30; // is it true for all the pa proc ? + DEBUG_ONLY(PRInt32 val;) + + // Try the multiplication by value.i + getMulAlgorithm(&algorithm, value.i, mulCost); + + // Try the multiplication by -value.i + getMulAlgorithm(&tempAlgorithm, -value.i, mulCost - 4); + if ((tempAlgorithm.cost + 4) < algorithm.cost) + { + algorithm = tempAlgorithm; + algorithm.cost += 4; // cost for neg. + methodType = mOpposite; + } + + // Try the multiplication by value.i-1 + getMulAlgorithm(&tempAlgorithm, value.i - 1, mulCost); + if ((tempAlgorithm.cost + 4) < algorithm.cost) + { + algorithm = tempAlgorithm; + algorithm.cost += 4; // cost for ldo. + methodType = mAddMultiplicand; + } + + if (algorithm.cost < mulCost) + { + // found a cheaper way to do the multiply. + if (algorithm.operations[0] == maZero) + { + Instruction& ldi = *new(mPool) HPPALdi(&inPrimitive, mPool, buildIM14(0)); + defineProducer(inPrimitive, ldi, 0); + return; + } + else if (algorithm.operations[0] == maMultiplicand) + { + Instruction& copy = *new(mPool) HPPACopy(&inPrimitive, mPool); + useProducer(inPrimitive.nthInputVariable(0), copy, 0); + accum = &defineTemporary(copy, 0); + DEBUG_ONLY(val = 1;) + } + else + { + PR_ASSERT(false); // there is an error in getMulAlgorithm. + } + + multiplicand = inPrimitive.nthInputVariable(0).getVirtualRegisterAnnotation(); + for (PRUint8 n = 1; n < algorithm.nOperations; n++) + { + PRUint8 shiftBy = algorithm.shiftAmount[n]; + + switch (algorithm.operations[n]) + { + case maShiftValue: // accum = accum << shiftBy + { + Instruction& zdep = *new(mPool) HPPAZdep(&inPrimitive, mPool, 31 - shiftBy, 32 - shiftBy); + useTemporaryVR(zdep, *accum, 0); + accum = &defineTemporary(zdep, 0); + DEBUG_ONLY(val <<= shiftBy); + } + break; + + case maAddValueToShiftMultiplicand: // accum = accum + (multiplicand << shiftBy) + accum = &genShiftAdd(inPrimitive, shiftBy, *multiplicand, *accum); + DEBUG_ONLY(val += (1 << shiftBy);) + break; + + case maSubShiftMultiplicandFromValue: // accum = accum - (multiplicand << shiftBy) + accum = &genShiftSub(inPrimitive, shiftBy, *multiplicand, *accum, true); + DEBUG_ONLY(val -= (1 << shiftBy);) + break; + + case maAddValueToShiftValue: // accum = (accum << shiftBy) + accum + accum = &genShiftAdd(inPrimitive, shiftBy, *accum, *accum); + DEBUG_ONLY(val += (val << shiftBy);) + break; + + case maSubValueFromShiftValue: // accum = (accum << shiftBy) - accum + accum = &genShiftSub(inPrimitive, shiftBy, *accum, *accum, false); + DEBUG_ONLY(val = (val << shiftBy) - val;) + break; + + case maAddMultiplicandToShiftValue: // accum = (accum << shiftBy) + multiplicand + accum = &genShiftAdd(inPrimitive, shiftBy, *accum, *multiplicand); + DEBUG_ONLY(val = (val << shiftBy) + 1;) + break; + + case maSubMultiplicandFromShiftValue: // accum = (accum << shiftBy) - multiplicand + accum = &genShiftSub(inPrimitive, shiftBy, *accum, *multiplicand, false); + DEBUG_ONLY(val = (val << shiftBy) - 1;) + break; + + default: + PR_ASSERT(false); // there is an error in getMulAlgorithm + } + } + + switch (methodType) + { + case mRegular: + defineProducerWithExistingVirtualRegister(*accum, inPrimitive, + *accum->getDefiningInstruction(), 0); + break; + case mOpposite: + { + Instruction& neg = *new(mPool) HPPASub(&inPrimitive, mPool, HPPA_R1_IS_ZERO); + useTemporaryVR(neg, *accum, 0); + defineProducer(inPrimitive, neg, 0); + DEBUG_ONLY(val = -val;) + } + break; + case mAddMultiplicand: + { + Instruction& addl = *new(mPool) HPPAAddl(&inPrimitive, mPool); + useTemporaryVR(addl, *accum, 0); + useTemporaryVR(addl, *multiplicand, 1); + defineProducer(inPrimitive, addl, 0); + DEBUG_ONLY(val = val + 1;) + } + break; + } + DEBUG_ONLY(PR_ASSERT(val = value.i);) + } + else + { + Instruction& xmpyu = *new(mPool) HPPAXmpyu(&inPrimitive, mPool); + VirtualRegister& constantVR = genLoadConstant(inPrimitive, value); + + useProducer(inPrimitive.nthInputVariable(0), xmpyu, 0, vrcFixedPoint); + useTemporaryVR(xmpyu, constantVR, 1, vrcFixedPoint); + defineProducer(inPrimitive, xmpyu, 0, vrcFixedPoint); + } +} + +void HPPAEmitter:: +emitDivImm(Primitive& inPrimitive, const Value& value) +{ + PRUint32 shift = value.i; + if(shift != 0 && (shift & (shift - 1)) == 0) + { + PRUint8 shiftBy; + PR_FLOOR_LOG2(shiftBy, shift); + + Instruction& extru = *new(mPool) HPPAExtru(&inPrimitive, mPool, 0, 1); + useProducer(inPrimitive.nthInputVariable(0), extru, 0); + VirtualRegister& tempVR = defineTemporary(extru, 0); + + Instruction& addl = *new(mPool) HPPAAddl(&inPrimitive, mPool); + useProducer(inPrimitive.nthInputVariable(0), addl, 0); + useTemporaryVR(addl, tempVR, 1); + redefineTemporary(addl, tempVR, 0); + + Instruction& extrs = *new(mPool) HPPAExtrs(&inPrimitive, mPool, 31 - shiftBy, 32 - shiftBy); + useTemporaryVR(extrs, tempVR, 0); + defineProducer(inPrimitive, extrs, 0); + } + else + { + PR_ASSERT(false); // FIXME + } +} + +void HPPAEmitter:: +emitAddImm(DataNode& inPrimitive, const Value& value) +{ + PRUint16 im14; + if(extractIM14(value, im14)) + { + Instruction& add = *new(mPool) HPPALdo(&inPrimitive, mPool, buildIM14(im14)); + add.standardUseDefine(*this); + } + else + { + Instruction& addl = *new(mPool) HPPAAddl(&inPrimitive, mPool); + VirtualRegister& constantVR = genLoadConstant(inPrimitive, value); + + useProducer(inPrimitive.nthInputVariable(0), addl, 0); + useTemporaryVR(addl, constantVR, 1); + defineProducer(inPrimitive, addl, 0); + } +} + +void HPPAEmitter:: +emitConst(Primitive& inPrimitive, const Value& value) +{ + PRUint16 im14; + if (extractIM14(value, im14)) + { + Instruction& ldi = *new(mPool) HPPALdi(&inPrimitive, mPool, buildIM14(im14)); + ldi.standardUseDefine(*this); + } + else + { + Instruction& ldil = *new(mPool) HPPALdil(&inPrimitive, mPool, buildIM21(HPPA_LEFT(value.i))); + VirtualRegister& vReg = *defineProducer(inPrimitive, ldil, 0); + + if (HPPA_RIGHT(value.i) != 0) + { + Instruction& ldo = *new(mPool) HPPALdo(&inPrimitive, mPool, buildIM14(HPPA_RIGHT(value.i))); + useTemporaryVR(ldo, vReg, 0); + redefineTemporary(ldo, vReg, 0); + } + } +} + +void HPPAEmitter:: +emitShlImm(Primitive& inPrimitive, const Value& value) +{ + Instruction& zdep = *new(mPool) HPPAZdep(&inPrimitive, mPool, 31 - value.i, 32 - value.i); + zdep.standardUseDefine(*this); +} + +void HPPAEmitter:: +emitAndImm(Primitive& inPrimitive, const Value& value) +{ + if (canUseExtruOrDepi0(value.i)) + { + PRUint32 mask = value.i; + PRUint8 ls0, ls1, ms0, p, len; + + // count the number of low ONES + for (ls0 = 0; ls0 < 32; ls0++) + if ((mask & (1 << ls0)) == 0) + break; + + // count the number of middle ZEROS + for (ls1 = ls0; ls1 < 32; ls1++) + if ((mask & (1 << ls1)) != 0) + break; + + // count then number of high ONES + for (ms0 = ls1; ms0 < 32; ms0++) + if ((mask & (1 << ms0)) == 0) + break; + + // Be sure that we counted all the bits + PR_ASSERT(ms0 == 32); + + if (ls1 == 32) + { + // The sequence is 0...01...1 + len = ls0; + PR_ASSERT(len); + + Instruction& extru = *new(mPool) HPPAExtru(&inPrimitive, mPool, 31, len); + extru.standardUseDefine(*this); + } + else + { + // The sequence is 1...10...01...1 | 1...10...0 + p = 31 - ls0; + len = ls1 - ls0; + + Instruction& copy = *new(mPool) HPPACopy(&inPrimitive, mPool); + useProducer(inPrimitive.nthInputVariable(0), copy, 0); + VirtualRegister& vReg = *defineProducer(inPrimitive, copy, 0); + + Instruction& depi = *new(mPool) HPPADepi(&inPrimitive, mPool, 31 - p, 32 - len, buildIM5(0)); + useTemporaryVR(depi, vReg, 0); + redefineTemporary(depi, vReg, 0); + } + } + else + { + // No optimization is possible. Emit the regular AND with a load constant before. + Instruction& andInsn = *new(mPool) HPPAAnd(&inPrimitive, mPool); + VirtualRegister& constantVR = genLoadConstant(inPrimitive, value); + + useProducer(inPrimitive.nthInputVariable(0), andInsn, 0); + useTemporaryVR(andInsn, constantVR, 1); + defineProducer(inPrimitive, andInsn, 0); + } +} + +void HPPAEmitter:: +emitXorImm(Primitive& inPrimitive, const Value& value) +{ + Instruction& xorInsn = *new(mPool) HPPAXor(&inPrimitive, mPool); + VirtualRegister& constantVR = genLoadConstant(inPrimitive, value); + + useProducer(inPrimitive.nthInputVariable(0), xorInsn, 0); + useTemporaryVR(xorInsn, constantVR, 1); + defineProducer(inPrimitive, xorInsn, 0); +} + +void HPPAEmitter:: +emitOrImm(Primitive& inPrimitive, const Value& value) +{ + if (canUseDepi1(value.i)) + { + // We can emit a depi instruction. + PRUint32 mask = value.i; + PRUint8 bs0, bs1, p, len; + + // Count the number of low ZEROS. + for (bs0 = 0; bs0 < 32; bs0++) + if ((mask & (1 << bs0)) != 0) + break; + + // Count the number of middle ONES + for (bs1 = bs0; bs1 < 32; bs1++) + if ((mask & (1 << bs1)) == 0) + break; + + // Be sure that we counted all bits in the sequence. x...x1...10...0 | x...x1...1 + // where x...x must be 0...0 + PR_ASSERT(((bs1 == 32) || (((PRUint32) 1 << bs1) > mask))); + + p = 31 - bs0; + len = bs1 - bs0; + + Instruction& copy = *new(mPool) HPPACopy(&inPrimitive, mPool); + useProducer(inPrimitive.nthInputVariable(0), copy, 0); + VirtualRegister& vReg = *defineProducer(inPrimitive, copy, 0); + + Instruction& depi = *new(mPool) HPPADepi(&inPrimitive, mPool, 31 - p, 32 - len, buildIM5(-1)); + useTemporaryVR(depi, vReg, 0); + redefineTemporary(depi, vReg, 0); + } + else + { + // No optimization is possible. Emit the regular OR with a load constant before. + Instruction& orInsn = *new(mPool) HPPAOr(&inPrimitive, mPool); + VirtualRegister& constantVR = genLoadConstant(inPrimitive, value); + + useProducer(inPrimitive.nthInputVariable(0), orInsn, 0); + useTemporaryVR(orInsn, constantVR, 1); + defineProducer(inPrimitive, orInsn, 0); + } +} + +void HPPAEmitter:: +emitInstruction(Primitive& inPrimitive, HPPAInstructionKind kind) +{ + Instruction& newInsn = genInstruction(&inPrimitive, mPool, kind); + newInsn.standardUseDefine(*this); +} + +void HPPAEmitter:: +emitArguments(ControlBegin& inBeginNode) +{ + PRUint32 curParamWords; // number of words of argument space used + PRUint32 curFloatingPointArg; // number of floating point arguments + + InsnExternalDefine& defineInsn = *new(mPool) InsnExternalDefine(&inBeginNode.arguments[0], mPool, inBeginNode.nArguments * 2); + + PRUint32 curArgIdx; // current index into the arguments in the ControlBegin + + curParamWords = 0; + curFloatingPointArg = 0; + for (curArgIdx = 0; curArgIdx < inBeginNode.nArguments && curParamWords < 4; curArgIdx++) + { + PrimArg& curArg = inBeginNode.arguments[curArgIdx]; + + switch (curArg.getOperation()) + { + case poArg_I: + case poArg_A: + { + Instruction& copyInsn = *new(mPool) HPPACopy(&curArg, mPool); + + // hook up this vr to the external define FIX-ME + VirtualRegister& inputVr = defineTemporary(defineInsn, curArgIdx); + inputVr.preColorRegister(registerNumberToColor[arg0-curParamWords]); + + // emit the copy + useTemporaryVR(copyInsn, inputVr, 0); + defineProducer(curArg, copyInsn, 0); + + curParamWords++; + break; + } + case poArg_L: + PR_ASSERT(false); // FIXME + + case poArg_F: + PR_ASSERT(false); // FIXME + + case poArg_D: + PR_ASSERT(false); // FIXME + + break; + + case poArg_M: + break; + + default: + PR_ASSERT(false); // Should not happen + break; + } + } + + // continue counting from before + // make all the rest of the defines as type none + for (;curArgIdx < inBeginNode.nArguments * 2; curArgIdx++) + { + defineInsn.getInstructionDefineBegin()[curArgIdx].kind = udNone; + } + // check for half stack half reg case +} + +void HPPAEmitter:: +emitCondBranch(Primitive& inPrimitive, HPPAConditionKind kind) +{ + ControlNode& target = ControlIf::cast(*inPrimitive.getContainer())->getTrueIfEdge().target; + DataNode& compare = inPrimitive.nthInput(0).getProducer().getNode(); // get the compare. + PRUint8 constant; + bool negate = hcInfo[kind].f; + + switch (compare.getOperation()) + { + case poCmpU_I: + case poCmpU_A: + case poCmp_I: + { + Instruction& cb = *new(mPool) HPPACondBranch(&inPrimitive, mPool, target, negate ? COMBF : COMBT, + negate ? HPPAConditionKind(kind & 7) : kind, HPPA_NULLIFICATION); + useProducer(compare.nthInputVariable(0), cb, 0); + useProducer(compare.nthInputVariable(1), cb, 1); + inPrimitive.setInstructionRoot(&cb); + } + break; + + case poCmpUI_I: + case poCmpUI_A: + case poCmpI_I: + if (extractIM5(compare.nthInputConstant(1), constant)) + { + kind = hcInfo[kind].swapped; + negate = hcInfo[kind].f; + Instruction& cb = *new(mPool) HPPACondBranch(&inPrimitive, mPool, target, negate ? COMIBF : COMIBT, + negate ? HPPAConditionKind(kind & 7) : kind, buildIM5(constant) + | HPPA_NULLIFICATION); + useProducer(compare.nthInputVariable(0), cb, 0); + inPrimitive.setInstructionRoot(&cb); + } + else + { + Instruction& cb = *new(mPool) HPPACondBranch(&inPrimitive, mPool, target, negate ? COMBF : COMBT, + negate ? HPPAConditionKind(kind & 7) : kind, HPPA_NULLIFICATION); + VirtualRegister& constantVR = genLoadConstant(compare, compare.nthInputConstant(1)); + useProducer(compare.nthInputVariable(0), cb, 0); + useTemporaryVR(cb, constantVR, 1); + inPrimitive.setInstructionRoot(&cb); + } + break; + + case poCmp_L: + case poCmpU_L: + case poFCmp_F: + case poFCmp_D: + case poConst_C: + default: + PR_ASSERT(false); // FIXME + break; + } +} + +bool HPPAEmitter:: +emitCopyAfter(DataNode& inDataNode, SortedDoublyLinkedList::iterator where, VirtualRegister& fromVr, VirtualRegister& toVr) +{ +#define COPY_KIND(fc, tc) ((((fc) & 0xff) << 8) | ((tc) & 0xff)) + + PRUint32 copyKind = COPY_KIND(fromVr.getClass(),toVr.getClass()); + + switch(copyKind) + { + case COPY_KIND(vrcInteger, vrcInteger): + { + Instruction& copy = *new(mPool) HPPACopy(&inDataNode, mPool); + copy.addUse(0, fromVr); + copy.addDefine(0, toVr); + toVr.setDefiningInstruction(copy); + + where->append(copy); + } + return false; + + case COPY_KIND(vrcInteger, vrcFixedPoint): + { + Instruction& intStore = *new(mPool) HPPAStoreIntegerToConvertStackSlot(&inDataNode, mPool, fromVr); + Instruction& fixedLoad = *new(mPool) HPPALoadFixedPointFromConvertStackSlot(&inDataNode, mPool, toVr); + toVr.setDefiningInstruction(fixedLoad); + // FIXME use & def + + where->append(intStore); + intStore.append(fixedLoad); + } + return true; + + case COPY_KIND(vrcFixedPoint, vrcInteger): + { + Instruction& fixedStore = *new(mPool) HPPAStoreFixedPointToConvertStackSlot(&inDataNode, mPool, fromVr); + Instruction& intLoad = *new(mPool) HPPALoadIntegerFromConvertStackSlot(&inDataNode, mPool, toVr); + toVr.setDefiningInstruction(intLoad); + // FIXME use & def + + where->append(fixedStore); + fixedStore.append(intLoad); + } + return true; + + default: + fprintf(stdout, "unhandled copy %d->%d\n", fromVr.getClass(), toVr.getClass()); + return false; + } +#undef COPY_KIND +} + +Instruction& HPPAEmitter:: +emitAbsoluteBranch(DataNode& inDataNode, ControlNode& inTarget) +{ + Instruction& branch = *new(mPool) HPPAAbsoluteBranch(&inDataNode, mPool, inTarget, BL, HPPA_NULLIFICATION); + return branch; +} + +void HPPAEmitter:: +initSpecialCall() +{ +#if defined(hppa) + PRUint32* codeSpaceBase = HPPASpecialCodeBegin; + PRUint32* codeSpaceLimit = HPPASpecialCodeEnd; + PRUint32 specialCodeSize = (codeSpaceLimit - codeSpaceBase) * sizeof(PRUint32); + + PRUint32* specialCode = (PRUint32 *) NativeCodeCache::getCache().acquireMemory(specialCodeSize + 4); + specialCode = (PRUint32 *) (((PRUint32) specialCode) + 3 & -4); // round up + + copy(codeSpaceBase, codeSpaceLimit, specialCode); + + for (PRUint8 i = 0; i < nSpecialCalls; i++) + { + PRUint32 offset = ((PRUint32 *) hscInfo[i].address) - codeSpaceBase; + MethodDescriptor md(hscInfo[i].string); + + NativeCodeCache::getCache().mapMemoryToMethod(md, (void *) &specialCode[offset]); +#ifdef DEBUG + hscInfo[i].address = (void *) &specialCode[offset]; +#endif /* DEBUG */ + + } + +#endif /* defined(hppa) */ +} + +void HPPAEmitter:: +formatPrologToMemory(void* inWhere) +{ + PRUint32* prolog = (PRUint32 *) inWhere; + + // 00: where + 00000008 + // 04: 00000000 + // 08: bl <+0x10>, %rp 0xe8400020 + // 0c: nop 0x08000240 + // 10: ldw -18(%sr0,%sp),%rp 0x4bc23fd1 + // 14: ldsid (%sr0,%rp),%r1 0x004010a1 + // 18: mtsp %r1,%sr0 0x00011820 + // 1c: be,n 0(%sr0,%rp) 0xe0400002 + // 20: ..... func .... + + prolog[0] = ((PRUint32) prolog) + 8; + prolog[1] = 0x00000000; + prolog[2] = 0xe8400020; + prolog[3] = 0x08000240; + prolog[4] = 0x4bc23fd1; + prolog[5] = 0x004010a1; + prolog[6] = 0x00011820; + prolog[7] = 0xe0400002; +} diff --git a/ef/Compiler/CodeGenerator/md/hppa/HPPAEmitter.h b/ef/Compiler/CodeGenerator/md/hppa/HPPAEmitter.h new file mode 100644 index 000000000000..1f935c765ae4 --- /dev/null +++ b/ef/Compiler/CodeGenerator/md/hppa/HPPAEmitter.h @@ -0,0 +1,103 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#ifndef _HPPA_EMITTER_H_ +#define _HPPA_EMITTER_H_ + +#include "InstructionEmitter.h" +#include "HPPAInstruction.h" +#include "VirtualRegister.h" +#include "FastBitSet.h" + +class PrimArg; +class Pool; + +#define UNDEFINED_RULE(inRuleKind) \ + case inRuleKind: \ + PR_ASSERT(false); \ + break; + +#define UNIMP_CODE(a) + +/* + *----------------------------------------------------------------------- + * + * HPPA-1.1 Instruction Emitter. + * + *----------------------------------------------------------------------- + */ +class HPPAEmitter : public InstructionEmitter +{ +protected: + Instruction& genInstruction(DataNode* inPrimitive, Pool& inPool, HPPAInstructionKind kind, PRUint32 data = 0); + + void emitInstruction(Primitive& inPrimitive, HPPAInstructionKind kind); + void emitCondBranch(Primitive& inPrimitive, HPPAConditionKind kind); + void emitOrImm(Primitive& inPrimitive, const Value& value); + void emitAndImm(Primitive& inPrimitive, const Value& value); + void emitXorImm(Primitive& inPrimitive, const Value& value); + void emitAddImm(DataNode& inPrimitive, const Value& value); + void emitDivImm(Primitive& inPrimitive, const Value& value); + void emitMulImm(Primitive& inPrimitive, const Value& value); + void emitShlImm(Primitive& inPrimitive, const Value& value); + void emitConst(Primitive& inPrimitive, const Value& value); + void emitResult(Primitive& inPrimitive); + void emitChkNull(Primitive& inPrimitive); + void emitLimitR(Primitive& inPrimitive); + void emitLimit(Primitive& inPrimitive); + void emitLoad(Primitive& inPrimitive, HPPAInstructionFlags flags = HPPA_NONE); + void emitLoadFromImm(Primitive& inPrimitive, HPPAInstructionFlags flags = HPPA_NONE); + void emitStore(Primitive& inPrimitive, HPPAInstructionFlags flags = HPPA_NONE); + void emitStoreImm(Primitive& inPrimitive, HPPAInstructionFlags flags = HPPA_NONE); + void emitStoreToImm(Primitive& inPrimitive, HPPAInstructionFlags flags = HPPA_NONE); + void emitStoreImmToImm(Primitive& inPrimitive, HPPAInstructionFlags flags = HPPA_NONE); + void emitShAddIndirect(Primitive& inPrimitive); + void emitSpecialCall(Primitive& inPrimitive, HPPASpecialCallKind kind); + + VirtualRegister& genLoadConstant(DataNode& inPrimitive, const Value& value, bool checkIM14 = true); + VirtualRegister& genShiftAdd(Primitive& inPrimitive, const PRUint8 shiftBy, VirtualRegister& shiftedReg, VirtualRegister& addedReg); + VirtualRegister& genShiftSub(Primitive& inPrimitive, const PRUint8 shiftBy, VirtualRegister& shiftedReg, VirtualRegister& subtractedReg, bool neg = false); + + static void initSpecialCall(); + static bool initSpecialCallDone; + +public: + HPPAEmitter(Pool& inPool, VirtualRegisterManager& vrMan) : InstructionEmitter(inPool, vrMan) + { + if (!initSpecialCallDone) + { + initSpecialCallDone = true; + initSpecialCall(); + } + } + + virtual void emitPrimitive(Primitive& inPrimitive, NamedRule inRule); + + void calculatePrologEpilog(Method& /*inMethod*/, uint32& outPrologSize, uint32& outEpilogSize) {outPrologSize = 32; outEpilogSize = 4;} + virtual void formatPrologToMemory(void* inWhere); + virtual void formatEpilogToMemory(void* inWhere) {*(PRUint32*)inWhere = 0xe840c002; /* bv,n 0(%rp) */} + + virtual void emitArgument(PrimArg& /*inArguments*/, const PRUint32 /*inArgumentIndex*/) {} + virtual void emitArguments(ControlBegin& inBeginNode); + virtual Instruction& emitAbsoluteBranch(DataNode& inDataNode, ControlNode& inTarget); + virtual bool emitCopyAfter(DataNode& inDataNode, SortedDoublyLinkedList::iterator where, VirtualRegister& fromVr, VirtualRegister& toVr); + virtual void emitLoadAfter(DataNode& /*inDataNode*/, SortedDoublyLinkedList::iterator /*where*/, VirtualRegister& /*loadedReg*/, VirtualRegister& /*stackReg*/) {} + virtual void emitStoreAfter(DataNode& /*inDataNode*/, SortedDoublyLinkedList::iterator /*where*/, VirtualRegister& /*storedReg*/, VirtualRegister& /*stackReg*/) {} +}; + +#endif /* _HPPA_EMITTER_H_ */ diff --git a/ef/Compiler/CodeGenerator/md/hppa/HPPAFuncs.h b/ef/Compiler/CodeGenerator/md/hppa/HPPAFuncs.h new file mode 100644 index 000000000000..c988ad24619c --- /dev/null +++ b/ef/Compiler/CodeGenerator/md/hppa/HPPAFuncs.h @@ -0,0 +1,43 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#ifndef _HPPA_FUNCS_H_ +#define _HPPA_FUNCS_H_ + +#include "prtypes.h" + + +#if defined(hppa) +#define HPPAFuncAddress(func) (func) +#else +#define HPPAFuncAddress(func) NULL +#endif /* defined(hppa) */ + +PR_BEGIN_EXTERN_C + +extern PRUint32* HPPASpecialCodeBegin; +extern PRUint32* HPPASpecialCodeEnd; + +extern PRUint32* HPPAremI; +extern PRUint32* HPPAremU; +extern PRUint32* HPPAdivI; +extern PRUint32* HPPAdivU; + +PR_END_EXTERN_C + +#endif /* _HPPA_FUNCS_H_ */ diff --git a/ef/Compiler/CodeGenerator/md/hppa/HPPAFuncs.s b/ef/Compiler/CodeGenerator/md/hppa/HPPAFuncs.s new file mode 100644 index 000000000000..dd7f2252ccca --- /dev/null +++ b/ef/Compiler/CodeGenerator/md/hppa/HPPAFuncs.s @@ -0,0 +1,694 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + .SPACE $PRIVATE$ + .SUBSPA $DATA$ + + .align 4 + .EXPORT HPPAremI,DATA +HPPAremI: + .long _remI + + .EXPORT HPPAremU,DATA +HPPAremU: + .long _remU + + .EXPORT HPPAdivI,DATA +HPPAdivI: + .long _divI + + .EXPORT HPPAdivU,DATA +HPPAdivU: + .long _divU + + .EXPORT HPPASpecialCodeBegin,DATA +HPPASpecialCodeBegin: + .long _begin + + .EXPORT HPPASpecialCodeEnd,DATA +HPPASpecialCodeEnd: + .long _end + + .SPACE $TEXT$ + .SUBSPA $CODE$ + + .align 4 +_begin: + +_remI: + addit,= 0,%arg1,%r0 + add,>= %r0,%arg0,%ret1 + sub %r0,%ret1,%ret1 + sub %r0,%arg1,%r1 + ds %r0,%r1,%r0 + copy %r0,%r1 + add %ret1,%ret1,%ret1 + ds %r1,%arg1,%r1 + addc %ret1,%ret1,%ret1 + ds %r1,%arg1,%r1 + addc %ret1,%ret1,%ret1 + ds %r1,%arg1,%r1 + addc %ret1,%ret1,%ret1 + ds %r1,%arg1,%r1 + addc %ret1,%ret1,%ret1 + ds %r1,%arg1,%r1 + addc %ret1,%ret1,%ret1 + ds %r1,%arg1,%r1 + addc %ret1,%ret1,%ret1 + ds %r1,%arg1,%r1 + addc %ret1,%ret1,%ret1 + ds %r1,%arg1,%r1 + addc %ret1,%ret1,%ret1 + ds %r1,%arg1,%r1 + addc %ret1,%ret1,%ret1 + ds %r1,%arg1,%r1 + addc %ret1,%ret1,%ret1 + ds %r1,%arg1,%r1 + addc %ret1,%ret1,%ret1 + ds %r1,%arg1,%r1 + addc %ret1,%ret1,%ret1 + ds %r1,%arg1,%r1 + addc %ret1,%ret1,%ret1 + ds %r1,%arg1,%r1 + addc %ret1,%ret1,%ret1 + ds %r1,%arg1,%r1 + addc %ret1,%ret1,%ret1 + ds %r1,%arg1,%r1 + addc %ret1,%ret1,%ret1 + ds %r1,%arg1,%r1 + addc %ret1,%ret1,%ret1 + ds %r1,%arg1,%r1 + addc %ret1,%ret1,%ret1 + ds %r1,%arg1,%r1 + addc %ret1,%ret1,%ret1 + ds %r1,%arg1,%r1 + addc %ret1,%ret1,%ret1 + ds %r1,%arg1,%r1 + addc %ret1,%ret1,%ret1 + ds %r1,%arg1,%r1 + addc %ret1,%ret1,%ret1 + ds %r1,%arg1,%r1 + addc %ret1,%ret1,%ret1 + ds %r1,%arg1,%r1 + addc %ret1,%ret1,%ret1 + ds %r1,%arg1,%r1 + addc %ret1,%ret1,%ret1 + ds %r1,%arg1,%r1 + addc %ret1,%ret1,%ret1 + ds %r1,%arg1,%r1 + addc %ret1,%ret1,%ret1 + ds %r1,%arg1,%r1 + addc %ret1,%ret1,%ret1 + ds %r1,%arg1,%r1 + addc %ret1,%ret1,%ret1 + ds %r1,%arg1,%r1 + addc %ret1,%ret1,%ret1 + ds %r1,%arg1,%r1 + addc %ret1,%ret1,%ret1 + ds %r1,%arg1,%r1 + addc %ret1,%ret1,%ret1 + movb,>=,n %r1,%ret1,L5 + add,< %arg1,%r0,%r0 + add,tr %r1,%arg1,%ret1 + sub %r1,%arg1,%ret1 +L5: add,>= %arg0,%r0,%r0 + sub %r0,%ret1,%ret1 + bv %r0(%r31) + nop + + .align 4 +_remU: + comibf,<,n 0x0,%arg1,_remU_special_case + sub %r0,%arg1,%ret1 + ds %r0,%ret1,%r0 + add %arg0,%arg0,%r1 + ds %r0,%arg1,%ret1 + addc %r1,%r1,%r1 + ds %ret1,%arg1,%ret1 + addc %r1,%r1,%r1 + ds %ret1,%arg1,%ret1 + addc %r1,%r1,%r1 + ds %ret1,%arg1,%ret1 + addc %r1,%r1,%r1 + ds %ret1,%arg1,%ret1 + addc %r1,%r1,%r1 + ds %ret1,%arg1,%ret1 + addc %r1,%r1,%r1 + ds %ret1,%arg1,%ret1 + addc %r1,%r1,%r1 + ds %ret1,%arg1,%ret1 + addc %r1,%r1,%r1 + ds %ret1,%arg1,%ret1 + addc %r1,%r1,%r1 + ds %ret1,%arg1,%ret1 + addc %r1,%r1,%r1 + ds %ret1,%arg1,%ret1 + addc %r1,%r1,%r1 + ds %ret1,%arg1,%ret1 + addc %r1,%r1,%r1 + ds %ret1,%arg1,%ret1 + addc %r1,%r1,%r1 + ds %ret1,%arg1,%ret1 + addc %r1,%r1,%r1 + ds %ret1,%arg1,%ret1 + addc %r1,%r1,%r1 + ds %ret1,%arg1,%ret1 + addc %r1,%r1,%r1 + ds %ret1,%arg1,%ret1 + addc %r1,%r1,%r1 + ds %ret1,%arg1,%ret1 + addc %r1,%r1,%r1 + ds %ret1,%arg1,%ret1 + addc %r1,%r1,%r1 + ds %ret1,%arg1,%ret1 + addc %r1,%r1,%r1 + ds %ret1,%arg1,%ret1 + addc %r1,%r1,%r1 + ds %ret1,%arg1,%ret1 + addc %r1,%r1,%r1 + ds %ret1,%arg1,%ret1 + addc %r1,%r1,%r1 + ds %ret1,%arg1,%ret1 + addc %r1,%r1,%r1 + ds %ret1,%arg1,%ret1 + addc %r1,%r1,%r1 + ds %ret1,%arg1,%ret1 + addc %r1,%r1,%r1 + ds %ret1,%arg1,%ret1 + addc %r1,%r1,%r1 + ds %ret1,%arg1,%ret1 + addc %r1,%r1,%r1 + ds %ret1,%arg1,%ret1 + addc %r1,%r1,%r1 + ds %ret1,%arg1,%ret1 + addc %r1,%r1,%r1 + ds %ret1,%arg1,%ret1 + addc %r1,%r1,%r1 + ds %ret1,%arg1,%ret1 + comiclr,<= 0,%ret1,%r0 + add %ret1,%arg1,%ret1 + bv,n %r0(%r31) + nop +_remU_special_case: + addit,= 0,%arg1,%r0 + sub,>>= %arg0,%arg1,%ret1 + copy %arg0,%ret1 + bv,n %r0(%r31) + nop + + .align 4 +_divI: + comibf,<<,n 0xf,%arg1,_divI_small_divisor + add,>= %r0,%arg0,%ret1 +_divI_normal: + sub %r0,%ret1,%ret1 + sub %r0,%arg1,%r1 + ds %r0,%r1,%r0 + add %ret1,%ret1,%ret1 + ds %r0,%arg1,%r1 + addc %ret1,%ret1,%ret1 + ds %r1,%arg1,%r1 + addc %ret1,%ret1,%ret1 + ds %r1,%arg1,%r1 + addc %ret1,%ret1,%ret1 + ds %r1,%arg1,%r1 + addc %ret1,%ret1,%ret1 + ds %r1,%arg1,%r1 + addc %ret1,%ret1,%ret1 + ds %r1,%arg1,%r1 + addc %ret1,%ret1,%ret1 + ds %r1,%arg1,%r1 + addc %ret1,%ret1,%ret1 + ds %r1,%arg1,%r1 + addc %ret1,%ret1,%ret1 + ds %r1,%arg1,%r1 + addc %ret1,%ret1,%ret1 + ds %r1,%arg1,%r1 + addc %ret1,%ret1,%ret1 + ds %r1,%arg1,%r1 + addc %ret1,%ret1,%ret1 + ds %r1,%arg1,%r1 + addc %ret1,%ret1,%ret1 + ds %r1,%arg1,%r1 + addc %ret1,%ret1,%ret1 + ds %r1,%arg1,%r1 + addc %ret1,%ret1,%ret1 + ds %r1,%arg1,%r1 + addc %ret1,%ret1,%ret1 + ds %r1,%arg1,%r1 + addc %ret1,%ret1,%ret1 + ds %r1,%arg1,%r1 + addc %ret1,%ret1,%ret1 + ds %r1,%arg1,%r1 + addc %ret1,%ret1,%ret1 + ds %r1,%arg1,%r1 + addc %ret1,%ret1,%ret1 + ds %r1,%arg1,%r1 + addc %ret1,%ret1,%ret1 + ds %r1,%arg1,%r1 + addc %ret1,%ret1,%ret1 + ds %r1,%arg1,%r1 + addc %ret1,%ret1,%ret1 + ds %r1,%arg1,%r1 + addc %ret1,%ret1,%ret1 + ds %r1,%arg1,%r1 + addc %ret1,%ret1,%ret1 + ds %r1,%arg1,%r1 + addc %ret1,%ret1,%ret1 + ds %r1,%arg1,%r1 + addc %ret1,%ret1,%ret1 + ds %r1,%arg1,%r1 + addc %ret1,%ret1,%ret1 + ds %r1,%arg1,%r1 + addc %ret1,%ret1,%ret1 + ds %r1,%arg1,%r1 + addc %ret1,%ret1,%ret1 + ds %r1,%arg1,%r1 + addc %ret1,%ret1,%ret1 + ds %r1,%arg1,%r1 + addc %ret1,%ret1,%ret1 + ds %r1,%arg1,%r1 + addc %ret1,%ret1,%ret1 + xor,>= %arg0,%arg1,%r0 + sub %r0,%ret1,%ret1 + bv,n %r0(%r31) + nop + +_divI_small_divisor: + blr,n %arg1,%r0 + nop + addit,= 0,%arg1,%r0 + nop + bv %r0(%r31) + copy %arg0,%ret1 + b,n _divI_2 + nop + b,n _divI_3 + nop + b,n _divI_4 + nop + b,n _divI_5 + nop + b,n _divI_6 + nop + b,n _divI_7 + nop + b,n _divI_8 + nop + b,n _divI_9 + nop + b,n _divI_10 + nop + b _divI_normal + add,>= %r0,%arg0,%ret1 + b,n _divI_12 + nop + b _divI_normal + add,>= %r0,%arg0,%ret1 + b,n _divI_14 + nop + b,n _divI_15 + nop + + .align 4 +_divU: + comibf,< 0xf,%arg1,_divU_special_divisor + sub %r0,%arg1,%r1 + ds %r0,%r1,%r0 +_divU_normal: + add %arg0,%arg0,%ret1 + ds %r0,%arg1,%r1 + addc %ret1,%ret1,%ret1 + ds %r1,%arg1,%r1 + addc %ret1,%ret1,%ret1 + ds %r1,%arg1,%r1 + addc %ret1,%ret1,%ret1 + ds %r1,%arg1,%r1 + addc %ret1,%ret1,%ret1 + ds %r1,%arg1,%r1 + addc %ret1,%ret1,%ret1 + ds %r1,%arg1,%r1 + addc %ret1,%ret1,%ret1 + ds %r1,%arg1,%r1 + addc %ret1,%ret1,%ret1 + ds %r1,%arg1,%r1 + addc %ret1,%ret1,%ret1 + ds %r1,%arg1,%r1 + addc %ret1,%ret1,%ret1 + ds %r1,%arg1,%r1 + addc %ret1,%ret1,%ret1 + ds %r1,%arg1,%r1 + addc %ret1,%ret1,%ret1 + ds %r1,%arg1,%r1 + addc %ret1,%ret1,%ret1 + ds %r1,%arg1,%r1 + addc %ret1,%ret1,%ret1 + ds %r1,%arg1,%r1 + addc %ret1,%ret1,%ret1 + ds %r1,%arg1,%r1 + addc %ret1,%ret1,%ret1 + ds %r1,%arg1,%r1 + addc %ret1,%ret1,%ret1 + ds %r1,%arg1,%r1 + addc %ret1,%ret1,%ret1 + ds %r1,%arg1,%r1 + addc %ret1,%ret1,%ret1 + ds %r1,%arg1,%r1 + addc %ret1,%ret1,%ret1 + ds %r1,%arg1,%r1 + addc %ret1,%ret1,%ret1 + ds %r1,%arg1,%r1 + addc %ret1,%ret1,%ret1 + ds %r1,%arg1,%r1 + addc %ret1,%ret1,%ret1 + ds %r1,%arg1,%r1 + addc %ret1,%ret1,%ret1 + ds %r1,%arg1,%r1 + addc %ret1,%ret1,%ret1 + ds %r1,%arg1,%r1 + addc %ret1,%ret1,%ret1 + ds %r1,%arg1,%r1 + addc %ret1,%ret1,%ret1 + ds %r1,%arg1,%r1 + addc %ret1,%ret1,%ret1 + ds %r1,%arg1,%r1 + addc %ret1,%ret1,%ret1 + ds %r1,%arg1,%r1 + addc %ret1,%ret1,%ret1 + ds %r1,%arg1,%r1 + addc %ret1,%ret1,%ret1 + ds %r1,%arg1,%r1 + addc %ret1,%ret1,%ret1 + ds %r1,%arg1,%r1 + bv %r0(%r31) + addc %ret1,%ret1,%ret1 +_divU_special_divisor: + comibf,<= 0,%arg1,_divU_big_divisor + nop + blr %arg1,%r0 + nop +_divU_small_divisor: + addit,= 0,%arg1,%r0 + nop + bv %r0(%r31) + copy %arg0,%ret1 + bv %r0(%r31) + extru %arg0,30,31,%ret1 + b,n _divU_3 + nop + bv %r0(%r31) + extru %arg0,29,30,%ret1 + b,n _divU_5 + nop + b,n _divU_6 + nop + b,n _divU_7 + nop + bv %r0(%r31) + extru %arg0,28,29,%ret1 + b,n _divU_9 + nop + b,n _divU_10 + nop + b _divU_normal + ds %r0,%r1,%r0 + b,n _divU_12 + nop + b _divU_normal + ds %r0,%r1,%r0 + b,n _divU_14 + nop + b,n _divU_15 + nop +_divU_big_divisor: + sub %arg0,%arg1,%r0 + bv %r0(%r31) + addc %r0,%r0,%ret1 + +_divI_2: + comclr,>= %arg0,%r0,%r0 + addi 1,%arg0,%arg0 + bv %r0(%r31) + extrs %arg0,30,31,%ret1 + +_divI_4: + comclr,>= %arg0,%r0,%r0 + addi 3,%arg0,%arg0 + bv %r0(%r31) + extrs %arg0,29,30,%ret1 + +_divI_8: + comclr,>= %arg0,%r0,%r0 + addi 7,%arg0,%arg0 + bv %r0(%r31) + extrs %arg0,28,29,%ret1 + +_divI_3: + comb,<,n %arg0,%r0,_divI_neg3 + addi 1,%arg0,%arg0 + extru %arg0,1,2,%ret1 + sh2add %arg0,%arg0,%arg0 + b _divI_pos + addc %ret1,%r0,%ret1 +_divI_neg3: + subi 1,%arg0,%arg0 + extru %arg0,1,2,%ret1 + sh2add %arg0,%arg0,%arg0 + b _divI_neg + addc %ret1,%r0,%ret1 +_divU_3: + addi 1,%arg0,%arg0 + addc %r0,%r0,%ret1 + shd %ret1,%arg0,30,%arg1 + sh2add %arg0,%arg0,%arg0 + b _divI_pos + addc %ret1,%arg1,%ret1 + +_divI_5: + comb,<,n %arg0,%r0,_divI_neg5 + addi 3,%arg0,%arg1 + sh1add %arg0,%arg1,%arg0 + b _divI_pos + addc %r0,%r0,%ret1 +_divI_neg5: + sub %r0,%arg0,%arg0 + addi 1,%arg0,%arg0 + shd %r0,%arg0,31,%ret1 + sh1add %arg0,%arg0,%arg0 + b _divI_neg + addc %ret1,%r0,%ret1 +_divU_5: + addi 1,%arg0,%arg0 + addc %r0,%r0,%ret1 + shd %ret1,%arg0,31,%arg1 + sh1add %arg0,%arg0,%arg0 + b _divI_pos + addc %arg1,%ret1,%ret1 + +_divI_6: + comb,<,n %arg0,%r0,_divI_neg6 + extru %arg0,30,31,%arg0 + addi 5,%arg0,%arg1 + sh2add %arg0,%arg1,%arg0 + b _divI_pos + addc %r0,%r0,%ret1 +_divI_neg6: + subi 2,%arg0,%arg0 + extru %arg0,30,31,%arg0 + shd %r0,%arg0,30,%ret1 + sh2add %arg0,%arg0,%arg0 + b _divI_neg + addc %ret1,%r0,%ret1 +_divU_6: + extru %arg0,30,31,%arg0 + addi 1,%arg0,%arg0 + shd %r0,%arg0,30,%ret1 + sh2add %arg0,%arg0,%arg0 + b _divI_pos + addc %ret1,%r0,%ret1 + +_divI_10: + comb,< %arg0,%r0,_divI_neg10 + copy %r0,%ret1 + extru %arg0,30,31,%arg0 + addibf 1,%arg0,_divI_pos + sh1add %arg0,%arg0,%arg0 +_divI_neg10: + subi 2,%arg0,%arg0 + extru %arg0,30,31,%arg0 + sh1add %arg0,%arg0,%arg0 + +_divI_neg: + shd %ret1,%arg0,28,%arg1 + shd %arg0,%r0,28,%r1 + add %arg0,%r1,%arg0 + addc %ret1,%arg1,%ret1 + shd %ret1,%arg0,24,%arg1 + shd %arg0,%r0,24,%r1 + add %arg0,%r1,%arg0 + addc %ret1,%arg1,%ret1 + shd %ret1,%arg0,16,%arg1 + shd %arg0,%r0,16,%r1 + add %arg0,%r1,%arg0 + addc %ret1,%arg1,%ret1 + bv %r0(%r31) + sub %r0,%ret1,%ret1 + +_divU_10: + extru %arg0,30,31,%arg0 + addi 3,%arg0,%arg1 + sh1add %arg0,%arg1,%arg0 + addc %r0,%r0,%ret1 + +_divI_pos: + shd %ret1,%arg0,28,%arg1 +_divI_pos_for_15: + shd %arg0,%r0,28,%r1 + add %arg0,%r1,%arg0 + addc %ret1,%arg1,%ret1 + shd %ret1,%arg0,24,%arg1 + shd %arg0,%r0,24,%r1 + add %arg0,%r1,%arg0 + addc %ret1,%arg1,%ret1 + shd %ret1,%arg0,16,%arg1 + shd %arg0,%r0,16,%r1 + add %arg0,%r1,%arg0 + bv %r0(%r31) + addc %ret1,%arg1,%ret1 + +_divI_12: + comb,< %arg0,%r0,_divI_neg12 + copy %r0,%ret1 + extru %arg0,29,30,%arg0 + addibf 1,%arg0,_divI_pos + sh2add %arg0,%arg0,%arg0 +_divI_neg12: + subi 4,%arg0,%arg0 + extru %arg0,29,30,%arg0 + b _divI_neg + sh2add %arg0,%arg0,%arg0 +_divU_12: + extru %arg0,29,30,%arg0 + addi 5,%arg0,%arg1 + sh2add %arg0,%arg1,%arg0 + b _divI_pos + addc %r0,%r0,%ret1 + +_divI_15: + comb,< %arg0,%r0,_divI_neg15 + copy %r0,%ret1 + addibf 1,%arg0,_divI_pos_for_15 + shd %ret1,%arg0,28,%arg1 +_divI_neg15: + b _divI_neg + subi 1,%arg0,%arg0 +_divU_15: + addi 1,%arg0,%arg0 + b _divI_pos + addc %r0,%r0,%ret1 + +_divI_7: + comb,<,n %arg0,%r0,_divI_neg7 +_divI_7a: + addi 1,%arg0,%arg0 + shd %r0,%arg0,29,%ret1 + sh3add %arg0,%arg0,%arg0 + addc %ret1,%r0,%ret1 +_divI_pos7: + shd %ret1,%arg0,26,%arg1 + shd %arg0,%r0,26,%r1 + add %arg0,%r1,%arg0 + addc %ret1,%arg1,%ret1 + shd %ret1,%arg0,20,%arg1 + shd %arg0,%r0,20,%r1 + add %arg0,%r1,%arg0 + addc %ret1,%arg1,%arg1 + copy %r0,%ret1 + shd,= %arg1,%arg0,24,%arg1 +L1: addbf %arg1,%ret1,L2 + extru %arg0,31,24,%arg0 + bv,n %r0(%r31) +L2: addbf %arg1,%arg0,L1 + extru,= %arg0,7,8,%arg1 + +_divI_neg7: + subi 1,%arg0,%arg0 +_divI_neg7a: + shd %r0,%arg0,29,%ret1 + sh3add %arg0,%arg0,%arg0 + addc %ret1,%r0,%ret1 +_divI_neg7_shift: + shd %ret1,%arg0,26,%arg1 + shd %arg0,%r0,26,%r1 + add %arg0,%r1,%arg0 + addc %ret1,%arg1,%ret1 + shd %ret1,%arg0,20,%arg1 + shd %arg0,%r0,20,%r1 + add %arg0,%r1,%arg0 + addc %ret1,%arg1,%arg1 + copy %r0,%ret1 + shd,= %arg1,%arg0,24,%arg1 +L3: addbf %arg1,%ret1,L4 + extru %arg0,31,24,%arg0 + bv %r0(%r31) + sub %r0,%ret1,%ret1 +L4: addbf %arg1,%arg0,L3 + extru,= %arg0,7,8,%arg1 + +_divU_7: + addi 1,%arg0,%arg0 + addc %r0,%r0,%ret1 + shd %ret1,%arg0,29,%arg1 + sh3add %arg0,%arg0,%arg0 + b _divI_pos7 + addc %arg1,%ret1,%ret1 + +_divI_9: + comb,<,n %arg0,%r0,_divI_neg9 + addi 1,%arg0,%arg0 + shd %r0,%arg0,29,%arg1 + shd %arg0,%r0,29,%r1 + sub %r1,%arg0,%arg0 + b _divI_pos7 + subb %arg1,%r0,%ret1 +_divI_neg9: + subi 1,%arg0,%arg0 + shd %r0,%arg0,29,%arg1 + shd %arg0,%r0,29,%r1 + sub %r1,%arg0,%arg0 + b _divI_neg7_shift + subb %arg1,%r0,%ret1 +_divU_9: + addi 1,%arg0,%arg0 + addc %r0,%r0,%ret1 + shd %ret1,%arg0,29,%arg1 + shd %arg0,%r0,29,%r1 + sub %r1,%arg0,%arg0 + b _divI_pos7 + subb %arg1,%ret1,%ret1 + +_divI_14: + comb,<,n %arg0,%r0,_divI_neg14 +_divU_14: + b _divI_7a + extru %arg0,30,31,%arg0 +_divI_neg14: + subi 2,%arg0,%arg0 + b _divI_neg7a + extru %arg0,30,31,%arg0 + +_end: diff --git a/ef/Compiler/CodeGenerator/md/hppa/HPPAInstruction.cpp b/ef/Compiler/CodeGenerator/md/hppa/HPPAInstruction.cpp new file mode 100644 index 000000000000..1bfa26af9c50 --- /dev/null +++ b/ef/Compiler/CodeGenerator/md/hppa/HPPAInstruction.cpp @@ -0,0 +1,677 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#include "Fundamentals.h" +#include "HPPAInstruction.h" +#include "HPPAFuncs.h" +#include "ControlNodes.h" + +HPPAInstructionInfo hiInfo[nHPPAInstructionKind] = +{ + { ADD, 0x02, 0x18, 6, "add", HPPA_NONE }, // ***** + { ADDBF, 0xff, 0x00, 0, "addbf", HPPA_UNIMP }, + { ADDBT, 0xff, 0x00, 0, "addbt", HPPA_UNIMP }, + { ADDO, 0xff, 0x00, 0, "addo", HPPA_UNIMP }, + { ADDIBF, 0xff, 0x00, 0, "addibf", HPPA_UNIMP }, + { ADDIBT, 0xff, 0x00, 0, "addibt", HPPA_UNIMP }, + { ADDIL, 0xff, 0x00, 0, "addil", HPPA_UNIMP }, + { ADDL, 0x02, 0x28, 6, "addl", HPPA_NONE }, // ***** + { ADDI, 0xff, 0x00, 0, "addi", HPPA_UNIMP }, + { ADDIT, 0xff, 0x00, 0, "addit", HPPA_UNIMP }, + { ADDITO, 0xff, 0x00, 0, "addito", HPPA_UNIMP }, + { ADDC, 0xff, 0x00, 0, "addc", HPPA_UNIMP }, + { ADDCO, 0xff, 0x00, 0, "addco", HPPA_UNIMP }, + { AND, 0x02, 0x08, 6, "and", HPPA_NONE }, // ***** + { ANDCM, 0xff, 0x00, 0, "andcm", HPPA_UNIMP }, + { BL, 0x3a, 0x00, 13, "bl", HPPA_NONE }, // ***** + { BLE, 0xff, 0x00, 0, "ble", HPPA_UNIMP }, + { BLR, 0xff, 0x00, 0, "blr", HPPA_UNIMP }, + { BE, 0xff, 0x00, 0, "be", HPPA_UNIMP }, + { BB, 0xff, 0x00, 0, "bb", HPPA_UNIMP }, + { BVB, 0xff, 0x00, 0, "bvb", HPPA_UNIMP }, + { BV, 0xff, 0x00, 0, "bv", HPPA_UNIMP }, + { BREAK, 0xff, 0x00, 0, "break", HPPA_UNIMP }, + { COMBF, 0x22, 0x00, 11, "combf", HPPA_NONE }, // ***** + { COMBT, 0x20, 0x00, 11, "combt", HPPA_NONE }, // ***** + { COMCLR, 0xff, 0x00, 0, "comclr", HPPA_UNIMP }, + { COMIBF, 0x23, 0x00, 0, "comibf", HPPA_DATA_HAS_IM5 }, // ***** + { COMIBT, 0x21, 0x00, 11, "comibt", HPPA_DATA_HAS_IM5 }, // ***** + { COMICLR, 0xff, 0x00, 0, "comiclr", HPPA_UNIMP }, + { CLDDX, 0xff, 0x00, 0, "clddx", HPPA_UNIMP }, + { CLDDS, 0xff, 0x00, 0, "cldds", HPPA_UNIMP }, + { CLDWX, 0xff, 0x00, 0, "cldwx", HPPA_UNIMP }, + { CLDWS, 0xff, 0x00, 0, "cldws", HPPA_UNIMP }, + { COPR, 0xff, 0x00, 0, "copr", HPPA_UNIMP }, + { CSTDX, 0xff, 0x00, 0, "cstdx", HPPA_UNIMP }, + { CSTDS, 0xff, 0x00, 0, "cstds", HPPA_UNIMP }, + { CSTWX, 0xff, 0x00, 0, "cstwx", HPPA_UNIMP }, + { CSTWS, 0xff, 0x00, 0, "cstws", HPPA_UNIMP }, + { COPY, 0x02, 0x09, 6, "copy", HPPA_R1_IS_ZERO | HPPA_IS_COPY }, // ***** + { DCOR, 0xff, 0x00, 0, "dcor", HPPA_UNIMP }, + { DEP, 0xff, 0x00, 0, "dep", HPPA_UNIMP }, + { DEPI, 0x35, 0x07, 9, "depi", HPPA_DATA_HAS_IM5 }, // ***** + { DIAG, 0xff, 0x00, 0, "diag", HPPA_UNIMP }, + { DS, 0xff, 0x00, 0, "ds", HPPA_UNIMP }, + { XOR, 0x02, 0x0a, 6, "xor", HPPA_NONE }, // **** + { EXTRS, 0x34, 0x07, 8, "extrs", HPPA_NONE }, // ***** + { EXTRU, 0x34, 0x06, 8, "extru", HPPA_NONE }, // ***** + { XMPYU, 0x0e, 0x00, 40, "xmpyu", HPPA_NONE }, + { FABS, 0xff, 0x00, 0, "fabs", HPPA_UNIMP }, + { FCMP, 0xff, 0x00, 0, "fcmp", HPPA_UNIMP }, + { FCNVXF, 0xff, 0x00, 0, "fcnvxf", HPPA_UNIMP }, + { FCNVFX, 0xff, 0x00, 0, "fcnvfx", HPPA_UNIMP }, + { FCNVFXT, 0xff, 0x00, 0, "fcnvfxt", HPPA_UNIMP }, + { FCNVFF, 0xff, 0x00, 0, "fcnvff", HPPA_UNIMP }, + { FDIV, 0xff, 0x00, 0, "fdiv", HPPA_UNIMP }, + { FLDDX, 0xff, 0x00, 0, "flddx", HPPA_UNIMP }, + { FLDDS, 0xff, 0x00, 0, "fldds", HPPA_UNIMP }, + { FLDWX, 0xff, 0x00, 0, "fldwx", HPPA_UNIMP }, + { FLDWS, 0x09, 0x00, 31, "fldws", HPPA_DATA_HAS_IM5 }, // ***** + { FMPY, 0xff, 0x00, 0, "fmpy", HPPA_UNIMP }, + { FMPYADD, 0xff, 0x00, 0, "fmpyadd", HPPA_UNIMP }, + { FMPYSUB, 0xff, 0x00, 0, "fmpysub", HPPA_UNIMP }, + { FRND, 0xff, 0x00, 0, "frnd", HPPA_UNIMP }, + { FSQRT, 0xff, 0x00, 0, "fsqrt", HPPA_UNIMP }, + { FSTDX, 0xff, 0x00, 0, "fstdx", HPPA_UNIMP }, + { FSTDS, 0xff, 0x00, 0, "fstds", HPPA_UNIMP }, + { FSTWS, 0x09, 0x00, 32, "fstws", HPPA_DATA_HAS_IM5 }, // ***** + { FSUB, 0xff, 0x00, 0, "fsub", HPPA_UNIMP }, + { FTEST, 0xff, 0x00, 0, "ftest", HPPA_UNIMP }, + { FDC, 0xff, 0x00, 0, "fdc", HPPA_UNIMP }, + { FDCE, 0xff, 0x00, 0, "fdce", HPPA_UNIMP }, + { FIC, 0xff, 0x00, 0, "fic", HPPA_UNIMP }, + { FICE, 0xff, 0x00, 0, "fice", HPPA_UNIMP }, + { GATE, 0xff, 0x00, 0, "gate", HPPA_UNIMP }, + { DEBUGID, 0xff, 0x00, 0, "debugid", HPPA_UNIMP }, + { OR, 0x02, 0x09, 6, "or", HPPA_NONE }, // ***** + { IDTLBA, 0xff, 0x00, 0, "idtlba", HPPA_UNIMP }, + { IDTLBP, 0xff, 0x00, 0, "idtlbp", HPPA_UNIMP }, + { IITLBA, 0xff, 0x00, 0, "iitlba", HPPA_UNIMP }, + { IITLBP, 0xff, 0x00, 0, "iitlbp", HPPA_UNIMP }, + { IDCOR, 0xff, 0x00, 0, "idcor", HPPA_UNIMP }, + { LDCWX, 0xff, 0x00, 0, "ldcwx", HPPA_UNIMP }, + { LDCWS, 0xff, 0x00, 0, "ldcws", HPPA_UNIMP }, + { LDB, 0xff, 0x00, 0, "ldb", HPPA_UNIMP }, + { LDBX, 0xff, 0x00, 0, "ldbx", HPPA_UNIMP }, + { LDBS, 0xff, 0x00, 0, "ldbs", HPPA_UNIMP }, + { LCI, 0xff, 0x00, 0, "lci", HPPA_UNIMP }, + { LDH, 0xff, 0x00, 0, "ldh", HPPA_UNIMP }, + { LDHX, 0xff, 0x00, 0, "ldhx", HPPA_UNIMP }, + { LDHS, 0xff, 0x00, 0, "ldhs", HPPA_UNIMP }, + { LDI, 0x0d, 0x00, 1, "ldi", HPPA_DATA_HAS_IM14 | HPPA_R1_IS_ZERO }, // ***** + { LDIL, 0x08, 0x00, 5, "ldil", HPPA_DATA_HAS_IM21 }, // ***** + { LDO, 0x0d, 0x00, 1, "ldo", HPPA_DATA_HAS_IM14 }, // ***** + { LPA, 0xff, 0x00, 0, "lpa", HPPA_UNIMP }, + { LDSID, 0xff, 0x00, 0, "ldsid", HPPA_UNIMP }, + { LDW, 0x12, 0x00, 1, "ldw", HPPA_DATA_HAS_IM14 }, // ***** + { LDWAX, 0xff, 0x00, 0, "ldwax", HPPA_UNIMP }, + { LDWAS, 0xff, 0x00, 0, "ldwas", HPPA_UNIMP }, + { LDWM, 0xff, 0x00, 0, "ldwm", HPPA_UNIMP }, + { LDWX, 0xff, 0x00, 0, "ldwx", HPPA_UNIMP }, + { LDWS, 0xff, 0x00, 0, "ldws", HPPA_UNIMP }, + { MOVB, 0xff, 0x00, 0, "movb", HPPA_UNIMP }, + { MFCTL, 0xff, 0x00, 0, "mfctl", HPPA_UNIMP }, + { MFDBAM, 0xff, 0x00, 0, "mfdbam", HPPA_UNIMP }, + { MFDBAO, 0xff, 0x00, 0, "mfdbao", HPPA_UNIMP }, + { MFIBAM, 0xff, 0x00, 0, "mfibam", HPPA_UNIMP }, + { MFIBAO, 0xff, 0x00, 0, "mfibao", HPPA_UNIMP }, + { MFSP, 0xff, 0x00, 0, "mfsp", HPPA_UNIMP }, + { MOVIB, 0xff, 0x00, 0, "movib", HPPA_UNIMP }, + { MCTL, 0xff, 0x00, 0, "mctl", HPPA_UNIMP }, + { MTBAM, 0xff, 0x00, 0, "mtbam", HPPA_UNIMP }, + { MTBAO, 0xff, 0x00, 0, "mtbao", HPPA_UNIMP }, + { MTIBAM, 0xff, 0x00, 0, "mtibam", HPPA_UNIMP }, + { MTIBAO, 0xff, 0x00, 0, "mtibao", HPPA_UNIMP }, + { MTSP, 0xff, 0x00, 0, "mtsp", HPPA_UNIMP }, + { MTSM, 0xff, 0x00, 0, "mtsm", HPPA_UNIMP }, + { PMDIS, 0xff, 0x00, 0, "pmdis", HPPA_UNIMP }, + { PMENB, 0xff, 0x00, 0, "pmenb", HPPA_UNIMP }, + { PROBER, 0xff, 0x00, 0, "prober", HPPA_UNIMP }, + { PROBERI, 0xff, 0x00, 0, "proberi", HPPA_UNIMP }, + { PROBEW, 0xff, 0x00, 0, "probew", HPPA_UNIMP }, + { PROBEWI, 0xff, 0x00, 0, "probewi", HPPA_UNIMP }, + { PDC, 0xff, 0x00, 0, "pdc", HPPA_UNIMP }, + { PDTLB, 0xff, 0x00, 0, "pdtlb", HPPA_UNIMP }, + { PDTLBE, 0xff, 0x00, 0, "pdtlbe", HPPA_UNIMP }, + { PITLB, 0xff, 0x00, 0, "pitlb", HPPA_UNIMP }, + { PITLBE, 0xff, 0x00, 0, "pitlbe", HPPA_UNIMP }, + { RSM, 0xff, 0x00, 0, "rsm", HPPA_UNIMP }, + { RFI, 0xff, 0x00, 0, "rfi", HPPA_UNIMP }, + { RFIR, 0xff, 0x00, 0, "rfir", HPPA_UNIMP }, + { SSM, 0xff, 0x00, 0, "ssm", HPPA_UNIMP }, + { SHD, 0xff, 0x00, 0, "shd", HPPA_UNIMP }, + { SH1ADD, 0xff, 0x00, 0, "sh1add", HPPA_UNIMP }, + { SH1ADDL, 0x02, 0x29, 6, "sh1addl", HPPA_NONE }, // ***** + { SH1ADDO, 0xff, 0x00, 0, "sh1addo", HPPA_UNIMP }, + { SH2ADD, 0xff, 0x00, 0, "sh2add", HPPA_UNIMP }, + { SH2ADDL, 0x02, 0x2a, 6, "sh2addl", HPPA_NONE }, // ***** + { SH2ADDO, 0xff, 0x00, 0, "sh2addo", HPPA_UNIMP }, + { SH3ADD, 0xff, 0x00, 0, "sh3add", HPPA_UNIMP }, + { SH3ADDL, 0x02, 0x2b, 6, "sh3addl", HPPA_NONE }, // ***** + { SH3ADDO, 0xff, 0x00, 0, "sh3addo", HPPA_UNIMP }, + { SPOP0, 0xff, 0x00, 0, "spop0", HPPA_UNIMP }, + { SPOP1, 0xff, 0x00, 0, "spop1", HPPA_UNIMP }, + { SPOP2, 0xff, 0x00, 0, "spop2", HPPA_UNIMP }, + { SPOP3, 0xff, 0x00, 0, "spop3", HPPA_UNIMP }, + { STB, 0xff, 0x00, 0, "stb", HPPA_UNIMP }, + { STBS, 0xff, 0x00, 0, "stbs", HPPA_UNIMP }, + { STBYS, 0xff, 0x00, 0, "stbys", HPPA_UNIMP }, + { STH, 0xff, 0x00, 0, "sth", HPPA_UNIMP }, + { STHS, 0xff, 0x00, 0, "sths", HPPA_UNIMP }, + { STW, 0x1a, 0x00, 1, "stw", HPPA_DATA_HAS_IM14 }, // ***** + { STWAS, 0xff, 0x00, 0, "stwas", HPPA_UNIMP }, + { STWM, 0xff, 0x00, 0, "stwm", HPPA_UNIMP }, + { STWS, 0xff, 0x00, 0, "stws", HPPA_UNIMP }, + { SUB, 0x02, 0x10, 6, "sub", HPPA_NONE }, // ***** + { SUBT, 0xff, 0x00, 0, "subt", HPPA_UNIMP }, + { SUBTO, 0xff, 0x00, 0, "subto", HPPA_UNIMP }, + { SUBO, 0xff, 0x00, 0, "subo", HPPA_UNIMP }, + { SUBI, 0xff, 0x00, 0, "subi", HPPA_UNIMP }, + { SUBIO, 0xff, 0x00, 0, "subio", HPPA_UNIMP }, + { SUBB, 0xff, 0x00, 0, "subb", HPPA_UNIMP }, + { SUBBO, 0xff, 0x00, 0, "subbo", HPPA_UNIMP }, + { SYNC, 0xff, 0x00, 0, "sync", HPPA_UNIMP }, + { SYNCDMA, 0xff, 0x00, 0, "syncdma", HPPA_UNIMP }, + { UADDCM, 0xff, 0x00, 0, "uaddcm", HPPA_UNIMP }, + { UADDCMT, 0xff, 0x00, 0, "uaddcmt", HPPA_UNIMP }, + { UXOR, 0xff, 0x00, 0, "uxor", HPPA_UNIMP }, + { VDEP, 0xff, 0x00, 0, "vdep", HPPA_UNIMP }, + { VDEPI, 0xff, 0x00, 0, "vdepi", HPPA_UNIMP }, + { VEXTRU, 0xff, 0x00, 0, "vextru", HPPA_UNIMP }, + { VSHD, 0xff, 0x00, 0, "vshd", HPPA_UNIMP }, + { ZDEP, 0x35, 0x02, 9, "zdep", HPPA_R1_IS_ZERO }, // ***** + { ZDEPI, 0xff, 0x00, 0, "zdepi", HPPA_UNIMP }, + { ZVDEP, 0xff, 0x00, 0, "zvdep", HPPA_UNIMP }, + { ZVDEPI, 0xff, 0x00, 0, "zvdepi", HPPA_UNIMP } +}; + +HPPAConditionInfo hcInfo[nHPPAConditionKind] = +{ + { hcNever, hcNever, 0, false, "" }, + { hcE, hcE, 1, false, "=" }, + { hcL, hcGe, 2, false, "<" }, + { hcLe, hcG, 3, false, "<=" }, + { hcLu, hcGeu, 4, false, "<<" }, + { hcLeu, hcGu, 5, false, "<<=" }, + { hcOver, hcOver, 6, false, "SV" }, + { hcOdd, hcOdd, 7, false, "OD" }, + { hcAlways, hcAlways, 0, true, "TR" }, + { hcNe, hcNe, 1, true, "<>" }, + { hcGe, hcL, 2, true, ">=" }, + { hcG, hcLe, 3, true, ">" }, + { hcGeu, hcLu, 4, true, ">>=" }, + { hcGu, hcLeu, 5, true, ">>" }, + { hcNOver, hcNOver, 6, true, "NSV" }, + { hcEven, hcEven, 7, true, "EV" } +}; + +char* registerNumberToString[] = +{ + // General registers + "0", "%r1", "%rp", "%r3", "%r4", "%r5", "%r6", "%r7", + "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15", + "%r16", "%r17", "%r18", "%r19", "%r20", "%r21", "%r22", "%arg3", + "%arg2", "%arg1", "%arg0", "%dp", "%ret0", "%ret1", "%sp", "%r31", + // Floating point registers + "%fr0L", "%fr0R", "%fr1L", "%fr1R", "%fr2L", "%fr2R", "%fr3L", "%fr3R", + "%fr4L", "%fr4R", "%fr5L", "%fr5R", "%fr6L", "%fr6R", "%fr7L", "%fr7R", + "%fr8L", "%fr8R", "%fr9L", "%fr9R", "%fr10L", "%fr10R", "%fr11L", "%fr11R", + "%fr12L", "%fr12R", "%fr13L", "%fr13R", "%fr14L", "%fr14R", "%fr15L", "%fr15R", + "%fr16L", "%fr16R", "%fr17L", "%fr17R", "%fr18L", "%fr18R", "%fr19L", "%fr19R", + "%fr20L", "%fr20R", "%fr21L", "%fr21R", "%fr22L", "%fr22R", "%fr23L", "%fr23R", + "%fr24L", "%fr24R", "%fr25L", "%fr25R", "%fr26L", "%fr26R", "%fr27L", "%fr27R", + "%fr28L", "%fr28R", "%fr29L", "%fr29R", "%fr30L", "%fr30R", "%fr31L", "%fr31R", + // Other strings + "%fr0", "%fr1", "%fr2", "%fr3", "%fr4", "%fr5", "%fr6", "%fr7", + "%fr8", "%fr9", "%fr10", "%fr11", "%fr12", "%fr13", "%fr14", "%fr15", + "%fr16", "%fr17", "%fr18", "%fr19", "%fr20", "%fr21", "%fr22", "%fr23", + "%fr24", "%fr25", "%fr26", "%fr27", "%fr28", "%fr29", "%fr30", "%fr31", +}; + +// available caller saved registers: +// %r19, %r20, %r21, %r22, %arg3, %arg2, %arg1, %arg0, %ret0, %ret1, %r31 +// available callee saved registers: +// %r4, %r5, %r6, %r7, %r8, %r9, %r10, %r11, %r12, %r13, %r14, %r15, %r16, %r17, %r18 + +PRUint8 registerNumberToColor[] = +{ + 79, 77, 12, 13, 14, 15, 16, 17, + 18, 19, 20, 21, 22, 23, 24, 25, + 26, 27, 28, 0, 1, 2, 3, 4, + 5, 6, 7, 8, 9, 10, 78, 11 +}; + +HPPARegisterNumber colorToRegisterNumber[] = +{ + // caller saved GR +/*0*/ r19, r20, r21, r22, arg3, arg2, arg1, arg0, +/*8*/ dp, ret0, ret1, r31, rp, + // callee saved GR +/*13*/ r3, r4, r5, r6, r7, r8, r9, r10, +/*21*/ r11, r12, r13, r14, r15, r16, r17, r18, + // caller saved FPR +/*29*/ fr8L, fr8R, fr9L, fr9R, fr10L, fr10R, fr11L, fr11R, +/*37*/ fr22L, fr22R, fr23L, fr23R, fr24L, fr24R, fr25L, fr25R, +/*45*/ fr26L, fr26R, fr27L, fr27R, fr28L, fr28R, fr29L, fr29R, +/*53*/ fr30L, fr30R, fr31L, fr31R, + // callee saved FPR +/*57*/ fr12L, fr12R, fr13L, fr13R, fr14L, fr14R, fr15L, fr15R, +/*65*/ fr16L, fr16R, fr17L, fr17R, fr18L, fr18R, fr19L, fr19R, +/*73*/ fr20L, fr20R, fr21L, fr21R, + // special registers +/*77*/ r1, sp, zero +}; + +#define COLOR_MASK1(regNum) (1 << registerNumberToColor[regNum]) +#define COLOR_MASK2(regNum) (1 << (registerNumberToColor[regNum] - 32)) +#define COLOR_MASK3(regNum) (1 << (registerNumberToColor[regNum] - 64)) + +HPPASpecialCallInfo hscInfo[nSpecialCalls] = +{ + { RemI, "$$remI", 2, 1, 0, 0, COLOR_MASK3(r1), HPPAFuncAddress(HPPAremI) }, // inter with r1 + { RemU, "$$remU", 2, 1, 0, 0, COLOR_MASK3(r1), HPPAFuncAddress(HPPAremU) }, // inter with r1 + { DivI, "$$divI", 2, 1, 0, 0, COLOR_MASK3(r1), HPPAFuncAddress(HPPAdivI) }, // inter with r1 + { DivU, "$$divU", 2, 1, 0, 0, COLOR_MASK3(r1), HPPAFuncAddress(HPPAdivU) }, // inter with r1 +}; + +HPPAInstructionKind shiftAddl[4] = +{ + INVALID, SH1ADDL, SH2ADDL, SH3ADDL +}; + + +static inline PRUint32 +dis_assemble_3(PRUint32 x) +{ + return (((x & 4) >> 2) | ((x & 3) << 1)) & 7; +} + +static inline void +dis_assemble_12(PRUint32 as12, PRUint32& x, PRUint32& y) +{ + y = (as12 & 0x800) >> 11; + x = ((as12 & 0x3ff) << 1) | ((as12 & 0x400) >> 10); +} + +static inline void +dis_assemble_17(PRUint32 as17, PRUint32& x, PRUint32& y, PRUint32& z) +{ + z = (as17 & 0x10000) >> 16; + x = (as17 & 0x0f800) >> 11; + y = (((as17 & 0x00400) >> 10) | ((as17 & 0x3ff) << 1)) & 0x7ff; +} + +static inline PRUint32 +dis_assemble_21 (PRUint32 as21) +{ + PRUint32 temp; + + temp = (as21 & 0x100000) >> 20; + temp |= (as21 & 0x0ffe00) >> 8; + temp |= (as21 & 0x000180) << 7; + temp |= (as21 & 0x00007c) << 14; + temp |= (as21 & 0x000003) << 12; + + return temp; +} + +static inline PRUint16 +low_sign_unext_14(PRUint16 x) +{ + return ((x & 0x1fff) << 1) | ((x & 0x2000) ? 1 : 0); +} + +static inline PRUint8 +low_sign_unext_5(PRUint8 x) +{ + return ((x & 0xf) << 1) | ((x & 0x10) ? 1 : 0); +} + +// HPPAInstruction methods + +#if defined(DEBUG) +void HPPAInstruction:: +printPretty(FILE* f) +{ + fprintf(f, "unimp(%s)", hiInfo[kind].string); +} +#endif + +HPPARegisterNumber HPPAInstruction:: +getR1() +{ + InstructionUse* use = getInstructionUseBegin(); + InstructionUse* limit = getInstructionUseEnd(); + + while (use < limit && !use->isVirtualRegister()) use++; + + if (use >= limit) + return zero; + else + return udToRegisterNumber(use[0]); +} + +HPPARegisterNumber HPPAInstruction:: +getR2() +{ + InstructionUse* use = getInstructionUseBegin(); + InstructionUse* limit = getInstructionUseEnd(); + + while (use < limit && !use->isVirtualRegister()) use++; + + if (use < &limit[-1] && use[1].isVirtualRegister()) + use++; // skip R1 + + if (use >= limit || !use->isVirtualRegister()) + return zero; + else + return udToRegisterNumber(use[0]); +} + +HPPARegisterNumber HPPAInstruction:: +getT() +{ + InstructionDefine* def = getInstructionDefineBegin(); + InstructionDefine* limit = getInstructionDefineEnd(); + + while (def < limit && !def->isVirtualRegister()) def++; + + if (def >= limit) + return zero; + else + return udToRegisterNumber(def[0]); +} + +// HPPAFormat1 methods +// |31 |25 |20 |15 |13 0| +// |-----------------|--------------|--------------|-----|-----------------------------------------| +// | op | b | t/r | s | im14 | +// |-----------------|--------------|--------------|-----|-----------------------------------------| + +void HPPAFormat1:: +formatToMemory(void* where, uint32 /*offset*/) +{ + *(PRUint32 *)where = (hiInfo[kind].opcode << 26) | (getR1() << 21) | (getT() << 16) | low_sign_unext_14(getIm14()); +} + +#if defined(DEBUG) +void HPPAFormat1:: +printPretty(FILE* f) +{ + if (flags & HPPA_R1_IS_ZERO) + fprintf(f, "%s %d,%s", hiInfo[kind].string, (PRInt16) getIm14(), getTString()); + else + fprintf(f, "%s %d(%s),%s", hiInfo[kind].string, (PRInt16) getIm14(), getR1String(), getTString()); +} +#endif + +#if defined(DEBUG) +void HPPALoad:: +printPretty(FILE* f) +{ + fprintf(f, "%s %d(0,%s),%s", hiInfo[kind].string, (PRInt16) getIm14(), getR1String(), getTString()); +} +#endif + +void HPPAStore:: +formatToMemory(void* where, uint32 /*offset*/) +{ + *(PRUint32 *)where = (hiInfo[kind].opcode << 26) | (getR1() << 21) | (getR2() << 16) | low_sign_unext_14(getIm14()); +} + +#if defined(DEBUG) +void HPPAStore:: +printPretty(FILE* f) +{ + fprintf(f, "%s %s,%d(0,%s)", hiInfo[kind].string, getR2String(), (PRInt16) getIm14(), getR1String()); +} +#endif + +// HPPAFormat5 methods +// |31 |25 |20 0| +// |-----------------|--------------|--------------------------------------------------------------| +// | op | t/r | im21 | +// |-----------------|--------------|--------------------------------------------------------------| + +void HPPAFormat5:: +formatToMemory(void* where, uint32 /*offset*/) +{ + *(PRUint32 *)where = (hiInfo[kind].opcode << 26) | (getT() << 21) | dis_assemble_21(IM21(im21)); +} + +#if defined(DEBUG) +void HPPAFormat5:: +printPretty(FILE* f) +{ + fprintf(f, "%s %d,%s", hiInfo[kind].string, IM21(im21), getTString()); +} +#endif + +// HPPAFormat6 methods +// |31 |25 |20 |15 |12|11 |5 |4 0| +// |-----------------|--------------|--------------|--------|--|-----------------|--|--------------| +// | op | r2 | r1 | c | f| ext6 |0 | t | +// |-----------------|--------------|--------------|--------|--|-----------------|--|--------------| + +void HPPAFormat6:: +formatToMemory(void* where, uint32 /*offset*/) +{ + *(PRUint32 *)where = (hiInfo[kind].opcode << 26) | (((flags & HPPA_R1_IS_ZERO) ? 0 : getR2()) << 21) | (getR1() << 16) | (hiInfo[kind].ext << 6) | getT(); +} + +#if defined(DEBUG) +void HPPAFormat6:: +printPretty(FILE* f) +{ + if (flags & HPPA_IS_COPY) + fprintf(f, "%s %s,%s", hiInfo[kind].string, getR1String(), getTString()); + else if (flags & HPPA_R1_IS_ZERO) + fprintf(f, "%s 0,%s,%s", hiInfo[kind].string, getR1String(), getTString()); + else + fprintf(f, "%s %s,%s,%s", hiInfo[kind].string, getR1String(), getR2String(), getTString()); +} +#endif + + +// HPPAFormat8 methods +// |31 |25 |20 |15 |12 |9 |4 0| +// |-----------------|--------------|--------------|--------|--------|--------------|--------------| +// | op | r | t | c | ext3 | p | clen | +// |-----------------|--------------|--------------|--------|--------|--------------|--------------| + +void HPPAFormat8:: +formatToMemory(void* where, uint32 /*offset*/) +{ + *(PRUint32 *)where = (hiInfo[kind].opcode << 26) | (getR1() << 21) | (getT() << 16) | (hiInfo[kind].ext << 10) | (cp << 5) | (32 - clen); +} + +#if defined(DEBUG) +void HPPAFormat8:: +printPretty(FILE* f) +{ + fprintf(f, "%s %s,%d,%d,%s", hiInfo[kind].string, getR1String(), cp, clen, getTString()); +} +#endif + +// HPPAFormat9 methods +// |31 |25 |20 |15 |12 |9 |4 0| +// |-----------------|--------------|--------------|--------|--------|--------------|--------------| +// | op | t | r/im5 | c | ext3 | cp | clen | +// |-----------------|--------------|--------------|--------|--------|--------------|--------------| + +void HPPAFormat9:: +formatToMemory(void* where, uint32 /*offset*/) +{ + *(PRUint32 *)where = (hiInfo[kind].opcode << 26) | (getT() << 21) | ((validIM5(im5) ? low_sign_unext_5(im5) : (PRUint8) getR1()) << 16) | + (hiInfo[kind].ext << 10) | ((31 - cp) << 5) | (32 - clen); +} + +#if defined(DEBUG) +void HPPAFormat9:: +printPretty(FILE* f) +{ + if (validIM5(im5)) + fprintf(f, "%s %d,%d,%d,%s", hiInfo[kind].string, IM5(im5), cp, clen, getTString()); + else + fprintf(f, "%s %s,%d,%d,%s", hiInfo[kind].string, getR1String(), cp, clen, getTString()); +} +#endif + +// HPPAFormat11 methods +// |31 |25 |20 |15 |12 | 1| 0| +// |-----------------|--------------|--------------|--------|--------------------------------|--|--| +// | op | r2/p | r1/im5 | c | w1 | n| w| +// |-----------------|--------------|--------------|--------|--------------------------------|--|--| + +void HPPAFormat11:: +formatToMemory(void* where, uint32 offset) +{ + PRUint32 w1, w; + + dis_assemble_12((target.getNativeOffset() - (offset + 8)) >> 2, w1, w); + + ((PRUint32 *)where)[0] = (hiInfo[kind].opcode << 26) | (getR2() << 21) | ((validIM5(im5) ? low_sign_unext_5(im5) : (PRUint8) getR1()) << 16) | + (hcInfo[cond].c << 13) | (w1 << 2) | ((nullification ? 1 : 0) << 1) | w; + if (nullification) + ((PRUint32 *)where)[1] = 0x08000240; // nop +} + +#if defined(DEBUG) +void HPPAFormat11:: +printPretty(FILE* f) +{ + if (validIM5(im5)) + fprintf(f, "%s,%s%s %d,%s,N%d%s", hiInfo[kind].string, hcInfo[cond].string, nullification ? ",n" : "", + IM5(im5), getR2String(), target.dfsNum, nullification ? "; nop" : ""); + else + fprintf(f, "%s,%s%s %s,%s,N%d%s", hiInfo[kind].string, hcInfo[cond].string, nullification ? ",n" : "", + getR1String(), getR2String(), target.dfsNum, nullification ? "; nop" : ""); +} +#endif + +// HPPAFormat12 methods +// |31 |25 |20 |15 |12 | 1| 0| +// |-----------------|--------------|--------------|--------|--------------------------------|--|--| +// | op | b | w1 | s | w2 | n| w| +// |-----------------|--------------|--------------|--------|--------------------------------|--|--| + +void HPPAFormat12:: +formatToMemory(void* where, uint32 offset) +{ + PRUint32 w2, w1, w; + + dis_assemble_17((target.getNativeOffset() - (offset + 8)) >> 2, w1, w2, w); + + ((PRUint32 *)where)[0] = (hiInfo[kind].opcode << 26) | /*(getT() << 21) |*/ (w1 << 16) | (w2 << 2) | ((nullification ? 1 : 0) << 1) | w; + if (nullification) + ((PRUint32 *)where)[1] = 0x08000240; // nop +} + +#if defined(DEBUG) +void HPPAFormat12:: +printPretty(FILE* f) +{ + fprintf(f, "%s%s N%d,%s%s", hiInfo[kind].string, nullification ? ",n" : "", + target.dfsNum, getTString(), nullification ? "; nop" : ""); +} +#endif + +// HPPAFormat13 methods +// |31 |25 |20 |15 |12 | 1| 0| +// |-----------------|--------------|--------------|--------|--------------------------------|--|--| +// | op | t | w1 | ext3 | w2 | n| w| +// |-----------------|--------------|--------------|--------|--------------------------------|--|--| +void HPPAFormat13:: +formatToMemory(void* where, uint32 /*offset*/) +{ + PRUint32 w2, w1, w; + + dis_assemble_17((((PRUint32) address) - (((PRUint32) where) + 8)) >> 2, w1, w2, w); + + ((PRUint32 *)where)[0] = (hiInfo[kind].opcode << 26) | (returnRegister << 21) | (w1 << 16) | (w2 << 2) | ((nullification ? 1 : 0) << 1) | w; + if (nullification) + ((PRUint32 *)where)[1] = 0x08000240; // nop +} + +#if defined(DEBUG) +void HPPAFormat13:: +printPretty(FILE* f) +{ + fprintf(f, "%s%s %s,%s", hiInfo[kind].string, nullification ? ",n" : "", getAddressString(), getTString()); +} +#endif + +// HPPAFormat31 methods +// |31 |25 |20 |15 |13|12|11 |9 |8 |5 |4 0| +// |-----------------|--------------|--------------|-----|--|--|-----|--|--------|--|--------------| +// | op | b | im5 | s |a |1 | cc |0 | uid |m | t | +// |-----------------|--------------|--------------|-----|--|--|-----|--|--------|--|--------------| + +void HPPAFormat31:: +formatToMemory(void* where, uint32 /*offset*/) +{ + *(PRUint32 *)where = 0; +} + +#if defined(DEBUG) +void HPPAFormat31:: +printPretty(FILE* f) +{ + fprintf(f, "%s %d(0,%s),%s", hiInfo[kind].string, (PRInt8) getIm5(), getR1String(), getTString()); +} +#endif + +// HPPAFormat32 methods +// |31 |25 |20 |15 |13|12|11 |9 |8 |5 |4 0| +// |-----------------|--------------|--------------|-----|--|--|-----|--|--------|--|--------------| +// | op | b | im5 | s |a |1 | cc |1 | uid |m | r | +// |-----------------|--------------|--------------|-----|--|--|-----|--|--------|--|--------------| + +void HPPAFormat32:: +formatToMemory(void* where, uint32 /*offset*/) +{ + *(PRUint32 *)where = 0; +} + +#if defined(DEBUG) +void HPPAFormat32:: +printPretty(FILE* f) +{ + fprintf(f, "%s %s,%d(0,%s)", hiInfo[kind].string, getR2String(), (PRInt8) getIm5(), getR1String()); +} +#endif + +// HPPAFormat40 methods +// |31 |25 |20 |15 |12|11|10 |8 |7 |6 |5 |4 0| +// |-----------------|--------------|--------------|--------|--|--|-----|--|--|--|--|--------------| +// | op | r1 | r2 | sop |r2|f | 3 |x |r1|t |0 | t | +// |-----------------|--------------|--------------|--------|--|--|-----|--|--|--|--|--------------| + +void HPPAFormat40:: +formatToMemory(void* where, uint32 /*offset*/) +{ + *(PRUint32 *)where = 0; +} + +#if defined(DEBUG) +void HPPAFormat40:: +printPretty(FILE* f) +{ + fprintf(f, "%s %s,%s,%s", hiInfo[kind].string, getR1String(), getR2String(), getTString()); +} +#endif diff --git a/ef/Compiler/CodeGenerator/md/hppa/HPPAInstruction.h b/ef/Compiler/CodeGenerator/md/hppa/HPPAInstruction.h new file mode 100644 index 000000000000..e6f5c9f61dc9 --- /dev/null +++ b/ef/Compiler/CodeGenerator/md/hppa/HPPAInstruction.h @@ -0,0 +1,1004 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#ifndef _HPPA_INSTRUCTION_H_ +#define _HPPA_INSTRUCTION_H_ + +#include "Fundamentals.h" +#include "Instruction.h" + +enum HPPAInstructionKind +{ + ADD, ADDBF, ADDBT, ADDO, ADDIBF, ADDIBT, ADDIL, ADDL, ADDI, ADDIT, + ADDITO, ADDC, ADDCO, AND, ANDCM, BL, BLE, BLR, BE, BB, + BVB, BV, BREAK, COMBF, COMBT, COMCLR, COMIBF, COMIBT, COMICLR, CLDDX, + CLDDS, CLDWX, CLDWS, COPR, CSTDX, CSTDS, CSTWX, CSTWS, COPY, DCOR, + DEP, DEPI, DIAG, DS, XOR, EXTRS, EXTRU, XMPYU, FABS, FCMP, + FCNVXF, FCNVFX, FCNVFXT, FCNVFF, FDIV, FLDDX, FLDDS, FLDWX, FLDWS, FMPY, + FMPYADD, FMPYSUB, FRND, FSQRT, FSTDX, FSTDS, FSTWS, FSUB, FTEST, FDC, + FDCE, FIC, FICE, GATE, DEBUGID, OR, IDTLBA, IDTLBP, IITLBA, IITLBP, + IDCOR, LDCWX, LDCWS, LDB, LDBX, LDBS, LCI, LDH, LDHX, LDHS, + LDI, LDIL, LDO, LPA, LDSID, LDW, LDWAX, LDWAS, LDWM, LDWX, + LDWS, MOVB, MFCTL, MFDBAM, MFDBAO, MFIBAM, MFIBAO, MFSP, MOVIB, MCTL, + MTBAM, MTBAO, MTIBAM, MTIBAO, MTSP, MTSM, PMDIS, PMENB, PROBER, PROBERI, + PROBEW, PROBEWI, PDC, PDTLB, PDTLBE, PITLB, PITLBE, RSM, RFI, RFIR, + SSM, SHD, SH1ADD, SH1ADDL, SH1ADDO, SH2ADD, SH2ADDL, SH2ADDO, SH3ADD, SH3ADDL, + SH3ADDO, SPOP0, SPOP1, SPOP2, SPOP3, STB, STBS, STBYS, STH, STHS, + STW, STWAS, STWM, STWS, SUB, SUBT, SUBTO, SUBO, SUBI, SUBIO, + SUBB, SUBBO, SYNC, SYNCDMA, UADDCM, UADDCMT, UXOR, VDEP, VDEPI, VEXTRU, + VSHD, ZDEP, ZDEPI, ZVDEP, ZVDEPI, + + nHPPAInstructionKind, INVALID +}; + +typedef PRUint32 HPPAInstructionFlags; + +struct HPPAInstructionInfo +{ + HPPAInstructionKind kind; + PRUint8 opcode; + PRUint8 ext; + PRUint8 format; + char* string; + HPPAInstructionFlags flags; +}; + +#define HPPA_isValidInsn(kind) !(hiInfo[kind].flags & HPPA_UNIMP) + +enum HPPAConditionKind +{ + hcNever, hcE, hcL, hcLe, hcLu, hcLeu, hcOver, hcOdd, + hcAlways, hcNe, hcGe, hcG, hcGeu, hcGu, hcNOver, hcEven, + + nHPPAConditionKind +}; + +struct HPPAConditionInfo +{ + HPPAConditionKind kind; + HPPAConditionKind swapped; + PRUint8 c; + bool f; + char *string; +}; + +enum HPPARegisterNumber +{ + zero, r1, rp, r3, r4, r5, r6, r7, + r8, r9, r10, r11, r12, r13, r14, r15, + r16, r17, r18, r19, r20, r21, r22, arg3, + arg2, arg1, arg0, dp, ret0, ret1, sp, r31, + fr0L, fr0R, fr1L, fr1R, fr2L, fr2R, fr3L, fr3R, + fr4L, fr4R, fr5L, fr5R, fr6L, fr6R, fr7L, fr7R, + fr8L, fr8R, fr9L, fr9R, fr10L, fr10R, fr11L, fr11R, + fr12L, fr12R, fr13L, fr13R, fr14L, fr14R, fr15L, fr15R, + fr16L, fr16R, fr17L, fr17R, fr18L, fr18R, fr19L, fr19R, + fr20L, fr20R, fr21L, fr21R, fr22L, fr22R, fr23L, fr23R, + fr24L, fr24R, fr25L, fr25R, fr26L, fr26R, fr27L, fr27R, + fr28L, fr28R, fr29L, fr29R, fr30L, fr30R, fr31L, fr31R, +}; + +enum HPPASpecialCallKind +{ + RemI, + RemU, + DivI, + DivU, + nSpecialCalls +}; + +struct HPPASpecialCallInfo +{ + HPPASpecialCallKind kind; + char* string; + PRUint8 nUses; + PRUint8 nDefines; + PRUint32 interferences1; + PRUint32 interferences2; + PRUint32 interferences3; + void* address; +}; + +extern char* registerNumberToString[]; +extern PRUint8 registerNumberToColor[]; +extern HPPARegisterNumber colorToRegisterNumber[]; +extern HPPAInstructionInfo hiInfo[]; +extern HPPAConditionInfo hcInfo[]; +extern HPPASpecialCallInfo hscInfo[]; +extern HPPAInstructionKind shiftAddl[]; + + +inline HPPARegisterNumber +udToRegisterNumber(InstructionUseOrDefine& useDef) +{ + assert(useDef.isVirtualRegister()); + return (colorToRegisterNumber[useDef.getVirtualRegister().getColor()]); +} + +class HPPAInstruction : public InsnUseXDefineYFromPool +{ +protected: + HPPAInstructionKind kind; + HPPAInstructionFlags flags; + PRUint8 in; + PRUint8 out; + + inline static HPPAInstructionFlags kindFlags(HPPAInstructionKind iKind, HPPAInstructionFlags others) {return hiInfo[iKind].flags | others;} + + virtual HPPARegisterNumber getR1(); + virtual HPPARegisterNumber getR2(); + virtual HPPARegisterNumber getT(); + + inline char* getR1String() {return registerNumberToString[getR1()];} + inline char* getR2String() {return registerNumberToString[getR2()];} + inline char* getTString() {return registerNumberToString[getT()];} + +public: + HPPAInstruction(DataNode* inPrimitive, Pool& inPool, PRUint8 nConsumer, PRUint8 nProducer, HPPAInstructionKind iKind, HPPAInstructionFlags iFlags) : + InsnUseXDefineYFromPool(inPrimitive, inPool, nConsumer, nProducer), kind(iKind), flags(kindFlags(iKind, iFlags)), in(nConsumer), out(nProducer) {} + + virtual size_t getFormattedSize() {return (4);} +#if defined(DEBUG) + virtual void printPretty(FILE* f); +#endif + +}; + +#define HPPA_UNIMP 0x80000000 +#define HPPA_NONE 0x00000000 +#define HPPA_R1_IS_ZERO 0x40000000 +#define HPPA_IS_COPY 0x20000000 +#define HPPA_NULLIFICATION 0x10000000 +#define HPPA_DATA_HAS_IM14 0x08000000 +#define HPPA_DATA_HAS_IM5 0x04000000 +#define HPPA_DATA_HAS_IM21 0x02000000 +#define HPPA_LOAD_VOLATILE 0x01000000 +#define HPPA_LOAD_CONSTANT 0x00800000 +#define HPPA_STORE_CONSTANT 0x00800000 +#define HPPA_REGISTER_INDIRECT 0x00400000 +#define HPPA_LAST_FLAG 0x00200000 + +#define HPPA_IM14_MASK 0x00003fff +#define HPPA_IM14_SHIFT 0 +#define HPPA_VALID_IM14_BIT 0x8000 +#define validIM14(im14) (im14 & HPPA_VALID_IM14_BIT) +#define hasIM14(data) ((data) & HPPA_DATA_HAS_IM14) +#define buildIM14(constant) ((((constant) & HPPA_IM14_MASK) << HPPA_IM14_SHIFT) | HPPA_DATA_HAS_IM14) +#define getIM14(data) (hasIM14(data) ? ((((data) >> HPPA_IM14_SHIFT) & HPPA_IM14_MASK) | HPPA_VALID_IM14_BIT) : 0) +#define IM14(im14) ((PRInt16)((im14 & 0x2000) ? (im14 | ~HPPA_IM14_MASK) : (im14 & HPPA_IM14_MASK))) + +#define HPPA_IM5_MASK 0x0000001f +#define HPPA_IM5_SHIFT 0 +#define HPPA_VALID_IM5_BIT 0x80 +#define validIM5(im5) (im5 & HPPA_VALID_IM5_BIT) +#define hasIM5(data) ((data) & HPPA_DATA_HAS_IM5) +#define buildIM5(constant) ((((constant) & HPPA_IM5_MASK) << HPPA_IM5_SHIFT) | HPPA_DATA_HAS_IM5) +#define getIM5(data) (hasIM5(data) ? ((((data) >> HPPA_IM5_SHIFT) & HPPA_IM5_MASK) | HPPA_VALID_IM5_BIT) : 0) +#define IM5(im5) ((PRInt8)((im5 & 0x10) ? (im5 | ~HPPA_IM5_MASK) : (im5 & HPPA_IM5_MASK))) + +#define HPPA_IM21_MASK 0x001fffff +#define HPPA_IM21_SHIFT 0 +#define HPPA_VALID_IM21_BIT 0x00200000 +#define hasIM21(im21) (im21 & HPPA_DATA_HAS_IM21) +#define buildIM21(constant) ((((constant) & HPPA_IM21_MASK) << HPPA_IM21_SHIFT) | HPPA_DATA_HAS_IM21) +#define getIM21(data) (hasIM21(data) ? ((((data) >> HPPA_IM21_SHIFT) & HPPA_IM21_MASK) | HPPA_VALID_IM21_BIT) : 0) +#define IM21(im21) ((PRInt32)((im21 & HPPA_IM21_MASK) << 11)) + +#define FITS_IM5(v,c) \ + PR_BEGIN_MACRO \ + if ((unsigned)(v) + 0x10 < 0x20) \ + { \ + c = v; \ + return true; \ + } \ + else \ + return false; \ + PR_END_MACRO + +#define FITS_UIM5(v,c) \ + PR_BEGIN_MACRO \ + if ((unsigned)(v) < 0x20) \ + { \ + c = v; \ + return true; \ + } \ + else \ + return false; \ + PR_END_MACRO + +#define FITS_IM11(v,c) \ + PR_BEGIN_MACRO \ + if ((unsigned)(v) + 0x400 < 0x800) \ + { \ + c = v; \ + return true; \ + } \ + else \ + return false; \ + PR_END_MACRO + +#define FITS_IM14(v,c) \ + PR_BEGIN_MACRO \ + if ((unsigned)(v) + 0x2000 < 0x4000) \ + { \ + c = v; \ + return true; \ + } \ + else \ + return false; \ + PR_END_MACRO + +#define HPPA_ADDR_ROUND(addr) (((addr) + 0x1000) & ~0x1fff) +#define HPPA_LEFTR(addr) ((HPPA_ADDR_ROUND(addr) >> 11) & 0x1fffff) +#define HPPA_RIGHTR(addr) ((addr) - HPPA_ADDR_ROUND(addr)) +#define HPPA_LEFT(value) (((value) & 0xfffff800) >> 11) +#define HPPA_RIGHT(value) ((value) & 0x7ff) + +inline bool extractIM5(const Value& v, PRUint8& out) {FITS_IM5(v.i,out);} +inline bool extractIM5(PRInt32 v, PRUint8& out) {FITS_IM5(v,out);} +inline bool extractUIM5(const Value& v, PRUint8& out) {FITS_UIM5(v.i,out);} +inline bool extractUIM5(PRInt32 v, PRUint8& out) {FITS_UIM5(v,out);} +inline bool extractIM11(const Value& v, PRUint16& out) {FITS_IM11(v.i,out);} +inline bool extractIM11(PRInt32 v, PRUint16& out) {FITS_IM11(v,out);} +inline bool extractIM14(const Value& v, PRUint16& out) {FITS_IM14(v.i,out);} +inline bool extractIM14(PRInt32 v, PRUint16& out) {FITS_IM14(v,out);} + +template +class HPPAGeneric : public HPPAFormatN +{ +public: + HPPAGeneric(DataNode* inPrimitive, Pool& inPool, HPPAInstructionFlags flags = 0) : + HPPAFormatN(inPrimitive, inPool, iKind, flags) {} +}; + +template +class HPPAGenericU16 : public HPPAFormatN +{ +public: + HPPAGenericU16(DataNode* inPrimitive, Pool& inPool, PRUint16 data, HPPAInstructionFlags flags = 0) : + HPPAFormatN(inPrimitive, inPool, iKind, data, flags) {} +}; + +template +class HPPAGenericU32 : public HPPAFormatN +{ +public: + HPPAGenericU32(DataNode* inPrimitive, Pool& inPool, PRUint32 data, HPPAInstructionFlags flags = 0) : + HPPAFormatN(inPrimitive, inPool, iKind, data, flags) {} +}; + +template +class HPPAGenericU8U8 : public HPPAFormatN +{ +public: + HPPAGenericU8U8(DataNode* inPrimitive, Pool& inPool, PRUint8 data1, PRUint8 data2, HPPAInstructionFlags flags = 0) : + HPPAFormatN(inPrimitive, inPool, iKind, data1, data2, flags) {} +}; + + +// Format1: +// +// Loads and Stores, Load and Store Word Modify, Load Offset +// |31 |25 |20 |15 |13 0| +// |-----------------|--------------|--------------|-----|-----------------------------------------| +// | op | b | t/r | s | im14 | +// |-----------------|--------------|--------------|-----|-----------------------------------------| + +class HPPAFormat1 : public HPPAInstruction +{ +protected: + PRUint16 im14; + + inline static PRUint8 getNConsumer(HPPAInstructionKind kind, HPPAInstructionFlags flags) {return (kindFlags(kind, flags) & HPPA_R1_IS_ZERO) ? 0 : 1;} + virtual PRUint16 getIm14() {return IM14(im14);} + +public: + HPPAFormat1(DataNode* inPrimitive, Pool& inPool, HPPAInstructionKind kind, HPPAInstructionFlags flags = 0) : + HPPAInstruction(inPrimitive, inPool, getNConsumer(kind,flags), 1, kind, flags), im14(getIM14(flags)) {assert(hasIM14(flags));} + HPPAFormat1(DataNode* inPrimitive, Pool& inPool, PRUint8 nConsumer, PRUint8 nProducer, HPPAInstructionKind kind, HPPAInstructionFlags flags = 0) : + HPPAInstruction(inPrimitive, inPool, nConsumer, nProducer, kind, flags), im14(getIM14(flags)) {assert(hasIM14(flags));} + + + virtual void formatToMemory(void* where, uint32 offset); +#if defined(DEBUG) + virtual void printPretty(FILE* f); +#endif +}; + +class HPPALoad : public HPPAFormat1 +{ +protected: + inline static PRUint8 getNConsumer(HPPAInstructionKind kind, HPPAInstructionFlags flags) {return ((kindFlags(kind, flags) & HPPA_LOAD_CONSTANT) == 0) ? 2 : 1;} + inline static PRUint8 getNProducer(HPPAInstructionKind kind, HPPAInstructionFlags flags) {return ((kindFlags(kind, flags) & HPPA_LOAD_VOLATILE) != 0) ? 2 : 1;} + +public: + HPPALoad(DataNode* inPrimitive, Pool& inPool, HPPAInstructionKind kind, HPPAInstructionFlags flags = 0) : + HPPAFormat1(inPrimitive, inPool, getNConsumer(kind,flags), getNProducer(kind,flags), kind, flags) {} + HPPALoad(DataNode* inPrimitive, Pool& inPool, HPPAInstructionKind kind, PRUint8 nConsumer, PRUint8 nProducer, HPPAInstructionFlags flags = 0) : + HPPAFormat1(inPrimitive, inPool, nConsumer, nProducer, kind, flags) {} + +#if defined(DEBUG) + virtual void printPretty(FILE* f); +#endif +}; + +class HPPASpillLoad : public HPPALoad +{ +protected: + virtual PRUint16 getIm14() {return 0;} + virtual HPPARegisterNumber getR1() {return sp;} + +public: + HPPASpillLoad(DataNode* inPrimitive, Pool& inPool, VirtualRegister& stackSlotRegister, VirtualRegister& destRegister) : + HPPALoad(inPrimitive, inPool, LDW, HPPA_LOAD_CONSTANT | buildIM14(0)) + {addUse(0, stackSlotRegister, vrcStackSlot); addDefine(0, destRegister, vrcInteger);} +}; + +class HPPALoadIntegerFromConvertStackSlot : public HPPALoad +{ +protected: + virtual PRUint16 getIm14() {return -16;} + virtual HPPARegisterNumber getR1() {return sp;} + +public: + HPPALoadIntegerFromConvertStackSlot(DataNode* inPrimitive, Pool& inPool, VirtualRegister& destRegister) : + HPPALoad(inPrimitive, inPool, LDW, 0, 1, buildIM14(0)) {addDefine(0, destRegister, vrcInteger);} +}; + + +class HPPAStore : public HPPAFormat1 +{ +protected: + inline static PRUint8 getNConsumer(HPPAInstructionKind kind, HPPAInstructionFlags flags) {return ((kindFlags(kind, flags) & HPPA_STORE_CONSTANT) == 0) ? 3 : 1;} + +public: + HPPAStore(DataNode* inPrimitive, Pool& inPool, HPPAInstructionKind kind, HPPAInstructionFlags flags = 0) : + HPPAFormat1(inPrimitive, inPool, getNConsumer(kind, flags), 1, kind, flags) {} + HPPAStore(DataNode* inPrimitive, Pool& inPool, HPPAInstructionKind kind, PRUint8 nConsumer, PRUint8 nProducer, HPPAInstructionFlags flags = 0) : + HPPAFormat1(inPrimitive, inPool, nConsumer, nProducer, kind, flags) {} + + virtual void formatToMemory(void* where, uint32 offset); +#if defined(DEBUG) + virtual void printPretty(FILE* f); +#endif +}; + +class HPPASpillStore : public HPPAStore +{ +protected: + virtual PRUint16 getIm14() {return 0;} + virtual HPPARegisterNumber getR1() {return sp;} + +public: + HPPASpillStore(DataNode* inPrimitive, Pool& inPool, VirtualRegister& stackSlotRegister, VirtualRegister& srcRegister) : + HPPAStore(inPrimitive, inPool, STW, HPPA_STORE_CONSTANT | buildIM14(0)) + {addUse(0, srcRegister, vrcInteger); addDefine(0, stackSlotRegister, vrcStackSlot);} + +}; + +class HPPAStoreIntegerToConvertStackSlot : public HPPAStore +{ +protected: + virtual PRUint16 getIm14() {return -16;} + virtual HPPARegisterNumber getR1() {return sp;} + +public: + HPPAStoreIntegerToConvertStackSlot(DataNode* inPrimitive, Pool& inPool, VirtualRegister& srcRegister) : + HPPAStore(inPrimitive, inPool, STW, 1, 0, buildIM14(0)) {addUse(0, srcRegister, vrcInteger);} +}; + +typedef HPPAGeneric HPPALdi; +typedef HPPAGeneric HPPALdo; + +// Format2: +// +// Indexed Loads +// |31 |25 |20 |15 |13|12|11 |9 |5 |4 0| +// |-----------------|--------------|--------------|-----|--|--|-----|-----------|--|--------------| +// | op | b | x | s | u| 0| cc | ext4 | m| t | +// |-----------------|--------------|--------------|-----|--|--|-----|-----------|--|--------------| + +// Format3: +// +// Short Displacement Loads +// |31 |25 |20 |15 |13|12|11 |9 |5 |4 0| +// |-----------------|--------------|--------------|-----|--|--|-----|-----------|--|--------------| +// | op | b | im5 | s | a| 1| cc | ext4 | m| t | +// |-----------------|--------------|--------------|-----|--|--|-----|-----------|--|--------------| + +// Format4: +// +// Short Displacement Stores, Store Bytes Short +// |31 |25 |20 |15 |13|12|11 |9 |5 |4 0| +// |-----------------|--------------|--------------|-----|--|--|-----|-----------|--|--------------| +// | op | b | im5 | s | a| 1| cc | ext4 | m| im5 | +// |-----------------|--------------|--------------|-----|--|--|-----|-----------|--|--------------| + +// Format5: +// +// Long Immediates +// |31 |25 |20 0| +// |-----------------|--------------|--------------------------------------------------------------| +// | op | t/r | im21 | +// |-----------------|--------------|--------------------------------------------------------------| +class HPPAFormat5 : public HPPAInstruction +{ +protected: + PRUint32 im21; + +public: + HPPAFormat5(DataNode* inPrimitive, Pool& inPool, HPPAInstructionKind kind, HPPAInstructionFlags flags = 0) : + HPPAInstruction(inPrimitive, inPool, 0, 1, kind, flags), im21(getIM21(flags)) {assert(hasIM21(flags));} + + virtual void formatToMemory(void* where, uint32 offset); +#if defined(DEBUG) + virtual void printPretty(FILE* f); +#endif +}; + +typedef HPPAGeneric HPPALdil; + +// Format6: +// +// Arithmetic/Logical +// |31 |25 |20 |15 |12|11 |5 |4 0| +// |-----------------|--------------|--------------|--------|--|-----------------|--|--------------| +// | op | r2 | r1 | c | f| ext6 |0 | t | +// |-----------------|--------------|--------------|--------|--|-----------------|--|--------------| +// + +class HPPAFormat6 : public HPPAInstruction +{ +protected: + inline static PRUint8 getNConsumer(HPPAInstructionKind kind, HPPAInstructionFlags flags) {return (kindFlags(kind, flags) & HPPA_R1_IS_ZERO) ? 1 : 2;} + +public: + HPPAFormat6(DataNode* inPrimitive, Pool& inPool, HPPAInstructionKind kind, HPPAInstructionFlags flags = 0) : + HPPAInstruction(inPrimitive, inPool, getNConsumer(kind,flags), 1, kind, flags) {} + +#if defined(DEBUG) + virtual void printPretty(FILE* f); +#endif + virtual void formatToMemory(void* where, uint32 offset); + virtual InstructionFlags getFlags() const {return (flags & HPPA_IS_COPY) ? ifCopy : ifNone;} +}; + +typedef HPPAGeneric HPPAOr; +typedef HPPAGeneric HPPAAnd; +typedef HPPAGeneric HPPAXor; +typedef HPPAGeneric HPPAAdd; +typedef HPPAGeneric HPPASub; +typedef HPPAGeneric HPPAAddl; +typedef HPPAGeneric HPPACopy; +typedef HPPAGeneric HPPASh1Addl; +typedef HPPAGeneric HPPASh2Addl; +typedef HPPAGeneric HPPASh3Addl; + +// Format7: +// +// Arithmetic Immediate +// |31 |25 |20 |15 |12|11|10 0| +// |-----------------|--------------|--------------|--------|--|--|--------------------------------| +// | op | r | t | c | f| e| im11 | +// |-----------------|--------------|--------------|--------|--|--|--------------------------------| + +// Format8: +// +// Extract +// |31 |25 |20 |15 |12 |9 |4 0| +// |-----------------|--------------|--------------|--------|--------|--------------|--------------| +// | op | r | t | c | ext3 | p | clen | +// |-----------------|--------------|--------------|--------|--------|--------------|--------------| +class HPPAFormat8 : public HPPAInstruction +{ +protected: + PRUint8 cp; + PRUint8 clen; + +public: + HPPAFormat8(DataNode* inPrimitive, Pool& inPool, HPPAInstructionKind kind, PRUint8 p, PRUint8 len, HPPAInstructionFlags flags = 0) : + HPPAInstruction(inPrimitive, inPool, 1, 1, kind, flags), cp(p), clen(len) {} + + virtual void formatToMemory(void* where, uint32 offset); +#if defined(DEBUG) + virtual void printPretty(FILE* f); +#endif +}; + +typedef HPPAGenericU8U8 HPPAExtru; +typedef HPPAGenericU8U8 HPPAExtrs; + +// Format9: +// +// Deposit +// |31 |25 |20 |15 |12 |9 |4 0| +// |-----------------|--------------|--------------|--------|--------|--------------|--------------| +// | op | t | r/im5 | c | ext3 | cp | clen | +// |-----------------|--------------|--------------|--------|--------|--------------|--------------| + +class HPPAFormat9 : public HPPAInstruction +{ +protected: + PRUint8 im5; + PRUint8 cp; + PRUint8 clen; + + inline static PRUint8 getNConsumer(HPPAInstructionKind kind, HPPAInstructionFlags flags) + { + PRUint8 nUse = hasIM5(kindFlags(kind,flags)) ? 1 : 2; + // for ZDEP, ZDEPI the target is erased. This register will die. + return (kindFlags(kind, flags) & HPPA_R1_IS_ZERO) ? nUse - 1 : nUse; + } + +public: + HPPAFormat9(DataNode* inPrimitive, Pool& inPool, HPPAInstructionKind kind, PRUint8 p, PRUint8 len, HPPAInstructionFlags flags = 0) : + HPPAInstruction(inPrimitive, inPool, getNConsumer(kind, flags), 1, kind, flags), im5(hasIM5(flags) ? getIM5(flags) : 0), + cp(p), clen(len) {} + + virtual void formatToMemory(void* where, uint32 offset); +#if defined(DEBUG) + virtual void printPretty(FILE* f); +#endif +}; + +typedef HPPAGenericU8U8 HPPADepi; +typedef HPPAGenericU8U8 HPPAZdep; + +// Format10: +// +// Shift +// |31 |25 |20 |15 |12 |9 |4 0| +// |-----------------|--------------|--------------|--------|--------|--------------|--------------| +// | op | r2 | r1 | c | ext3 | cp | t | +// |-----------------|--------------|--------------|--------|--------|--------------|--------------| + +// Format11: +// +// Conditional Branch +// |31 |25 |20 |15 |12 | 1| 0| +// |-----------------|--------------|--------------|--------|--------------------------------|--|--| +// | op | r2/p | r1/im5 | c | w1 | n| w| +// |-----------------|--------------|--------------|--------|--------------------------------|--|--| + +class HPPAFormat11 : public HPPAInstruction +{ +protected: + ControlNode& target; + HPPAConditionKind cond; + PRUint8 im5; + bool nullification; + + inline static PRUint8 getNConsumer(HPPAInstructionKind kind, HPPAInstructionFlags flags) {return hasIM5(kindFlags(kind,flags)) ? 1 : 2;} + +public: + HPPAFormat11(DataNode* inPrimitive, Pool& inPool, ControlNode& t, HPPAInstructionKind kind, + HPPAConditionKind cKind, HPPAInstructionFlags flags = 0) + : HPPAInstruction(inPrimitive, inPool, getNConsumer(kind, flags), 0, kind, flags), + target(t), cond(cKind), im5(hasIM5(flags) ? getIM5(flags) : 0), nullification(flags & HPPA_NULLIFICATION) + {} + + virtual size_t getFormattedSize() {return (nullification ? 8 : 4);} + virtual void formatToMemory(void* where, uint32 offset); +#if defined(DEBUG) + virtual void printPretty(FILE* f); +#endif +}; + +typedef HPPAFormat11 HPPACondBranch; + +// Format12: +// +// Branch External, Branch and Link External +// |31 |25 |20 |15 |12 | 1| 0| +// |-----------------|--------------|--------------|--------|--------------------------------|--|--| +// | op | b | w1 | s | w2 | n| w| +// |-----------------|--------------|--------------|--------|--------------------------------|--|--| + +class HPPAFormat12 : public HPPAInstruction +{ +protected: + ControlNode& target; + bool nullification; + +public: + HPPAFormat12(DataNode* inPrimitive, Pool& inPool, ControlNode& t, HPPAInstructionKind kind, HPPAInstructionFlags flags = 0) + : HPPAInstruction(inPrimitive, inPool, 0, 0, kind, flags), + target(t), nullification(flags & HPPA_NULLIFICATION) + {} + + virtual HPPARegisterNumber getT() {return zero;} + virtual size_t getFormattedSize() {return (nullification ? 8 : 4);} + virtual void formatToMemory(void* where, uint32 offset); +#if defined(DEBUG) + virtual void printPretty(FILE* f); +#endif +}; + +typedef HPPAFormat12 HPPAAbsoluteBranch; + +// Format13: +// +// Branch and Link, Gateway +// |31 |25 |20 |15 |12 | 1| 0| +// |-----------------|--------------|--------------|--------|--------------------------------|--|--| +// | op | t | w1 | ext3 | w2 | n| w| +// |-----------------|--------------|--------------|--------|--------------------------------|--|--| + +class HPPAFormat13 : public HPPAInstruction +{ +protected: + void* address; + HPPARegisterNumber returnRegister; + bool nullification; + +public: + HPPAFormat13(DataNode* inPrimitive, Pool& inPool, void *f, PRUint8 nUses, PRUint8 nDefines, HPPAInstructionKind kind, + HPPARegisterNumber ret, HPPAInstructionFlags flags = 0) + : HPPAInstruction(inPrimitive, inPool, nUses, nDefines, kind, flags), address(f), returnRegister(ret), nullification(flags & HPPA_NULLIFICATION) {} + + virtual char *getAddressString() {return "";} + virtual size_t getFormattedSize() {return (nullification ? 8 : 4);} + virtual void formatToMemory(void* where, uint32 offset); +#if defined(DEBUG) + virtual void printPretty(FILE* f); +#endif +}; + +class HPPASpecialCall : public HPPAFormat13 +{ +protected: + HPPASpecialCallKind callKind; + +public: + HPPASpecialCall(DataNode* inPrimitive, Pool& inPool, HPPASpecialCallKind kind, HPPAInstructionFlags flags = 0) : + HPPAFormat13(inPrimitive, inPool, hscInfo[kind].address, hscInfo[kind].nUses, hscInfo[kind].nDefines, BL, r31, flags), callKind(kind) {} + + virtual char* getAddressString() {return hscInfo[callKind].string;} + virtual HPPARegisterNumber getT() {return r31;} + + virtual PRUint32* getExtraRegisterInterferenceBegin() {return &hscInfo[callKind].interferences1;} + virtual PRUint32* getExtraRegisterInterferenceEnd() {return &hscInfo[callKind].interferences3 + 1;} + virtual InstructionFlags getFlags() const {return ifSpecialCall;} +}; + +// Format14: +// +// Branch and Link Register, Branch Vectored +// |31 |25 |20 |15 |12 | 1| 0| +// |-----------------|--------------|--------------|--------|--------------------------------|--|--| +// | op | t/b | x | ext3 | 0 | n| 0| +// |-----------------|--------------|--------------|--------|--------------------------------|--|--| + +// Format15: +// +// Data Memory Management, Probe +// |31 |25 |20 |15 |13 |5 |4 0| +// |-----------------|--------------|--------------|-----|-----------------------|--|--------------| +// | op | b | r/x/im5 | s | ext8 |m | t | +// |-----------------|--------------|--------------|-----|-----------------------|--|--------------| + +// Format16: +// +// Instruction Memory Management +// |31 |25 |20 |15 |12 |5 |4 0| +// |-----------------|--------------|--------------|--------|--------------------|--|--------------| +// | op | b | r/x/im5 | s | ext7 |m | t | +// |-----------------|--------------|--------------|--------|--------------------|--|--------------| + +// Format17: +// +// Break +// |31 |25 |12 |4 0| +// |-----------------|--------------------------------------|-----------------------|--------------| +// | op | im13 | ext8 | im5 | +// |-----------------|--------------------------------------|-----------------------|--------------| + +// Format18: +// +// Diagnose +// |31 |25 0| +// |-----------------|-----------------------------------------------------------------------------| +// | op | | +// |-----------------|-----------------------------------------------------------------------------| + +// Format19: +// +// Move to/from Space Register +// |31 |25 |20 |15 |12 |4 0| +// |-----------------|--------------|--------------|--------|-----------------------|--------------| +// | op | rv | r | s | ext8 | t | +// |-----------------|--------------|--------------|--------|-----------------------|--------------| + +// Format20: +// +// Load Space ID +// |31 |25 |20 |15 |13|12 |4 0| +// |-----------------|--------------|--------------|-----|--|-----------------------|--------------| +// | op | b | rv | s | 0| ext8 | t | +// |-----------------|--------------|--------------|-----|--|-----------------------|--------------| + + +// Format21: +// +// Move to Control Register +// |31 |25 |20 |15 |12 |4 0| +// |-----------------|--------------|--------------|--------|-----------------------|--------------| +// | op | t | r | rv | ext8 | 0 | +// |-----------------|--------------|--------------|--------|-----------------------|--------------| + +// Format22: +// +// Move from Control Register +// |31 |25 |20 |15 |12 |4 0| +// |-----------------|--------------|--------------|--------|-----------------------|--------------| +// | op | r | 0 | rv | ext8 | t | +// |-----------------|--------------|--------------|--------|-----------------------|--------------| + +// Format23: +// +// System Control +// |31 |25 |20 |15 |12 |4 0| +// |-----------------|--------------|--------------|--------|-----------------------|--------------| +// | op | b | r/im5 | 0 | ext8 | t | +// |-----------------|--------------|--------------|--------|-----------------------|--------------| + +// Format24: +// +// Special Operation Zero +// |31 |25 |10 |8 |5 |4 0| +// |-----------------|--------------------------------------------|-----|--------|--|--------------| +// | op | sop1 | 0 | sfu |n | sop2 | +// |-----------------|--------------------------------------------|-----|--------|--|--------------| + +// Format25: +// +// Special Operation One +// |31 |25 |10 |8 |5 |4 0| +// |-----------------|--------------------------------------------|-----|--------|--|--------------| +// | op | sop | 1 | sfu |n | t | +// |-----------------|--------------------------------------------|-----|--------|--|--------------| + +// Format26: +// +// Special Operation Two +// |31 |25 |20 |10 |8 |5 |4 0| +// |-----------------|--------------|-----------------------------|-----|--------|--|--------------| +// | op | r | sop1 | 2 | sfu |n | sop2 | +// |-----------------|--------------|-----------------------------|-----|--------|--|--------------| + +// Format27: +// +// Special Operation Three +// |31 |25 |20 |15 |10 |8 |5 |4 0| +// |-----------------|--------------|--------------|--------------|-----|--------|--|--------------| +// | op | r2 | r1 | sop1 | 3 | sfu |n | sop2 | +// |-----------------|--------------|--------------|--------------|-----|--------|--|--------------| + +// Format28: +// +// Coprocessor Operation +// |31 |25 |8 |5 |4 0| +// |-----------------|--------------------------------------------------|--------|--|--------------| +// | op | sop1 | uid |n | sop2 | +// |-----------------|--------------------------------------------------|--------|--|--------------| + +// Format29: +// +// Coprocessor Indexed Loads +// |31 |25 |20 |15 |13|12|11 |9 |8 |5 |4 0| +// |-----------------|--------------|--------------|-----|--|--|-----|--|--------|--|--------------| +// | op | b | x | s |u |0 | cc |0 | uid |m | t | +// |-----------------|--------------|--------------|-----|--|--|-----|--|--------|--|--------------| + +// Format30: +// +// Coprocessor Indexed Stores +// |31 |25 |20 |15 |13|12|11 |9 |8 |5 |4 0| +// |-----------------|--------------|--------------|-----|--|--|-----|--|--------|--|--------------| +// | op | b | x | s |u |0 | cc |1 | uid |m | r | +// |-----------------|--------------|--------------|-----|--|--|-----|--|--------|--|--------------| + +// Format31: +// +// Coprocessor Short Displacement Loads +// |31 |25 |20 |15 |13|12|11 |9 |8 |5 |4 0| +// |-----------------|--------------|--------------|-----|--|--|-----|--|--------|--|--------------| +// | op | b | im5 | s |a |1 | cc |0 | uid |m | t | +// |-----------------|--------------|--------------|-----|--|--|-----|--|--------|--|--------------| +class HPPAFormat31 : public HPPAInstruction +{ +protected: + PRUint8 im5; + virtual PRUint8 getIm5() {return IM5(im5);} + +public: + HPPAFormat31(DataNode* inPrimitive, Pool& inPool, HPPAInstructionKind kind, HPPAInstructionFlags flags = 0) : + HPPAInstruction(inPrimitive, inPool, 0, 1, kind, flags), im5(getIM5(flags)) {assert(hasIM5(flags));} + + virtual void formatToMemory(void* where, uint32 offset); +#if defined(DEBUG) + virtual void printPretty(FILE* f); +#endif +}; + +class HPPALoadFixedPointFromConvertStackSlot : public HPPAFormat31 +{ +protected: + virtual PRUint8 getIm5() {return -16;} + virtual HPPARegisterNumber getR1() {return sp;} + +public: + HPPALoadFixedPointFromConvertStackSlot(DataNode* inPrimitive, Pool& inPool, VirtualRegister& destRegister) : + HPPAFormat31(inPrimitive, inPool, FLDWS, HPPA_LOAD_CONSTANT | buildIM5(0)) {addDefine(0, destRegister, vrcFixedPoint);} +}; + +// Format32: +// +// Coprocessor Short Displacement Stores +// |31 |25 |20 |15 |13|12|11 |9 |8 |5 |4 0| +// |-----------------|--------------|--------------|-----|--|--|-----|--|--------|--|--------------| +// | op | b | im5 | s |a |1 | cc |1 | uid |m | r | +// |-----------------|--------------|--------------|-----|--|--|-----|--|--------|--|--------------| +class HPPAFormat32 : public HPPAInstruction +{ +protected: + PRUint8 im5; + virtual PRUint8 getIm5() {return IM5(im5);} + +public: + HPPAFormat32(DataNode* inPrimitive, Pool& inPool, HPPAInstructionKind kind, HPPAInstructionFlags flags = 0) : + HPPAInstruction(inPrimitive, inPool, 1, 0, kind, flags), im5(getIM5(flags)) {assert(hasIM5(flags));} + + virtual void formatToMemory(void* where, uint32 offset); +#if defined(DEBUG) + virtual void printPretty(FILE* f); +#endif +}; + +class HPPAStoreFixedPointToConvertStackSlot : public HPPAFormat32 +{ +protected: + virtual PRUint8 getIm5() {return -16;} + virtual HPPARegisterNumber getR1() {return sp;} + +public: + HPPAStoreFixedPointToConvertStackSlot(DataNode* inPrimitive, Pool& inPool, VirtualRegister& srcRegister) : + HPPAFormat32(inPrimitive, inPool, FSTWS, HPPA_STORE_CONSTANT | buildIM5(0)) {addUse(0, srcRegister, vrcFixedPoint);} +}; + +// Format33: +// +// Floating-point Operation Zero, Major Opcode 0C +// |31 |25 |20 |15 |12 |10 |8 |5 |4 0| +// |-----------------|--------------|--------------|--------|-----|-----|--------|--|--------------| +// | op | r | 0 | sop | fmt | 0 | 0 |0 | t | +// |-----------------|--------------|--------------|--------|-----|-----|--------|--|--------------| + +// Format34: +// +// Floating-point Operation One, Major Opcode 0C +// |31 |25 |20 |16 |14 |12 |10 |8 |5 |4 0| +// |-----------------|--------------|-----------|-----|-----|-----|-----|--------|--|--------------| +// | op | r | 0 | sop | df | sf | 1 | 0 |0 | t | +// |-----------------|--------------|-----------|-----|-----|-----|-----|--------|--|--------------| + +// Format35: +// +// Floating-point Operation Two, Major Opcode 0C +// |31 |25 |20 |15 |12 |10 |8 |5 |4 0| +// |-----------------|--------------|--------------|--------|-----|-----|--------|--|--------------| +// | op | r1 | r2 | sop | fmt | 2 | 0 |n | c | +// |-----------------|--------------|--------------|--------|-----|-----|--------|--|--------------| + +// Format36: +// +// Floating-point Operation three, Major Opcode 0C +// |31 |25 |20 |15 |12 |10 |8 |5 |4 0| +// |-----------------|--------------|--------------|--------|-----|-----|--------|--|--------------| +// | op | r1 | r2 | sop | fmt | 3 | 0 |0 | t | +// |-----------------|--------------|--------------|--------|-----|-----|--------|--|--------------| + +// Format37: +// +// Floating-point Operation Zero, Major Opcode 0E +// |31 |25 |20 |15 |12 |10 |8 |7 |6 |5 |4 0| +// |-----------------|--------------|--------------|--------|-----|-----|--|--|--|--|--------------| +// | op | r1 | r2 | sop | fmt | 0 |0 |r |t |0 | t | +// |-----------------|--------------|--------------|--------|-----|-----|--|--|--|--|--------------| + +// Format38: +// +// Floating-point Operation One, Major Opcode 0E +// |31 |25 |20 |16 |14 |12 |10 |8 |7 |6 |5 |4 0| +// |-----------------|--------------|-----------|-----|-----|-----|-----|--|--|--|--|--------------| +// | op | r | 0 | sop | df | sf | 1 |0 |r |t |0 | t | +// |-----------------|--------------|-----------|-----|-----|-----|-----|--|--|--|--|--------------| + +// Format39: +// +// Floating-point Operation Two, Major Opcode 0E +// |31 |25 |20 |15 |12|11|10 |8 |7 |6 |5 |4 0| +// |-----------------|--------------|--------------|--------|--|--|-----|--|--|--|--|--------------| +// | op | r1 | r2 | sop |r2|f | 2 |0 |r1|0 |0 | c | +// |-----------------|--------------|--------------|--------|--|--|-----|--|--|--|--|--------------| + +// Format40: +// +// Floating-point Operation Three, Major Opcode 0E +// |31 |25 |20 |15 |12|11|10 |8 |7 |6 |5 |4 0| +// |-----------------|--------------|--------------|--------|--|--|-----|--|--|--|--|--------------| +// | op | r1 | r2 | sop |r2|f | 3 |x |r1|t |0 | t | +// |-----------------|--------------|--------------|--------|--|--|-----|--|--|--|--|--------------| +class HPPAFormat40 : public HPPAInstruction +{ +protected: + +public: + HPPAFormat40(DataNode* inPrimitive, Pool& inPool, HPPAInstructionKind kind, HPPAInstructionFlags flags = 0) : + HPPAInstruction(inPrimitive, inPool, 2, 1, kind, flags) {} + + virtual void formatToMemory(void* where, uint32 offset); +#if defined(DEBUG) + virtual void printPretty(FILE* f); +#endif +}; +typedef HPPAGeneric HPPAXmpyu; + +// Format41: +// +// Floating-point Multiple-operation +// |31 |25 |20 |15 |10 |5 |4 0| +// |-----------------|--------------|--------------|--------------|--------------|--|--------------| +// | op | rm1 | rm2 | ta | ra |f | tm | +// |-----------------|--------------|--------------|--------------|--------------|--|--------------| + + +//------------------------------ Field Names ----------------------------------// +// // +// a - modify before/after bit // +// b - base register // +// c - condition specifier // +// cc - cache control hint // +// clen - 31 - extract/deposit length // +// cp - 31 - bit position // +// df - floating-point destination format // +// e or ext - operation code extension // +// f - condition negation bit // +// f or fmt - floating-point data format // +// im - immediate value // +// m - modify bit // +// n - nullify bit // +// op - operation code // +// p - extract/deposit/shift bit position // +// r, r1, or r2 - source register // +// ra, rm1, or rm2 - floating-point multiple-operation source register // +// rv - reserved instruction field // +// s - 2 or 3 bit space register // +// sf - floating-point source format // +// sfu - special function unit number // +// sop, sop1, or sop2 - special function unit or coprocessor operation // +// t, ta, or tm - target register // +// u - shift index bit // +// uid - coprocessor unit identifier // +// w, w1, or w2 - word offset/word offset part // +// x - index register // +// // +//-----------------------------------------------------------------------------// + + +#endif /* _HPPA_INSTRUCTION_H_ */ diff --git a/ef/Compiler/CodeGenerator/md/hppa/HPPAMul.cpp b/ef/Compiler/CodeGenerator/md/hppa/HPPAMul.cpp new file mode 100644 index 000000000000..82bf4fb1b312 --- /dev/null +++ b/ef/Compiler/CodeGenerator/md/hppa/HPPAMul.cpp @@ -0,0 +1,260 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#include "Fundamentals.h" +#include "prbit.h" + +#include "HPPAMul.h" + +/* + *----------------------------------------------------------------------- + * + * Local data for an HPPA proc. This should be obtained by asking the + * Code Generator to fill these arrays. + * + *----------------------------------------------------------------------- + */ + +static PRInt16 shiftCosts[32] = +{ + 0, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4 +}; + +static PRInt16 shiftAddCosts[32] = +{ + 4, 4, 4, 4, 999, 999, 999, 999, + 999, 999, 999, 999, 999, 999, 999, 999, + 999, 999, 999, 999, 999, 999, 999, 999, + 999, 999, 999, 999, 999, 999, 999, 999 +}; + +static PRInt16 shiftSubCosts[32] = +{ + 4, 999, 999, 999, 999, 999, 999, 999, + 999, 999, 999, 999, 999, 999, 999, 999, + 999, 999, 999, 999, 999, 999, 999, 999, + 999, 999, 999, 999, 999, 999, 999, 999 +}; + +static PRInt16 addCost = 4; + +/* + *----------------------------------------------------------------------- + * + * getMulAlgorithm -- + * + * Return the best algorithm for an immediate multiplication. + * If algorithm.cost >= maxCost or retval is false then no algorithm + * was found and a regular multiplication should be used. + * + * This algorithm does not work if the register to multiply is larger + * than an PRUint32 and the multiplicand does not fit exactely in an PRUint32. + * e.g.: long long mul by a negative value. + * + *----------------------------------------------------------------------- + */ +bool +getMulAlgorithm(MulAlgorithm* algorithm, PRUint32 multiplicand, PRInt16 maxCost) +{ + PRUint32 mask; + PRUint8 currentCost; + PRInt8 shiftBy; + + algorithm->cost = maxCost; + if (maxCost <= 0) + return false; + + if (multiplicand == 0x1) + { + algorithm->nOperations = 1; + algorithm->cost = 0; + algorithm->operations[0] = maMultiplicand; + return true; + } + + if (multiplicand == 0x0) + { + algorithm->nOperations = 1; + algorithm->cost = 0; + algorithm->operations[0] = maZero; + return true; + } + + MulAlgorithm* downAlgorithm = new MulAlgorithm(); + MulAlgorithm* bestAlgorithm = new MulAlgorithm(); + MulAlgorithm* swapAlgorithm; + + // we try to do a shift if there is a group of 0 bits. + if ((multiplicand & 0x1) == 0x0) + { + // number of low zero bits. + mask = multiplicand & -multiplicand; + PR_FLOOR_LOG2(shiftBy, mask); + + currentCost = shiftCosts[shiftBy]; + getMulAlgorithm(downAlgorithm, multiplicand >> shiftBy, maxCost - currentCost); + currentCost += downAlgorithm->cost; + + if (currentCost < maxCost) + { + swapAlgorithm = downAlgorithm, downAlgorithm = bestAlgorithm, bestAlgorithm = swapAlgorithm; + bestAlgorithm->shiftAmount[bestAlgorithm->nOperations] = shiftBy; + bestAlgorithm->operations[bestAlgorithm->nOperations] = maShiftValue; + maxCost = currentCost; + } + } + + // If this is an odd number, we can try to add one or to subtract one. + if ((multiplicand & 0x1) != 0x0) + { + for (mask = 1; (mask & multiplicand) != 0x0; mask <<= 1); + + if (mask > 2 && multiplicand != 3) + { + currentCost = addCost; + getMulAlgorithm(downAlgorithm, multiplicand + 1, maxCost - currentCost); + currentCost += downAlgorithm->cost; + + if (currentCost < maxCost) + { + swapAlgorithm = downAlgorithm, downAlgorithm = bestAlgorithm, bestAlgorithm = swapAlgorithm; + bestAlgorithm->shiftAmount[bestAlgorithm->nOperations] = 0; + bestAlgorithm->operations[bestAlgorithm->nOperations] = maSubShiftMultiplicandFromValue; + maxCost = currentCost; + } + } + else + { + currentCost = addCost; + getMulAlgorithm(downAlgorithm, multiplicand - 1, maxCost - currentCost); + currentCost += downAlgorithm->cost; + + if (currentCost < maxCost) + { + swapAlgorithm = downAlgorithm, downAlgorithm = bestAlgorithm, bestAlgorithm = swapAlgorithm; + bestAlgorithm->shiftAmount[bestAlgorithm->nOperations] = 0; + bestAlgorithm->operations[bestAlgorithm->nOperations] = maAddValueToShiftMultiplicand; + maxCost = currentCost; + } + } + } + + mask = multiplicand - 1; + PR_FLOOR_LOG2(shiftBy, mask); + while (shiftBy >= 2) + { + PRUint32 d; + + d = (0x1 << shiftBy) + 1; + if (multiplicand % d == 0 && multiplicand > d) + { + currentCost = PR_MIN(shiftAddCosts[shiftBy], addCost + shiftCosts[shiftBy]); + getMulAlgorithm(downAlgorithm, multiplicand / d, maxCost - currentCost); + currentCost += downAlgorithm->cost; + + if (currentCost < maxCost) + { + swapAlgorithm = downAlgorithm, downAlgorithm = bestAlgorithm, bestAlgorithm = swapAlgorithm; + bestAlgorithm->shiftAmount[bestAlgorithm->nOperations] = shiftBy; + bestAlgorithm->operations[bestAlgorithm->nOperations] = maAddValueToShiftValue; + maxCost = currentCost; + } + break; + } + + d = (0x1 << shiftBy) - 1; + if (multiplicand % d == 0 && multiplicand > d) + { + currentCost = PR_MIN(shiftSubCosts[shiftBy], addCost + shiftCosts[shiftBy]); + getMulAlgorithm(downAlgorithm, multiplicand / d, maxCost - currentCost); + currentCost += downAlgorithm->cost; + + if (currentCost < maxCost) + { + swapAlgorithm = downAlgorithm, downAlgorithm = bestAlgorithm, bestAlgorithm = swapAlgorithm; + bestAlgorithm->shiftAmount[bestAlgorithm->nOperations] = shiftBy; + bestAlgorithm->operations[bestAlgorithm->nOperations] = maSubValueFromShiftValue; + maxCost = currentCost; + } + break; + } + shiftBy--; + } + + if ((multiplicand & 0x1) != 0x0) + { + mask = multiplicand - 1; + mask = mask & -mask; + if (mask != 0 && (mask & (mask - 1)) == 0) + { + PR_FLOOR_LOG2(shiftBy, mask); + currentCost = shiftAddCosts[shiftBy]; + getMulAlgorithm(downAlgorithm, (multiplicand - 1) >> shiftBy, maxCost - currentCost); + currentCost += downAlgorithm->cost; + + if (currentCost < maxCost) + { + swapAlgorithm = downAlgorithm, downAlgorithm = bestAlgorithm, bestAlgorithm = swapAlgorithm; + bestAlgorithm->shiftAmount[bestAlgorithm->nOperations] = shiftBy; + bestAlgorithm->operations[bestAlgorithm->nOperations] = maAddMultiplicandToShiftValue; + maxCost = currentCost; + } + } + + mask = multiplicand + 1; + mask = mask & -mask; + if (mask != 0 && (mask & (mask - 1)) == 0) + { + PR_FLOOR_LOG2(shiftBy, mask); + currentCost = shiftSubCosts[shiftBy]; + getMulAlgorithm(downAlgorithm, (multiplicand + 1) >> shiftBy, maxCost - currentCost); + currentCost += downAlgorithm->cost; + + if (currentCost < maxCost) + { + swapAlgorithm = downAlgorithm, downAlgorithm = bestAlgorithm, bestAlgorithm = swapAlgorithm; + bestAlgorithm->shiftAmount[bestAlgorithm->nOperations] = shiftBy; + bestAlgorithm->operations[bestAlgorithm->nOperations] = maSubMultiplicandFromShiftValue; + maxCost = currentCost; + } + } + } + + // No algorithm found. + if (maxCost == algorithm->cost) + return false; + + // Too long + if (bestAlgorithm->nOperations == 32) + return false; + + algorithm->nOperations = bestAlgorithm->nOperations + 1; + algorithm->cost = maxCost; + + copy(bestAlgorithm->operations, &bestAlgorithm->operations[algorithm->nOperations], algorithm->operations); + copy(bestAlgorithm->shiftAmount, &bestAlgorithm->shiftAmount[algorithm->nOperations], algorithm->shiftAmount); + + // we better find a way to avoid allocating memory each time. + delete downAlgorithm; + delete bestAlgorithm; + + return true; +} diff --git a/ef/Compiler/CodeGenerator/md/hppa/HPPAMul.h b/ef/Compiler/CodeGenerator/md/hppa/HPPAMul.h new file mode 100644 index 000000000000..b700a4e2b53d --- /dev/null +++ b/ef/Compiler/CodeGenerator/md/hppa/HPPAMul.h @@ -0,0 +1,47 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#ifndef _HPPA_MUL_H_ +#define _HPPA_MUL_H_ + +#include "Fundamentals.h" + +enum MultiplicationOperation +{ + maZero, // total = 0 + maMultiplicand, // total = multiplicand + maShiftValue, // total = value << shiftBy + maAddValueToShiftMultiplicand, // total = value + (multiplicand << shiftBy) + maSubShiftMultiplicandFromValue, // total = value - (multiplicand << shiftBy) + maAddValueToShiftValue, // total = (value << shiftBy) + value + maSubValueFromShiftValue, // total = (value << shiftBy) - value + maAddMultiplicandToShiftValue, // total = (value << shiftBy) + multiplicand + maSubMultiplicandFromShiftValue, // total = (value << shiftBy) - multiplicand +}; + +struct MulAlgorithm +{ + PRInt16 cost; + PRUint16 nOperations; + MultiplicationOperation operations[32]; + PRUint8 shiftAmount[32]; +}; + +extern bool getMulAlgorithm(MulAlgorithm* algorithm, PRUint32 multiplicand, PRInt16 maxCost); + +#endif /* _HPPA_MUL_H_ */ diff --git a/ef/Compiler/CodeGenerator/md/hppa/Makefile b/ef/Compiler/CodeGenerator/md/hppa/Makefile new file mode 100644 index 000000000000..7609c47e2429 --- /dev/null +++ b/ef/Compiler/CodeGenerator/md/hppa/Makefile @@ -0,0 +1,73 @@ +#!gmake +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +DEPTH = ../../../.. + +MODULE_NAME = hppa + +include $(DEPTH)/config/config.mk + +INCLUDES += \ + -I$(DEPTH)/Utilities/General \ + -I$(DEPTH)/Utilities/zlib \ + -I$(DEPTH)/Runtime/ClassReader \ + -I$(DEPTH)/Compiler/FrontEnd \ + -I$(DEPTH)/Runtime/NativeMethods \ + -I$(DEPTH)/Runtime/System \ + -I$(DEPTH)/Compiler/PrimitiveGraph \ + -I$(DEPTH)/Runtime/ClassInfo \ + -I$(DEPTH)/Runtime/FileReader \ + -I$(DEPTH)/Compiler/CodeGenerator \ + -I$(DEPTH)/Compiler/CodeGenerator/md \ + -I$(DEPTH)/Compiler/RegisterAllocator \ + $(NULL) + +CXXSRCS = \ + HPPAEmitter.cpp \ + HPPAInstruction.cpp \ + HPPAMul.cpp \ + hppa.nad.burg.cpp \ + $(NULL) + +include $(DEPTH)/config/rules.mk + +export:: hppa.nad.burg.cpp + +libs:: $(MODULE) + +# +# Rules to generate hppa.nad.burg.[cpp][h] +# + +hppa.nad.burg.cpp: hppa.nad.burg $(BURG) + $(BURG) -I -o $@ < $< + +hppa.nad.burg: hppa.nad $(DEPTH)/Compiler/PrimitiveGraph/PrimitiveOperations $(DEPTH)/Tools/Nad/nad.pl + $(PERL) $(DEPTH)/Tools/Nad/nad.pl $< $(DEPTH)/Compiler/PrimitiveGraph/PrimitiveOperations \ + $(DEPTH)/Compiler/PrimitiveGraph/PrimitiveOperations.h \ + $(DEPTH)/Compiler/PrimitiveGraph/PrimitiveOperations.cpp \ + $<.burg.h > $@ + +# +# Extra cleaning +# + +clobber:: + rm -f hppa.nad.burg.cpp hppa.nad.burg.h hppa.nad.burg + +realclean clobber_all:: + rm -f hppa.nad.burg.cpp hppa.nad.burg.h hppa.nad.burg diff --git a/ef/Compiler/CodeGenerator/md/hppa/hppa.nad b/ef/Compiler/CodeGenerator/md/hppa/hppa.nad new file mode 100644 index 000000000000..142248dbd8dd --- /dev/null +++ b/ef/Compiler/CodeGenerator/md/hppa/hppa.nad @@ -0,0 +1,452 @@ +%top +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#include "Burg.h" +% + +%terminals +% + +%startsymbols +Control +Result +Exception +Store +Vcond +Vint +Vfixed +Vlong +Vfloat +Vdouble +Vptr +Cint +Cfixed +Clong +Cfloat +Cdouble +Cptr +% + +%grammar +Vint: coReg_I $1 $ +Vlong: coReg_L $1 $ +Vfloat: coReg_F $1 $ +Vdouble: coReg_D $1 $ +Vptr: coReg_A $1 $ +Vcond: coReg_C $1 $ +Store: coReg_M $1 $ +Cint: coReg_I $1 $ +Cfixed: coReg_I $1 $ +Clong: coReg_L $1 $ +Cfloat: coReg_F $1 $ +Cdouble: coReg_D $1 $ +Cptr: coReg_A $1 $ + +Vfixed: Vint $1 $ +Vint: Vfixed $1 $ + +Vfixed: poConst_I $1 $emConst_IF +Vint: poConst_I $1 $emConst_I +Vlong: poConst_L $1 $emConst_L +Vfloat: poConst_F $1 $emConst_F +Vdouble: poConst_D $1 $emConst_D +Vptr: poConst_A $1 $emConst_A +Vcond: poConst_C $1 $emConst_C + +Store: poBreak(Store) $1 $emBreak + +Vint: poArg_I $1 $emArg_I +Vlong: poArg_L $1 $emArg_L +Vfloat: poArg_F $1 $emArg_F +Vdouble: poArg_D $1 $emArg_D +Vptr: poArg_A $1 $emArg_A +Store: poArg_M $1 $emArg_M + +Result: poResult_I(Vint) $1 $emResult_I +Result: poResult_L(Vlong) $1 $emResult_L +Result: poResult_F(Vfloat) $1 $emResult_F +Result: poResult_D(Vdouble) $1 $emResult_D +Result: poResult_A(Vptr) $1 $emResult_A +// (not used): poResult_C(Acond) $1 $emResult_C +Result: poResult_M(Store) $1 $emResult_M + +Control: poIfLt(Vcond) $1 $emIfLt +Control: poIfEq(Vcond) $1 $emIfEq +Control: poIfLe(Vcond) $1 $emIfLe +Control: poIfGt(Vcond) $1 $emIfGt +Control: poIfLgt(Vcond) $1 $emIfLgt +Control: poIfGe(Vcond) $1 $emIfGe +Control: poIfOrd(Vcond) $1 $emIfOrd +Control: poIfUnord(Vcond) $1 $emIfUnord +Control: poIfULt(Vcond) $1 $emIfULt +Control: poIfUEq(Vcond) $1 $emIfUEq +Control: poIfULe(Vcond) $1 $emIfULe +Control: poIfUGt(Vcond) $1 $emIfUGt +Control: poIfNe(Vcond) $1 $emIfNe +Control: poIfUGe(Vcond) $1 $emIfUGe + +Control: poSwitch(Vint) $1 $emSwitch + +Vint: poAnd_I(Vint, Vint) $1 $emAnd_I +Vlong: poAnd_L(Vlong, Vlong) $1 $emAnd_L +Vint: poAndI_I(Vint, Cint) $1 $emAndI_I +Vlong: poAndI_L(Vlong, Clong) $1 $emAndI_L +Vint: poOr_I(Vint, Vint) $1 $emOr_I +Vlong: poOr_L(Vlong, Vlong) $1 $emOr_L +Vint: poOrI_I(Vint, Cint) $1 $emOrI_I +Vlong: poOrI_L(Vlong, Clong) $1 $emOrI_L +Vint: poXor_I(Vint, Vint) $1 $emXor_I +Vlong: poXor_L(Vlong, Vlong) $1 $emXor_L +Vint: poXorI_I(Vint, Cint) $1 $emXorI_I +Vlong: poXorI_L(Vlong, Clong) $1 $emXorI_L + + +Vptr: poAdd_A(Vptr, poShlI_I(Vint, Cint)) $1 $emShAdd_IIndirect + +Vint: poAdd_I(Vint, Vint) $1 $emAdd_I +Vlong: poAdd_L(Vlong, Vlong) $1 $emAdd_L +Vptr: poAdd_A(Vptr, Vint) $1 $emAdd_A +Vptr: poAddU_A(Vptr, Vint) $1 $emAddU_A +Vint: poAddI_I(Vint, Cint) $1 $emAddI_I +Vlong: poAddI_L(Vlong, Clong) $1 $emAddI_L +Vptr: poAddI_A(Vptr, Cint) $1 $emAddI_A +Vptr: poAddR_A(Cptr, Vint) $1 $emAddR_A +Vptr: poAddRU_A(Cptr, Vint) $1 $emAddRU_A + +Vint: poSub_I(Vint, Vint) $1 $emSub_I +Vlong: poSub_L(Vlong, Vlong) $1 $emSub_L +Vptr: poSub_A(Vptr, Vint) $1 $emSub_A +Vptr: poSubU_A(Vptr, Vint) $1 $emSubU_A +Vint: poSubR_I(Cint, Vint) $1 $emSubR_I +Vlong: poSubR_L(Clong, Vlong) $1 $emSubR_L +Vptr: poSubR_A(Cptr, Vint) $1 $emSubR_A +Vptr: poSubUR_A(Cptr, Vint) $1 $emSubUR_A +Vint: poSubA_I(Vptr, Vptr) $1 $emSubA_I +Vint: poSubAI_I(Vptr, Cptr) $1 $emSubAI_I +Vint: poSubAR_I(Cptr, Vptr) $1 $emSubAR_I + +Vfixed: poMul_I(Vfixed, Vfixed) $1 $emMul_I +Vlong: poMul_L(Vlong, Vlong) $1 $emMul_L +Vfixed: poMulI_I(Vfixed, Cfixed) $1 $emMulI_I +Vlong: poMulI_L(Vlong, Clong) $1 $emMulI_L + +Vint: poDivI_I(Vint, Cint) $1 $emDivI_I +Vint: poModE_I(Vint, Vint) $1 $emModE_I + +Vint: poShl_I(Vint, Vint) $1 $emShl_I +Vlong: poShl_L(Vlong, Vint) $1 $emShl_L +Vint: poShlI_I(Vint, Cint) $1 $emShlI_I +Vlong: poShlI_L(Vlong, Cint) $1 $emShlI_L +Vint: poShlR_I(Cint, Vint) $1 $emShlR_I +Vlong: poShlR_L(Clong, Vint) $1 $emShlR_L +Vint: poShr_I(Vint, Vint) $1 $emShr_I +Vlong: poShr_L(Vlong, Vint) $1 $emShr_L +Vint: poShrI_I(Vint, Cint) $1 $emShrI_I +Vlong: poShrI_L(Vlong, Cint) $1 $emShrI_L +Vint: poShrR_I(Cint, Vint) $1 $emShrR_I +Vlong: poShrR_L(Clong, Vint) $1 $emShrR_L +Vint: poShrU_I(Vint, Vint) $1 $emShrU_I +Vlong: poShrU_L(Vlong, Vint) $1 $emShrU_L +Vint: poShrUI_I(Vint, Cint) $1 $emShrUI_I +Vlong: poShrUI_L(Vlong, Cint) $1 $emShrUI_L +Vint: poShrUR_I(Cint, Vint) $1 $emShrUR_I +Vlong: poShrUR_L(Clong, Vint) $1 $emShrUR_L + +Vint: poExt_I(Vint, Cint) $1 $emExt_I +Vlong: poExt_L(Vlong, Cint) $1 $emExt_L + +Vfloat: poFAdd_F(Vfloat, Vfloat) $1 $emFAdd_F +Vdouble: poFAdd_D(Vdouble, Vdouble) $1 $emFAdd_D +Vfloat: poFAddI_F(Vfloat, Cfloat) $1 $emFAddI_F +Vdouble: poFAddI_D(Vdouble, Cdouble) $1 $emFAddI_D + +Vfloat: poFSub_F(Vfloat, Vfloat) $1 $emFSub_F +Vdouble: poFSub_D(Vdouble, Vdouble) $1 $emFSub_D +Vfloat: poFSubR_F(Cfloat, Vfloat) $1 $emFSubR_F +Vdouble: poFSubR_D(Cdouble, Vdouble) $1 $emFSubR_D + +Vfloat: poFMul_F(Vfloat, Vfloat) $1 $emFMul_F +Vdouble: poFMul_D(Vdouble, Vdouble) $1 $emFMul_D +Vfloat: poFMulI_F(Vfloat, Cfloat) $1 $emFMulI_F +Vdouble: poFMulI_D(Vdouble, Cdouble) $1 $emFMulI_D + +Vfloat: poFDiv_F(Vfloat, Vfloat) $1 $emFDiv_F +Vdouble: poFDiv_D(Vdouble, Vdouble) $1 $emFDiv_D +Vfloat: poFDivI_F(Vfloat, Cfloat) $1 $emFDivI_F +Vdouble: poFDivI_D(Vdouble, Cdouble) $1 $emFDivI_D +Vfloat: poFDivR_F(Cfloat, Vfloat) $1 $emFDivR_F +Vdouble: poFDivR_D(Cdouble, Vdouble) $1 $emFDivR_D + +Vfloat: poFRem_F(Vfloat, Vfloat) $1 $emFRem_F +Vdouble: poFRem_D(Vdouble, Vdouble) $1 $emFRem_D +Vfloat: poFRemI_F(Vfloat, Cfloat) $1 $emFRemI_F +Vdouble: poFRemI_D(Vdouble, Cdouble) $1 $emFRemI_D +Vfloat: poFRemR_F(Cfloat, Vfloat) $1 $emFRemR_F +Vdouble: poFRemR_D(Cdouble, Vdouble) $1 $emFRemR_D + +Vint: poConvI_L(Vlong) $1 $emConvI_L +Vlong: poConvL_I(Vint) $1 $emConvL_I + +Vint: poFConvI_F(Vfloat) $1 $emFConvI_F +Vint: poFConvI_D(Vdouble) $1 $emFConvI_D +Vlong: poFConvL_F(Vfloat) $1 $emFConvL_F +Vlong: poFConvL_D(Vdouble) $1 $emFConvL_D +Vfloat: poFConvF_I(Vint) $1 $emFConvF_I +Vfloat: poFConvF_L(Vlong) $1 $emFConvF_L +Vfloat: poFConvF_D(Vdouble) $1 $emFConvF_D +Vdouble: poFConvD_I(Vint) $1 $emFConvD_I +Vdouble: poFConvD_L(Vlong) $1 $emFConvD_L +Vdouble: poFConvD_F(Vfloat) $1 $emFConvD_F + +Vcond: poCmp_I(Vint, Vint) $1 $emCmp_I +Vcond: poCmp_L(Vlong, Vlong) $1 $emCmp_L +Vcond: poCmpI_I(Vint, Cint) $1 $emCmpI_I +Vcond: poCmpI_L(Vlong, Clong) $1 $emCmpI_L +Vcond: poCmpU_I(Vint, Vint) $1 $emCmpU_I +Vcond: poCmpU_L(Vlong, Vlong) $1 $emCmpU_L +Vcond: poCmpU_A(Vptr, Vptr) $1 $emCmpU_A +Vcond: poCmpUI_I(Vint, Cint) $1 $emCmpUI_I +Vcond: poCmpUI_L(Vlong, Clong) $1 $emCmpUI_L +Vcond: poCmpUI_A(Vptr, Cptr) $1 $emCmpUI_A + +Vcond: poFCmp_F(Vfloat, Vfloat) $1 $emFCmp_F +Vcond: poFCmp_D(Vdouble, Vdouble) $1 $emFCmp_D +Vcond: poFCmpI_F(Vfloat, Cfloat) $1 $emFCmpI_F +Vcond: poFCmpI_D(Vdouble, Cdouble) $1 $emFCmpI_D + +Vint: poLt_I(Vcond) $1 $emLt_I +Vint: poEq_I(Vcond) $1 $emEq_I +Vint: poLe_I(Vcond) $1 $emLe_I +Vint: poGt_I(Vcond) $1 $emGt_I +Vint: poLgt_I(Vcond) $1 $emLgt_I +Vint: poGe_I(Vcond) $1 $emGe_I +Vint: poOrd_I(Vcond) $1 $emOrd_I +Vint: poUnord_I(Vcond) $1 $emUnord_I +Vint: poULt_I(Vcond) $1 $emULt_I +Vint: poUEq_I(Vcond) $1 $emUEq_I +Vint: poULe_I(Vcond) $1 $emULe_I +Vint: poUGt_I(Vcond) $1 $emUGt_I +Vint: poNe_I(Vcond) $1 $emNe_I +Vint: poUGe_I(Vcond) $1 $emUGe_I + +Vint: poCatL_I(Vcond) $1 $emCatL_I +Vint: poCatG_I(Vcond) $1 $emCatG_I +Vint: poCatCL_I(Vcond) $1 $emCatCL_I +Vint: poCatCG_I(Vcond) $1 $emCatCG_I + +Exception: poChkNull(Vptr) $1 $emChkNull +Exception: poLimit(Vint, Vint) $1 $emLimit +Exception: poLimitI(Vint, Cint) $1 $emLimitI +Exception: poLimitR(Cint, Vint) $1 $emLimitR + +Vint: poLd_I(Vptr) $1 $emLd_I +Vlong: poLd_L(Vptr) $1 $emLd_L +Vfloat: poLd_F(Vptr) $1 $emLd_F +Vdouble: poLd_D(Vptr) $1 $emLd_D +Vptr: poLd_A(Vptr) $1 $emLd_A +Vint: poLdE_I(Cptr) $1 $emLdE_I +Vlong: poLdE_L(Cptr) $1 $emLdE_L +Vfloat: poLdE_F(Cptr) $1 $emLdE_F +Vdouble: poLdE_D(Cptr) $1 $emLdE_D +Vptr: poLdE_A(Cptr) $1 $emLdE_A +Vint: poLdG_I(Cptr) $1 $emLdG_I +Vlong: poLdG_L(Cptr) $1 $emLdG_L +Vfloat: poLdG_F(Cptr) $1 $emLdG_F +Vdouble: poLdG_D(Cptr) $1 $emLdG_D +Vptr: poLdG_A(Cptr) $1 $emLdG_A +Vint: poLdS_B(Vptr) $1 $emLdS_B +Vint: poLdS_H(Vptr) $1 $emLdS_H +Vint: poLdSE_B(Cptr) $1 $emLdSE_B +Vint: poLdSE_H(Cptr) $1 $emLdSE_H +Vint: poLdSG_B(Cptr) $1 $emLdSG_B +Vint: poLdSG_H(Cptr) $1 $emLdSG_H +Vint: poLdU_B(Vptr) $1 $emLdU_B +Vint: poLdU_H(Vptr) $1 $emLdU_H +Vint: poLdUE_B(Cptr) $1 $emLdUE_B +Vint: poLdUE_H(Cptr) $1 $emLdUE_H +Vint: poLdUG_B(Cptr) $1 $emLdUG_B +Vint: poLdUG_H(Cptr) $1 $emLdUG_H +Vint: poLdV_I(Vptr) $1 $emLdV_I +Vlong: poLdV_L(Vptr) $1 $emLdV_L +Vfloat: poLdV_F(Vptr) $1 $emLdV_F +Vdouble: poLdV_D(Vptr) $1 $emLdV_D +Vptr: poLdV_A(Vptr) $1 $emLdV_A +Vint: poLdVE_I(Cptr) $1 $emLdVE_I +Vlong: poLdVE_L(Cptr) $1 $emLdVE_L +Vfloat: poLdVE_F(Cptr) $1 $emLdVE_F +Vdouble: poLdVE_D(Cptr) $1 $emLdVE_D +Vptr: poLdVE_A(Cptr) $1 $emLdVE_A +Vint: poLdVG_I(Cptr) $1 $emLdVG_I +Vlong: poLdVG_L(Cptr) $1 $emLdVG_L +Vfloat: poLdVG_F(Cptr) $1 $emLdVG_F +Vdouble: poLdVG_D(Cptr) $1 $emLdVG_D +Vptr: poLdVG_A(Cptr) $1 $emLdVG_A +Vint: poLdVS_B(Vptr) $1 $emLdVS_B +Vint: poLdVS_H(Vptr) $1 $emLdVS_H +Vint: poLdVSE_B(Cptr) $1 $emLdVSE_B +Vint: poLdVSE_H(Cptr) $1 $emLdVSE_H +Vint: poLdVSG_B(Cptr) $1 $emLdVSG_B +Vint: poLdVSG_H(Cptr) $1 $emLdVSG_H +Vint: poLdVU_B(Vptr) $1 $emLdVU_B +Vint: poLdVU_H(Vptr) $1 $emLdVU_H +Vint: poLdVUE_B(Cptr) $1 $emLdVUE_B +Vint: poLdVUE_H(Cptr) $1 $emLdVUE_H +Vint: poLdVUG_B(Cptr) $1 $emLdVUG_B +Vint: poLdVUG_H(Cptr) $1 $emLdVUG_H +Vint: poLdC_I(Vptr) $1 $emLdC_I +Vint: poLdC_L(Vptr) $1 $emLdC_L +Vint: poLdC_F(Vptr) $1 $emLdC_F +Vint: poLdC_D(Vptr) $1 $emLdC_D +Vint: poLdC_A(Vptr) $1 $emLdC_A +Vint: poLdCE_I(Vptr) $1 $emLdCE_I +Vint: poLdCE_L(Vptr) $1 $emLdCE_L +Vint: poLdCE_F(Vptr) $1 $emLdCE_F +Vint: poLdCE_D(Vptr) $1 $emLdCE_D +Vint: poLdCE_A(Vptr) $1 $emLdCE_A + +Vint: poLdC_I(poAddI_A(Vptr, Cint)) $0 $emLdC_IRegisterIndirect +Vint: poLd_I(poAddI_A(Vptr, Cint)) $0 $emLd_IRegisterIndirect + + +// poLdCG_I = 257, // Load constant global *Cptr -> Vint (not used) +// poLdCG_L = 258, // Load constant global *Cptr -> Vlong (not used) +// poLdCG_F = 259, // Load constant global *Cptr -> Vfloat (not used) +// poLdCG_D = 260, // Load constant global *Cptr -> Vdouble (not used) +// poLdCG_A = 261, // Load constant global *Cptr -> Vptr (not used) +Vint: poLdCS_B(Vptr) $1 $emLdCS_B +Vint: poLdCS_H(Vptr) $1 $emLdCS_H +Vint: poLdCSE_B(Cptr) $1 $emLdCSE_B +Vint: poLdCSE_H(Cptr) $1 $emLdCSE_H +//Vint (not used): poLdCSG_B(Cptr) $1 $emLdCSG_B +//Vint (not used): poLdCSG_H(Cptr) $1 $emLdCSG_H +Vint: poLdCU_B(Vptr) $1 $emLdCU_B +Vint: poLdCU_H(Vptr) $1 $emLdCU_H +Vint: poLdCUE_B(Cptr) $1 $emLdCUE_B +Vint: poLdCUE_H(Cptr) $1 $emLdCUE_H +//Vint (not used): poLdCUG_B(Cptr) $1 $emLdCUG_B +//Vint (not used): poLdCUG_H(Cptr) $1 $emLdCUG_H + +Store: poSt_B(Vptr, Vint) $1 $emSt_B +Store: poSt_H(Vptr, Vint) $1 $emSt_H +Store: poSt_I(Vptr, Vint) $1 $emSt_I +Store: poSt_L(Vptr, Vlong) $1 $emSt_L +Store: poSt_F(Vptr, Vfloat) $1 $emSt_F +Store: poSt_D(Vptr, Vdouble) $1 $emSt_D +Store: poSt_A(Vptr, Vptr) $1 $emSt_A +Store: poStI_B(Vptr, Cint) $1 $emStI_B +Store: poStI_H(Vptr, Cint) $1 $emStI_H +Store: poStI_I(Vptr, Cint) $1 $emStI_I +Store: poStI_L(Vptr, Clong) $1 $emStI_L +Store: poStI_F(Vptr, Cfloat) $1 $emStI_F +Store: poStI_D(Vptr, Cdouble) $1 $emStI_D +Store: poStI_A(Vptr, Cptr) $1 $emStI_A +Store: poStE_B(Cptr, Vint) $1 $emStE_B +Store: poStE_H(Cptr, Vint) $1 $emStE_H +Store: poStE_I(Cptr, Vint) $1 $emStE_I +Store: poStE_L(Cptr, Vlong) $1 $emStE_L +Store: poStE_F(Cptr, Vfloat) $1 $emStE_F +Store: poStE_D(Cptr, Vdouble) $1 $emStE_D +Store: poStE_A(Cptr, Vptr) $1 $emStE_A +Store: poStEI_B(Cptr, Cint) $1 $emStEI_B +Store: poStEI_H(Cptr, Cint) $1 $emStEI_H +Store: poStEI_I(Cptr, Cint) $1 $emStEI_I +Store: poStEI_L(Cptr, Clong) $1 $emStEI_L +Store: poStEI_F(Cptr, Cfloat) $1 $emStEI_F +Store: poStEI_D(Cptr, Cdouble) $1 $emStEI_D +Store: poStEI_A(Cptr, Cptr) $1 $emStEI_A +Store: poStG_B(Cptr, Vint) $1 $emStG_B +Store: poStG_H(Cptr, Vint) $1 $emStG_H +Store: poStG_I(Cptr, Vint) $1 $emStG_I +Store: poStG_L(Cptr, Vlong) $1 $emStG_L +Store: poStG_F(Cptr, Vfloat) $1 $emStG_F +Store: poStG_D(Cptr, Vdouble) $1 $emStG_D +Store: poStG_A(Cptr, Vptr) $1 $emStG_A +Store: poStGI_B(Cptr, Cint) $1 $emStGI_B +Store: poStGI_H(Cptr, Cint) $1 $emStGI_H +Store: poStGI_I(Cptr, Cint) $1 $emStGI_I +Store: poStGI_L(Cptr, Clong) $1 $emStGI_L +Store: poStGI_F(Cptr, Cfloat) $1 $emStGI_F +Store: poStGI_D(Cptr, Cdouble) $1 $emStGI_D +Store: poStGI_A(Cptr, Cptr) $1 $emStGI_A +Store: poStV_B(Vptr, Vint) $1 $emStV_B +Store: poStV_H(Vptr, Vint) $1 $emStV_H +Store: poStV_I(Vptr, Vint) $1 $emStV_I +Store: poStV_L(Vptr, Vlong) $1 $emStV_L +Store: poStV_F(Vptr, Vfloat) $1 $emStV_F +Store: poStV_D(Vptr, Vdouble) $1 $emStV_D +Store: poStV_A(Vptr, Vptr) $1 $emStV_A +Store: poStVI_B(Vptr, Cint) $1 $emStVI_B +Store: poStVI_H(Vptr, Cint) $1 $emStVI_H +Store: poStVI_I(Vptr, Cint) $1 $emStVI_I +Store: poStVI_L(Vptr, Clong) $1 $emStVI_L +Store: poStVI_F(Vptr, Cfloat) $1 $emStVI_F +Store: poStVI_D(Vptr, Cdouble) $1 $emStVI_D +Store: poStVI_A(Vptr, Cptr) $1 $emStVI_A +Store: poStVE_B(Cptr, Vint) $1 $emStVE_B +Store: poStVE_H(Cptr, Vint) $1 $emStVE_H +Store: poStVE_I(Cptr, Vint) $1 $emStVE_I +Store: poStVE_L(Cptr, Vlong) $1 $emStVE_L +Store: poStVE_F(Cptr, Vfloat) $1 $emStVE_F +Store: poStVE_D(Cptr, Vdouble) $1 $emStVE_D +Store: poStVE_A(Cptr, Vptr) $1 $emStVE_A +Store: poStVEI_B(Cptr, Cint) $1 $emStVEI_B +Store: poStVEI_H(Cptr, Cint) $1 $emStVEI_H +Store: poStVEI_I(Cptr, Cint) $1 $emStVEI_I +Store: poStVEI_L(Cptr, Clong) $1 $emStVEI_L +Store: poStVEI_F(Cptr, Cfloat) $1 $emStVEI_F +Store: poStVEI_D(Cptr, Cdouble) $1 $emStVEI_D +Store: poStVEI_A(Cptr, Cptr) $1 $emStVEI_A +Store: poStVG_B(Cptr, Vint) $1 $emStVG_B +Store: poStVG_H(Cptr, Vint) $1 $emStVG_H +Store: poStVG_I(Cptr, Vint) $1 $emStVG_I +Store: poStVG_L(Cptr, Vlong) $1 $emStVG_L +Store: poStVG_F(Cptr, Vfloat) $1 $emStVG_F +Store: poStVG_D(Cptr, Vdouble) $1 $emStVG_D +Store: poStVG_A(Cptr, Vptr) $1 $emStVG_A +Store: poStVGI_B(Cptr, Cint) $1 $emStVGI_B +Store: poStVGI_H(Cptr, Cint) $1 $emStVGI_H +Store: poStVGI_I(Cptr, Cint) $1 $emStVGI_I +Store: poStVGI_L(Cptr, Clong) $1 $emStVGI_L +Store: poStVGI_F(Cptr, Cfloat) $1 $emStVGI_F +Store: poStVGI_D(Cptr, Cdouble) $1 $emStVGI_D +Store: poStVGI_A(Cptr, Cptr) $1 $emStVGI_A + +Store: poSt_I(poAddI_A(Vptr, Cint), Vint) $0 $emSt_IRegisterIndirect +Store: poStI_I(poAddI_A(Vptr, Cint), Cint) $0 $emStI_IRegisterIndirect + +// Store, Vint: poMEnter_A(Vptr) $1 $emMEnter_A +// Store, Vint: poMEnterG_A(Cptr) $1 $emMEnterG_A +// Store, Vint: poMExit_A(Vptr) $1 $emMExit_A +// Store, Vint: poMExitG_A(Cptr) $1 $emMExitG_A +// Vptr: poLookupV_A(Vptr, Cint) $1 $emLookupV_A +// Vptr: poLookupI_A(Vptr, Cint) $1 $emLookupI_A +// ...: poSysCall(M) $1 $emSysCall +// Store, ...: poSysCallV(M) $1 $emSysCallV +// ..., E: poSysCallE(M) $1 $emSysCallE +// Store, ..., E: poSysCallEV(M) $1 $emSysCallEV +//Store, ..., E: poCall(Va) $1 $emCall + +VInt: poCallI $1 $emCallI_I +Vlong: poCallI $1 $emCallI_L +Vfloat: poCallI $1 $emCallI_F +Vdouble: poCallI $1 $emCallI_D +Vptr: poCallI $1 $emCallI_P +// Store, ..., E: poCallF(F) $1 $emCallF + +% + diff --git a/ef/Compiler/CodeGenerator/md/ppc/AssembledInstructions.h b/ef/Compiler/CodeGenerator/md/ppc/AssembledInstructions.h new file mode 100644 index 000000000000..8b0ce42eca29 --- /dev/null +++ b/ef/Compiler/CodeGenerator/md/ppc/AssembledInstructions.h @@ -0,0 +1,72 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +// AssembledInstructions.h +#ifndef _H_ASSEMBLEDINSTRUCTIONS +#define _H_ASSEMBLEDINSTRUCTIONS + +const Uint32 kBlr = 0x4e800020; // blr +const Uint32 kBlrl = 0x4e800021; // blrl +const Uint32 kMtlrR0 = 0x7c0803a6; // mtlr r0 +const Uint32 kMtctrR0 = 0x7c0903a6; // mtctr r0 +const Uint32 kBctr = 0x4e800420; // bctr +const Uint32 kOriR0 = 0x60000000; // ori r0, r0, 0 +const Uint32 kAddiR0 = 0x38000000; // addi r0, r0, 0 +const Uint32 addisR0 = 0x3C000000; // addis r0, r0, 0 + +const Uint32 kBla = 0x48000003; // bla +const Uint32 kBl = 0x48000001; // bl +const Uint32 kB = 0x48000000; // b +const Uint32 kNop = 0x60000000; // nop +const Uint32 kLwzR0_R13 = 0x800D0000; // lwz r0, ?(r13) + +inline Uint32 +shiftLeftMask(Uint32 inValue, Uint32 inShift, Uint32 inMask = 0xFFFFFFFF) +{ + return ((inValue << inShift) & inMask); +} + +inline Uint32 +makeDForm(Uint8 inOpcd, Uint8 inD, Uint8 inA, Int16 inIMM) +{ + return (shiftLeftMask(inOpcd, 26) | + shiftLeftMask(inD, 21) | + shiftLeftMask(inA, 16) | + shiftLeftMask(inIMM, 0, 0xFFFF)); +} + +const uint32 mfcrR0 = 0x7c000026; // mfcr r0 +const uint32 stwR04R1 = 0x90010004; // stw r0, 4(r1) +const uint32 mflrR0 = 0x7c0802a6; // mflr r0 +const uint32 stwR08R1 = 0x90010008; // stw r0, 8(r1) +const uint32 stfd_FR_offR1 = 0xd8010000; // stfd fr?, ?(r1) +const uint32 stw_R_offR1 = 0x90010000; // stw r?, ?(r1) +const uint32 stwuR1_offR1 = 0x94210000; // stwu r1, ?(r1) +const uint32 lisR12_imm = 0x3d800000; // lis r12, ? +const uint32 oriR12R12_imm = 0x618c0000; // ori r12, r12, ? +const uint32 stwuxR1R1R12 = 0x7c21616e; // stwux r1, r1, r12 + +const uint32 lwzR08R1 = 0x80010008; // lwz r0, 8(r1) +const uint32 lwzR04R1 = 0x80010004; // lwz r0, 4(r1) +const uint32 mtcrR0 = 0x7c0ff120; // mtcr r0 +const uint32 lfd_FR_offR1 = 0xc8010000; // lfd fr?, ?(r1) +const uint32 lwz_R_offR1 = 0x80010000; // lwz r?, ?(r1) +const uint32 addiR1R1_imm = 0x38210000; // addi r1, r1, ? +const uint32 addR1R1R12 = 0x7c216214; // add r1, r1, r12 + +#endif //_H_ASSEMBLEDINSTRUCTIONS + diff --git a/ef/Compiler/CodeGenerator/md/ppc/Makefile b/ef/Compiler/CodeGenerator/md/ppc/Makefile new file mode 100644 index 000000000000..eaf86c2fe32f --- /dev/null +++ b/ef/Compiler/CodeGenerator/md/ppc/Makefile @@ -0,0 +1,92 @@ +#!gmake +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +####################################################################### +# (1) Directory specific info # +####################################################################### + +DEPTH = ../../../.. + +CPPSRCS = PPC601AppleMacOSEmitter.cpp \ + PPCInstructions.cpp \ + ppc601-macos.nad.burg.cpp \ + $(NULL) + +LOCAL_MD_EXPORTS_ppc = AssembledInstructions.h \ + PPC601AppleMacOSEmitter.h \ + PPC601AppleMacOS_Support.h \ + PPC601Cpu.h \ + PPCCalls.h \ + PPCInstructionTemplates.h \ + PPCInstructions.h \ + $(NULL) + + + + +MODULE_NAME = EF + +####################################################################### +# (2) Include "component" configuration information. # +####################################################################### + +include $(DEPTH)/config/config.mk + +####################################################################### +# (3) Include "local" platform-dependent assignments (OPTIONAL). # +####################################################################### + + +####################################################################### +# (4) Execute "component" rules. (OPTIONAL) # +####################################################################### + +include $(DEPTH)/config/rules.mk + +####################################################################### +# (7) Execute "local" rules. (OPTIONAL). # +####################################################################### + +# +# Rules to obtain burg-generated files +# +export:: ppc601-macos.nad.burg.cpp + + +# +# Rules to generate ppc601-macos.nad.burg.[cpp][h] +# + +ppc601-macos.nad.burg.cpp: ppc601-macos.nad.burg $(BURG) + $(BURG) -I -o $@ < $< + +ppc601-macos.nad.burg: ppc601-macos.nad $(DEPTH)/Compiler/PrimitiveGraph/PrimitiveOperations $(DEPTH)/Tools/Nad/nad.pl + $(PERL) $(DEPTH)/Tools/Nad/nad.pl $< $(DEPTH)/Compiler/PrimitiveGraph/PrimitiveOperations \ + $(DEPTH)/Compiler/PrimitiveGraph/PrimitiveOperations.h \ + $(DEPTH)/Compiler/PrimitiveGraph/PrimitiveOperations.cpp \ + $<.burg.h > $@ + +# +# Extra cleaning +# + +clobber:: + rm -f ppc601-macos.nad.burg.cpp ppc601-macos.nad.burg.h ppc601-macos.nad.burg + +realclean clobber_all:: + rm -f ppc601-macos.nad.burg.cpp ppc601-macos.nad.burg.h ppc601-macos.nad.burg + diff --git a/ef/Compiler/CodeGenerator/md/ppc/PPC601AppleMacOSEmitter.cpp b/ef/Compiler/CodeGenerator/md/ppc/PPC601AppleMacOSEmitter.cpp new file mode 100644 index 000000000000..d95ee17d24bd --- /dev/null +++ b/ef/Compiler/CodeGenerator/md/ppc/PPC601AppleMacOSEmitter.cpp @@ -0,0 +1,1618 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +// PPC601AppleMacOSEmitter.cp +// +// Scott M. Silver +// Peter Desantis +// Laurent Morichetti +// +// Subclass of InstructionEmitter which handles emitting for the ppc601 + + +#include "PPC601AppleMacOSEmitter.h" +#include "PPC601AppleMacOS_Support.h" +#include "Instruction.h" +#include "ppc601-macos.nad.burg.h" +#include "ControlNodes.h" +#include "SysCalls.h" +#include "AssembledInstructions.h" +#include "PPCInstructions.h" +#include "PPCCalls.h" + +// Use the PowerPC disassembler that comes with the mac if possible +#if defined(DEBUG) && defined(__MWERKS__) +#include +#if defined(GENERATINGPOWERPC) && GENERATINGPOWERPC +#define USING_MAC_PPC_DISASSEMBLER +#ifdef __TYPES__ // save old types + #define __OLD_TYPES__ +#endif +#define __TYPES__ +#include "Disassembler.h" +#define MAC_PPC_DISASSEMBLER_OPTIONS (Disassemble_PowerPC32|Disassemble_RsvBitsErr|Disassemble_FieldErr|Disassemble_Extended|Disassemble_BasicComm|Disassemble_CRBits|Disassemble_CRFltBits|Disassemble_BranchBO|Disassemble_TrapTO) +#ifndef __OLD_TYPES__ + #undef __TYPES__ +#endif +#endif +#endif + + +const Uint8 kR3Color = 0; // for return values <= 32 bits +const Uint8 kR4Color = 1; // for return values > 32 bits + +const Uint8 kFR1Color = 0; // for return values <= 64 bits + +const Uint8 kJitGlobalsColor = 29; // used for global values +const Uint8 kJitGlobalsRegister = 13; +const Uint8 kStackRegister = 13; + + + +#ifdef __MWERKS__ +#pragma mark - +#pragma mark ¥ÊEmitter ¥ +#endif + + +#define BINARY_PRIMITIVE_IX(inRuleKind, inOp) \ + case inRuleKind: \ + genArith_IX(inPrimitive, inOp); \ + break; + +#define BINARY_PRIMITIVE_ID(inRuleKind, inOp, inOpX) \ + case inRuleKind: \ + genArith_ID(inPrimitive, inOp, inOpX); \ + break; + +#define UNDEFINED_RULE(inRuleKind) \ + case inRuleKind: \ + assert(false); \ + break; + +#define BINARY_PRIMITIVE_SET(inRuleRoot, inOpX, inOpD) \ + BINARY_PRIMITIVE_IX(inRuleRoot##_I, inOpX); + +void PPCEmitter:: +emitPrimitive(Primitive& inPrimitive, NamedRule inRule) +{ + switch (inRule) + { + case emConst_I: + case emConst_A: + emit_Const_I(inPrimitive); + break; + case emConst_F: + emit_Const_F(inPrimitive); + break; + case emResult_I: case emResult_A: + emit_Result_I(inPrimitive); + break; + case emResult_F: + emit_Result_F(inPrimitive); + break; + case emIfLt: case emIfULt: + genBranch(inPrimitive, condLt); + break; + case emIfEq: case emIfUEq: + genBranch(inPrimitive, condEq); + break; + case emIfLe: case emIfULe: + genBranch(inPrimitive, condLe); + break; + case emIfGt: case emIfUGt: + genBranch(inPrimitive, condGt); + break; + case emIfLgt: case emIfNe: + genBranch(inPrimitive, condLgt); + break; + case emIfGe: case emIfUGe: + genBranch(inPrimitive, condGe); + break; + BINARY_PRIMITIVE_SET(emAnd, xfAnd, dfAndi); + BINARY_PRIMITIVE_SET(emOr, xfOr, dfOri); + BINARY_PRIMITIVE_SET(emXor, xfXor, dfXori); + BINARY_PRIMITIVE_SET(emAdd, xfAdd, dfAddi); + case emAdd_A: case emAddU_A: + genArith_IX(inPrimitive, xfAdd); + break; +// case emAddI_A: +// genArith_ID(inPrimitive, dfAddi, xfAdd); +// break; +// case emAddR_A: +// genArith_RD(inPrimitive, dfAddi, xfAdd, false); +// break; +// case emAddRU_A: +// genArith_RD(inPrimitive, dfAddi, xfAdd, true); +// break; + case emSub_I: + genArithReversed_IX(inPrimitive, xfSubf); + break; +/// case emSubR_I: +// emit_SubR(inPrimitive, false); +// break; +// case emSubAI_I: +// emit_SubI(inPrimitive); +// break; +/// case emSubAR_I: +// emit_SubR(inPrimitive, false); +// break; +// case emSub_A: case emSubU_A: +// genArithReversed_IX(inPrimitive, xfSubf); +// break; +// case emSubR_A: +// emit_SubR(inPrimitive, false); +// break; +// case emSubUR_A: +// emit_SubR(inPrimitive, true); +// break; + BINARY_PRIMITIVE_SET(emMul, xfMullw, dfMulli); + case emDiv_I: + emit_Div_I(inPrimitive); + break; + case emDivE_I: + emit_DivE_I(inPrimitive); + break; +// case emDivI_I: +// emit_DivI_I(inPrimitive); +// break; +// case emDivR_I: +// emit_DivR_I(inPrimitive); +// break; +// case emDivRE_I: +// emit_DivRE_I(inPrimitive); +// break; + case emDivU_I: + emit_DivU_I(inPrimitive); + break; + case emDivUE_I: + emit_DivUE_I(inPrimitive); + break; +// case emDivUI_I: +// emit_DivUI_I(inPrimitive); +// break; +// case emDivUR_I: +// emit_DivUR_I(inPrimitive); +// break; +// case emDivURE_I: +// emit_DivURE_I(inPrimitive); +// break; + case emModE_I: + emit_ModE_I(inPrimitive); + break; + case emShl_I: + { + Instruction& shiftLeft = *new(mPool) XFormXY(&inPrimitive, mPool, 2, 1, xfSlw, pfNil); + shiftLeft.standardUseDefine(*this); + } + break; +// case emShlI_I: +// emit_ShlI_I(inPrimitive); +// break; +// + case emChkNull: + { + TrapD& newInsn = *new(mPool) TrapD(&inPrimitive, mPool, condEq, false, 0); + + newInsn.standardUseDefine(*this); + } + break; +// case emLimitR: +// emit_LimitR(inPrimitive); +// break; + case emLimit: + emit_Limit(inPrimitive, 0); + break; + case emLd_IRegisterIndirect: case emLd_ARegisterIndirect: + emit_Ld_IRegisterIndirect(inPrimitive); + break; + case emLd_I: case emLd_A: + { + LdD_& newInsn = *new(mPool) LdD_(&inPrimitive, mPool, dfLwz, 0); + + newInsn.standardUseDefine(*this); + } + break; + case emSt_I: + { + StD& newInsn = *new(mPool) StD(&inPrimitive, mPool, dfStw, 0); + newInsn.standardUseDefine(*this); + } + break; +// case emStI_I: +// emit_StI_I(inPrimitive); +// break; +// case emStI_IRegisterIndirect: +// emit_StI_IRegisterIndirect(inPrimitive); +// break; + case emSt_IRegisterIndirect: + emit_St_IRegisterIndirect(inPrimitive); + break; + case emDynamicCall: + { + CallD_& newInsn = *new CallD_(&inPrimitive, mPool, CallD_::numberOfArguments(inPrimitive), CallD_::hasReturnValue(inPrimitive), *this); + } + break; + case emStaticCall: + { + Call_& newInsn = *new Call_(&inPrimitive, mPool, Call_::numberOfArguments(inPrimitive), Call_::hasReturnValue(inPrimitive), *this); + } + break; + case emSysCallEV: + { + CallS_V& newInsn = *new CallS_V(&inPrimitive, mPool, CallS_V::numberOfArguments(inPrimitive), CallS_V::hasReturnValue(inPrimitive), *this, PrimSysCall::cast(inPrimitive).sysCall.function); + } + break; + case emSysCallEC: + { + CallS_C& newInsn = *new CallS_C(&inPrimitive, mPool, CallS_C::numberOfArguments(inPrimitive), CallS_C::hasReturnValue(inPrimitive), *this, PrimSysCall::cast(inPrimitive).sysCall.function); + } + break; + case emSysCallE: + { + CallS_& newInsn = *new CallS_(&inPrimitive, mPool, CallS_::numberOfArguments(inPrimitive), CallS_::hasReturnValue(inPrimitive), *this, PrimSysCall::cast(inPrimitive).sysCall.function); + } + break; + case emCmp_I: + emit_Cmp_I(inPrimitive); + break; +// case emCmpI_I: +// emit_CmpI_I(inPrimitive); +// break; + case emFAdd_F: + { + Instruction& insn = sAFormInfos[afFadd].creatorFunction(inPrimitive, mPool, afFadd); + useProducer(inPrimitive.nthInputVariable(0), insn, 0, vrcFloatingPoint); + useProducer(inPrimitive.nthInputVariable(1), insn, 1, vrcFloatingPoint); + defineProducer(inPrimitive, insn, 0, vrcFloatingPoint); + } + break; +// case emFAddI_F: +// { +// VirtualRegister& contantVR = genLoadConstant_F(inPrimitive, inPrimitive.nthInputConstant(1).f); +// Instruction& insn = sAFormInfos[afFadd].creatorFunction(inPrimitive, mPool, afFadd); +// useProducer(inPrimitive.nthInputVariable(0), insn, 0, vrcFloatingPoint); +// useTemporaryVR(insn, contantVR, 1, vrcFloatingPoint); + // defineProducer(inPrimitive, insn, 0, vrcFloatingPoint); + // } +// break; + default: + //assert(false) + ; + } +} + + +void PPCEmitter:: +emit_Const_I(Primitive& inPrimitive) +{ + Int32 constant = (*static_cast(&inPrimitive)).value.i; + + // can't use genLoadConstant_I here because we need to assign the VR to this producer + // (and this producer could already have a VR assigned to it) + if ((constant <= 32767) && (constant >= -32768)) + { + ArithIZeroInputD& lo16 = *new(mPool) ArithIZeroInputD(&inPrimitive, mPool, dfAddi, (Uint16) constant); + defineProducer(inPrimitive, lo16, 0); + } + else + { + // if we need to load a constant larger that 16 bits, then we use an addis, ori combo + // we need to make the input of the the ori depend on the output of the addis so that + // those instructions come in uninterrupted pairs (because we don't support defining half + // of a VirtualRegister) + ArithIZeroInputD& hi16 = *new(mPool) ArithIZeroInputD(&inPrimitive, mPool, dfAddis, (Uint16)((Uint32) constant >> 16)); + VirtualRegister& constantVr = *defineProducer(inPrimitive, hi16, 0); + + LogicalID& lo16 = *new(mPool) LogicalID(&inPrimitive, mPool, dfOri, (Uint16)((Uint32) constant)); + useTemporaryVR(lo16, constantVr, 0); + redefineTemporary(lo16, constantVr, 0); + } +} + +void PPCEmitter:: +emit_Const_F(Primitive& inPrimitive) +{ + Flt32 constant = (*static_cast(&inPrimitive)).value.f; + + Uint16 offset; + mAccumulatorTOC.addData(&constant, sizeof(constant), offset); + + Instruction& ldConstant = *new(mPool) LdD_RTOC(&inPrimitive, mPool, dfLfs, offset); + defineProducer(inPrimitive, ldConstant, 0, vrcFloatingPoint); +} + +void PPCEmitter:: +emit_StI_I(Primitive& inPrimitive) +{ + VirtualRegister& constantReg = genLoadConstant_I(inPrimitive, inPrimitive.nthInputConstant(2).i); + StD& storeInsn = *new(mPool) StD(&inPrimitive, mPool, dfStw, 0); + + useTemporaryVR(storeInsn, constantReg, 1); + useProducer(inPrimitive.nthInputVariable(0), storeInsn, 0); + trespass("Not implemented yet"); + //defineProducer(inPrimitive, storeInsn, 0); + //defineProducer(nthOutputProducer(inPrimitive, 1), storeInsn, 0); +} + +void PPCEmitter:: +emit_St_IRegisterIndirect(Primitive& inPrimitive) +{ + Int16 offset; + + // Need to get immediate arguement from producer's primitive + DataNode* addrSource = &inPrimitive.nthInput(1).getVariable(); + + if(!extractS16(PrimConst::cast(addrSource->nthInputVariable(1)).value, offset)) + assert(false); + + StD& storeInsn = *new(mPool) StD(&inPrimitive, mPool, dfStw, offset); + useProducer(inPrimitive.nthInputVariable(0), storeInsn, 0); // <- store + useProducer(addrSource->nthInputVariable(0), storeInsn, 1); // <- address base + useProducer(inPrimitive.nthInputVariable(2), storeInsn, 2); // <- value + defineProducer(inPrimitive, storeInsn, 0); // -> store +} + + +void PPCEmitter:: +emit_ShlI_I(Primitive& inPrimitive) +{ + uint8 shiftBy; + + extractU8(inPrimitive.nthInputConstant(1), shiftBy); + + MFormInAOnly& newInsn = *new(mPool) MFormInAOnly(&inPrimitive, mPool, mfRlwinm, shiftBy, 0, 31 - shiftBy, pfNil); // slwi ra, rs, shiftBy + newInsn.standardUseDefine(*this); +} + + +void PPCEmitter:: +emit_Div_I(Primitive& inPrimitive) +{ + ArithX& divInsn = *new(mPool) ArithX(&inPrimitive, mPool, xfDivw, pfNil); + + useProducer(inPrimitive.nthInputVariable(0), divInsn, 0); + useProducer(inPrimitive.nthInputVariable(1), divInsn, 1); + defineProducer(inPrimitive, divInsn, 0); +} + +void PPCEmitter:: +emit_DivE_I(Primitive& inPrimitive) +{ + genThrowIfDivisorZero(inPrimitive); + emit_Div_I(inPrimitive); +} + + +void PPCEmitter:: +emit_DivI_I(Primitive& inPrimitive) +{ + Value& immediate = inPrimitive.nthInputConstant(1); + + if(isPowerOfTwo(immediate.i)) + { + uint8 shiftBy = 31 - leadingZeros(immediate.i); + + XInAOnly& shiftRight = *new(mPool) XInAOnly(&inPrimitive, mPool, xfSrawi, pfNil, shiftBy); + shiftRight.standardUseDefine(*this); + } + else + { + VirtualRegister& divisor = genLoadConstant_I(inPrimitive, immediate.i); + ArithX& divInsn = *new(mPool) ArithX(&inPrimitive, mPool, xfDivw, pfNil); + + useTemporaryVR(divInsn, divisor, 1); + useProducer(inPrimitive.nthInputVariable(0), divInsn, 0); + defineProducer(inPrimitive, divInsn, 0); + } +} + +void PPCEmitter:: +emit_DivR_I(Primitive& inPrimitive) +{ + Value& immediate = inPrimitive.nthInputConstant(0); // remember it's reversed + + if(isPowerOfTwo(immediate.i)) + { + uint8 shiftBy = 31 - leadingZeros(immediate.i); + + XInAOnly& shiftRight = *new(mPool) XInAOnly(&inPrimitive, mPool, xfSrawi, pfNil, shiftBy); + useProducer(inPrimitive.nthInputVariable(1), shiftRight, 0); + defineProducer(inPrimitive, shiftRight, 0); + } + else + { + VirtualRegister& divisor = genLoadConstant_I(inPrimitive, immediate.i); + ArithX& divInsn = *new(mPool) ArithX(&inPrimitive, mPool, xfDivw, pfNil); + + useTemporaryVR(divInsn, divisor, 1); + useProducer(inPrimitive.nthInputVariable(1), divInsn, 0); + defineProducer(inPrimitive, divInsn, 0); + } +} + + +void PPCEmitter:: +emit_DivRE_I(Primitive& inPrimitive) +{ + genThrowIfDivisorZero(inPrimitive); + emit_DivR_I(inPrimitive); +} + +void PPCEmitter:: +emit_DivU_I(Primitive& inPrimitive) +{ + ArithX& divInsn = *new(mPool) ArithX(&inPrimitive, mPool, xfDivwu, pfNil); + + useProducer(inPrimitive.nthInputVariable(0), divInsn, 0); + useProducer(inPrimitive.nthInputVariable(1), divInsn, 0); + defineProducer(inPrimitive, divInsn, 0); +} + +void PPCEmitter:: +emit_DivUE_I(Primitive& inPrimitive) +{ + genThrowIfDivisorZero(inPrimitive); + + emit_DivU_I(inPrimitive); +} + +void PPCEmitter:: +emit_DivUI_I(Primitive& inPrimitive) +{ + Value& immediate = inPrimitive.nthInputConstant(1); + + if(isPowerOfTwo(immediate.i)) + { + Uint8 shiftBy = 31 - leadingZeros(immediate.i); + + MFormInAOnly& shiftRight = *new(mPool) MFormInAOnly(&inPrimitive, mPool, mfRlwinm, 32-shiftBy, shiftBy, 31, pfNil); // srwi ra, rs, shiftBy + shiftRight.standardUseDefine(*this); + } + else + { + VirtualRegister& divisor = genLoadConstant_I(inPrimitive, immediate.i); + ArithX& divInsn = *new(mPool) ArithX(&inPrimitive, mPool, xfDivwu, pfNil); + + useTemporaryVR(divInsn, divisor, 1); + useProducer(inPrimitive.nthInputVariable(0), divInsn, 0); + defineProducer(inPrimitive, divInsn, 0); + } +} + +void PPCEmitter:: +emit_DivUR_I(Primitive& inPrimitive) +{ + Value& immediate = inPrimitive.nthInputConstant(0); + + if(isPowerOfTwo(immediate.i)) + { + uint8 shiftBy = 31 - leadingZeros(immediate.i); + + MFormInAOnly& shiftRight = *new(mPool) MFormInAOnly(&inPrimitive, mPool, mfRlwinm, 32-shiftBy, shiftBy, 31, pfNil); // srwi ra, rs, shiftBy + useProducer(inPrimitive.nthInputVariable(1), shiftRight, 0); + defineProducer(inPrimitive.nthInputVariable(0), shiftRight, 0); + } + else + { + VirtualRegister& divisor = genLoadConstant_I(inPrimitive, immediate.i); + ArithX& divInsn = *new(mPool) ArithX(&inPrimitive, mPool, xfDivwu, pfNil); + + useTemporaryVR(divInsn, divisor, 1); + useProducer(inPrimitive.nthInputVariable(1), divInsn, 0); + defineProducer(inPrimitive, divInsn, 0); + } +} + +void PPCEmitter:: +emit_DivURE_I(Primitive& inPrimitive) +{ + genThrowIfDivisorZero(inPrimitive); + + emit_DivURE_I(inPrimitive); +} + + +void PPCEmitter:: +emit_Mod_I(Primitive& inPrimitive) +{ + // divw rt, ta, rb # rt = (ra-R)/rb + // mullw rt, rt, rb # rt = ra-R + // subf rt, rt, rta # rt = R + ArithX& divInsn = *new(mPool) ArithX(&inPrimitive, mPool, xfDivw, pfNil); + useProducer(inPrimitive.nthInputVariable(0), divInsn, 0); + useProducer(inPrimitive.nthInputVariable(1), divInsn, 1); + VirtualRegister& tempVr = defineTemporary(divInsn, 0); + + ArithX& mullInsn = *new(mPool) ArithX(&inPrimitive, mPool, xfMullw, pfNil); + useProducer(inPrimitive.nthInputVariable(1), mullInsn, 1); + useTemporaryVR(mullInsn, tempVr, 0); + redefineTemporary(mullInsn, tempVr, 0); + + ArithX& subInsn = *new(mPool) ArithX(&inPrimitive, mPool, xfSubf, pfNil); + useTemporaryVR(subInsn, tempVr, 0); + useProducer(inPrimitive.nthInputVariable(0), subInsn, 1); + defineProducer(inPrimitive, subInsn, 0); +} + +void PPCEmitter:: +emit_ModE_I(Primitive& inPrimitive) +{ + genThrowIfDivisorZero(inPrimitive); + emit_Mod_I(inPrimitive); +} +#if 0 + +void PPCEmitter:: +emit_ModI_I(Primitive& inPrimitive) +{ + genMod_I(inPrimitive); +} + +void PPCEmitter:: +emit_ModR_I(Primitive& inPrimitive) +{ + genMod_I(inPrimitive); +} + +void PPCEmitter:: +emit_ModRE_I(Primitive& inPrimitive) +{ + genThrowIfDivisorZero(inPrimitive); + genMod_I(inPrimitive); +} + +void PPCEmitter:: +emit_ModU_I(Primitive& inPrimitive) +{ + genThrowIfDivisorZero(inPrimitive); + genMod_I(inPrimitive); +} + +//ta = dividiend +//rb = divisor + +void PPCEmitter:: +genMod_I(Primitive& inPrimitive) +{ + // FIX-ME? Could reduce register pressure here by + // folding the constant in the mullw to kill rb one instruction earlier + // divw rt, ta, rb # rt = (ra-R)/rb + // mullw rt, rt, rb # rt = ra-R + // subf rt, rt, rta # rt = R + ArithX& divInsn = *new(mPool) ArithX(&inPrimitive, mPool, xfDivw, pfNil); + VirtualRegister* dividendVr; + VirtualRegister* divisorVr; + + if (inPrimitive.nthInputIsConstant(0)) + dividendVr = &genLoadConstant_I(inPrimitive.nthInputConstant(0).i) + else + dividendVr = useProducer(inPrimitive.nthInputVariable(0), divInsn, 0); + + if (inPrimitive.nthInputIsConstant(1)) + divisorVr = &genLoadConstant_I(inPrimitive.nthInputConstant(1).i) + else + divisorVr = useProducer(inPrimitive.nthInputVariable(1), divInsn, 1); + + VirtualRegister& tempVr = defineTemporary(divInsn, 0); + + ArithX& mullInsn = *new(mPool) ArithX(&inPrimitive, mPool, xfMullw, pfNil); + useTemporaryVR(mullInsn, *divisorVr, 1); + useTemporaryVR(mullInsn, tempVr, 0); + redefineTemporary(mullInsn, tempVr, 0); + + ArithX& subInsn = *new(mPool) ArithX(&inPrimitive, mPool, xfSubf, pfNil); + useTemporaryVR(subInsn, tempVr, 0); + useTemporaryVR(subInsn, *dividendVr, 1); + defineProducer(inPrimitive, subInsn, 0); +} + +void PPCEmitter:: +genModU_I(Primitive& inPrimitive) +{ + // FIX-ME? Could reduce register pressure here by + // folding the constant in the mullw to kill rb one instruction earlier + // divw rt, ta, rb # rt = (ra-R)/rb + // mullw rt, rt, rb # rt = ra-R + // subf rt, rt, rta # rt = R + ArithX& divInsn = *new(mPool) ArithX(&inPrimitive, mPool, xfDivwu, pfNil); + VirtualRegister* dividendVr; + VirtualRegister* divisorVr; + + if (inPrimitive.nthInputIsConstant(0)) + dividendVr = &genLoadConstant_I(inPrimitive.nthInputConstant(0).i) + else + dividendVr = useProducer(inPrimitive.nthInputVariable(0), divInsn, 0); + + if (inPrimitive.nthInputIsConstant(1)) + divisorVr = &genLoadConstant_I(inPrimitive.nthInputConstant(1).i) + else + divisorVr = useProducer(inPrimitive.nthInputVariable(1), divInsn, 1); + + VirtualRegister& tempVr = defineTemporary(divInsn, 0); + + ArithX& mullInsn = *new(mPool) ArithX(&inPrimitive, mPool, xfMullw, pfNil); + useTemporaryVR(mullInsn, *divisorVr, 1); + useTemporaryVR(mullInsn, tempVr, 0); + redefineTemporary(mullInsn, tempVr, 0); + + ArithX& subInsn = *new(mPool) ArithX(&inPrimitive, mPool, xfSubf, pfNil); + useTemporaryVR(subInsn, tempVr, 0); + useTemporaryVR(subInsn, *dividendVr, 1); + defineProducer(inPrimitive, subInsn, 0); +} +#endif + +void PPCEmitter:: +emit_Ld_IRegisterIndirect(Primitive& inPrimitive) +{ + Int16 constant; + DataNode& immSource = inPrimitive.nthInput(1).getVariable(); // immediate arguement from producer's primitive + + if(extractS16(immSource.nthInputConstant(1), constant)) + { + LdD_& newInsn = *new(mPool) LdD_(&inPrimitive, mPool, dfLwz, constant); + + useProducer(inPrimitive.nthInputVariable(0), newInsn, 0); // M to poLd_I + useProducer(immSource.nthInputVariable(0), newInsn, 1); // Vint to poAdd_A + defineProducer(inPrimitive, newInsn, 0); // Vint from poLd_I + } + else + { + assert(false); +// emitPrimitive(immSource); +// emitPrimitive(inPrimitive); + } +} + +void PPCEmitter:: +emit_LimitR(Primitive& inPrimitive) +{ + Int16 constant; + + if (extractS16(inPrimitive.nthInputConstant(0), constant)) + { + TrapD& newInsn = *new(mPool) TrapD(&inPrimitive, mPool, condLe, false, constant); + useProducer(inPrimitive.nthInputVariable(1), newInsn, 0); + inPrimitive.setInstructionRoot(&newInsn); + } + else + { + // fix-me handle immediate values larger than the use of a single instruction allows + assert(false); + } +} + + +void PPCEmitter:: +emit_Limit(Primitive& inPrimitive, PPCInsnFlags inFlags) +{ + TrapX& newInsn = *new(mPool) TrapX(&inPrimitive, mPool, condGe, false, inFlags); + newInsn.standardUseDefine(*this); +} + + +void PPCEmitter:: +emit_Cmp_I(Primitive& inPrimitive) +{ + CmpIX& newInsn = *new(mPool) CmpIX(&inPrimitive, mPool, xfCmp, 0); + newInsn.standardUseDefine(*this); +} + + +void PPCEmitter:: +emit_CmpI_I(Primitive& inPrimitive) +{ + Int16 constant; + + if (extractS16(inPrimitive.nthInputConstant(1), constant)) + { + CmpID& newInsn = *new(mPool) CmpID(&inPrimitive, mPool, dfCmpi, constant); + newInsn.standardUseDefine(*this); + } + else + { + VirtualRegister& constantVr = genLoadConstant_I(inPrimitive, inPrimitive.nthInputConstant(1).i); + CmpIX& newInsn = *new(mPool) CmpIX(&inPrimitive, mPool, xfCmp, 0); + + useProducer(inPrimitive.nthInputVariable(0), newInsn, 0); + useTemporaryVR(newInsn, constantVr, 1); + defineProducer(inPrimitive, newInsn, 0); + } +} + +void PPCEmitter:: +emit_Result_I(Primitive& inPrimitive) +{ + VirtualRegister* returnVr; + + if (inPrimitive.nthInputIsConstant(0)) + { + // if the result is a constant load it into a register + returnVr = &genLoadConstant_I(inPrimitive, inPrimitive.nthInputConstant(0).i); + } + else + { + // otherwise create a buffer copy instruction between the result + // and the precolored register + Copy_I& copyInsn = *new(mPool) Copy_I(&inPrimitive, mPool); + + returnVr = &defineTemporary(copyInsn, 0); + useProducer(inPrimitive.nthInputVariable(0), copyInsn, 0); + } + + // integer results (and _A go in r3) + returnVr->preColorRegister(kR3Color); + + // create a special instruction for the RegisterAllocator which says this result + // is used elsewhere (but not in this body of code). + InsnExternalUse& externalUse = *new(mPool) InsnExternalUse(&inPrimitive, mPool, 1); + useTemporaryVR(externalUse, *returnVr, 0); + inPrimitive.setInstructionRoot(&externalUse); +} + +void PPCEmitter:: +emit_Result_F(Primitive& inPrimitive) +{ + VirtualRegister* returnVr; + + if (inPrimitive.nthInputIsConstant(0)) + { + // if the result is a constant load it into a register + returnVr = &genLoadConstant_F(inPrimitive, inPrimitive.nthInputConstant(0).f); + } + else + { + // otherwise create a buffer copy instruction between the result + // and the precolored register + XInBOnly& copyInsn = *new(mPool) XInBOnly(&inPrimitive, mPool, xfFmr, pfNil); + + useProducer(inPrimitive.nthInputVariable(0), copyInsn, 0, vrcFloatingPoint); + returnVr = &defineTemporary(copyInsn, 0, vrcFloatingPoint); + } + + // integer results (and _A go in r3) + returnVr->preColorRegister(1); + + // create a special instruction for the RegisterAllocator which says this result + // is used elsewhere (but not in this body of code). + InsnExternalUse& externalUse = *new(mPool) InsnExternalUse(&inPrimitive, mPool, 1); + useTemporaryVR(externalUse, *returnVr, 0, vrcFloatingPoint); + inPrimitive.setInstructionRoot(&externalUse); +} + + +#ifdef __MWERKS__ +#pragma mark - +#pragma mark ¥ Utilities ¥ +#endif + +void PPCEmitter:: +genLoadIZero(Primitive& inPrimitive, PPCInsnFlags /*inFlags*/) +{ + LdD_& newInsn = *new(mPool) LdD_(&inPrimitive, mPool, dfLwz, 0); + + newInsn.standardUseDefine(*this); +} + + +void PPCEmitter:: +genBranch(Primitive& inPrimitive, Condition2 cond) +{ + ControlNode& controlIf = *inPrimitive.getContainer(); + BranchCB& newInsn = *new(mPool) BranchCB(&inPrimitive, mPool, controlIf.getTrueSuccessor().getTarget(), cond, false, false); + + newInsn.standardUseDefine(*this); +} + +// need to do an add +// with a negated constant +void PPCEmitter:: +emit_SubI(Primitive& inPrimitive) +{ + Int16 constant; + + // perform an addi with -constant if we're in range + if (extractS16(inPrimitive.nthInputConstant(1), constant)) + { + ArithID& newInsn = *new(mPool) ArithID(&inPrimitive, mPool, dfAddi, -constant); + + newInsn.standardUseDefine(*this); + } + else + { + // otherwise load the constant, and do a subf + VirtualRegister& constantReg = genLoadConstant_I(inPrimitive, inPrimitive.nthInputConstant(1).i); + + ArithX& opInsn = *new(mPool) ArithX(&inPrimitive, mPool, xfSubf, pfNil); + + useTemporaryVR(opInsn, constantReg, 1); + useProducer(inPrimitive.nthInputVariable(0), opInsn, 0); + defineProducer(inPrimitive, opInsn, 0); + } +} + +void PPCEmitter:: +emit_SubR(Primitive& inPrimitive, bool inUnsigned) +{ + // first negate the Vint edge + Instruction& negate = *new(mPool) XInAOnly(&inPrimitive, mPool, xfNeg, pfNil, 0); + useProducer(inPrimitive.nthInputVariable(1), negate, 0); + defineProducer(inPrimitive, negate, 0); + + // then perform the appropriate add + genArith_RD(inPrimitive, dfAddi, xfAdd, inUnsigned); +} + +void PPCEmitter:: +genArith_ID(Primitive& inPrimitive, DFormKind inKind, XFormKind inXKind) +{ + Int16 constant; + + if (extractS16(inPrimitive.nthInputConstant(1), constant)) + { + ArithID& newInsn = *new(mPool) ArithID(&inPrimitive, mPool, inKind, constant); + + newInsn.standardUseDefine(*this); + } + else + { + VirtualRegister& constantReg = genLoadConstant_I(inPrimitive, inPrimitive.nthInputConstant(1).i); + + ArithX& opInsn = *new(mPool) ArithX(&inPrimitive, mPool, inXKind, pfNil); + + useTemporaryVR(opInsn, constantReg, 0); + useProducer(inPrimitive.nthInputVariable(0), opInsn, 1); + defineProducer(inPrimitive, opInsn, 0); + } +} + +// this is when the constant is in the first position, not in the second +void PPCEmitter:: +genArith_RD(Primitive& inPrimitive, DFormKind inKind, XFormKind inXKind, bool inIsUnsigned) +{ + Int16 constant; + + // use a normal D form Arithmetic if the value fits in a signed word, or + // it's unsigned and the constant is > 0 if it were treated as signed + if (extractS16(inPrimitive.nthInputConstant(0), constant) && ((!inIsUnsigned) || (inIsUnsigned && constant >= 0))) + { + ArithID& newInsn = *new(mPool) ArithID(&inPrimitive, mPool, inKind, constant); + + useProducer(inPrimitive.nthInputVariable(1), newInsn, 0); + defineProducer(inPrimitive, newInsn, 0); + } + else + { + VirtualRegister& constantReg = genLoadConstant_I(inPrimitive, inPrimitive.nthInputConstant(0).i); + + ArithX& opInsn = *new(mPool) ArithX(&inPrimitive, mPool, inXKind, pfNil); + + useTemporaryVR(opInsn, constantReg, 0); + useProducer(inPrimitive.nthInputVariable(1), opInsn, 1); + defineProducer(inPrimitive, opInsn, 0); + } +} + + + +void PPCEmitter:: +genArith_IX(Primitive& inPrimitive, XFormKind inKind) +{ + ArithX& newInsn = *new(mPool) ArithX(&inPrimitive, mPool, inKind, pfNil); + + newInsn.standardUseDefine(*this); +} + +// this is for reversed operands in the native instruction +void PPCEmitter:: +genArithReversed_IX(Primitive& inPrimitive, XFormKind inKind) +{ + ArithX& newInsn = *new(mPool) ArithX(&inPrimitive, mPool, inKind, pfNil); + + useProducer(inPrimitive.nthInputVariable(1), newInsn, 0); + useProducer(inPrimitive.nthInputVariable(0), newInsn, 1); + defineProducer(inPrimitive, newInsn, 0); +} + + +VirtualRegister& PPCEmitter:: +genLoadConstant_I(DataNode& inPrimitive, Int32 inConstant) +{ + VirtualRegister* vr; + + if ((inConstant <= 32767) && (inConstant >= -32768)) + { + ArithIZeroInputD& lo16 = *new(mPool) ArithIZeroInputD(&inPrimitive, mPool, dfAddi, inConstant); + vr = &defineTemporary(lo16, 0); + } + else + { + // if we need to load a constant larger that 16 bits, then we use an addis, ori combo + ArithIZeroInputD& hi16 = *new(mPool) ArithIZeroInputD(&inPrimitive, mPool, dfAddis, (Uint16)(((Uint32) inConstant) >> 16)); + VirtualRegister& constantVr = defineTemporary(hi16, 0); + + LogicalID& lo16 = *new(mPool) LogicalID(&inPrimitive, mPool, dfOri, (Uint16)((Uint32) inConstant)); + useTemporaryVR(lo16, constantVr, 0); + redefineTemporary(lo16, constantVr, 0); + + vr = &constantVr; + } + + return (*vr); +} + + +VirtualRegister& PPCEmitter:: +genLoadConstant_F(DataNode& inPrimitive, Flt32 inConstant) +{ + Uint16 offset; + void *d = mAccumulatorTOC.addData(&inConstant, sizeof(inConstant), offset); + assert(d); + + Instruction& ldConstant = *new(mPool) LdD_RTOC(&inPrimitive, mPool, dfLfs, offset); + return (defineTemporary(ldConstant, 0, vrcFloatingPoint)); +} + +void PPCEmitter:: +genThrowIfDivisorZero(Primitive& inPrimitive) +{ + // Check the divisor != 0 + TrapD& trapInsn = *new(mPool) TrapD(&inPrimitive, mPool, condEq, false, 0); + useProducer(inPrimitive.nthInputVariable(1), trapInsn, 0); + inPrimitive.setInstructionRoot(&trapInsn); +} + +#ifdef __MWERKS__ +#pragma mark - +#pragma mark ¥ÊFormatting Support ¥ +#endif + +Instruction& PPCEmitter:: +emitAbsoluteBranch(DataNode& inDataNode, ControlNode& inTarget) +{ + BranchI& newInsn = *new(mPool) BranchI(&inDataNode, mPool, inTarget, false, false); + + return (newInsn); +} + +#ifdef __MWERKS__ +#pragma mark - +#pragma mark ¥ÊRegisterAllocator Support ¥ +#endif + +bool PPCEmitter:: +emitCopyAfter(DataNode& inDataNode, InstructionList::iterator where, VirtualRegister& fromVr, VirtualRegister& toVr) +{ + ArithID& newInsn = *new(mPool) ArithID(&inDataNode, mPool, dfAddi, 0); + + newInsn.addUse(0, fromVr); + newInsn.addDefine(0, toVr); +#ifdef DEBUG + toVr.setDefiningInstruction(newInsn); +#endif + newInsn.insertAfter(*where); + return false; +} + +void PPCEmitter:: +emitStoreAfter(DataNode& inDataNode, InstructionList::iterator where, VirtualRegister& storedReg, VirtualRegister& stackReg) +{ + StD_SpillRegister& newInsn = *new(mPool) StD_SpillRegister(&inDataNode, mPool, stackReg, storedReg); + + newInsn.insertAfter(*where); +} + +void PPCEmitter:: +emitLoadAfter(DataNode& inDataNode, InstructionList::iterator where, VirtualRegister& loadedReg, VirtualRegister& stackReg) +{ + LdD_SpillRegister& newInsn = *new(mPool) LdD_SpillRegister(&inDataNode, mPool, stackReg, loadedReg); +#ifdef DEBUG + loadedReg.setDefiningInstruction(newInsn); +#endif + newInsn.insertAfter(*where); +} + +#ifdef __MWERKS__ +#pragma mark - +#pragma mark ¥ÊDebug Support ¥ +#endif + +#ifdef DEBUG +void* +disassemble1(LogModuleObject &f, void* inFrom) +{ +#ifdef USING_MAC_PPC_DISASSEMBLER + char mnemonic[100]; + char operand[100]; + char comment[100]; + + ppcDisassembler((unsigned long *)inFrom, 0, MAC_PPC_DISASSEMBLER_OPTIONS, mnemonic, operand, comment, NULL, NULL); + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("%p: %-10s %-40s %-40s\n", inFrom, mnemonic, operand, comment)); + + return ((char*) inFrom + 4); +#else + f; + inFrom = NULL; + return NULL; +#endif +} +#endif + +#ifdef __MWERKS__ +#pragma mark - +#pragma mark ¥ÊLinkage Support ¥ +#endif + +void PPCEmitter:: +emitArguments(ControlNode::BeginExtra& inBeginNode) +{ + Uint16 curParamWords; // number of words of argument space used + Uint16 curFloatingPointArg; // number of floating point arguments + + if (inBeginNode.nArguments == 0) + return; + + InsnExternalDefine& defineInsn = *new(mPool) InsnExternalDefine(&inBeginNode[0], mPool, inBeginNode.nArguments * 2); + + Uint8 curArgIdx; // current index into the arguments in ControlNode::BeginExtra + + curParamWords = 0; + curFloatingPointArg = 1; + for (curArgIdx = 0; curArgIdx < inBeginNode.nArguments && curParamWords < 8; curArgIdx++) + { + PrimArg& curArg = inBeginNode[curArgIdx]; + + switch (curArg.getOperation()) + { + case poArg_I: + case poArg_A: + { + if (curArg.hasConsumers()) + { + Copy_I& copyInsn = *new(mPool) Copy_I(&curArg, mPool); + + // hook up this vr to the external define FIX-ME + VirtualRegister& inputVr = defineTemporary(defineInsn, curArgIdx); + inputVr.preColorRegister(curParamWords); + + // emit the copy + useTemporaryVR(copyInsn, inputVr, 0); + defineProducer(curArg, copyInsn, 0); + } + curParamWords++; + break; + } + case poArg_L: + { + assert(false); + if (curParamWords < 6) + { + Copy_I& copyInsn = *new(mPool) Copy_I(&curArg, mPool); + + // hook up this vr to the external define FIX-ME + VirtualRegister& inputVr = defineTemporary(defineInsn, curArgIdx); + + useTemporaryVR(copyInsn, inputVr, 0); + defineProducer(curArg, copyInsn, 0); + + //inputVr.preColorRegister(curParamWords); + //inputVr.preColorRegister(curParamWords); + } + else if (curParamWords < 7) + { + // make the external define create this argument + VirtualRegister& inputVr = defineTemporary(defineInsn, curArgIdx); // specify 32bit fixed point register + inputVr.preColorRegister(6); + + // copy the hiword argument in r10 (color=6) to a new vr + Copy_I& copyInsn = *new(mPool) Copy_I(&curArg, mPool); + useTemporaryVR(copyInsn, inputVr, 0); + + VirtualRegister& copyVr64 = mVRAllocator.newVirtualRegister(); // FIX-ME want to specify a "64" bit vr + defineProducerWithExistingVirtualRegister(copyVr64, curArg, copyInsn, 0); + + // copy the loword argument from the appropriate stackslot to a new vr + LdD_FixedSource& loadParam = *new(mPool) LdD_FixedSource(&curArg, mPool, dfLwz, 24 + 32); + + // fix-me add use or change to special stack relative load + defineProducer(curArg, loadParam, 0); // specify loword of 32 bit register + } + curParamWords+=2; + break; + } + case poArg_F: + { + XInBOnly& copyInsn = *new(mPool) XInBOnly(&curArg, mPool, xfFmr, pfNil); + + // emit the copy + // hook up this vr to the external define + VirtualRegister& inputVr = defineTemporary(defineInsn, curArgIdx, vrcFloatingPoint); + inputVr.preColorRegister(curFloatingPointArg); + + useTemporaryVR(copyInsn, inputVr, 0, vrcFloatingPoint); + defineProducer(curArg, copyInsn, 0, vrcFloatingPoint); + + curParamWords++; + curFloatingPointArg++; + break; + } + case poArg_D: + assert(false); + break; + + case poArg_M: + break; + + default: + assert(0); + } + } + + // do appropriate loads for each argument + Uint8 stackArgIdx; + for (stackArgIdx = curArgIdx; stackArgIdx < inBeginNode.nArguments; stackArgIdx++) + { + PrimArg& curArg = inBeginNode[stackArgIdx]; + + switch (curArg.getOperation()) + { + case poArg_I: + case poArg_A: + { + if (curArg.hasConsumers()) + { + LdD_FixedSource& loadParam = *new(mPool) LdD_FixedSource(&curArg, mPool, dfLwz, 24 + curParamWords * 4); + + useTemporaryOrder(loadParam, defineTemporaryOrder(defineInsn, stackArgIdx), 0); + defineProducer(curArg, loadParam, 0); + } + curParamWords++; + break; + } + case poArg_L: + assert(false); + case poArg_F: + { +#if 0 + LoadSP& loadParam = *new(mPool) LoadSP(&curArg, mPool, 24 + curParamWords * 4, dfLfs); + + defineProducer(curArg, loadParam, 0); +#endif + curParamWords++; + break; + } + case poArg_D: + assert(false); + default: + assert(false); + } + } + + // continue counting from before + // make all the rest of the defines as type none + for (;curArgIdx < inBeginNode.nArguments * 2; curArgIdx++) + defineInsn.getInstructionDefineBegin()[curArgIdx].kind = udNone; + +#if 0 + MacDebugger& macDebugger = *new(mPool) MacDebugger(&inBeginNode.initialMemory, *this); + inBeginNode.initialMemory.setInstructionRoot(&macDebugger); +#endif +} + + +const Uint32 upper16 = 0xffff0000; +const Uint32 lower16 = 0x0000ffff; + + +void PPCFormatter:: +calculatePrologEpilog(Method& /*inMethod*/, Uint32& outPrologSize, Uint32& outEpilogSize) +{ + Uint8 usedNonVolatileGPR = 10; // mVRAllocator.nUsedCalleeSavedRegisters; + Uint8 usedNonVolatileFPR = 0; + Uint32 localsWords = 0; // localSize_words + const Uint32 kLinkAreaWords = 2; + Uint32 totalRegisterWords; + + assert(usedNonVolatileGPR <= 14); + assert(usedNonVolatileFPR <= 13); + + mSaveGPRwords = usedNonVolatileGPR; + mSaveFPRwords = usedNonVolatileFPR * 2; // 2 words per FPR + + // total amount of space needed to save non-volatile registers + totalRegisterWords = mSaveGPRwords + mSaveFPRwords; + if(totalRegisterWords < 8) + totalRegisterWords = 8; + + // figure total size of frame + mFrameSizeWords = mEmitter.mMaxArgWords + kLinkAreaWords + localsWords + totalRegisterWords; + mFrameSizeWords = (mFrameSizeWords + 3 & ~3); // align to 4 byte boundary + + Uint32 prologSize_words; + Uint32 epilogSize_words; + + // Number of instructions + if((mFrameSizeWords * 4) > 32768) // We need 3 instructions to create the stack frame + { + // Prolog needs 4 instruction to save CR and LR + // and 1 instruction to save each FPR and GPR + // and 3 instructions to create the stack frame + prologSize_words = 7 + usedNonVolatileFPR + usedNonVolatileGPR; + + // Epilog needs 4 instruction to restore CR and LR + // and 1 instruction to restore each FPR and GPR + // and 3 instruction to restore the stack frame + // and 1 instruction to return (branch to lr) + epilogSize_words = prologSize_words + 1; + } + else + { + // We need 1 instruction to create the stack frame + // Prolog needs 4 instruction to save CR and LR + // and 1 instruction to save each FPR and GPR + // and 1 instruction to create the stack frame + prologSize_words = 1 + 2 + /*2*/ + usedNonVolatileFPR + usedNonVolatileGPR; + + // Epilog needs 4 instruction to restore CR and LR + // and 1 instruction to restore each FPR and GPR + // and 1 instruction to restore the stack frame + // and 1 instruction to return (branch to lr) + epilogSize_words = prologSize_words + 1; + } + + // now convert from words to bytes + outPrologSize = prologSize_words * 4; + outEpilogSize = epilogSize_words * 4; +} + + +void PPCFormatter:: +formatPrologToMemory(void* inWhere) +{ + Uint32* nextInstruction = (Uint32*)inWhere; + +#if 0 + /* + Write instructions to save CR + mfcr r0 + stw r0, 4(r1) + */ + *nextInstruction++ = mfcrR0; + *nextInstruction++ = stwR04R1; +#endif + + /* + Write instructions to save LR + mflr r0 + stw r0, 8(r1) + */ + *nextInstruction++ = mflrR0; + *nextInstruction++ = stwR08R1; + + /* + Save non-volatile FPRs + non volatile floating point registers are in the range fr14 - fr31 + the saved block of non-volatile registers must start at fr31 and move up to fr 14 + + for(i = 0; i < #FPR to be saved; i++) + stfd fr(31-x), (-8 * (i+1))(r1) + */ + Uint16 i; + + for(i = 0; i < (mSaveFPRwords/2); i++) + { + Uint32 fpr = 31-i; + fpr = fpr<<21; + Int32 off = (-8 * (i+1)); + Uint32 offset = off & lower16; + + Uint32 stfd = stfd_FR_offR1 | fpr | offset; + + *nextInstruction++ = stfd; + } + + /* + Save non-volatile GPRs + non volatile general purpose registers are in the range r13 - r31 + the saved block of non-volatile registers must start at r31 and move up to fr 13 + + for(i = 0; i < #GPR to be saved; i++) + stw r(31-x), (-4 * (i+1)) - (4 * fprSize_words)) (r1) + */ + for(i = 0; i < (mSaveGPRwords); i++) + { + Uint32 gpr = 31-i; + gpr = gpr<<21; + Int32 off = (-4 * (i+1)) - (4 * mSaveFPRwords); + Uint32 offset = off & lower16; + + Uint32 stw = stw_R_offR1 | gpr | offset; + + *nextInstruction++ = stw; + } + + /* + Create stack frame + + if(frameSize_bytes > 32768) + lis r12, upper 16-bits of -frameSize_bytes + ori r12, lower 16-bits of -frameSize_bytes + stwuz r1, r1, r12stwu r1, -frameSize_bytes(r1) + else + stwu r1, -frameSize_bytes(r1) + */ + + Int32 frameSize_bytes = -4*mFrameSizeWords; + if(frameSize_bytes < -32768) + { + + Uint32 sfUpper = upper16 & frameSize_bytes; + sfUpper = sfUpper>>16; + Uint32 sfLower = lower16 & frameSize_bytes; + + uint lis = lisR12_imm | sfUpper; + uint ori = oriR12R12_imm | sfLower; + + *nextInstruction++ = lis; + *nextInstruction++ = ori; + *nextInstruction = stwuxR1R1R12 ; + + } else { + Uint32 offset = frameSize_bytes & lower16; + uint stwv = stwuR1_offR1 | offset; + *nextInstruction = stwv; + } + +#ifdef DEBUG + nextInstruction++; + Uint32 numberInstructions = nextInstruction - (Uint32*)inWhere; + // assert((numberInstructions * 4) == mPrologSize_bytes); FIX-ME +#endif +} + + + +void PPCFormatter:: +formatEpilogToMemory(void* inWhere) +{ + Uint32* nextInstruction = (Uint32*)inWhere; + + /* + Return to parent's stack frame + + if(frameSize_bytes > 32768) + lis r12, upper 16-bits of frameSize_bytes + ori r12, lower 16-bits of frameSize_bytes + addi r1, r1, r12 + else + addi r1, r1, frameSize_bytes + */ + + const Uint32 frameSize_bytes = 4*mFrameSizeWords; + if(frameSize_bytes > 32768) + { + Uint32 sfUpper = upper16 & frameSize_bytes; + sfUpper = sfUpper>>16; + Uint32 sfLower = lower16 & frameSize_bytes; + + uint lis = lisR12_imm | sfUpper; + uint ori = oriR12R12_imm | sfLower; + + *nextInstruction++ = lis; + *nextInstruction++ = ori; + *nextInstruction++ = addR1R1R12; + } + else + { + Uint32 offset = lower16 & frameSize_bytes; + Uint32 addi = addiR1R1_imm | offset; + *nextInstruction++ = addi; + } + +#if 0 + /* + restore CR + lwz r0, 4(r1) + mtcr r0 + */ + *nextInstruction++ = lwzR04R1; + *nextInstruction++ = mtcrR0; +#endif + + /* + restore LR + lwz r0, 8(r1) + mtlr r0 + */ + *nextInstruction++ = lwzR08R1; + *nextInstruction++ = kMtlrR0; + + /* + Restore non-volatile FPRs + for(i = 0; i < #FPR to be saved; i++) + lfd fr(31-x), (-8 * (i+1))(r1) + */ + Uint16 i; + + for(i = 0; i < (mSaveFPRwords/2); i++) + { + Uint32 fpr = 31-i; + fpr = fpr<<21; + Int32 off = (-8 * (i+1)); + Uint32 offset = off & lower16; + + Uint32 lfd = lfd_FR_offR1 | fpr | offset; + + *nextInstruction++ = lfd; + } + + + /* + Save non-volatile GPRs + for(i = 0; i < #GPR to be saved; i++) + lwz r(31-x), (-4 * (i+1)) - (4 * fprSize_words)) (r1) + */ + for(i = 0; i < (mSaveGPRwords); i++) + { + Uint32 gpr = 31-i; + gpr = gpr<<21; + Int32 off = (-4 * (i+1)) - (4 * mSaveFPRwords); + Uint32 offset = off & lower16; + + Uint32 lwz = lwz_R_offR1 | gpr | offset; + + *nextInstruction++ = lwz; + } + + *nextInstruction = kBlr; + +#ifdef DEBUG + nextInstruction++; + Uint32 numberInstructions = nextInstruction - (Uint32*)inWhere; + //assert((numberInstructions * 4) == mEpilogSize_bytes); // FIX-ME +#endif +} + +#ifdef XP_MAC +#include "StringUtils.h" + +class PPCTraceInfo +{ + // a trace back table is a PPCTraceInfo + // aligned on a 4 byte boundary +public: + PPCTraceInfo(const char* inSymbol) : + symbol(inSymbol) + { + symbolLen = PL_strlen(symbol); + magic[0] = 0; + magic[1] = 0x00092040; + magic[2] = 0; + } + + Uint32 magic[3]; // some flags and other unknown stuff + Uint32 functionLen; // length of function in bytes + Uint16 symbolLen; // length of following symbol + TemporaryStringCopy symbol; // symbol to write out + + size_t + getFormattedSize() + { + size_t size = offsetof(PPCTraceInfo, symbol) + symbolLen; + + // align 4 + return ((size + 3) & ~3); + } + + void + formatToMemory(void* inStart, Uint32 inFunctionLength) + { + Uint32 x[] = {0, 0x00092041, 0x80030000, 0x00000078, 0x00202E5F, 0x5F63745F, 0x5F313954, 0x656D706F, 0x72617279, 0x53747269, 0x6E67436F, 0x70794650, 0x43630000}; + + unsigned char* output = static_cast(inStart); + char *cp; + + for (cp = symbol; *cp; cp++) + { + if (!(('A' <= *cp && *cp <= 'Z') || ('a' <= *cp && *cp <= 'z'))) + *cp = 'x'; + } + + functionLen = inFunctionLength; + output += offsetof(PPCTraceInfo, symbol); + memcpy(output, symbol, symbolLen); + + symbolLen = (symbolLen + 1) & ~1; + output -= offsetof(PPCTraceInfo, symbol); + memcpy(output, &magic[0], offsetof(PPCTraceInfo, symbol)); + } +}; + + +#endif // XP_MAC + +#include "FieldOrMethod.h" +#include "NativeFormatter.h" + +void PPCFormatter:: +beginFormatting(const FormattedCodeInfo& inInfo) +{ + Int16 offsetInRealTOC; + + // determine offset we need to add to the offsets into the accumulator toc + mRealTOC = &acquireTOC(mEmitter.mAccumulatorTOC.getNext() - mEmitter.mAccumulatorTOC.mBegin); + + void *d = mRealTOC->addData(mEmitter.mAccumulatorTOC.mBegin, mEmitter.mAccumulatorTOC.getNext() - mEmitter.mAccumulatorTOC.mBegin, offsetInRealTOC); + assert(d); + mRealTOCOffset = offsetInRealTOC + mRealTOC->mGlobalPtr - mRealTOC->mBegin; + + // grab ptr to beginning of stuff that's not code + mNextFreePostMethod = (Uint32*) ((Uint8*) inInfo.methodStart + inInfo.bodySize + inInfo.preMethodSize); +} + + + +void PPCFormatter:: +calculatePrePostMethod(Method& inMethod, Uint32& outPreMethodSize, Uint32& outPostMethodSize) +{ + outPreMethodSize = 0; + outPostMethodSize = mEmitter.mCrossTOCPtrGlCount * kCrossTocPtrGlBytes; + +#ifdef FIX_ME + PPCTraceInfo traceBack(inMethod.toString()); + + outPostMethodSize += traceBack.getFormattedSize(); //sTraceInfo.size(inMethod.toString()); +#else + inMethod; +#endif +} + +void PPCFormatter:: +formatPostMethodToMemory(void* inWhere, const FormattedCodeInfo& inInfo) +{ +#ifdef XP_MAC +#if 0 + PPCTraceInfo traceBack(inInfo.method->toString()); + + traceBack.formatToMemory(inWhere, inInfo.bodySize); +#endif + inWhere; + inInfo; +#else + inWhere; + inInfo; +#endif +} + + + +Uint8* PPCFormatter:: +createTransitionVector(const FormattedCodeInfo& inInfo) +{ + TVector newTVector = {inInfo.methodStart, (void*) mRealTOC->mGlobalPtr}; + Uint16 offset; + + void* tvectorPtr = mRealTOC->addData(&newTVector, sizeof(newTVector), offset); + + assert(tvectorPtr); // FIX-ME handle case where TOC blows up + + return (Uint8*)tvectorPtr; +} + + + diff --git a/ef/Compiler/CodeGenerator/md/ppc/PPC601AppleMacOSEmitter.h b/ef/Compiler/CodeGenerator/md/ppc/PPC601AppleMacOSEmitter.h new file mode 100644 index 000000000000..2feb5de83eae --- /dev/null +++ b/ef/Compiler/CodeGenerator/md/ppc/PPC601AppleMacOSEmitter.h @@ -0,0 +1,190 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +// PPC601AllMacOSEmitter.h +// +// Scott M. Silver +// + +#ifndef _H_PPC601AllMacOSEmitter +#define _H_PPC601AllMacOSEmitter + +#include "InstructionEmitter.h" +#include "VirtualRegister.h" +#include "Value.h" +#include "PPCInstructions.h" +#include "PPC601AppleMacOS_Support.h" + +#include "FormatStructures.h" // for FCI, StackFrameInfo + +/* FIX these have been moved to FormatStructures.h + +struct StackFrameInfo +{ + Uint8 GPR_words; + Uint8 FPR_words; + Uint32 localStore_bytes; + + // returns the offset into the stack frame of the beginning of the restore area + Uint32 getRestoreOffset() { return localStore_bytes; } +}; + +// struct FormattedCodeInfo; +*/ + +template class Call; + +class PPCEmitter : + public InstructionEmitter +{ + // these Call Instructions set "themselves" up, ie they call "useProducer" + friend class Call; + friend class Call; + friend class Call; + friend class Call; + friend class Call; + friend class MacDebugger; + + friend class PPCFormatter; // uses protected member variables for linkage, etc + +protected: + uint32 mMaxArgWords; // maximum words needed in call build area (accumulated) + uint32 mCrossTOCPtrGlCount; // number of ptr glue's needed (all are cross-toc now, even if not needed) + JitGlobals mAccumulatorTOC; // TOC which contains all the data extracted at emit time, transferred to actual TOC + // when formatting (we need to make sure we have a TOC which can contain all of the + // necessary data) + +public: + PPCEmitter(Pool& inPool, VirtualRegisterManager& inVrManager) : + InstructionEmitter(inPool, inVrManager), + mCrossTOCPtrGlCount(0), + mMaxArgWords(0) { } + + virtual void emitPrimitive(Primitive& inPrimitive, NamedRule inRule); + bool emitCopyAfter(DataNode& inDataNode, InstructionList::iterator where, VirtualRegister& fromVr, VirtualRegister& toVr); + void emitLoadAfter(DataNode& inDataNode, InstructionList::iterator where, VirtualRegister& loadedReg, VirtualRegister& stackReg); + void emitStoreAfter(DataNode& inDataNode, InstructionList::iterator where, VirtualRegister& storedReg, VirtualRegister& stackReg); + Instruction& emitAbsoluteBranch(DataNode& inDataNode, ControlNode& inTarget); + void emitArguments(ControlNode::BeginExtra& inBeginNode); + +private: + void emit_LimitR(Primitive& inPrimitive); + void emit_Limit(Primitive& inPrimitive, PPCInsnFlags inFlags); + void emit_Const_I(Primitive& inPrimitive); + void emit_Const_F(Primitive& inPrimitive); + void emit_Ld_IRegisterIndirect(Primitive& inPrimitive); + void emit_Add_I(Primitive& inPrimitive); + void emit_AddI_I(Primitive& inPrimitive); + + void emit_Div_I(Primitive& inPrimitive); + void emit_DivE_I(Primitive& inPrimitive); + void emit_DivI_I(Primitive& inPrimitive); + void emit_DivR_I(Primitive& inPrimitive); + void emit_DivRE_I(Primitive& inPrimitive); + void emit_DivU_I(Primitive& inPrimitive); + void emit_DivUE_I(Primitive& inPrimitive); + void emit_DivUI_I(Primitive& inPrimitive); + void emit_DivUR_I(Primitive& inPrimitive); + void emit_DivURE_I(Primitive& inPrimitive); + + void emit_Mod_I(Primitive& inPrimitive); + void emit_ModE_I(Primitive& inPrimitive); + + void emit_CmpI_I(Primitive& inPrimitive); + void emit_Cmp_I(Primitive& inPrimitive); + void emit_StI_I(Primitive& inPrimitive); + void emit_StI_IRegisterIndirect(Primitive& inPrimitive); + void emit_St_IRegisterIndirect(Primitive& inPrimitive); + void emit_ShlI_I(Primitive& inPrimitive); + void emit_Call(Primitive& inPrimitive); + void emit_Result_I(Primitive& inPrimitive); + void emit_Result_F(Primitive& inPrimitive); + + void genBranch(Primitive& inPrimitive, Condition2 cond); + void genLoadIZero(Primitive& inPrimitive, PPCInsnFlags inFlags); + void genArith_ID(Primitive& inPrimitive, DFormKind inKind, XFormKind inXKind); + void genArith_IX(Primitive& inPrimitive, XFormKind inKind); + void genArith_RD(Primitive& inPrimitive, DFormKind inKind, XFormKind inXKind, bool inIsUnsigned); + void genArithReversed_IX(Primitive& inPrimitive, XFormKind inKind); + void emit_SubR(Primitive& inPrimitive, bool inUnsigned); + void emit_SubI(Primitive& inPrimitive); + + void genThrowIfDivisorZero(Primitive& inPrimitive); + +protected: + VirtualRegister& genLoadConstant_I(DataNode& inPrimitive, Int32 inConstant); + VirtualRegister& genLoadConstant_F(DataNode& inPrimitive, Flt32 inConstant); +}; + +class PPCFormatter +{ +private: + StackFrameInfo mStackPolicy; + +protected: + void* mNextFreePostMethod; // next free block of memory following the method's epilog (valid after beginFormatting) + JitGlobals* mRealTOC; // contains this methods actual TOC (valid after beginFormatting) + Int16 mRealTOCOffset; // this is the "fix-up" added to an offset obtained from the accumulator TOC (valid after beginFormatting) + + uint8 mSaveGPRwords; // number of non-volatile GPR's used in the function (valid after calculatePrologEpilog) + uint8 mSaveFPRwords; // number of non-volatile FPR's used in the function (valid after calculatePrologEpilog) + uint32 mFrameSizeWords; // whole size of frame (valid after calculatePrologEpilog) + + // these Instructions need access to mNextFreePostMethod and the real TOC + friend class Call; + friend class Call; + friend class Call; + friend class Call; + friend class Call; + friend class MacDebugger; + + // Fix-up for real TOC + friend class LdD_RTOC; + +public: + const PPCEmitter& mEmitter; + + PPCFormatter(const MdEmitter& inEmitter) : + mEmitter(inEmitter) { } + + void calculatePrologEpilog(Method& inMethod, Uint32& outPrologSize, Uint32& outEpilogSize); + void formatEpilogToMemory(void* inWhere); + void formatPrologToMemory(void* inWhere); + + void beginFormatting(const FormattedCodeInfo& inInfo); + void endFormatting(const FormattedCodeInfo& /*inInfo*/) { } + void calculatePrePostMethod(Method& inMethod, Uint32& outPreMethodSize, Uint32& outPostMethodSize); + void formatPostMethodToMemory(void* inWhere, const FormattedCodeInfo& inInfo); + void formatPreMethodToMemory(void* /*inWhere*/, const FormattedCodeInfo& /*inInfo*/) { } + + void initStackFrameInfo() {} + + Uint8* createTransitionVector(const FormattedCodeInfo& /*inInfo*/); + + StackFrameInfo& getStackFrameInfo() {return mStackPolicy; } + +}; + +#ifdef DEBUG +void *disassemble1(LogModuleObject &f, void* inFrom); +#endif + +#endif // _H_PPC601AllMacOSEmitter + + + + diff --git a/ef/Compiler/CodeGenerator/md/ppc/PPC601AppleMacOS_Support.cpp b/ef/Compiler/CodeGenerator/md/ppc/PPC601AppleMacOS_Support.cpp new file mode 100644 index 000000000000..ed7ae8b6e873 --- /dev/null +++ b/ef/Compiler/CodeGenerator/md/ppc/PPC601AppleMacOS_Support.cpp @@ -0,0 +1,471 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +// PPC601AppleMacOS_Support.cpp. +// +// Scott M. Silver +// +// Support for the "Just-In-Time" part of the compiler +// Also a handful of routines for dealing with PowerPC linkage oddities (ptr gl, etc) + +#include "NativeCodeCache.h" +#include "NativeFormatter.h" +#include "PPC601AppleMacOS_Support.h" +#include "NativeFormatter.h" +#include "AssembledInstructions.h" +#include "JavaObject.h" + + +// All volatile registers +struct VolatileRegisters +{ + Uint32 r3; Uint32 r4; Uint32 r5; Uint32 r6; + Uint32 r7; Uint32 r8; Uint32 r9; Uint32 r10; + Flt64 fp0; Flt64 fp1; Flt64 fp2; Flt64 fp3; + Flt64 fp4; Flt64 fp5; Flt64 fp6; Flt64 fp7; + Flt64 fp8; Flt64 fp9; Flt64 fp10; Flt64 fp11; + Flt64 fp12; Flt64 fp13; Flt64 r31; +}; + +static void* +formatDynamicPtrGl(void* inStart, uint8 inRegister); + +static void +formatCompileStubPtrGl(void* inStart); + +asm static void +locate(); + +asm void +saveVolatiles(VolatileRegisters *vr); + +asm void +restoreVolatiles(VolatileRegisters *vr); + +const uint32 kDynamicPtrGlBytes = 20; // see formatDynamicPtrGl + +// formatDynamicPtrGl +// +// Output some pointer glue through register inRegister +// beginning at inStart in memory. We require that +// the size of the buffer be at least kDynamicPtrGlBytes +// long. This kind of pointer glue is used for +// dispatching v-table based (dynamic) calls. +static void* +formatDynamicPtrGl(void* inStart, Uint8 inRegister) +{ + Uint32* curPC = (Uint32*) inStart; + + *curPC++ = makeDForm(36, 2, 1, 20); // stw rtoc, 20(sp) + *curPC++ = makeDForm(32, 0, inRegister, 0); // lwz r0, 0(inRegister) + *curPC++ = makeDForm(32, 2, inRegister, 4); // lwz rtoc, 4(inRegister); + *curPC++ = kMtctrR0; // mtctr r0 + *curPC++ = kBctr; // bctr + return (curPC); +} + + +// formatCrossTocPtrGl +// +// Output cross-toc ptr gl beginning at inStart. +// Use inTOCOffset at the offset in the TOC to find +// the callee's TVector ptr. The buffer beginning at inStart +// must be at least kCrossTocPtrGlBytes long. +void* +formatCrossTocPtrGl(void* inStart, int16 inTOCOffset) +{ + uint32* curPC = (uint32*) inStart; + + *curPC++ = makeDForm(32, 12, 2, inTOCOffset); // lwz r12, offset(rtoc) + *curPC++ = makeDForm(36, 2, 1, 20); // stw rtoc, 20(sp) + *curPC++ = makeDForm(32, 0, 12, 0); // lwz r0, 0(r12) + *curPC++ = makeDForm(32, 2, 12, 4); // lwz rtoc, 4(r12); + *curPC++ = kMtctrR0; // mtctr r0 + *curPC++ = kBctr; // bctr + return (curPC); +} + + +const uint32 kCompileStubPtrGlBytes = 12; // see formatCompileStubPtrGl + +// formatCompileStubPtrGl +// +// Output a short stub beginng at inStart which loads +// the address of "locate" and jumps to it. The TOC must be set to +// the system's TOC before this routine is called (which is why a compile stub +// has a TVector with it's TOC set to the system TOC). inStart is +// assumbed to be a buffer of atleast kCompileStubPtrGlBytes. +static void +formatCompileStubPtrGl(void* inStart) +{ + uint32* curPC = (uint32*) inStart; + + // this is some cruft to locate the offset (from C) to locate's TVector + uint8* startTOC = ((uint8**) formatCompileStubPtrGl)[1]; // grab our TOC + uint8* compileStubFunction = (uint8*) locate; // grab &locate (which is ptr to TVector) + + *curPC++ = makeDForm(32, 0, 2, compileStubFunction - startTOC); // lwz r0, locate(RTOC) + *curPC++ = kMtctrR0; // mtctr r0 + *curPC++ = kBctr; // bctr +} + + +// DynamicPtrGlManager +// +// Manages a hunk of dynamic ptr gl +// FIX-ME synchronization +class DynamicPtrGlManager +{ +public: + enum + { + kFirstPossibleRegister = 4, // since r3 must be the this ptr and can never be used for dynamic dispatching + kLastPossibleRegister = 31, + kTotalPtrGls = kLastPossibleRegister - kFirstPossibleRegister + 1 + }; + + DynamicPtrGlManager() + { + void* allPtrGls = NativeCodeCache::getCache().acquireMemory(kTotalPtrGls * kDynamicPtrGlBytes); + mPtrGl = new void*[kTotalPtrGls]; + + void** curPtrGl = mPtrGl; + + for (int curReg = kFirstPossibleRegister; curReg < kLastPossibleRegister + 1; curReg++) + { + *curPtrGl++ = allPtrGls; + allPtrGls = formatDynamicPtrGl(allPtrGls, curReg); + } + } + + void * + getGl(void* DEBUG_ONLY(inFromWhere), Uint8 inWhichRegister) + { + #ifdef DEBUG + Int32 dummy; + #endif + + assert(inWhichRegister >= kFirstPossibleRegister && inWhichRegister <= kLastPossibleRegister); + + // FIX-ME allocate new ptr glues if this fails + assert(canBePCRelative(inFromWhere, mPtrGl[inWhichRegister - kFirstPossibleRegister], dummy)); + + return (mPtrGl[inWhichRegister - kFirstPossibleRegister]); + } + + + void** mPtrGl; +}; + +DynamicPtrGlManager sPtrGlueManager; + +void* getDynamicPtrGl(void* inFromWhere, Uint8 inWhichRegister) +{ + return (sPtrGlueManager.getGl(inFromWhere, inWhichRegister)); +} + + +// getCompileStubPtrGl +// +// Locate a compile stub ptr gl withing pc-relative range of inFromWhere +// If one does not exist, create one. Assume that the newly created +// one will be in range. We also assume we will be reusing this often +// due to (hopefully) monotonically increasing addresses of new blocks +// of memory. FIX-ME? +// +// sMostRecentCompileStubPtrGl is maintained such that it is a single +// entry cache for the last CompileStubPtrGl we generated. +// +// A compileStubPtrGl is a sequence of instructions which jumps to +// the "locate" function which, in some way, locates/compiles/loads, etc +// a currently uncompiled method. +void* getCompileStubPtrGl(void* inFromWhere) +{ + Int32 dummyOffset; + static void* sMostRecentCompileStubPtrGl = NULL; // This is a global! + + // make a new ptr glue for the compile stub + if ((sMostRecentCompileStubPtrGl == NULL) || (!canBePCRelative(inFromWhere, sMostRecentCompileStubPtrGl, dummyOffset))) + { + void* newPtrGl = NativeCodeCache::getCache().acquireMemory(kCompileStubPtrGlBytes); + formatCompileStubPtrGl(newPtrGl); + sMostRecentCompileStubPtrGl = newPtrGl; + } + + // assert that we actually succeeded in our goal, this really + // should result in programattic failure (abort, etc) + bool compileStubAssertion = canBePCRelative(inFromWhere, sMostRecentCompileStubPtrGl, dummyOffset); + assert(compileStubAssertion); + + return (sMostRecentCompileStubPtrGl); +} + + +// _MD_createTVector +// +// Create a "transition vector" a two word entry containing a ptr to inFunctionMemory +// (the beginning of a compiled function) and a second word containing the environment +// or TOC pointer...currently we always use the system TOC. All other TVector's should +// be acquired from the Formatter objects. +void* _MD_createTVector(const MethodDescriptor& /*inMethodDescriptor*/, void* inFunctionMemory) +{ + TVector* newTVector = (TVector*) NativeCodeCache::getCache().acquireMemory(sizeof(TVector)); + newTVector->functionPtr = inFunctionMemory; + newTVector->toc = *((void**)_MD_createTVector + 1); + + return (newTVector); +} + + +// BackPatchInfo +// +// little structure used to communicate between the assembly +// stub and the actual compilation and backpatching of the caller +struct BackPatchInfo +{ + void** callerTOC; // caller's TOC + JavaObject* thisPtr; // callee this ptr (if a dynamic dispatch, otherwise undefined) +}; + + +// backPatchMethod +// +// Cause the caller to call inMethodAddress next time the call instruction +// is encountered (instead of going through the stub). inLastPC is the next +// PC to be executed upon return from the intended callee (just after the call +// instruction. inUserData is assumed to point to a BackPatchInfo*. (above) +// +// The trick is, that this has to be atomic. That is, atomic from the standpoint +// that any thread entering the caller must not crash, but it would be ok for the +// thread to end up in the compile stub. +// +// For backpatching vtables, we call a routine on the method object which +// does all our dirty work. (It's non-trivial since the same method can occupy +// different positions in a vtable due to interfaces). +// We do the work for static dispatches. Our strategy is to try to use the cheapest +// call-like instruction. See the "General Idea" section at the top of this file +// for details of this strategy. +void* backPatchMethod(void* inMethodAddress, void* inLastPC, void* inUserData) +{ + TVector* methodTVector = (TVector*) inMethodAddress; + Uint32* nopOrRestoreToc = (Uint32*) inLastPC; + BackPatchInfo* backPatchInfo = (BackPatchInfo*) inUserData; + + // find bl + Uint32* blToPtrGlue = nopOrRestoreToc - 1; + assert ((*blToPtrGlue & kBl) == kBl); + + // see where the destination of this bl -- it must be some kind of ptrgl + Int16 offsetToPtrGlue = (Int16) (*blToPtrGlue & 0x000FFFC); + Uint32* ptrGlue = (Uint32*) (((Uint8*) (nopOrRestoreToc - 1)) + offsetToPtrGlue); + + if (*ptrGlue == makeDForm(36, 2, 1, 20)) // stw rtoc, 20(sp) + { + // dynamic call + Uint32* dynamicLookup = blToPtrGlue - 1; + + assert ((*dynamicLookup & makeDForm(32, 0, 0, 0)) == makeDForm(32, 0, 0, 0)); // lwz r?, offset(rtoc) + Int16 vtableOffset = *dynamicLookup & 0xFFFF; // grab offset in table + + // replace value in vtable + ((void**)&backPatchInfo->thisPtr->type)[vtableOffset >> 2] = inMethodAddress; + } + else + { + // static call + assert ((*ptrGlue & makeDForm(32, 12, 2, 0)) == makeDForm(32, 12, 2, 0)); // lwz r12, offset(rtoc) + + Int32 offsetToCallee; + bool sameTOC = (backPatchInfo->callerTOC == methodTVector->toc); + + // first try an absolute branch + // then try a pc-relative branch + // last use the ptr glue (just change the entry in the TOC) + if (sameTOC && (Uint32) methodTVector->functionPtr < 0x3FFFFFF) + { + *blToPtrGlue = kBla | ( (Uint32) methodTVector->functionPtr & 0x03FFFFFF); + blToPtrGlue[1] = kNop; + } + else if (sameTOC && canBePCRelative(blToPtrGlue, methodTVector->functionPtr, offsetToCallee)) + { + *blToPtrGlue = (kBl | offsetToCallee); // change bl to branch directly to callee + blToPtrGlue[1] = kNop; // don't restore toc, same toc + } + else + { + Int16 tocOffset = *ptrGlue & 0xFFFF; // grab offset in table + + backPatchInfo->callerTOC[tocOffset] = inMethodAddress; // now change the ptr in the table + } + } + + + return (inMethodAddress); +} + + +// locate +// +// Assembly glue called by the locateStub to actually locate/compile/etc a +// method and back patch the caller. We save all volatiles (and +// of course save non-volatiles if we use them), fill in a BackPatchInfo +// object, and hand off control to compileAndBackPatchMethod. Upon return +// we restore volatiles, fix up the stack (so it appears we were at the +// callsite in the caller), and jump to the intended callee (returned by +// compileAndBackPatchMethod). +// +// Only one parameter is assumed, r11 = ptr to CacheEntry of method to be located. +// We chose r11 because it is volatile, but not used by any ptr-gl generated by +// the Metrowerks Compilers. We may have to do something slightly different for +// AIX. We may just push the cacheEntry on the stack in the stub, and fix up +// the stack in here. +// +// Currently we only "locate" methods by compilation +asm static void locate() +{ + register CacheEntry* cacheEntry; + register void* oldLR; + register TVector* compiledMethod; + BackPatchInfo backPatchInfo; + VolatileRegisters volatileRegisters; + + fralloc + mr cacheEntry, r11 // save r11 somewhere else, in case we end up in ptrgl somewhere + mflr oldLR + + // save off volatiles + stw r3, backPatchInfo.thisPtr // r3 is saved in backPatchInfo (it is the thisPtr sometimes) + la r3, volatileRegisters // save rest of volatiles + bl saveVolatiles + + // fill in the rest of backPatchInfo + lwz r5, 260(SP) // caller's RTOC (260 is a special constant, dependent on amt of stack space used in this function) + stw r5, backPatchInfo.callerTOC + + // compileAndBackPatch + mr r3, cacheEntry + mr r4, oldLR + la r5, backPatchInfo + bl compileAndBackPatchMethod // r3 = TVector to actual method + mr compiledMethod, r3 // compiledMethod = TVector to actual method + + // restore volatiles + la r3, volatileRegisters + bl restoreVolatiles + lwz r3, backPatchInfo.thisPtr // restore r3 + + // jmp to the real callee + lwz r0, compiledMethod->functionPtr // r0 = ptr to method + lwz RTOC, compiledMethod->toc // RTOC = toc of compiled method + mtctr r0 // ctr = ptr to method + frfree + bctr +} + + +// saveVolatiles +// +// Save all non-volatiles except r3 (because it is used for the incoming parameter) +asm void saveVolatiles(register VolatileRegisters *vr) +{ +// stw r3, vr->r3 + stfd fp0, vr->fp0 + stw r4, vr->r4 + stfd fp1, vr->fp1 + stw r5, vr->r5 + stfd fp2, vr->fp2 + stw r6, vr->r6 + stfd fp3, vr->fp3 + stw r7, vr->r7 + stfd fp4, vr->fp4 + stw r8, vr->r8 + stfd fp5, vr->fp5 + stw r9, vr->r9 + stfd fp6, vr->fp6 + stw r10, vr->r10 + stfd fp7, vr->fp7 + stfd fp8, vr->fp8 + stfd fp9, vr->fp9 + stfd fp10, vr->fp10 + stfd fp11, vr->fp11 + stfd fp12, vr->fp12 + stfd fp13, vr->fp13 + blr +} + +// restoreVolatiles +// +// Restore all non-volatiles except r3 (because it is used for the incoming parameter) +asm void restoreVolatiles(register VolatileRegisters *vr) +{ +// lwz r3, vr->r3 + lfd fp0, vr->fp0 + lwz r4, vr->r4 + lfd fp1, vr->fp1 + lwz r5, vr->r5 + lfd fp2, vr->fp2 + lwz r6, vr->r6 + lfd fp3, vr->fp3 + lwz r7, vr->r7 + lfd fp4, vr->fp4 + lwz r8, vr->r8 + lfd fp5, vr->fp5 + lwz r9, vr->r9 + lfd fp6, vr->fp6 + lwz r10, vr->r10 + lfd fp7, vr->fp7 + lfd fp8, vr->fp8 + lfd fp9, vr->fp9 + lfd fp10, vr->fp10 + lfd fp11, vr->fp11 + lfd fp12, vr->fp12 + lfd fp13, vr->fp13 + blr +} + + +void * +generateNativeStub(NativeCodeCache& /*inCache*/, const CacheEntry& /*inCacheEntry*/, void * /*nativeFunction*/) +{ + trespass("Not implemented"); + return 0; +} + + +// generateCompileStub +// +// Genereate a kLocateStubBytes stub from memory acquired fromn inCache. +// The branches to some ptr-gl which jumps to the actual "locate" routine. +// It is assumed that there is already a reachable compileStubPtrGl, or one +// can be created by calling getCompileStubPtrGl. +extern void* +generateCompileStub(NativeCodeCache& inCache, const CacheEntry& inCacheEntry) +{ + const size_t kLocateStubBytes = 12; + + Uint32* stub = (Uint32*) inCache.acquireMemory(kLocateStubBytes); + Uint32* curPC = stub; + + *curPC++ = makeDForm(15, 11, 0, ((Uint32) &inCacheEntry) >> 16); // addis r11, r0, hiword + *curPC++ = makeDForm(24, 11, 11, ((Uint32) &inCacheEntry) & 0xFFFF); // ori r11, r11, loword + *curPC = (kB | (((PRUptrdiff) getCompileStubPtrGl(curPC) - (PRUptrdiff) curPC) & 0x03FFFFFF)); // b compileStubPtrGl + + return (_MD_createTVector(inCacheEntry.descriptor, stub)); +} + + + diff --git a/ef/Compiler/CodeGenerator/md/ppc/PPC601AppleMacOS_Support.h b/ef/Compiler/CodeGenerator/md/ppc/PPC601AppleMacOS_Support.h new file mode 100644 index 000000000000..e5e6b63e2df7 --- /dev/null +++ b/ef/Compiler/CodeGenerator/md/ppc/PPC601AppleMacOS_Support.h @@ -0,0 +1,163 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +// PPC601AppleMacOS_Support.h +// +// Scott M. Silver + +#ifndef _H_PPC601APPLEMACOS_SUPPORT +#define _H_PPC601APPLEMACOS_SUPPORT +#include + +void* getDynamicPtrGl(void* inFromWhere, Uint8 inWhichRegister); + +// JitGlobals +// +// Maintains a table of size 2^16 +// 16 bit signed offsets are used to load data out of the table +// The gp (or rtoc), therefore, points to the middle of the table +class JitGlobals +{ +public: + enum + { + kTOCSize = 0x10000 + }; + + JitGlobals() + { + mBegin = (const Uint8*) new Uint8[kTOCSize]; + mGlobalPtr = (const Uint8*) mBegin + (kTOCSize >> 1); + mEnd = (const Uint8*) mBegin + kTOCSize; + mNext = (Uint8*) mBegin; + } + + ~JitGlobals() + { + delete mBegin; + } + +public: + // addData + // Add data beginning at inData of size inSize + // to the JitGlobals. Returns the address of the + // copied data in JG or NULL if the globals are full. + // outOffset is the offset in the table where the data + // was added + void* addData(const void* inData, Uint16 inSize, Uint16 &outOffset) + { + // ¥¥ FIX-ME BEGIN LOCK + Uint16 alignedSize = (inSize + 3) & ~3; // align to 4 bytes + + Uint8* dest = mNext; + + // make sure we didn't overflow the tbl + if (mNext + alignedSize > mEnd) + return (NULL); + + // copy data and return offset into table + memcpy(dest, inData, inSize); + outOffset = dest - mGlobalPtr; + mNext += alignedSize; + + return (dest); + // ¥¥ÊFIX-ME END LOCK + } + + // toOffset + // Returnns true if inData is in JG. outOffset + // is the offset to the data if its in the table. + bool toOffset(void* inData, Uint16& outOffset) + { + if (inData >= (void*)mBegin && inData < (void*)mNext) + { + outOffset = (Uint8*) inData - mBegin; + return (true); + } + else + return (false); + } + + // unsafe, only use if you are the only thread + // who will be touching this table + inline Uint8* getNext() const { return mNext; } + +public: + const Uint8* mBegin; // beginning of table + const Uint8* mEnd; // end of table + const Uint8* mGlobalPtr; // what the "global ptr" should point to +private: + Uint8* mNext; // next free entry in table +}; + +struct TVector +{ + void* functionPtr; + void* toc; +}; + +extern JitGlobals gJitGlobals; + +//bool canBePCRelative(void* inStart, void* inDest, Int32& outOffset); + + +// canBePCRelative +// +inline bool canBePCRelative(void* inStart, void* inDest, Int32& outOffset) +{ + outOffset = (PRUptrdiff) inDest - (PRUptrdiff) inStart; + + if (inDest > inStart) + return (outOffset < 0x1ffffff); + else + return (outOffset > (Int32) 0xfe000000); +} + +extern JitGlobals& +acquireTOC(Uint16 inDesiredAmount); + +void* getCompileStubPtrGl(void* inFromWhere); +const uint32 kCrossTocPtrGlBytes = 24; + +void* formatCrossTocPtrGl(void* inStart, int16 inTOCOffset); + +#ifndef XP_MAC +inline void* getDynamicPtrGl(void* /* inFromWhere */, Uint8 /* inWhichRegister */) +{ + return NULL; +} +inline void* formatCrossTocPtrGl(void* /* inStart */, int16 /* inTOCOffset */) +{ + return NULL; +} +#endif + +// acquireTOC +// +// Try to find a TOC with enough space left in it to fit a desired amount. +// If one cannot be located, create a new TOC and return that. +// +// FIX-ME - right now we only support one TOC +inline JitGlobals& +acquireTOC(Uint16 /*inDesiredAmount*/) +{ + static JitGlobals sJitGlobals; // This is a global + + return (sJitGlobals); +} + +#endif // _H_PPC601APPLEMACOS_SUPPORT diff --git a/ef/Compiler/CodeGenerator/md/ppc/PPC601Cpu.h b/ef/Compiler/CodeGenerator/md/ppc/PPC601Cpu.h new file mode 100644 index 000000000000..2b898784dc73 --- /dev/null +++ b/ef/Compiler/CodeGenerator/md/ppc/PPC601Cpu.h @@ -0,0 +1,48 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#if !defined(_PPC601_CPU_H_) || defined(INCLUDE_EMITTER) +#define _PPC601_CPU_H_ + +#define FIRST_CALLER_SAVED_GR 0 +#define LAST_CALLER_SAVED_GR 9 +#define FIRST_CALLEE_SAVED_GR 10 +#define LAST_CALLEE_SAVED_GR 28 +#define FIRST_CALLER_SAVED_FPR 0 +#define LAST_CALLER_SAVED_FPR 9 +#define FIRST_CALLEE_SAVED_FPR 10 +#define LAST_CALLEE_SAVED_FPR 28 + +#define FIRST_GREGISTER 0 +#define LAST_GREGISTER 28 +#define FIRST_FPREGISTER 0 +#define LAST_FPREGISTER 28 +#define NUMBER_OF_SPECIAL_REGISTERS 0 + +class PPCEmitter; +class PPCFormatter; +typedef PPCFormatter MdFormatter; +typedef PPCEmitter MdEmitter; + +#ifdef INCLUDE_EMITTER +#include "PPC601AppleMacOSEmitter.h" +#endif + +#define CPU_IS_SUPPORTED + +#endif /* _PPC601_CPU_H_ */ diff --git a/ef/Compiler/CodeGenerator/md/ppc/PPCCalls.h b/ef/Compiler/CodeGenerator/md/ppc/PPCCalls.h new file mode 100644 index 000000000000..670a9a31b544 --- /dev/null +++ b/ef/Compiler/CodeGenerator/md/ppc/PPCCalls.h @@ -0,0 +1,313 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +// PPCCalls.h +// +// Scott M. Silver +// + +#ifndef _H_PPCCALLS +#define _H_PPCCALLS + +#include "PPC601AppleMacOSEmitter.h" +#include "AssembledInstructions.h" + +template +class Call : + public PPCInstructionXY +{ +public: + static inline bool hasReturnValue(DataNode& inDataNode); // determines whether Call Primitive has return value + static inline uint8 numberOfArguments(DataNode& inDataNode); // determines number of real arguments (not including store) + + Call(DataNode* inDataNode, Pool& inPool, uint8 inRegisterArguments, bool inHasReturnValue, PPCEmitter& inEmitter, void* inFunc = NULL); + + virtual void formatToMemory(void* inStart, Uint32 inOffset, MdFormatter& inFormatter); + virtual size_t getFormattedSize(MdFormatter& /*inFormatter*/) { return (8); } + virtual InstructionFlags getFlags() const { return (ifCall); } + + +protected: + int16 mTOCOffset; // offset in accumulator TOC + TVector* mCalleeAddress; // addres of cuntion + +#ifdef DEBUG +public: + virtual void printPretty(FILE* f) { fprintf(f, "call %X", mCalleeAddress); } +#endif +}; + + +template +class CallS : + public Call +{ +public: + inline CallS(DataNode* inDataNode, Pool& inPool, uint8 inRegisterArguments, bool inHasReturnValue, PPCEmitter& inEmitter, void* inFunc) : + Call(inDataNode, inPool, inRegisterArguments, inHasReturnValue, inEmitter, inFunc) { } +}; + +#ifdef MANUAL_TEMPLATES +template class Call; +template class Call; +template class Call; +template class Call; +template class Call; +#endif + +typedef CallS CallS_V; +typedef CallS CallS_; +typedef CallS CallS_C; +typedef Call Call_; + + +// Dynamically dispatched call +class CallD_ : + public Call +{ +public: + inline CallD_(DataNode* inDataNode, Pool& inPool, uint8 inRegisterArguments, bool inHasReturnValue, PPCEmitter& inEmitter) : + Call(inDataNode, inPool, inRegisterArguments, inHasReturnValue, inEmitter) { } + + void formatToMemory(void* inStart, Uint32 /*inOffset*/, MdFormatter& inFormatter); +}; + + +template bool +Call:: +hasReturnValue(DataNode& inDataNode) +{ + bool hasReturnValue = (inDataNode.getOutgoingEdgesBegin() + tHasOutgoingStore < inDataNode.getOutgoingEdgesEnd()); + + return (hasReturnValue); +} + +template uint8 +Call:: +numberOfArguments(DataNode& inDataNode) +{ + DataConsumer* firstArg; + DataConsumer* lastArg; + + assert(!(tHasFunctionAddress && !tHasIncomingStore)); // no such primitive + firstArg = inDataNode.getInputsBegin() + tHasFunctionAddress + tHasIncomingStore; + lastArg = inDataNode.getInputsEnd(); + + return (lastArg - firstArg); +} + + +// -> mem regarg1 regarg2 regarg3 regarg3 +// <- mem [returnval] +template +Call:: +Call(DataNode* inDataNode, Pool& inPool, uint8 inRegisterArguments, bool /*inHasReturnValue*/, PPCEmitter& inEmitter, void* inFunc) : + PPCInstructionXY(inDataNode, inPool, inRegisterArguments + tHasIncomingStore + tIsDynamic, 1 + tHasOutgoingStore) +{ + if (!tIsDynamic) + inEmitter.mCrossTOCPtrGlCount++; + + const DoublyLinkedList& projectionConsumers = inDataNode->getConsumers(); + DoublyLinkedList::iterator curProjectionEdge = projectionConsumers.begin(); + DataNode* returnValProducer; + + // outgoing store + if (tHasOutgoingStore) + { + DataNode& projectionA = projectionConsumers.get(curProjectionEdge).getNode(); + DataNode* projectionB = (projectionConsumers.done(curProjectionEdge = projectionConsumers.advance(curProjectionEdge))) ? 0 : &projectionConsumers.get(curProjectionEdge).getNode(); + + if (projectionA.hasKind(vkMemory)) + { + inEmitter.defineProducer(projectionA, *this, 0); // -> mem + returnValProducer = projectionB; + } + else + { + assert(projectionB); // projectionB must be the memory producer + inEmitter.defineProducer(*projectionB, *this, 0); // -> mem + returnValProducer = &projectionA; + } + } + else + returnValProducer = (projectionConsumers.done(curProjectionEdge = projectionConsumers.advance(curProjectionEdge))) ? 0 : &projectionConsumers.get(curProjectionEdge).getNode(); + + if (returnValProducer) + { + VirtualRegister* returnValVR; + + // the Call defines a temporary register, which is precolored to + // the appropriate return register + returnValVR = &inEmitter.defineTemporary(*this, 1); + + switch (returnValProducer->getKind()) + { + case vkInt: case vkAddr: + { + returnValVR->preColorRegister(kR3Color); + + // now create a "buffer" copy between the precolored return register + // and make the Copy define the return value edge from the pkCall + Copy_I& copyInsn = *new(inPool) Copy_I(inDataNode, inPool); + inEmitter.useTemporaryVR(copyInsn, *returnValVR, 0); + inEmitter.defineProducer(*returnValProducer, copyInsn, 0); + break; + } + case vkLong: + assert(false); + break; + case vkFloat: case vkDouble: + assert(false); + break; + default: + assert(false); + } + } + else + getInstructionDefineBegin()[1].kind = udNone; // zero out the unused outgoing edge + + DataConsumer* firstArgument; + DataConsumer* curArgument; + + // incoming store + if (tHasIncomingStore) + inEmitter.useProducer(inDataNode->nthInputVariable(0), *this, 0); // -> mem + + firstArgument = inDataNode->getInputsBegin() + tHasFunctionAddress + tHasIncomingStore; + + if (tHasFunctionAddress) + { + assert(inFunc == NULL); // programmer error to specify a function address if this Call has a function address + + if (tIsDynamic) + inEmitter.useProducer(inDataNode->nthInputVariable(1), *this, 1); // -> incoming address + else + mCalleeAddress = (TVector*) addressFunction(PrimConst::cast(inDataNode->nthInputVariable(1)).value.a); + } + else + mCalleeAddress = (TVector*) inFunc; + + inEmitter.mAccumulatorTOC.addData(&mCalleeAddress, sizeof(TVector), mTOCOffset); + + // move all arguments <= 8 words into registers, handle most of the stack passed arguments later + uint8 curFixedArg = 0; // number of words passes as fixed arguments + uint8 curFloatArg = 0; // number of words passed as float arguments + uint8 curTotalArgNumber = tHasIncomingStore + tIsDynamic; // use number, which starts at 1 after the store, if it exists + + for (curArgument = firstArgument; curArgument < inDataNode->getInputsEnd(); curArgument++, curTotalArgNumber++) + { + VirtualRegister* vr; + + switch (curArgument->getKind()) + { + case vkInt: + case vkAddr: + if (curFixedArg <= 8) + { + if (curArgument->isConstant()) + vr = &inEmitter.genLoadConstant_I(*inDataNode, curArgument->getConstant().i); + else + { + Copy_I& copyInsn = *new(inPool) Copy_I(inDataNode, inPool); + + inEmitter.useProducer(curArgument->getVariable(), copyInsn, 0); + vr = &inEmitter.defineTemporary(copyInsn, 0); + } + + inEmitter.useTemporaryVR(*this, *vr, curTotalArgNumber); + vr->preColorRegister(curFixedArg); + } + else + { + StD_FixedDestRegister& storeParam = *new(inPool) StD_FixedDestRegister(inDataNode, inPool, dfLwz, 24 + (curFixedArg + curFloatArg) * 4); + + if (curArgument->isConstant()) + { + VirtualRegister& vr = inEmitter.genLoadConstant_I(*inDataNode, curArgument->getConstant().i); + inEmitter.useTemporaryVR(storeParam, vr, 1); + } + else + inEmitter.useProducer(curArgument->getVariable(), storeParam, 1); + + // have the store use the incoming store edge, and define a temporary outgoing edge + // make the call depend on this temporary outgoing store edge + inEmitter.useProducer(inDataNode->nthInputVariable(0), storeParam, 0); + inEmitter.useTemporaryOrder(*this, inEmitter.defineTemporaryOrder(storeParam, 0), curTotalArgNumber); + } + curFixedArg++; + break; + case vkFloat: + case vkDouble: + if (curFloatArg <= 13) + vr->preColorRegister(curFloatArg++); + else + assert(false); + break; + case vkLong: + assert(false); + break; + default: + assert(false); + } + } + + // keep track of maximum words used + inEmitter.mMaxArgWords = PR_MAX(inEmitter.mMaxArgWords, curFixedArg + curFloatArg); +} + + +template +void Call:: +formatToMemory(void* inStart, Uint32 /*inOffset*/, MdFormatter& inFormatter) +{ + assert(!tIsDynamic); + + uint32 *curPC = curPC = (uint32 *) inStart; + int32 branchOffset; + bool sameTOC = (mCalleeAddress->toc == inFormatter.mRealTOC->mGlobalPtr); + bool isStub = true; // callee is stub + + if (!isStub && sameTOC && (uint32) mCalleeAddress->functionPtr < 0x3FFFFFF) + { + *curPC++ = kBla | ( (uint32) mCalleeAddress->functionPtr & 0x03FFFFFF); + *curPC++ = kNop; + } + else if (!isStub && sameTOC && canBePCRelative(inStart, (void*) mCalleeAddress, branchOffset)) + { + *curPC++ = kBl | (branchOffset & 0x03FFFFFF); + *curPC++ = kNop; + } + else + { + // we can or the offset right into the bl instruction (because aa and lk nicely use the last 2 bits) + *curPC++ = kBl | (((uint32) inFormatter.mNextFreePostMethod - (uint32)inStart) & 0x03FFFFFF); + + inFormatter.mNextFreePostMethod = (uint32*) formatCrossTocPtrGl(inFormatter.mNextFreePostMethod, mTOCOffset + inFormatter.mRealTOCOffset); + *curPC++ = makeDForm(32, 2, 1, 20); // stw rtoc, 20(sp) + } +} + +inline void CallD_:: +formatToMemory(void* inStart, Uint32 /*inOffset*/, MdFormatter& /*inFormatter*/) +{ + uint32 *curPC = (uint32 *) inStart; + + *curPC++ = kBl | (((uint32) getDynamicPtrGl(inStart, udToRegisterNumber(getInstructionUseBegin()[1])) - (uint32) inStart) & 0x03FFFFFF); + *curPC++ = makeDForm(32, 2, 1, 20); // stw rtoc, 20(sp) +} + +#endif // _H_PPCCALLS diff --git a/ef/Compiler/CodeGenerator/md/ppc/PPCInstructionTemplates.h b/ef/Compiler/CodeGenerator/md/ppc/PPCInstructionTemplates.h new file mode 100644 index 000000000000..44d041edf0b4 --- /dev/null +++ b/ef/Compiler/CodeGenerator/md/ppc/PPCInstructionTemplates.h @@ -0,0 +1,168 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +// PPCInstructionTemplates.h +// +// Scott M. Silver + +// enum name +// opcode +// string +#ifdef DO_DFORM +DFORM_ARITH_DEFINE(Addi, 14) +DFORM_ARITH_DEFINE(Addis, 15) +DFORM_ARITH_DEFINE(Mulli, 7) +DFORM_ARITH_DEFINE(Ori, 24) +DFORM_ARITH_DEFINE(Oris, 25) +DFORM_ARITH_DEFINE(Subfic, 8) +DFORM_ARITH_DEFINE(Xori, 26) +DFORM_ARITH_DEFINE(Xoris, 27) + +DFORM_ARITHCC_DEFINE(Addic, 13) +DFORM_ARITHCC_DEFINE(Andi, 28) +DFORM_ARITHCC_DEFINE(Andis, 29) + +DFORM_LOAD_DEFINE(Lbz, 34) +DFORM_LOAD_DEFINE(Lfd, 50) +DFORM_LOAD_DEFINE(Lfs, 48) +DFORM_LOAD_DEFINE(Lha, 42) +DFORM_LOAD_DEFINE(Lhz, 40) +DFORM_LOAD_DEFINE(Lwz, 32) + +DFORM_LOADU_DEFINE(Lbzu, 35) +DFORM_LOADU_DEFINE(Lfdu, 51) +DFORM_LOADU_DEFINE(Lfsu, 49) +DFORM_LOADU_DEFINE(Lhau, 43) +DFORM_LOADU_DEFINE(Lhzu, 41) +DFORM_LOADU_DEFINE(Lwzu, 33) + + +DFORM_STORE_DEFINE(Stb, 38) +DFORM_STORE_DEFINE(Stfd, 54) +DFORM_STORE_DEFINE(Stfs, 52) +DFORM_STORE_DEFINE(Sth, 44) +DFORM_STORE_DEFINE(Stw, 36) + +DFORM_STOREU_DEFINE(Stu, 39) +DFORM_STOREU_DEFINE(Stfdu, 55) +DFORM_STOREU_DEFINE(Stfsu, 53) +DFORM_STOREU_DEFINE(Sthu, 45) +DFORM_STOREU_DEFINE(Stwu, 37) + +DFORM_ARITH_DEFINE(Cmpi, 11) +DFORM_ARITH_DEFINE(Cmpli, 10) + +DFORM_TRAP_DEFINE(Twi, 3) +#endif + +#ifdef DO_XFORM +XFORM_ARITH_DEFINE(Add, 266, 31) +XFORM_ARITH_DEFINE(Addc, 10, 31) +XFORM_ARITH_DEFINE(Adde, 138, 31) +XFORM_ARITH_DEFINE(Divw, 459, 31) +XFORM_ARITH_DEFINE(Divwu, 138, 31) +XFORM_ARITH_DEFINE(Mulhw, 75, 31) +XFORM_ARITH_DEFINE(Mulhwu, 11, 31) +XFORM_ARITH_DEFINE(Mullw, 235, 31) +XFORM_ARITH_DEFINE(Subf, 40, 31) +XFORM_ARITH_DEFINE(Subfc, 8, 31) +XFORM_ARITH_DEFINE(Subfe, 136, 31) + +XFORM_INAONLY_DEFINE(Addme, 234, 31) +XFORM_INAONLY_DEFINE(Addze, 202, 31) +XFORM_INAONLY_DEFINE(Neg, 104, 31) +XFORM_INAONLY_DEFINE(Subfme, 232, 31) +XFORM_INAONLY_DEFINE(Subfze, 200, 31) + +XFORM_INAONLY_DEFINE(Srawi, 824-512, 31) + +XFORM_ARITH_DEFINE(And, 138, 31) +XFORM_ARITH_DEFINE(Andc, 75, 31) +XFORM_ARITH_DEFINE(Eqv, 284, 31) +XFORM_ARITH_DEFINE(Nand, 476, 31) +XFORM_ARITH_DEFINE(Nor, 124, 31) +XFORM_ARITH_DEFINE(Or, 444, 31) +XFORM_ARITH_DEFINE(Orc, 412, 31) +XFORM_ARITH_DEFINE(Slw, 24, 31) +XFORM_ARITH_DEFINE(Sraw, 792, 31) // FIX-ME prob isn't correct +XFORM_ARITH_DEFINE(Srw, 536, 31) // FIX-ME prob isn't corect +XFORM_ARITH_DEFINE(Xor, 316, 31) + +XFORM_CMP_DEFINE(Cmp, 0, 31) +XFORM_CMP_DEFINE(Cmpl, 32, 31) + +XFORM_CMP_DEFINE(Fcmpo, 0, 63) +XFORM_CMP_DEFINE(Fcmpu, 32, 63) + +XFORM_LOAD_DEFINE(Lbzx, 87, 31) +XFORM_LOAD_DEFINE(Lfdx, 599, 31) // FIX-ME prob isn't corect +XFORM_LOAD_DEFINE(Lfsx, 535, 31) +XFORM_LOAD_DEFINE(Lhax, 343, 31) +XFORM_LOAD_DEFINE(Lhbrx, 790, 31) // FIX-ME prob isn't corect +XFORM_LOAD_DEFINE(Lhzx, 279, 31) +XFORM_LOAD_DEFINE(Lwarx, 20, 31) +XFORM_LOAD_DEFINE(Lwbrx, 534, 31) // FIX-ME prob isn't corect +XFORM_LOAD_DEFINE(Lwzx, 23, 31) + +XFORM_LOADU_DEFINE(Lbzux, 119, 31) +XFORM_LOADU_DEFINE(Lfdux, 631, 31) // FIX-ME prob isn't corect +XFORM_LOADU_DEFINE(Lfsux, 567, 31) // FIX-ME prob isn't corect +XFORM_LOADU_DEFINE(Lhaux, 375, 31) +XFORM_LOADU_DEFINE(Lhzux, 311, 31) +XFORM_LOADU_DEFINE(Lwzux, 55, 31) + +XFORM_STORE_DEFINE(Stbx, 215, 31) +XFORM_STORE_DEFINE(Stfdx, 727, 31) // FIX-ME prob isn't corect +XFORM_STORE_DEFINE(Stfsx, 663, 31) // FIX-ME prob isn't corect +XFORM_STORE_DEFINE(Sthbrx, 918, 31) // FIX-ME prob isn't corect +XFORM_STORE_DEFINE(Sthx, 407, 31) +XFORM_STORE_DEFINE(Stwbrx, 662, 31) // FIX-ME prob isn't corect +XFORM_STORE_DEFINE(Stwx, 151, 31) + +XFORM_STOREU_DEFINE(Stbux, 247, 31) +XFORM_STOREU_DEFINE(Stfdux, 759, 31) // FIX-ME prob isn't corect +XFORM_STOREU_DEFINE(Stfsux, 695, 31) // FIX-ME prob isn't corect +XFORM_STOREU_DEFINE(Sthux, 439, 31) +XFORM_STOREU_DEFINE(Stwux, 183, 31) + +/* X Form - TrapWord */ +XFORM_TRAP_DEFINE(Tw, 4, 31) + +/* X Form - XInBOnly */ +XFORM_INBONLY_DEFINE(Fabs, 264, 63) +XFORM_INBONLY_DEFINE(Fctiw, 14, 63) +XFORM_INBONLY_DEFINE(Fctiwz, 15, 63) +XFORM_INBONLY_DEFINE(Fmr, 72, 63) +XFORM_INBONLY_DEFINE(Fnabs, 136, 63) +XFORM_INBONLY_DEFINE(Fneg, 40, 63) +XFORM_INBONLY_DEFINE(Frsp, 12, 63) + +#endif + +#ifdef DO_MFORM +MFORM_DEFINE(Rlwimi, 20) +MFORM_DEFINE(Rlwinm, 21) +MFORM_DEFINE(Rlwnm, 23) +#endif + +#ifdef DO_AFORM +// name, opcode, xo, has A (ie A != 0), has B, hasC, sets CC (ie Rc) + + +AFORM_DEFINE(Fadd, 63, 21, true, true, false, false) +AFORM_DEFINE(FaddC, 63, 21, true, true, false, true) +#endif DO_AFORM diff --git a/ef/Compiler/CodeGenerator/md/ppc/PPCInstructions.cpp b/ef/Compiler/CodeGenerator/md/ppc/PPCInstructions.cpp new file mode 100644 index 000000000000..3e34196f510c --- /dev/null +++ b/ef/Compiler/CodeGenerator/md/ppc/PPCInstructions.cpp @@ -0,0 +1,143 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +// PPCInstructions.cpp +// +// Scott M. Silver + +#include "PPCInstructions.h" +#include "PPC601AppleMacOSEmitter.h" + +/* Instantiate templates explicitly if needed */ +#ifdef MANUAL_TEMPLATES +template class AForm; +template class AForm; +#endif + + +void DFormXY:: +formatToMemory(void* inStart, Uint32 /*inOffset*/, MdFormatter& /*inFormatter*/) +{ + struct + { + uint OPCD:6; + uint D:5; + uint A:5; + uint IMM:16; + } dForm; + + dForm.OPCD = sDFormInfos[mKind].opcode; + dForm.D = getD(); + dForm.A = getA(); + dForm.IMM = getIMM(); + + *(Uint32*) inStart = *(Uint32*) &dForm; +} + +void LdD_RTOC:: +formatToMemory(void* inStart, Uint32 inOffset, PPCFormatter& inFormatter) +{ + mImmediate += inFormatter.mRealTOCOffset; + + LdD_FixedSource<2>::formatToMemory(inStart, inOffset, inFormatter); +} + +void XFormXY:: +formatToMemory(void* inStart, Uint32 /*inOffset*/, MdFormatter& /*inFormatter*/) +{ + struct + { + uint OPCD:6; + uint D:5; + uint A:5; + uint B:5; + uint OE:1; + uint XO:9; + uint RC:1; + } xForm; + + xForm.OPCD = sXFormInfos[mKind].primary;; + xForm.D = getD(); + xForm.A = getA(); + xForm.B = getB(); + xForm.OE = ((mFlags & pfOE) != 0) ? 1 : 0; + xForm.XO = sXFormInfos[mKind].opcode; + xForm.RC = ((mFlags & pfRc) != 0) ? 1 : 0; + + *(Uint32*) inStart = *(Uint32*) &xForm; +} + +void BranchI:: +formatToMemory(void* inStart, Uint32 inOffset, MdFormatter& /*inFormatter*/) +{ + mIForm.LI = (mTarget.getNativeOffset() - inOffset) >> 2; + + *(Uint32*) inStart = *(Uint32*) &mIForm; +} + + +void BranchCB:: +formatToMemory(void* inStart, Uint32 inOffset, MdFormatter& /*inFormatter*/) +{ + mCForm.BD = (mTarget.getNativeOffset() - inOffset) >> 2; + *(Uint32*) inStart = *(Uint32*) &mCForm; +} + +BranchCB:: +BranchCB(DataNode* inPrimitive, Pool& inPool, ControlNode& inTarget, Condition2 inCondition, bool inAbsolute, bool inLink) : + PPCInstructionXY(inPrimitive, inPool, 1, 0), + mTarget(inTarget) +#if DEBUG + , mCond(inCondition) +#endif +{ + mCForm.OPCD = 16; + + mCForm.BO = sBranchConditions[inCondition].bo; +// mCForm.Y = 0; + mCForm.BI = sBranchConditions[inCondition].bi; + mCForm.AA = inAbsolute; + mCForm.LK = inLink; +} + +void MForm:: +formatToMemory(void* inStart, Uint32 /*inOffset*/, MdFormatter& /*inFormatter*/) +{ + struct + { + uint OPCD:6; + uint S:5; + uint A:5; + uint B:5; + uint MB:5; + uint ME:5; + uint RC:1; + } mForm; + + mForm.OPCD = sMFormInfos[mKind].opcode; + mForm.S = getS(); + mForm.A = getA(); + mForm.B = getB(); + mForm.MB = getMB(); + mForm.ME = getME(); + mForm.RC = ((mFlags & pfRc) != 0) ? 1 : 0; + + *(Uint32*) inStart = *(Uint32*) &mForm; +} + + + diff --git a/ef/Compiler/CodeGenerator/md/ppc/PPCInstructions.h b/ef/Compiler/CodeGenerator/md/ppc/PPCInstructions.h new file mode 100644 index 000000000000..edbf503378c3 --- /dev/null +++ b/ef/Compiler/CodeGenerator/md/ppc/PPCInstructions.h @@ -0,0 +1,955 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +// PPCInstructions.h +// +// Scott M. Silver +// Peter Desantis + +#ifndef _H_PPCINSTRUCTIONS +#define _H_PPCINSTRUCTIONS + +#include "prtypes.h" +#include "Instruction.h" +#include "ControlNodes.h" + +typedef Uint8 PPCInsnFlags; +enum +{ + pfNil = 0x00, // nothing special + pfRc = 0x01, // sets a condition code + pfOE = 0x02 // set the overflow flag +}; + +#ifdef __MWERKS__ +#pragma mark - +#pragma mark ¥ÊPPCInstructionXY ¥ +#endif + +// PPCInstructionXY +// +// Base class for all PPC instructions +class PPCInstructionXY : + public InsnUseXDefineYFromPool +{ +public: + inline PPCInstructionXY(DataNode* inPrimitive, Pool& inPool, Uint8 inX, Uint8 inY) : + InsnUseXDefineYFromPool(inPrimitive, inPool, inX, inY) { } + virtual size_t getFormattedSize(MdFormatter& /*inFormatter*/) { return (4); } +}; + + +// Fixed point color to register map. +const Uint8 sFixedPointRegisterMap[] = +{ + 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 31, // -> first non-volatile + 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, + 19, 18, 17, 16, 15, 14 // 13 // -> last non-volatile, but used as globals +}; + +const Uint8 sFloatingPointRegisterMap[] = +{ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, + 11, 12, 13, // -> first non-volatile + 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31 // -> last non-volatile +}; + +// udToRegisterNumber +// +// Map colors of registers to real register numbers +inline Uint8 +udToRegisterNumber(InstructionUseOrDefine& inUse) +{ + Uint32 color = inUse.getVirtualRegister().colorInfo.color; + if (inUse.getVirtualRegister().getClass() == vrcInteger) + { + if (color < sizeof(sFixedPointRegisterMap) / sizeof(Uint8)) + return (sFixedPointRegisterMap[color]); +#ifdef DEBUG + else + return 255; +#endif + } + else if (inUse.getVirtualRegister().getClass() == vrcFloatingPoint) + { + if (color < sizeof(sFloatingPointRegisterMap) / sizeof(Uint8)) + return (sFloatingPointRegisterMap[color]); +#ifdef DEBUG + else + return 255; +#endif + } + else + assert(false); + return 255; // never reached +} + +#ifdef __MWERKS__ +#pragma mark - +#pragma mark ¥ÊD-Form ¥ +#endif + +#define MAKE_DFORM_ENUM(inName) df##inName, + +#define DFORM_ARITH_DEFINE(inName, inOpcode) MAKE_DFORM_ENUM(inName) +#define DFORM_ARITHCC_DEFINE(inName, inOpcode) MAKE_DFORM_ENUM(inName) +#define DFORM_LOAD_DEFINE(inName, inOpcode) MAKE_DFORM_ENUM(inName) +#define DFORM_LOADU_DEFINE(inName, inOpcode) MAKE_DFORM_ENUM(inName) +#define DFORM_STORE_DEFINE(inName, inOpcode) MAKE_DFORM_ENUM(inName) +#define DFORM_STOREU_DEFINE(inName, inOpcode) MAKE_DFORM_ENUM(inName) +#define DFORM_TRAP_DEFINE(inName, inOpcode) MAKE_DFORM_ENUM(inName) +#define DO_DFORM +enum DFormKind +{ + #include "PPCInstructionTemplates.h" + dfLast +}; + +#undef DFORM_ARITH_DEFINE +#undef DFORM_ARITHCC_DEFINE +#undef DFORM_LOAD_DEFINE +#undef DFORM_LOADU_DEFINE +#undef DFORM_STORE_DEFINE +#undef DFORM_STOREU_DEFINE +#undef DFORM_TRAP_DEFINE + +struct DFormInstructionInfo +{ + Uint16 opcode; + char* formatStr; +}; + +#define MAKE_DFORM_INFO(inOpcode, inString) \ + { inOpcode, inString }, + +#define DFORM_ARITH_DEFINE(inName, inOpcode) MAKE_DFORM_INFO(inOpcode, #inName" r%d, r%d, %d") +#define DFORM_ARITHCC_DEFINE(inName, inOpcode) MAKE_DFORM_INFO(inOpcode, #inName" r%d, r%d, %d") +#define DFORM_LOAD_DEFINE(inName, inOpcode) MAKE_DFORM_INFO(inOpcode, #inName" r%d, %d(r%d)") +#define DFORM_LOADU_DEFINE(inName, inOpcode) MAKE_DFORM_INFO(inOpcode, #inName" r%d, %d(r%d)") +#define DFORM_STORE_DEFINE(inName, inOpcode) MAKE_DFORM_INFO(inOpcode, #inName" r%d, %d(r%d)") +#define DFORM_STOREU_DEFINE(inName, inOpcode) MAKE_DFORM_INFO(inOpcode, #inName" r%d, %d(r%d)") +#define DFORM_TRAP_DEFINE(inName, inOpcode) MAKE_DFORM_INFO(inOpcode, #inName"%s r%d, %d") + +const DFormInstructionInfo sDFormInfos[] = +{ + #include "PPCInstructionTemplates.h" +}; +#undef DO_DFORM + + + + + +class DFormXY : + public PPCInstructionXY +{ +public: + inline DFormXY(DataNode* inPrimitive, Pool& inPool, DFormKind inKind, Uint8 inX, Uint8 inY) : + PPCInstructionXY(inPrimitive, inPool, inX, inY), + mKind(inKind) { } + virtual void formatToMemory(void* inStart, Uint32 inOffset, MdFormatter& /*inFormatter*/); + +protected: + Uint8 getOPCD() { return (sDFormInfos[mKind].opcode); } + virtual Uint8 getD() { return (udToRegisterNumber(getInstructionDefineBegin()[0])); } + virtual Uint8 getA() { return (udToRegisterNumber(getInstructionUseBegin()[0])); } + virtual Uint16 getIMM() = 0; + + const Uint16 mKind; + +#ifdef DEBUG +public: + virtual void printPretty(FILE* f) {fprintf(f, sDFormInfos[mKind].formatStr, getD(), getA(), getIMM());} +#endif +}; + +class DFormXYImmediate : + public DFormXY +{ +public: + inline DFormXYImmediate(DataNode* inPrimitive, Pool& inPool, DFormKind inKind, Uint8 inX, Uint8 inY, Uint16 inImmediate) : + mImmediate(inImmediate), + DFormXY(inPrimitive, inPool, inKind, inX, inY) { } + + virtual Uint16 getIMM() { return mImmediate; } + + Uint16 mImmediate; // immediate value +}; + + + +template +class LdD : + public DFormXYImmediate +{ +public: + inline LdD(DataNode* inPrimitive, Pool& inPool, DFormKind inKind, Uint16 inImmediate) : + DFormXYImmediate(inPrimitive, inPool, inKind, tUses, tDefines, inImmediate) { } + + virtual Uint8 getA() { return (udToRegisterNumber(getInstructionUseBegin()[tAOffset])); } + virtual Uint8 getD() { return (udToRegisterNumber(getInstructionDefineBegin()[tDOffset])); } +}; + + +template +class LdD_FixedSource : + public LdD<0, 1, 0, 0> +{ +public: + inline LdD_FixedSource(DataNode* inPrimitive, Pool& inPool, DFormKind inKind, Uint16 inImmediate) : + LdD<0, 1, 0, 0>(inPrimitive, inPool, inKind, inImmediate) { assert (tFixedSourceRegister < 32); } + + virtual Uint8 getA() { return (tFixedSourceRegister); } +}; + +// the formatToMemory routine does a fix-up +// based on the real toc offset +class LdD_RTOC : + public LdD_FixedSource<2> +{ +public: + inline LdD_RTOC(DataNode* inPrimitive, Pool& inPool, DFormKind inKind, Uint16 inImmediate) : + LdD_FixedSource<2>(inPrimitive, inPool, inKind, inImmediate) { } + + virtual void formatToMemory(void* inStart, Uint32 inOffset, MdFormatter& inFormatter); +}; + +typedef LdD<2, 1, 1, 0> LdD_; // Rvalue | mem Raddress +typedef LdD<2, 2, 1, 1> LdD_V; // mem Rvalue | mem Raddress + +// Rvalue | Sstackslot +class LdD_SpillRegister : + public LdD<1, 1, 0, 0> +{ +public: + inline LdD_SpillRegister(DataNode* inPrimitive, Pool& inPool, VirtualRegister& inStackSlot, VirtualRegister& inDefine) : + LdD<1, 1, 0, 0>(inPrimitive, inPool, dfLwz, 0) { addUse(0, inStackSlot); addDefine(0, inDefine); } + + // FIX-ME what about 64 bit fregs. + virtual Uint16 getIMM() { return ((Uint16)(getInstructionUseBegin()[0].getVirtualRegister().getColor() * -4) - 4); } + virtual Uint8 getA() { return (1); } +}; + +// -- + +// mem | mem Raddress Rvalue +class StD : + public DFormXYImmediate +{ +public: + inline StD(DataNode* inPrimitive, Pool& inPool, DFormKind inKind, Int16 inImmediate, Uint8 inUses = 3, Uint8 inDefines = 1) : + DFormXYImmediate(inPrimitive, inPool, inKind, inUses, inDefines, inImmediate) { } + + virtual Uint8 getA() { return (udToRegisterNumber(getInstructionUseBegin()[1])); } + virtual Uint8 getD() { return (udToRegisterNumber(getInstructionUseBegin()[2])); } + +#ifdef DEBUG +public: + virtual void printPretty(FILE* f) {fprintf(f, sDFormInfos[mKind].formatStr, getD(), getA(), getIMM());} +#endif +}; + +// Sstackslot | Rvalue +class StD_SpillRegister : + public StD +{ +public: + inline StD_SpillRegister(DataNode* inPrimitive, Pool& inPool, VirtualRegister& inStackSlot, VirtualRegister& inUse) : + StD(inPrimitive, inPool, dfStw, 0, 1, 1) { addDefine(0, inStackSlot); addUse(0, inUse); } + + virtual Uint16 getIMM() { return ((Uint16)(getInstructionUseBegin()[0].getVirtualRegister().getColor() * -4) - 4); } + virtual Uint8 getA() { return (1); } + virtual Uint8 getD() { return (udToRegisterNumber(getInstructionUseBegin()[0])); } +}; + +// mem | mem value +template +class StD_FixedDestRegister : + public StD +{ +public: + inline StD_FixedDestRegister(DataNode* inPrimitive, Pool& inPool, DFormKind inKind, Uint16 inImmediate) : + StD(inPrimitive, inPool, inKind, inImmediate, 2, 1) { } + + virtual Uint8 getA() { return (tFixedDestRegister); } + virtual Uint8 getD() { return (udToRegisterNumber(getInstructionUseBegin()[1])); } +}; + +class ArithID : + public DFormXYImmediate +{ +public: + inline ArithID(DataNode* inPrimitive, Pool& inPool, DFormKind inKind, Int16 inImmediate) : + DFormXYImmediate(inPrimitive, inPool, inKind, 1, 1, inImmediate) { } + + virtual InstructionFlags getFlags() const { return ((mImmediate == 0 && mKind == dfAddi) ? ifCopy : ifNone); } +}; + +class LogicalID : + public DFormXYImmediate +{ +public: + inline LogicalID(DataNode* inPrimitive, Pool& inPool, DFormKind inKind, Int16 inImmediate) : + DFormXYImmediate(inPrimitive, inPool, inKind, 1, 1, inImmediate) { } + + Uint8 getA() { return (udToRegisterNumber(getInstructionDefineBegin()[0])); } + Uint8 getD() { return (udToRegisterNumber(getInstructionUseBegin()[0])); } + virtual InstructionFlags getFlags() const { return ((mImmediate == 0 && mKind == dfAddi) ? ifCopy : ifNone); } +}; + + +class ArithIZeroInputD : + public DFormXYImmediate +{ +public: + inline ArithIZeroInputD(DataNode* inPrimitive, Pool& inPool, DFormKind inKind, Uint16 inImmediate, Uint8 inFakeUses = 0) : + DFormXYImmediate(inPrimitive, inPool, inKind, inFakeUses, 1, inImmediate) { } + + Uint8 getA() { return (0); } +}; + +class LogicalIZeroInputD : + public DFormXYImmediate +{ +public: + inline LogicalIZeroInputD(DataNode* inPrimitive, Pool& inPool, DFormKind inKind, Uint16 inImmediate, Uint8 inFakeUses = 0) : + DFormXYImmediate(inPrimitive, inPool, inKind, inFakeUses, 1, inImmediate) { } + + Uint8 getA() { return (udToRegisterNumber(getInstructionDefineBegin()[0])); } + Uint8 getD() { return (0); } +}; + + +class Copy_I : + public ArithID +{ +public: + inline Copy_I(DataNode* inPrimitive, Pool& inPool) : + ArithID(inPrimitive, inPool, dfAddi, 0) { } +}; + + +class ArithIDSetCC : + public DFormXYImmediate +{ +public: + inline ArithIDSetCC(DataNode* inPrimitive, Pool& inPool, DFormKind inKind, Uint16 inImmediate) : + DFormXYImmediate(inPrimitive, inPool, inKind, 2, 2, inImmediate) { } +}; + + +class CmpID : + public DFormXYImmediate +{ +public: + inline CmpID(DataNode* inPrimitive, Pool& inPool, DFormKind inKind, Uint16 inImmediate) : + DFormXYImmediate(inPrimitive, inPool, inKind, 1, 1, inImmediate) { } + +protected: + virtual Uint8 getD() { return (0); } // always use cr0, and L=0 + +#ifdef DEBUG +public: + virtual void printPretty(FILE* f) { fprintf(f, sDFormInfos[mKind].formatStr, getD() >> 2, getA(), getIMM()); } +#endif +}; + +// the bits in order (or offsets into a condition register) +// neg (lt) +// pos (gt) +// zero (eq) +// summary overflow (so) +// 0010y branch if cond is false +// 0110y branch if cond is true +struct TrapCondition +{ + char* name; + Uint8 to; +}; + +// indexed by Condition2 +static TrapCondition sSignedTrapConditions[] = +{ + {"", 31}, + {"lt", 16}, + {"eq", 4}, + {"le", 20}, + {"gt", 8}, + {"ne", 24}, + {"ge", 12} +}; + +// indexed by Condition2 +static TrapCondition sUnsignedTrapConditions[] = +{ + {"", 31}, + {"llt", 2}, + {"eq", 4}, + {"lle", 6}, + {"lgt", 1}, + {"ne", 24}, + {"lge", 5} +}; + +class TrapD : + public DFormXYImmediate +{ +public: + inline TrapD(DataNode* inPrimitive, Pool& inPool, Condition2 inCondition, bool inSigned, Uint16 inImmediate) : + DFormXYImmediate(inPrimitive, inPool, dfTwi, 1, 0, inImmediate), + mSigned(inSigned), + mCond(inCondition) { } + +protected: + virtual Uint8 getD() { return (mSigned ? sSignedTrapConditions[mCond].to : sUnsignedTrapConditions[mCond].to); } + virtual Uint8 getA() { return (udToRegisterNumber(getInstructionUseBegin()[0])); } + + const bool mSigned; + const Condition2 mCond; + +#ifdef DEBUG +public: + virtual void printPretty(FILE* f) { fprintf(f, sDFormInfos[mKind].formatStr, mSigned ? sSignedTrapConditions[mCond].name : sUnsignedTrapConditions[mCond].name, getA(), getIMM()); } +#endif +}; + +#ifdef __MWERKS__ +#pragma mark - +#pragma mark ¥ÊX & XO-Form ¥ +#endif + + +#define MAKE_XFORM_ENUM(inName) xf##inName, + +#define XFORM_ARITH_DEFINE(inName, inOpcode, inPrimary) MAKE_XFORM_ENUM(inName) +#define XFORM_INAONLY_DEFINE(inName, inOpcode, inPrimary) MAKE_XFORM_ENUM(inName) +#define XFORM_CMP_DEFINE(inName, inOpcode, inPrimary) MAKE_XFORM_ENUM(inName) +#define XFORM_LOAD_DEFINE(inName, inOpcode, inPrimary) MAKE_XFORM_ENUM(inName) +#define XFORM_LOADU_DEFINE(inName, inOpcode, inPrimary) MAKE_XFORM_ENUM(inName) +#define XFORM_STORE_DEFINE(inName, inOpcode, inPrimary) MAKE_XFORM_ENUM(inName) +#define XFORM_STOREU_DEFINE(inName, inOpcode, inPrimary) MAKE_XFORM_ENUM(inName) +#define XFORM_TRAP_DEFINE(inName, inOpcode, inPrimary) MAKE_XFORM_ENUM(inName) +#define XFORM_INBONLY_DEFINE(inName, inOpcode, inPrimary) MAKE_XFORM_ENUM(inName) +#define DO_XFORM +enum XFormKind +{ + #include "PPCInstructionTemplates.h" + xfLast +}; + +#undef XFORM_ARITH_DEFINE +#undef XFORM_INAONLY_DEFINE +#undef XFORM_CMP_DEFINE +#undef XFORM_LOAD_DEFINE +#undef XFORM_LOADU_DEFINE +#undef XFORM_STORE_DEFINE +#undef XFORM_STOREU_DEFINE +#undef XFORM_TRAP_DEFINE +#undef XFORM_INBONLY_DEFINE + +struct XFormInstructionInfo +{ + Uint16 opcode; + Uint16 primary; + char* formatStr; +}; + +#define MAKE_XFORM_INFO(inOpcode, inPrimary, inString) \ + { inOpcode, inPrimary, inString }, + +#define XFORM_ARITH_DEFINE(inName, inOpcode, inPrimary) MAKE_XFORM_INFO(inOpcode, inPrimary, #inName" r%d, r%d, r%d") +#define XFORM_INAONLY_DEFINE(inName, inOpcode, inPrimary) MAKE_XFORM_INFO(inOpcode, inPrimary, #inName" r%d, r%d, r%d") +#define XFORM_CMP_DEFINE(inName, inOpcode, inPrimary) MAKE_XFORM_INFO(inOpcode, inPrimary, #inName" r%d, r%d, r%d") +#define XFORM_LOAD_DEFINE(inName, inOpcode, inPrimary) MAKE_XFORM_INFO(inOpcode, inPrimary, #inName" r%d, r%d, r%d") +#define XFORM_LOADU_DEFINE(inName, inOpcode, inPrimary) MAKE_XFORM_INFO(inOpcode, inPrimary, #inName" r%d, r%d, r%d") +#define XFORM_STORE_DEFINE(inName, inOpcode, inPrimary) MAKE_XFORM_INFO(inOpcode, inPrimary, #inName" r%d, r%d, r%d") +#define XFORM_STOREU_DEFINE(inName, inOpcode, inPrimary) MAKE_XFORM_INFO(inOpcode, inPrimary, #inName" r%d, r%d, r%d") +#define XFORM_TRAP_DEFINE(inName, inOpcode, inPrimary) MAKE_XFORM_INFO(inOpcode, inPrimary, #inName" r%d, r%d, r%d") +#define XFORM_INBONLY_DEFINE(inName, inOpcode, inPrimary) MAKE_XFORM_INFO(inOpcode, inPrimary, #inName" r%d, r%d, r%d") + +const XFormInstructionInfo sXFormInfos[] = +{ + #include "PPCInstructionTemplates.h" +}; +#undef DO_XFORM + +static char* +sFlagsExtensionTbl[] = +{ + "", // none + ".", // pfRc + "o", // pfOE + "o." // pfRC | afOE +}; + + +class XFormXY : + public PPCInstructionXY +{ +public: + inline XFormXY(DataNode* inPrimitive, Pool& inPool, Uint8 inX, Uint8 inY, XFormKind inKind, PPCInsnFlags inFlags) : + PPCInstructionXY(inPrimitive, inPool, inX, inY), + mFlags(inFlags), + mKind(inKind) { } + virtual void formatToMemory(void* inStart, Uint32 inOffset, MdFormatter& /*inFormatter*/); + +protected: + virtual Uint8 getOPCD() { return (31); } + virtual Uint8 getD() { return (udToRegisterNumber(getInstructionDefineBegin()[0])); } + virtual Uint8 getA() { return (udToRegisterNumber(getInstructionUseBegin()[0])); } + virtual Uint8 getB() { return (udToRegisterNumber(getInstructionUseBegin()[1])); } + virtual Uint16 getXO() { return (sXFormInfos[mKind].opcode); } + + PPCInsnFlags mFlags; + XFormKind mKind; + +#ifdef DEBUG +public: + virtual void printPretty(FILE* f) { fprintf(f, sXFormInfos[mKind].formatStr, flagsToExtension(), getD(), getA(), getB()); } + const char* flagsToExtension() { return sFlagsExtensionTbl[mFlags & 3]; } // only look at OE and Rc bits +#endif +}; + + +class TrapX : + public XFormXY +{ +public: + inline TrapX(DataNode* inPrimitive, Pool& inPool, Condition2 inCondition, bool inSigned, PPCInsnFlags inFlags) : + XFormXY(inPrimitive, inPool, 2, 0, xfTw, inFlags), + mSigned(inSigned), + mCond(inCondition) { } + +protected: + virtual Uint8 getD() { return (mSigned ? sSignedTrapConditions[mCond].to : sUnsignedTrapConditions[mCond].to); } + +#ifdef DEBUG +public: + virtual void printPretty(FILE* f) { fprintf(f, sXFormInfos[mKind].formatStr, mSigned ? sSignedTrapConditions[mCond].name : sUnsignedTrapConditions[mCond].name, getA(), getB()); } +#endif + +protected: + bool mSigned; + Condition2 mCond; +}; + +template +class LdX : + public XFormXY +{ +public: + inline LdX(DataNode* inPrimitive, Pool& inPool, XFormKind inKind) : + XFormXY(inPrimitive, inPool, inX, inY, inKind, pfNil) { assert(inKind >= xfLbzx && inKind <= xfLwzx); } + + virtual Uint8 getD() { return (udToRegisterNumber(getInstructionDefineBegin()[inD])); } + virtual Uint8 getA() { return (udToRegisterNumber(getInstructionUseBegin()[inA])); } + virtual Uint8 getB() { return (udToRegisterNumber(getInstructionUseBegin()[inB])); } +}; + +typedef LdX<2, 1, 0, 0, 1> LdX_C; // Rvalue <- Raddress Radddress +typedef LdX<3, 2, 1, 1, 2> LdX_V; // mem Rvalue Raddress <- mem Raddress Raddress +typedef LdX<3, 1, 0, 1, 2> LdX_; // Rvalue <- mem Raddress Raddress + + +// mem <- mem Raddress Raddress Value +class StX : + public XFormXY +{ +public: + inline StX(DataNode* inPrimitive, Pool& inPool, XFormKind inKind) : + XFormXY(inPrimitive, inPool, 4, 1, inKind, pfNil) { assert(inKind >= xfStbx && inKind <= xfStwx); } + + virtual Uint8 getD() { return (udToRegisterNumber(getInstructionUseBegin()[3])); } + virtual Uint8 getA() { return (udToRegisterNumber(getInstructionUseBegin()[1])); } + virtual Uint8 getB() { return (udToRegisterNumber(getInstructionUseBegin()[2])); } +}; + + +class ArithX : + public XFormXY +{ +public: + inline ArithX(DataNode* inPrimitive, Pool& inPool, XFormKind inKind, PPCInsnFlags inFlags) : + XFormXY(inPrimitive, inPool, 2, ((inFlags & pfRc) == 0) ? 1 : 2, inKind, inFlags) { } +}; + +class XOInAOnly : + public XFormXY +{ +public: + // if we want to use the lswi, need to deal with memory edge + inline XOInAOnly(DataNode* inPrimitive, Pool& inPool, XFormKind inKind, PPCInsnFlags inFlags) : + XFormXY(inPrimitive, inPool, 1, ((inFlags & pfRc) == 0) ? 1 : 2, inKind, inFlags) {} + +protected: + virtual Uint8 getA() { return 0; } +}; + +class XInAOnly : + public XFormXY +{ +public: + // if we want to use the lswi, need to deal with memory edge + inline XInAOnly(DataNode* inPrimitive, Pool& inPool, XFormKind inKind, PPCInsnFlags inFlags, Uint8 inB) : + XFormXY(inPrimitive, inPool, 1, ((inFlags & pfRc) == 0) ? 1 : 2, inKind, (inFlags | pfOE)), + mB(inB) { } + +protected: + virtual Uint8 getD() { return (XFormXY::getA()); } + virtual Uint8 getA() { return (XFormXY::getD()); } + virtual Uint8 getB() { assert (mB < (1 << 6)); return mB; } + Uint8 mB; +}; + +class XInBOnly : + public XFormXY +{ +public: + inline XInBOnly(DataNode* inPrimitive, Pool& inPool, XFormKind inKind, PPCInsnFlags inFlags) : + XFormXY(inPrimitive, inPool, 1, ((inFlags & pfRc) == 0) ? 1 : 2, inKind, inFlags) { } + +protected: + virtual Uint8 getA() { return (0); } + virtual Uint8 getB() { return (udToRegisterNumber(getInstructionUseBegin()[0])); } + virtual InstructionFlags getFlags() const { return ((mKind == xfFmr) ? ifCopy : ifNone); } + Uint8 mA; +}; + +class CmpIX : + public XFormXY +{ +public: + inline CmpIX(DataNode* inPrimitive, Pool& inPool, XFormKind inKind, PPCInsnFlags inFlags) : + XFormXY(inPrimitive, inPool, 2, 1, inKind, inFlags) { } + +protected: + virtual Uint8 getD() { return (0); } // always use cr0 +}; + +class CmpFX : + public XFormXY +{ +public: + inline CmpFX(DataNode* inPrimitive, Pool& inPool, XFormKind inKind, PPCInsnFlags inFlags) : + XFormXY(inPrimitive, inPool, 2, 1, inKind, inFlags) { } + +protected: + virtual Uint8 getD() { return (0); } // always use cr0 +}; + +#ifdef __MWERKS__ +#pragma mark - +#pragma mark ¥ÊIForm ¥ +#endif + +class BranchI : + public PPCInstructionXY +{ +public: + inline BranchI(DataNode* inPrimitive, Pool& inPool, ControlNode& inTarget, bool inAbsolute = false, bool inLink = false) : + PPCInstructionXY(inPrimitive, inPool, 0, 0), mTarget(inTarget) + { mIForm.OPCD = 18; mIForm.LI = 0; mIForm.AA = inAbsolute; mIForm.LK = inLink;} + + virtual void formatToMemory(void* inStart, Uint32 inOffset, MdFormatter& /*inFormatter*/); + #ifdef DEBUG + virtual void printPretty(FILE* f) { fprintf(f, "bxx %d", mTarget.getNativeOffset()); } + #endif + +protected: + ControlNode& mTarget; + + struct + { + int OPCD:6; + int LI:24; + int AA:1; + int LK:1; + } mIForm; +}; + +#ifdef __MWERKS__ +#pragma mark - +#pragma mark ¥ÊIForm ¥ +#endif + +// the bits in order (or offsets into a condition register) +// neg (lt) +// pos (gt) +// zero (eq) +// summary overflow (so) +// 0010y branch if cond is false +// 0110y branch if cond is true +struct BranchCondition +{ + char* name; + Uint8 bo; + Uint8 bi; +}; + +// indexed by Condition2 +const BranchCondition sBranchConditions[] = +{ + {"always", 0, 0}, + {"lt", 12, 0}, + {"eq", 12, 2}, + {"le", 4, 1}, + {"gt", 12, 1}, + {"ne", 4, 2}, + {"ge", 4, 0} +}; + +#if 0 + BO BI + cond0, // 0000 Always false + condLt, // 0001 arg1 < arg2 0110y 0 lt + condEq, // 0010 arg1 = arg2 0110y 2 eq + condLe, // 0011 arg1 <= arg2 0010y 1 not gt + condGt, // 0100 arg1 > arg2 0110y 1 gt + condLgt, // 0101 arg1 <> arg2 0010y 2 not eq + condGe, // 0110 arg1 >= arg2 0010y 0 not lt + +-- only up to these are supported + condOrd, // 0111 arg1 <=> arg2 (i.e. arg1 and arg2 are ordered) 0110y 3 so ?? nan + condUnord, // 1000 arg1 ? arg2 (i.e. arg1 and arg2 are unordered) 0010y 3 not so + condULt, // 1001 arg1 ?< arg2 do we have to deal with these below here?? + condUEq, // 1010 arg1 ?= arg2 + condULe, // 1011 arg1 ?<= arg2 + condUGt, // 1100 arg1 ?> arg2 + condNe, // 1101 arg1 != arg2 + condUGe, // 1110 arg1 ?>= arg2 + cond1 // 1111 Always true +#endif + +class BranchCB : + public PPCInstructionXY +{ +public: + BranchCB(DataNode* inPrimitive, Pool& inPool, ControlNode& inTarget, Condition2 inCondition, bool inAbsolute = false, bool inLink = false); + virtual void formatToMemory(void* inStart, Uint32 inOffset, MdFormatter& /*inFormatter*/); + + +protected: + ControlNode& mTarget; + + struct + { + unsigned int OPCD:6; + unsigned int BO:5; +// unsigned int Y:1; + unsigned int BI:5; + unsigned int BD:14; + unsigned int AA:1; + unsigned int LK:1; + } mCForm; + +#if DEBUG +public: + virtual void printPretty(FILE* f) { fprintf(f, "b%s %d", sBranchConditions[mCond].name, mTarget.getNativeOffset()); } + +protected: + Condition2 mCond; +#endif +}; + + +#ifdef __MWERKS__ +#pragma mark - +#pragma mark ¥ÊM-Form ¥ +#endif + +#define DO_MFORM +struct MFormInstructionInfo +{ + Uint16 opcode; + char* formatStr; +}; + + +#define MAKE_MFORM_ENUM(inName) mf##inName, +#define MFORM_DEFINE(inName, inOpcode) MAKE_MFORM_ENUM(inName) + +enum MFormKind +{ + #include "PPCInstructionTemplates.h" + mfLast +}; + +#undef MFORM_DEFINE + +#define MAKE_MFORM_INFO(inName, inOpcode) \ + { inOpcode, #inName"%s r%d, r%d, r%d, %d, %d"}, + +#define MFORM_DEFINE(inName, inOpcode) MAKE_MFORM_INFO(inName, inOpcode) + +const MFormInstructionInfo sMFormInfos[] = +{ + #include "PPCInstructionTemplates.h" +}; + +#undef MFORM_DEFINE +#undef DO_MFORM + +class MForm : + public PPCInstructionXY +{ +public: + inline MForm(DataNode* inPrimitive, Pool& inPool, Uint8 inUses, MFormKind inKind, Uint8 inMaskBegin, Uint8 inMaskEnd, PPCInsnFlags inFlags) : + PPCInstructionXY(inPrimitive, inPool, inUses, 1 + (bool) (inFlags & pfRc)), + mFlags(inFlags), + mKind(inKind), + mMaskBegin(inMaskBegin), + mMaskEnd(inMaskEnd) { } + virtual void formatToMemory(void* inStart, Uint32 inOffset, MdFormatter& /*inFormatter*/); + + + +protected: + Uint16 getOPCD() { return (sXFormInfos[mKind].opcode); } + Uint8 getS() { return (udToRegisterNumber(getInstructionUseBegin()[0])); } + Uint8 getA() { return (udToRegisterNumber(getInstructionDefineBegin()[0])); } + virtual Uint8 getB() { return (udToRegisterNumber(getInstructionUseBegin()[1])); } + Uint8 getMB() { return (mMaskBegin); } + Uint8 getME() { return (mMaskEnd); } + +#ifdef DEBUG +public: + virtual void printPretty(FILE* f) { fprintf(f, sMFormInfos[mKind].formatStr, flagsToExtension(), getA(), getS(), getB(), getMB(), getME()); } +protected: + const char* flagsToExtension() { return sFlagsExtensionTbl[mFlags & 1]; /* only look at Rc bit */ } +#endif + + PPCInsnFlags mFlags; + MFormKind mKind; + Uint8 mMaskBegin; + Uint8 mMaskEnd; +}; + + +class MFormInAOnly : + public MForm +{ +public: + inline MFormInAOnly(DataNode* inPrimitive, Pool& inPool, MFormKind inKind, Uint8 inB, Uint8 inMaskBegin, Uint8 inMaskEnd, PPCInsnFlags inFlags) : + MForm(inPrimitive, inPool, 1, inKind, inMaskBegin, inMaskEnd, inFlags), + mB(inB) { } +protected: + virtual Uint8 getB() { return (mB); } + + Uint8 mB; +}; + +#ifdef __MWERKS__ +#pragma mark - +#pragma mark ¥ÊA-Form ¥ +#endif + + +#define DO_AFORM + + +#define MAKE_AFORM_ENUM(inName) af##inName, +#define AFORM_DEFINE(inName, inOpcode, inXo, inHasA, inHasB, inHasC, inRc) MAKE_AFORM_ENUM(inName) + +enum AFormKind +{ + #include "PPCInstructionTemplates.h" + afLast +}; + +#undef AFORM_DEFINE + +template +class AForm : + public PPCInstructionXY +{ +public: + inline AForm(DataNode* inPrimitive, Pool& inPool, AFormKind inKind) : + PPCInstructionXY(inPrimitive, inPool, tHasA + tHasB + tHasC, tRc + 1), + mKind(inKind) {} + +protected: + Uint16 getOPCD() { return (sAFormInfos[mKind].opcode); } + Uint8 getD() { return (udToRegisterNumber(getInstructionDefineBegin()[0])); } + Uint8 getA() { return (tHasA ? udToRegisterNumber(getInstructionUseBegin()[0]) : 0); } + Uint8 getB() { return (tHasB ? udToRegisterNumber(getInstructionUseBegin()[tHasA]) : 0); } + Uint8 getC() { return (tHasC ? udToRegisterNumber(getInstructionUseBegin()[tHasA + tHasB]) : 0); } + +public: + virtual void + formatToMemory(void* inStart, Uint32 /*inOffset*/, MdFormatter& /*inFormatter*/) + { + struct + { + uint OPCD:6; + uint D:5; + uint A:5; + uint B:5; + uint C:5; + uint XO:5; + uint RC:1; + } aForm; + + aForm.OPCD = sAFormInfos[mKind].opcode; + aForm.D = getD(); + aForm.A = getA(); + aForm.B = getB(); + aForm.C = getC(); + aForm.XO = sAFormInfos[mKind].xo; + aForm.RC = tRc; + + *(Uint32*) inStart = *(Uint32*) &aForm; + } + + static Instruction& + createInstruction(DataNode& inPrimitive, Pool& mPool, AFormKind inKind) + { + return *new(mPool) AForm(&inPrimitive, mPool, inKind); + } + +protected: + const AFormKind mKind; +#ifdef DEBUG +public: + virtual void printPretty(FILE* /*f*/) {} +protected: + const char* flagsToExtension() { return sFlagsExtensionTbl[tRc]; } // only look at Rc bit +#endif +}; + +struct AFormInstructionInfo +{ + Uint16 opcode; + Uint16 xo; + Instruction& (*creatorFunction)(DataNode&, Pool&, AFormKind); + char* formatStr; +}; + +#define MAKE_AFORM_INFO(inName, inOpcode, inXo, inHasA, inHasB, inHasC, inRc) \ + { inOpcode, inXo, AForm::createInstruction, #inName"%s r%d, r%d, r%d, %d, %d"}, + +#define AFORM_DEFINE(inName, inOpcode, inXo, inHasA, inHasB, inHasC, inRc) MAKE_AFORM_INFO(inName, inOpcode, inXo, inHasA, inHasB, inHasC, inRc) + +const AFormInstructionInfo sAFormInfos[] = +{ + #include "PPCInstructionTemplates.h" +}; + +#undef AFORM_DEFINE +#undef DO_AFORM + +#endif // _H_PPCINSTRUCTIONS diff --git a/ef/Compiler/CodeGenerator/md/ppc/ppc-makefile.mac b/ef/Compiler/CodeGenerator/md/ppc/ppc-makefile.mac new file mode 100644 index 000000000000..2db91e1b10b6 --- /dev/null +++ b/ef/Compiler/CodeGenerator/md/ppc/ppc-makefile.mac @@ -0,0 +1,41 @@ +#!gmake +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +# ppc-makefile.mac +# +# Scott M. Silver +# +# Assuming MOZ_SRC was set up (to point to the directory above ns), this +# makefile generates the PrimitiveOperations and CodeGenerator specific +# stuff (including BURG, etc) + +NAD_SRC = "{MOZ_SRC}:ns:electricalfire:Compiler:CodeGenerator:md:ppc:ppc601-macos.nad" +PRIMITIVEOPERATIONS = "{MOZ_SRC}:ns:electricalfire:Compiler:PrimitiveGraph:PrimitiveOperations" +NAD = {PERL} "{MOZ_SRC}:ns:electricalfire:Tools:Nad:Nad.pl" + +NAD_OUTPUTS = {NAD_SRC}.burg.h {NAD_SRC}.burg.cpp {PRIMITIVEOPERATIONS}.h {PRIMITIVEOPERATIONS}.cpp + +{NAD_OUTPUTS} Ä {NAD_SRC} {PRIMITIVEOPERATIONS} + {NAD} {NAD_SRC} {PRIMITIVEOPERATIONS} {PRIMITIVEOPERATIONS}.h {PRIMITIVEOPERATIONS}.cpp {NAD_SRC}.burg.h > BurgOut + BURG -I {NAD_SRC}.burg.cpp + set TouchedFiles "`ResolveAlias {PRIMITIVEOPERATIONS}.h`" + set TouchedFiles "{TouchedFiles},`ResolveAlias {NAD_SRC}.burg.h`" + set TouchedFiles "{TouchedFiles},`ResolveAlias {NAD_SRC}.burg.cpp`" + set TouchedFiles "{TouchedFiles},`ResolveAlias {PRIMITIVEOPERATIONS}.cpp`" + export TouchedFiles + + diff --git a/ef/Compiler/CodeGenerator/md/ppc/ppc.nad b/ef/Compiler/CodeGenerator/md/ppc/ppc.nad new file mode 100644 index 000000000000..3a43f24f1544 --- /dev/null +++ b/ef/Compiler/CodeGenerator/md/ppc/ppc.nad @@ -0,0 +1,406 @@ +%top +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +% + +Vptr <- Vint() +Vint <- Vptr() + +Vint <- poConst_I() cost(1) +%{ + genPrimConst_32(thisPrimitive); +%} + +Vptr <- poConst_A() cost(1) +%{ + genPrimConst_32(thisPrimitive); +%} + +Vfloat <- poConst_F() cost(1) +%{ + Flt32 constant = (*static_cast(&thisPrimitive)).value.f; + + Uint16 offset; + mAccumulatorTOC.addData(&constant, sizeof(constant), offset); + + Instruction& ldConstant = *new(mPool) LdD_RTOC(&thisPrimitive, mPool, dfLfs, offset); + defineProducer(thisPrimitive, ldConstant, 0, vrcFloatingPoint); +%} + +Result <- poResult_I(Vint inResult) cost(1) +%{ + genPrimResult_32(thisPrimitive, inResult); +%} + +Result <- poResult_A(Vptr inResult) cost(1) +%{ + genPrimResult_32(thisPrimitive, inResult); +%} + +Result <- poResult_F(Vfloat inResult) cost(1) +%{ + VirtualRegister* returnVr; + + // generate: fmr fp0, fpResultRegister + + // create a buffer copy instruction between the result + // and the precolored register + XInBOnly& copyInsn = *new(mPool) XInBOnly(&thisPrimitive, mPool, xfFmr, pfNil); + + useProducer(inResult, copyInsn, 0, vrcFloatingPoint); + returnVr = &defineTemporary(copyInsn, 0, vrcFloatingPoint); + + // floating point results go somwhere FIX-ME + returnVr->preColorRegister(1); + + // create a special instruction for the RegisterAllocator which says this result + // is used elsewhere (but not in this body of code). + InsnExternalUse& externalUse = *new(mPool) InsnExternalUse(&thisPrimitive, mPool, 1); + useTemporaryVR(externalUse, *returnVr, 0, vrcFloatingPoint); + thisPrimitive.setInstructionRoot(&externalUse); +%} + +#define IF_CONTROL(inPrimOp, inCondition) \ + Control <- inPrimOp(Vcond) cost(1) \ + %{ \ + genBranch(thisPrimitive, inCondition); \ + %} + +IF_CONTROL(poIfLt, condLt) +IF_CONTROL(poIfNe, condNe) +IF_CONTROL(poIfEq, condEq) +IF_CONTROL(poIfLe, condLe) +IF_CONTROL(poIfGt, condGt) +IF_CONTROL(poIfLgt, condLgt) +IF_CONTROL(poIfGe, condGe) + +Vint <- poAnd_I(Vint inA, Vint inB) cost(1) +%{ + genArithX_32(thisPrimitive, xfAnd, inA, inB); +%} + +Vint <- poOr_I(Vint inA, Vint inB) cost(1) +%{ + genArithX_32(thisPrimitive, xfOr, inA, inB); +%} + +Vint <- poXor_I(Vint inA, Vint inB) cost(1) +%{ + genArithX_32(thisPrimitive, xfXor, inA, inB); +%} + +Vint <- poAnd_I(Vint inA, Vint inB) cost(1) +%{ + genArithX_32(thisPrimitive, xfAnd, inA, inB); +%} + +Vint <- poAdd_I(Vint inA, coConstS16 inConstant) cost(1) +%{ + genArithD_32(thisPrimitive, dfAddi, inA, PrimConst::cast(inConstant).value.i); +%} + +Vint <- poAdd_I(coConstS16 inConstant, Vint inB) cost(1) +%{ + genArithD_32(thisPrimitive, dfAddi, inB, PrimConst::cast(inConstant).value.i); +%} + +Vint <- poAdd_I(Vptr inA, Vint inB) cost(1) +%{ + genArithX_32(thisPrimitive, xfAdd, inA, inB); +%} + +Vptr <- poAddU_A(Vptr inA, Vint inB) cost(1) +%{ + genArithX_32(thisPrimitive, xfAdd, inA, inB); +%} + +Vptr <- poAdd_A(Vptr inA, Vint inB) cost(1) +%{ + genArithX_32(thisPrimitive, xfAdd, inA, inB); +%} + +Vint <- poSub_I(Vptr inA, Vint inB) cost(1) +%{ + genArithX_32(thisPrimitive, xfSubf, inB, inA); +%} + + +Vptr <- poSub_A(Vptr inA, Vint inB) cost(1) +%{ + genArithX_32(thisPrimitive, xfSubf, inB, inA); +%} + +Vint <- poMul_I(Vint inA, Vint inB) cost(1) +%{ + genArithX_32(thisPrimitive, xfMullw, inA, inB); +%} + +Vint <- poDiv_I(Vint inDividend, Vint inDivisor) cost(1) +%{ + genArithX_32(thisPrimitive, xfDivw, inDividend, inDivisor); +%} + +Vint <- poDivE_I(Vint inDividend, Vint inDivisor) cost(1) +%{ + // FIX-ME must handle divide by zero system exception + genArithX_32(thisPrimitive, xfDivw, inDividend, inDivisor); +%} + +Vint <- poDivU_I(Vint inDividend, Vint inDivisor) cost(1) +%{ + genArithX_32(thisPrimitive, xfDivwu, inDividend, inDivisor); +%} + +Vint <- poDivUE_I(Vint inDividend, Vint inDivisor) cost(1) +%{ + // FIX-ME must handle divide by zero system exception + genArithX_32(thisPrimitive, xfDivwu, inDividend, inDivisor); +%} + + +Vint <- poMod_I(Vint inDividend, Vint inDivisor) cost(1) +%{ + genMod(thisPrimitive, xfDivw, inDividend, inDivisor); +%} + +Vint <- poModE_I(Vint inDividend, Vint inDivisor) cost(1) +%{ + // FIX-ME must handle divide by zero system exception + genMod(thisPrimitive, xfDivw, inDividend, inDivisor); +%} + + +Vint <- poModU_I(Vint inDividend, Vint inDivisor) cost(1) +%{ + // FIX-ME must handle divide by zero system exception + genMod(thisPrimitive, xfDivwu, inDividend, inDivisor); +%} + +Vint <- poShl_I(Vint inValue, Vint inShiftAmount) cost(1) +%{ + XOutA& newInsn = *new(mPool) XOutA(&thisPrimitive, mPool, xfSlw, pfNil); + + useProducer(inValue, newInsn, 0); + useProducer(inShiftAmount, newInsn, 1); + defineProducer(thisPrimitive, newInsn, 0); +%} + + +Vfloat <- poFAdd_F(Vfloat inA, Vfloat inB) cost(1) +%{ + genArith_FP(thisPrimitive, afFadd, inA, inB); +%} + +Vcond <- poCmp_I(Vint inA, Vint inB) cost(1) +%{ + CmpIX& newInsn = *new(mPool) CmpIX(&thisPrimitive, mPool, xfCmp, 0); + + useProducer(inA, newInsn, 0); + useProducer(inB, newInsn, 1); + defineProducer(thisPrimitive, newInsn, 0); +%} + +Vcond <- poCmpU_I(Vint inA, Vint inB) cost(1) +%{ + CmpIX& newInsn = *new(mPool) CmpIX(&thisPrimitive, mPool, xfCmpl, 0); + + useProducer(inA, newInsn, 0); + useProducer(inB, newInsn, 1); + defineProducer(thisPrimitive, newInsn, 0); +%} + +Exception <- poChkNull(Vptr inTestValue) cost(1) +%{ + genThrowIfZero(thisPrimitive, inTestValue); +%} + + +Exception <- poLimit(Vint inIndex, Vint inBound) cost(1) +%{ + TrapX& newInsn = *new(mPool) TrapX(&thisPrimitive, mPool, condGe, false, pfNil); + useProducer(inIndex, newInsn, 0); + useProducer(inBound, newInsn, 1); + thisPrimitive.setInstructionRoot(&newInsn); +%} + +#define LD_FIXED(inPrimOp, inReturnType, inOpcode) \ + inReturnType <- inPrimOp(Vptr[1] inAddress) cost(1) \ + %{ \ + genLd_Fixed(thisPrimitive, inOpcode, inAddress); \ + %} + +#define LDE_FIXED(inPrimOp, inReturnType, inOpcode) \ + inReturnType <- inPrimOp(Vptr[1] inAddress) cost(1) \ + %{ \ + genThrowIfZero(thisPrimitive, inAddress); \ + genLd_Fixed(thisPrimitive, inOpcode, inAddress); \ + %} + +#define LD_SEX(inPrimOp, inLdOpcode, inSexOpcode) \ + Vint <- inPrimOp(Vptr[1] inAddress) cost(1) \ + %{ \ + genLd_Fixed(thisPrimitive, inLdOpcode, inAddress); \ + \ + XInAOnly &ext = *new(mPool) XInAOnly(&thisPrimitive, mPool, inSexOpcode, pfNil, 0); \ + useProducer(thisPrimitive, ext, 0); \ + defineProducer(thisPrimitive, ext, 0); \ + %} + +#define LDE_SEX(inPrimOp, inLdOpcode, inSexOpcode) \ + Vint <- inPrimOp(Vptr[1] inAddress) cost(1) \ + %{ \ + genThrowIfZero(thisPrimitive, inAddress); \ + genLd_Fixed(thisPrimitive, inLdOpcode, inAddress); \ + \ + XInAOnly &ext = *new(mPool) XInAOnly(&thisPrimitive, mPool, inSexOpcode, pfNil, 0); \ + useProducer(thisPrimitive, ext, 0); \ + defineProducer(thisPrimitive, ext, 0); \ + %} + +#define LD_FLOATING(inPrimOp, inReturnType, inOpcode) \ + inReturnType <- inPrimOp(Vptr[1] inAddress) cost(1) \ + %{ \ + genLd_FP(thisPrimitive, inOpcode, inAddress); \ + %} + + +#define LDE_FLOATING(inPrimOp, inReturnType, inOpcode) \ + inReturnType <- inPrimOp(Vptr[1] inAddress) cost(1) \ + %{ \ + genThrowIfZero(thisPrimitive, inAddress); \ + genLd_FP(thisPrimitive, inOpcode, inAddress); \ + %} + + +LD_FIXED(poLd_I, Vint, dfLwz) +LD_FIXED(poLd_A, Vptr, dfLwz) +LD_FLOATING(poLd_F, Vfloat, dfLfs) + +LDE_FIXED(poLdE_I, Vint, dfLwz) +LDE_FIXED(poLdE_A, Vptr, dfLwz) +LDE_FLOATING(poLdE_F, Vfloat, dfLfs) + +LD_SEX(poLdS_B, dfLbz, xfExtsb) +LD_SEX(poLdS_H, dfLhz, xfExtsh) +LDE_SEX(poLdS_B, dfLbz, xfExtsb) +LDE_SEX(poLdS_H, dfLhz, xfExtsh) + +LD_FIXED(poLdU_B, Vint, dfLbz) +LD_FIXED(poLdU_H, Vint, dfLhz) +LDE_FIXED(poLdUE_B, Vint, dfLbz) +LDE_FIXED(poLdUE_H, Vint, dfLhz) + + +Store <- poSt_B(Vptr[1] inAddress, Vint inValue) cost(1) +%{ + genSt(thisPrimitive, dfStb, inAddress, inValue); +%} + +Store <- poSt_H(Vptr[1] inAddress, Vint inValue) cost(1) +%{ + genSt(thisPrimitive, dfSth, inAddress, inValue); +%} + +Store <- poSt_I(Vptr[1] inAddress, Vint inValue) cost(1) +%{ + genSt(thisPrimitive, dfStw, inAddress, inValue); +%} + +Store <- poSt_F(Vptr[1] inAddress, Vfloat inValue) cost(1) +%{ + genSt(thisPrimitive, dfStfs, inAddress, inValue); +%} + +Store <- poSt_A(Vptr[1] inAddress, Vptr inValue) cost(1) +%{ + genSt(thisPrimitive, dfStw, inAddress, inValue); +%} + +Store <- poStE_B(Vptr[1] inAddress, Vint inValue) cost(1) +%{ + genThrowIfZero(thisPrimitive, inAddress); // FIX-ME eliminate on AIX + genSt(thisPrimitive, dfStb, inAddress, inValue); +%} + +Store <- poStE_H(Vptr[1] inAddress, Vint inValue) cost(1) +%{ + genThrowIfZero(thisPrimitive, inAddress); // FIX-ME eliminate on AIX + genSt(thisPrimitive, dfSth, inAddress, inValue); +%} + +Store <- poStE_I(Vptr[1] inAddress, Vint inValue) cost(1) +%{ + genThrowIfZero(thisPrimitive, inAddress); // FIX-ME eliminate on AIX + genSt(thisPrimitive, dfStw, inAddress, inValue); +%} + +Store <- poStE_F(Vptr[1] inAddress, Vfloat inValue) cost(1) +%{ + genThrowIfZero(thisPrimitive, inAddress); // FIX-ME eliminate on AIX + genSt(thisPrimitive, dfStfs, inAddress, inValue); +%} + +Store <- poStE_A(Vptr[1] inAddress, Vptr inValue) cost(1) +%{ + genThrowIfZero(thisPrimitive, inAddress); // FIX-ME eliminate on AIX + genSt(thisPrimitive, dfStw, inAddress, inValue); +%} + + +Tuple <- poSysCall() cost(1) +%{ + CallS_& newInsn = *new CallS_(&thisPrimitive, mPool, CallS_::numberOfArguments(thisPrimitive), CallS_::hasReturnValue(thisPrimitive), *this, PrimSysCall::cast(thisPrimitive).sysCall.function); +%} + +Tuple <- poSysCallE() cost(1) +%{ + CallS_& newInsn = *new CallS_(&thisPrimitive, mPool, CallS_::numberOfArguments(thisPrimitive), CallS_::hasReturnValue(thisPrimitive), *this, PrimSysCall::cast(thisPrimitive).sysCall.function); +%} + +Tuple <- poSysCallC() cost(1) +%{ + CallS_C& newInsn = *new CallS_C(&thisPrimitive, mPool, CallS_C::numberOfArguments(thisPrimitive), CallS_C::hasReturnValue(thisPrimitive), *this, PrimSysCall::cast(thisPrimitive).sysCall.function); +%} + +Tuple <- poSysCallEC() cost(1) +%{ + CallS_C& newInsn = *new CallS_C(&thisPrimitive, mPool, CallS_C::numberOfArguments(thisPrimitive), CallS_C::hasReturnValue(thisPrimitive), *this, PrimSysCall::cast(thisPrimitive).sysCall.function); +%} + +Tuple <- poSysCallV() cost(1) +%{ + CallS_V& newInsn = *new CallS_V(&thisPrimitive, mPool, CallS_V::numberOfArguments(thisPrimitive), CallS_V::hasReturnValue(thisPrimitive), *this, PrimSysCall::cast(thisPrimitive).sysCall.function); +%} + +Tuple <- poSysCallEV() cost(1) +%{ + CallS_V& newInsn = *new CallS_V(&thisPrimitive, mPool, CallS_V::numberOfArguments(thisPrimitive), CallS_V::hasReturnValue(thisPrimitive), *this, PrimSysCall::cast(thisPrimitive).sysCall.function); +%} + +Tuple <- poCall(Vptr) cost(1) +%{ + // Dynamic call + CallD_& newInsn = *new CallD_(&thisPrimitive, mPool, CallD_::numberOfArguments(thisPrimitive), CallD_::hasReturnValue(thisPrimitive), *this); +%} + +Tuple <- poCall(poConst_A) cost(1) +%{ + // Static call + Call_& newInsn = *new Call_(&thisPrimitive, mPool, Call_::numberOfArguments(thisPrimitive), Call_::hasReturnValue(thisPrimitive), *this); +%} + diff --git a/ef/Compiler/CodeGenerator/md/ppc/ppc601-macos.nad b/ef/Compiler/CodeGenerator/md/ppc/ppc601-macos.nad new file mode 100644 index 000000000000..68f6ebda9be7 --- /dev/null +++ b/ef/Compiler/CodeGenerator/md/ppc/ppc601-macos.nad @@ -0,0 +1,286 @@ +%top +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#include "Burg.h" +% + +%terminals +% + +%startsymbols +Control +Result +Exception +Store +Vcond +Vint +Vlong +Vfloat +Vdouble +Vptr +Cint +Clong +Cfloat +Cdouble +Cptr +Tuple +% + +%grammar +Vint: coReg_I $1 $ +Vlong: coReg_L $1 $ +Vfloat: coReg_F $1 $ +Vdouble: coReg_D $1 $ +Vptr: coReg_A $1 $ +Vcond: coReg_C $1 $ +Store: coReg_M $1 $ +Cint: coReg_I $1 $ +Clong: coReg_L $1 $ +Cfloat: coReg_F $1 $ +Cdouble: coReg_D $1 $ +Cptr: coReg_A $1 $ + +Vint: poConst_I $1 $emConst_I +Vlong: poConst_L $1 $emConst_L +Vfloat: poConst_F $1 $emConst_F +//Vdouble: poConst_D $1 $emConst_D +Vptr: poConst_A $1 $emConst_A +//Vcond: poConst_C $1 $emConst_C + +//Store: poBreak(Store) $1 $emBreak + +Vint: poArg_I $1 $ +Vlong: poArg_L $1 $ +Vfloat: poArg_F $1 $ +Vdouble: poArg_D $1 $ +Vptr: poArg_A $1 $ +Store: poArg_M $1 $ + +Result: poResult_I(Vint) $1 $emResult_I +//Result: poResult_L(Vlong) $1 $emResult_L +Result: poResult_F(Vfloat) $1 $emResult_F +//Result: poResult_D(Vdouble) $1 $emResult_D +Result: poResult_A(Vptr) $1 $emResult_A +Result: poResult_M(Store) $1 $ + +Control: poIfLt(Vcond) $1 $emIfLt +Control: poIfEq(Vcond) $1 $emIfEq +Control: poIfLe(Vcond) $1 $emIfLe +Control: poIfGt(Vcond) $1 $emIfGt +Control: poIfLgt(Vcond) $1 $emIfLgt +Control: poIfGe(Vcond) $1 $emIfGe +Control: poIfOrd(Vcond) $1 $emIfOrd +//Control: poIfUnord(Vcond) $1 $emIfUnord +Control: poIfULt(Vcond) $1 $emIfULt +Control: poIfUEq(Vcond) $1 $emIfUEq +Control: poIfULe(Vcond) $1 $emIfULe +Control: poIfUGt(Vcond) $1 $emIfUGt +Control: poIfNe(Vcond) $1 $emIfNe +Control: poIfUGe(Vcond) $1 $emIfUGe + +//Control: poSwitch(Vint) $1 $emSwitch + +Vint: poAnd_I(Vint, Vint) $1 $emAnd_I +Vlong: poAnd_L(Vlong, Vlong) $1 $emAnd_L +Vint: poOr_I(Vint, Vint) $1 $emOr_I +Vlong: poOr_L(Vlong, Vlong) $1 $emOr_L +Vint: poXor_I(Vint, Vint) $1 $emXor_I +Vlong: poXor_L(Vlong, Vlong) $1 $emXor_L + +Vint: poAdd_I(Vint, Vint) $1 $emAdd_I +//Vlong: poAdd_L(Vlong, Vlong) $1 $emAdd_L +Vptr: poAdd_A(Vptr, Vint) $1 $emAdd_A +Vptr: poAddU_A(Vptr, Vint) $1 $emAddU_A + +Vint: poSub_I(Vint, Vint) $1 $emSub_I +//Vlong: poSub_L(Vlong, Vlong) $1 $emSub_L +Vptr: poSub_A(Vptr, Vint) $1 $emSub_A +Vptr: poSubU_A(Vptr, Vint) $1 $emSubU_A +Vint: poSubA_I(Vptr, Vptr) $1 $emSubA_I + +Vint: poMul_I(Vint, Vint) $1 $emMul_I +//Vlong: poMul_L(Vlong, Vlong) $1 $emMul_L + +Vint: poDiv_I(Vint, Vint) $1 $emDiv_I +//Vint: poDiv_L(Vlong, Vlong) $1 $emDiv_L +Vint: poDivE_I(Vint, Vint) $1 $emDivE_I +//Vint: poDivE_L(Vlong, Vlong) $1 $emDivE_L +Vint: poDivU_I(Vint, Vint) $1 $emDivU_I +//Vint: poDivU_L(Vlong, Vlong) $1 $emDivU_L +Vint: poDivUE_I(Vint, Vint) $1 $emDivUE_I +//Vint: poDivUE_L(Vlong, Vlong) $1 $emDivUE_L + +Vint: poMod_I(Vint, Vint) $1 $emMod_I +//Vint: poMod_L(Vlong, Vlong) $1 $emMod_L +Vint: poModE_I(Vint, Vint) $1 $emModE_I +//Vint: poModE_L(Vlong, Vlong) $1 $emModE_L +//Vint: poModU_I(Vint, Vint) $1 $emModU_I +//Vint: poModU_L(Vlong, Vlong) $1 $emModU_L +//Vint: poModUE_I(Vint, Vint) $1 $emModUE_I +//Vint: poModUE_L(Vlong, Vlong) $1 $emModUE_L + +Vint: poShl_I(Vint, Vint) $1 $emShl_I +//Vlong: poShl_L(Vlong, Vint) $1 $emShl_L + +//Vint: poShr_I(Vint, Vint) $1 $emShr_I +//Vlong: poShr_L(Vlong, Vint) $1 $emShr_L +//Vint: poShrU_I(Vint, Vint) $1 $emShrU_I +//Vlong: poShrU_L(Vlong, Vint) $1 $emShrU_L + +//Vint: poExt_I(Vint, Cint) $1 $emExt_I +//Vlong: poExt_L(Vlong, Cint) $1 $emExt_L + +Vfloat: poFAdd_F(Vfloat, Vfloat) $1 $emFAdd_F +//Vdouble: poFAdd_D(Vdouble, Vdouble) $1 $emFAdd_D + +//Vfloat: poFSub_F(Vfloat, Vfloat) $1 $emFSub_F +//Vdouble: poFSub_D(Vdouble, Vdouble) $1 $emFSub_D + +//Vfloat: poFMul_F(Vfloat, Vfloat) $1 $emFMul_F +//Vdouble: poFMul_D(Vdouble, Vdouble) $1 $emFMul_D + +//Vfloat: poFDiv_F(Vfloat, Vfloat) $1 $emFDiv_F +//Vdouble: poFDiv_D(Vdouble, Vdouble) $1 $emFDiv_D + +//Vfloat: poFRem_F(Vfloat, Vfloat) $1 $emFRem_F +//Vdouble: poFRem_D(Vdouble, Vdouble) $1 $emFRem_D + +//Vint: poConvI_L(Vlong) $1 $emConvI_L +//Vlong: poConvL_I(Vint) $1 $emConvL_I + +//Vint: poFConvI_F(Vfloat) $1 $emFConvI_F +//Vint: poFConvI_D(Vdouble) $1 $emFConvI_D +//Vlong: poFConvL_F(Vfloat) $1 $emFConvL_F +//Vlong: poFConvL_D(Vdouble) $1 $emFConvL_D +//Vfloat: poFConvF_I(Vint) $1 $emFConvF_I +//Vfloat: poFConvF_L(Vlong) $1 $emFConvF_L +//Vfloat: poFConvF_D(Vdouble) $1 $emFConvF_D +//Vdouble: poFConvD_I(Vint) $1 $emFConvD_I +//Vdouble: poFConvD_L(Vlong) $1 $emFConvD_L +//Vdouble: poFConvD_F(Vfloat) $1 $emFConvD_F + +Vcond: poCmp_I(Vint, Vint) $1 $emCmp_I +//Vcond: poCmp_L(Vlong, Vlong) $1 $emCmp_L +//Vcond: poCmpU_I(Vint, Vint) $1 $emCmpU_I +//Vcond: poCmpU_L(Vlong, Vlong) $1 $emCmpU_L +//Vcond: poCmpU_A(Vptr, Vptr) $1 $emCmpU_A + +//Vcond: poFCmp_F(Vfloat, Vfloat) $1 $emFCmp_F +//Vcond: poFCmp_D(Vdouble, Vdouble) $1 $emFCmp_D + +//Vint: poLt_I(Vcond) $1 $emLt_I +//Vint: poEq_I(Vcond) $1 $emEq_I +//Vint: poLe_I(Vcond) $1 $emLe_I +//Vint: poGt_I(Vcond) $1 $emGt_I +//Vint: poLgt_I(Vcond) $1 $emLgt_I +//Vint: poGe_I(Vcond) $1 $emGe_I +//Vint: poOrd_I(Vcond) $1 $emOrd_I +//Vint: poUnord_I(Vcond) $1 $emUnord_I +//Vint: poULt_I(Vcond) $1 $emULt_I +//Vint: poUEq_I(Vcond) $1 $emUEq_I +//Vint: poULe_I(Vcond) $1 $emULe_I +//Vint: poUGt_I(Vcond) $1 $emUGt_I +//Vint: poNe_I(Vcond) $1 $emNe_I +//Vint: poUGe_I(Vcond) $1 $emUGe_I + +//Vint: poCatL_I(Vcond) $1 $emCatL_I +//Vint: poCatG_I(Vcond) $1 $emCatG_I +//Vint: poCatCL_I(Vcond) $1 $emCatCL_I +//Vint: poCatCG_I(Vcond) $1 $emCatCG_I + +Exception: poChkNull(Vptr) $1 $emChkNull +Exception: poLimit(Vint, Vint) $1 $emLimit + +Vint: poLd_I(Vptr) $1 $emLd_I +//Vlong: poLd_L(Vptr) $1 $emLd_L +//Vfloat: poLd_F(Vptr) $1 $emLd_F +//Vdouble: poLd_D(Vptr) $1 $emLd_D +Vptr: poLd_A(Vptr) $1 $emLd_A +//Vint: poLdE_I(Cptr) $1 $emLdE_I +//Vlong: poLdE_L(Cptr) $1 $emLdE_L +//Vfloat: poLdE_F(Cptr) $1 $emLdE_F +//Vdouble: poLdE_D(Cptr) $1 $emLdE_D +//Vptr: poLdE_A(Cptr) $1 $emLdE_A +//Vint: poLdS_B(Vptr) $1 $emLdS_B +//Vint: poLdS_H(Vptr) $1 $emLdS_H +//Vint: poLdSE_B(Cptr) $1 $emLdSE_B +//Vint: poLdSE_H(Cptr) $1 $emLdSE_H +//Vint: poLdU_B(Vptr) $1 $emLdU_B +//Vint: poLdU_H(Vptr) $1 $emLdU_H +//Vint: poLdUE_B(Cptr) $1 $emLdUE_B +//Vint: poLdUE_H(Cptr) $1 $emLdUE_H +//Vint: poLdV_I(Vptr) $1 $emLdV_I +//Vlong: poLdV_L(Vptr) $1 $emLdV_L +//Vfloat: poLdV_F(Vptr) $1 $emLdV_F +//Vdouble: poLdV_D(Vptr) $1 $emLdV_D +//Vptr: poLdV_A(Vptr) $1 $emLdV_A +//Vint: poLdVE_I(Cptr) $1 $emLdVE_I +//Vlong: poLdVE_L(Cptr) $1 $emLdVE_L +//Vfloat: poLdVE_F(Cptr) $1 $emLdVE_F +//Vdouble: poLdVE_D(Cptr) $1 $emLdVE_D +//Vptr: poLdVE_A(Cptr) $1 $emLdVE_A + +Vint: poLd_I(poAdd_A(Vptr, Cint)) $0 $emLd_IRegisterIndirect +Vptr: poLd_A(poAdd_A(Vptr, Cint)) $0 $emLd_ARegisterIndirect + +//Store: poSt_B(Vptr, Vint) $1 $emSt_B +//Store: poSt_H(Vptr, Vint) $1 $emSt_H +Store: poSt_I(Vptr, Vint) $1 $emSt_I +//Store: poSt_L(Vptr, Vlong) $1 $emSt_L +//Store: poSt_F(Vptr, Vfloat) $1 $emSt_F +//Store: poSt_D(Vptr, Vdouble) $1 $emSt_D +//Store: poSt_A(Vptr, Vptr) $1 $emSt_A +//Store: poStE_B(Cptr, Vint) $1 $emStE_B +//Store: poStE_H(Cptr, Vint) $1 $emStE_H +//Store: poStE_I(Cptr, Vint) $1 $emStE_I +//Store: poStE_L(Cptr, Vlong) $1 $emStE_L +//Store: poStE_F(Cptr, Vfloat) $1 $emStE_F +//Store: poStE_D(Cptr, Vdouble) $1 $emStE_D +//Store: poStE_A(Cptr, Vptr) $1 $emStE_A +//Store: poStV_B(Vptr, Vint) $1 $emStV_B +//Store: poStV_H(Vptr, Vint) $1 $emStV_H +//Store: poStV_I(Vptr, Vint) $1 $emStV_I +//Store: poStV_L(Vptr, Vlong) $1 $emStV_L +//Store: poStV_F(Vptr, Vfloat) $1 $emStV_F +//Store: poStV_D(Vptr, Vdouble) $1 $emStV_D +//Store: poStV_A(Vptr, Vptr) $1 $emStV_A +//Store: poStVE_B(Cptr, Vint) $1 $emStVE_B +//Store: poStVE_H(Cptr, Vint) $1 $emStVE_H +//Store: poStVE_I(Cptr, Vint) $1 $emStVE_I +//Store: poStVE_L(Cptr, Vlong) $1 $emStVE_L +//Store: poStVE_F(Cptr, Vfloat) $1 $emStVE_F +//Store: poStVE_D(Cptr, Vdouble) $1 $emStVE_D +//Store: poStVE_A(Cptr, Vptr) $1 $emStVE_A + +Store: poSt_I(poAdd_A(Vptr, poConst_I), Vint) $0 $emSt_IRegisterIndirect + +Store: poProj_M $1 $ +Vint: poProj_I $1 $ +Vptr: poProj_A $1 $ + +Tuple: poSysCall $1 $emSysCall +Tuple: poSysCallE $1 $emSysCallE +Tuple: poSysCallC $1 $emSysCallC +Tuple: poSysCallEC $1 $emSysCallEC +Tuple: poSysCallV $1 $emSysCallV +Tuple: poSysCallEV $1 $emSysCallEV + +Tuple: poCall(Vptr) $1 $emDynamicCall +Tuple: poCall(poConst_A) $1 $emStaticCall +% + diff --git a/ef/Compiler/CodeGenerator/md/sparc/Makefile b/ef/Compiler/CodeGenerator/md/sparc/Makefile new file mode 100644 index 000000000000..fca486149848 --- /dev/null +++ b/ef/Compiler/CodeGenerator/md/sparc/Makefile @@ -0,0 +1,72 @@ +#!gmake +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +DEPTH = ../../../.. + +MODULE_NAME = sparc + +include $(DEPTH)/config/config.mk + +INCLUDES += \ + -I$(DEPTH)/Utilities/General \ + -I$(DEPTH)/Utilities/zlib \ + -I$(DEPTH)/Runtime/ClassReader \ + -I$(DEPTH)/Compiler/FrontEnd \ + -I$(DEPTH)/Runtime/NativeMethods \ + -I$(DEPTH)/Runtime/System \ + -I$(DEPTH)/Compiler/PrimitiveGraph \ + -I$(DEPTH)/Runtime/ClassInfo \ + -I$(DEPTH)/Runtime/FileReader \ + -I$(DEPTH)/Compiler/CodeGenerator \ + -I$(DEPTH)/Compiler/CodeGenerator/md \ + -I$(DEPTH)/Compiler/RegisterAllocator \ + $(NULL) + +CXXSRCS = \ + SparcInstruction.cpp \ + SparcSunOSEmitter.cpp \ + sparc.nad.burg.cpp \ + $(NULL) + +include $(DEPTH)/config/rules.mk + +export:: sparc.nad.burg.cpp + +libs:: $(MODULE) + +# +# Rules to generate sparc.nad.burg.[cpp][h] +# + +sparc.nad.burg.cpp: sparc.nad.burg $(BURG) + $(BURG) -I -o $@ < $< + +sparc.nad.burg: sparc.nad $(DEPTH)/Compiler/PrimitiveGraph/PrimitiveOperations $(DEPTH)/Tools/Nad/nad.pl + $(PERL) $(DEPTH)/Tools/Nad/nad.pl $< $(DEPTH)/Compiler/PrimitiveGraph/PrimitiveOperations \ + $(DEPTH)/Compiler/PrimitiveGraph/PrimitiveOperations.h \ + $(DEPTH)/Compiler/PrimitiveGraph/PrimitiveOperations.cpp \ + $<.burg.h > $@ + +# +# Extra cleaning +# + +clobber:: + rm -f sparc.nad.burg.cpp sparc.nad.burg.h sparc.nad.burg + +realclean clobber_all:: + rm -f sparc.nad.burg.cpp sparc.nad.burg.h sparc.nad.burg diff --git a/ef/Compiler/CodeGenerator/md/sparc/SparcInstruction.cpp b/ef/Compiler/CodeGenerator/md/sparc/SparcInstruction.cpp new file mode 100644 index 000000000000..fdce698bd1e5 --- /dev/null +++ b/ef/Compiler/CodeGenerator/md/sparc/SparcInstruction.cpp @@ -0,0 +1,297 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#include "Fundamentals.h" +#include "SparcInstruction.h" +#include "ControlNodes.h" + +SparcInstructionInfo siInfo[nSparcInstructionKind] = +{ + { siAnd, 2, 0x01, "and" }, + { siAndCC, 2, 0x11, "andcc" }, + { siAndN, 2, 0x05, "andn" }, + { siAndNCC, 2, 0x15, "andncc" }, + { siOr, 2, 0x02, "or" }, + { siOrCC, 2, 0x12, "orcc" }, + { siOrN, 2, 0x06, "orn" }, + { siOrNCC, 2, 0x16, "orncc" }, + { siXor, 2, 0x03, "xor" }, + { siXorCC, 2, 0x13, "xorcc" }, + { siXNor, 2, 0x07, "xnor" }, + { siXNorCC, 2, 0x17, "xnorcc" }, + { siSll, 2, 0x25, "sll" }, + { siSrl, 2, 0x26, "srl" }, + { siSra, 2, 0x27, "sra" }, + { siAdd, 2, 0x00, "add" }, + { siAddCC, 2, 0x10, "addcc" }, + { siAddX, 2, 0x08, "addx" }, + { siAddXCC, 2, 0x18, "addxcc" }, + { siSub, 2, 0x04, "sub" }, + { siSubCC, 2, 0x14, "subcc" }, + { siSubX, 2, 0x0c, "subx" }, + { siSubXCC, 2, 0x1c, "subxcc" }, + { siUMul, 2, 0x0a, "umul" }, + { siUMulCC, 2, 0x1a, "umulcc" }, + { siSMul, 2, 0x0b, "smul" }, + { siSMulCC, 2, 0x1b, "smulcc" }, + { siUDiv, 2, 0x0e, "udiv" }, + { siUDivCC, 2, 0x1e, "udivcc" }, + { siSDiv, 2, 0x0f, "sdiv" }, + { siSDivCC, 2, 0x1f, "sdvicc" }, + { siTrap, 2, 0x3a, "trap" }, + { siLdSb, 3, 0x09, "ldsb" }, + { siLdSh, 3, 0x0a, "ldsh" }, + { siLdUb, 3, 0x01, "ldub" }, + { siLdUh, 3, 0x02, "lduh" }, + { siLd, 3, 0x00, "ld" }, + { siLdd, 3, 0x03, "ldd" }, + { siStSb, 3, 0x05, "stsb" }, + { siStSh, 3, 0x06, "stsh" }, + { siSt, 3, 0x04, "st" }, + { siStd, 3, 0x07, "std" }, + { siBranch, 0, 0x02, "b" }, +}; + +SparcAccessInfo saInfo[nSparcAccessKind] = +{ + { saRRR, 2, 1 }, + { saRIR, 1, 1 }, + { saRZR, 1, 1 }, + { saZRR, 1, 1 }, + { saZIR, 0, 1 }, + { saZZR, 0, 1 }, + { saRRZ, 2, 0 }, + { saRIZ, 1, 0 }, + { saRZZ, 1, 0 }, +}; + +SparcConditionInfo scInfo[nSparcConditionKind] = +{ + { scA, 0x08, "a" }, + { scN, 0x00, "n" }, + { scNe, 0x09, "ne" }, + { scE, 0x01, "e" }, + { scG, 0x0a, "g" }, + { scLe, 0x02, "le" }, + { scGe, 0x0b, "ge" }, + { scL, 0x03, "l" }, + { scGu, 0x0c, "gu" }, + { scLeu, 0x04, "leu" }, + { scCc, 0x0d, "cc" }, + { scGeu, 0x0d, "cc" }, + { scCs, 0x05, "cs" }, + { scLu, 0x05, "cs" }, + { scPos, 0x0e, "pos" }, + { scNeg, 0x06, "neg" }, + { scVc, 0x0f, "vc" }, + { scVs, 0x07, "vs" } +}; + +char* registerNumberToString[] = +{ + "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7", + "o0", "o1", "o2", "o3", "o4", "o5", "sp", "o7", + "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7", + "i0", "i1", "i2", "i3", "i4", "i5", "fp", "i7" +}; + +uint8 registerNumberToColor[] = +{ + 255, 255, 255, 255, 255, 255, 255, 255, + 8, 9, 10, 11, 12, 13, 255, 255, + 0, 1, 2, 3, 4, 5, 6, 7, + 14, 15, 16, 17, 18, 19, 255, 255 +}; + +SparcRegisterNumber colorToRegisterNumber[] = +{ + l0, l1, l2, l3, l4, l5, l6, l7, + o0, o1, o2, o3, o4, o5, + i0, i1, i2, i3, i4, i5, +}; + +void SparcFormatBCond:: +formatToMemory(void* inStart, uint32 inOffset) +{ + uint32 insn = 0; + insn |= (siInfo[kind].op & 0x3) << 30; + if (a) insn |= (1 << 29); + insn |= (scInfo[cond].cond & 0xf) << 25; + insn |= (siInfo[kind].op3 & 0x7) << 22; + insn |= ((target.getNativeOffset() - inOffset) >> 2) & 0x3fffff; + *(uint32*) inStart = insn; + if (a) ((uint32*) inStart)[1] = 1 << 24; +} + +void SparcFormatC:: +formatToMemory(void* inStart, uint32 /*inOffset*/) +{ + uint32 insn = 0; + + insn |= (siInfo[kind].op & 0x3) << 30; + insn |= (getRD() & 0x1f) << 25; + insn |= (siInfo[kind].op3 & 0x3f) << 19; + insn |= (getRS1() & 0x1f) << 14; + if (imm13) + insn |= (imm13 | 0x2000); + else + insn |= getRS2(); + + *(uint32*) inStart = insn; +} + + +void SparcFormatC:: +printPretty(FILE* f) +{ + switch (access) + { + case saRIR: case saZIR: case saRIZ: + fprintf(f, "%s %%%s,%d,%%%s", siInfo[kind].string, + registerNumberToString[getRS1()], + imm13, + registerNumberToString[getRD()]); + break; + default: + fprintf(f, "%s %%%s,%%%s,%%%s", siInfo[kind].string, + registerNumberToString[getRS1()], + registerNumberToString[getRS2()], + registerNumberToString[getRD()]); + } +} + +void SparcLoadStore:: +printPretty(FILE* f) +{ + switch (access) + { + case saRIR: case saRZR: + if (isLoad) + fprintf(f, "%s [%%%s+%d],%%%s", siInfo[kind].string, + registerNumberToString[getRS1()], + imm13, + registerNumberToString[getRD()]); + else + fprintf(f, "%s %%%s,[%%%s+%d]", siInfo[kind].string, + registerNumberToString[getRD()], + registerNumberToString[getRS1()], + imm13); + break; + default: + if (isLoad) + fprintf(f, "%s [%%%s+%%%s],%%%s", siInfo[kind].string, + registerNumberToString[getRS1()], + registerNumberToString[getRS2()], + registerNumberToString[getRD()]); + else + fprintf(f, "%s %%%s,[%%%s+%%%s]", siInfo[kind].string, + registerNumberToString[getRD()], + registerNumberToString[getRS1()], + registerNumberToString[getRS2()]); + break; + } +} + +void SparcTrap:: +printPretty(FILE* f) +{ + fprintf(f, "t%s throw_exception", scInfo[cond].string); +} + +void SparcFormatBCond:: +printPretty(FILE* f) +{ + fprintf(f, "%s%s%s N%d%s", siInfo[kind].string, scInfo[cond].string, a ? ",a" : "", + target.dfsNum, a ? "; nop" : ""); +} + +uint8 SparcFormatC:: +getRS1() +{ + switch (access) + { + case saZRR: case saZIR: case saZZR: + return g0; + + default: + return useToRegisterNumber(getInstructionUseBegin()[0]); + } +} + +uint8 SparcFormatC:: +getRS2() +{ +#if DEBUG + if (access == saRIR || access == saZIR || access == saRIZ) assert(0); +#endif + + switch (access) + { + case saZZR: case saRZZ: case saRZR: + return g0; + + default: + return useToRegisterNumber(getInstructionUseBegin()[1]); + } +} + +uint8 SparcFormatC:: +getRD() +{ + switch (access) + { + case saRRZ: case saRIZ: case saRZZ: + return g0; + + default: + return defineToRegisterNumber(getInstructionDefineBegin()[0]); + } +} + +uint8 SparcLoadStore:: +getRS1() +{ + switch (access) + { + case saZRR: case saZIR: case saZZR: + return g0; + + default: + return useToRegisterNumber(getInstructionUseBegin()[isLoadC ? 0 : 1]); + } +} + +uint8 SparcLoadStore:: +getRS2() +{ + assert(0); +} + +uint8 SparcLoadStore:: +getRD() +{ + switch (access) + { + case saRRZ: case saRIZ: case saRZZ: + return g0; + + default: + return (isLoad) ? defineToRegisterNumber(getInstructionDefineBegin()[hasMemoryEdge ? 1 : 0]) : + useToRegisterNumber(getInstructionUseBegin()[2]); + } +} diff --git a/ef/Compiler/CodeGenerator/md/sparc/SparcInstruction.h b/ef/Compiler/CodeGenerator/md/sparc/SparcInstruction.h new file mode 100644 index 000000000000..6215df57fc65 --- /dev/null +++ b/ef/Compiler/CodeGenerator/md/sparc/SparcInstruction.h @@ -0,0 +1,318 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#ifndef _SPARC_INSTRUCTION_H_ +#define _SPARC_INSTRUCTION_H_ + +#include "Fundamentals.h" +#include "Instruction.h" + +// +// Instruction format A (op=1): CALL +// +// |31 |29 0| +// |-----------------------------------------------------------------------------------------------| +// | op | disp30 | +// |-----------------------------------------------------------------------------------------------| +// +// +// Instruction format B (op=0): SETHI & Branches +// +// |31 |29|28 |24 |21 0| +// |-----------------------------------------------------------------------------------------------| +// | op | rd | op2 | imm22 | +// |-----------------------------------------------------------------------------------------------| +// | op |a | cond | op2 | disp22 | +// |-----------------------------------------------------------------------------------------------| +// +// +// Instruction format C (op=2|op=3): arithmetic, logical, shift, memory instructions & remaining. +// +// |31 |29 |24 |18 |13|12 |4 0| +// |-----------------------------------------------------------------------------------------------| +// | op | rd | op3 | rs1 |0 | asi | rs2 | +// |-----------------------------------------------------------------------------------------------| +// | op | rd | op3 | rs1 |1 | simm13 | +// |-----------------------------------------------------------------------------------------------| +// | op | rd | op3 | rs1 | opf | rs2 | +// |-----------------------------------------------------------------------------------------------| +// + +enum SparcInstructionKind +{ + siAnd, + siAndCC, + siAndN, + siAndNCC, + siOr, + siOrCC, + siOrN, + siOrNCC, + siXor, + siXorCC, + siXNor, + siXNorCC, + siSll, + siSrl, + siSra, + siAdd, + siAddCC, + siAddX, + siAddXCC, + siSub, + siSubCC, + siSubX, + siSubXCC, + siUMul, + siUMulCC, + siSMul, + siSMulCC, + siUDiv, + siUDivCC, + siSDiv, + siSDivCC, + siTrap, + siLdSb, + siLdSh, + siLdUb, + siLdUh, + siLd, + siLdd, + siStSb, + siStSh, + siSt, + siStd, + siBranch, + nSparcInstructionKind +}; + +enum SparcAccessKind +{ + saRRR, // insn r[s1],r[s2],r[d] + saRIR, // insn r[s1],imm13,r[d] + saRZR, // insn r[s1],r[g0],r[d] + saZRR, // insn r[g0],r[s2],r[d] + saZIR, // insn r[g0],imm13,r[d] + saZZR, // insn r[g0],r[g0],r[d] + saRRZ, // insn r[s1],r[s2],r[g0] + saRIZ, // insn r[s1],imm13,r[g0] + saRZZ, // insn r[s1],r[g0],r[g0] + nSparcAccessKind +}; + +#define saRR saRRZ +#define saRI saRIZ +#define saRZ saRZZ + +enum SparcConditionKind +{ + scA, // always + scN, // never + scNe, // on Not Equal + scE, // on Equal + scG, // on Greater + scLe, // on Less or Equal + scGe, // on Greater or Equal + scL, // on Less + scGu, // on Greater Unsigned + scLeu, // on Less or Equal Unsigned + scCc, // on Carry Clear (Greater than or Equal, Unsigned) + scGeu, + scCs, // on Carry Set (Less than, Unsigned) + scLu, + scPos, // on Positive + scNeg, // on Negative + scVc, // on Overflow Clear + scVs, // on Overflow Set + nSparcConditionKind +}; + +enum SparcRegisterNumber +{ + g0, g1, g2, g3, g4, g5, g6, g7, + o0, o1, o2, o3, o4, o5, sp, o7, + l0, l1, l2, l3, l4, l5, l6, l7, + i0, i1, i2, i3, i4, i5, fp, i7 +}; + +struct SparcConditionInfo +{ + SparcConditionKind kind; + uint8 cond; + char *string; +}; + +struct SparcInstructionInfo +{ + SparcInstructionKind kind; + uint8 op; + uint8 op3; + char* string; +}; + +struct SparcAccessInfo +{ + SparcAccessKind kind; + uint8 nConsumer; + uint8 nProducer; +}; + +extern SparcInstructionInfo siInfo[]; +extern SparcAccessInfo saInfo[]; +extern SparcConditionInfo scInfo[]; +extern char* registerNumberToString[]; +extern SparcRegisterNumber colorToRegisterNumber[]; +extern uint8 registerNumberToColor[]; + +class SparcFormatBCond : public InsnUseXDefineYFromPool +{ +protected: + SparcInstructionKind kind; + SparcConditionKind cond; + bool a; + ControlNode& target; + +public: + SparcFormatBCond(DataNode* inPrimitive, Pool& inPool, ControlNode& t, SparcInstructionKind iKind, SparcConditionKind cKind, bool annul) : + InsnUseXDefineYFromPool(inPrimitive, inPool, 1, 0), + kind(iKind), cond(cKind), a(annul), target(t) {} + + virtual void printPretty(FILE* f); + virtual size_t getFormattedSize() {return (a ? 8 : 4);} + virtual void formatToMemory(void* inStart, uint32 inOffset); +}; + + +class SparcBranch : public SparcFormatBCond +{ +public: + SparcBranch(DataNode* inPrimitive, Pool& inPool, ControlNode& t, SparcConditionKind cKind, bool annul) : + SparcFormatBCond(inPrimitive, inPool, t, siBranch, cKind, annul) {} +}; + +class SparcFormatC : public InsnUseXDefineYFromPool +{ +protected: + SparcInstructionKind kind; + SparcAccessKind access; + int16 imm13; + +public: + SparcFormatC(DataNode* inPrimitive, Pool& inPool, uint8 nConsumer = 0, uint8 nProducer = 0) : + InsnUseXDefineYFromPool(inPrimitive, inPool, nConsumer, nProducer) {} + + virtual void printPretty(FILE* f); + virtual size_t getFormattedSize() {return 4;} + virtual void formatToMemory(void* inStart, uint32 /*inOffset*/); + + + inline SparcRegisterNumber useToRegisterNumber(InstructionUse& use); + inline SparcRegisterNumber defineToRegisterNumber(InstructionDefine& use); + + virtual uint8 getRS1(); + virtual uint8 getRS2(); + virtual uint8 getRD(); +}; + +class SparcInsn : public SparcFormatC +{ +public: + SparcInsn(DataNode* inPrimitive, Pool& inPool, SparcInstructionKind iKind, SparcAccessKind aKind, int16 constant = 0) : + SparcFormatC(inPrimitive, inPool, saInfo[aKind].nConsumer, saInfo[aKind].nProducer) + {kind = iKind; access = aKind; imm13 = constant;} + + virtual InstructionFlags getFlags() const {if (kind == siOr && access == saRZR) return (ifCopy); else return(ifNone);} +}; + +class SparcTrap : public SparcFormatC +{ +protected: + SparcConditionKind cond; +public: + SparcTrap(DataNode* inPrimitive, Pool& inPool, SparcConditionKind cKind, SparcAccessKind aKind, int16 constant = 0) : + SparcFormatC(inPrimitive, inPool, 1, 0), cond(cKind) + {kind = siTrap; access = aKind; imm13 = constant;} + virtual uint8 getRS1() {return g0;} + virtual uint8 getRS2() {return g0;} + virtual uint8 getRD() {return scInfo[cond].cond;} + virtual void printPretty(FILE* f); +}; + +class SparcCmp : public SparcFormatC +{ +public: + SparcCmp(DataNode* inPrimitive, Pool& inPool, SparcAccessKind aKind, int16 constant = 0) : + SparcFormatC(inPrimitive, inPool, saInfo[aKind].nConsumer, 1) + {kind = siSubCC; access = aKind; imm13 = constant;} +}; + +class SparcLoadStore : public SparcFormatC +{ +protected: + bool hasMemoryEdge; + bool isLoad; + bool isLoadC; + +public: + SparcLoadStore(DataNode* inPrimitive, Pool& inPool, SparcInstructionKind iKind, SparcAccessKind aKind, bool has_mem, bool is_load, bool is_loadC, int16 constant = 0) : + SparcFormatC(inPrimitive, inPool, is_load ? (is_loadC ? 1 : 2) : 3, (is_load && has_mem) ? 2 : 1), hasMemoryEdge(has_mem), isLoad(is_load), isLoadC(is_loadC) + { + kind = iKind; access = aKind; imm13 = constant; + } + virtual void printPretty(FILE* f); + virtual uint8 getRS1(); + virtual uint8 getRS2(); + virtual uint8 getRD(); +}; + +class SparcLoadC : public SparcLoadStore +{ +public: + SparcLoadC(DataNode* inPrimitive, Pool& inPool, SparcInstructionKind iKind, SparcAccessKind aKind, int16 constant = 0) : + SparcLoadStore(inPrimitive, inPool, iKind, aKind, false, true, true, constant) {} +}; + +class SparcLoad : public SparcLoadStore +{ +public: + SparcLoad(DataNode* inPrimitive, Pool& inPool, SparcInstructionKind iKind, SparcAccessKind aKind, bool memEdge, int16 constant = 0) : + SparcLoadStore(inPrimitive, inPool, iKind, aKind, memEdge, true, false, constant) {} +}; + +class SparcStore : public SparcLoadStore +{ +public: + SparcStore(DataNode* inPrimitive, Pool& inPool, SparcInstructionKind iKind, SparcAccessKind aKind, int16 constant = 0) : + SparcLoadStore(inPrimitive, inPool, iKind, aKind, true, false, false, constant) {} +}; + +inline SparcRegisterNumber SparcFormatC:: +useToRegisterNumber(InstructionUse& use) +{ + assert(use.isVirtualRegister()); + return (colorToRegisterNumber[use.getVirtualRegister().getColor()]); +} + +inline SparcRegisterNumber SparcFormatC:: +defineToRegisterNumber(InstructionDefine& def) +{ + assert(def.isVirtualRegister()); + return (colorToRegisterNumber[def.getVirtualRegister().getColor()]); +} + +#endif /* _SPARC_INSTRUCTION_H_ */ diff --git a/ef/Compiler/CodeGenerator/md/sparc/SparcSunOSEmitter.cpp b/ef/Compiler/CodeGenerator/md/sparc/SparcSunOSEmitter.cpp new file mode 100644 index 000000000000..dedd8587fcea --- /dev/null +++ b/ef/Compiler/CodeGenerator/md/sparc/SparcSunOSEmitter.cpp @@ -0,0 +1,591 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#include "SparcSunOSEmitter.h" +#include "SparcInstruction.h" +#include "ControlNodes.h" +#include "sparc-sunos.nad.burg.h" + +#define BINARY_PRIMITIVE_I(inRuleKind, inOp) \ + case inRuleKind: \ + emit_Insn_I(inPrimitive, inOp); \ + break; + +#define BINARY_PRIMITIVEI_I(inRuleKind, inOp) \ + case inRuleKind: \ + emit_InsnI_I(inPrimitive, inOp); \ + break; + +#define UNDEFINED_RULE(inRuleKind) \ + case inRuleKind: \ + assert(false); \ + break; + +#define BINARY_PRIMITIVE_SET(inRuleRoot, inOp) \ + BINARY_PRIMITIVE_I(inRuleRoot##_I, inOp); \ + UNDEFINED_RULE(inRuleRoot##_L); \ + BINARY_PRIMITIVEI_I(inRuleRoot##I_I, inOp); \ + UNDEFINED_RULE(inRuleRoot##I_L); + +void SparcSunOSEmitter:: +emitPrimitive(Primitive& inPrimitive, NamedRule inRule) +{ + switch (inRule) + { + case emConst_I: + emit_Const_I(inPrimitive); + break; + case emArg_I: + case emArg_L: + case emArg_F: + case emArg_D: + case emArg_A: + assert(false); + break; + case emResult_M: + case emArg_M: + break; + case emResult_I: + { + VirtualRegister* returnVr; + if (inPrimitive.nthInputIsConstant(0)) + { + returnVr = &genLoadConstant(inPrimitive, inPrimitive.nthInputConstant(0).i); + } + else + { + SparcInsn& copyInsn = *new(mPool) SparcInsn(&inPrimitive, mPool, siOr, saRZR); + + returnVr = &defineTemporary(copyInsn, 0); + useProducer(inPrimitive.nthInputVariable(0), copyInsn, 0); + } + + returnVr->precolorRegister(registerNumberToColor[o0]); + + InsnExternalUse& externalUse = *new(mPool) InsnExternalUse(&inPrimitive); + useTemporaryVR(externalUse, *returnVr, 0); + inPrimitive.setInstructionRoot(&externalUse); + } + break; + case emIfLt: + emit_B(inPrimitive, scL); + break; + case emIfULt: + emit_B(inPrimitive, scLu); + break; + case emIfEq: + case emIfUEq: + emit_B(inPrimitive, scE); + break; + case emIfLe: + emit_B(inPrimitive, scLe); + break; + case emIfULe: + emit_B(inPrimitive, scLeu); + break; + case emIfGt: + emit_B(inPrimitive, scG); + break; + case emIfUGt: + emit_B(inPrimitive, scGu); + break; + case emIfLgt: + case emIfNe: + emit_B(inPrimitive, scNe); + break; + case emIfGe: + emit_B(inPrimitive, scGe); + break; + case emIfUGe: + emit_B(inPrimitive, scGeu); + break; + case emIfOrd: + case emIfUnord: + assert(false); // Shouldn't happen with int edges... + break; + BINARY_PRIMITIVE_SET(emAnd, siAnd); + BINARY_PRIMITIVE_SET(emOr, siOr ); + BINARY_PRIMITIVE_SET(emXor, siXor); + BINARY_PRIMITIVE_SET(emAdd, siAdd); + case emAdd_A: + emit_Insn_I(inPrimitive, siAdd); + break; + case emAddI_A: + emit_InsnI_I(inPrimitive, siAdd); + break; + BINARY_PRIMITIVE_SET(emMul, siSMul); + case emDivI_I: + emit_DivI_I(inPrimitive); + break; + case emModE_I: + emit_ModE_I(inPrimitive); + break; + case emShlI_I: + emit_InsnI_I(inPrimitive, siSll); + break; + case emChkNull: + emit_ChkNull(inPrimitive); + break; + case emLimitR: + emit_LimitR(inPrimitive); + break; + case emLimit: + emit_Limit(inPrimitive); + break; + case emLdC_IRegisterIndirect: + emit_LdC_IRegisterIndirect(inPrimitive); + break; + case emLd_IRegisterIndirect: + emit_Ld_IRegisterIndirect(inPrimitive); + break; + case emLdC_I: + fprintf(stdout, "*** should emit emLdC_I\n"); + //genLoadIZero(inPrimitive, pfConstant); + break; + case emLd_I: + fprintf(stdout, "*** should emit emLd_I\n"); + //genLoadIZero(inPrimitive, 0); + break; + case emSt_I: + fprintf(stdout, "*** should emit emSt_I\n"); + //{ + //StoreNoUpdateD& newInsn = *new(mPool) StoreNoUpdateD(&inPrimitive, mPool, dfStw, 0, 0); + //newInsn.standardUseDefine(*this); + //} + break; + case emStI_I: + fprintf(stdout, "*** should emit emStI_I\n"); + //emit_StI_I(inPrimitive); + break; + case emStI_IRegisterIndirect: + emit_StI_IRegisterIndirect(inPrimitive); + break; + case emSt_IRegisterIndirect: + emit_St_IRegisterIndirect(inPrimitive); + break; + case emCallI_I: + case emCallI_L: + case emCallI_F: + case emCallI_D: + case emCallI_P: + fprintf(stdout, "*** should emit emCallI_P\n"); + //emit_Call(inPrimitive); + break; + case emCmp_I: + emit_Cmp_I(inPrimitive); + break; + case emCmpI_I: + emit_CmpI_I(inPrimitive); + break; + default: + //assert(false) + break; + } +} + +void SparcSunOSEmitter:: +emit_Const_I(Primitive& inPrimitive) +{ + int32 constI = (*static_cast(&inPrimitive)).value.i; + if ((constI >= -4096) && (constI <= 4095)) + { + SparcInsn& newInsn = *new(mPool) SparcInsn(&inPrimitive, mPool, siOr, constI ? saZIR : saZZR, constI & 0x1fff); + defineProducer(inPrimitive, newInsn, 0); + } + else if ((constI & 0x1fff) == 0) + { + // FIXME + assert(0); + } + else + { + // FIXME + assert(0); + } +} + +void SparcSunOSEmitter:: +emit_InsnI_I(Primitive& inPrimitive, SparcInstructionKind kind) +{ + int32 constI = inPrimitive.nthInputConstant(1).i; + if ((constI >= -4096) && (constI <= 4095)) + { + SparcInsn& newInsn = *new(mPool) SparcInsn(&inPrimitive, mPool, kind, constI ? saRIR : saRZR, constI & 0x1fff); + newInsn.standardUseDefine(*this); + } + else + { + assert(0); + } +} + +void SparcSunOSEmitter:: +emit_Insn_I(Primitive& inPrimitive, SparcInstructionKind kind) +{ + SparcInsn& newInsn = *new(mPool) SparcInsn(&inPrimitive, mPool, kind, saRRR); + newInsn.standardUseDefine(*this); +} + +void SparcSunOSEmitter:: +emit_Cmp_I(Primitive& inPrimitive) +{ + SparcCmp& newInsn = *new(mPool) SparcCmp(&inPrimitive, mPool, saRR); + newInsn.standardUseDefine(*this); +} + +void SparcSunOSEmitter:: +emit_CmpI_I(Primitive& inPrimitive) +{ + int32 constI = inPrimitive.nthInputConstant(1).i; + if ((constI >= -4096) && (constI <= 4095)) + { + SparcCmp& newInsn = *new(mPool) SparcCmp(&inPrimitive, mPool, constI ? saRI : saRZ, constI & 0x1fff); + newInsn.standardUseDefine(*this); + } + else + { + assert(0); + } +} + +void SparcSunOSEmitter:: +emit_B(Primitive& inPrimitive, SparcConditionKind cond) +{ + ControlIf& controlIf = ControlIf::cast(*inPrimitive.getContainer()); + SparcBranch& newInsn = *new(mPool) SparcBranch(&inPrimitive, mPool, *(controlIf.getTrueIfEdge().target), cond, true); + newInsn.standardUseDefine(*this); +} + +Instruction& SparcSunOSEmitter:: +emitAbsoluteBranch(DataNode& inDataNode, ControlNode& inTarget) +{ + SparcBranch& newInsn = *new(mPool) SparcBranch(&inDataNode, mPool, inTarget, scA, true); + return (newInsn); +} + +void SparcSunOSEmitter:: +emitArguments(ControlBegin& inBeginNode) +{ + uint32 curParamWords; // number of words of argument space used + uint32 curFloatingPointArg; // number of floating point arguments + + InsnExternalDefine& defineInsn = *new(mPool) InsnExternalDefine(&inBeginNode.arguments[0], mPool, inBeginNode.nArguments * 2); + + uint32 curArgIdx; // current index into the arguments in the ControlBegin + + curParamWords = 0; + curFloatingPointArg = 0; + for (curArgIdx = 0; curArgIdx < inBeginNode.nArguments && curParamWords < 6; curArgIdx++) + { + PrimArg& curArg = inBeginNode.arguments[curArgIdx]; + + switch (curArg.getOperation()) + { + case poArg_I: + case poArg_A: + { + SparcInsn& copyInsn = *new(mPool) SparcInsn(&curArg, mPool, siOr, saRZR); + + // hook up this vr to the external define FIX-ME + VirtualRegister& inputVr = defineTemporary(defineInsn, curArgIdx); + inputVr.precolorRegister(registerNumberToColor[i0+curParamWords]); + + // emit the copy + useTemporaryVR(copyInsn, inputVr, 0); + defineProducer(curArg, copyInsn, 0); + + curParamWords++; + break; + } + case poArg_L: + assert(false); + + case poArg_F: + assert(false); + + case poArg_D: + assert(false); + + break; + + case poArg_M: + break; + + default: + assert(false); + break; + } + } + + // FIXME: emit the load for the arguments on the stack + + // continue counting from before + // make all the rest of the defines as type none + for (;curArgIdx < inBeginNode.nArguments * 2; curArgIdx++) + { + defineInsn.getInstructionDefineBegin()[curArgIdx].kind = udNone; + } + // check for half stack half reg case +} + +Instruction& SparcSunOSEmitter:: +emitCopy(DataNode& inDataNode, VirtualRegister& fromVr, VirtualRegister& toVr) +{ + SparcInsn& newInsn = *new(mPool) SparcInsn(&inDataNode, mPool, siOr, saRZR); + newInsn.addUse(0, fromVr); + newInsn.addDefine(0, toVr); +#if DEBUG + toVr.setDefineInstruction(newInsn); +#endif + return (newInsn); +} + +void SparcSunOSEmitter:: +emit_DivI_I(Primitive& inPrimitive) +{ + Value& immediate = inPrimitive.nthInputConstant(1); + if(isPowerOfTwo(immediate.i)) + { + uint8 shiftBy = 31 - leadingZeros(immediate.i); + + SparcInsn& shiftRightL = *new(mPool) SparcInsn(&inPrimitive, mPool, siSrl, saRIR, 31); + useProducer(inPrimitive.nthInputVariable(0), shiftRightL, 0); + VirtualRegister& tempVr = defineTemporary(shiftRightL, 0); + inPrimitive.setInstructionRoot(&shiftRightL); + + SparcInsn& addInsn = *new(mPool) SparcInsn(&inPrimitive, mPool, siAdd, saRRR); + useProducer(inPrimitive.nthInputVariable(0), addInsn, 0); + useTemporaryVR(addInsn, tempVr, 1); + redefineTemporary(addInsn, tempVr, 0); + + SparcInsn& shiftRight = *new(mPool) SparcInsn(&inPrimitive, mPool, siSra, saRIR, shiftBy); + useTemporaryVR(shiftRight, tempVr, 0); + defineProducer(inPrimitive, shiftRight, 0); + } + else + // FIXME: check 0 + emit_InsnI_I(inPrimitive, siSDiv); +} + +void SparcSunOSEmitter:: +emit_ModE_I(Primitive& inPrimitive) +{ + // Check the divisor != 0 + SparcCmp& cmpInsn = *new(mPool) SparcCmp(&inPrimitive, mPool, saRZ); + useProducer(inPrimitive.nthInputVariable(1), cmpInsn, 0); + cmpInsn.addDefine(0, udCond); + SparcTrap& trapInsn = *new(mPool) SparcTrap(&inPrimitive, mPool, scE, saRRR /* FIXME */); + trapInsn.addUse(0, udCond); + trapInsn.getInstructionUseBegin()->setDefiningInstruction(cmpInsn); + inPrimitive.setInstructionRoot(&trapInsn); + + SparcInsn& divInsn = *new(mPool) SparcInsn(&inPrimitive, mPool, siSDiv, saRRR); + useProducer(inPrimitive.nthInputVariable(0), divInsn, 0); + useProducer(inPrimitive.nthInputVariable(1), divInsn, 1); + VirtualRegister& tempVr = defineTemporary(divInsn, 0); + + SparcInsn& mullInsn = *new(mPool) SparcInsn(&inPrimitive, mPool, siSMul, saRRR); + useProducer(inPrimitive.nthInputVariable(1), mullInsn, 1); + useTemporaryVR(mullInsn, tempVr, 0); + redefineTemporary(mullInsn, tempVr, 0); + + SparcInsn& subInsn = *new(mPool) SparcInsn(&inPrimitive, mPool, siSub, saRRR); + useTemporaryVR(subInsn, tempVr, 0); + useProducer(inPrimitive.nthInputVariable(0), subInsn, 1); + defineProducer(inPrimitive, subInsn, 0); +} + +void SparcSunOSEmitter:: +emit_ChkNull(Primitive& inPrimitive) +{ + SparcCmp& cmpInsn = *new(mPool) SparcCmp(&inPrimitive, mPool, saRZ); + useProducer(inPrimitive.nthInputVariable(0), cmpInsn, 0); + cmpInsn.addDefine(0, udCond); + + SparcTrap& trapInsn = *new(mPool) SparcTrap(&inPrimitive, mPool, scE, saRRR /* FIXME */); + trapInsn.addUse(0, udCond); + trapInsn.getInstructionUseBegin()->setDefiningInstruction(cmpInsn); + inPrimitive.setInstructionRoot(&trapInsn); +} + +void SparcSunOSEmitter:: +emit_LimitR(Primitive& inPrimitive) +{ + int32 constI = inPrimitive.nthInputConstant(0).i; + if ((constI >= -4096) && (constI <= 4095)) + { + SparcCmp& cmpInsn = *new(mPool) SparcCmp(&inPrimitive, mPool, constI ? saRI : saRZ, constI & 0x1fff); + useProducer(inPrimitive.nthInputVariable(1), cmpInsn, 0); + cmpInsn.addDefine(0, udCond); + + SparcTrap& trapInsn = *new(mPool) SparcTrap(&inPrimitive, mPool, scLe, saRRR /* FIXME */); + trapInsn.addUse(0, udCond); + trapInsn.getInstructionUseBegin()->setDefiningInstruction(cmpInsn); + inPrimitive.setInstructionRoot(&trapInsn); + } + else + { + assert(0); + } +} + +void SparcSunOSEmitter:: +emit_Limit(Primitive& inPrimitive) +{ + SparcCmp& cmpInsn = *new(mPool) SparcCmp(&inPrimitive, mPool, saRR); + useProducer(inPrimitive.nthInputVariable(0), cmpInsn, 0); + useProducer(inPrimitive.nthInputVariable(1), cmpInsn, 1); + cmpInsn.addDefine(0, udCond); + + SparcTrap& trapInsn = *new(mPool) SparcTrap(&inPrimitive, mPool, scGe, saRRR /* FIXME */); + trapInsn.addUse(0, udCond); + trapInsn.getInstructionUseBegin()->setDefiningInstruction(cmpInsn); + inPrimitive.setInstructionRoot(&trapInsn); +} + + +void SparcSunOSEmitter:: +emit_LdC_IRegisterIndirect(Primitive& inPrimitive) +{ + DataNode& immSource = inPrimitive.nthInput(0).getProducer().getNode(); + + int32 constI = immSource.nthInputConstant(1).i; + if ((constI >= -4096) && (constI <= 4095)) + { + SparcLoadC& newInsn = *new(mPool) SparcLoadC(&inPrimitive, mPool, siLd, saRIR, constI); + useProducer(immSource.nthInputVariable(0), newInsn, 0); + defineProducer(inPrimitive, newInsn, 0); + } + else + { + assert(false); + } +} + +void SparcSunOSEmitter:: +emit_Ld_IRegisterIndirect(Primitive& inPrimitive) +{ + DataNode& immSource = inPrimitive.nthInput(1).getProducer().getNode(); + + int32 constI = immSource.nthInputConstant(1).i; + + if ((constI >= -4096) && (constI <= 4095)) + { + SparcLoad& newInsn = *new(mPool) SparcLoad(&inPrimitive, mPool, siLd, saRIR, false, constI); + useProducer(inPrimitive.nthInputVariable(0), newInsn, 0); // M to poLd_I + useProducer(immSource.nthInputVariable(0), newInsn, 1); // Vint to poAdd_A + defineProducer(inPrimitive, newInsn, 0); // Vint from poLd_I + } + else + { + assert(false); + } +} + +void SparcSunOSEmitter:: +emit_StI_IRegisterIndirect(Primitive& inPrimitive) +{ + SparcStore* storeInsn; + + // load the constant to be stored into constVr + VirtualRegister& constVr = genLoadConstant(inPrimitive, inPrimitive.nthInputConstant(2).i); + + // grab the immediate value from the incoming poAddA_I + DataNode& addrSource = inPrimitive.nthInput(1).getProducer().getNode(); + + int32 offset = addrSource.nthInputConstant(1).i; + if ((offset >= -4096) && (offset <= 4095)) + { + storeInsn = new(mPool) SparcStore(&inPrimitive, mPool, siSt, saRIR, offset); + useProducer(addrSource.nthInputVariable(0), *storeInsn, 1); + } + else + { + assert(false); + } + useProducer(inPrimitive.nthInputVariable(0), *storeInsn, 0); // <- store + useTemporaryVR(*storeInsn, constVr, 2); // <- value + defineProducer(inPrimitive, *storeInsn, 0); // -> store +} + +void SparcSunOSEmitter:: +emit_St_IRegisterIndirect(Primitive& inPrimitive) +{ + DataNode& addrSource = inPrimitive.nthInput(1).getProducer().getNode(); + + int32 offset = addrSource.nthInputConstant(1).i; + if ((offset >= -4096) && (offset <= 4095)) + { + SparcStore& storeInsn = *new(mPool) SparcStore(&inPrimitive, mPool, siSt, saRIR, offset); + useProducer(inPrimitive.nthInputVariable(0), storeInsn, 0); // <- store + useProducer(addrSource.nthInputVariable(0), storeInsn, 1); // <- address base + useProducer(inPrimitive.nthInputVariable(2), storeInsn, 2); // <- value + defineProducer(inPrimitive, storeInsn, 0); // -> store + } + else + { + assert(false); + } +} + + +VirtualRegister& SparcSunOSEmitter:: +genLoadConstant(DataNode& inPrimitive, int32 constI) +{ + if ((constI >= -4096) && (constI <= 4095)) + { + SparcInsn& newInsn = *new(mPool) SparcInsn(&inPrimitive, mPool, siOr, constI ? saZIR : saZZR, constI & 0x1fff); + VirtualRegister& constantVr = defineTemporary(newInsn, 0); + return constantVr; + } + else if ((constI & 0x1fff) == 0) + { + // FIXME + assert(0); + } + else + { + // FIXME + assert(0); + } +} + +uint32 SparcSunOSEmitter:: +getPrologSize() const +{ + return 4; +} + +void SparcSunOSEmitter:: +formatPrologToMemory(void* inWhere) +{ + *(uint32*) inWhere = 0x9de3bf90; // save %sp,-112,%sp +} + +uint32 SparcSunOSEmitter:: +getEpilogSize() const +{ + return 8; +} + +void SparcSunOSEmitter:: +formatEpilogToMemory(void* inWhere) +{ + ((uint32*) inWhere)[0] = 0x81c7e008; // ret + ((uint32*) inWhere)[1] = 0x81e80000; // restore %g0,%g0,%g0 +} diff --git a/ef/Compiler/CodeGenerator/md/sparc/SparcSunOSEmitter.h b/ef/Compiler/CodeGenerator/md/sparc/SparcSunOSEmitter.h new file mode 100644 index 000000000000..d572be318b33 --- /dev/null +++ b/ef/Compiler/CodeGenerator/md/sparc/SparcSunOSEmitter.h @@ -0,0 +1,66 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#ifndef _SPARC_SUNOS_EMITTER_H_ +#define _SPARC_SUNOS_EMITTER_H_ + +#include "InstructionEmitter.h" +#include "SparcInstruction.h" +#include "VirtualRegister.h" + +class PrimArg; +class Pool; + +class SparcSunOSEmitter : public InstructionEmitter +{ +public: + SparcSunOSEmitter(Pool& inPool, VirtualRegisterManager& vrMan) : InstructionEmitter(inPool, vrMan) {} + + virtual void emitPrimitive(Primitive& inPrimitive, NamedRule inRule); + + virtual uint32 getPrologSize() const; + virtual void formatPrologToMemory(void* inWhere); + virtual uint32 getEpilogSize() const; + virtual void formatEpilogToMemory(void* inWhere); + + virtual void emitArguments(ControlBegin& inBeginNode); + virtual void emitArgument(PrimArg& /*inArguments*/, const uint /*inArgumentIndex*/) {} + virtual Instruction& emitCopy(DataNode& inDataNode, VirtualRegister& fromVr, VirtualRegister& toVr); + virtual Instruction& emitLoad(DataNode& /*inDataNode*/, VirtualRegister& /*loadedRegister*/, VirtualRegister& /*stackRegister*/) {} + virtual Instruction& emitStore(DataNode& /*inDataNode*/, VirtualRegister& /*storedRegister*/, VirtualRegister& /*stackRegister*/) {}; + virtual Instruction& emitAbsoluteBranch(DataNode& inDataNode, ControlNode& inTarget); + + void emit_Insn_I(Primitive& inPrimitive, SparcInstructionKind kind); + void emit_InsnI_I(Primitive& inPrimitive, SparcInstructionKind kind); + void emit_Const_I(Primitive& inPrimitive); + void emit_Cmp_I(Primitive& inPrimitive); + void emit_CmpI_I(Primitive& inPrimitive); + void emit_B(Primitive& inPrimitive, SparcConditionKind kind); + void emit_ModE_I(Primitive& inPrimitive); + void emit_DivI_I(Primitive& inPrimitive); + void emit_ChkNull(Primitive& inPrimitive); + void emit_LimitR(Primitive& inPrimitive); + void emit_Limit(Primitive& inPrimitive); + void emit_LdC_IRegisterIndirect(Primitive& inPrimitive); + void emit_Ld_IRegisterIndirect(Primitive& inPrimitive); + void emit_StI_IRegisterIndirect(Primitive& inPrimitive); + void emit_St_IRegisterIndirect(Primitive& inPrimitive); + VirtualRegister& genLoadConstant(DataNode& inPrimitive, int32 inConstant); +}; + +#endif /* _SPARC_SUNOS_EMITTER_H_ */ diff --git a/ef/Compiler/CodeGenerator/md/sparc/sparc-sunos.nad b/ef/Compiler/CodeGenerator/md/sparc/sparc-sunos.nad new file mode 100644 index 000000000000..ad6205e5b72b --- /dev/null +++ b/ef/Compiler/CodeGenerator/md/sparc/sparc-sunos.nad @@ -0,0 +1,441 @@ +%top +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#include "Burg.h" +% + +%terminals +% + +%startsymbols +Control +Result +Exception +Store +Vcond +Vint +Vlong +Vfloat +Vdouble +Vptr +Cint +Clong +Cfloat +Cdouble +Cptr +% + +%grammar +Vint: coReg_I $1 $ +Vlong: coReg_L $1 $ +Vfloat: coReg_F $1 $ +Vdouble: coReg_D $1 $ +Vptr: coReg_A $1 $ +Vcond: coReg_C $1 $ +Store: coReg_M $1 $ +Cint: coReg_I $1 $ +Clong: coReg_L $1 $ +Cfloat: coReg_F $1 $ +Cdouble: coReg_D $1 $ +Cptr: coReg_A $1 $ + +Vint: poConst_I $1 $emConst_I +Vlong: poConst_L $1 $emConst_L +Vfloat: poConst_F $1 $emConst_F +Vdouble: poConst_D $1 $emConst_D +Vptr: poConst_A $1 $emConst_A +Vcond: poConst_C $1 $emConst_C + +Store: poBreak(Store) $1 $emBreak + +Vint: poArg_I $1 $emArg_I +Vlong: poArg_L $1 $emArg_L +Vfloat: poArg_F $1 $emArg_F +Vdouble: poArg_D $1 $emArg_D +Vptr: poArg_A $1 $emArg_A +Store: poArg_M $1 $emArg_M + +Result: poResult_I(Vint) $1 $emResult_I +Result: poResult_L(Vlong) $1 $emResult_L +Result: poResult_F(Vfloat) $1 $emResult_F +Result: poResult_D(Vdouble) $1 $emResult_D +Result: poResult_A(Vptr) $1 $emResult_A +// (not used): poResult_C(Acond) $1 $emResult_C +Result: poResult_M(Store) $1 $emResult_M + +Control: poIfLt(Vcond) $1 $emIfLt +Control: poIfEq(Vcond) $1 $emIfEq +Control: poIfLe(Vcond) $1 $emIfLe +Control: poIfGt(Vcond) $1 $emIfGt +Control: poIfLgt(Vcond) $1 $emIfLgt +Control: poIfGe(Vcond) $1 $emIfGe +Control: poIfOrd(Vcond) $1 $emIfOrd +Control: poIfUnord(Vcond) $1 $emIfUnord +Control: poIfULt(Vcond) $1 $emIfULt +Control: poIfUEq(Vcond) $1 $emIfUEq +Control: poIfULe(Vcond) $1 $emIfULe +Control: poIfUGt(Vcond) $1 $emIfUGt +Control: poIfNe(Vcond) $1 $emIfNe +Control: poIfUGe(Vcond) $1 $emIfUGe + +Control: poSwitch(Vint) $1 $emSwitch + +Vint: poAnd_I(Vint, Vint) $1 $emAnd_I +Vlong: poAnd_L(Vlong, Vlong) $1 $emAnd_L +Vint: poAndI_I(Vint, Cint) $1 $emAndI_I +Vlong: poAndI_L(Vlong, Clong) $1 $emAndI_L +Vint: poOr_I(Vint, Vint) $1 $emOr_I +Vlong: poOr_L(Vlong, Vlong) $1 $emOr_L +Vint: poOrI_I(Vint, Cint) $1 $emOrI_I +Vlong: poOrI_L(Vlong, Clong) $1 $emOrI_L +Vint: poXor_I(Vint, Vint) $1 $emXor_I +Vlong: poXor_L(Vlong, Vlong) $1 $emXor_L +Vint: poXorI_I(Vint, Cint) $1 $emXorI_I +Vlong: poXorI_L(Vlong, Clong) $1 $emXorI_L + +Vint: poAdd_I(Vint, Vint) $1 $emAdd_I +Vlong: poAdd_L(Vlong, Vlong) $1 $emAdd_L +Vptr: poAdd_A(Vptr, Vint) $1 $emAdd_A +Vptr: poAddU_A(Vptr, Vint) $1 $emAddU_A +Vint: poAddI_I(Vint, Cint) $1 $emAddI_I +Vlong: poAddI_L(Vlong, Clong) $1 $emAddI_L +Vptr: poAddI_A(Vptr, Cint) $1 $emAddI_A +Vptr: poAddR_A(Cptr, Vint) $1 $emAddR_A +Vptr: poAddRU_A(Cptr, Vint) $1 $emAddRU_A + +Vint: poSub_I(Vint, Vint) $1 $emSub_I +Vlong: poSub_L(Vlong, Vlong) $1 $emSub_L +Vptr: poSub_A(Vptr, Vint) $1 $emSub_A +Vptr: poSubU_A(Vptr, Vint) $1 $emSubU_A +Vint: poSubR_I(Cint, Vint) $1 $emSubR_I +Vlong: poSubR_L(Clong, Vlong) $1 $emSubR_L +Vptr: poSubR_A(Cptr, Vint) $1 $emSubR_A +Vptr: poSubUR_A(Cptr, Vint) $1 $emSubUR_A +Vint: poSubA_I(Vptr, Vptr) $1 $emSubA_I +Vint: poSubAI_I(Vptr, Cptr) $1 $emSubAI_I +Vint: poSubAR_I(Cptr, Vptr) $1 $emSubAR_I + +Vint: poMul_I(Vint, Vint) $1 $emMul_I +Vlong: poMul_L(Vlong, Vlong) $1 $emMul_L +Vint: poMulI_I(Vint, Cint) $1 $emMulI_I +Vlong: poMulI_L(Vlong, Clong) $1 $emMulI_L + +Vint: poDivI_I(Vint, Cint) $1 $emDivI_I +Vint: poModE_I(Vint, Vint) $1 $emModE_I + +Vint: poShl_I(Vint, Vint) $1 $emShl_I +Vlong: poShl_L(Vlong, Vint) $1 $emShl_L +Vint: poShlI_I(Vint, Cint) $1 $emShlI_I +Vlong: poShlI_L(Vlong, Cint) $1 $emShlI_L +Vint: poShlR_I(Cint, Vint) $1 $emShlR_I +Vlong: poShlR_L(Clong, Vint) $1 $emShlR_L +Vint: poShr_I(Vint, Vint) $1 $emShr_I +Vlong: poShr_L(Vlong, Vint) $1 $emShr_L +Vint: poShrI_I(Vint, Cint) $1 $emShrI_I +Vlong: poShrI_L(Vlong, Cint) $1 $emShrI_L +Vint: poShrR_I(Cint, Vint) $1 $emShrR_I +Vlong: poShrR_L(Clong, Vint) $1 $emShrR_L +Vint: poShrU_I(Vint, Vint) $1 $emShrU_I +Vlong: poShrU_L(Vlong, Vint) $1 $emShrU_L +Vint: poShrUI_I(Vint, Cint) $1 $emShrUI_I +Vlong: poShrUI_L(Vlong, Cint) $1 $emShrUI_L +Vint: poShrUR_I(Cint, Vint) $1 $emShrUR_I +Vlong: poShrUR_L(Clong, Vint) $1 $emShrUR_L + +Vint: poExt_I(Vint, Cint) $1 $emExt_I +Vlong: poExt_L(Vlong, Cint) $1 $emExt_L + +Vfloat: poFAdd_F(Vfloat, Vfloat) $1 $emFAdd_F +Vdouble: poFAdd_D(Vdouble, Vdouble) $1 $emFAdd_D +Vfloat: poFAddI_F(Vfloat, Cfloat) $1 $emFAddI_F +Vdouble: poFAddI_D(Vdouble, Cdouble) $1 $emFAddI_D + +Vfloat: poFSub_F(Vfloat, Vfloat) $1 $emFSub_F +Vdouble: poFSub_D(Vdouble, Vdouble) $1 $emFSub_D +Vfloat: poFSubR_F(Cfloat, Vfloat) $1 $emFSubR_F +Vdouble: poFSubR_D(Cdouble, Vdouble) $1 $emFSubR_D + +Vfloat: poFMul_F(Vfloat, Vfloat) $1 $emFMul_F +Vdouble: poFMul_D(Vdouble, Vdouble) $1 $emFMul_D +Vfloat: poFMulI_F(Vfloat, Cfloat) $1 $emFMulI_F +Vdouble: poFMulI_D(Vdouble, Cdouble) $1 $emFMulI_D + +Vfloat: poFDiv_F(Vfloat, Vfloat) $1 $emFDiv_F +Vdouble: poFDiv_D(Vdouble, Vdouble) $1 $emFDiv_D +Vfloat: poFDivI_F(Vfloat, Cfloat) $1 $emFDivI_F +Vdouble: poFDivI_D(Vdouble, Cdouble) $1 $emFDivI_D +Vfloat: poFDivR_F(Cfloat, Vfloat) $1 $emFDivR_F +Vdouble: poFDivR_D(Cdouble, Vdouble) $1 $emFDivR_D + +Vfloat: poFRem_F(Vfloat, Vfloat) $1 $emFRem_F +Vdouble: poFRem_D(Vdouble, Vdouble) $1 $emFRem_D +Vfloat: poFRemI_F(Vfloat, Cfloat) $1 $emFRemI_F +Vdouble: poFRemI_D(Vdouble, Cdouble) $1 $emFRemI_D +Vfloat: poFRemR_F(Cfloat, Vfloat) $1 $emFRemR_F +Vdouble: poFRemR_D(Cdouble, Vdouble) $1 $emFRemR_D + +Vint: poConvI_L(Vlong) $1 $emConvI_L +Vlong: poConvL_I(Vint) $1 $emConvL_I + +Vint: poFConvI_F(Vfloat) $1 $emFConvI_F +Vint: poFConvI_D(Vdouble) $1 $emFConvI_D +Vlong: poFConvL_F(Vfloat) $1 $emFConvL_F +Vlong: poFConvL_D(Vdouble) $1 $emFConvL_D +Vfloat: poFConvF_I(Vint) $1 $emFConvF_I +Vfloat: poFConvF_L(Vlong) $1 $emFConvF_L +Vfloat: poFConvF_D(Vdouble) $1 $emFConvF_D +Vdouble: poFConvD_I(Vint) $1 $emFConvD_I +Vdouble: poFConvD_L(Vlong) $1 $emFConvD_L +Vdouble: poFConvD_F(Vfloat) $1 $emFConvD_F + +Vcond: poCmp_I(Vint, Vint) $1 $emCmp_I +Vcond: poCmp_L(Vlong, Vlong) $1 $emCmp_L +Vcond: poCmpI_I(Vint, Cint) $1 $emCmpI_I +Vcond: poCmpI_L(Vlong, Clong) $1 $emCmpI_L +Vcond: poCmpU_I(Vint, Vint) $1 $emCmpU_I +Vcond: poCmpU_L(Vlong, Vlong) $1 $emCmpU_L +Vcond: poCmpU_A(Vptr, Vptr) $1 $emCmpU_A +Vcond: poCmpUI_I(Vint, Cint) $1 $emCmpUI_I +Vcond: poCmpUI_L(Vlong, Clong) $1 $emCmpUI_L +Vcond: poCmpUI_A(Vptr, Cptr) $1 $emCmpUI_A + +Vcond: poFCmp_F(Vfloat, Vfloat) $1 $emFCmp_F +Vcond: poFCmp_D(Vdouble, Vdouble) $1 $emFCmp_D +Vcond: poFCmpI_F(Vfloat, Cfloat) $1 $emFCmpI_F +Vcond: poFCmpI_D(Vdouble, Cdouble) $1 $emFCmpI_D + +Vint: poLt_I(Vcond) $1 $emLt_I +Vint: poEq_I(Vcond) $1 $emEq_I +Vint: poLe_I(Vcond) $1 $emLe_I +Vint: poGt_I(Vcond) $1 $emGt_I +Vint: poLgt_I(Vcond) $1 $emLgt_I +Vint: poGe_I(Vcond) $1 $emGe_I +Vint: poOrd_I(Vcond) $1 $emOrd_I +Vint: poUnord_I(Vcond) $1 $emUnord_I +Vint: poULt_I(Vcond) $1 $emULt_I +Vint: poUEq_I(Vcond) $1 $emUEq_I +Vint: poULe_I(Vcond) $1 $emULe_I +Vint: poUGt_I(Vcond) $1 $emUGt_I +Vint: poNe_I(Vcond) $1 $emNe_I +Vint: poUGe_I(Vcond) $1 $emUGe_I + +Vint: poCatL_I(Vcond) $1 $emCatL_I +Vint: poCatG_I(Vcond) $1 $emCatG_I +Vint: poCatCL_I(Vcond) $1 $emCatCL_I +Vint: poCatCG_I(Vcond) $1 $emCatCG_I + +Exception: poChkNull(Vptr) $1 $emChkNull +Exception: poLimit(Vint, Vint) $1 $emLimit +Exception: poLimitI(Vint, Cint) $1 $emLimitI +Exception: poLimitR(Cint, Vint) $1 $emLimitR + +Vint: poLd_I(Vptr) $1 $emLd_I +Vlong: poLd_L(Vptr) $1 $emLd_L +Vfloat: poLd_F(Vptr) $1 $emLd_F +Vdouble: poLd_D(Vptr) $1 $emLd_D +Vptr: poLd_A(Vptr) $1 $emLd_A +Vint: poLdE_I(Cptr) $1 $emLdE_I +Vlong: poLdE_L(Cptr) $1 $emLdE_L +Vfloat: poLdE_F(Cptr) $1 $emLdE_F +Vdouble: poLdE_D(Cptr) $1 $emLdE_D +Vptr: poLdE_A(Cptr) $1 $emLdE_A +Vint: poLdG_I(Cptr) $1 $emLdG_I +Vlong: poLdG_L(Cptr) $1 $emLdG_L +Vfloat: poLdG_F(Cptr) $1 $emLdG_F +Vdouble: poLdG_D(Cptr) $1 $emLdG_D +Vptr: poLdG_A(Cptr) $1 $emLdG_A +Vint: poLdS_B(Vptr) $1 $emLdS_B +Vint: poLdS_H(Vptr) $1 $emLdS_H +Vint: poLdSE_B(Cptr) $1 $emLdSE_B +Vint: poLdSE_H(Cptr) $1 $emLdSE_H +Vint: poLdSG_B(Cptr) $1 $emLdSG_B +Vint: poLdSG_H(Cptr) $1 $emLdSG_H +Vint: poLdU_B(Vptr) $1 $emLdU_B +Vint: poLdU_H(Vptr) $1 $emLdU_H +Vint: poLdUE_B(Cptr) $1 $emLdUE_B +Vint: poLdUE_H(Cptr) $1 $emLdUE_H +Vint: poLdUG_B(Cptr) $1 $emLdUG_B +Vint: poLdUG_H(Cptr) $1 $emLdUG_H +Vint: poLdV_I(Vptr) $1 $emLdV_I +Vlong: poLdV_L(Vptr) $1 $emLdV_L +Vfloat: poLdV_F(Vptr) $1 $emLdV_F +Vdouble: poLdV_D(Vptr) $1 $emLdV_D +Vptr: poLdV_A(Vptr) $1 $emLdV_A +Vint: poLdVE_I(Cptr) $1 $emLdVE_I +Vlong: poLdVE_L(Cptr) $1 $emLdVE_L +Vfloat: poLdVE_F(Cptr) $1 $emLdVE_F +Vdouble: poLdVE_D(Cptr) $1 $emLdVE_D +Vptr: poLdVE_A(Cptr) $1 $emLdVE_A +Vint: poLdVG_I(Cptr) $1 $emLdVG_I +Vlong: poLdVG_L(Cptr) $1 $emLdVG_L +Vfloat: poLdVG_F(Cptr) $1 $emLdVG_F +Vdouble: poLdVG_D(Cptr) $1 $emLdVG_D +Vptr: poLdVG_A(Cptr) $1 $emLdVG_A +Vint: poLdVS_B(Vptr) $1 $emLdVS_B +Vint: poLdVS_H(Vptr) $1 $emLdVS_H +Vint: poLdVSE_B(Cptr) $1 $emLdVSE_B +Vint: poLdVSE_H(Cptr) $1 $emLdVSE_H +Vint: poLdVSG_B(Cptr) $1 $emLdVSG_B +Vint: poLdVSG_H(Cptr) $1 $emLdVSG_H +Vint: poLdVU_B(Vptr) $1 $emLdVU_B +Vint: poLdVU_H(Vptr) $1 $emLdVU_H +Vint: poLdVUE_B(Cptr) $1 $emLdVUE_B +Vint: poLdVUE_H(Cptr) $1 $emLdVUE_H +Vint: poLdVUG_B(Cptr) $1 $emLdVUG_B +Vint: poLdVUG_H(Cptr) $1 $emLdVUG_H +Vint: poLdC_I(Vptr) $1 $emLdC_I +Vint: poLdC_L(Vptr) $1 $emLdC_L +Vint: poLdC_F(Vptr) $1 $emLdC_F +Vint: poLdC_D(Vptr) $1 $emLdC_D +Vint: poLdC_A(Vptr) $1 $emLdC_A +Vint: poLdCE_I(Vptr) $1 $emLdCE_I +Vint: poLdCE_L(Vptr) $1 $emLdCE_L +Vint: poLdCE_F(Vptr) $1 $emLdCE_F +Vint: poLdCE_D(Vptr) $1 $emLdCE_D +Vint: poLdCE_A(Vptr) $1 $emLdCE_A + +Vint: poLdC_I(poAddI_A(Vptr, Cint)) $0 $emLdC_IRegisterIndirect +Vint: poLd_I(poAddI_A(Vptr, Cint)) $0 $emLd_IRegisterIndirect + + +// poLdCG_I = 257, // Load constant global *Cptr -> Vint (not used) +// poLdCG_L = 258, // Load constant global *Cptr -> Vlong (not used) +// poLdCG_F = 259, // Load constant global *Cptr -> Vfloat (not used) +// poLdCG_D = 260, // Load constant global *Cptr -> Vdouble (not used) +// poLdCG_A = 261, // Load constant global *Cptr -> Vptr (not used) +Vint: poLdCS_B(Vptr) $1 $emLdCS_B +Vint: poLdCS_H(Vptr) $1 $emLdCS_H +Vint: poLdCSE_B(Cptr) $1 $emLdCSE_B +Vint: poLdCSE_H(Cptr) $1 $emLdCSE_H +//Vint (not used): poLdCSG_B(Cptr) $1 $emLdCSG_B +//Vint (not used): poLdCSG_H(Cptr) $1 $emLdCSG_H +Vint: poLdCU_B(Vptr) $1 $emLdCU_B +Vint: poLdCU_H(Vptr) $1 $emLdCU_H +Vint: poLdCUE_B(Cptr) $1 $emLdCUE_B +Vint: poLdCUE_H(Cptr) $1 $emLdCUE_H +//Vint (not used): poLdCUG_B(Cptr) $1 $emLdCUG_B +//Vint (not used): poLdCUG_H(Cptr) $1 $emLdCUG_H + +Store: poSt_B(Vptr, Vint) $1 $emSt_B +Store: poSt_H(Vptr, Vint) $1 $emSt_H +Store: poSt_I(Vptr, Vint) $1 $emSt_I +Store: poSt_L(Vptr, Vlong) $1 $emSt_L +Store: poSt_F(Vptr, Vfloat) $1 $emSt_F +Store: poSt_D(Vptr, Vdouble) $1 $emSt_D +Store: poSt_A(Vptr, Vptr) $1 $emSt_A +Store: poStI_B(Vptr, Cint) $1 $emStI_B +Store: poStI_H(Vptr, Cint) $1 $emStI_H +Store: poStI_I(Vptr, Cint) $1 $emStI_I +Store: poStI_L(Vptr, Clong) $1 $emStI_L +Store: poStI_F(Vptr, Cfloat) $1 $emStI_F +Store: poStI_D(Vptr, Cdouble) $1 $emStI_D +Store: poStI_A(Vptr, Cptr) $1 $emStI_A +Store: poStE_B(Cptr, Vint) $1 $emStE_B +Store: poStE_H(Cptr, Vint) $1 $emStE_H +Store: poStE_I(Cptr, Vint) $1 $emStE_I +Store: poStE_L(Cptr, Vlong) $1 $emStE_L +Store: poStE_F(Cptr, Vfloat) $1 $emStE_F +Store: poStE_D(Cptr, Vdouble) $1 $emStE_D +Store: poStE_A(Cptr, Vptr) $1 $emStE_A +Store: poStEI_B(Cptr, Cint) $1 $emStEI_B +Store: poStEI_H(Cptr, Cint) $1 $emStEI_H +Store: poStEI_I(Cptr, Cint) $1 $emStEI_I +Store: poStEI_L(Cptr, Clong) $1 $emStEI_L +Store: poStEI_F(Cptr, Cfloat) $1 $emStEI_F +Store: poStEI_D(Cptr, Cdouble) $1 $emStEI_D +Store: poStEI_A(Cptr, Cptr) $1 $emStEI_A +Store: poStG_B(Cptr, Vint) $1 $emStG_B +Store: poStG_H(Cptr, Vint) $1 $emStG_H +Store: poStG_I(Cptr, Vint) $1 $emStG_I +Store: poStG_L(Cptr, Vlong) $1 $emStG_L +Store: poStG_F(Cptr, Vfloat) $1 $emStG_F +Store: poStG_D(Cptr, Vdouble) $1 $emStG_D +Store: poStG_A(Cptr, Vptr) $1 $emStG_A +Store: poStGI_B(Cptr, Cint) $1 $emStGI_B +Store: poStGI_H(Cptr, Cint) $1 $emStGI_H +Store: poStGI_I(Cptr, Cint) $1 $emStGI_I +Store: poStGI_L(Cptr, Clong) $1 $emStGI_L +Store: poStGI_F(Cptr, Cfloat) $1 $emStGI_F +Store: poStGI_D(Cptr, Cdouble) $1 $emStGI_D +Store: poStGI_A(Cptr, Cptr) $1 $emStGI_A +Store: poStV_B(Vptr, Vint) $1 $emStV_B +Store: poStV_H(Vptr, Vint) $1 $emStV_H +Store: poStV_I(Vptr, Vint) $1 $emStV_I +Store: poStV_L(Vptr, Vlong) $1 $emStV_L +Store: poStV_F(Vptr, Vfloat) $1 $emStV_F +Store: poStV_D(Vptr, Vdouble) $1 $emStV_D +Store: poStV_A(Vptr, Vptr) $1 $emStV_A +Store: poStVI_B(Vptr, Cint) $1 $emStVI_B +Store: poStVI_H(Vptr, Cint) $1 $emStVI_H +Store: poStVI_I(Vptr, Cint) $1 $emStVI_I +Store: poStVI_L(Vptr, Clong) $1 $emStVI_L +Store: poStVI_F(Vptr, Cfloat) $1 $emStVI_F +Store: poStVI_D(Vptr, Cdouble) $1 $emStVI_D +Store: poStVI_A(Vptr, Cptr) $1 $emStVI_A +Store: poStVE_B(Cptr, Vint) $1 $emStVE_B +Store: poStVE_H(Cptr, Vint) $1 $emStVE_H +Store: poStVE_I(Cptr, Vint) $1 $emStVE_I +Store: poStVE_L(Cptr, Vlong) $1 $emStVE_L +Store: poStVE_F(Cptr, Vfloat) $1 $emStVE_F +Store: poStVE_D(Cptr, Vdouble) $1 $emStVE_D +Store: poStVE_A(Cptr, Vptr) $1 $emStVE_A +Store: poStVEI_B(Cptr, Cint) $1 $emStVEI_B +Store: poStVEI_H(Cptr, Cint) $1 $emStVEI_H +Store: poStVEI_I(Cptr, Cint) $1 $emStVEI_I +Store: poStVEI_L(Cptr, Clong) $1 $emStVEI_L +Store: poStVEI_F(Cptr, Cfloat) $1 $emStVEI_F +Store: poStVEI_D(Cptr, Cdouble) $1 $emStVEI_D +Store: poStVEI_A(Cptr, Cptr) $1 $emStVEI_A +Store: poStVG_B(Cptr, Vint) $1 $emStVG_B +Store: poStVG_H(Cptr, Vint) $1 $emStVG_H +Store: poStVG_I(Cptr, Vint) $1 $emStVG_I +Store: poStVG_L(Cptr, Vlong) $1 $emStVG_L +Store: poStVG_F(Cptr, Vfloat) $1 $emStVG_F +Store: poStVG_D(Cptr, Vdouble) $1 $emStVG_D +Store: poStVG_A(Cptr, Vptr) $1 $emStVG_A +Store: poStVGI_B(Cptr, Cint) $1 $emStVGI_B +Store: poStVGI_H(Cptr, Cint) $1 $emStVGI_H +Store: poStVGI_I(Cptr, Cint) $1 $emStVGI_I +Store: poStVGI_L(Cptr, Clong) $1 $emStVGI_L +Store: poStVGI_F(Cptr, Cfloat) $1 $emStVGI_F +Store: poStVGI_D(Cptr, Cdouble) $1 $emStVGI_D +Store: poStVGI_A(Cptr, Cptr) $1 $emStVGI_A + +Store: poSt_I(poAddI_A(Vptr, Cint), Vint) $0 $emSt_IRegisterIndirect +Store: poStI_I(poAddI_A(Vptr, Cint), Cint) $0 $emStI_IRegisterIndirect + +// Store, Vint: poMEnter_A(Vptr) $1 $emMEnter_A +// Store, Vint: poMEnterG_A(Cptr) $1 $emMEnterG_A +// Store, Vint: poMExit_A(Vptr) $1 $emMExit_A +// Store, Vint: poMExitG_A(Cptr) $1 $emMExitG_A +// Vptr: poLookupV_A(Vptr, Cint) $1 $emLookupV_A +// Vptr: poLookupI_A(Vptr, Cint) $1 $emLookupI_A +// ...: poSysCall(M) $1 $emSysCall +// Store, ...: poSysCallV(M) $1 $emSysCallV +// ..., E: poSysCallE(M) $1 $emSysCallE +// Store, ..., E: poSysCallEV(M) $1 $emSysCallEV +//Store, ..., E: poCall(Va) $1 $emCall + +VInt: poCallI $1 $emCallI_I +Vlong: poCallI $1 $emCallI_L +Vfloat: poCallI $1 $emCallI_F +Vdouble: poCallI $1 $emCallI_D +Vptr: poCallI $1 $emCallI_P +// Store, ..., E: poCallF(F) $1 $emCallF +% + diff --git a/ef/Compiler/CodeGenerator/md/x86/Makefile b/ef/Compiler/CodeGenerator/md/x86/Makefile new file mode 100644 index 000000000000..d4463e44c8d7 --- /dev/null +++ b/ef/Compiler/CodeGenerator/md/x86/Makefile @@ -0,0 +1,113 @@ +#!gmake +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +####################################################################### +# (1) Directory specific info # +####################################################################### + +DEPTH = ../../../.. + +CPPSRCS = x86-win32.nad.burg.cpp \ + x86ArgumentList.cpp \ + x86Opcode.cpp \ + x86Win32Emitter.cpp \ + x86Win32Instruction.cpp \ + x86Formatter.cpp \ + x86StdCall.cpp \ + x86Float.cpp \ + $(OS_SUPPORT) \ + $(NULL) + +LOCAL_MD_EXPORTS_x86 = x86ArgumentList.h \ + x86Float.h \ + x86Formatter.h \ + x86Linux_Support.h \ + x86Opcode.h \ + x86StdCall.h \ + x86Win32Cpu.h \ + x86Win32Emitter.h \ + x86Win32Instruction.h \ + $(NULL) + +MODULE_NAME = EF + +####################################################################### +# (2) Include "component" configuration information. # +####################################################################### + +include $(DEPTH)/config/config.mk + +####################################################################### +# (3) Include "local" platform-dependent assignments (OPTIONAL). # +####################################################################### + +# +# Generation of OS-specific support files +# +ifeq ($(OS_ARCH),WINNT) +OS_SUPPORT = x86Win32_Support.cpp +endif + +ifeq ($(OS_ARCH),Linux) +ASFILES = x86Linux.s +OS_SUPPORT = x86Linux_Support.cpp +endif + +####################################################################### +# (4) Execute "component" rules. (OPTIONAL) # +####################################################################### + +include $(DEPTH)/config/rules.mk + +####################################################################### +# (7) Execute "local" rules. (OPTIONAL). # +####################################################################### + +# +# Rules to generate x86-win32.nad.burg.[cpp][h] +# +ifneq ($(OS_ARCH),WINNT) +x86-win32.nad.burg.cpp: x86-win32.nad.burg $(BURG) + $(BURG) -I -o $@ < $< + +x86-win32.nad.burg: x86-win32.nad $(DEPTH)/Compiler/PrimitiveGraph/PrimitiveOperations $(DEPTH)/Tools/Nad/nad.pl + $(PERL) $(DEPTH)/Tools/Nad/nad.pl $< $(DEPTH)/Compiler/PrimitiveGraph/PrimitiveOperations \ + $(LOCAL_EXPORT_DIR)/PrimitiveOperations.h \ + $(DEPTH)/Compiler/PrimitiveGraph/PrimitiveOperations.cpp \ + $<.burg.h > $@ +else +x86-win32.nad.burg.cpp: x86-win32.nad $(BURG) $(DEPTH)/Compiler/PrimitiveGraph/PrimitiveOperations $(DEPTH)/Tools/Nad/nad.pl + $(DEPTH)/config/genburg.bat $(BURG) $(DEPTH)/Tools/Nad/nad.pl $< $(DEPTH)/Compiler/PrimitiveGraph/PrimitiveOperations + cp $(DEPTH)/Compiler/PrimitiveGraph/PrimitiveOperations.h $(LOCAL_EXPORT_DIR) +endif + +# +# Extra cleaning +# +clean clobber realclean clobber_all:: + rm -f x86-win32.nad.burg.cpp x86-win32.nad.burg.h x86-win32.nad.burg + +# +# Special rules for x86Win32Support.cpp on Windows: it currently breaks the +# compiler if compiled with optimizations +# +ifeq ($(OS_ARCH),WINNT) +OPT_FLAG = -O2 +$(OBJDIR)/x86Win32_Support$(OBJ_SUFFIX): x86Win32_Support.cpp + $(CCC) -c $(filter-out $(OPT_FLAG),$(CFLAGS)) $< -Fo$@ +endif + diff --git a/ef/Compiler/CodeGenerator/md/x86/x86-makefile.mac b/ef/Compiler/CodeGenerator/md/x86/x86-makefile.mac new file mode 100644 index 000000000000..4bc3b72875a8 --- /dev/null +++ b/ef/Compiler/CodeGenerator/md/x86/x86-makefile.mac @@ -0,0 +1,31 @@ +#!gmake +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +NAD_SRC = "{MOZ_SRC}:ns:electricalfire:Compiler:CodeGenerator:md:x86:x86-win32.nad" +PRIMITIVEOPERATIONS = "{MOZ_SRC}:ns:electricalfire:Compiler:PrimitiveGraph:PrimitiveOperations" +NAD = {PERL} "{MOZ_SRC}:ns:electricalfire:Tools:Nad:Nad.pl" + +NAD_OUTPUTS = {NAD_SRC}.burg.h {NAD_SRC}.burg.cpp {PRIMITIVEOPERATIONS}.h {PRIMITIVEOPERATIONS}.cpp + +{NAD_OUTPUTS} Ä {NAD_SRC} {PRIMITIVEOPERATIONS} + {NAD} {NAD_SRC} {PRIMITIVEOPERATIONS} {PRIMITIVEOPERATIONS}.h {PRIMITIVEOPERATIONS}.cpp {NAD_SRC}.burg.h > BurgOut + BURG -I {NAD_SRC}.burg.cpp + set TouchedFiles "`ResolveAlias {PRIMITIVEOPERATIONS}.h`" + set TouchedFiles "{TouchedFiles},`ResolveAlias {NAD_SRC}.burg.h`" + set TouchedFiles "{TouchedFiles},`ResolveAlias {NAD_SRC}.burg.cpp`" + set TouchedFiles "{TouchedFiles},`ResolveAlias {PRIMITIVEOPERATIONS}.cpp`" + export TouchedFiles diff --git a/ef/Compiler/CodeGenerator/md/x86/x86-win32.nad b/ef/Compiler/CodeGenerator/md/x86/x86-win32.nad new file mode 100644 index 000000000000..e448347cca59 --- /dev/null +++ b/ef/Compiler/CodeGenerator/md/x86/x86-win32.nad @@ -0,0 +1,390 @@ +%top +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#include "Burg.h" +% + +%terminals +% + +%startsymbols +Control +Result +Exception +Store +Vcond +Vint +Vlong +Vfloat +Vdouble +Vptr +Cint +Clong +Cfloat +Cdouble +Cptr +Tuple +% + +%grammar +Vint: coReg_I $1 $ +Vlong: coReg_L $1 $ +Vfloat: coReg_F $1 $ +Vdouble: coReg_D $1 $ +Vptr: coReg_A $1 $ +Vcond: coReg_C $1 $ +Store: coReg_M $1 $ +Cint: coReg_I $1 $ +Clong: coReg_L $1 $ +Cfloat: coReg_F $1 $ +Cdouble: coReg_D $1 $ +Cptr: coReg_A $1 $ + +Vint: poConst_I $1 $emConst_I +Vlong: poConst_L $1 $emConst_L +Vptr: poConst_A $1 $emConst_A + +Vfloat: poConst_F $1 $emConst_F +Vdouble: poConst_D $1 $emConst_D +// Vcond: poConst_C $1 $emConst_C + +//----------------------------------------------------------------- +// Addressing Mode Helpers +Scale: poShl_I(Vint, poConst_I) $0 +ScaleIndex: poAdd_A(Vptr, Scale) $0 +//ScaleIndex: Vptr $0 +DispScaleIndex: poAdd_A(ScaleIndex, poConst_I) $0 +MemDSI: poLd_I(DispScaleIndex) $0 + +Disp: poAdd_A(Vptr, poConst_I) $0 +MemDisp: poLd_I(Disp) $0 + +//----------------------------------------------------------------- +Store: poBreak(Store) $1 $emBreak + +Vint: poArg_I $1 $ +Vlong: poArg_L $1 $ +Vfloat: poArg_F $1 $ +Vdouble: poArg_D $1 $ +Vptr: poArg_A $1 $ +Store: poArg_M $1 $ + +Result: poResult_I(Vint) $1 $emResult_I +Result: poResult_A(Vptr) $1 $emResult_A +Result: poResult_L(Vlong) $1 $emResult_L + +Result: poResult_F(Vfloat) $1 $emResult_F +Result: poResult_D(Vdouble) $1 $emResult_D +// Result: poResult_C(Acond) $1 $emResult_C +Result: poResult_M(Store) $1 $ + + +//----------------------------------------------------------------- +// Conditional Branches +Control: poIfLt(Vcond) $1 $emIfLt +Control: poIfEq(Vcond) $1 $emIfEq +Control: poIfLe(Vcond) $1 $emIfLe +Control: poIfGt(Vcond) $1 $emIfGt +Control: poIfLgt(Vcond) $1 $emIfLgt +Control: poIfGe(Vcond) $1 $emIfGe + +Control: poIfULt(Vcond) $1 $emIfULt +Control: poIfUEq(Vcond) $1 $emIfUEq +Control: poIfULe(Vcond) $1 $emIfULe +Control: poIfUGt(Vcond) $1 $emIfUGt +Control: poIfNe(Vcond) $1 $emIfNe +Control: poIfUGe(Vcond) $1 $emIfUGe + +//----------------------------------------------------------------- +// Booleans +Vint: poLt_I(Vcond) $1 $emLt_I +Vint: poEq_I(Vcond) $1 $emEq_I +Vint: poLe_I(Vcond) $1 $emLe_I +Vint: poGt_I(Vcond) $1 $emGt_I +Vint: poLgt_I(Vcond) $1 $emLgt_I +Vint: poGe_I(Vcond) $1 $emGe_I + +Vint: poULt_I(Vcond) $1 $emULt_I +Vint: poUEq_I(Vcond) $1 $emUEq_I +Vint: poULe_I(Vcond) $1 $emULe_I +Vint: poUGt_I(Vcond) $1 $emUGt_I +Vint: poNe_I(Vcond) $1 $emNe_I +Vint: poUGe_I(Vcond) $1 $emUGe_I + +//----------------------------------------------------------------- +// switch +Control: poSwitch(Vint) $1 $emSwitch + +//----------------------------------------------------------------- +// And +Vint: poAnd_I(Vint, Vint) $1 $emAnd_I +Vint: poAnd_I(Vint, poConst_I) $1 $emAndI_I +Vlong: poAnd_L(Vlong, Vlong) $1 $emAnd_L + +//----------------------------------------------------------------- +// Or +Vint: poOr_I(Vint, Vint) $1 $emOr_I +Vint: poOr_I(Vint, poConst_I) $1 $emOrI_I +Vlong: poOr_L(Vlong, Vlong) $1 $emOr_L + +//----------------------------------------------------------------- +// Xor +Vint: poXor_I(Vint, Vint) $1 $emXor_I +Vint: poXor_I(Vint, poConst_I) $1 $emXorI_I +Vlong: poXor_L(Vlong, Vlong) $1 $emXor_L + +//----------------------------------------------------------------- +// Add +Vint: poAdd_I(Vint, Vint) $1 $emAdd_I +Vptr: poAdd_A(Vptr, Vint) $1 $emAdd_A +Vint: poAdd_I(Vint, poConst_I) $1 $emAddI_I +Vptr: poAdd_A(Vptr, poConst_I) $1 $emAddI_A +Vlong: poAdd_L(Vlong, Vlong) $1 $emAdd_L + +//----------------------------------------------------------------- +// Sub +Vint: poSub_I(poConst_I, Vint) $1 $emSubR_I +Vint: poSub_I(Vint, Vint) $1 $emSub_I +Vptr: poSub_A(Vptr, Vint) $1 $emSub_A +Vlong: poSub_L(Vlong, Vlong) $1 $emSub_L + +//----------------------------------------------------------------- +// Mul +Vint: poMul_I(Vint, Vint) $1 $emMul_I +Vlong: poMul_L(Vlong, Vlong) $1 $emMul_L + +//----------------------------------------------------------------- +// Div +Vint: poDiv_I(Vint, Vint) $1 $emDiv_I +Vint: poDivE_I(Vint, Vint) $1 $emDivE_I + +Vint: poDivU_I(Vint, Vint) $1 $emDivU_I +Vint: poDivUE_I(Vint, Vint) $1 $emDivUE_I + +Vint: poDiv_I(Vint, MemDSI) $1 $emDiv_I_MemDSI +Vint: poDivE_I(Vint, MemDSI) $1 $emDivE_I_MemDSI +Vint: poDiv_I(Vint, MemDSI) $1 $emDivU_I_MemDSI +Vint: poDivE_I(Vint, MemDSI) $1 $emDivUE_I_MemDSI + +Vlong: poDiv_L(Vlong, Vlong) $1 $emDiv_L +Vlong: poDivE_L(Vlong, Vlong) $1 $emDivE_L + +//----------------------------------------------------------------- +// Mod +Vint: poMod_I(Vint, Vint) $1 $emMod_I +Vint: poModE_I(Vint, Vint) $1 $emModE_I + +Vint: poModU_I(Vint, Vint) $1 $emModU_I +Vint: poModUE_I(Vint, Vint) $1 $emModUE_I + +Vint: poMod_I(Vint, MemDSI) $1 $emMod_I_MemDSI +Vint: poModE_I(Vint, MemDSI) $1 $emModE_I_MemDSI +Vint: poMod_I(Vint, MemDSI) $1 $emModU_I_MemDSI +Vint: poModE_I(Vint, MemDSI) $1 $emModUE_I_MemDSI + +Vlong: poMod_L(Vlong, Vlong) $1 $emMod_L +Vlong: poModE_L(Vlong, Vlong) $1 $emModE_L + +//----------------------------------------------------------------- +// Shl +Vint: poShl_I(Vint, Vint) $1 $emShl_I +Vint: poShl_I(Vint, poConst_I) $1 $emShlI_I +Vlong: poShl_L(Vlong, Vint) $1 $emShl_L + +//----------------------------------------------------------------- +// Shr +Vint: poShr_I(Vint, Vint) $1 $emShr_I +Vint: poShr_I(Vint, poConst_I) $1 $emShrI_I +Vlong: poShr_L(Vlong, Vint) $1 $emShr_L + +//----------------------------------------------------------------- +// Shru +Vint: poShrU_I(Vint, Vint) $1 $emShrU_I +Vint: poShrU_I(Vint, poConst_I) $1 $emShrUI_I +Vlong: poShrU_L(Vlong, Vint) $1 $emShrU_L + +//----------------------------------------------------------------- +// sign extend +Vint: poExt_I(Vint, poConst_I) $1 $emExt_I +Vlong: poExt_L(Vlong, poConst_I) $1 $emExt_L + +//----------------------------------------------------------------- +// Floating Point + +Vfloat: poFAdd_F(Vfloat, Vfloat) $1 $emFAdd_F +Vdouble: poFAdd_D(Vdouble, Vdouble) $1 $emFAdd_D + +Vfloat: poFSub_F(Vfloat, Vfloat) $1 $emFSub_F +Vdouble: poFSub_D(Vdouble, Vdouble) $1 $emFSub_D + +Vfloat: poFMul_F(Vfloat, Vfloat) $1 $emFMul_F +Vdouble: poFMul_D(Vdouble, Vdouble) $1 $emFMul_D + +Vfloat: poFDiv_F(Vfloat, Vfloat) $1 $emFDiv_F +Vdouble: poFDiv_D(Vdouble, Vdouble) $1 $emFDiv_D + +Vfloat: poFRem_F(Vfloat, Vfloat) $1 $emFRem_F +Vdouble: poFRem_D(Vdouble, Vdouble) $1 $emFRem_D + +//----------------------------------------------------------------- +// Convert +Vint: poConvI_L(Vlong) $1 $emConvI_L +Vlong: poConvL_I(Vint) $1 $emConvL_I + +Vint: poFConvI_F(Vfloat) $1 $emFConvI_F +Vint: poFConvI_D(Vdouble) $1 $emFConvI_D +Vlong: poFConvL_F(Vfloat) $1 $emFConvL_F +Vlong: poFConvL_D(Vdouble) $1 $emFConvL_D +Vfloat: poFConvF_I(Vint) $1 $emFConvF_I +Vfloat: poFConvF_L(Vlong) $1 $emFConvF_L +Vfloat: poFConvF_D(Vdouble) $1 $emFConvF_D +Vdouble: poFConvD_I(Vint) $1 $emFConvD_I +Vdouble: poFConvD_L(Vlong) $1 $emFConvD_L +Vdouble: poFConvD_F(Vfloat) $1 $emFConvD_F + +//----------------------------------------------------------------- +// Compare +Vcond: poCmp_I(Vint, Vint) $1 $emCmp_I +Vcond: poCmpU_I(Vint, Vint) $1 $emCmpU_I +Vcond: poCmpU_A(Vptr, Vptr) $1 $emCmpU_A + +Vcond: poCmp_I(Vint, poConst_I) $1 $emCmpI_I +Vcond: poCmpU_I(Vint, poConst_I) $1 $emCmpUI_I + +Vint: poCatL_I(poCmp_L(Vlong, Vlong)) $1 $em3wayCmpL_L +Vint: poCatCL_I(poCmp_L(Vlong, Vlong)) $1 $em3wayCmpCL_L + +Vint: poCatL_I(poFCmp_F(Vfloat, Vfloat)) $1 $em3wayCmpF_L +Vint: poCatG_I(poFCmp_F(Vfloat, Vfloat)) $1 $em3wayCmpF_G +Vint: poCatL_I(poFCmp_D(Vdouble, Vdouble)) $1 $em3wayCmpD_L +Vint: poCatG_I(poFCmp_D(Vdouble, Vdouble)) $1 $em3wayCmpD_G + +Vint: poCatCL_I(poFCmp_F(Vfloat, Vfloat)) $1 $em3wayCmpCF_L +Vint: poCatCG_I(poFCmp_F(Vfloat, Vfloat)) $1 $em3wayCmpCF_G +Vint: poCatCL_I(poFCmp_D(Vdouble, Vdouble)) $1 $em3wayCmpCD_L +Vint: poCatCG_I(poFCmp_D(Vdouble, Vdouble)) $1 $em3wayCmpCD_G + +Vcond: poCmp_I(MemDSI, poConst_I) $1 $emCmpI_I_MemDSI +Vcond: poCmp_I(MemDSI, Vint) $1 $emCmp_I_MemDSI + +//----------------------------------------------------------------- +// CheckNull +Exception: poChkNull(Vptr) $1 $emChkNull + +//----------------------------------------------------------------- +// Limit +Exception: poLimit(Vint, Vint) $1 $emLimit +Exception: poLimit(poConst_I, Vint) $1 $emLimitR +Exception: poLimit(poConst_I, MemDisp) $1 $emLimitR_MemDisp +Exception: poLimit(Vint, MemDisp) $1 $emLimit_MemDisp + +//----------------------------------------------------------------- +// Check/Limit Cast +Exception: poChkCast_A(Vptr, poConst_A) $1 $emChkCastI_A +Exception: poChkCast_A(Vptr, Vptr) $1 $emChkCast_A + +Exception: poChkCast_I(Vint, Vint) $1 $emChkCast_I + +Exception: poLimCast(Vint) $1 $emLimCast + +//----------------------------------------------------------------- +// Load +Vint: poLd_I(Vptr) $1 $emLd_I +Vptr: poLd_A(Vptr) $1 $emLd_A +Vlong: poLd_L(Vptr) $1 $emLd_L +Vfloat: poLd_F(Vptr) $1 $emLd_F +Vdouble: poLd_D(Vptr) $1 $emLd_D + +Vint: poLdS_B(Vptr) $1 $emLdS_B +Vint: poLdU_B(Vptr) $1 $emLdU_B + +Vint: poLdS_H(Vptr) $1 $emLdS_H +Vint: poLdU_H(Vptr) $1 $emLdU_H + +Vint: MemDisp $1 $emLd_I_MemDisp +Vint: MemDSI $1 $emLd_I_MemDSI + +// FIXME - Add these patterns for performance +// Vfloat: poLd_F(Disp) $1 $emLd_F_MemDisp +// Vfloat: poLd_F(DispScaleIndex) $1 $emLd_F_MemDSI +// Vdouble: poLd_D(Disp) $1 $emLd_D_MemDisp +// Vdouble: poLd_D(DispScaleIndex) $1 $emLd_D_MemDSI + +//----------------------------------------------------------------- +// Store +Store: poSt_I(Vptr, Vint) $1 $emSt_I +Store: poSt_I(Vptr, poConst_I) $1 $emStI_I +Store: poSt_A(Vptr, Vptr) $1 $emSt_A +Store: poSt_L(Vptr, Vlong) $1 $emSt_L + +Store: poSt_B(Vptr, Vint) $1 $emSt_B +Store: poSt_H(Vptr, Vint) $1 $emSt_H + +Store: poSt_I(Disp, poConst_I) $1 $emStI_I_MemDisp +Store: poSt_I(Disp, Vint) $1 $emSt_I_MemDisp +Store: poSt_I(DispScaleIndex, Vint) $1 $emSt_I_MemDSI + +Store: poSt_F(Vptr, Vfloat) $1 $emSt_F +Store: poSt_D(Vptr, Vdouble) $1 $emSt_D + +// FIXME - Add below patterns for performance +//Store: poSt_F(Disp, poConst_I) $1 $emStI_F_MemDisp +//Store: poSt_F(Disp, Vint) $1 $emSt_F_MemDisp +//Store: poSt_F(DispScaleIndex, Vint) $1 $emSt_F_MemDSI + +//Store: poSt_D(Disp, poConst_I) $1 $emStI_D_MemDisp +//Store: poSt_D(Disp, Vint) $1 $emSt_D_MemDisp +//Store: poSt_D(DispScaleIndex, Vint) $1 $emSt_D_MemDSI + +//----------------------------------------------------------------- +// Monitor +//Store: poMEnter_A(Vptr) $1 $emMEnter_A +//Store: poMExit_A(Vptr) $1 $emMExit_A + +//----------------------------------------------------------------- +// Monitor +Store: poMEnter(Store, Vptr) $1 $emMEnter +Store: poMExit(Store, Vptr) $1 $emMExit + +//----------------------------------------------------------------- +// Projections +Store: poProj_M $1 $ +Vint: poProj_I $1 $ +Vptr: poProj_A $1 $ +Vlong: poProj_L $1 $ +Vfloat: poProj_F $1 $ +Vdouble: poProj_D $1 $ + +//----------------------------------------------------------------- +// Syscalls +Tuple: poSysCall $1 $emSysCall +Tuple: poSysCallE $1 $emSysCallE +Tuple: poSysCallC $1 $emSysCallC +Tuple: poSysCallEC $1 $emSysCallEC +Tuple: poSysCallV $1 $emSysCallV +Tuple: poSysCallEV $1 $emSysCallEV + +//----------------------------------------------------------------- +// Calls +Tuple: poCall(Vptr) $1 $emDynamicCall +Tuple: poCall(poConst_A) $1 $emStaticCall + +//----------------------------------------------------------------- +// Catch +Vptr: poCatch $1 $emCatch +% diff --git a/ef/Compiler/CodeGenerator/md/x86/x86ArgumentList.cpp b/ef/Compiler/CodeGenerator/md/x86/x86ArgumentList.cpp new file mode 100644 index 000000000000..d2be0e5bd481 --- /dev/null +++ b/ef/Compiler/CodeGenerator/md/x86/x86ArgumentList.cpp @@ -0,0 +1,1144 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +// +// x86ArgumentList.cpp +// +// Peter DeSantis +// Simon Holmes a Court + +#include "x86ArgumentList.h" +#include "x86Opcode.h" +#include "x86Win32Instruction.h" +#include "MemoryAccess.h" +#include "x86Formatter.h" + +UT_DEFINE_LOG_MODULE(x86ArgList); + +// Maps register alloc color to x86 machine register +// Order matters. +x86GPR colorTox86GPR[] = +{ + EAX, + EBX, + ECX, + EDX, + ESI, + EDI, + /*ESP, + EBP*/ +}; + +// Maps x86 machine register to register alloc color +// Order matters. +Uint8 x86GPRToColor[] = +{ + 0, // EAX + 2, // ECX + 3, // EDX + 1, // EBX + 6, // ESP + 7, // EBP + 4, // ESI + 5, // EDI +}; + +// Text labels listed by processor register numbers +// Order matters. +char* x86GPRText[] = +{ + "eax", + "ecx", + "edx", + "ebx", + "esp", + "ebp", + "esi", + "edi" +}; + +/*-------------------------------------------------------------------------------- +x86ArgumentType + struct x86ArgumentTypeInfo + { + Uint8 atiSize; // number of bytes needed to format + Uint8 atiNumUses; // number of uses consumed + SIBScale atiScale; // scale factor + TypeClass atTypeClass; // can the type be passed to the constructor? + char* atiPrintInfo; // debug formatting string // FIX shouldn't be in release build + } +atRegisterIndirect, atBaseIndexed, atScaledIndexedBy2, atScaledIndexedBy4, atScaledIndexedBy8, atStackOffset can +only be specified without displacements. The constructor promotes these types based on the size of the +displacement. The constructors depends on the ordering of these. +*/ + +enum SIBScale +{ + kScaleBy1 = 0x00, + kScaleBy2 = 0x40, + kScaleBy4 = 0x80, + kScaleBy8 = 0xc0, + kScaleIllegal = 0xff // not a legal SIB value -- used only for debugging +}; + +enum TypeClass +{ + kCannotHaveDisp,// can be passed in as a parameter + kMustHaveDisp, // as per kPrimaryArg, but _must_ have an extra arg (displacement or immediate) + kMayHaveDisp, // as per kPrimaryArg, but _may_ have an extra arg (displacement or immediate) + kDerived // cannot be passed in with a parameter +}; + +// Each x86ArgumentType has a x86ArgumentTypeInfo defined for it in atInfo. +struct x86ArgumentTypeInfo +{ + Uint8 atiSize; // number of bytes needed to format + Uint8 atiNumUses; // number of uses consumed + SIBScale atiScale; // scale factor + TypeClass atTypeClass; // see TypeClass + char* atiPrintInfo; // debug formatting string // FIX shouldn't be in release build +}; + +x86ArgumentTypeInfo atInfo[] = +{ + {1, 1, kScaleIllegal, kCannotHaveDisp,"%s"}, // atRegDirect + {5, 1, kScaleIllegal, kCannotHaveDisp,"%d[%s]"}, // atRegAllocStackSlot + {5, 1, kScaleIllegal, kCannotHaveDisp,"%d[%s]"}, // atRegAllocStackSlotHi32 + + {1, 1, kScaleIllegal, kMayHaveDisp, "[%s]"}, // atRegisterIndirect + {2, 1, kScaleIllegal, kDerived, "%d[%s]"}, // atRegisterRelative1ByteDisplacement + {5, 1, kScaleIllegal, kDerived, "%d[%s]"}, // atRegisterRelative4ByteDisplacement + + {2, 2, kScaleBy1, kMayHaveDisp, "[%s+%s]"}, // atBaseIndexed + {3, 2, kScaleBy1, kDerived, "%d[%s+%s]"}, // atBaseRelativeIndexed1ByteDisplacement + {6, 2, kScaleBy1, kDerived, "%d[%s+%s]"}, // atBaseRelativeIndexed4ByteDisplacement + + {2, 2, kScaleBy2, kMayHaveDisp, "[%s+2*%s]"}, // atScaledIndexedBy2 + {3, 2, kScaleBy2, kDerived, "%d[%s+2*%s]"}, // atScaledIndexed1ByteDisplacementBy2 + {6, 2, kScaleBy2, kDerived, "%d[%s+2*%s]"}, // atBaseRelativeIndexed4ByteDisplacementBy2 + + {2, 2, kScaleBy4, kMayHaveDisp, "[%s+4*%s]"}, // atScaledIndexedBy4 + {3, 2, kScaleBy4, kDerived, "%d[%s+4*%s]"}, // atScaledIndexed1ByteDisplacementBy4 + {6, 2, kScaleBy4, kDerived, "%d[%s+4*%s]"}, // atScaledIndexed4ByteDisplacementBy4 + + {2, 2, kScaleBy8, kMayHaveDisp, "[%s+8*%s]"}, // atScaledIndexedBy8 + {3, 2, kScaleBy8, kDerived, "%d[%s+8*%s]"}, // atScaledIndexed1ByteDisplacementBy8 + {6, 2, kScaleBy8, kDerived, "%d[%s+8*%s]"}, // atScaledIndexed4ByteDisplacementBy8 + + {0, 0, kScaleIllegal, kMayHaveDisp, "NOT USED"}, // atStackOffset + {2, 0, kScaleIllegal, kDerived, "%d[EBP]"}, // atStackOffset1ByteDisplacement + {5, 0, kScaleIllegal, kDerived, "%d[EBP]"}, // atStackOffset4ByteDisplacement + + {6, 0, kScaleIllegal, kMustHaveDisp, "[0x%08x]"}, // atAbsoluteAddress + {0, 0, kScaleIllegal, kCannotHaveDisp,"%d"} // atImmediateOnly +}; + +//-------------------------------------------------------------------------------- +// SingleArgumentList + +// Method: alGetRegisterOperand +// Purpose: extract the register or registers that are the components of the current operand +// Used by: X86Opcode_Reg_Condensable when it is trying to append register operands into the opcode +// Input: instruction +// Output: returns the register number (if SingleArgumentList and ImmediateArgumentList) +// or NOT_A_REG (otherwise) +Uint8 x86SingleArgumentList:: +alGetRegisterOperand(x86ArgListInstruction& inInsn) +{ + if(argType1 == atRegDirect) + { + InstructionUse* useBegin = &(inInsn.getInstructionUseBegin()[0]); + InstructionUse* useEnd = inInsn.getInstructionUseEnd(); + + if((useBegin < useEnd) && useBegin->isVirtualRegister()) + return useToRegisterNumber(*useBegin); + + InstructionDefine* defineBegin = inInsn.getInstructionDefineBegin(); + InstructionDefine* defineEnd = inInsn.getInstructionDefineEnd(); + assert((defineBegin < defineEnd) && (defineBegin)->isVirtualRegister()) ; + return defineToRegisterNumber(*defineBegin); + } + // Must be memory + return NOT_A_REG; +} + +// Method: extractOperand +// Purpose: extract the register or registers that are the components of the current operand +// Input: instruction +// location of the register encodings +// Output: one or two registers (expressed as x86 register numbers) +// reg = either InstructionUses[inInstructionUseStartIndex] or the first InstructionDefine +// reg2 = is filled iff the use or define after reg is a valid register +inline void extractOperand(x86ArgListInstruction& inInsn, Uint8 inInstructionUseStartIndex, Uint8& reg, Uint8& reg2) +{ + + InstructionUse* useBegin = &(inInsn.getInstructionUseBegin()[inInstructionUseStartIndex]); + InstructionUse* useEnd = inInsn.getInstructionUseEnd(); + + if((useBegin < useEnd) && useBegin->isVirtualRegister()) + { + reg = useToRegisterNumber(*useBegin); + if((useBegin + 1 < useEnd) && (useBegin +1)->isVirtualRegister()) + reg2 = useToRegisterNumber(*(useBegin+1)); + else + reg2 = NOT_A_REG; + } + else + { // This means that the virtual registers must be the first of the defines + InstructionDefine* defineBegin = inInsn.getInstructionDefineBegin(); + InstructionDefine* defineEnd = inInsn.getInstructionDefineEnd(); + assert((defineBegin < defineEnd) && (defineBegin)->isVirtualRegister()) ; + reg = defineToRegisterNumber(*defineBegin); + if ((defineBegin + 1 < defineEnd) && (defineBegin + 1)->isVirtualRegister()) + reg2 = defineToRegisterNumber(*(defineBegin+1)); + else + reg2 = NOT_A_REG; + } +} + +#ifdef DEBUG_LOG + +// Method: alPrintPretty +// Purpose: basic print pretty utility function for all argument lists which have one or more reg/mem operands +// Input: LogModuleObject +// x86ArgListInstruction to be printed +// type of argument +// location of the register encodings +// Output: prints to LogModuleObject +void x86SingleArgumentList:: +alPrintPretty(LogModuleObject &f, x86ArgListInstruction& inInsn, x86ArgumentType inType, Uint8 inInstructionUseStartIndex ) +{ + switch (inType) + { + case atImmediateOnly: + return; + + case atAbsoluteAddress: + UT_OBJECTLOG(f, PR_LOG_ALWAYS, (atInfo[inType].atiPrintInfo, arg4ByteDisplacement)); + return; + + case atRegAllocStackSlot: + { + InstructionUse* useBegin = &(inInsn.getInstructionUseBegin()[inInstructionUseStartIndex]); + InstructionUse* useEnd = inInsn.getInstructionUseEnd(); + + if((useBegin < useEnd) && useBegin->isVirtualRegister()) // Stack slot is the use + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("slot%d", useBegin->getVirtualRegister().getColor())); + else // Stack slot is the define + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("slot%d", inInsn.getInstructionDefineBegin()->getVirtualRegister().getColor() )); + } + return; + + case atRegAllocStackSlotHi32: + { + InstructionUse* useBegin = &(inInsn.getInstructionUseBegin()[inInstructionUseStartIndex]); + InstructionUse* useEnd = inInsn.getInstructionUseEnd(); + + if((useBegin < useEnd) && useBegin->isVirtualRegister()) // Stack slot is the use + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("Hi32(slot%d)", useBegin->getVirtualRegister().getColor())); + else // Stack slot is the define + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("Hi32(slot%d)", inInsn.getInstructionDefineBegin()->getVirtualRegister().getColor() )); + } + return; + + case atStackOffset1ByteDisplacement: + UT_OBJECTLOG(f, PR_LOG_ALWAYS, (atInfo[inType].atiPrintInfo, arg1ByteDisplacement)); + return; + + case atStackOffset4ByteDisplacement: + UT_OBJECTLOG(f, PR_LOG_ALWAYS, (atInfo[inType].atiPrintInfo, arg4ByteDisplacement)); + return; + default: + 0; // do nothing -- fall through (is there a better way to make gcc happy?) + } + + // registers are needed for remaining types + Uint8 reg, reg2; + extractOperand(inInsn, inInstructionUseStartIndex, reg, reg2); + + switch (inType) + { + case (atRegDirect): + case (atRegisterIndirect): + UT_OBJECTLOG(f, PR_LOG_ALWAYS, (atInfo[inType].atiPrintInfo, x86GPRText[reg] )); + break; + + case (atRegisterRelative1ByteDisplacement): + UT_OBJECTLOG(f, PR_LOG_ALWAYS, (atInfo[inType].atiPrintInfo, arg1ByteDisplacement, x86GPRText[reg] )); + break; + + case (atRegisterRelative4ByteDisplacement): + UT_OBJECTLOG(f, PR_LOG_ALWAYS, (atInfo[inType].atiPrintInfo, arg4ByteDisplacement, x86GPRText[reg] )); + break; + + case(atBaseIndexed): + case(atScaledIndexedBy2): + case(atScaledIndexedBy4): + case(atScaledIndexedBy8): + assert(reg2 != NOT_A_REG); + UT_OBJECTLOG(f, PR_LOG_ALWAYS, (atInfo[inType].atiPrintInfo, x86GPRText[reg], x86GPRText[reg2] )); + break; + + case(atBaseRelativeIndexed1ByteDisplacement): + case(atScaledIndexed1ByteDisplacementBy2): + case(atScaledIndexed1ByteDisplacementBy4): + case(atScaledIndexed1ByteDisplacementBy8): + assert(reg2 != NOT_A_REG); + UT_OBJECTLOG(f, PR_LOG_ALWAYS, (atInfo[inType].atiPrintInfo, arg1ByteDisplacement, x86GPRText[reg], x86GPRText[reg2] )); + break; + + default: + UT_OBJECTLOG(f, PR_LOG_ALWAYS, (atInfo[inType].atiPrintInfo, arg4ByteDisplacement, x86GPRText[reg], x86GPRText[reg2] )); + break; + } +} + +#endif // DEBUG_LOG + +// Method: alSize +// Purpose: calculate the size of the argument list +// Input: type of argument +// instruction +// location of the register encodings +// Output: number of bytes of space needed to encode argument +Uint8 x86SingleArgumentList:: +alSize(x86ArgumentType inType, x86ArgListInstruction& inInsn, Uint8 inInstructionUseStartIndex, MdFormatter& inFormatter) +{ + switch (inType) + { + case atRegisterIndirect: + { + Uint8 reg, reg2; + extractOperand(inInsn, inInstructionUseStartIndex, reg, reg2); + if ((reg == EBP)) + return 2; + return atInfo[inType].atiSize; + } + break; + + case atRegAllocStackSlot: + case atRegAllocStackSlotHi32: + { + InstructionUseOrDefine* uord = NULL; + InstructionUse* useBegin = &inInsn.getInstructionUseBegin()[inInstructionUseStartIndex]; + InstructionUse* useEnd = inInsn.getInstructionUseEnd(); + if ((useBegin < useEnd) && useBegin->isVirtualRegister()) + uord = useBegin; + else + uord = inInsn.getInstructionDefineBegin(); + + Uint32 unsizedDisplacement = inFormatter.getStackSlotOffset(uord->getVirtualRegister()); + if(valueIsOneByteSigned(unsizedDisplacement)) + return 2; + else + return 5; + } + break; + +/* + If we want to use ESP + case (atRegisterIndirect): + if ((reg == EBP)) + return 2; + case (atRegisterRelative1ByteDisplacement): + if (getRegUse() == ESP) + return 3; + + case (atRegisterRelative4ByteDisplacement): + if (getRegUse() == ESP) + return 6; +*/ + + default: + return atInfo[inType].atiSize; + } +} + +void x86SingleArgumentList:: +alFormatStackSlotToMemory(void* inStart, x86ArgListInstruction& inInsn, Uint8 inInstructionUseStartIndex, + MdFormatter& inFormatter, int offset) +{ + Uint8 modRM = 0; + Uint8* start = (Uint8*) inStart; + + InstructionUse* useBegin = &inInsn.getInstructionUseBegin()[inInstructionUseStartIndex]; + InstructionUse* useEnd = inInsn.getInstructionUseEnd(); + + // find the stack slot + VirtualRegister* vrStackSlot = NULL; + if ((useBegin < useEnd) && useBegin->isVirtualRegister()) // if there are uses + { + vrStackSlot = &(useBegin->getVirtualRegister()); + } + + // at this point vrStackSlot points to + // a. a stack slot (the correct thing to do) + // b. an non-stack slot register (bad) + // c. NULL + // In the last two conditions we need to get the stack slot from the define + if(vrStackSlot == NULL || vrStackSlot->getClass() != StackSlotRegister) + { + InstructionDefine* defineBegin = inInsn.getInstructionDefineBegin(); + InstructionDefine* defineEnd = inInsn.getInstructionDefineEnd(); + assert(defineBegin < defineEnd); // we've got to have one! + + vrStackSlot = &(defineBegin->getVirtualRegister()); + assert(vrStackSlot->getClass() == StackSlotRegister); + } + + Int32 unsizedDisplacement = inFormatter.getStackSlotOffset(*vrStackSlot) + offset; + assert(vrStackSlot->getClass() == StackSlotRegister); + + if(valueIsOneByteSigned(unsizedDisplacement)) + { + modRM = 0x40 | EBP; + *start++ = modRM; + *(Int8*)start = (Uint8)unsizedDisplacement; + } + else + { + modRM = 0x80 | EBP; + *start++ = modRM; + *(Int32*)start = unsizedDisplacement; + } +} + +void x86SingleArgumentList:: +alFormatNonRegToMemory(void* inStart, x86ArgListInstruction& /*inInsn*/, x86ArgumentType inType, MdFormatter& /*inFormatter*/) +{ + Uint8* start = (Uint8*) inStart; + Uint8 modRM, SIB; + + switch(inType) + { + case atAbsoluteAddress: + modRM = 0x04; + SIB = 0x25; + *start++ = modRM; + *start++ = SIB; + // Absolute memory address must use a 4 byte "displacement". + writeLittleWordUnaligned((void*)start, arg4ByteDisplacement); + break; + + case atStackOffset1ByteDisplacement: + modRM = 0x45; + *start++ = modRM; + *start = arg1ByteDisplacement; + break; + + case atStackOffset4ByteDisplacement: + modRM = 0x85; + *start++ = modRM; + writeLittleWordUnaligned((void*)start, arg4ByteDisplacement); + break; + + default: + trespass("illegal inType"); + } +} + +void x86SingleArgumentList:: +alFormatRegToMemory(void* inStart, x86ArgListInstruction& inInsn, x86ArgumentType inType, Uint8 inInstructionUseStartIndex, MdFormatter& /*inFormatter*/) +{ + Uint8 modRM; + Uint8 SIB; + Uint8 reg, reg2; + + Uint8* start = (Uint8*) inStart; + SIBScale scale = atInfo[argType1].atiScale; + extractOperand(inInsn, inInstructionUseStartIndex, reg, reg2); + assert( reg != ESP && reg2 != ESP ); + + switch (inType) + { + case atRegDirect: + modRM = 0xc0 | reg; + *start = modRM; + break; + + case atRegisterIndirect: + if (reg == EBP) + { + modRM = 0x45; + *start++ = modRM; + *start = 0; + break; + } + /* if (reg == ESP) + { + modRM = 0x04; + SIB = 0x24; + *start = modRM; + start++; + *start = SIB; + return; + } + */ + modRM = 0x00 | reg; + *start = modRM; + break; + + case atBaseIndexed: + case atScaledIndexedBy2: + case atScaledIndexedBy4: + case atScaledIndexedBy8: + assert(reg2 != NOT_A_REG); + assert(scale != kScaleIllegal); + modRM = 0x04; + *start++ = modRM; + assert (reg != EBP); // EBP is an invalid index + //assert (reg2 != ESP); // Index + SIB = scale | (reg2 << 3) | reg; + *start = SIB; + break; + + case atBaseRelativeIndexed1ByteDisplacement: + case atScaledIndexed1ByteDisplacementBy2: + case atScaledIndexed1ByteDisplacementBy4: + case atScaledIndexed1ByteDisplacementBy8: + assert(reg2 != NOT_A_REG); + assert(scale != kScaleIllegal); + modRM = 0x44; + *start++ = modRM; + SIB = scale | ( reg2 << 3) | reg; + *start++ = SIB; + *start = arg1ByteDisplacement; + break; + + case atBaseRelativeIndexed4ByteDisplacement: + case atScaledIndexed4ByteDisplacementBy2: + case atScaledIndexed4ByteDisplacementBy4: + case atScaledIndexed4ByteDisplacementBy8: + assert(reg2 != NOT_A_REG); // must have two regs + assert(scale != kScaleIllegal); + modRM = 0x84; + assert (reg2 != ESP); // ESP is an invalid index + SIB = scale | ( reg2 << 3) | reg; + *start++ = modRM; + *start++ = SIB; + writeLittleWordUnaligned((void*)start, arg4ByteDisplacement); + break; + + case atRegisterRelative1ByteDisplacement: + if (reg == ESP) + { + modRM = 0x44; + SIB = 0x24; + *start++ = modRM; + *start++ = SIB; + *start = arg1ByteDisplacement; + } + else + { + modRM = 0x40 | reg; + *start++ = modRM; + *start = arg1ByteDisplacement; + } + break; + + case atRegisterRelative4ByteDisplacement: + if (reg == ESP) + { + modRM = 0x84; + SIB = 0x24; + *start++ = modRM; + *start = SIB; + } else { + modRM = 0x80 | reg; + *start++ = modRM; + writeLittleWordUnaligned((void*)start, arg4ByteDisplacement); + } + break; + + default: + trespass("illegal inType"); + } +} + +// Format an instruction to IA32 machine code +void x86SingleArgumentList:: +alFormatToMemory(void* inStart, x86ArgListInstruction& inInsn, x86ArgumentType inType, Uint8 inInstructionUseStartIndex, MdFormatter& inFormatter) +{ + // FIX replace by table lookup if more efficient + switch(inType) + { + case atImmediateOnly: + return; + + case atAbsoluteAddress: + case atStackOffset1ByteDisplacement: + case atStackOffset4ByteDisplacement: + alFormatNonRegToMemory(inStart, inInsn, inType, inFormatter); + return; + + case atRegAllocStackSlot: + alFormatStackSlotToMemory(inStart, inInsn, inInstructionUseStartIndex, inFormatter, 0); + return; + + case atRegAllocStackSlotHi32: + alFormatStackSlotToMemory(inStart, inInsn, inInstructionUseStartIndex, inFormatter, 4); + return; + + case atRegDirect: + case atRegisterIndirect: + case atBaseIndexed: + case atScaledIndexedBy2: + case atScaledIndexedBy4: + case atScaledIndexedBy8: + case atBaseRelativeIndexed1ByteDisplacement: + case atScaledIndexed1ByteDisplacementBy2: + case atScaledIndexed1ByteDisplacementBy4: + case atScaledIndexed1ByteDisplacementBy8: + case atBaseRelativeIndexed4ByteDisplacement: + case atScaledIndexed4ByteDisplacementBy2: + case atScaledIndexed4ByteDisplacementBy4: + case atScaledIndexed4ByteDisplacementBy8: + case atRegisterRelative1ByteDisplacement: + case atRegisterRelative4ByteDisplacement: + alFormatRegToMemory(inStart, inInsn, inType, inInstructionUseStartIndex, inFormatter); + return; + + default: + trespass("illegal inType"); + } +} + +//-------------------------------------------------------------------------------- +// x86SingleArgumentList +x86SingleArgumentList:: +x86SingleArgumentList(x86ArgumentType inType) : + argType1(inType) +{ + // check that inType is valid. + assert(atInfo[inType].atTypeClass == kMayHaveDisp || atInfo[inType].atTypeClass == kCannotHaveDisp); +} + +x86SingleArgumentList:: +x86SingleArgumentList(x86ArgumentType inType, Uint32 inDisplacement) +{ + assert(atInfo[inType].atTypeClass == kMayHaveDisp || atInfo[inType].atTypeClass == kMustHaveDisp); + if(inType == atAbsoluteAddress) + { + // Must take a 4 byte address + arg4ByteDisplacement = inDisplacement; + argType1 = inType; + return; + } + + assert(atInfo[inType].atTypeClass == kMayHaveDisp); + if(valueIsOneByteSigned(inDisplacement)) + { + arg1ByteDisplacement = (Uint8)inDisplacement; + argType1 = (x86ArgumentType)(inType + 1); + } else { + arg4ByteDisplacement = inDisplacement; + argType1 = (x86ArgumentType)(inType + 2); + } +} + +bool x86SingleArgumentList:: +alSwitchArgumentTypeToSpill(Uint8 /*inWhichUse*/, x86ArgListInstruction& /* inInsn */ ) +{ + // assert(argType1 != atRegAllocStackSlot); // wouldn't we be lying in our result if this were true? + bool couldSpill; + + if(argType1 == atRegDirect) + { + argType1 = atRegAllocStackSlot; + couldSpill = true; + } + else + couldSpill = false; + + return couldSpill; +} + +void x86SingleArgumentList:: +alFormatToMemory(void* inStart, Uint32 /*inOffset*/, x86ArgListInstruction& inInsn, MdFormatter& inFormatter) +{ + // If the argument is a register direct and the opcode can be appended with the reg + // then the argument list is empty, so do nothing. + if( (argType1 != atRegDirect) || (!inInsn.regOperandCanBeCondensed()) ) + alFormatToMemory(inStart, inInsn, argType1, 0, inFormatter); +} + +Uint8 x86SingleArgumentList:: +alSize(x86ArgListInstruction& inInsn, MdFormatter& inFormatter) +{ + // If the argument is a register direct and the opcode can be appended with the reg + // then the argument list is empty, so do nothing. + if( (argType1 != atRegDirect) || (!inInsn.regOperandCanBeCondensed()) ) + return alSize(argType1, inInsn, 0, inFormatter); + else + return 0; +} + +//-------------------------------------------------------------------------------- +// x86DoubleArgumentList +x86DoubleArgumentList:: +x86DoubleArgumentList(x86ArgumentType inType1, x86ArgumentType inType2) : + x86SingleArgumentList(inType1), + argType2(inType2) +{ + // check that at most one of the operands is 'memory' + // ie check that at least on of the operands is register + assert(inType1 == atRegDirect || inType2 == atRegDirect); + + // check that inType is valid. + assert(atInfo[inType1].atTypeClass == kMayHaveDisp || atInfo[inType1].atTypeClass == kCannotHaveDisp); + assert(atInfo[inType2].atTypeClass == kMayHaveDisp || atInfo[inType2].atTypeClass == kCannotHaveDisp); +} + +x86DoubleArgumentList:: +x86DoubleArgumentList(x86ArgumentType inType1, x86ArgumentType inType2, Uint32 inDisplacement) +{ + // Make sure only one of the operands is memory type. And set the type based on the displacement. + switch(inType1) + { + case (atRegDirect): + argType1 = inType1; + switch(inType2) + { +/* case (atMemoryDirect): + arg4ByteDisplacement = inDisplacement; + argType2 = inType2; + break; +*/ + case (atRegisterIndirect): + case (atBaseIndexed): + case (atScaledIndexedBy2): + case (atScaledIndexedBy4): + case (atScaledIndexedBy8): + if(valueIsOneByteSigned(inDisplacement)) + { + arg1ByteDisplacement = (Uint8)inDisplacement; + argType2 = x86ArgumentType(inType2 + 1); + } else { + arg4ByteDisplacement = inDisplacement; + argType2 = x86ArgumentType(inType2 + 2); + } + break; + default: + assert(false); + } + break; + +/* case (atMemoryDirect): + arg4ByteDisplacement = inDisplacement; + argType1 = inType1; + assert(inType2 == atRegDirect); + argType2 = atRegDirect; + break; +*/ +// case kMayHaveDisp: + case (atRegisterIndirect): + case (atBaseIndexed): + case (atScaledIndexedBy2): + case (atScaledIndexedBy4): + case (atScaledIndexedBy8): + case (atStackOffset): + if(valueIsOneByteSigned(inDisplacement)) + { + arg1ByteDisplacement = (Uint8)inDisplacement; + argType1 = x86ArgumentType(inType1 + 1); + } else { + arg4ByteDisplacement = inDisplacement; + argType1 = x86ArgumentType(inType1 + 2); + } + assert(inType2 == atRegDirect); + argType2 = atRegDirect; + break; + default: + assert(false); + } +} + +#ifdef DEBUG +void x86DoubleArgumentList:: +alCheckIntegrity(x86ArgListInstruction& inInsn) +{ + VRClass reg1; + VRClass reg2; + + if(argType1 == atRegDirect || argType1 == atRegAllocStackSlot || argType1 == atRegAllocStackSlotHi32) + reg1 = alGetArg1VirtualRegister(inInsn)->getClass(); + if(argType2 == atRegDirect || argType2 == atRegAllocStackSlot || argType2 == atRegAllocStackSlotHi32) + reg2 = alGetArg2VirtualRegister(inInsn)->getClass(); + + // ie if use1 is an IntegerRegister, arg1 must be atRegDirect + // etc. + if(argType1 == atRegDirect) + if(reg1 != IntegerRegister) + goto failedTest; + if(argType1 == atRegAllocStackSlot || argType1 == atRegAllocStackSlotHi32) + if(reg1 != StackSlotRegister) + goto failedTest; + if(argType2 == atRegDirect) + if(reg2 != IntegerRegister) + goto failedTest; + if(argType2 == atRegAllocStackSlot || argType2 == atRegAllocStackSlotHi32) + if(reg2 != StackSlotRegister) + goto failedTest; + + return; + +failedTest: + fprintf(stderr, "\n\n** Failed Test\n"); + alPrintArgs(inInsn); + trespass("argument list failed integrity check"); +} + +void x86DoubleArgumentList:: +alPrintArgs(x86ArgListInstruction& inInsn) +{ + UT_LOG(x86ArgList, PR_LOG_DEBUG, ("\n Instruction %p\n", &inInsn)); + UT_LOG(x86ArgList, PR_LOG_DEBUG, (" argType1: ")); + switch(argType1) + { + case atRegDirect: UT_LOG(x86ArgList, PR_LOG_DEBUG, ("atRegDirect ")); break; + case atRegAllocStackSlot: UT_LOG(x86ArgList, PR_LOG_DEBUG, ("atRegAllocStackSlot ")); break; + case atRegAllocStackSlotHi32: UT_LOG(x86ArgList, PR_LOG_DEBUG, ("atRegAllocStackSlotHi32 ")); break; + default: UT_LOG(x86ArgList, PR_LOG_DEBUG, ("other ")); break; + } + UT_LOG(x86ArgList, PR_LOG_DEBUG, ("use1(vr %p): ", alGetArg1VirtualRegister(inInsn))); + switch(alGetArg1VirtualRegister(inInsn)->getClass()) + { + case IntegerRegister: UT_LOG(x86ArgList, PR_LOG_DEBUG, ("IntegerRegister\n")); break; + case StackSlotRegister: UT_LOG(x86ArgList, PR_LOG_DEBUG, ("StackSlotRegister\n")); break; + default: UT_LOG(x86ArgList, PR_LOG_DEBUG, ("other\n")); break; + } + + UT_LOG(x86ArgList, PR_LOG_DEBUG, (" argType2: ")); + switch(argType2) + { + case atRegDirect: UT_LOG(x86ArgList, PR_LOG_DEBUG, ("atRegDirect ")); break; + case atRegAllocStackSlot: UT_LOG(x86ArgList, PR_LOG_DEBUG, ("atRegAllocStackSlot ")); break; + case atRegAllocStackSlotHi32: UT_LOG(x86ArgList, PR_LOG_DEBUG, ("atRegAllocStackSlotHi32 ")); break; + default: UT_LOG(x86ArgList, PR_LOG_DEBUG, ("other ")); break; + } + UT_LOG(x86ArgList, PR_LOG_DEBUG, ("use2(vr %p): ", alGetArg2VirtualRegister(inInsn))); + switch(alGetArg2VirtualRegister(inInsn)->getClass()) + { + case IntegerRegister: UT_LOG(x86ArgList, PR_LOG_DEBUG, ("IntegerRegister\n\n")); break; + case StackSlotRegister: UT_LOG(x86ArgList, PR_LOG_DEBUG, ("StackSlotRegister\n\n")); break; + default: UT_LOG(x86ArgList, PR_LOG_DEBUG, ("other\n\n")); break; + } +} + +#endif + +bool x86DoubleArgumentList:: +alSwitchArgumentTypeToSpill(Uint8 inWhichUse, x86ArgListInstruction& inInsn) +{ + +#ifdef DEBUG + alCheckIntegrity(inInsn); // ensure that everthing makes sense here +#endif + + // ensure that we are not trying to spill a stack slot register + if(inWhichUse == 0) + assert(argType1 != atRegAllocStackSlot && argType1 != atRegAllocStackSlotHi32); + else + assert(argType2 != atRegAllocStackSlot && argType2 != atRegAllocStackSlotHi32); + + // can only spill if both arguments are currently atRegDirect + if((argType1 != atRegDirect) || (argType2 != atRegDirect)) + return false; + + // try to spill + assert(inWhichUse <= 1); + if(inWhichUse == 0) // first use + { + // to spill we'll need to reverse the operands + // return failure if operands couldn't be reversed + if(!inInsn.canReverseOperands()) + return false; + + // ok, we can reverse, so do it + argType1 = atRegAllocStackSlot; + } + else // second use + { + // FIX FIX FIX Quick Hack + if(!inInsn.canReverseOperands()) + return false; + + argType2 = atRegAllocStackSlot; + } + return true; +} + +// temporary helper method until x86DoubleArgumentList can be cleaned up +bool x86DoubleArgumentList:: +alHasTwoArgs(x86ArgListInstruction& inInsn) +{ + InstructionUse* useBegin = inInsn.getInstructionUseBegin(); + InstructionUse* supplementaryUseBegin = useBegin + atInfo[argType1].atiNumUses; // skip over first arg's registers + InstructionUse* useEnd = inInsn.getInstructionUseEnd(); + return (supplementaryUseBegin < useEnd) && supplementaryUseBegin->isVirtualRegister(); +} + +void x86DoubleArgumentList:: +alFormatToMemory(void* inStart, Uint32 /*inOffset*/, x86ArgListInstruction& inInsn, MdFormatter& inFormatter) +{ + VirtualRegister* directReg; + + // Four cases: + // + // Use1 == Def Use2 is memory + // a b a [b] + // +----------+ <- +----------+ <- + // | add + --> add a, b | add + --> add a, [b] + // +----------+ +----------+ + // a a + // + // + // Use1 != Def Use1 is memory + // a [a] b + // +----------+ +----------+ -> + // | movsx + --> movsx b, a | add + --> add b, [a] + // +----------+ +----------+ + // b [a] + // + // + // + // 1. if there is a memory, format it first + // 2. if both register and only one use, format the define first + + // Format Mem/Reg Operand // mem/reg == first use if... + if( (argType1 != atRegDirect) || // ...arg1 is memory, or + (argType1 == atRegDirect && argType2 == atRegDirect && !alHasTwoArgs(inInsn))) // ...both reg, and there is only one use + { + x86SingleArgumentList::alFormatToMemory(inStart, inInsn, argType1, 0, inFormatter); + directReg = alGetArg2VirtualRegister(inInsn); + assert(directReg->getClass() == IntegerRegister); // reg must be Integer register + } + else + { + //otherwise mem/reg == second use + x86SingleArgumentList::alFormatToMemory(inStart, inInsn, argType2, 1, inFormatter); + directReg = alGetArg1VirtualRegister(inInsn); + assert(directReg->getClass() == IntegerRegister); // reg must be Integer register + } + + // Format Reg Operand + *(Uint8*)inStart = *(Uint8*)inStart | (getRegisterNumber(directReg) << 3); +} + +#ifdef DEBUG_LOG + +void x86DoubleArgumentList:: +alPrintPretty(LogModuleObject &f, x86ArgListInstruction& inInsn) +{ + InstructionUse* useBegin = inInsn.getInstructionUseBegin(); + InstructionUse* useEnd = inInsn.getInstructionUseEnd(); + Uint8 totalUses = atInfo[argType1].atiNumUses + atInfo[argType2].atiNumUses; + + // Check to see if there are enough uses to encode all of the registers. If this is the + // case then the operands should be printed in there normal order. Otherwise the second operand is defined + // only in the defines (ie a mov instruction) and should be printed first. + if(useEnd >= useBegin + totalUses) + { + x86SingleArgumentList::alPrintPretty(f, inInsn, argType1, 0); + UT_OBJECTLOG(f, PR_LOG_ALWAYS, (", ")); + x86SingleArgumentList::alPrintPretty(f, inInsn, argType2, atInfo[argType1].atiNumUses); + } else { + x86SingleArgumentList::alPrintPretty(f, inInsn, argType2, atInfo[argType1].atiNumUses); + UT_OBJECTLOG(f, PR_LOG_ALWAYS, (", ")); + x86SingleArgumentList::alPrintPretty(f, inInsn, argType1, 0); + } +} + +#endif // DEBUG_LOG + +VirtualRegister* x86DoubleArgumentList:: +alGetArg1VirtualRegister(x86ArgListInstruction& inInsn) +{ + InstructionUse* use = inInsn.getInstructionUseBegin(); + return &use->getVirtualRegister(); +} + +// Find the virtual register corresponding to the second argument +VirtualRegister* x86DoubleArgumentList:: +alGetArg2VirtualRegister(x86ArgListInstruction& inInsn) +{ + VirtualRegister* vreg; + + InstructionUse* useBegin = inInsn.getInstructionUseBegin(); + InstructionUse* useEnd = inInsn.getInstructionUseEnd(); + InstructionUse* supplementaryUseBegin = useBegin + atInfo[argType1].atiNumUses; // skip over first arg's registers + + if( (supplementaryUseBegin < useEnd) && supplementaryUseBegin->isVirtualRegister() ) + { + vreg = &(supplementaryUseBegin->getVirtualRegister()); // supplementary uses + } + else + { + InstructionDefine* defineBegin = inInsn.getInstructionDefineBegin(); + vreg = &(defineBegin->getVirtualRegister()); // first define + } + + return vreg; +} + +//-------------------------------------------------------------------------------- +// x86ControlNodeOffsetArgumentList +#ifdef DEBUG_LOG + +void x86ControlNodeOffsetArgumentList:: +alPrintPretty(LogModuleObject &f, x86ArgListInstruction& /*inInsn*/) +{ + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("0x%x [N%d]", cnoTarget.getNativeOffset(), cnoTarget.dfsNum, cnoTarget.dfsNum)); +} + +#endif // DEBUG_LOG + +void x86ControlNodeOffsetArgumentList:: +alFormatToMemory(void* inStart, Uint32 inOffset, x86ArgListInstruction& inInsn, MdFormatter& /*inFormatter*/) +{ + // To compute the relative branch we subtract our current address from out target address. Then we subtract the size + // of our instruction because our current IP is actually there. This is the sum of the size of the opcode and the size of the + // argumentlist. NOTE: If we use 1 byte jumps in the future then this needs to be fixed from a constant 4. + writeLittleWordUnaligned((void*)inStart, cnoTarget.getNativeOffset() - inOffset - inInsn.opcodeSize() - 4); +} + +//-------------------------------------------------------------------------------- +// x86CondensableImmediateArgumentList +// must take 4 byte immediate +void x86CondensableImmediateArgumentList:: +alFormatToMemory(void* inStart, Uint32 /*inOffset*/, x86ArgListInstruction& inInsn, MdFormatter& inFormatter) +{ + Uint8* immLocation; + // find location of immediate. + if(argType1 != atRegDirect) + { + // argument list takes up some space + immLocation = (Uint8*)inStart + x86SingleArgumentList::alSize(argType1, inInsn, 0, inFormatter); + x86SingleArgumentList::alFormatToMemory(inStart, inInsn, argType1, 0, inFormatter); + } else + // argument list has been captured in the opcode + immLocation = (Uint8*)inStart; + + // write out the immediate + writeLittleWordUnaligned((void*)immLocation, imm4Bytes); +} + +Uint8 x86CondensableImmediateArgumentList:: +alSize(x86ArgListInstruction& inInsn, MdFormatter& inFormatter) +{ + return x86SingleArgumentList::alSize(inInsn, inFormatter) + 4; +} + +//-------------------------------------------------------------------------------- +// x86ImmediateArgumentList +void x86ImmediateArgumentList:: +alFormatToMemory(void* inStart, Uint32 /*inOffset*/, x86ArgListInstruction& inInsn, MdFormatter& inFormatter) +{ + // Find the location of the immediate. + Uint8* immLocation = (Uint8*)inStart; + if (argType1 != atImmediateOnly) + { + immLocation += x86SingleArgumentList::alSize(argType1, inInsn, 0, inFormatter); + x86SingleArgumentList::alFormatToMemory(inStart, inInsn, argType1, 0, inFormatter); + } + + // write out the immediate + if(iSize == is1ByteImmediate && inInsn.opcodeCanAccept1ByteImmediate()) + *immLocation = imm1Byte; + else + { + assert(inInsn.opcodeCanAccept4ByteImmediate()); + writeLittleWordUnaligned((void*)immLocation, imm4Bytes); + } +} + +Uint8 x86ImmediateArgumentList:: +alSize(x86ArgListInstruction& inInsn, MdFormatter& inFormatter) +{ + Uint8 size = 0; + + // Handle special case of immediate push, which has only one argument + if (argType1 != atImmediateOnly) + size += x86SingleArgumentList::alSize(inInsn, inFormatter); + + if (iSize == is1ByteImmediate && inInsn.opcodeCanAccept1ByteImmediate()) + size += 1; + else + { + assert(inInsn.opcodeCanAccept4ByteImmediate()); + size += 4; + } + return size; +} + +//-------------------------------------------------------------------------------- +// x86SpecialRegMemArgumentList +void x86SpecialRegMemArgumentList:: +alFormatToMemory(void* inStart, Uint32 inOffset, x86ArgListInstruction& inInsn, MdFormatter& inFormatter) +{ + if(argType1 == atRegDirect) + { + // We should output ourselves as though we were a double argument list + // with both arguments being the same register. + InstructionUse* useBegin = inInsn.getInstructionUseBegin(); + InstructionUse* useEnd = inInsn.getInstructionUseEnd(); + Uint8 reg; + + if( (useBegin < useEnd) && (useBegin->isVirtualRegister()) ) + reg = useToRegisterNumber(*useBegin); + else { + InstructionDefine* defineBegin = inInsn.getInstructionDefineBegin(); + InstructionDefine* defineEnd = inInsn.getInstructionDefineEnd(); + assert( (defineBegin < defineEnd) && (defineBegin->isVirtualRegister()) ); + reg = defineToRegisterNumber(*defineBegin); + } + *(Uint8*)inStart = ( 0xc0 | (reg) | (reg << 3) ); + } + else + { + // Otherwise we format ourselves as though we were an immediate argument list + x86ImmediateArgumentList::alFormatToMemory(inStart, inOffset, inInsn, inFormatter); + } +} + +#ifdef DEBUG_LOG + +void x86SpecialRegMemArgumentList:: +alPrintPretty(LogModuleObject &f, x86ArgListInstruction& inInsn) +{ + if(argType1 == atRegDirect) + { + // We should print ourselves as though we were a double argument list + // with both arguments being the same register. + InstructionUse* useBegin = inInsn.getInstructionUseBegin(); + InstructionUse* useEnd = inInsn.getInstructionUseEnd(); + Uint8 reg; + if( (useBegin < useEnd) && (useBegin->isVirtualRegister()) ) + reg = useToRegisterNumber(*useBegin); + else { + InstructionDefine* defineBegin = inInsn.getInstructionDefineBegin(); + InstructionDefine* defineEnd = inInsn.getInstructionDefineEnd(); + assert( (defineBegin < defineEnd) && (defineBegin->isVirtualRegister()) ); + reg = defineToRegisterNumber(*defineBegin); + } + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("%s, %s", x86GPRText[reg], x86GPRText[reg] )); + } else + // Otherwise we print ourselves as though we were an immediate argument list + x86ImmediateArgumentList::alPrintPretty(f, inInsn); +} + +#endif // DEBUG_LOG diff --git a/ef/Compiler/CodeGenerator/md/x86/x86ArgumentList.h b/ef/Compiler/CodeGenerator/md/x86/x86ArgumentList.h new file mode 100644 index 000000000000..3f4d15e89748 --- /dev/null +++ b/ef/Compiler/CodeGenerator/md/x86/x86ArgumentList.h @@ -0,0 +1,519 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +// +// File: x86ArgumentList.h +// +// Authors: Peter DeSantis +// Simon Holmes a Court +// + +#ifndef _X86ARGUMENTLIST +#define _X86ARGUMENTLIST + +/* +*********************************************************************************************************************************** +x86 ArgumentLists +Anywhere from 0 to 10 bytes of information following the x86 Opcode. +Includes the ModR/M byte, the SIB byte, the Displacement field and the immediate field. +*********************************************************************************************************************************** +*/ + +#include "CatchAssert.h" +#include + + +#include "prtypes.h" +#include "ControlNodes.h" +#include "x86Opcode.h" +#include "MemoryAccess.h" + +class x86ArgListInstruction; + +enum x86ImmediateSize +{ + isNoImmediate, + is1ByteImmediate, + is4ByteImmediate +}; + + +enum x86ArgumentType +{ + atRegDirect, + atRegAllocStackSlot, // Stack slot designated by the register allocator + atRegAllocStackSlotHi32, // Upper 32-bits of 64-bit stack slot designated by the register allocator + + atRegisterIndirect, // + atRegisterRelative1ByteDisplacement, + atRegisterRelative4ByteDisplacement, + + atBaseIndexed, // + atBaseRelativeIndexed1ByteDisplacement, + atBaseRelativeIndexed4ByteDisplacement, + + atScaledIndexedBy2, // + atScaledIndexed1ByteDisplacementBy2, + atScaledIndexed4ByteDisplacementBy2, + + atScaledIndexedBy4, // + atScaledIndexed1ByteDisplacementBy4, + atScaledIndexed4ByteDisplacementBy4, + + atScaledIndexedBy8, // + atScaledIndexed1ByteDisplacementBy8, + atScaledIndexed4ByteDisplacementBy8, + + atStackOffset, + atStackOffset1ByteDisplacement, + atStackOffset4ByteDisplacement, + + atAbsoluteAddress, + atImmediateOnly +}; + +// Maps register alloc color to x86 machine register +extern x86GPR colorTox86GPR[]; + +// Maps x86 machine register to register alloc color +extern Uint8 x86GPRToColor[]; + +//-------------------------------------------------------------------------------- +// x86ArgumentList +// Abstract base class +class x86ArgumentList +{ +protected: + x86ArgumentList() { } + +public: + + virtual void alFormatToMemory(void* inStart, Uint32 inOffset, x86ArgListInstruction& inInsn, MdFormatter& /*inFormatter*/) = 0; + virtual Uint8 alSize(x86ArgListInstruction& /*inInsn*/, MdFormatter& /*inFormatter*/) = 0; + + virtual Uint8 alGetRegisterOperand( x86ArgListInstruction& /*inInsn*/ ) { return NOT_A_REG; } + + virtual bool alSwitchArgumentTypeToSpill(Uint8 /*inWhichUse*/, x86ArgListInstruction& /* inInsn */ ) { return false;} + virtual x86ImmediateSize alSizeOfImmediate() { return isNoImmediate; } + virtual bool alIsRegisterDirect() { return true; } + +#ifdef DEBUG + virtual void alCheckIntegrity(x86ArgListInstruction& /*inInsn*/) { /* do nothing for now, except for double argument list */ } + virtual void alPrintArgs(x86ArgListInstruction& /*inInsn*/) { /* do nothing for now, except for double argument list */ } +#endif // DEBUG + +#ifdef DEBUG_LOG + virtual void alPrintPretty(LogModuleObject &f, x86ArgListInstruction& inInsn) = 0; +#endif // DEBUG_LOG +}; + +//-------------------------------------------------------------------------------- +// x86EmptyArgumentList +// Contains no information +class x86EmptyArgumentList : + public x86ArgumentList +{ +public: + x86EmptyArgumentList() {} + virtual void alFormatToMemory(void* /*inStart*/, Uint32 /*inOffset*/, x86ArgListInstruction& /*inInsn*/, MdFormatter& /*inFormatter*/) {} + virtual Uint8 alSize(x86ArgListInstruction& /*inInsn*/, MdFormatter& /*inFormatter*/) { return 0; } + +#ifdef DEBUG_LOG +public: + virtual void alPrintPretty(LogModuleObject /*f*/, x86ArgListInstruction& /*inInsn*/) {} +#endif // DEBUG_LOG +}; + +//-------------------------------------------------------------------------------- +// x86ControlNodeOffsetArgumentList +class x86ControlNodeOffsetArgumentList : + public x86ArgumentList +{ +public: + x86ControlNodeOffsetArgumentList( ControlNode& inTarget ) : cnoTarget(inTarget) { } + virtual void alFormatToMemory(void* inStart, Uint32 inOffset, x86ArgListInstruction& inInsn, MdFormatter& /*inFormatter*/); + // FIX In the future we would like short jumps to be encode with 1 byte immediates. + virtual Uint8 alSize(x86ArgListInstruction& /*inInsn*/, MdFormatter& /*inFormatter*/) { return 4; } + virtual x86ImmediateSize alSizeOfImmediate() { return is4ByteImmediate; } + +protected: + ControlNode& cnoTarget; + +#ifdef DEBUG_LOG +public: + virtual void alPrintPretty(LogModuleObject &f, x86ArgListInstruction& /*inInsn*/); +#endif +}; + +/*================================================================================ + The following argument lists all depend on the InstructionUses and InstructionDefines to contain the Virtual Registers + which have been assigned machine registers prior to printing or formating. Additionally, all make assumptions about the + properties of the uses and defines which hold the VRs. + + Let the array of uses be enumerated u0, u1, u2,...un, and the array of defines d0, d1, d2,...dm. + + These assumptions require the following: + + For some ux, all ui i <= x are uses which contain VRs (represent machine registers) and all uj j > x are uses which do + not contain VRs (represent machine registers). + + Similarly, For some dx, all ui i <= x are defines which contain VRs (represent machine registers) and all dj j > x are defines which do + not contain VRs (represent machine registers). + + If some register/memory operand is overwritten then it encoded in the first use(s) and the first define(s). + + Many of the functions use a wrap around approach. They take some offset into the uses array and expect to find the virtual registers + necessary to format themselves at that spot. If instead they find that they are beyond the end of the array of uses or that the current + use is not a VR, then they know that they can find they VRs at the beginning of the defines. +*/ + +//-------------------------------------------------------------------------------- +// x86SingleArgumentList +// One register or memory operand +class x86SingleArgumentList : + public x86ArgumentList +{ +public: + x86SingleArgumentList(x86ArgumentType inType); + x86SingleArgumentList(x86ArgumentType inType, Uint32 inDisplacement); + + virtual void alFormatToMemory(void* inStart, Uint32 inOffset, x86ArgListInstruction& inInsn, MdFormatter& /*inFormatter*/); + virtual Uint8 alSize(x86ArgListInstruction& inInsn, MdFormatter& /*inFormatter*/); + virtual bool alSwitchArgumentTypeToSpill(Uint8 inWhichUse, x86ArgListInstruction& /* inInsn */); + + virtual Uint8 alGetRegisterOperand( x86ArgListInstruction& inInsn ); + virtual bool alIsRegisterDirect() { return argType1 == atRegDirect; } + +protected: + x86SingleArgumentList() { } + + // Utility functions used by all super classes of x86SingleArgumentList */ + void alFormatToMemory(void* inStart, x86ArgListInstruction& inInsn, x86ArgumentType inType, Uint8 inInstructionUseStartIndex, MdFormatter& /*inFormatter*/); + Uint8 alSize(x86ArgumentType inType, x86ArgListInstruction& inInsn, Uint8 inInstructionUseStartIndex, MdFormatter& /*inFormatter*/); + + x86ArgumentType argType1; + + union + { + Uint8 arg1ByteDisplacement; + Uint32 arg4ByteDisplacement; + }; + +private: + void alFormatStackSlotToMemory(void* inStart, x86ArgListInstruction& inInsn, Uint8 inInstructionUseStartIndex, MdFormatter& /*inFormatter*/, int offset); + void alFormatNonRegToMemory(void* inStart, x86ArgListInstruction& inInsn, x86ArgumentType inType, MdFormatter& /*inFormatter*/); + void alFormatRegToMemory(void* inStart, x86ArgListInstruction& inInsn, x86ArgumentType inType, Uint8 inInstructionUseStartIndex, MdFormatter& /*inFormatter*/); + +#ifdef DEBUG_LOG +public: + virtual void alPrintPretty(LogModuleObject &f, x86ArgListInstruction& inInsn) { alPrintPretty(f, inInsn, argType1, 0); } + void alPrintPretty(LogModuleObject &f, x86ArgListInstruction& inInsn, x86ArgumentType inType, Uint8 inInstructionUseStartIndex); +#endif // DEBUG_LOG +}; + +//-------------------------------------------------------------------------------- +// x86DoubleArgumentList +// A memory and a register operand or two register operands +class x86DoubleArgumentList : + public x86SingleArgumentList +{ +protected: + x86ArgumentType argType2; + +public: + x86DoubleArgumentList(x86ArgumentType inType1, x86ArgumentType inType2); + x86DoubleArgumentList(x86ArgumentType inType1, x86ArgumentType inType2, Uint32 inDisplacement); + + virtual void alFormatToMemory(void* inStart, Uint32 inOffset, x86ArgListInstruction& inInsn, MdFormatter& /*inFormatter*/); + virtual Uint8 alSize(x86ArgListInstruction& inInsn, MdFormatter& /*inFormatter*/); + + virtual Uint8 alGetRegisterOperand( x86ArgListInstruction& /*inInsn*/ ) { return NOT_A_REG; } + + virtual bool alSwitchArgumentTypeToSpill(Uint8 inWhichUse, x86ArgListInstruction& /* inInsn */ ); + + VirtualRegister* alGetArg1VirtualRegister(x86ArgListInstruction& inInsn); + VirtualRegister* alGetArg2VirtualRegister(x86ArgListInstruction& inInsn); + + virtual bool alIsRegisterDirect() { return argType1 == atRegDirect && argType2 == atRegDirect; } + bool akIsArg1Direct() { return argType1 == atRegDirect; } + bool akIsArg2Direct() { return argType2 == atRegDirect; } + bool alHasTwoArgs(x86ArgListInstruction& inInsn); + +#ifdef DEBUG + virtual void alCheckIntegrity(x86ArgListInstruction& inInsn); + virtual void alPrintArgs(x86ArgListInstruction& inInsn); +#endif // DEBUG + +#ifdef DEBUG_LOG +public: + virtual void alPrintPretty(LogModuleObject &f, x86ArgListInstruction& inInsn); +#endif // DEBUG_LOG +}; + +inline Uint8 x86DoubleArgumentList:: +alSize(x86ArgListInstruction& inInsn, MdFormatter& inFormatter) +{ + // The formatting of the mem argument determines the size of the argumentlist because one register direct can + // just be ORed. + int size; + if(argType1 != atRegDirect) + size = x86SingleArgumentList::alSize(argType1, inInsn, 0, inFormatter); + else + size = x86SingleArgumentList::alSize(argType2, inInsn, 1, inFormatter); + return size; +} + +//-------------------------------------------------------------------------------- +// x86ImmediateArgumentList +// One reg or mem operand and an immediate operand. +class x86ImmediateArgumentList : + public x86SingleArgumentList +{ +public: + x86ImmediateArgumentList(x86ArgumentType inType1, Uint32 inImm); + x86ImmediateArgumentList(x86ArgumentType inType1, Uint32 inDisplacement, Uint32 inImm); + + virtual void alFormatToMemory(void* inStart, Uint32 inOffset, x86ArgListInstruction& inInsn, MdFormatter& /*inFormatter*/); + virtual Uint8 alSize(x86ArgListInstruction& inInsn, MdFormatter& /*inFormatter*/); + + virtual x86ImmediateSize alSizeOfImmediate() { return iSize; } + +protected: + + union + { + Uint8 imm1Byte; + Uint32 imm4Bytes; + }; + + x86ImmediateSize iSize; + +#ifdef DEBUG_LOG +public: + virtual void alPrintPretty(LogModuleObject &f, x86ArgListInstruction& inInsn); +#endif // DEBUG_LOG +}; + +inline x86ImmediateArgumentList:: +x86ImmediateArgumentList(x86ArgumentType inType1, Uint32 inImm) +: x86SingleArgumentList(inType1) +{ + imm4Bytes = inImm; + if(valueIsOneByteSigned(inImm)) + iSize = is1ByteImmediate; + else + iSize = is4ByteImmediate; +} + +inline x86ImmediateArgumentList:: +x86ImmediateArgumentList(x86ArgumentType inType1, Uint32 inDisplacement, Uint32 inImm) +: x86SingleArgumentList(inType1, inDisplacement) +{ + imm4Bytes = inImm; + if(valueIsOneByteSigned(inImm)) + iSize = is1ByteImmediate; + else + iSize = is4ByteImmediate; +} + +#ifdef DEBUG_LOG + +inline void x86ImmediateArgumentList:: +alPrintPretty(LogModuleObject &f, x86ArgListInstruction& inInsn) +{ + x86SingleArgumentList::alPrintPretty(f, inInsn, argType1, 0 ); + if (argType1 != atImmediateOnly) + UT_OBJECTLOG(f, PR_LOG_ALWAYS, (", ")); + if(iSize == is1ByteImmediate) + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("%0x", imm1Byte)); + else + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("%0x", imm4Bytes)); +} + +#endif // DEBUG_LOG + +//-------------------------------------------------------------------------------- +// x86CondensableImmediateArgumentList +class x86CondensableImmediateArgumentList : + public x86SingleArgumentList +{ +public: + x86CondensableImmediateArgumentList(x86ArgumentType inType1, Uint32 inImm); + x86CondensableImmediateArgumentList(x86ArgumentType inType1, Uint32 inDisplacement, Uint32 inImm); + + virtual void alFormatToMemory(void* inStart, Uint32 inOffset, x86ArgListInstruction& inInsn, MdFormatter& /*inFormatter*/); + virtual Uint8 alSize(x86ArgListInstruction& inInsn, MdFormatter& /*inFormatter*/); + + virtual x86ImmediateSize alSizeOfImmediate() { return iSize; } + +protected: + Uint32 imm4Bytes; + x86ImmediateSize iSize; + +#ifdef DEBUG_LOG +public: + virtual void alPrintPretty(LogModuleObject &f, x86ArgListInstruction& inInsn); +#endif // DEBUG_LOG +}; + +inline x86CondensableImmediateArgumentList:: +x86CondensableImmediateArgumentList(x86ArgumentType inType1, Uint32 inImm) +: x86SingleArgumentList(inType1), imm4Bytes(inImm) +{ +} + +inline x86CondensableImmediateArgumentList:: +x86CondensableImmediateArgumentList(x86ArgumentType inType1, Uint32 inDisplacement, Uint32 inImm) +: x86SingleArgumentList(inType1, inDisplacement), imm4Bytes(inImm) +{ +} + +#ifdef DEBUG_LOG + +inline void x86CondensableImmediateArgumentList:: +alPrintPretty(LogModuleObject &f, x86ArgListInstruction& inInsn) +{ + x86SingleArgumentList::alPrintPretty(f, inInsn, argType1, 0 ); + UT_OBJECTLOG(f, PR_LOG_ALWAYS, (", %0x", imm4Bytes)); +} + +#endif // DEBUG_LOG + +//-------------------------------------------------------------------------------- +// x86DoubleImmediateArgumentList +// [ immediate argument, mem, and reg] or [immediate argument, two reg operands] +class x86DoubleImmediateArgumentList : + public x86DoubleArgumentList +{ +public: + x86DoubleImmediateArgumentList(x86ArgumentType inType1, x86ArgumentType inType2, Uint32 inImm); + x86DoubleImmediateArgumentList(x86ArgumentType inType1, x86ArgumentType inType2, Uint32 inDisplacement, Uint32 inImm); + virtual void alFormatToMemory(void* inStart, Uint32 inOffset, x86ArgListInstruction& inInsn, MdFormatter& /*inFormatter*/); + virtual Uint8 alSize(x86ArgListInstruction& /*inInsn*/, MdFormatter& /*inFormatter*/); + + virtual x86ImmediateSize alSizeOfImmediate() { return iSize; } + +protected: + + union + { + Uint8 imm1Byte; + Uint32 imm4Bytes; + }; + + x86ImmediateSize iSize; + +#ifdef DEBUG_LOG +public: + virtual void alPrintPretty(LogModuleObject &f, x86ArgListInstruction& inInsn); +#endif // DEBUG_LOG +}; + +inline x86DoubleImmediateArgumentList:: +x86DoubleImmediateArgumentList(x86ArgumentType inType1, x86ArgumentType inType2, Uint32 inImm) +: x86DoubleArgumentList(inType1, inType2) +{ + imm4Bytes = inImm; +// if(valueIsOneByteSigned(inImm)) +// iSize = is1ByteImmediate; +// else + iSize = is4ByteImmediate; +} + +inline x86DoubleImmediateArgumentList:: +x86DoubleImmediateArgumentList(x86ArgumentType inType1, x86ArgumentType inType2, Uint32 inDisplacement, Uint32 inImm) + : x86DoubleArgumentList(inType1, inType2, inDisplacement) +{ + imm4Bytes = inImm; +// if(valueIsOneByteSigned(inImm)) // FIX +// iSize = is1ByteImmediate; +// else + iSize = is4ByteImmediate; +} + +inline Uint8 x86DoubleImmediateArgumentList:: +alSize(x86ArgListInstruction& inInsn, MdFormatter& inFormatter) +{ + Uint32 size = x86DoubleArgumentList::alSize(inInsn, inFormatter); + + if(iSize == is1ByteImmediate) + size += 1; + else + size += 4; + + return size; + } + +inline void x86DoubleImmediateArgumentList:: +alFormatToMemory(void* inStart, Uint32 inOffset, x86ArgListInstruction& inInsn, MdFormatter& inFormatter) +{ + x86DoubleArgumentList::alFormatToMemory(inStart, inOffset, inInsn, inFormatter); + + Uint8* immLocation = (Uint8*)inStart + x86DoubleArgumentList::alSize(inInsn, inFormatter); + if(iSize == is1ByteImmediate) + *immLocation = imm1Byte; + else + writeLittleWordUnaligned((void*)immLocation, imm4Bytes); +} + +#ifdef DEBUG_LOG + +inline void x86DoubleImmediateArgumentList:: +alPrintPretty(LogModuleObject &f, x86ArgListInstruction& inInsn) +{ + x86DoubleArgumentList::alPrintPretty(f, inInsn); + if(iSize == is1ByteImmediate) + UT_OBJECTLOG(f, PR_LOG_ALWAYS, (", %0x", imm1Byte)); + else + UT_OBJECTLOG(f, PR_LOG_ALWAYS, (", %0x", imm4Bytes)); +} + +#endif // DEBUG_LOG + +//-------------------------------------------------------------------------------- +// x86SpecialRegMemArgumentList +// Only used with x86SpecialRegMemOpcode +// This argument list holds an immediate value and a single argument. In its initial form it emits a double argument list +// of the one register operand. If it is switched to spill type it prints the memory operand and the immediate value. + +class x86SpecialRegMemArgumentList : + public x86ImmediateArgumentList +{ +public: + x86SpecialRegMemArgumentList(Uint32 inImm) : x86ImmediateArgumentList(atRegDirect, inImm) { } + + virtual void alFormatToMemory(void* inStart, Uint32 inOffset, x86ArgListInstruction& inInsn, MdFormatter& /*inFormatter*/); + virtual Uint8 alSize(x86ArgListInstruction& inInsn, MdFormatter& /*inFormatter*/); + +#ifdef DEBUG_LOG +public: + virtual void alPrintPretty(LogModuleObject &f, x86ArgListInstruction& inInsn); +#endif // DEBUG_LOG +}; + +inline Uint8 x86SpecialRegMemArgumentList:: +alSize(x86ArgListInstruction& inInsn, MdFormatter& inFormatter) +{ + Uint8 size; + if(argType1 == atRegDirect) + size = 1; // Only need the ModR/M byte + else + size = x86ImmediateArgumentList::alSize(inInsn, inFormatter); + return size; +} + +#endif //X86_ARGUMENTLIST diff --git a/ef/Compiler/CodeGenerator/md/x86/x86Float.cpp b/ef/Compiler/CodeGenerator/md/x86/x86Float.cpp new file mode 100644 index 000000000000..8e81ffa866ad --- /dev/null +++ b/ef/Compiler/CodeGenerator/md/x86/x86Float.cpp @@ -0,0 +1,732 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +// +// x86Float.cpp - Floating-point code-generation for x86 processors +// + +#include "x86Float.h" +#include "x86Win32Emitter.h" +#include "FloatUtils.h" + +// Note: In comments below, TOS = Top of FPU stack + +//==================================================================================================== +// Register classes for float and double operands +// FIXME - For now, all float and double virtual registers are allocated on the stack +const VRClass vrcFloat = vrcStackSlot; +const VRClass vrcDouble = vrcStackSlot; // FIXME - Stack slots are temporarily 8-bytes, so they can hold a double + + +//==================================================================================================== +// Floating-point instruction classes + +/*-------------------------------------------------------------------------------- +Floating-Point instructions where one operand is a memory location and the other is +the top of stack, e.g. binary operations like add, and load/store/conversion instructions. + +oiBaseOpcode + contains the opcode for the instruction + +oiOpcodeInformation + 6 set if opcode extension is used + [5 4 3] contain Regfield opcode extension (if bit 6 is set) + others set to 0 +*/ + +// Utility macros for setting up opcode table +#define NO_EXTENSION 8 // Register extensions range from 0 to 7, so this special code indicates that + // there is no R/M byte + +#define FLOAT_INFO(first_opcode, reg_extension) \ + first_opcode, ((reg_extension != NO_EXTENSION) * ((1<< 6) | ((reg_extension) << 3))) + +x86OpcodeInfo InsnFloatMemory::opcodeTable[] = +{ + {FLOAT_INFO(0xD9, 3), "fstp32"}, // TOS => 32-bit float memory. Pop TOS. + {FLOAT_INFO(0xDD, 3), "fstp64"}, // TOS => 64-bit double memory. Pop TOS. + {FLOAT_INFO(0xD9, 2), "fst32"}, // TOS => 32-bit float memory. (Don't pop FPU stack.) + {FLOAT_INFO(0xDD, 2), "fst64"}, // TOS => 64-bit double memory. (Don't pop FPU stack.) + {FLOAT_INFO(0xDB, 3), "fistp32"}, // Round(TOS) => 32-bit int memory. Pop TOS. + {FLOAT_INFO(0xDF, 7), "fistp64"}, // Round(TOS) => 64-bit long memory. Pop TOS. + {FLOAT_INFO(0xD9, 0), "fld32"}, // 32-bit float memory => Push on FPU stack + {FLOAT_INFO(0xDD, 0), "fld64"}, // 64-bit float memory => Push on FPU stack + {FLOAT_INFO(0xDB, 0), "fild32"}, // 32-bit int memory => convert to FP and push on FPU stack + {FLOAT_INFO(0xDF, 5), "fild64"}, // 64-bit long memory => convert to FP and push on FPU stack + {FLOAT_INFO(0xD8, 0), "fadd32"}, // Add TOS and 32-bit float memory => replace TOS + {FLOAT_INFO(0xDC, 0), "fadd64"}, // Add TOS and 64-bit double memory => replace TOS + {FLOAT_INFO(0xD8, 1), "fmul32"}, // Multiply TOS and 32-bit float memory => replace TOS + {FLOAT_INFO(0xDC, 1), "fmul64"}, // Multiply TOS and 64-bit double memory => replace TOS + {FLOAT_INFO(0xD8, 4), "fsub32"}, // Subtract TOS from 32-bit float memory => replace TOS + {FLOAT_INFO(0xDC, 4), "fsub64"}, // Subtract TOS from 64-bit double memory => replace TOS + {FLOAT_INFO(0xD8, 5), "fsubr32"}, // Subtract 32-bit float memory from TOS => replace TOS + {FLOAT_INFO(0xDC, 5), "fsubr64"}, // Subtract 64-bit double memory from TOS => replace TOS + {FLOAT_INFO(0xD8, 6), "fdiv32"}, // Divide TOS by 32-bit float memory => replace TOS + {FLOAT_INFO(0xDC, 6), "fdiv64"}, // Divide TOS by 64-bit double memory => replace TOS + {FLOAT_INFO(0xD8, 3), "fcomp32"}, // Compare TOS to 32-bit float memory, setting FPU flags, pop TOS + {FLOAT_INFO(0xDC, 3), "fcomp64"} // Compare TOS to 64-bit double memory, setting FPU flags, pop TOS +}; + +void InsnFloatMemory:: +formatToMemory(void* inStart, Uint32 inOffset, MdFormatter& inFormatter) +{ + assert(opcodeInfo != NULL && iArgumentList != NULL); + Uint8 *opLocation = (Uint8*)inStart; + + // Format the opcode to memory + *opLocation++ = opcodeInfo->oiBaseOpcode; + + // Find the location of the argument list and format it to memory + iArgumentList->alFormatToMemory((void*)opLocation, inOffset, *this, inFormatter); + + // If the opcode has an opcode extension then OR it into the proper place. ( the reg field of the modr/m byte.) + Uint8 regFieldExtension = kRegfield_Mask & opcodeInfo->oiOpcodeInformation; + *opLocation |= regFieldExtension; +} + +/*---------------------------------------------------------------------------------------------------------- +Floating-Point instructions where source and destination are implicitly on the FPU stack + e.g. negation, comparison + +oiBaseOpcode + contains the first byte of the opcode for the instruction + +oiOpcodeInformation + contains the second byte of the opcode for the instruction +*/ + +x86OpcodeInfo InsnFloatReg::opcodeTable[] = +{ + {0xDF, 0xE9, "fucomip st, st(1)"}, // Compare top two operands on FPU stack and set EFLAGS, pop FPU stack + {0xD9, 0xE0, "fchs"}, // Negate top of stack value + {0xDF, 0xE0, "fnstsw ax"} // Copy FPU status register to AX +}; + +void InsnFloatReg:: +formatToMemory(void* inStart, Uint32 /*inOffset*/, MdFormatter& /*inFormatter*/) +{ + // Format the opcode to memory. There is no argument list. + Uint8* start = (Uint8*) inStart; + *start++ = opcodeInfo->oiBaseOpcode; + *start = opcodeInfo->oiOpcodeInformation; +} + +//==================================================================================================== +// Instruction generation utilities + +InsnDoubleOpDir& x86Win32Emitter:: +copyFromFloatToIntegerRegister(DataNode& inDataNode, InsnUseXDefineYFromPool& defInsn) +{ + VirtualRegister& vr = defineTemporary(defInsn, 0, vrcStackSlot); + InsnDoubleOpDir& copyInsn = *new(mPool) InsnDoubleOpDir(&inDataNode, mPool, raCopyI, atRegAllocStackSlot, atRegDirect, 1, 1); + useTemporaryVR(copyInsn, vr, 0); + return copyInsn; +} + +InsnDoubleOpDir& x86Win32Emitter:: +copyFromIntegerRegisterToFloat(DataNode& inDataNode, InsnUseXDefineYFromPool& defInsn) +{ + VirtualRegister& vr = defineTemporary(defInsn, 0); + InsnDoubleOpDir& copyInsn = *new(mPool) InsnDoubleOpDir(&inDataNode, mPool, raCopyI, atRegDirect, atRegAllocStackSlot, 1, 1); + useTemporaryVR(copyInsn, vr, 0); + return copyInsn; +} + +//==================================================================================================== +// Floating-point binary operations, i.e. add, subtract, multiply, divide, modulus + +void x86Win32Emitter:: +emit_BinaryFloat(Primitive& inPrimitive, + x86FloatMemoryType binary_op, x86FloatMemoryType load_op, x86FloatMemoryType store_op, + VRClass vrClass) +{ + // Fetch first operand of binary op from memory and push it on the FPU stack + InsnFloatMemory &loadInsn = *new InsnFloatMemory(&inPrimitive, mPool, load_op, 1, 1); + useProducer(inPrimitive.nthInputVariable(0), loadInsn, 0, vrClass); + InstructionDefine& define1 = defineTemporaryOrder(loadInsn, 0); + + // Fetch second operand and perform binary operation, result replaces top of FPU stack + InsnFloatMemory &binaryInsn = *new InsnFloatMemory(&inPrimitive, mPool, binary_op, 2, 1); + useProducer(inPrimitive.nthInputVariable(1), binaryInsn, 0, vrClass); + useTemporaryOrder(binaryInsn, define1, 1); + InstructionDefine& define2 = defineTemporaryOrder(binaryInsn, 0); + + // Pop result of binary operation from FPU stack and store into memory + InsnFloatMemory &storeInsn = *new InsnFloatMemory(&inPrimitive, mPool, store_op, 1, 1); + useTemporaryOrder(storeInsn, define2, 0); + defineProducer(inPrimitive, storeInsn, 0, vrClass); // result +} + +// Emit 32-bit float binary operation +void x86Win32Emitter:: +emit_BinaryFloat32(Primitive& inPrimitive, x86FloatMemoryType binary_op) +{ + emit_BinaryFloat(inPrimitive, binary_op, fld32, fstp32, vrcFloat); +} + +// Emit 64-bit float binary operation +void x86Win32Emitter:: +emit_BinaryFloat64(Primitive& inPrimitive, x86FloatMemoryType binary_op) +{ + emit_BinaryFloat(inPrimitive, binary_op, fld64, fstp64, vrcDouble); +} + +void x86Win32Emitter:: +emit_FAdd_F(Primitive& inPrimitive) { + emit_BinaryFloat32(inPrimitive, fadd32); +} + +void x86Win32Emitter:: +emit_FAdd_D(Primitive& inPrimitive) { + emit_BinaryFloat64(inPrimitive, fadd64); +} + +void x86Win32Emitter:: +emit_FMul_F(Primitive& inPrimitive) { + emit_BinaryFloat32(inPrimitive, fmul32); +} + +void x86Win32Emitter:: +emit_FMul_D(Primitive& inPrimitive) { + emit_BinaryFloat64(inPrimitive, fmul64); +} + +void x86Win32Emitter:: +emit_FSub_F(Primitive& inPrimitive) { + emit_BinaryFloat32(inPrimitive, fsub32); +} + +void x86Win32Emitter:: +emit_FSub_D(Primitive& inPrimitive) { + emit_BinaryFloat64(inPrimitive, fsub64); +} + +void x86Win32Emitter:: +emit_FDiv_F(Primitive& inPrimitive) { + emit_BinaryFloat32(inPrimitive, fdiv32); +} + +void x86Win32Emitter:: +emit_FDiv_D(Primitive& inPrimitive) { + emit_BinaryFloat64(inPrimitive, fdiv64); +} + +// FIXME - Modulus is wrapper around fmod function. Should be changed to inline code. +void x86Win32Emitter:: +emit_FRem_D(Primitive& inPrimitive) +{ + new(mPool) CallS_C(&inPrimitive, mPool, 2, true, *this, (void (*)(void))&javaFMod); +} + +// Wrapper around fmod() for 32-bit float operands instead of double operands +static Flt32 fmod32(Flt32 a, Flt32 b) +{ + return (Flt32)javaFMod(a, b); +} + +void x86Win32Emitter:: +emit_FRem_F(Primitive& inPrimitive) +{ + new(mPool) CallS_C(&inPrimitive, mPool, 2, true, *this, (void (*)(void))&fmod32); +} + + +//----------------------------------------------------------------------------------------------------------- +// Conversions to/from floating-point +// +// All conversions are two steps: +// 1) Load input operand onto FPU stack from memory, with possible conversion to floating-point type +// 2) Simultaneously convert and store from top of FPU stack into memory location, with possible +// conversion to integer type. + +void x86Win32Emitter:: +emit_FConv(Primitive& inPrimitive) +{ + InsnFloatMemory *loadInsn; + + // Fetch input operand from memory and push it on the FPU stack + switch (inPrimitive.nthInputVariable(0).getKind()) { + case vkFloat: + loadInsn = new InsnFloatMemory(&inPrimitive, mPool, fld32, 1, 1); + useProducer(inPrimitive.nthInputVariable(0), *loadInsn, 0, vrcFloat); + break; + + case vkDouble: + loadInsn = new InsnFloatMemory(&inPrimitive, mPool, fld64, 1, 1); + useProducer(inPrimitive.nthInputVariable(0), *loadInsn, 0, vrcDouble); + break; + + case vkInt: + { + InsnDoubleOpDir& copyInsn = *new(mPool) InsnDoubleOpDir(&inPrimitive, mPool, raCopyI, atRegDirect, atRegAllocStackSlot, 1, 1); + useProducer(inPrimitive.nthInputVariable(0), copyInsn, 0); + VirtualRegister& tmp = defineTemporary(copyInsn, 0, vrcStackSlot); + + loadInsn = new InsnFloatMemory(&inPrimitive, mPool, fild32, 1, 1); + useTemporaryVR(*loadInsn, tmp, 0, vrcStackSlot); + } + break; + + case vkLong: + { + InsnDoubleOpDir& copyInsnHi = *new(mPool) InsnDoubleOpDir(&inPrimitive, mPool, raCopyI, atRegDirect, atRegAllocStackSlotHi32, 1, 1); + useProducer(inPrimitive.nthInputVariable(0), copyInsnHi, 0, vrcInteger, vidHigh); + VirtualRegister& tmp64 = defineTemporary(copyInsnHi, 0, vrcStackSlot); + + InsnDoubleOpDir& copyInsnLo = *new(mPool) InsnDoubleOpDir(&inPrimitive, mPool, raCopyI, atRegDirect, atRegAllocStackSlot, 2, 1); + useProducer(inPrimitive.nthInputVariable(0), copyInsnLo, 0, vrcInteger, vidLow); + useTemporaryVR(copyInsnLo, tmp64, 1); + InstructionDefine& orderStoreLoad = defineTemporaryOrder(copyInsnLo, 0); + + loadInsn = new InsnFloatMemory(&inPrimitive, mPool, fild64, 2, 1); + useTemporaryVR(*loadInsn, tmp64, 0, vrcStackSlot); + useTemporaryOrder(*loadInsn, orderStoreLoad, 1); + } + break; + default: + // Absence of default case generates gcc warnings. + break; + } + + InstructionDefine& order = defineTemporaryOrder(*loadInsn, 0); + + // Store value from top of FPU stack into memory + ValueKind vk = inPrimitive.getKind(); + switch (vk) { + case vkFloat: + { + // Pop result from FPU stack and store into memory as 32-bit float + InsnFloatMemory& storeInsn = *new InsnFloatMemory(&inPrimitive, mPool, fstp32, 1, 1); + useTemporaryOrder(storeInsn, order, 0); + defineProducer(inPrimitive, storeInsn, 0, vrcFloat); + } + break; + + case vkDouble: + { + // Pop result from FPU stack and store into memory as 64-bit double + InsnFloatMemory& storeInsn = *new InsnFloatMemory(&inPrimitive, mPool, fstp64, 1, 1); + useTemporaryOrder(storeInsn, order, 0); + defineProducer(inPrimitive, storeInsn, 0, vrcDouble); + } + break; + + case vkInt: + case vkLong: + { + /* Rounding is controlled by the RC flag in the FPU. Round-to-nearest is the desired rounding mode for + all floating-point instructions *except* conversions from floating-point types to integer types, in + which case round-towards-zero (truncation) is mandated. Rather than temporarily changing the RC flag + for all such conversions, we achieve the equivalent result by subtracting or adding 0.5 to the value + before rounding, i.e. + + truncate(x) <==> round(x + sign(x) * 0.5) + + FIXME - we still don't handle out-of-range inputs and NaNs per the Java spec. + + */ + + // Store the 32-bit representation of the floating-point input operand into memory so that we can extract its sign. + InsnFloatMemory& storeInsn1 = *new InsnFloatMemory(&inPrimitive, mPool, fst32, 1, 1); + useTemporaryOrder(storeInsn1, order, 0); + VirtualRegister& tmpVR1 = defineTemporary(storeInsn1, 0, vrcStackSlot); + + // Extract the sign bit of the input operand + x86Instruction& andInsn = *new(mPool) x86Instruction(&inPrimitive, mPool, iaAndImm, 0x80000000, atRegAllocStackSlot, 1, 1); + useTemporaryVR(andInsn, tmpVR1, 0, vrcStackSlot); + redefineTemporary(andInsn, tmpVR1, 0, vrcStackSlot); + + // Generate 0.5 * sign(input) + const float half = 0.5; + x86Instruction& orInsn = *new(mPool) x86Instruction(&inPrimitive, mPool, iaOrImm, *(Uint32*)&half, atRegAllocStackSlot, 1, 1); + useTemporaryVR(orInsn, tmpVR1, 0, vrcStackSlot); + redefineTemporary(orInsn, tmpVR1, 0, vrcStackSlot); + + // Subtract 0.5 * sign(input) from input operand + InsnFloatMemory& subInsn = *new InsnFloatMemory(&inPrimitive, mPool, fsub32, 1, 1); + useTemporaryVR(subInsn, tmpVR1, 0, vrcStackSlot); + redefineTemporaryOrder(subInsn, order, 0); + + if (vk == vkInt) { + // Pop result from FPU stack, convert to 32-bit integer, and store into memory + + InsnFloatMemory& storeInsn = *new InsnFloatMemory(&inPrimitive, mPool, fistp32, 1, 1); + useTemporaryOrder(storeInsn, order, 0); + + // All transfers from the FPU must go through memory, so make a copy from the memory location + // to the integer register destination. + InsnDoubleOpDir& copyInsn = copyFromFloatToIntegerRegister(inPrimitive, storeInsn); + defineProducer(inPrimitive, copyInsn, 0); + + } else { // vkLong + // Pop result from FPU stack, convert to 64-bit integer, and store into memory + InsnFloatMemory& storeInsn = *new InsnFloatMemory(&inPrimitive, mPool, fistp64, 1, 1); + useTemporaryOrder(storeInsn, order, 0); + VirtualRegister& tmp64 = defineTemporary(storeInsn, 0, vrcStackSlot); // 64-bit integer stack slot + + // Copy high 32-bits from memory to integer register + InsnDoubleOpDir& copyInsnHi = *new(mPool) InsnDoubleOpDir(&inPrimitive, mPool, raCopyI, atRegAllocStackSlotHi32, atRegDirect, 1, 1); + useTemporaryVR(copyInsnHi, tmp64, 0, vrcStackSlot); + defineProducer(inPrimitive, copyInsnHi, 0, vrcInteger, vidHigh); + + // Copy low 32-bits from memory to integer register + InsnDoubleOpDir& copyInsnLo = *new(mPool) InsnDoubleOpDir(&inPrimitive, mPool, raCopyI, atRegAllocStackSlot, atRegDirect, 1, 1); + useTemporaryVR(copyInsnLo, tmp64, 0, vrcStackSlot); + defineProducer(inPrimitive, copyInsnLo, 0, vrcInteger, vidLow); + } + } + break; + + default: + // Absence of default case generates gcc warnings. + assert(0); + break; + } +} + +//==================================================================================================== +// Floating-point function-call glue + +// Obtain the 32-bit float return value of a function call +void x86Win32Emitter:: +emit_CallReturnF(InsnUseXDefineYFromPool& callInsn, DataNode& callPrimitive, DataNode& returnValProducer) +{ + InstructionDefine& define = defineTemporaryOrder(callInsn, 1); + + // Pop result from FPU stack and store into memory as 32-bit float + InsnFloatMemory& storeInsn = *new InsnFloatMemory(&callPrimitive, mPool, fstp32, 1, 1); + useTemporaryOrder(storeInsn, define, 0); + defineProducer(returnValProducer, storeInsn, 0, vrcFloat); +} + +// Obtain the 64-bit double return value of a function call +void x86Win32Emitter:: +emit_CallReturnD(InsnUseXDefineYFromPool& callInsn, DataNode& callPrimitive, DataNode& returnValProducer) +{ + InstructionDefine& define = defineTemporaryOrder(callInsn, 1); + + // Pop result from FPU stack and store into memory as 64-bit double + InsnFloatMemory& storeInsn = *new InsnFloatMemory(&callPrimitive, mPool, fstp64, 1, 1); + useTemporaryOrder(storeInsn, define, 0); + defineProducer(returnValProducer, storeInsn, 0, vrcDouble); +} + +// Retrieve a 32-bit float argument from the call stack +void x86Win32Emitter:: +emit_ArgF(PrimArg& arg, InstructionDefine& order, int curStackOffset) +{ + InsnDoubleOpDir& loadParam = *new(mPool) InsnDoubleOpDir(&arg, mPool, raLoadI, curStackOffset, atStackOffset, atRegDirect, 1, 1); + useTemporaryOrder(loadParam, order, 0); + InsnDoubleOpDir& copyInsn = copyFromIntegerRegisterToFloat(arg, loadParam); + defineProducer(arg, copyInsn, 0, vrcFloat); +} + +// Retrieve a 64-bit double argument from the call stack +void x86Win32Emitter:: +emit_ArgD(PrimArg& arg, InstructionDefine& order, int curStackOffset) +{ + InsnFloatMemory& loadInsn = *new InsnFloatMemory(&arg, mPool, fld64, atStackOffset, curStackOffset, 1, 1); + useTemporaryOrder(loadInsn, order, 0); + redefineTemporaryOrder(loadInsn, order, 0); + + InsnFloatMemory& copyInsn = *new InsnFloatMemory(&arg, mPool, fstp64, 1, 1); + useTemporaryOrder(copyInsn, order, 0); + defineProducer(arg, copyInsn, 0, vrcDouble); +} + +// Push float function return value on top of FPU stack +void x86Win32Emitter:: +emit_Result_F(Primitive& inPrimitive) +{ + InsnFloatMemory ©Insn = *new InsnFloatMemory(&inPrimitive, mPool, fld32, 1, 1); + InsnExternalUse& extInsn = *new(mPool) InsnExternalUse(&inPrimitive, mPool, 1); + + useProducer(inPrimitive.nthInputVariable(0), copyInsn, 0, vrcFloat); + InstructionDefine& define = defineTemporaryOrder(copyInsn, 0); + useTemporaryOrder(extInsn, define, 0); + + inPrimitive.setInstructionRoot(&extInsn); +} + +// Push double function return value on top of FPU stack +void x86Win32Emitter:: +emit_Result_D(Primitive& inPrimitive) +{ + InsnFloatMemory ©Insn = *new InsnFloatMemory(&inPrimitive, mPool, fld64, 1, 1); + InsnExternalUse& extInsn = *new(mPool) InsnExternalUse(&inPrimitive, mPool, 1); + + useProducer(inPrimitive.nthInputVariable(0), copyInsn, 0, vrcDouble); + InstructionDefine& define = defineTemporaryOrder(copyInsn, 0); + useTemporaryOrder(extInsn, define, 0); + + inPrimitive.setInstructionRoot(&extInsn); +} + +//==================================================================================================== +// Comparisons + +// Matches pattern: poCatL_I(poFCmp_F(Vfloat, Vfloat)) +/* Emits code that follows this pattern: + + fld ; push second_arg on FPU stack + fcomp [ebp + xx] ; Load first_arg, set integer condition flags and pop all args + fnstsw ax ; Copy FPU status reg into AX + sahf ; Copy AX into EFLAGS status reg + seta al ; al = (first_arg > second_arg) ? 1 : 0; + setb bl ; bl = ((first_arg < second_arg) || (first_arg == NAN) || (second_arg == NAN)) ? 1 : 0 + sub ebx, eax ; Result in lowest byte is -1, 0, or +1 + movsx eax, bl ; Sign-extend low byte to 32-bits + + (Some changes in operand usage will appear depending on the exact pattern of primitives being matched.) +*/ + +void x86Win32Emitter:: +emit_3wayCmpF(Primitive& inPrimitive, DataNode &first_operand, DataNode &second_operand, + bool negate_result, x86FloatMemoryType load_op, x86FloatMemoryType cmpOp, VRClass vrClass) +{ + // Push first operand on FPU stack + InsnFloatMemory& loadInsn2 = *new InsnFloatMemory(&inPrimitive, mPool, load_op, 1, 1); + useProducer(first_operand, loadInsn2, 0, vrClass); + InstructionDefine& order = defineTemporaryOrder(loadInsn2, 0); + + // Set FPU status flags + // FIXME - Should this define a condition-flag edge ? There really should be separate + // edge types for integer and FPU condition codes. + InsnFloatMemory& cmpInsn = *new InsnFloatMemory(&inPrimitive, mPool, cmpOp, 2, 1); + useProducer(second_operand, cmpInsn, 0, vrClass); + useTemporaryOrder(cmpInsn, order, 1); + redefineTemporaryOrder(cmpInsn, order, 0); + + // Copy FPU status flags to AX register + InsnFloatReg& copyFromStatusFlagsInsn = *new InsnFloatReg(&inPrimitive, mPool, fnstsw, 1, 1); + useTemporaryOrder(copyFromStatusFlagsInsn, order, 0); + VirtualRegister& FPUstatus = defineTemporary(copyFromStatusFlagsInsn, 0); + FPUstatus.preColorRegister(x86GPRToColor[EAX]); + + // sahf instruction (copy from AX into integer status flags register) + InsnNoArgs& sahfInsn = *new(mPool) InsnNoArgs(&inPrimitive, mPool, opSahf, 1, 1); + useTemporaryVR(sahfInsn, FPUstatus, 0); + sahfInsn.addDefine(0, udCond); + + // setnbe instruction + InsnSet& setInsn1 = *new(mPool) InsnSet(&inPrimitive, mPool, ccJNBE, 1, 1); + setInsn1.addUse(0, udCond); + setInsn1.getInstructionUseBegin()[0].src = &sahfInsn; // condition edge + + // setb instruction + InsnSet& setInsn2 = *new(mPool) InsnSet(&inPrimitive, mPool, ccJB, 1, 1); + setInsn2.addUse(0, udCond); + setInsn2.getInstructionUseBegin()[0].src = &sahfInsn; // condition edge + + VirtualRegister* tmpVR1, *tmpVR2; + if (negate_result) { + tmpVR2 = &defineTemporary(setInsn1, 0); // (first_operand > second_operand) -> tmpVR2 + tmpVR1 = &defineTemporary(setInsn2, 0); // ((first_operand < second_operand) || + // (first_operand == NAN) || + // (second_operand == NAN)) -> tmpVR1 + } else { + tmpVR1 = &defineTemporary(setInsn1, 0); // (first_operand > second_operand) -> tmpVR1 + tmpVR2 = &defineTemporary(setInsn2, 0); // ((first_operand < second_operand) || + // (first_operand == NAN) || + // (second_operand == NAN)) -> tmpVR2 + } + + // FIXME - We must store result of SET instruction in either AL, BL, CL, or DL, but there's no + // way to indicate this restriction to the register allocator so, for now, we hard-code the registers + tmpVR1->preColorRegister(x86GPRToColor[EAX]); + tmpVR2->preColorRegister(x86GPRToColor[EBX]); + + // sub instruction + InsnDoubleOpDir& subInsn = *new(mPool) InsnDoubleOpDir(&inPrimitive, mPool, raSub); + useTemporaryVR(subInsn, *tmpVR1, 0); + useTemporaryVR(subInsn, *tmpVR2, 1); + redefineTemporary(subInsn, *tmpVR1, 0); // tmpVR1 - tmpVR2 -> tmpVR1 + + // Upper 24 bits are garbage. Sign-extend byte to 32-bits using movs instruction + InsnDoubleOp& extInsn = *new(mPool) InsnDoubleOp(&inPrimitive, mPool, opMovSxB, atRegDirect, atRegDirect, 1, 1); + useTemporaryVR(extInsn, *tmpVR1, 0); + defineProducer(inPrimitive, extInsn, 0); // exts(tmpVR1) -> result +} + +void x86Win32Emitter:: +emit_3wayCmpF_G(Primitive& inPrimitive) +{ + Primitive& cmpPrimitive = Primitive::cast(inPrimitive.nthInputVariable(0)); + emit_3wayCmpF(inPrimitive, cmpPrimitive.nthInputVariable(0), cmpPrimitive.nthInputVariable(1), + false, fld32, fcomp32, vrcFloat); +} + +void x86Win32Emitter:: +emit_3wayCmpF_L(Primitive& inPrimitive) +{ + Primitive& cmpPrimitive = Primitive::cast(inPrimitive.nthInputVariable(0)); + emit_3wayCmpF(inPrimitive, cmpPrimitive.nthInputVariable(1), cmpPrimitive.nthInputVariable(0), + true, fld32, fcomp32, vrcFloat); +} + +void x86Win32Emitter:: +emit_3wayCmpD_G(Primitive& inPrimitive) +{ + Primitive& cmpPrimitive = Primitive::cast(inPrimitive.nthInputVariable(0)); + emit_3wayCmpF(inPrimitive, cmpPrimitive.nthInputVariable(0), cmpPrimitive.nthInputVariable(1), + false, fld64, fcomp64, vrcDouble); +} + +void x86Win32Emitter:: +emit_3wayCmpD_L(Primitive& inPrimitive) +{ + Primitive& cmpPrimitive = Primitive::cast(inPrimitive.nthInputVariable(0)); + emit_3wayCmpF(inPrimitive, cmpPrimitive.nthInputVariable(1), cmpPrimitive.nthInputVariable(0), + true, fld64, fcomp64, vrcDouble); +} + +void x86Win32Emitter:: +emit_3wayCmpCF_G(Primitive& inPrimitive) +{ + Primitive& cmpPrimitive = Primitive::cast(inPrimitive.nthInputVariable(0)); + emit_3wayCmpF(inPrimitive, cmpPrimitive.nthInputVariable(1), cmpPrimitive.nthInputVariable(0), + false, fld32, fcomp32, vrcFloat); +} + +void x86Win32Emitter:: +emit_3wayCmpCF_L(Primitive& inPrimitive) +{ + Primitive& cmpPrimitive = Primitive::cast(inPrimitive.nthInputVariable(0)); + emit_3wayCmpF(inPrimitive, cmpPrimitive.nthInputVariable(0), cmpPrimitive.nthInputVariable(1), + true, fld32, fcomp32, vrcFloat); +} + +void x86Win32Emitter:: +emit_3wayCmpCD_G(Primitive& inPrimitive) +{ + Primitive& cmpPrimitive = Primitive::cast(inPrimitive.nthInputVariable(0)); + emit_3wayCmpF(inPrimitive, cmpPrimitive.nthInputVariable(1), cmpPrimitive.nthInputVariable(0), + false, fld64, fcomp64, vrcDouble); +} + +void x86Win32Emitter:: +emit_3wayCmpCD_L(Primitive& inPrimitive) +{ + Primitive& cmpPrimitive = Primitive::cast(inPrimitive.nthInputVariable(0)); + emit_3wayCmpF(inPrimitive, cmpPrimitive.nthInputVariable(0), cmpPrimitive.nthInputVariable(1), + true, fld64, fcomp64, vrcDouble); +} + +//==================================================================================================== +// Constants + +// Generate 32-bit float constant +void x86Win32Emitter:: +emit_LoadConstant_F(Primitive& inPrimitive) +{ + Uint32 constant = (*static_cast(&inPrimitive)).value.i; + + x86Instruction* newInsn; + + if(constant == 0) + newInsn = new(mPool) x86Instruction(&inPrimitive, mPool, srmMoveImm0, 0, 0, 1); + else + newInsn = new(mPool) x86Instruction(&inPrimitive, mPool, ceMoveImm, constant, atRegDirect, 0, 1); + + defineProducer(inPrimitive, copyFromIntegerRegisterToFloat(inPrimitive, *newInsn), 0, vrcFloat); // result +} + +// Generate 64-bit double constant +// FIXME: Need to create an in-memory literal pool for storing double constants, rather than using immediate instructions +void x86Win32Emitter:: +emit_LoadConstant_D(Primitive& inPrimitive) +{ + Flt64 constant = (*static_cast(&inPrimitive)).value.d; + + // Store 64-bit double constant in literal pool + // FIXME - We should have a literal pool for each method to store in-memory constants + // and which can be released when the method is discarded. + Flt64* literalPoolEntry = (Flt64*)malloc(sizeof(Flt64)); + *literalPoolEntry = constant; + + // Fetch from memory and temporarily push 64-bit double on the FPU stack + InsnFloatMemory &loadInsn = *new InsnFloatMemory(&inPrimitive, mPool, fld64, atAbsoluteAddress, (Uint32)literalPoolEntry, 0, 1); + InstructionDefine& order = defineTemporaryOrder(loadInsn, 0); + + // Pop 64-bit double from FPU stack and store into double variable + InsnFloatMemory& storeInsn = *new InsnFloatMemory(&inPrimitive, mPool, fstp64, 1, 1); + useTemporaryOrder(storeInsn, order, 0); + defineProducer(inPrimitive, storeInsn, 0, vrcDouble); // result +} + +//==================================================================================================== +// Floating-point memory operations + +void x86Win32Emitter:: +emit_Ld_F(Primitive& inPrimitive) +{ + // Load 32-bit float into an integer register + InsnDoubleOpDir& loadInsn = *new(mPool) InsnDoubleOpDir(&inPrimitive, mPool, raLoadI, atRegisterIndirect, atRegDirect); + useProducer(inPrimitive.nthInputVariable(0), loadInsn, 1); // memory edge + useProducer(inPrimitive.nthInputVariable(1), loadInsn, 0); // address + + // Store into 32-bit float variable + InsnDoubleOpDir& storeInsn = copyFromIntegerRegisterToFloat(inPrimitive, loadInsn); + defineProducer(inPrimitive, storeInsn, 0, vrcFloat); // result +} + +void x86Win32Emitter:: +emit_Ld_D(Primitive& inPrimitive) +{ + // Fetch from memory and temporarily push 64-bit double on the FPU stack + InsnFloatMemory &loadInsn = *new InsnFloatMemory(&inPrimitive, mPool, fld64, atRegisterIndirect, 2, 1); + useProducer(inPrimitive.nthInputVariable(0), loadInsn, 1); // memory edge + useProducer(inPrimitive.nthInputVariable(1), loadInsn, 0); // address + InstructionDefine& order = defineTemporaryOrder(loadInsn, 0); + + // Pop 64-bit double from FPU stack + InsnFloatMemory& storeInsn = *new InsnFloatMemory(&inPrimitive, mPool, fstp64, 1, 1); + useTemporaryOrder(storeInsn, order, 0); + defineProducer(inPrimitive, storeInsn, 0, vrcDouble); // result +} + +void x86Win32Emitter:: +emit_St_F(Primitive& inPrimitive) +{ + // Load 32-bit float into an integer register + InsnDoubleOpDir& loadInsn = *new(mPool) InsnDoubleOpDir(&inPrimitive, mPool, raCopyI, atRegAllocStackSlot, atRegDirect, 1, 1); + useProducer(inPrimitive.nthInputVariable(2), loadInsn, 0); // data + VirtualRegister& floatVal = defineTemporary(loadInsn, 0); // intermediate output + + // Store temporary integer register into indirect register destination + InsnDoubleOpDir& storeInsn = *new(mPool) InsnDoubleOpDir(&inPrimitive, mPool, raStoreI, atRegisterIndirect, atRegDirect, 3, 1); + useProducer(inPrimitive.nthInputVariable(1), storeInsn, 0); // address + useTemporaryVR(storeInsn, floatVal, 1); // data + useProducer(inPrimitive.nthInputVariable(0), storeInsn, 2); // memory edge in + defineProducer(inPrimitive, storeInsn, 0); // memory edge out +} + +void x86Win32Emitter:: +emit_St_D(Primitive& inPrimitive) +{ + // Temporarily push 64-bit double on the FPU stack + InsnFloatMemory& loadInsn = *new InsnFloatMemory(&inPrimitive, mPool, fld64, 1, 1); + useProducer(inPrimitive.nthInputVariable(2), loadInsn, 0, vrcDouble); // data + InstructionDefine& order = defineTemporaryOrder(loadInsn, 0); + + // Pop result from FPU stack and store into memory as 64-bit double + InsnFloatMemory& storeInsn = *new InsnFloatMemory(&inPrimitive, mPool, fstp64, atRegisterIndirect, 3, 1); + useProducer(inPrimitive.nthInputVariable(1), storeInsn, 0); // address + useTemporaryOrder(storeInsn, order, 1); + useProducer(inPrimitive.nthInputVariable(0), storeInsn, 2); // memory edge in + defineProducer(inPrimitive, storeInsn, 0); // memory edge out +} diff --git a/ef/Compiler/CodeGenerator/md/x86/x86Float.h b/ef/Compiler/CodeGenerator/md/x86/x86Float.h new file mode 100644 index 000000000000..327464a3a37f --- /dev/null +++ b/ef/Compiler/CodeGenerator/md/x86/x86Float.h @@ -0,0 +1,130 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +// +// x86Float.h - Floating-point code-generation for x86 processors +// + +#ifndef X86_FLOAT_H +#define X86_FLOAT_H + +#include "x86Win32Instruction.h" + +//----------------------------------------------------------------------------------------------------------- +// Floating-point instructions in which one operand is a memory location. +// If there is a second operand, then it is implicitly the top of the FPU stack. + +class InsnFloatMemory : + public x86ArgListInstruction +{ +public: + InsnFloatMemory(DataNode* inPrimitive, Pool& inPool, x86FloatMemoryType inOpInfo, int inX, int inY): + x86ArgListInstruction (inPrimitive, inPool, inX, inY ) + { + opcodeInfo = &opcodeTable[inOpInfo]; + iArgumentList = new x86SingleArgumentList(atRegAllocStackSlot); + } + + InsnFloatMemory(DataNode* inPrimitive, Pool& inPool, x86FloatMemoryType inOpInfo, x86ArgumentType argType, + Int32 displacement, int inX, int inY): + x86ArgListInstruction (inPrimitive, inPool, inX, inY ) + { + opcodeInfo = &opcodeTable[inOpInfo]; + iArgumentList = new x86SingleArgumentList(argType, displacement); + } + + InsnFloatMemory(DataNode* inPrimitive, Pool& inPool, x86FloatMemoryType inOpInfo, x86ArgumentType argType, + int inX, int inY): + x86ArgListInstruction (inPrimitive, inPool, inX, inY ) + { + opcodeInfo = &opcodeTable[inOpInfo]; + iArgumentList = new x86SingleArgumentList(argType); + } + + virtual Uint8 opcodeSize() {return 1;} + + virtual void formatToMemory(void * /*inStart*/, Uint32 /*inCurOffset*/, MdFormatter& /*inEmitter*/); + + // spilling + virtual bool switchUseToSpill(Uint8 /*inWhichUse*/, VirtualRegister &/*inVR*/) { return false; } + virtual bool switchDefineToSpill(Uint8 /*inWhichDefine*/, VirtualRegister &/*inVR*/) { return false; } + + // Control Spilling + virtual bool opcodeAcceptsSpill() { return false; } + virtual void switchOpcodeToSpill() { assert(0); } + +protected: + x86OpcodeInfo* opcodeInfo; + +private: + static x86OpcodeInfo opcodeTable[]; + +public: +#ifdef DEBUG_LOG + // Debugging Methods + virtual void printOpcode(LogModuleObject &f) { UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("%-9s", opcodeInfo->oiText)); } +#endif // DEBUG_LOG +}; + +//----------------------------------------------------------------------------------------------------------- +// Floating-point instructions in which all operands and results are implicitly on the FPU stack + +enum x86FloatRegType +{ + fucomip, + fneg, + fnstsw +}; + +class InsnFloatReg : + public InsnUseXDefineYFromPool +{ +public: + InsnFloatReg(DataNode* inPrimitive, Pool& inPool, x86FloatRegType inOpInfo, Uint8 inX, Uint8 inY): + InsnUseXDefineYFromPool (inPrimitive, inPool, inX, inY ) + { + opcodeInfo = &opcodeTable[inOpInfo]; + } + + virtual Uint8 opcodeSize() {return 2;} + + virtual size_t getFormattedSize(MdFormatter& /*inFormatter*/) { return 2; }; + virtual void formatToMemory(void * /*inStart*/, Uint32 /*inCurOffset*/, MdFormatter& /*inEmitter*/); + + // spilling + virtual bool switchUseToSpill(Uint8 /*inWhichUse*/, VirtualRegister &/*inVR*/) { return false; } + virtual bool switchDefineToSpill(Uint8 /*inWhichDefine*/, VirtualRegister &/*inVR*/) { return false; } + + // Control Spilling + virtual bool opcodeAcceptsSpill() { return false; } + virtual void switchOpcodeToSpill() { assert(0); } + +protected: + x86OpcodeInfo* opcodeInfo; + +private: + static x86OpcodeInfo opcodeTable[]; + +public: +#ifdef DEBUG_LOG + // Debugging Methods + virtual void printPretty(LogModuleObject &f) { UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("%-9s", opcodeInfo->oiText)); } +#endif // DEBUG_LOG +}; + +#endif // X86_FLOAT_H + diff --git a/ef/Compiler/CodeGenerator/md/x86/x86Formatter.cpp b/ef/Compiler/CodeGenerator/md/x86/x86Formatter.cpp new file mode 100644 index 000000000000..a85bdbc12bfb --- /dev/null +++ b/ef/Compiler/CodeGenerator/md/x86/x86Formatter.cpp @@ -0,0 +1,236 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +// +// File: x86Formatter.cpp +// +// Authors: Peter DeSantis +// Simon Holmes a Court +// Scott Silver +// + +#include "x86Formatter.h" +#include "FieldOrMethod.h" +#include "MemoryAccess.h" +#include "JavaObject.h" + +//----------------------------------------------------------------------------------------------------------- +// Constants +const Uint8 kPush_ebp = 0x55; +const Uint8 kPush_edi = 0x57; +const Uint8 kPush_esi = 0x56; +const Uint8 kPush_ebx = 0x53; + +const Uint16 kMov_ebp_esp = 0x8bec; +const Uint16 kSub_esp_Imm8 = 0x83ec; // 8-bit immediate subtract (8-bit val extended to 32-bits) +const Uint16 kSub_esp_Imm32 = 0x81ec; // Signed, 32-bit immediate subtract + +const Uint8 kPop_ebp = 0x5d; +const Uint8 kPop_ebx = 0x5b; +const Uint8 kPop_esi = 0x5e; +const Uint8 kPop_edi = 0x5f; + +const Uint8 kRet = 0xc3; +const Uint8 kRet_Imm16 = 0xc2; +const Uint16 kMov_esp_ebp = 0x8be5; + +//----------------------------------------------------------------------------------------------------------- +// x86Formatter + +void x86Formatter:: +beginFormatting(const FormattedCodeInfo& inInfo) +{ + mFCI = inInfo; +} + +void x86Formatter:: +initStackFrameInfo() +{ + mStackFrameInfo.init(mEmitter.mVRAllocator); +} + +void x86Formatter:: +calculatePrologEpilog(Method& inMethod, Uint32& outPrologSize, Uint32& outEpilogSize) +{ + Uint32 GPRwords = mStackFrameInfo.getNumSavedGPRWords(); + Uint32 localStoreBytes = mStackFrameInfo.getLocalStoreSizeBytes(); + + if(localStoreBytes == 0) + { + mPrologSize_bytes = 3 + GPRwords; + mEpilogSize_bytes = 4 + GPRwords; + } + else { + if (localStoreBytes < 128) + mPrologSize_bytes = 6 + GPRwords; + else + mPrologSize_bytes = 9 + GPRwords; + mEpilogSize_bytes = 6 + GPRwords; + } + + // determine how many words were passed to us, so the epilog can clean up the stack + const Signature& ourSignature = inMethod.getSignature(); + const int numArgs = ourSignature.nArguments; + const Type** ourArgs = ourSignature.argumentTypes; + + mNumberOfArgumentWords = 0; + for(int i = 0; i < numArgs; i++) + mNumberOfArgumentWords += nTypeKindSlots(ourArgs[i]->typeKind); + + outPrologSize = mPrologSize_bytes; + outEpilogSize = mEpilogSize_bytes; +} + +void x86Formatter:: +formatPrologToMemory(void* inWhere) +{ + Uint8* where = (uint8*)inWhere; + + // push ebp + *where++ = kPush_ebp; + + //mov ebp, esp + writeBigHalfwordUnaligned(where, kMov_ebp_esp); + where += 2; + + // reserve local store space + // sub esp, localstore + Uint32 localStoreBytes = mStackFrameInfo.getLocalStoreSizeBytes(); + if (localStoreBytes) { + if (localStoreBytes < 128) + { + writeBigHalfwordUnaligned(where, kSub_esp_Imm8); + where += 2; + *where++ = localStoreBytes; + } + else + { + writeBigHalfwordUnaligned(where, kSub_esp_Imm32); + where += 2; + writeLittleWordUnaligned(where, localStoreBytes); + where += 4; + } + } + + // save GPRs -- FIX change to bitfields sometime + Uint32 GPRwords = mStackFrameInfo.getNumSavedGPRWords(); + if(GPRwords > 2) + *where++ = kPush_edi; + if(GPRwords > 1) + *where++ = kPush_esi; + if(GPRwords > 0) + *where++ = kPush_ebx; +} + +void x86Formatter:: +formatEpilogToMemory(void* inWhere) +{ + Uint8* where = (uint8*)inWhere; + + // restore GPRs -- FIX change to bitfields sometime + Uint32 GPRwords = mStackFrameInfo.getNumSavedGPRWords(); + if(GPRwords > 0) + *where++ = kPop_ebx; + if(GPRwords > 1) + *where++ = kPop_esi; + if(GPRwords > 2) + *where++ = kPop_edi; + + // mov esp, ebp + Uint32 localStoreBytes = mStackFrameInfo.getLocalStoreSizeBytes(); + if(localStoreBytes != 0) + { + writeBigHalfwordUnaligned(where, kMov_esp_ebp); + where+=2; + } + + // pop ebp + *where++ = kPop_ebp; + + // return cleaning the stack of passed in arguments + if(mNumberOfArgumentWords != 0) + { + *where++ = kRet_Imm16; + writeLittleHalfwordUnaligned(where, mNumberOfArgumentWords * 4); + } + else + { + *where = kRet; + } +} + +Uint8* x86Formatter:: +createTransitionVector(const FormattedCodeInfo& inInfo) +{ + return inInfo.methodStart; +} + +Uint8* x86Formatter:: +getMethodBegin() +{ + return mFCI.methodStart; +} + +//----------------------------------------------------------------------------------------------------------- +// Debugging + +#ifdef DEBUG_LOG + +#include "XDisAsm.h" + +#define USING_X86_DISASSEMBLER + +const int kMaxDissasemblyBytes = 8; // maximum number of bytes to dump per instruction + +// Function: disassemble1 +void* +disassemble1(LogModuleObject &f, void* inFrom) +{ +#ifdef USING_X86_DISASSEMBLER + char* disasmText; + char* startAddr = (char*)inFrom; + char* curAddr = startAddr; + + disasmText = disasmx86( 0, + &curAddr, + curAddr + 32, + kDisAsmFlag32BitSegments); + + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("0x%p: ", inFrom)); + + // print memory dump + Uint8 numBytes = (Uint8)curAddr - (Uint8)startAddr; + for(int i = 0; i < kMaxDissasemblyBytes; i++) + { + if (i < numBytes) { + Uint8 address= ((Uint8*)startAddr)[i]; + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("%x%x ", address/16, address%16)); + } + else + UT_OBJECTLOG(f, PR_LOG_ALWAYS, (" ")); + } + + UT_OBJECTLOG(f, PR_LOG_ALWAYS, (" %s\n", disasmText)); + return (curAddr); +#else + f = NULL; inFrom = NULL; + return NULL; +#endif + +} + +#endif // DEBUG_LOG diff --git a/ef/Compiler/CodeGenerator/md/x86/x86Formatter.h b/ef/Compiler/CodeGenerator/md/x86/x86Formatter.h new file mode 100644 index 000000000000..2febbdd2dcff --- /dev/null +++ b/ef/Compiler/CodeGenerator/md/x86/x86Formatter.h @@ -0,0 +1,115 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +// +// File: x86Formatter.h +// +// Authors: Peter DeSantis +// Simon Holmes a Court +// Scott Silver +// + +#ifndef X86_FORMATTER +#define X86_FORMATTER + +#include "Fundamentals.h" +#include "FormatStructures.h" // for FCI, StackFrameInfo +#include "x86Win32Emitter.h" // temp? + +const int kStackSlotSize = 8; + +//----------------------------------------------------------------------------------------------------------- +// x86StackFrameInfo +class x86StackFrameInfo : + public StackFrameInfo +{ +public: + x86StackFrameInfo() { } + + void init(VirtualRegisterManager& inVRManager) + { + // eventually the register allocator will tell us all this information + numSavedGPRs = 3; + numSavedFPRs = 0; + numMonitorSlots = 0; + + localStore_bytes = inVRManager.nUsedStackSlots * kStackSlotSize; + + StackFrameInfo::init(inVRManager); + } + + // return number of bytes than EBP of the stack slot + Int32 getStackSlotOffset(VirtualRegister& inVr) + { + assert(hasBeenInited); + assert(inVr.getClass() == StackSlotRegister); + return (inVr.getColor() * - kStackSlotSize) - kStackSlotSize; + } + +private: +}; + +//----------------------------------------------------------------------------------------------------------- +// x86Formatter +class x86Formatter +{ +protected: + Uint16 mNumberOfArgumentWords; + + Uint32 mFrameSize_words; + Uint32 mPrologSize_bytes; + Uint32 mEpilogSize_bytes; + + x86StackFrameInfo mStackFrameInfo; + + // later should be object, not pointer + FormattedCodeInfo mFCI; // cached format info + +public: + // fields + const MdEmitter& mEmitter; + + // methods + x86Formatter(const MdEmitter& inEmitter) : mEmitter(inEmitter) { } + void calculatePrologEpilog(Method& /*inMethod*/, Uint32& outPrologSize, Uint32& outEpilogSize); + void formatEpilogToMemory(void* inWhere); + void formatPrologToMemory(void* inWhere); + + void beginFormatting(const FormattedCodeInfo& inInfo); + void endFormatting(const FormattedCodeInfo& /*inInfo*/) { } + + void calculatePrePostMethod(Method& /*inMethod*/, Uint32& outPreMethodSize, Uint32& outPostMethodSize) { outPreMethodSize = outPostMethodSize = 0; } + void formatPostMethodToMemory(void* /*inWhere*/, const FormattedCodeInfo& /*inInfo*/) { } + void formatPreMethodToMemory(void* /*inWhere*/, const FormattedCodeInfo& /*inInfo*/) { } + + // stack frame stuff + void initStackFrameInfo(); + StackFrameInfo& getStackFrameInfo() {return mStackFrameInfo; } + Int32 getStackSlotOffset(VirtualRegister& inVr) { return mStackFrameInfo.getStackSlotOffset(inVr); } + + Uint8* createTransitionVector(const FormattedCodeInfo& inInfo); + + Uint8* getMethodBegin(); +}; + + +#ifdef DEBUG_LOG +void* disassemble1(LogModuleObject &f, void* inFrom); +#endif + + +#endif // X86_FORMATTER diff --git a/ef/Compiler/CodeGenerator/md/x86/x86Linux.s b/ef/Compiler/CodeGenerator/md/x86/x86Linux.s new file mode 100644 index 000000000000..89f299cc8a4a --- /dev/null +++ b/ef/Compiler/CodeGenerator/md/x86/x86Linux.s @@ -0,0 +1,593 @@ +/* -*- Mode: asm; tab-width:4; truncate-lines:t -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + + .file "x86Linux.S" + +#define ALIGN .align 16 +#define SYMBOL_NAME(name) name +#define SYMBOL_NAME_LABEL(name) name##: + +#define GLOBAL_ENTRY_START(name) \ + ALIGN; \ + .globl SYMBOL_NAME(name); \ + .type SYMBOL_NAME(name),@function; \ + SYMBOL_NAME_LABEL(name) + +#define GLOBAL_ENTRY_END(name) \ + SYMBOL_NAME_LABEL(.L##name); \ + .size SYMBOL_NAME(name),SYMBOL_NAME(.L##name)-SYMBOL_NAME(name) + + +GLOBAL_ENTRY_START(staticCompileStub) + + push %eax /* Save all volatiles */ + push %ebx + push %ecx + push %edx + push 20(%esp) /* Push the second argument to compileAndBackPatchMethod (return address) */ + push 20(%esp) /* Push the first argument to compileAndBackPatchMethod (cacheEntry) */ + call compileAndBackPatchMethod + pop %edx /* Remove passes arguments */ + pop %edx /* Remove passes arguments */ + mov %eax, 16(%esp) /* Overwrite cacheEntry with function address */ + pop %edx /* Restore volatiles */ + pop %ecx + pop %ebx + pop %eax + ret /* Jump to function leaving the return address at the top of the stack */ + +GLOBAL_ENTRY_END(staticCompileStub) + +GLOBAL_ENTRY_START(compileStub) + push 0xefbeadde /* This is a dummy immediate that will be filled in by */ + jmp staticCompileStub /* generateCompileStub with the cacheEntry */ +GLOBAL_ENTRY_END(compileStub) + +/* + * 64bit Arithmetic Support Functions + * + * x86Extract64Bit + * + * Origin: Simon + * Purpose: signed right-aligned field extraction + * In: 64 bit source (on stack) + * 32 bit extraction size (on stack) + * Out: 64 bit result + * Note: Only works in range 1 <= b <= 63, b is extraction amount + */ +GLOBAL_ENTRY_START(x86Extract64Bit) + + mov 4(%esp),%eax /* load low byte of a */ + + mov 12(%esp),%ecx /*load shift amount */ + cmp $0x20,%ecx + jg greater32 + + /* extract <= than 32 bits + * shift amount = 32 - extract + */ + neg %ecx + add $0x20,%ecx /* ecx = 32 - extract */ + shl %cl,%eax + sar %cl,%eax + cdq /* sign extend into EDX:EAX */ + ret $12 + +greater32: + /* ext > 32 bits + * shift amount = 64 - extract + */ + mov 8(%esp),%edx /* load high byte of a */ + neg %ecx + add $0x40,%ecx /* ecx = 64 - extract */ + shl %cl,%edx + sar %cl,%edx + ret $12 + +GLOBAL_ENTRY_END(x86Extract64Bit) + +/* + * 3WayCompare + * + * Origin: Symantec JIT + * Purpose: compare two longs + * In: two longs on the stack + * Out: depends on condition flags: + * less = -1 + * equal = 0 + * greater = 1 + */ +GLOBAL_ENTRY_START(x86ThreeWayCMP_L) + + /* edx:eax is tos, ecx:ebx is nos */ + mov 8(%esp),%ecx + mov 16(%esp),%edx + + cmp %edx,%ecx + jl lcmp_m1 + + jg lcmp_1 + + mov 4(%esp),%ecx + mov 12(%esp),%edx + + cmp %edx,%ecx + ja lcmp_1 + + mov $0,%eax + jb lcmp_m1 + + ret $16 + + .align 4 +lcmp_m1: + mov $-1,%eax + ret $16 + + .align 4 +lcmp_1: + mov $1,%eax + ret $16 + +GLOBAL_ENTRY_END(x86ThreeWayCMP_L) + +/* + * llmul + * + * Origin: Intel Code (via MSDev) + * Purpose: long multiply (same for signed/unsigned) + * In: args are passed on the stack: + * 1st pushed: multiplier (QWORD) + * 2nd pushed: multiplicand (QWORD) + * Out: EDX:EAX - product of multiplier and multiplicand + * Note: parameters are removed from the stack + * Uses: ECX + */ +GLOBAL_ENTRY_START(x86Mul64Bit) + + /* A*B = (A.lo * B.lo) + (A.lo * B.hi) + (B.lo * A.hi) ??? */ + mov 8(%esp),%eax /* A.hi */ + mov 16(%esp),%ecx /* B.hi */ + or %eax,%ecx /* test for both hiwords zero */ + mov 12(%esp),%ecx /* B.lo */ + jnz hard + + /* easy case + * both are zero, just mult ALO and BLO + */ + mov 4(%esp),%eax /* A.lo */ + mul %ecx /* A.lo * B.lo */ + ret $16 /* callee restores the stack */ + + /* hard case */ +hard: + push %ebx + + mul %ecx /* A.hi * B.lo */ + mov %eax,%ebx /* save result */ + + mov 8(%esp),%eax /* A.lo */ + mull 14(%esp) /* A.lo * B.hi */ + add %eax,%ebx /* ebx = ((A.lo * B.hi) + (A.hi * B.lo)) */ + + mov 8(%esp),%eax /* A.lo */ + mul %ecx /* edx:eax = A.lo * B.lo */ + add %ebx,%edx /* now edx has all the LO*HI stuff */ + + pop %ebx + + ret $16 /* callee restores the stack */ + +GLOBAL_ENTRY_END(x86Mul64Bit) + +/* + * lldiv + * + * Origin: Intel Code (via MSDev) + * Purpose: signed long divide + * In: args are passed on the stack: + * 1st pushed: divisor (QWORD) + * 2nd pushed: dividend (QWORD) + * Out: EDX:EAX contains the quotient (dividend/divisor) + * Note: parameters are removed from the stack + * Uses: ECX + */ +GLOBAL_ENTRY_START(x86Div64Bit) + + push %edi + push %esi + push %ebx + + /* Determine sign of the result (%edi = 0 if result is positive, non-zero + * otherwise) and make operands positive. + */ + xor %edi,%edi /* result sign assumed positive */ + + mov 20(%esp),%eax /* hi word of a */ + or %eax,%eax /* test to see if signed */ + jge L1 /* skip rest if a is already positive */ + inc %edi /* complement result sign flag */ + mov 16(%esp),%edx /* lo word of a */ + neg %eax /* make a positive */ + neg %edx + sbb $0,%eax + mov %eax,20(%esp) /* save positive value */ + mov %edx,16(%esp) +L1: + mov 28(%esp),%eax /* hi word of b */ + or %eax,%eax /* test to see if signed */ + jge L2 /* skip rest if b is already positive */ + inc %edi /* complement the result sign flag */ + mov 24(%esp),%edx /* lo word of a */ + neg %eax /* make b positive */ + neg %edx + sbb $0,%eax + mov %eax,28(%esp) /* save positive value */ + mov %edx,24(%esp) +L2: + + /* Now do the divide. First look to see if the divisor is less than 4194304K. + * If so, then we can use a simple algorithm with word divides, otherwise + * things get a little more complex. + * NOTE - %eax currently contains the high order word of DVSR + */ + or %eax,%eax /* check to see if divisor < 4194304K */ + jnz L3 /* nope, gotta do this the hard way */ + mov 24(%esp),%ecx /* load divisor */ + mov 20(%esp),%eax /* load high word of dividend */ + xor %edx,%edx + div %ecx /* %eax <- high order bits of quotient */ + mov %eax,%ebx /* save high bits of quotient */ + mov 16(%esp),%eax /* %edx:%eax <- remainder:lo word of dividend */ + div %ecx /* %eax <- low order bits of quotient */ + mov %ebx,%edx /* %edx:%eax <- quotient */ + jmp L4 /* set sign, restore stack and return */ + + /* Here we do it the hard way. Remember, %eax contains the high word of DVSR */ +L3: + mov %eax,%ebx /* %ebx:ecx <- divisor */ + mov 24(%esp),%ecx + mov 20(%esp),%edx /* %edx:%eax <- dividend */ + mov 16(%esp),%eax +L5: + shr $1,%ebx /* shift divisor right one bit */ + rcr $1,%ecx + shr $1,%edx /* shift dividend right one bit */ + rcr $1,%eax + or %ebx,%ebx + jnz L5 /* loop until divisor < 4194304K */ + div %ecx /* now divide, ignore remainder */ + mov %eax,%esi /* save quotient */ + + /* We may be off by one, so to check, we will multiply the quotient + * by the divisor and check the result against the orignal dividend + * Note that we must also check for overflow, which can occur if the + * dividend is close to 2**64 and the quotient is off by 1. + */ + mull 28(%esp) /* QUOT * HIWORD(DVSR) */ + mov %eax,%ecx + mov 24(%esp),%eax + mul %esi /* QUOT * LOWORD(DVSR) */ + add %ecx,%edx /* %EDX:%EAX = QUOT * DVSR */ + jc L6 /* carry means Quotient is off by 1 */ + + /* do long compare here between original dividend and the result of the + * multiply in %edx:%eax. If original is larger or equal, we are ok, otherwise + * subtract one (1) from the quotient. + */ + cmp 20(%esp),%edx /* compare hi words of result and original */ + ja L6 /* if result > original, do subtract */ + jb L7 /* if result < original, we are ok */ + cmp 16(%esp),%eax /* hi words are equal, compare lo words */ + jbe L7 /* if less or equal we are ok, else subtract */ +L6: + dec %esi /* subtract 1 from quotient */ +L7: + xor %edx,%edx /* %edx:%eax <- quotient */ + mov %esi,%eax + + /* Just the cleanup left to do. %edx:%eax contains the quotient. Set the sign + * according to the save value, cleanup the stack, and return. + */ +L4: + dec %edi /* check to see if result is negative */ + jnz L8 /* if %EDI == 0, result should be negative */ + neg %edx /* otherwise, negate the result */ + neg %eax + sbb $0,%edx + + /* Restore the saved registers and return. */ +L8: + pop %ebx + pop %esi + pop %edi + + ret $16 + +GLOBAL_ENTRY_END(x86Div64Bit) + +/* + * llrem + * + * Origin: MSDev + * Purpose: signed long remainder + * In: args are passed on the stack: + * 1st pushed: divisor (QWORD) + * 2nd pushed: dividend (QWORD) + * Out: %EDX:%EAX contains the quotient (dividend/divisor) + * Note: parameters are removed from the stack + * Uses: %ECX + */ +GLOBAL_ENTRY_START(x86Mod64Bit) + + push %ebx + push %edi + + /* Determine sign of the result (%edi = 0 if result is positive, non-zero + * otherwise) and make operands positive. + */ + xor %edi,%edi /* result sign assumed positive */ + + mov 16(%esp),%eax /* hi word of a */ + or %eax,%eax /* test to see if signed */ + jge LL1 /* skip rest if a is already positive */ + inc %edi /* complement result sign flag bit */ + mov 12(%esp),%edx /* lo word of a */ + neg %eax /* make a positive */ + neg %edx + sbb $0,%eax + mov %eax,16(%esp) /* save positive value */ + mov %edx,12(%esp) +LL1: + mov 24(%esp),%eax /* hi word of b */ + or %eax,%eax /* test to see if signed */ + jge LL2 /* skip rest if b is already positive */ + mov 20(%esp),%edx /* lo word of b */ + neg %eax /* make b positive */ + neg %edx + sbb $0,%eax + mov %eax,24(%esp) /* save positive value */ + mov %edx,20(%esp) +LL2: + /* Now do the divide. First look to see if the divisor is less than 4194304K. + * If so, then we can use a simple algorithm with word divides, otherwise + * things get a little more complex. + * NOTE - %eax currently contains the high order word of DVSR + */ + or %eax,%eax /* check to see if divisor < 4194304K */ + jnz LL3 /* nope, gotta do this the hard way */ + mov 20(%esp),%ecx /* load divisor */ + mov 16(%esp),%eax /* load high word of dividend */ + xor %edx,%edx + div %ecx /* %edx <- remainder */ + mov 12(%esp),%eax /* %edx:%eax <- remainder:lo word of dividend */ + div %ecx /* %edx <- final remainder */ + mov %edx,%eax /* %edx:%eax <- remainder */ + xor %edx,%edx + dec %edi /* check result sign flag */ + jns LL4 /* negate result, restore stack and return */ + jmp LL8 /* result sign ok, restore stack and return */ + + /* Here we do it the hard way. Remember, %eax contains the high word of DVSR */ +LL3: + mov %eax,%ebx /* %ebx:%ecx <- divisor */ + mov 20(%esp),%ecx + mov 16(%esp),%edx /* %edx:%eax <- dividend */ + mov 12(%esp),%eax +LL5: + shr $1,%ebx /* shift divisor right one bit */ + rcr $1,%ecx + shr $1,%edx /* shift dividend right one bit */ + rcr $1,%eax + or %ebx,%ebx + jnz LL5 /* loop until divisor < 4194304K */ + div %ecx /* now divide, ignore remainder */ + + /* We may be off by one, so to check, we will multiply the quotient + * by the divisor and check the result against the orignal dividend + * Note that we must also check for overflow, which can occur if the + * dividend is close to 2**64 and the quotient is off by 1. + */ + mov %eax,%ecx /* save a copy of quotient in %ECX */ + mull 24(%esp) + xchg %eax,%ecx /* save product, get quotient in %EAX */ + mull 20(%esp) + add %ecx,%edx /* %EDX:%EAX = QUOT * DVSR */ + jc LL6 /* carry means Quotient is off by 1 */ + + /* do long compare here between original dividend and the result of the + * multiply in %edx:%eax. If original is larger or equal, we are ok, otherwise + * subtract the original divisor from the result. + */ + cmp 16(%esp),%edx /* compare hi words of result and original */ + ja LL6 /* if result > original, do subtract */ + jb LL7 /* if result < original, we are ok */ + cmp 12(%esp),%eax /* hi words are equal, compare lo words */ + jbe LL7 /* if less or equal we are ok, else subtract */ +LL6: + sub 20(%esp),%eax /* subtract divisor from result */ + sbb 24(%esp),%edx +LL7: + + /* Calculate remainder by subtracting the result from the original dividend. + * Since the result is already in a register, we will do the subtract in the + * opposite direction and negate the result if necessary. + */ + sub 12(%esp),%eax /* subtract dividend from result */ + sbb 16(%esp),%edx + + /* Now check the result sign flag to see if the result is supposed to be positive + * or negative. It is currently negated (because we subtracted in the 'wrong' + * direction), so if the sign flag is set we are done, otherwise we must negate + * the result to make it positive again. + */ + dec %edi /* check result sign flag */ + jns LL8 /* result is ok, restore stack and return */ +LL4: + neg %edx /* otherwise, negate the result */ + neg %eax + sbb $0,%edx + + /* Just the cleanup left to do. %edx:%eax contains the quotient. + * Restore the saved registers and return. + */ +LL8: + pop %edi + pop %ebx + + ret $16 + +GLOBAL_ENTRY_END(x86Mod64Bit) + +/* + * llshl + * + * Origin: MSDev. modified + * Purpose: long shift left + * In: args are passed on the stack: (FIX make fastcall) + * 1st pushed: amount (int) + * 2nd pushed: source (long) + * Out: %EDX:%EAX contains the result + * Note: parameters are removed from the stack + * Uses: %ECX, destroyed + */ +GLOBAL_ENTRY_START(x86Shl64Bit) + + /* prepare from stack */ + mov 4(%esp),%eax + mov 8(%esp),%edx + mov 12(%esp),%ecx + + cmp $64,%cl + jae RETZERO + + /* Handle shifts of between 0 and 31 bits */ + cmp $32,%cl + jae MORE32 + shld %eax,%edx + shl %cl,%eax + ret $12 + + /* Handle shifts of between 32 and 63 bits */ +MORE32: + mov %eax,%edx + xor %eax,%eax + and $31,%cl + shl %cl,%edx + ret $12 + + /* return 0 in %edx:%eax */ +RETZERO: + xor %eax,%eax + xor %edx,%edx + ret $12 + +GLOBAL_ENTRY_END(x86Shl64Bit) + + +/* + * llshr + * + * Origin: MSDev. modified + * Purpose: long shift right + * In: args are passed on the stack: (FIX make fastcall) + * 1st pushed: amount (int) + * 2nd pushed: source (long) + * Out: %EDX:%EAX contains the result + * Note: parameters are removed from the stack + * Uses: %ECX, destroyed + */ +GLOBAL_ENTRY_START(x86Shr64Bit) + + /* prepare from stack */ + mov 4(%esp),%eax + mov 8(%esp),%edx + mov 12(%esp),%ecx + + cmp $64,%cl + jae RRETZERO + + /* Handle shifts of between 0 and 31 bits */ + cmp $32,%cl + jae MMORE32 + shrd %edx,%eax + shr %cl,%edx + ret $12 + + /* Handle shifts of between 32 and 63 bits */ +MMORE32: + mov %edx,%eax + xor %edx,%edx + and $31,%cl + shr %cl,%eax + ret $12 + + /* return 0 in %edx:%eax */ +RRETZERO: + xor %eax,%eax + xor %edx,%edx + ret $12 + +GLOBAL_ENTRY_END(x86Shr64Bit) + +/* + * llsar + * + * Origin: MSDev. modified + * Purpose: long shift right signed + * In: args are passed on the stack: (FIX make fastcall) + * 1st pushed: amount (int) + * 2nd pushed: source (long) + * Out: %EDX:%EAX contains the result + * Note: parameters are removed from the stack + * Uses: %ECX, destroyed + */ +GLOBAL_ENTRY_START(x86Sar64Bit) + + /* prepare from stack */ + mov 4(%esp),%eax + mov 8(%esp),%edx + mov 12(%esp),%ecx + + /* Handle shifts of 64 bits or more (if shifting 64 bits or more, the result */ + /* depends only on the high order bit of %edx). */ + cmp $64,%cl + jae RETSIGN + + /* Handle shifts of between 0 and 31 bits */ + cmp $32,%cl + jae MMMORE32 + shrd %edx,%eax + sar %cl,%edx + ret $12 + + /* Handle shifts of between 32 and 63 bits */ +MMMORE32: + mov %edx,%eax + sar $31,%edx + and $31,%cl + sar %cl,%eax + ret $12 + + /* Return double precision 0 or -1, depending on the sign of %edx */ +RETSIGN: + sar $31,%edx + mov %edx,%eax + ret $12 + +GLOBAL_ENTRY_END(x86Sar64Bit) diff --git a/ef/Compiler/CodeGenerator/md/x86/x86Linux_Support.cpp b/ef/Compiler/CodeGenerator/md/x86/x86Linux_Support.cpp new file mode 100644 index 000000000000..cc8b5aa0b7a8 --- /dev/null +++ b/ef/Compiler/CodeGenerator/md/x86/x86Linux_Support.cpp @@ -0,0 +1,125 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +/* + x86Linux_Support.cpp +*/ + +#include "NativeCodeCache.h" +#include +#include "Fundamentals.h" +#include "MemoryAccess.h" +#include "x86Linux_Support.h" + + +void* JNIenv = 0; + +extern ClassWorld world; + +#ifdef DEBUG +// Pointer to the instruction after the call (used by exception handler to check +// I wanted to use: +// void* compileStubReEntryPoint = (void*) ((Uint8*)staticCompileStub + 17); +// but MSDev appears to have a bug, in that compileStubReEntryPoint will be set == (void*)staticCompileStub +// which is clearly wrong. +void* compileStubAddress = (void*)staticCompileStub; +void* compileStubReEntryPoint = (Uint8*)compileStubAddress + 17; +#endif // DEBUG + +void * +generateNativeStub(NativeCodeCache& inCache, const CacheEntry& inCacheEntry, void *nativeFunction) +{ + Method* method = inCacheEntry.descriptor.method; + Uint32 nWords = method->getSignature().nArguments; + + assert(method->getModifiers() & CR_METHOD_NATIVE); + + extern Uint32 sysInvokeNativeStubs[]; + Uint8 stubSize = 10; + void* stub; + + // Write out the native stub + stub = inCache.acquireMemory(stubSize); + Uint8* where = (Uint8*)stub; + *where++ = 0x68; // pushl + writeLittleWordUnaligned(where, (uint32)(nativeFunction)); + where += 4; + *where++ = 0xe9; // jmp + writeLittleWordUnaligned(where, (Uint8 *) sysInvokeNativeStubs[nWords] - (where + 4)); + + // Return the address of the stub. + return ((void*)stub); +} + +void * +generateJNIGlue(NativeCodeCache& inCache, + const CacheEntry& inCacheEntry, + void *nativeFunction) +{ + void* stub; + Method* method = inCacheEntry.descriptor.method; + assert(method->getModifiers() & CR_METHOD_NATIVE); + + Uint8 stubSize = 12; + + // Write out the JNI compile stub + stub = inCache.acquireMemory(stubSize); + Uint8* where = (Uint8*) stub; + *where++ = 0x58; // popl %eax + *where++ = 0x68; // pushl + writeLittleWordUnaligned(where, (Uint32) JNIenv); + where += 4; + *where++ = 0xe9; // jmp + writeLittleWordUnaligned(where, reinterpret_cast(nativeFunction) - Uint32(where + 4)); + return stub; +} + +void * +generateCompileStub(NativeCodeCache& inCache, const CacheEntry& inCacheEntry) +{ + void* stub; + uint8 stubSize = 10; + + // Write out the dynamic compile stub + stub = inCache.acquireMemory(stubSize); + Uint8* where = (Uint8*)stub; + *where++ = 0x68; // pushl + writeLittleWordUnaligned(where, (uint32)(&inCacheEntry)); + where += 4; + *where++ = 0xe9; // jmp + writeLittleWordUnaligned(where, (Uint8 *) staticCompileStub - (where + 4)); + + // Return the address of the dynamic stub. + return ((void*)stub); +} + +void* +backPatchMethod(void* inMethodAddress, void* inLastPC, void* /*inUserDefined*/) +{ + + uint32 curAddress = (uint32) inLastPC; + uint32 methodAddress = (uint32) inMethodAddress; + + // Compute the relative branch + uint32* relativeBranch = ((uint32*)inLastPC)-1; + int32 offset = methodAddress - curAddress; + + // Backpatch the method. + writeLittleWordUnaligned((void*)relativeBranch, offset); + + return (inMethodAddress); +} diff --git a/ef/Compiler/CodeGenerator/md/x86/x86Linux_Support.h b/ef/Compiler/CodeGenerator/md/x86/x86Linux_Support.h new file mode 100644 index 000000000000..9f52c26becec --- /dev/null +++ b/ef/Compiler/CodeGenerator/md/x86/x86Linux_Support.h @@ -0,0 +1,31 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#ifndef _X86_LINUX_SUPPORT_H_ +#define _X86_LINUX_SUPPORT_H_ + +#include "prtypes.h" + +PR_BEGIN_EXTERN_C + +extern void staticCompileStub(); + +PR_END_EXTERN_C + +#endif // _X86_LINUX_SUPPORT_H_ + diff --git a/ef/Compiler/CodeGenerator/md/x86/x86Opcode.cpp b/ef/Compiler/CodeGenerator/md/x86/x86Opcode.cpp new file mode 100644 index 000000000000..8b31eebf3567 --- /dev/null +++ b/ef/Compiler/CodeGenerator/md/x86/x86Opcode.cpp @@ -0,0 +1,230 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + /* + desantis + holmes a court (commenting) + + x86Opcode.cpp + + NOTE: + This file is being phased out -- please do not add to it without speaking to simon +*/ + +#include "CatchAssert.h" + +#include "x86Opcode.h" +#include "x86ArgumentList.h" + +// Not used anywhere +// { 0x69, 0x00, "imul " } //iaMulImm 69 0000 0000 + +//================================================================================ +/* Opcode Information + +Each OpcodeInfo consists of + x86OpcodeInfo { + oiBaseOpcode // generally the opcode, but can have additional info + oiOpcodeInformation // additional info about opcode + oiText // string for fake disassembly + } + +Field bits are referred to as [7 6 5 4 3 2 1 0] + +-------------------------------------------------------------------------------- +ImmediateArithType +eg: + 1000 00s1: 11 111 reg:immdata immediate with register + 1000 00s1:mod 111 r/m:immdata immediate with memory + +oiBaseOpcode + contains the opcode for the instruction + 1 (Size) always 0 (assigned at format time) + +oiOpcodeInformation + 7 set if two byte opcode + 6 set if has an opcode extension + [5 4 3] opcode extension of the instructrion + 1 set if must take a 1-byte immediate + 0 set if must take a 4-byte immediate + others set to 0 +*/ +x86OpcodeInfo iaInfo[] = +{ + // ** * + { 0x81, 0x40, "add " }, //iaAddImm 81/0 0100 0000 + { 0x81, 0x78, "cmp " }, //iaCmpImm 81/7 0111 1000 + { 0xe9, 0x40, "jmp " }, //iaJmp e9/0 0100 0000 + { 0x68, 0x40, "push "}, //iaPushImm 68/0 0100 0000 + { 0x81, 0x60, "and "}, //iaAndImm 81/4 0110 0000 + { 0x81, 0x48, "or "}, //iaOrImm 81/1 0100 1000 + { 0x81, 0x70, "xor "}, //iaXorImm 81/6 0111 0000 +}; + +/*-------------------------------------------------------------------------------- +ExtendedType +eg + 1100 0001: 11 111 reg:imm8data reg by immediate count + 1100 0001:mod 111 r/m:imm8data memory by immediate count + +oiBaseOpcode + contains the opcode for the instruction + +oiOpcodeInformation + 7 set if two byte opcode + [5 4 3] contain Regfield opcode extension + 1 set if can take a 1-byte immediate + 0 set if can take a 4-byte immediate + others set to 0 +*/ +x86OpcodeInfo eInfo[] = +{ // ** * + { 0xf7, 0x38, "idiv eax, " }, //eIDiv f7/7 0011 1000 + { 0xf7, 0x30, "div eax, " }, //eDiv f7/6 0011 0000 + { 0xf7, 0x20, "div eax, " }, //eMul f7/4 0010 0000 + { 0xc7, 0x01, "movImm " }, //eMoveImm c7/0 0000 0001 // used when won't be condensable + { 0xff, 0x30, "push "}, //ePush ff/6 0011 0000 // FIX Peter? (what's wrong?) + { 0xc1, 0x3a, "sar "}, //eSarImm c1/7 0011 1010 + { 0xc1, 0x2a, "shr "}, //eShrImm c1/5 0010 1010 + { 0xc1, 0x22, "shl "}, //eShlImm c1/4 0010 0010 + { 0xd1, 7<<3, "sar(by1) "}, //eSar1 c1/7 0011 1000 + { 0xd1, 5<<3, "shr(by1) "}, //eShr1 c1/5 0010 1000 + { 0xd1, 4<<3, "shl(by1) "}, //eShl1 c1/4 0010 0000 + { 0xd3, 7<<3, "sar(bycl) "}, //eSarCl c1/7 0011 1000 + { 0xd3, 5<<3, "shr(bycl) "}, //eShrCl c1/5 0010 1000 + { 0xd3, 4<<3, "shl(bycl) "}, //eShlCl c1/4 0010 0000 + { 0xf7, 3<<3, "neg "}, //eNeg f7/3 0001 1000 +}; + +/*-------------------------------------------------------------------------------- +CondensableExtendedType +Like ExtendedOpcodes but have alternate (condensed) encoding: 5-bit opcode + 3-bit reg operand +eg + 0100 0 rg reg (preferred encoding) + 1111 1111:mod 000 r/m memory + +oiBaseOpcode + contains the opcode for the instruction + +oiOpcodeInformation + [7 6 5 4 3] register condensed form opcode + [2 1 0] regfield extension in extended form + +NOTE: These opcodes cannot be two bytes and must take 4 BYTE IMMEDIATES +*/ + +x86OpcodeInfo ceInfo[] = +{ // norm condns + { 0xff, 0x40, "inc " }, //ceInc ff/0 40+reg 0100 0000 + { 0xff, 0x49, "dec " }, //ceDec ff/1 48+reg 0100 1001 + { 0xc7, 0xb8, "movImm " }, //ceMoveImm c7/0 b8+reg 1011 1000 + { 0xff, 0x46, "pop " } //cePop ff/0 40+reg 0101 0110 // 50+rd, ff/6 +}; + + +/*-------------------------------------------------------------------------------- +SpecialRegMemType + +eg [cmp vrx, 0] is the same as [test vrx, vrx] but the latter saves a byte +eg [mov vrx, 0] = [xor vrx, vrx] but the latter saves 4 bytes + +Optimisations like the above can only be applied to reg/reg + +oiBaseOpcode + contains the opcode for the instruction + +oiOpcodeInformation + 7 set if two byte opcode + 6 0 means register (StandardType) form + 1 means memory (ExtendedType) form + [5 4 3] contain Regfield opcode extension for ExtendedType form + + 1 set if can take a 1-byte immediate + 0 set if can take a 4-byte immediate + +Pairing + register form followed by memory form +*/ + +x86OpcodeInfo srmInfo[] = +{ + // cmp vrx, 0 = test vrx, vrx (save 1 byte) + {0x85, 0x00, "test "}, //srmCmpImm0 85/r 0000 0000 (2 bytes) + {0x83, 0x7a, "cmp "}, //srm1NOTUSED 83/7 0111 1010 (2+1 bytes) + + // mov vrx, 0 = xor vrx, vrx (save 4 bytes) + {0x31, 0x00, "xor "}, //srmMoveImm0 31/r 0000 0000 (2 bytes) + {0xc7, 0x41, "mov "} //srm3NOTUSED c7/0 0100 0001 (2+4 bytes) +}; + +//================================================================================ +// Member functions + +/*-------------------------------------------------------------------------------- +x86Opcode_ImmArith -- encodes x86ImmediateArithType + + - Sign/size bit which specifies 8 or 32 bits operand + - _possible_ three bit opcode extension (stored in the REG field of the MODR/M byte) +*/ +void x86Opcode_ImmArith:: +opFormatToMemory(void* inStart, x86ArgumentList& inAL, x86ArgListInstruction& /*inInsn*/ ) +{ + Uint8* start = (Uint8*) inStart; + + if(opInfo->oiOpcodeInformation & kIs_2_Byte_Mask) + *start++ = kPrefix_For_2_Byte; + + switch(inAL.alSizeOfImmediate()) + { + case(is4ByteImmediate): + *start = opInfo->oiBaseOpcode; + break; + + case(is1ByteImmediate): + *start = opInfo->oiBaseOpcode | (0x02); + break; + + default: + assert(false); // FIX what other possibilities are there? + break; + } +} + +//-------------------------------------------------------------------------------- +//x86Opcode_Condensable_Reg -- encodes x86CondensableExtendedType +void x86Opcode_Condensable_Reg:: +opFormatToMemory(void* inStart, x86ArgumentList& inAL, x86ArgListInstruction& inInsn) +{ + Uint8* start = (Uint8*) inStart; + Uint8 reg = inAL.alGetRegisterOperand(inInsn); + + if(reg == NOT_A_REG) // Operand is not a register + *start = opInfo->oiBaseOpcode; + else + *start = (opInfo->oiOpcodeInformation & kCondensed_Op_Mask) | reg; // 5-bit opcode + 3-bit reg +} + +bool x86Opcode_Condensable_Reg:: +opHasRegFieldExtension(x86ArgumentList& inAL, x86ArgListInstruction& inInsn) +{ + Uint8 reg = inAL.alGetRegisterOperand( inInsn ); + if(reg == NOT_A_REG) // Operand is not a register + return true; + return false; +} + +//-------------------------------------------------------------------------------- diff --git a/ef/Compiler/CodeGenerator/md/x86/x86Opcode.h b/ef/Compiler/CodeGenerator/md/x86/x86Opcode.h new file mode 100644 index 000000000000..fd91bea30d77 --- /dev/null +++ b/ef/Compiler/CodeGenerator/md/x86/x86Opcode.h @@ -0,0 +1,377 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +/* + x86Opcode.h + + desantis + simon + + NOTE: + This file is being phased out -- please do not add to it without speaking to simon +*/ + +#ifndef _X86OPCODE +#define _X86OPCODE + +#include "CatchAssert.h" +#include + +#include "Fundamentals.h" +#include "LogModule.h" + +class x86ArgumentList; +class x86ArgListInstruction; + +//================================================================================ +// enums +enum x86NoArgsCode +{ + opCdq, + opBreak, + opSahf +}; + +enum x86DoubleOpCode +{ + opMul, + opMovSxB, + opMovSxH, + opMovZxB, + opMovZxH +}; + +enum x86DoubleOpDirCode +{ + raAdd, + raAdc, + raSub, + raSbb, + raAnd, + raOr, + raXor, + raCmp, + + raLoadI, + raCopyI, + raStoreI, + raSaveReg, + + raStoreB, + raStoreH +}; + +// Floating-point instructions in which one operand is a memory location. +// If there is a second operand, then it is implicitly the top of the FPU stack. +enum x86FloatMemoryType +{ + fstp32, // TOS => 32-bit float memory. Pop FPU. + fstp64, // TOS => 64-bit double memory. Pop FPU. + fst32, // TOS => 32-bit float memory. (Don't pop FPU stack.) + fst64, // TOS => 64-bit double memory. (Don't pop FPU stack.) + fistp32, // Round(TOS) => 32-bit int memory. Pop FPU. + fistp64, // Round(TOS) => 64-bit long memory. Pop FPU. + fld32, // 32-bit float memory => Push on FPU stack + fld64, // 64-bit float memory => Push on FPU stack + fild32, // 32-bit int memory => convert to FP and push on FPU stack + fild64, // 64-bit long memory => convert to FP and push on FPU stack + fadd32, // Add TOS and 32-bit float memory => replace TOS + fadd64, // Add TOS and 64-bit double memory => replace TOS + fmul32, // Multiply TOS and 32-bit float memory => replace TOS + fmul64, // Multiply TOS and 64-bit double memory => replace TOS + fsub32, // Subtract TOS from 32-bit float memory => replace TOS + fsub64, // Subtract TOS from 64-bit double memory => replace TOS + fsubr32, // Subtract 32-bit float memory from TOS => replace TOS + fsubr64, // Subtract 64-bit double memory from TOS => replace TOS + fdiv32, // Divide TOS by 32-bit float memory => replace TOS + fdiv64, // Divide TOS by 64-bit double memory => replace TOS + fcomp32, // Compare TOS to 32-bit float memory, setting FPU flags, pop TOS + fcomp64 // Compare TOS to 64-bit double memory, setting FPU flags, pop TOS +}; + +// enums for the x96 conidtion code +enum x86ConditionCode +{ + ccJO = 0x00, + ccJNO = 0x01, + ccJB = 0x02, + ccJNB = 0x03, + ccJE = 0x04, + ccJNE = 0x05, + ccJBE = 0x06, + ccJNBE = 0x07, + ccJS = 0x08, + ccJNS = 0x09, + ccJP = 0x0a, + ccJNP = 0x0b, + ccJL = 0x0c, + ccJNL = 0x0d, + ccJLE = 0x0e, + ccJNLE = 0x0f +}; + +/*================================================================================ +x86 Opcodes + - Can be one byte or two bytes in length. If two bytes, the first byte is 0x0f. + - Can have bits to control: + - data flow direction(D), + - sign extension(S) // FIX pete, isn't this 'size' not 'sign'? + - conditions (cond), and + - register field + - opcode extensions (Reg). + - Can have an alternate (condensed) encoding which allows a single register operand to be encoded in the opcode. +*/ + +enum x86GPR +{ + EAX = 0, + ECX = 1, + EDX = 2, + EBX = 3, + ESP = 4, + EBP = 5, + ESI = 6, + EDI = 7, + NOT_A_REG = 255 +}; + +// bit masks +const int kRegfield_Mask = 0x38; // 0b00111000 +const int kIs_Memory_Form_Mask = 0x40; // 0b01000000 +const int kCondition_Code_Mask = 0x0f; // 0b00001111 +const int kCondensed_Op_Mask = 0xf8; // 0b11111000 +const int kIs_2_Byte_Mask = 0x80; // 0b10000000 +const int kIs_16_Bit_Mask = 0x40; // 0b01000000 +const int kExtension_Mask = 0x40; // 0b01000000 + +const int kPrefix_For_16_Bits = 0x66; +const int kPrefix_For_2_Byte = 0x0f; // 0b00001111 + +/*-------------------------------------------------------------------------------- +Opcode Information +*/ +struct x86OpcodeInfo +{ + uint8 oiBaseOpcode; // generally the opcode, but can have additional info + uint8 oiOpcodeInformation; // additional info about opcode + char* oiText; // string for fake disassembly +}; + +extern x86OpcodeInfo iaInfo[]; +enum x86ImmediateArithType +{ + iaAddImm, + iaCmpImm, + iaJmp, + iaPushImm, + iaAndImm, + iaOrImm, + iaXorImm +}; + +extern x86OpcodeInfo eInfo[]; +enum x86ExtendedType +{ + eIDiv, + eDiv, + eMul, + eMoveImm, + ePush, + eSarImm, + eShrImm, + eShlImm, + eSar1, + eShr1, + eShl1, + eSarCl, + eShrCl, + eShlCl, + eNeg +}; + +extern x86OpcodeInfo ceInfo[]; +enum x86CondensableExtendedType +{ + ceInc, + ceDec, + ceMoveImm, + cePop +}; + +extern x86OpcodeInfo srmInfo[]; +enum x86SpecialRegMemType +{ + srmCmpImm0, + srm1NOTUSED, + srmMoveImm0, + srm3NOTUSED +}; + +//================================================================================ +// Class Declarations + +/*-------------------------------------------------------------------------------- +x86Opcode -- encodes x86StandardType + +Basic opcode + - 8 or 16 bits + - no toggable bits and + - does NOT have a register field opcode extension or alternate encoding. +*/ +class x86Opcode +{ +public: + virtual void opPrintPretty(LogModuleObject &f) { UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("%-9s", opInfo->oiText)); } + virtual uint8 opSize() { return( (opInfo->oiOpcodeInformation >> 7) + 1); } + virtual void opFormatToMemory(void* inStart, x86ArgumentList& /*inAL*/, x86ArgListInstruction& /*inInsn*/); + + virtual bool opHasRegFieldExtension( x86ArgumentList& /*inAL*/, x86ArgListInstruction& /*inInsn*/ ) { return (false); } + virtual uint8 opGetRegFieldExtension() { assert(false); return 0; } + + virtual bool opRegOperandCanBeCondensed() { return false; } + + virtual void opReverseOperands() { assert(false); } + + virtual void opSwitchToRegisterIndirect() { } + + virtual bool opCanAccept1ByteImmediate() { assert(false); return false; } + virtual bool opCanAccept4ByteImmediate() { assert(false); return false; } + +protected: + x86Opcode() {} + x86Opcode( x86ImmediateArithType inType ) { opInfo = &(iaInfo[inType]); } + x86Opcode( x86ExtendedType inType ) { opInfo = &(eInfo[inType]); } + x86Opcode( x86CondensableExtendedType inType ) { opInfo = &(ceInfo[inType]); } + x86Opcode( x86SpecialRegMemType inType ) { opInfo = &(srmInfo[inType]); } + x86OpcodeInfo* opInfo; +}; + +inline void x86Opcode:: +opFormatToMemory(void* inStart, x86ArgumentList& /*inAL*/, x86ArgListInstruction& /*inInsn*/) +{ + uint8* start = (uint8*) inStart; + if(opInfo->oiOpcodeInformation & kIs_2_Byte_Mask) + *start++ = kPrefix_For_2_Byte; + *start = opInfo->oiBaseOpcode; +} + +/*-------------------------------------------------------------------------------- +x86Opcode_Reg -- encodes x86EntendedType + + - no switchable bits + - three bit opcode extension (stored in the REG field of the MODR/M byte) +*/ +class x86Opcode_Reg : + public virtual x86Opcode +{ +public: + x86Opcode_Reg ( x86ExtendedType inInfo ) : x86Opcode(inInfo) { } + + virtual bool opHasRegFieldExtension( x86ArgumentList& /*inAL*/, x86ArgListInstruction& /*inInsn*/ ) { return true; } + virtual uint8 opGetRegFieldExtension() { return (kRegfield_Mask & opInfo->oiOpcodeInformation); } + + virtual bool opCanAccept1ByteImmediate() { return ((0x02 & opInfo->oiOpcodeInformation) == 0x02); } + virtual bool opCanAccept4ByteImmediate() { return ((0x01 & opInfo->oiOpcodeInformation) == 0x01); } + +protected: + x86Opcode_Reg() { } +}; + +/*-------------------------------------------------------------------------------- +x86Opcode_Condensable_Reg -- encodes x86CondensableExtendedType + + - no switchable bits + - three bit opcode extension (stored in the REG field of the MODR/M byte) + - alternate encoding which has a 5-bit opcode + 3-bit register operand +*/ +class x86Opcode_Condensable_Reg : + public x86Opcode +{ +public: + x86Opcode_Condensable_Reg ( x86CondensableExtendedType inInfo ) : x86Opcode(inInfo) { } + + virtual bool opHasRegFieldExtension( x86ArgumentList& inAL, x86ArgListInstruction& inInsn ); + virtual uint8 opGetRegFieldExtension() { return ((0x03 & opInfo->oiOpcodeInformation) << 3); } + + virtual bool opCanAccept1ByteImmediate() { return false; } + virtual bool opCanAccept4ByteImmediate() { return true; } + + virtual bool opRegOperandCanBeCondensed(){ return true; } + + virtual uint8 opSize() { return 1; } + virtual void opFormatToMemory(void* inStart, x86ArgumentList& inAL, x86ArgListInstruction& inInsn); +}; + +/*-------------------------------------------------------------------------------- +x86Opcode_ImmArith -- encodes x86ImmediateArithType + + - must have sign/size bit which specifies 8 or 32 bits operand + - _possible_ three bit opcode extension (stored in the REG field of the MODR/M byte) +*/ +class x86Opcode_ImmArith : + public x86Opcode +{ +public: + x86Opcode_ImmArith( x86ImmediateArithType inInfo ) : x86Opcode( inInfo ) { } + virtual void opFormatToMemory( void* inStart, x86ArgumentList& /*inAL*/, x86ArgListInstruction& /*inInsn*/); + + virtual bool opHasRegFieldExtension( x86ArgumentList& /*inAL*/, x86ArgListInstruction& /*inInsn*/ ) + { return (bool)((opInfo->oiOpcodeInformation >> 6) && 1); } + virtual uint8 opGetRegFieldExtension() + { assert(kExtension_Mask & opInfo->oiOpcodeInformation); return (kRegfield_Mask & opInfo->oiOpcodeInformation); } + virtual bool opCanAccept1ByteImmediate() { return true; } + virtual bool opCanAccept4ByteImmediate() { return true; } + + virtual void opSwitchToRegisterIndirect() { } // FIX can't do this for imul ??? + +protected: + x86Opcode_ImmArith() { } +}; + +/*-------------------------------------------------------------------------------- +x86Opcode_SpecialRegMem -- x86SpecialRegMemType + + - switches between + x86Opcode_Reg when operand is a memory argument, and + x86Opcode when operand is a register argument +*/ +class x86Opcode_SpecialRegMem : + public x86Opcode_Reg // note not x86Opcode! +{ +public: + x86Opcode_SpecialRegMem( x86SpecialRegMemType inType) : + x86Opcode(inType) { } + + virtual bool opHasRegFieldExtension( x86ArgumentList& /*inAL*/, x86ArgListInstruction& /*inInsn*/ ) + { + return((kIs_Memory_Form_Mask & opInfo->oiOpcodeInformation) == kIs_Memory_Form_Mask); + } + + virtual uint8 opGetRegFieldExtension() + { + assert(kIs_Memory_Form_Mask & opInfo->oiOpcodeInformation); + return (kRegfield_Mask & opInfo->oiOpcodeInformation); + } + + virtual void opSwitchToRegisterIndirect() + { + assert(!(kIs_Memory_Form_Mask & opInfo->oiOpcodeInformation)); + opInfo++; + } +}; + +#endif // _X86OPCODE diff --git a/ef/Compiler/CodeGenerator/md/x86/x86StdCall.cpp b/ef/Compiler/CodeGenerator/md/x86/x86StdCall.cpp new file mode 100644 index 000000000000..2fe78b3cded0 --- /dev/null +++ b/ef/Compiler/CodeGenerator/md/x86/x86StdCall.cpp @@ -0,0 +1,250 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +// +// x86StdCall.cpp - StdCall calling convention +// + +#include "x86StdCall.h" +#include "x86Win32Emitter.h" + +// Utility function to push one function-call argument on the stack +void +pushCallArg(DataConsumer& argument, DataNode* usesNode, InstructionDefine*& orderingDependency, Pool& inPool, x86Win32Emitter& inEmitter) +{ + // Do the first argument specially because that sets up the chain of ordering dependencies + int numOrderingUses = orderingDependency ? 1 : 0; + + // If pushing constant arguments, use the immediate form of the push instruction + if (argument.getVariable().getCategory() == pcConst) { + switch (argument.getKind()) { + + // 32-bit constants + case vkInt: + case vkAddr: + case vkFloat: + { + Uint32 constant = PrimConst::cast(argument.getVariable()).value.i; + x86Instruction& pushInsn = *new(inPool) x86Instruction(usesNode, inPool, iaPushImm, constant, atImmediateOnly, numOrderingUses, 1); + + // First arg is handled differently + if (orderingDependency) { + inEmitter.useTemporaryOrder(pushInsn, *orderingDependency, 0); + inEmitter.redefineTemporaryOrder(pushInsn, *orderingDependency, 0); + } else { + orderingDependency = &inEmitter.defineTemporaryOrder(pushInsn, 0); + } + } + break; + + // 64-bit constants require two immediate-form push instructions + case vkDouble: + case vkLong: + { + Int64 constant = PrimConst::cast(argument.getVariable()).value.l; + Int32 low = (Int32)((Uint64)constant & 0xFFFFFFFF); + Int32 high = (Int32)((Uint64)constant >> 32); + + x86Instruction& pushInsnHi = *new(inPool) x86Instruction(usesNode, inPool, iaPushImm, high, atImmediateOnly, numOrderingUses, 1); + + // First arg is handled differently + if (orderingDependency) { + inEmitter.useTemporaryOrder(pushInsnHi, *orderingDependency, 0); + inEmitter.redefineTemporaryOrder(pushInsnHi, *orderingDependency, 0); + } else { + orderingDependency = &inEmitter.defineTemporaryOrder(pushInsnHi, 0); + } + + x86Instruction& pushInsnLo = *new(inPool) x86Instruction(usesNode, inPool, iaPushImm, low, atImmediateOnly, 1, 1); + inEmitter.useTemporaryOrder(pushInsnLo, *orderingDependency, 0); + inEmitter.redefineTemporaryOrder(pushInsnLo, *orderingDependency, 0); + } + break; + + default: + assert(0); + } + return; + } + + // Push non-constant function call argument + switch (argument.getKind()) { + + case vkInt: + case vkAddr: + { + x86Instruction& storeParam = *new(inPool) x86Instruction(usesNode, inPool, ePush, atRegDirect, 1 + numOrderingUses, 1); + inEmitter.useProducer(argument.getVariable(), storeParam, 0); + + // First arg is handled differently + if (orderingDependency) { + inEmitter.useTemporaryOrder(storeParam, *orderingDependency, 1); + inEmitter.redefineTemporaryOrder(storeParam, *orderingDependency, 0); + } else { + orderingDependency = &inEmitter.defineTemporaryOrder(storeParam, 0); + } + } + break; + + case vkFloat: + { + InsnDoubleOpDir& copyParamInsn = *new(inPool) InsnDoubleOpDir(usesNode, inPool, raCopyI, atRegAllocStackSlot, atRegDirect, 1, 1); + inEmitter.useProducer(argument.getVariable(), copyParamInsn, 0, vrcStackSlot); + VirtualRegister& vr = inEmitter.defineTemporary(copyParamInsn, 0); + + x86Instruction& storeParamInsn = *new(inPool) x86Instruction(usesNode, inPool, ePush, atRegDirect, 1 + numOrderingUses, 1); + inEmitter.useTemporaryVR(storeParamInsn, vr, 0); + + // First arg is handled differently + if (orderingDependency) { + inEmitter.useTemporaryOrder(storeParamInsn, *orderingDependency, 1); + inEmitter.redefineTemporaryOrder(storeParamInsn, *orderingDependency, 0); + } else { + orderingDependency = &inEmitter.defineTemporaryOrder(storeParamInsn, 0); + } + } + break; + + case vkDouble: + { + // Push high 32-bits of double + InsnDoubleOpDir& copyParamInsnHi = *new(inPool) InsnDoubleOpDir(usesNode, inPool, raCopyI, atRegAllocStackSlotHi32, atRegDirect, 1, 2); + inEmitter.useProducer(argument.getVariable(), copyParamInsnHi, 0, vrcStackSlot); + VirtualRegister& vrHi = inEmitter.defineTemporary(copyParamInsnHi, 0); + + x86Instruction& storeParamInsnHi = *new(inPool) x86Instruction(usesNode, inPool, ePush, atRegDirect, 1 + numOrderingUses, 1); + inEmitter.useTemporaryVR(storeParamInsnHi, vrHi, 0); + + // First arg is handled differently + if (orderingDependency) { + inEmitter.useTemporaryOrder(storeParamInsnHi, *orderingDependency, 1); + inEmitter.redefineTemporaryOrder(storeParamInsnHi, *orderingDependency, 0); + } else { + orderingDependency = &inEmitter.defineTemporaryOrder(storeParamInsnHi, 0); + } + + // Push low 32-bits of double + InsnDoubleOpDir& copyParamInsnLo = *new(inPool) InsnDoubleOpDir(usesNode, inPool, raCopyI, atRegAllocStackSlot, atRegDirect, 1, 2); + inEmitter.useProducer(argument.getVariable(), copyParamInsnLo, 0, vrcStackSlot); + VirtualRegister& vrLo = inEmitter.defineTemporary(copyParamInsnLo, 0); + + x86Instruction& storeParamInsnLo = *new(inPool) x86Instruction(usesNode, inPool, ePush, atRegDirect, 2, 1); + inEmitter.useTemporaryVR(storeParamInsnLo, vrLo, 0); + inEmitter.useTemporaryOrder(storeParamInsnLo, *orderingDependency, 1); + inEmitter.redefineTemporaryOrder(storeParamInsnLo, *orderingDependency, 0); + } + break; + + case vkLong: + { + x86Instruction& storeParamHigh = *new(inPool) x86Instruction(usesNode, inPool, ePush, atRegDirect, 1 + numOrderingUses, 1); + inEmitter.useProducer(argument.getVariable(), storeParamHigh, 0, vrcInteger, vidHigh); + + // First arg is handled differently + if (orderingDependency) { + inEmitter.useTemporaryOrder(storeParamHigh, *orderingDependency, 1); + inEmitter.redefineTemporaryOrder(storeParamHigh, *orderingDependency, 0); + } else { + orderingDependency = &inEmitter.defineTemporaryOrder(storeParamHigh, 0); + } + + x86Instruction& storeParamLow = *new(inPool) x86Instruction(usesNode, inPool, ePush, atRegDirect, 2, 1); + inEmitter.useProducer(argument.getVariable(), storeParamLow, 0, vrcInteger, vidLow); + inEmitter.useTemporaryOrder(storeParamLow, *orderingDependency, 1); + inEmitter.redefineTemporaryOrder(storeParamLow, *orderingDependency, 0); + } + break; + + default: + assert(false); + } +} + + +void x86Win32Emitter:: +emitArguments(ControlNode::BeginExtra& inBeginNode) +{ + if (inBeginNode.nArguments == 0) + return; + + InsnExternalDefine& defineInsn = *new(mPool) InsnExternalDefine(&inBeginNode[0], mPool, inBeginNode.nArguments * 2); + + // do appropriate loads for each argument + Uint32 curStackOffset = 8; + + Uint8 curIndex = 0; // Index into defineInsn + unsigned int curArgument; + for (curArgument = 0; curArgument < inBeginNode.nArguments; curArgument++) + { + PrimArg& curArg = inBeginNode[curArgument]; + + switch (curArg.getOperation()) + { + case poArg_I: + case poArg_A: + if (curArg.hasConsumers()) + { + + InsnDoubleOpDir& loadParam = *new(mPool) InsnDoubleOpDir(&curArg, mPool, raLoadI, curStackOffset, atStackOffset, atRegDirect, 1, 1); + useTemporaryOrder(loadParam, defineTemporaryOrder(defineInsn, curIndex), 0); + defineProducer(curArg, loadParam, 0); + } + curIndex++; + curStackOffset += 4; + break; + + case poArg_F: + if (curArg.hasConsumers()) + emit_ArgF(curArg, defineTemporaryOrder(defineInsn, curIndex), curStackOffset); + curIndex++; + curStackOffset += 4; + break; + + case poArg_L: + if (curArg.hasConsumers()) + { + InsnDoubleOpDir& loadHi = *new(mPool) InsnDoubleOpDir(&curArg, mPool, raLoadI, curStackOffset + 4, atStackOffset, atRegDirect, 1, 1); + InsnDoubleOpDir& loadLo = *new(mPool) InsnDoubleOpDir(&curArg, mPool, raLoadI, curStackOffset, atStackOffset, atRegDirect, 1, 1); + useTemporaryOrder(loadLo, defineTemporaryOrder(defineInsn, curIndex), 0); + useTemporaryOrder(loadHi, defineTemporaryOrder(defineInsn, curIndex + 1), 0); + defineProducer(curArg, loadLo, 0, vrcInteger, vidLow); + defineProducer(curArg, loadHi, 0, vrcInteger, vidHigh); + } + curIndex += 2; + curStackOffset += 8; + break; + + case poArg_D: + if (curArg.hasConsumers()) + emit_ArgD(curArg, defineTemporaryOrder(defineInsn, curIndex), curStackOffset); + curIndex++; + curStackOffset += 8; + break; + + default: + assert(false); + } + } + + // continue counting from before + // make all the rest of the defines as type none + for (;curIndex < inBeginNode.nArguments * 2; curIndex++) + { + defineInsn.getInstructionDefineBegin()[curIndex].kind = udNone; + } +} + diff --git a/ef/Compiler/CodeGenerator/md/x86/x86StdCall.h b/ef/Compiler/CodeGenerator/md/x86/x86StdCall.h new file mode 100644 index 000000000000..0caf73e7aa92 --- /dev/null +++ b/ef/Compiler/CodeGenerator/md/x86/x86StdCall.h @@ -0,0 +1,206 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +// +// x86StdCall.h - StdCall calling convention +// + +#include "x86Win32Instruction.h" + +// Utility function to push one function-call argument on the stack +void pushCallArg(DataConsumer &curArgument, DataNode* usesNode, InstructionDefine*& orderingDependency, Pool& inPool, x86Win32Emitter& inEmitter); + +// -> mem regarg1 regarg2 regarg3 regarg3 +// <- mem [returnval] + + +// inHasReturnValue is deprecated, and is ignored +template +Call:: +Call( DataNode* inDataNode, + Pool& inPool, + Uint8 inRegisterArguments, + bool /*inHasReturnValue*/, + x86Win32Emitter& inEmitter, + void (*inFunc)(), + DataNode* inUseDataNode) : + InsnUseXDefineYFromPool(inDataNode, inPool, ((inRegisterArguments != 0) ? 1 : 0) + tHasIncomingStore + tIsDynamic, 3) + // add extra use for ordering edge (see below) if more than one argument +{ + DataNode* returnValProducer; // node whose outgoing edge is the return value + + if (inDataNode->hasKind(vkTuple)) + { + // if called with a Primitive with kind vkTuple, we know we will have to deal with a projection edge + const DoublyLinkedList& projectionConsumers = inDataNode->getConsumers(); + DoublyLinkedList::iterator curProjectionEdge = projectionConsumers.begin(); + + // grab the outgoing store (if there is one) + // set up returnValProducer to point to the return value producer (if it exists) + // one of the two consumers of the projection node must be the memory node, the other must be the Return value node + if (tHasOutgoingStore) + { + DataNode& projectionA = projectionConsumers.get(curProjectionEdge).getNode(); + DataNode* projectionB = (projectionConsumers.done(curProjectionEdge = projectionConsumers.advance(curProjectionEdge))) ? 0 : &projectionConsumers.get(curProjectionEdge).getNode(); + + if (projectionA.hasKind(vkMemory)) + { + inEmitter.defineProducer(projectionA, *this, 0); // -> mem + returnValProducer = projectionB; + } + else + { + assert(projectionB); // projectionB must be the memory producer + inEmitter.defineProducer(*projectionB, *this, 0); // -> mem + returnValProducer = &projectionA; + } + } + else + returnValProducer = (projectionConsumers.done(curProjectionEdge = projectionConsumers.advance(curProjectionEdge))) ? 0 : &projectionConsumers.get(curProjectionEdge).getNode(); + } + else + { + // non-call Primitive treated as an out-of-line call + assert(!tHasFunctionAddress && !tIsDynamic); + + // since outgoing stores are handled separately and are not + // a real return type, we make the return value code ignore + // them + if (tHasOutgoingStore) + { + assert(inDataNode->hasKind(vkMemory)); + inEmitter.defineProducer(*inDataNode, *this, 0); //-> mem + returnValProducer = NULL; + } + else + returnValProducer = inDataNode; + } + + // pre-color (and buffer) the return value + if (returnValProducer) + { + switch (returnValProducer->getKind()) + { + case vkInt: + case vkAddr: + { + VirtualRegister* returnValVR; + + // the Call defines a temporary register, which is precolored to + // the appropriate return register + returnValVR = &inEmitter.defineTemporary(*this, 1); + returnValVR->preColorRegister(x86GPRToColor[EAX]); + + // now create a "buffer" copy between the precolored return register + // and make the Copy define the return value edge from the poCall + InsnDoubleOpDir& copyInsn = newCopyInstruction(*inDataNode, inPool); + inEmitter.useTemporaryVR(copyInsn, *returnValVR, 0); + inEmitter.defineProducer(*returnValProducer, copyInsn, 0); + // fiX-ME none-out unused return value argument + break; + } + + case vkLong: + { + // results returned in eax (low) and edx (high) + VirtualRegister* lowVR; + VirtualRegister* highVR; + + lowVR = &inEmitter.defineTemporary(*this, 1); + highVR = &inEmitter.defineTemporary(*this, 2); + lowVR->preColorRegister(x86GPRToColor[EAX]); + highVR->preColorRegister(x86GPRToColor[EDX]); + + InsnDoubleOpDir& copyHiInsn = newCopyInstruction(*inDataNode, inPool); + inEmitter.useTemporaryVR(copyHiInsn, *highVR, 0); + inEmitter.defineProducer(*returnValProducer, copyHiInsn, 0, vrcInteger, vidHigh); + + InsnDoubleOpDir& copyLowInsn = newCopyInstruction(*inDataNode, inPool); + inEmitter.useTemporaryVR(copyLowInsn, *lowVR, 0); + inEmitter.defineProducer(*returnValProducer, copyLowInsn, 0, vrcInteger, vidLow); + } + break; + + case vkFloat: + inEmitter.emit_CallReturnF(*this, *inDataNode, *returnValProducer); + break; + + case vkDouble: + inEmitter.emit_CallReturnD(*this, *inDataNode, *returnValProducer); + break; + + default: + assert(false); + break; + } + } + else if (!tHasOutgoingStore) + inDataNode->setInstructionRoot(this); // if no outgoing edges (no return value or memory edge, we need to hook this on) + + DataConsumer* firstArgument; + DataConsumer* curArgument; + + // uses may begin at some passed in node, instead of the node from which the call originates + DataNode* usesNode = (inUseDataNode) ? inUseDataNode : inDataNode; + + // incoming store + if (tHasIncomingStore) + inEmitter.useProducer(usesNode->nthInputVariable(0), *this, tIsDynamic + (inRegisterArguments > 0)); // -> mem + + firstArgument = usesNode->getInputsBegin() + tHasFunctionAddress + tHasIncomingStore; + + // grab the callee address (it might not be a static call) + if (tHasFunctionAddress) + { + assert(inFunc == NULL); // programmer error to specify a function address if this Call has a function address + if (tIsDynamic) + inEmitter.useProducer(usesNode->nthInputVariable(1), *this, 0); // -> incoming address + else + mCalleeAddress = (Uint32) nthInputConstantUint32(*usesNode, 1); + } + else + mCalleeAddress = (Uint32) inFunc; + + // start at last argument and push arguments from right to left + + curArgument = usesNode->getInputsEnd() - 1; // arguments array is last + 1 + + // BASIC IDEA: + // + // We are creating a bunch of pushes followed by a call instruction + // Since pushes are clearly ordered operations we need an edge to maintain that ordering. + // We use an order edge defined by the first push, and which is used and by each + // subsequent push. This ends in a use by the Call (*this). + // + // In the end we will have somethinglike Call -> Arg0 -> Arg1 -> ... -> ArgN-1 -> ArgN + // where Call is the call instruction and the Arg's are pushes. + // + // The scheduler will walk up the use chain and do the last arg first and then come + // back down the chain. + InstructionDefine* orderingDependency = NULL; // maintains "thread" to order the pushes of the arguments + + if(curArgument >= firstArgument) + { + // Generate pushes for the arguments. Order them with Order Edges. + // Note x86 arguments are pushed on the stack from right to left. + for (; curArgument >= firstArgument; curArgument--) + pushCallArg(*curArgument, usesNode, orderingDependency, inPool, inEmitter); + + // this is the final order edge which is attached to the Call instruction + inEmitter.useTemporaryOrder(*this, *orderingDependency, tIsDynamic); + } +} diff --git a/ef/Compiler/CodeGenerator/md/x86/x86Win32Cpu.h b/ef/Compiler/CodeGenerator/md/x86/x86Win32Cpu.h new file mode 100644 index 000000000000..221a84ec477d --- /dev/null +++ b/ef/Compiler/CodeGenerator/md/x86/x86Win32Cpu.h @@ -0,0 +1,49 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#if !defined(_X86WIN32_CPU_H_) || defined(INCLUDE_EMITTER) +#define _X86WIN32_CPU_H_ + +#define FIRST_CALLEE_SAVED_GR 4 +#define LAST_CALLEE_SAVED_GR 6 +#define FIRST_CALLER_SAVED_GR 0 +#define LAST_CALLER_SAVED_GR 3 +#define FIRST_CALLEE_SAVED_FPR 0 +#define LAST_CALLEE_SAVED_FPR -1 +#define FIRST_CALLER_SAVED_FPR 0 +#define LAST_CALLER_SAVED_FPR -1 + +#define FIRST_GREGISTER 0 +#define LAST_GREGISTER 5 +#define FIRST_FPREGISTER 0 +#define LAST_FPREGISTER -1 +#define NUMBER_OF_SPECIAL_REGISTERS 0 + +class x86Win32Emitter; +class x86Formatter; +typedef x86Formatter MdFormatter; +typedef x86Win32Emitter MdEmitter; + +#ifdef INCLUDE_EMITTER +#include "x86Win32Emitter.h" +#include "x86Formatter.h" +#endif + +#define CPU_IS_SUPPORTED + +#endif /* _X86WIN32_CPU_H_ */ diff --git a/ef/Compiler/CodeGenerator/md/x86/x86Win32Emitter.cpp b/ef/Compiler/CodeGenerator/md/x86/x86Win32Emitter.cpp new file mode 100644 index 000000000000..2d16e2ba6226 --- /dev/null +++ b/ef/Compiler/CodeGenerator/md/x86/x86Win32Emitter.cpp @@ -0,0 +1,1582 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +// +// File: x86Win32Emitter.cpp +// +// Authors: Peter DeSantis +// Simon Holmes a Court +// + +// Temporary +// Some CL args I use: +// -sys javasoft/sqe/tests/api/java/lang/Boolean/BooleanTests1 +// -stage i -method insertElementAt (Ljava/lang/Object;I)V java/util/Vector +// -stage -noinvoke i -method cmpLongTestHarnessHelper (JJ)I TinyClass +// -l Output -l Package TinyClass +// -breakCompile TinyClass Sieve ([I)V -html -log x86ArgList 4 -log x86Emitter 4 -log x86Spill 4 -log FieldOrMethod 4 -l Package -sys TinyClass +// -sys -html -log x86Emitter 4 -log FieldOrMethod 4 -ta -be java.lang.String startsWith (Ljava/lang/String;I)Z TinyClass +// -sys -html -be suntest.quicktest.runtime.QuickTest assert (ZLjava/lang/String;)V javasoft/sqe/tests/api/java/lang/Integer/IntegerTests32 + +#include "x86Win32Emitter.h" +#include "x86Win32Instruction.h" +#include "x86StdCall.h" +#include "Primitives.h" +#include "SysCalls.h" +#include "x86SysCallsRuntime.h" +#include "JavaObject.h" + +#include "x86-win32.nad.burg.h" +#include "ControlNodes.h" + +#include "x86Win32Instruction.h" + +#include "x86Win32ExceptionHandler.h" + +UT_DEFINE_LOG_MODULE(x86Emitter); + +//----------------------------------------------------------------------------------------------------------- +// Debugging + + +#ifdef DEBUG_LOG_VERBOSE +// for rule printing + extern char* burm_string[]; + extern int burm_max_rule; +#endif + +//----------------------------------------------------------------------------------------------------------- +// Emitter + +// Structures/Enums + +x86ArgumentType memDSIAddressingModes[] = +{ + atBaseIndexed, + atScaledIndexedBy2, + atScaledIndexedBy4, + atScaledIndexedBy8 +}; + +struct x86CondList +{ + x86ConditionCode ccSigned; + x86ConditionCode ccUnsigned; +}; + +x86CondList condList[] = +{ + // signed, unsigned + { ccJL, ccJB }, // cLt + { ccJE, ccJE }, // cEq + { ccJLE, ccJBE }, // cLe + { ccJNLE, ccJNBE }, // cGt + { ccJNE, ccJNE }, // cLgt + { ccJNL, ccJNB }, // cGe +}; + +//----------------------------------------------------------------------------------------------------------- +void x86Win32Emitter:: +emitPrimitive(Primitive& inPrimitive, NamedRule inRule) +{ +#ifdef DEBUG_LOG_VERBOSE // very noisy + char* ruleName; + if(inRule < burm_max_rule && (ruleName = burm_string[inRule]) != 0) + printf("[%3d] %-50s ", inRule, ruleName); + else + printf("[%3d] %-50s ", inRule, NULL); +#endif + + // case statement corresponding to rules in the grammar + switch (inRule) + { + //----------------------------------------------------------------------- + // General + case emConst_I: emit_LoadConstant_I(inPrimitive); break; + case emConst_A: emit_LoadAddress(inPrimitive); break; + case emConst_L: emit_LoadConstant_L(inPrimitive); break; + case emConst_F: emit_LoadConstant_F(inPrimitive); break; + case emConst_D: emit_LoadConstant_D(inPrimitive); break; + + case emResult_I: emit_Result_I(inPrimitive); break; + case emResult_A: emit_Result_I(inPrimitive); break; + case emResult_L: emit_Result_L(inPrimitive); break; + case emResult_F: emit_Result_F(inPrimitive); break; + case emResult_D: emit_Result_D(inPrimitive); break; + + case emBreak: emit_Break(inPrimitive); break; + + //----------------------------------------------------------------------- + // Control Flow + case emIfLt: emit_B(inPrimitive, rawLt); break; + case emIfEq: emit_B(inPrimitive, rawEq); break; + case emIfLe: emit_B(inPrimitive, rawLe); break; + case emIfGt: emit_B(inPrimitive, rawGt); break; + case emIfLgt: emit_B(inPrimitive, rawLgt); break; + case emIfGe: emit_B(inPrimitive, rawGe); break; + + case emIfULt: emit_B(inPrimitive, rawLt); break; + case emIfUEq: emit_B(inPrimitive, rawEq); break; + case emIfULe: emit_B(inPrimitive, rawLe); break; + case emIfUGt: emit_B(inPrimitive, rawGt); break; + case emIfNe: emit_B(inPrimitive, rawLgt); break; + case emIfUGe: emit_B(inPrimitive, rawGe); break; + + //----------------------------------------------------------------------- + // Booleans + case emLt_I: emit_Cond(inPrimitive, rawLt); break; + case emEq_I: emit_Cond(inPrimitive, rawEq); break; + case emLe_I: emit_Cond(inPrimitive, rawLe); break; + case emGt_I: emit_Cond(inPrimitive, rawGt); break; + case emLgt_I: emit_Cond(inPrimitive, rawLgt); break; + case emGe_I: emit_Cond(inPrimitive, rawGe); break; + + case emULt_I: emit_Cond(inPrimitive, rawLt); break; + case emUEq_I: emit_Cond(inPrimitive, rawEq); break; + case emULe_I: emit_Cond(inPrimitive, rawLe); break; + case emUGt_I: emit_Cond(inPrimitive, rawGt); break; + case emNe_I: emit_Cond(inPrimitive, rawLgt); break; + case emUGe_I: emit_Cond(inPrimitive, rawGe); break; + + //----------------------------------------------------------------------- + // Switch + case emSwitch: emit_Switch(inPrimitive); break; + + //----------------------------------------------------------------------- + // Scalar and Aritmetic Logic + + // And + case emAnd_I: emit_And_I(inPrimitive); break; + case emAndI_I: emit_AndI_I(inPrimitive); break; + + case emAnd_L: emit_And_L(inPrimitive); break; + + // Or + case emOr_I: emit_Or_I(inPrimitive); break; + case emOrI_I: emit_OrI_I(inPrimitive); break; + case emOr_L: emit_Or_L(inPrimitive); break; + + // Xor + case emXor_I: emit_Xor_I(inPrimitive); break; + case emXorI_I: emit_XorI_I(inPrimitive); break; + + case emXor_L: emit_Xor_L(inPrimitive); break; + + // Add + case emAdd_I: emit_Add_I(inPrimitive); break; + case emAdd_A: emit_Add_I(inPrimitive); break; + + case emAddI_I: emit_AddI_I(inPrimitive); break; + case emAddI_A: emit_AddI_I(inPrimitive); break; + + case emAdd_L: emit_Add_L(inPrimitive); break; + + // Sub + case emSub_I: emit_Sub_I(inPrimitive); break; + case emSub_A: emit_Sub_I(inPrimitive); break; + + case emSub_L: emit_Sub_L(inPrimitive); break; + case emSubR_I: emit_SubR_I(inPrimitive); break; + + // Mul + case emMul_I: emit_Mul_I(inPrimitive); break; + case emMul_L: emit_Mul_L(inPrimitive); break; + + // Div + case emDiv_I: emit_Div_I(inPrimitive); break; + case emDivE_I: emit_Div_I(inPrimitive); break; + + case emDiv_I_MemDSI: emit_Div_I_MemDSI(inPrimitive); break; + case emDivE_I_MemDSI: emit_Div_I_MemDSI(inPrimitive); break; + + case emDivU_I: emit_DivU_I(inPrimitive); break; + case emDivUE_I: emit_DivU_I(inPrimitive); break; + + case emDivU_I_MemDSI: emit_DivU_I_MemDSI(inPrimitive); break; + case emDivUE_I_MemDSI: emit_DivU_I_MemDSI(inPrimitive); break; + + case emDiv_L: emit_Div_L(inPrimitive); break; + case emDivE_L: emit_Div_L(inPrimitive); break; + + // Mod + case emMod_I: emit_Mod_I(inPrimitive); break; + case emModE_I: emit_Mod_I(inPrimitive); break; + + case emMod_I_MemDSI: emit_Mod_I_MemDSI(inPrimitive); break; + case emModE_I_MemDSI: emit_Mod_I_MemDSI(inPrimitive); break; + + case emModU_I: emit_ModU_I(inPrimitive); break; + case emModUE_I: emit_ModU_I(inPrimitive); break; + + case emModU_I_MemDSI: emit_ModU_I_MemDSI(inPrimitive); break; + case emModUE_I_MemDSI: emit_ModU_I_MemDSI(inPrimitive); break; + + case emMod_L: emit_Mod_L(inPrimitive); break; + case emModE_L: emit_Mod_L(inPrimitive); break; + + // Shift + case emShl_I: emit_Shl_I(inPrimitive); break; + case emShlI_I: emit_ShlI_I(inPrimitive); break; + + case emShr_I: emit_Sar_I(inPrimitive); break; + case emShrI_I: emit_SarI_I(inPrimitive); break; + + case emShrU_I: emit_Shr_I(inPrimitive); break; + case emShrUI_I: emit_ShrI_I(inPrimitive); break; + + case emShl_L: emit_Shl_L(inPrimitive); break; + case emShr_L: emit_Sar_L(inPrimitive); break; + case emShrU_L: emit_Shr_L(inPrimitive); break; + + // Sign Extend + case emExt_I: emit_Ext_I(inPrimitive); break; + case emExt_L: emit_Ext_L(inPrimitive); break; + + //----------------------------------------------------------------------- + // Floating Point Arithmetic + + case emFAdd_D: emit_FAdd_D(inPrimitive); break; + case emFAdd_F: emit_FAdd_F(inPrimitive); break; + + case emFMul_D: emit_FMul_D(inPrimitive); break; + case emFMul_F: emit_FMul_F(inPrimitive); break; + + case emFSub_D: emit_FSub_D(inPrimitive); break; + case emFSub_F: emit_FSub_F(inPrimitive); break; + + case emFDiv_D: emit_FDiv_D(inPrimitive); break; + case emFDiv_F: emit_FDiv_F(inPrimitive); break; + + case emFRem_D: emit_FRem_D(inPrimitive); break; + case emFRem_F: emit_FRem_F(inPrimitive); break; + + //----------------------------------------------------------------------- + // Integer conversion + case emConvI_L: emit_ConvI_L(inPrimitive); break; + case emConvL_I: emit_ConvL_I(inPrimitive); break; + + //----------------------------------------------------------------------- + // Float conversion + case emFConvI_F: + case emFConvI_D: + case emFConvL_F: + case emFConvL_D: + case emFConvF_I: + case emFConvF_L: + case emFConvF_D: + case emFConvD_I: + case emFConvD_L: + case emFConvD_F: emit_FConv(inPrimitive); break; + + //----------------------------------------------------------------------- + // Comparison + case emCmp_I: emit_Cmp_I(inPrimitive); break; + case emCmpU_I: emit_Cmp_I(inPrimitive); break; + case emCmpU_A: emit_Cmp_I(inPrimitive); break; + + case emCmpI_I: emit_CmpI_I(inPrimitive); break; + case emCmpUI_I: emit_CmpI_I(inPrimitive); break; + + case emCmpI_I_MemDSI: emit_CmpI_I_MemDSI(inPrimitive); break; + case emCmp_I_MemDSI: emit_Cmp_I_MemDSI(inPrimitive); break; + + case em3wayCmpL_L: emit_3wayCmpL_L(inPrimitive); break; + case em3wayCmpCL_L: emit_3wayCmpCL_L(inPrimitive); break; + + case em3wayCmpF_L: emit_3wayCmpF_L(inPrimitive); break; + case em3wayCmpF_G: emit_3wayCmpF_G(inPrimitive); break; + case em3wayCmpD_L: emit_3wayCmpD_L(inPrimitive); break; + case em3wayCmpD_G: emit_3wayCmpD_G(inPrimitive); break; + + case em3wayCmpCF_L: emit_3wayCmpCF_L(inPrimitive); break; + case em3wayCmpCF_G: emit_3wayCmpCF_G(inPrimitive); break; + case em3wayCmpCD_L: emit_3wayCmpCD_L(inPrimitive); break; + case em3wayCmpCD_G: emit_3wayCmpCD_G(inPrimitive); break; + + //----------------------------------------------------------------------- + // Limit + case emLimitR: emit_LimitR(inPrimitive); break; + case emLimit: emit_Limit(inPrimitive); break; + case emLimitR_MemDisp: emit_LimitR_MemDisp(inPrimitive); break; + case emLimit_MemDisp: emit_Limit_MemDisp(inPrimitive); break; + + //----------------------------------------------------------------------- + // Cast + case emLimCast: emit_LimCast(inPrimitive); break; + case emChkCastI_A: emit_ChkCast_Const(inPrimitive); break; + case emChkCast_A: emit_ChkCast(inPrimitive); break; + case emChkCast_I: emit_ChkCast(inPrimitive); break; + + //----------------------------------------------------------------------- + // Memory + case emLd_I: genLd_I(inPrimitive); break; + case emLd_A: genLd_I(inPrimitive); break; + case emLd_L: emit_Ld_L(inPrimitive); break; + case emLd_F: emit_Ld_F(inPrimitive); break; + case emLd_D: emit_Ld_D(inPrimitive); break; + + + case emLd_I_MemDisp: emit_Ld_I_MemDisp(inPrimitive); break; + case emLd_I_MemDSI: emit_Ld_I_MemDSI(inPrimitive); break; + + case emLdS_B: emit_LdS_B(inPrimitive); break; + case emLdU_B: emit_LdU_B(inPrimitive); break; + case emLdS_H: emit_LdS_H(inPrimitive); break; + case emLdU_H: emit_LdU_H(inPrimitive); break; + + case emSt_I: emit_St_I(inPrimitive); break; + case emSt_A: emit_St_I(inPrimitive); break; + case emSt_L: emit_St_L(inPrimitive); break; + case emStI_I: emit_StI_I(inPrimitive); break; + + case emSt_B: emit_St_B(inPrimitive); break; + case emSt_H: emit_St_H(inPrimitive); break; + + case emStI_I_MemDisp: emit_StI_I_MemDisp(inPrimitive); break; + case emSt_I_MemDisp: emit_St_I_MemDisp(inPrimitive); break; + case emSt_I_MemDSI: emit_St_I_MemDSI(inPrimitive); break; + + case emSt_F: emit_St_F(inPrimitive); break; + case emSt_D: emit_St_D(inPrimitive); break; + +/* FIXME: Implement performance optimizations + + case emLd_F_MemDisp: + case emLd_F_MemDSI: + case emLd_D_MemDisp: + case emLd_D_MemDSI: assert(0); break; + + case emStI_F_MemDisp: + case emSt_F_MemDisp: + case emSt_F_MemDSI: + + case emStI_D_MemDisp: + case emSt_D_MemDisp: + case emSt_D_MemDSI: + assert(0); break; +*/ + + case emCatch: emit_Catch(inPrimitive); break; + + //----------------------------------------------------------------------- + // Calls + case emStaticCall: + { + new(mPool) Call_(&inPrimitive, mPool, Call_::numberOfArguments(inPrimitive), Call_::hasReturnValue(inPrimitive), *this); + break; + } + case emDynamicCall: + { + new(mPool) CallD_(&inPrimitive, mPool, CallD_::numberOfArguments(inPrimitive), CallD_::hasReturnValue(inPrimitive), *this); + break; + } + case emSysCall: case emSysCallE: + { + new(mPool) CallS_( &inPrimitive, mPool, CallS_::numberOfArguments(inPrimitive), true, *this, + (void (*)()) static_cast(&inPrimitive)->sysCall.function); + break; + } + case emSysCallC: case emSysCallEC: + { + new(mPool) CallS_C( &inPrimitive, mPool, + CallS_C::numberOfArguments(inPrimitive), true, *this, + (void (*)()) static_cast(&inPrimitive)->sysCall.function); + break; + } + case emSysCallV: case emSysCallEV: + { + new(mPool) CallS_V( &inPrimitive, mPool, + CallS_V::numberOfArguments(inPrimitive), true, *this, + (void (*)()) static_cast(&inPrimitive)->sysCall.function); + break; + } + + //----------------------------------------------------------------------- + // Monitors + case emMEnter: emit_MonitorEnter(inPrimitive); break; + case emMExit: emit_MonitorExit(inPrimitive); break; + + //----------------------------------------------------------------------- + // Misc + case emChkNull: emit_ChkNull(inPrimitive); break; + + default: +#ifdef DEBUG_LOG_VERBOSE + printf(" (unimplemented)"); +#endif + break; + } + +#ifdef DEBUG_LOG_VERBOSE + printf("\n"); +#endif +} + +//----------------------------------------------------------------------------------------------------------- +// Utility +bool x86Win32Emitter:: +emitCopyAfter(DataNode& inDataNode, InstructionList::iterator where, VirtualRegister& fromVr, VirtualRegister& toVr) +{ + InsnDoubleOpDir& newInsn = newCopyInstruction(inDataNode, mPool); + newInsn.addUse(0, fromVr); + newInsn.addDefine(0, toVr); + newInsn.insertAfter(*where); + +#if DEBUG + toVr.setDefiningInstruction(newInsn); + newInsn.checkIntegrity(); // ensure that everthing makes sense here +#endif + return false; +} + +void x86Win32Emitter:: +emitStoreAfter(DataNode& inDataNode, InstructionList::iterator where, VirtualRegister& storedReg, VirtualRegister& stackReg) +{ + InsnDoubleOpDir& newInsn = *new(mPool) InsnDoubleOpDir(&inDataNode, mPool, raSaveReg, atRegDirect, atRegAllocStackSlot, 1, 1); + newInsn.addUse(0, storedReg); + newInsn.addDefine(0, stackReg); + newInsn.insertAfter(*where); + + UT_LOG(x86Emitter, PR_LOG_DEBUG, (" emitStoreAfter (insn %p)\n", &newInsn)); +#if DEBUG + newInsn.printDebug(UT_LOG_MODULE(x86Emitter)); + newInsn.checkIntegrity(); // ensure that everthing makes sense here +#endif +} + +void x86Win32Emitter:: +emitLoadAfter(DataNode& inDataNode, InstructionList::iterator where, VirtualRegister& loadedReg, VirtualRegister& stackReg) +{ + InsnDoubleOpDir& newInsn = *new(mPool) InsnDoubleOpDir(&inDataNode, mPool, raLoadI, atRegAllocStackSlot, atRegDirect, 1, 1); + newInsn.addUse(0, stackReg); + newInsn.addDefine(0, loadedReg); + newInsn.insertAfter(*where); + +#ifdef DEBUG // FIX why do you do this Laurent? + loadedReg.setDefiningInstruction(newInsn); +#endif + + UT_LOG(x86Emitter, PR_LOG_DEBUG, (" emitLoadAfter (insn %p)\n", &newInsn)); +#ifdef DEBUG + newInsn.printDebug(UT_LOG_MODULE(x86Emitter)); + newInsn.printArgs(); + newInsn.checkIntegrity(); // ensure that everthing makes sense here +#endif +} + +Instruction& x86Win32Emitter:: +emitAbsoluteBranch(DataNode& inDataNode, ControlNode& inTarget) +{ + x86Instruction& newInsn = *new(mPool) x86Instruction(&inDataNode, mPool, inTarget); + return (newInsn); +} + +// COMMENT ME +VirtualRegister& x86Win32Emitter:: +emit_CopyOfInput(x86ArgListInstruction& /*inInsn*/, DataNode& inPrimitive, Uint8 inWhichInput, VirtualRegisterID inID) +{ + // FIX-ME assumes fixed point registers + InsnDoubleOpDir& newInsn = newCopyInstruction(inPrimitive, mPool); + useProducer(inPrimitive.nthInputVariable(inWhichInput), newInsn, 0, vrcInteger, inID); + VirtualRegister &vrToBeOverwritten = *defineProducer(inPrimitive, newInsn, 0, vrcInteger, inID); + return vrToBeOverwritten; +} + +//----------------------------------------------------------------------------------------------------------- +// Arithmetic +/* +// Broken for now +void x86Win32Emitter:: +emit_MulI_I(Primitive& inPrimitive) +{ + // FIX check for power of two + assert(false); + Uint32 constant = nthInputConstantUint32(inPrimitive, 1); + x86Instruction& newInsn = *new(mPool) x86Instruction(&inPrimitive, mPool, sMulImm, constant, atRegDirect, atRegDirect, 1, 1); + useProducer(inPrimitive.nthInputVariable(0), newInsn, 0); + defineProducer(inPrimitive, newInsn, 0); +} +*/ + +void x86Win32Emitter:: +emit_Mul_I(Primitive& inPrimitive) +{ + InsnDoubleOp& newInsn = *new(mPool) InsnDoubleOp(&inPrimitive, mPool, opMul); + newInsn.x86StandardUseDefine(*this); +} + +void x86Win32Emitter:: +emit_AddI_I(Primitive& inPrimitive) +{ + x86Instruction* newInsn; + Uint32 constant = nthInputConstantUint32(inPrimitive, 1); + + if(constant == 1) { // inc + newInsn = new(mPool) x86Instruction(&inPrimitive, mPool, ceInc, atRegDirect, 1, 1); + newInsn->x86StandardUseDefine(*this); + } else if((int)constant == -1) { // dec + newInsn = new(mPool) x86Instruction(&inPrimitive, mPool, ceDec, atRegDirect, 1, 1); + newInsn->x86StandardUseDefine(*this); + } else { // add + newInsn = new(mPool) x86Instruction(&inPrimitive, mPool, iaAddImm, constant, atRegDirect, 1, 1); + newInsn->x86StandardUseDefine(*this); + } +} + +void x86Win32Emitter:: +emit_Add_I(Primitive& inPrimitive) +{ + InsnDoubleOpDir& newInsn = *new(mPool) InsnDoubleOpDir(&inPrimitive, mPool, raAdd); + newInsn.x86StandardUseDefine(*this); +} + +void x86Win32Emitter:: +emit_Sub_I(Primitive& inPrimitive) +{ + InsnDoubleOpDir& newInsn = *new(mPool) InsnDoubleOpDir(&inPrimitive, mPool, raSub); + newInsn.x86StandardUseDefine(*this); +} + +// a - b = (-b) + a +void x86Win32Emitter:: +emit_SubR_I(Primitive& inPrimitive) +{ + Uint32 constant = nthInputConstantUint32(inPrimitive, 0); + + // negate + x86Instruction& negInsn = *new(mPool) x86Instruction(&inPrimitive, mPool, eNeg, atRegDirect, 1, 1 ); + VirtualRegister& vrOut = emit_CopyOfInput(negInsn, inPrimitive, 1); + useProducer(inPrimitive, negInsn, 0); + redefineTemporary(negInsn, vrOut, 0); + + // add constant + // FIX later work out how to avoid emitting + x86Instruction& addInsn = *new(mPool) x86Instruction(&inPrimitive, mPool, iaAddImm, constant, atRegDirect, 1, 1); + useProducer(inPrimitive, addInsn, 0); + defineProducer(inPrimitive, addInsn, 0); + // FIX is this right +} + +//----------------------------------------------------------------------------------------------------------- +// Integer Logical Operations + +void x86Win32Emitter::emit_AndI_I(Primitive& inPrimitive) { genLogicI_I(inPrimitive, iaAndImm); } +void x86Win32Emitter::emit_OrI_I(Primitive& inPrimitive) { genLogicI_I(inPrimitive, iaOrImm); } +void x86Win32Emitter::emit_XorI_I(Primitive& inPrimitive) { genLogicI_I(inPrimitive, iaXorImm); } + +void x86Win32Emitter::emit_And_I(Primitive& inPrimitive) { genLogic_I(inPrimitive, raAnd); } +void x86Win32Emitter::emit_Or_I(Primitive& inPrimitive) { genLogic_I(inPrimitive, raOr); } +void x86Win32Emitter::emit_Xor_I(Primitive& inPrimitive) { genLogic_I(inPrimitive, raXor); } + +void x86Win32Emitter:: +genLogicI_I(Primitive& inPrimitive, x86ImmediateArithType iaType) +{ + Uint32 constant = nthInputConstantUint32(inPrimitive, 1); + x86Instruction& newInsn = *new(mPool) x86Instruction(&inPrimitive, mPool, iaType, constant, atRegDirect, 1, 1); + newInsn.x86StandardUseDefine(*this); +} + +void x86Win32Emitter:: +genLogic_I(Primitive& inPrimitive, x86DoubleOpDirCode raType) +{ + InsnDoubleOpDir& newInsn = *new(mPool) InsnDoubleOpDir(&inPrimitive, mPool, raType); + newInsn.x86StandardUseDefine(*this); +} + +//----------------------------------------------------------------------------------------------------------- +// Integer Shifts + +void x86Win32Emitter::emit_SarI_I(Primitive& inPrimitive) { genShiftI_I(inPrimitive, eSarImm, eSar1); } +void x86Win32Emitter::emit_ShrI_I(Primitive& inPrimitive) { genShiftI_I(inPrimitive, eShrImm, eShr1); } +void x86Win32Emitter::emit_ShlI_I(Primitive& inPrimitive) { genShiftI_I(inPrimitive, eShlImm, eShl1); } + +void x86Win32Emitter::emit_Sar_I(Primitive& inPrimitive) { genShift_I(inPrimitive, eSarCl); } +void x86Win32Emitter::emit_Shr_I(Primitive& inPrimitive) { genShift_I(inPrimitive, eShrCl); } +void x86Win32Emitter::emit_Shl_I(Primitive& inPrimitive) { genShift_I(inPrimitive, eShlCl); } + +void x86Win32Emitter::genShiftI_I(Primitive& inPrimitive, x86ExtendedType eByImmediate, x86ExtendedType eBy1) +{ + Uint32 constant = nthInputConstantUint32(inPrimitive, 1); + if(constant == 1) + { + x86Instruction& newInsn = *new(mPool) x86Instruction(&inPrimitive, mPool, eBy1, atRegDirect, 1, 1); + newInsn.x86StandardUseDefine(*this); + } + else + { + x86Instruction& newInsn = *new(mPool) x86Instruction(&inPrimitive, mPool, eByImmediate, constant, atRegDirect, 1, 1); + newInsn.x86StandardUseDefine(*this); + } +} + +void x86Win32Emitter::genShift_I(Primitive& inPrimitive, x86ExtendedType eByCl) +{ + x86Instruction& shiftInsn = *new(mPool) x86Instruction(&inPrimitive, mPool, eByCl, atRegDirect, 2, 1 ); + + // we kill one of our inputs, make copy + emit_CopyOfInput(shiftInsn, inPrimitive, 0); + + // input and output arg 0 will have been copied to the outgoing edge + // by emit_CopyOfInput + useProducer(inPrimitive, shiftInsn, 0); + defineProducer(inPrimitive, shiftInsn, 0); + + // now make a buffer copy of the shift by value so we can precolor + InsnDoubleOpDir& shiftByCopy = newCopyInstruction(inPrimitive, mPool); + useProducer(inPrimitive.nthInputVariable(1), shiftByCopy, 0); + VirtualRegister& shiftByVR = defineTemporary(shiftByCopy, 0); + shiftByVR.preColorRegister(x86GPRToColor[ECX]); + + // setup last input of the shift instruction + useTemporaryVR(shiftInsn, shiftByVR, 1); +}; + +//----------------------------------------------------------------------------------------------------------- +// 64 bit support +void x86Win32Emitter::emit_Add_L(Primitive& inPrimitive) { emit_Arithmetic_L(inPrimitive, raAdd, raAdc); } +void x86Win32Emitter::emit_Sub_L(Primitive& inPrimitive) { emit_Arithmetic_L(inPrimitive, raSub, raSbb); } + +void x86Win32Emitter:: +emit_Arithmetic_L(Primitive& inPrimitive, x86DoubleOpDirCode insnTypeLo, x86DoubleOpDirCode insnTypeHi) +{ + // low word arithmetic + InsnDoubleOpDir& insnLo = *new(mPool) InsnDoubleOpDir(&inPrimitive, mPool, insnTypeLo, atRegDirect, atRegDirect, 2, 2); + VirtualRegister& vrLo = emit_CopyOfInput(insnLo, inPrimitive, 0, vidLow); + useProducer(inPrimitive, insnLo, 0, vrcInteger, vidLow); + useProducer(inPrimitive.nthInputVariable(1), insnLo, 1, vrcInteger, vidLow); + redefineTemporary(insnLo, vrLo, 0); + insnLo.addDefine(1, udCond); + + // high word arithmetic with carry + InsnDoubleOpDir& insnHi = *new(mPool) InsnDoubleOpDir(&inPrimitive, mPool, insnTypeHi, atRegDirect, atRegDirect, 3, 1); + VirtualRegister& vrHi = emit_CopyOfInput(insnHi, inPrimitive, 0, vidHigh); + useProducer(inPrimitive, insnHi, 0, vrcInteger, vidHigh); + useProducer(inPrimitive.nthInputVariable(1), insnHi, 1, vrcInteger, vidHigh); + insnHi.addUse(2, udCond); + insnHi.getInstructionUseBegin()[2].src = &insnLo; // FIX hack in lieu of temporary condition edge + redefineTemporary(insnHi, vrHi, 0); +} + + +void x86Win32Emitter::emit_And_L(Primitive& inPrimitive) { emit_Logic_L(inPrimitive, raAnd); } +void x86Win32Emitter::emit_Or_L(Primitive& inPrimitive) { emit_Logic_L(inPrimitive, raOr); } +void x86Win32Emitter::emit_Xor_L(Primitive& inPrimitive) { emit_Logic_L(inPrimitive, raXor); } + +void x86Win32Emitter:: +emit_Logic_L(Primitive& inPrimitive, x86DoubleOpDirCode insnType) +{ + // low word + InsnDoubleOpDir& insnLo = *new(mPool) InsnDoubleOpDir(&inPrimitive, mPool, insnType); + VirtualRegister& vrLo = emit_CopyOfInput(insnLo, inPrimitive, 0, vidLow); + useProducer(inPrimitive, insnLo, 0, vrcInteger, vidLow); + useProducer(inPrimitive.nthInputVariable(1), insnLo, 1, vrcInteger, vidLow); + redefineTemporary(insnLo, vrLo, 0); + + // high word + InsnDoubleOpDir& insnHi = *new(mPool) InsnDoubleOpDir(&inPrimitive, mPool, insnType); + VirtualRegister& vrHi = emit_CopyOfInput(insnHi, inPrimitive, 0, vidHigh); + useProducer(inPrimitive, insnHi, 0, vrcInteger, vidHigh); + useProducer(inPrimitive.nthInputVariable(1), insnHi, 1, vrcInteger, vidHigh); + redefineTemporary(insnHi, vrHi, 0); +} + +#if defined(WIN32) +extern void x86Mul64Bit(); +extern void x86Div64Bit(); +extern void x86Mod64Bit(); +extern void x86Shl64Bit(); +extern void x86Shr64Bit(); +extern void x86Sar64Bit(); +extern void x86ThreeWayCMP_L(); +extern void x86ThreeWayCMPC_L(); +extern void x86Extract64Bit(); +#elif defined(LINUX) +extern "C" { +extern void x86Mul64Bit(void); +extern void x86Div64Bit(void); +extern void x86Mod64Bit(void); +extern void x86Shl64Bit(void); +extern void x86Shr64Bit(void); +extern void x86Sar64Bit(void); +extern void x86ThreeWayCMP_L(void); +extern void x86ThreeWayCMPC_L(void) {trespass("Not implemented");} +extern void x86Extract64Bit(void); +}; +#endif + +#if !defined(WIN32) && !defined(LINUX) +static void x86Mul64Bit() {trespass("Not implemented");} +static void x86Div64Bit() {trespass("Not implemented");} +static void x86Mod64Bit() {trespass("Not implemented");} +static void x86Shl64Bit() {trespass("Not implemented");} +static void x86Shr64Bit() {trespass("Not implemented");} +static void x86Sar64Bit() {trespass("Not implemented");} +static void x86ThreeWayCMP_L() {trespass("Not implemented");} +static void x86ThreeWayCMPC_L() {trespass("Not implemented");} +static void x86Extract64Bit() {trespass("Not implemented");} +#endif + +void x86Win32Emitter:: +emit_Mul_L(Primitive& inPrimitive) +{ + new(mPool) CallS_C(&inPrimitive, mPool, 2, true, *this, &x86Mul64Bit); +} + +void x86Win32Emitter:: +emit_Div_L(Primitive& inPrimitive) +{ + new(mPool) CallS_C(&inPrimitive, mPool, 2, true, *this, &x86Div64Bit); +} + +void x86Win32Emitter:: +emit_Mod_L(Primitive& inPrimitive) +{ + new(mPool) CallS_C(&inPrimitive, mPool, 2, true, *this, &x86Mod64Bit); +} + +void x86Win32Emitter:: +emit_3wayCmpL_L(Primitive& inPrimitive) +{ + new(mPool) CallS_C(&inPrimitive, mPool, 2, true, *this, &x86ThreeWayCMP_L, &(inPrimitive.nthInputVariable(0))); +} + +void x86Win32Emitter:: +emit_3wayCmpCL_L(Primitive& inPrimitive) +{ + new(mPool) CallS_C(&inPrimitive, mPool, 2, true, *this, &x86ThreeWayCMP_L, &(inPrimitive.nthInputVariable(0))); +} + +void x86Win32Emitter:: +emit_Shl_L(Primitive& inPrimitive) +{ + new(mPool) CallS_C(&inPrimitive, mPool, 2, true, *this, &x86Shl64Bit); +} + +void x86Win32Emitter:: +emit_Shr_L(Primitive& inPrimitive) +{ + new(mPool) CallS_C(&inPrimitive, mPool, 2, true, *this, &x86Shr64Bit); +} + +void x86Win32Emitter:: +emit_Sar_L(Primitive& inPrimitive) +{ + new(mPool) CallS_C(&inPrimitive, mPool, 2, true, *this, &x86Sar64Bit); +} + +void x86Win32Emitter:: +emit_Ext_L(Primitive& inPrimitive) +{ + new(mPool) CallS_C(&inPrimitive, mPool, 2, true, *this, &x86Extract64Bit); +} + +void x86Win32Emitter:: +emit_ConvL_I(Primitive& inPrimitive) +{ + // make a copy of the input and precolour it to EAX + InsnDoubleOpDir& copyOfInput = newCopyInstruction(inPrimitive, mPool); + useProducer(inPrimitive.nthInputVariable(0), copyOfInput, 0); + VirtualRegister& vrIn = defineTemporary(copyOfInput, 0); + vrIn.preColorRegister(x86GPRToColor[EAX]); + + // create CDQ instruction, use vrIn and define vrHi and vrLo + InsnNoArgs& insnCdq = *new(mPool) InsnNoArgs(&inPrimitive, mPool, opCdq, 1, 2); + useTemporaryVR(insnCdq, vrIn, 0); + VirtualRegister& vrHi = defineTemporary(insnCdq, 0); + VirtualRegister& vrLo = defineTemporary(insnCdq, 1); + + // precolour vrHi and vrLo + vrHi.preColorRegister(x86GPRToColor[EDX]); + vrLo.preColorRegister(x86GPRToColor[EAX]); + + // make copies of vrHi and vrLo and define the producer + InsnDoubleOpDir& copyHi = newCopyInstruction(inPrimitive, mPool); + useTemporaryVR(copyHi, vrHi, 0); + defineProducer(inPrimitive, copyHi, 0, vrcInteger, vidHigh); + + InsnDoubleOpDir& copyLo = newCopyInstruction(inPrimitive, mPool); + useTemporaryVR(copyLo, vrLo, 0); + defineProducer(inPrimitive, copyLo, 0, vrcInteger, vidLow); +} + +void x86Win32Emitter:: +emit_ConvI_L(Primitive& inPrimitive) +{ + // make a copy of the low register of the input + InsnDoubleOpDir& copyOfInput = newCopyInstruction(inPrimitive, mPool); + useProducer(inPrimitive.nthInputVariable(0), copyOfInput, 0, vrcInteger, vidLow); + defineProducer(inPrimitive, copyOfInput, 0); +} + +void x86Win32Emitter:: +emit_Ld_L(Primitive& inPrimitive) +{ + InsnDoubleOpDir& insnLo = *new(mPool) InsnDoubleOpDir(&inPrimitive, mPool, raLoadI, atRegisterIndirect, atRegDirect, 2, 1); + useProducer(inPrimitive.nthInputVariable(0), insnLo, 1); // memory edge + useProducer(inPrimitive.nthInputVariable(1), insnLo, 0); // address + defineProducer(inPrimitive, insnLo, 0, vrcInteger, vidLow); // -> lo + + InsnDoubleOpDir& insnHi = *new(mPool) InsnDoubleOpDir(&inPrimitive, mPool, raLoadI, 4, atRegisterIndirect, atRegDirect, 2, 1); + useProducer(inPrimitive.nthInputVariable(0), insnHi, 1); // memory edge + useProducer(inPrimitive.nthInputVariable(1), insnHi, 0); // address + defineProducer(inPrimitive, insnHi, 0, vrcInteger, vidHigh); // -> hi +} + +void x86Win32Emitter:: +emit_St_L(Primitive& inPrimitive) +{ + InsnDoubleOpDir& insnLo = *new(mPool) InsnDoubleOpDir(&inPrimitive, mPool, raStoreI, atRegisterIndirect, atRegDirect, 2, 1); + useProducer(inPrimitive.nthInputVariable(1), insnLo, 0); // address + useProducer(inPrimitive.nthInputVariable(2), insnLo, 1, vrcInteger, vidLow); // <- lo +// FIX for now these are commented out -- see comment below +// useProducer(inPrimitive.nthInputVariable(0), insnLo, 2); // memory edge in +// defineProducer(inPrimitive, insnLo, 0); // memory edge out + InstructionDefine& define = defineTemporaryOrder(insnLo, 0); + + // FIX for now we are using the memory edge out from lo as the memory edge in for hi. + // This is because the memory edges don't have a clue about high/low registers + InsnDoubleOpDir& insnHi = *new(mPool) InsnDoubleOpDir(&inPrimitive, mPool, raStoreI, 4, atRegisterIndirect, atRegDirect, 4, 1); + useProducer(inPrimitive.nthInputVariable(1), insnHi, 0); // address + useProducer(inPrimitive.nthInputVariable(2), insnHi, 1, vrcInteger, vidHigh); // <- hi + useProducer(inPrimitive.nthInputVariable(0), insnHi, 2); // memory edge in + useTemporaryOrder(insnHi, define, 3); + defineProducer(inPrimitive, insnHi, 0); // memory edge out +} + +//----------------------------------------------------------------------------------------------------------- +void x86Win32Emitter:: +emit_Break(Primitive& inPrimitive) +{ + new(mPool) InsnNoArgs(&inPrimitive, mPool, opBreak, 0, 0); +} + +//----------------------------------------------------------------------------------------------------------- +// Comparisons + +void x86Win32Emitter:: +emit_Cmp_I(Primitive& inPrimitive) +{ + InsnDoubleOpDir& newInsn = *new(mPool) InsnDoubleOpDir(&inPrimitive, mPool, raCmp); + newInsn.standardUseDefine(*this); +} + +void x86Win32Emitter:: +emit_CmpI_I(Primitive& inPrimitive) +{ + Uint32 constant = nthInputConstantUint32(inPrimitive, 1); + + if(constant == 0) + { + x86Instruction& newInsn = *new(mPool) x86Instruction(&inPrimitive, mPool, srmCmpImm0, 0, 1, 1 ); + newInsn.standardUseDefine(*this); + } else { + x86Instruction& newInsn = *new(mPool) x86Instruction(&inPrimitive, mPool, iaCmpImm, constant, atRegDirect, 1, 1 ); + newInsn.standardUseDefine(*this); + } +} + +//----------------------------------------------------------------------------------------------------------- +// Div and Mod are very similar in X86, so we try to factor out as much as we can + +// Normal Addressing Modes +void x86Win32Emitter::emit_Div_I(Primitive& p) { genDivBackEnd(genDivMod_FrontEnd(p, eIDiv)); } +void x86Win32Emitter::emit_DivU_I(Primitive& p) { genDivBackEnd(genDivMod_FrontEnd(p, eDiv )); } +void x86Win32Emitter::emit_Mod_I(Primitive& p) { genModBackEnd(genDivMod_FrontEnd(p, eIDiv)); } +void x86Win32Emitter::emit_ModU_I(Primitive& p) { genModBackEnd(genDivMod_FrontEnd(p, eDiv )); } + +// Displaced, Scaled, Indexed Addressing Mode +void x86Win32Emitter::emit_Div_I_MemDSI(Primitive& p) { genDivBackEnd(genDivMod_FrontEnd_MemDSI(p, eIDiv)); } +void x86Win32Emitter::emit_DivU_I_MemDSI(Primitive& p) { genDivBackEnd(genDivMod_FrontEnd_MemDSI(p, eDiv )); } +void x86Win32Emitter::emit_Mod_I_MemDSI(Primitive& p) { genModBackEnd(genDivMod_FrontEnd_MemDSI(p, eIDiv)); } +void x86Win32Emitter::emit_ModU_I_MemDSI(Primitive& p) { genModBackEnd(genDivMod_FrontEnd_MemDSI(p, eDiv )); } + +// does div, mod, divU, modU +// div divides dividend in EAX:EDX by divisor in reg/mem +x86Instruction& x86Win32Emitter:: +genDivMod_FrontEnd(Primitive& inPrimitive, x86ExtendedType insnType) +{ + // make a copy of the dividend (since it will be eventually overwritten) + InsnDoubleOpDir& dividendCopy = newCopyInstruction(inPrimitive, mPool); + useProducer(inPrimitive.nthInputVariable(0), dividendCopy, 0); + VirtualRegister& vrEAXin = defineTemporary(dividendCopy, 0); + vrEAXin.preColorRegister(x86GPRToColor[EAX]); + + // convert to quad word + InsnNoArgs& insnCdq = *new(mPool) InsnNoArgs(&inPrimitive, mPool, opCdq, 1, 2); + useTemporaryVR(insnCdq, vrEAXin, 0); + VirtualRegister& vrEAXOut = defineTemporary(insnCdq, 0); + VirtualRegister& vrEDXOut = defineTemporary(insnCdq, 1); + vrEAXOut.preColorRegister(x86GPRToColor[EAX]); + vrEDXOut.preColorRegister(x86GPRToColor[EDX]); + + // divide + x86Instruction& insnDivide = *new(mPool)x86Instruction(&inPrimitive, mPool, insnType, atRegDirect, 3, 2); + useProducer(inPrimitive.nthInputVariable(1), insnDivide, 0); + useTemporaryVR(insnDivide, vrEAXOut, 1); + useTemporaryVR(insnDivide, vrEDXOut, 2); + + return insnDivide; +} + +// poDiv_I(Vint, MemDSI) +// dividend / divisor +x86Instruction& x86Win32Emitter:: +genDivMod_FrontEnd_MemDSI(Primitive& inPrimitive, x86ExtendedType insnType) +{ + // get the DSI parameters + DataNode& loadPrimitive = inPrimitive.nthInputVariable(1); + + MemDSIParameters parms(loadPrimitive); + assert(parms.scale <= 3); // eventually MemDSI will be limited to scale <=3 + + // make a copy of the dividend (since it will be eventually overwritten) + InsnDoubleOpDir& dividendCopy = newCopyInstruction(inPrimitive, mPool); + useProducer(inPrimitive.nthInputVariable(0), dividendCopy, 0); + VirtualRegister& vrEAXin = defineTemporary(dividendCopy, 0); + vrEAXin.preColorRegister(x86GPRToColor[EAX]); // input must be in EAX + + // convert to quad word + InsnNoArgs& insnCdq = *new(mPool) InsnNoArgs(&inPrimitive, mPool, opCdq, 1, 2); + useTemporaryVR(insnCdq, vrEAXin, 0); + VirtualRegister& vrEAXOut = defineTemporary(insnCdq, 0); + VirtualRegister& vrEDXOut = defineTemporary(insnCdq, 1); + vrEAXOut.preColorRegister(x86GPRToColor[EAX]); + vrEDXOut.preColorRegister(x86GPRToColor[EDX]); + + // divide + x86Instruction& insnDivide = + *new(mPool)x86Instruction(&inPrimitive, mPool, insnType, memDSIAddressingModes[parms.scale], parms.displacement, 5, 2); + + useProducer(parms.baseProducer, insnDivide, 0); // base + useProducer(parms.indexProducer, insnDivide, 1); // index + useTemporaryVR(insnDivide, vrEAXOut, 2); // EAX + useTemporaryVR(insnDivide, vrEDXOut, 3); // EDX + useProducer(loadPrimitive.nthInputVariable(0), insnDivide, 4); // memory edge in + + return insnDivide; +} + +// backends for div and mod +void x86Win32Emitter:: +genDivBackEnd(x86Instruction& inInsn) +{ + DataNode& primitive = *(inInsn.getPrimitive()); + VirtualRegister *vrEAX, *vrEDX; + + vrEAX = &defineTemporary(inInsn, 0); + vrEAX->preColorRegister(x86GPRToColor[EAX]); + + InsnDoubleOpDir& insnCopy = newCopyInstruction(primitive, mPool); + useTemporaryVR(insnCopy, *vrEAX, 0); + defineProducer(primitive, insnCopy, 0); + + vrEDX = &defineTemporary(inInsn, 1); // unused result + vrEDX->preColorRegister(x86GPRToColor[EDX]); +} + +void x86Win32Emitter:: +genModBackEnd(x86Instruction& inInsn) +{ + DataNode& primitive = *(inInsn.getPrimitive()); + VirtualRegister *vrEAX, *vrEDX; + + vrEDX = &defineTemporary(inInsn, 1); + vrEDX->preColorRegister(x86GPRToColor[EDX]); + + InsnDoubleOpDir& insnCopy = newCopyInstruction(primitive, mPool); + useTemporaryVR(insnCopy, *vrEDX, 0); + defineProducer(primitive, insnCopy, 0); + + vrEAX = &defineTemporary(inInsn, 0); // unused result + vrEAX->preColorRegister(x86GPRToColor[EAX]); +} + +//----------------------------------------------------------------------------------------------------------- + +void x86Win32Emitter:: +emit_LoadConstant_I(Primitive& inPrimitive) +{ + Uint32 constant = (*static_cast(&inPrimitive)).value.i; + + x86Instruction* newInsn; + + if(constant == 0) + newInsn = new(mPool) x86Instruction(&inPrimitive, mPool, srmMoveImm0, 0, 0, 1); + else + newInsn = new(mPool) x86Instruction(&inPrimitive, mPool, ceMoveImm, constant, atRegDirect, 0, 1); + + defineProducer(inPrimitive, *newInsn, 0); +} + +void x86Win32Emitter:: +emit_LoadConstant_L(Primitive& inPrimitive) +{ + Int64 constant = (*static_cast(&inPrimitive)).value.l; + // FIX make better + Int32 low = (Int32)((Uint64) constant & 0xFFFFFFFF); + Int32 high = (Int32)((Uint64)constant >> 32); + + x86Instruction* loInsn; + x86Instruction* hiInsn; + + if(low == 0) + loInsn = new(mPool) x86Instruction(&inPrimitive, mPool, srmMoveImm0, 0, 0, 1); + else + loInsn = new(mPool) x86Instruction(&inPrimitive, mPool, ceMoveImm, low, atRegDirect, 0, 1); + defineProducer(inPrimitive, *loInsn, 0, vrcInteger, vidLow); + + if(high == 0) + hiInsn = new(mPool) x86Instruction(&inPrimitive, mPool, srmMoveImm0, 0, 0, 1); + else + hiInsn = new(mPool) x86Instruction(&inPrimitive, mPool, ceMoveImm, high, atRegDirect, 0, 1); + defineProducer(inPrimitive, *hiInsn, 0, vrcInteger, vidHigh); +} + +void x86Win32Emitter:: +emit_Catch(Primitive& inPrimitive) +{ + // create a define instruction which tells the register allocator that the register + // is defined elsewhere (in the exception support code) + InsnExternalDefine& defineInsn = *new(mPool) InsnExternalDefine(&inPrimitive, mPool, 1); + + // define an outgoing edge which is a vr precolored to EAX + VirtualRegister& exceptionObj = defineTemporary(defineInsn, 0); + exceptionObj.preColorRegister(x86GPRToColor[ECX]); // FIX should be eax (hack to work around reg alloc bug + + // now create a buffer copy between the precolored EAX and define the outgoing + // VR with the outgoing edge of the Catch primitive + InsnDoubleOpDir& copyInsn = *new(mPool) InsnDoubleOpDir(&inPrimitive, mPool, raCopyI, atRegDirect, atRegDirect, 1, 1); + useTemporaryVR(copyInsn, exceptionObj, 0); + defineProducer(inPrimitive, copyInsn, 0); +} + +void x86Win32Emitter:: +emit_LoadAddress(Primitive& inPrimitive) +{ + addr a= (*static_cast(&inPrimitive)).value.a; + Uint32 constant = (Uint32)addressFunction(a); + x86Instruction& newInsn = *new(mPool) x86Instruction(&inPrimitive, mPool, ceMoveImm, constant, atRegDirect, 0, 1); + defineProducer(inPrimitive, newInsn, 0); +} + +void x86Win32Emitter:: +emit_Ext_I(Primitive& inPrimitive) +{ + Uint32 shiftAmount = 32 - nthInputConstantUint32(inPrimitive, 1); + + // shift left by shiftAmount + x86Instruction& shl = *new(mPool) x86Instruction(&inPrimitive, mPool, eShlImm, shiftAmount, atRegDirect, 1, 1); + shl.x86StandardUseDefine(*this); + + // sar by shiftAmount + x86Instruction& sar = *new(mPool) x86Instruction(&inPrimitive, mPool, eSarImm, shiftAmount, atRegDirect, 1, 1); + useProducer(inPrimitive, sar, 0); + defineProducer(inPrimitive, sar, 0); +} + +// Method: emit_Switch +// Purpose: emit a switch +void x86Win32Emitter:: +emit_Switch(Primitive& inPrimitive) +{ + InsnSwitch& jmpInsn = *new InsnSwitch(&inPrimitive, mPool); + jmpInsn.standardUseDefine(*this); +} + +// Method: getConditionCode +// Purpose: check the condition edge we depend upon to see if it is signed or unsigned and +// use it to select the x86 condition code +// Assumes: condition edge is always the 0th input (currently an invariant) +inline x86ConditionCode getConditionCode(Primitive& inPrimitive, RawConditionCode rawCondType) +{ + x86ConditionCode condType; + if(inPrimitive.nthInputVariable(0).isSignedCompare()) + condType = condList[rawCondType].ccSigned; + else + condType = condList[rawCondType].ccUnsigned; + return condType; +} + +// Method: emit_B +// Purpose: emit a conditional branch +void x86Win32Emitter:: +emit_B(Primitive& inPrimitive, RawConditionCode rawCondType) +{ + // since the condition code depends on whether the comparison was signed or unsinged, + // we need to determine whether the comparison primitive preceding this primitive was + // signed or unsigned and use that to select the appropriate condition code. + x86ConditionCode condType = getConditionCode(inPrimitive, rawCondType); + + // conditional branch + ControlNode& controlIf = *inPrimitive.getContainer(); + InsnCondBranch& newInsn = *new(mPool) InsnCondBranch(&inPrimitive, mPool, condType, controlIf); + newInsn.standardUseDefine(*this); +} + +// Method: emit_Cond +// Purpose: emit a condition flags -> boolean conversion +// Code must be in the form +// xor eax,eax WE EMIT +// cmp ecx, value (emitted by CMP primitive) +// sete al WE EMIT +// [copy al, tempVr] WE EMIT (tempVR is in the outgoing edge) +// +// It is imperative that the instruction scheduler clears the destination before the comparison, +// otherwise the compare flags will be clobbered by the xor eax, eax +void x86Win32Emitter:: +emit_Cond(Primitive& inPrimitive, RawConditionCode rawCondType) +{ + // see comment in emit_B + x86ConditionCode condType = getConditionCode(inPrimitive, rawCondType); + + // clear the destination + x86Instruction& clearInsn = *new(mPool) x86Instruction(&inPrimitive, mPool, srmMoveImm0, 0, 0, 1); + VirtualRegister& outputVR = defineTemporary(clearInsn,0); + outputVR.preColorRegister(x86GPRToColor[EAX]); + + // set instruction + InsnSet& setInsn = *new(mPool) InsnSet(&inPrimitive, mPool, condType); + useTemporaryVR(setInsn, outputVR, 0); // register to store into + useProducer(inPrimitive.nthInputVariable(0), setInsn, 1); // condition edge + redefineTemporary(setInsn, outputVR, 0); // -> result + + // create buffer copy + InsnDoubleOpDir& copyInsn = newCopyInstruction(inPrimitive, mPool); + useTemporaryVR(copyInsn, outputVR, 0); + defineProducer(inPrimitive, copyInsn, 0); +} + +void x86Win32Emitter:: +genLd_I(Primitive& inPrimitive) +{ + InsnDoubleOpDir& newInsn = *new(mPool) InsnDoubleOpDir(&inPrimitive, mPool, raLoadI, atRegisterIndirect, atRegDirect); + useProducer(inPrimitive.nthInputVariable(0), newInsn, 1); // memory edge + useProducer(inPrimitive.nthInputVariable(1), newInsn, 0); // address + defineProducer(inPrimitive, newInsn, 0); // output +} + +void x86Win32Emitter:: +emit_LdS_B(Primitive& inPrimitive) +{ + InsnDoubleOp& newInsn = *new(mPool) InsnDoubleOp(&inPrimitive, mPool, opMovSxB, atRegisterIndirect, atRegDirect); + useProducer(inPrimitive.nthInputVariable(0), newInsn, 1); // memory edge + useProducer(inPrimitive.nthInputVariable(1), newInsn, 0); // address + defineProducer(inPrimitive, newInsn, 0); // output +} + +void x86Win32Emitter:: +emit_LdU_B(Primitive& inPrimitive) +{ + InsnDoubleOp& newInsn = *new(mPool) InsnDoubleOp(&inPrimitive, mPool, opMovZxB, atRegisterIndirect, atRegDirect); + useProducer(inPrimitive.nthInputVariable(0), newInsn, 1); // memory edge + useProducer(inPrimitive.nthInputVariable(1), newInsn, 0); // address + defineProducer(inPrimitive, newInsn, 0); // output +} + +void x86Win32Emitter:: +emit_LdS_H(Primitive& inPrimitive) +{ + InsnDoubleOp& newInsn = *new(mPool) InsnDoubleOp(&inPrimitive, mPool, opMovSxH, atRegisterIndirect, atRegDirect); + useProducer(inPrimitive.nthInputVariable(0), newInsn, 1); // memory edge + useProducer(inPrimitive.nthInputVariable(1), newInsn, 0); // address + defineProducer(inPrimitive, newInsn, 0); // output +} + +void x86Win32Emitter:: +emit_LdU_H(Primitive& inPrimitive) +{ + InsnDoubleOp& newInsn = *new(mPool) InsnDoubleOp(&inPrimitive, mPool, opMovZxH, atRegisterIndirect, atRegDirect); + useProducer(inPrimitive.nthInputVariable(0), newInsn, 1); // memory edge + useProducer(inPrimitive.nthInputVariable(1), newInsn, 0); // address + defineProducer(inPrimitive, newInsn, 0); // output +} + +void x86Win32Emitter:: +genLdC_I(Primitive& inPrimitive) +{ + InsnDoubleOpDir& newInsn = *new(mPool) InsnDoubleOpDir(&inPrimitive, mPool, raLoadI, atRegisterIndirect, atRegDirect, 1, 1); + defineProducer(inPrimitive, newInsn, 0); + useProducer(inPrimitive.nthInputVariable(0), newInsn, 0); + + /* FIX pete -- why + put a flag in for exceptions here!!!! + use curIndex as the place to put it */ +} + +// poLimit(Vint, Vint) throw if va >= vb (ie ensure va < vb) OK +// form cmp r1, r2 throw if r1 >= r2 r1 nb r2 +// so skip if !nb ==> b +void x86Win32Emitter:: +emit_Limit(Primitive& inPrimitive) +{ + // compare + InsnDoubleOpDir& compare = *new(mPool) InsnDoubleOpDir(&inPrimitive, mPool, raCmp); + useProducer(inPrimitive.nthInputVariable(0), compare, 0); + useProducer(inPrimitive.nthInputVariable(1), compare, 1); + compare.addDefine(0, udCond); + + // branch + // jump to exception handler >= ie jnb + InsnSysCallCondBranch& branch = *new(mPool) InsnSysCallCondBranch(&inPrimitive, mPool, ccJB, (void (*)())sysThrowArrayIndexOutOfBoundsException); + branch.addUse(0, udCond); + branch.getInstructionUseBegin()->src = &compare; + inPrimitive.setInstructionRoot(&branch); +} + +// Common code for limCast, chkCast and chkNull primitives +void x86Win32Emitter:: +emit_ExceptionCheck(Primitive& inPrimitive, x86ConditionCode condType, Uint32 constant, void (*throwExceptionFunction)()) +{ + x86Instruction& trap = *new(mPool) x86Instruction(&inPrimitive, mPool, iaCmpImm, constant, atRegDirect, 1, 1); + useProducer(inPrimitive.nthInputVariable(0), trap, 0); + trap.addDefine(0, udCond); + + // branch + InsnSysCallCondBranch& branch = *new(mPool) InsnSysCallCondBranch(&inPrimitive, mPool, condType, throwExceptionFunction); + branch.addUse(0, udCond); + branch.getInstructionUseBegin()->src = &trap; + inPrimitive.setInstructionRoot(&branch); +} + +// poChkCast_I(vint, Vint) or poChkCast_A(Vptr, Vptr) +void x86Win32Emitter:: +emit_ChkCast(Primitive& inPrimitive) +{ + InsnDoubleOpDir& trap = *new(mPool) InsnDoubleOpDir(&inPrimitive, mPool, raCmp); + useProducer(inPrimitive.nthInputVariable(0), trap, 0); + useProducer(inPrimitive.nthInputVariable(1), trap, 1); + trap.addDefine(0, udCond); + + // branch + InsnSysCallCondBranch& branch = *new(mPool) InsnSysCallCondBranch(&inPrimitive, mPool, ccJE, (void (*)())sysThrowClassCastException); + branch.addUse(0, udCond); + branch.getInstructionUseBegin()->src = &trap; + inPrimitive.setInstructionRoot(&branch); +} + +// poChkCast_A(Vptr, Cptr) +void x86Win32Emitter:: +emit_ChkCast_Const(Primitive& inPrimitive) +{ + Uint32 classPtr = nthInputConstantUint32(inPrimitive, 1); + emit_ExceptionCheck(inPrimitive, ccJE, classPtr, (void (*)())sysThrowClassCastException); +} + +void x86Win32Emitter:: +emit_LimCast(Primitive& inPrimitive) +{ + Uint32 numVTableEntries = nthInputConstantUint32(inPrimitive, 1); + emit_ExceptionCheck(inPrimitive, ccJNB, numVTableEntries, (void (*)())sysThrowClassCastException); +} + +void x86Win32Emitter:: +emit_ChkNull(Primitive& inPrimitive) +{ + emit_ExceptionCheck(inPrimitive, ccJNE, 0, (void (*)())sysThrowNullPointerException); +} + +void x86Win32Emitter:: +emit_Result_I(Primitive& inPrimitive) +{ + InsnDoubleOpDir& copyInsn = newCopyInstruction(inPrimitive, mPool); + InsnExternalUse& extInsn = *new(mPool) InsnExternalUse(&inPrimitive, mPool, 1); + + useProducer(inPrimitive.nthInputVariable(0), copyInsn, 0); + VirtualRegister& resultReg = defineTemporary(copyInsn, 0); + resultReg.preColorRegister(x86GPRToColor[EAX]); + useTemporaryVR(extInsn, resultReg, 0); + inPrimitive.setInstructionRoot(&extInsn); +} + +void x86Win32Emitter:: +emit_Result_L(Primitive& inPrimitive) +{ + // Low + InsnDoubleOpDir& copyLo = newCopyInstruction(inPrimitive, mPool, 1, 2); + InsnExternalUse& extLoInsn = *new(mPool) InsnExternalUse(&inPrimitive, mPool, 1); + + useProducer(inPrimitive.nthInputVariable(0), copyLo, 0, vrcInteger, vidLow); + VirtualRegister& vrLo = defineTemporary(copyLo, 0); + vrLo.preColorRegister(x86GPRToColor[EAX]); + + useTemporaryVR(extLoInsn, vrLo, 0); + + // High + InsnDoubleOpDir& copyHi = newCopyInstruction(inPrimitive, mPool, 2, 1); + InsnExternalUse& extHiInsn = *new(mPool) InsnExternalUse(&inPrimitive, mPool, 1); + + useProducer(inPrimitive.nthInputVariable(0), copyHi, 0, vrcInteger, vidHigh); + VirtualRegister& vrHi = defineTemporary(copyHi, 0); + vrHi.preColorRegister(x86GPRToColor[EDX]); + + useTemporaryVR(extHiInsn, vrHi, 0); + useTemporaryOrder(copyHi, defineTemporaryOrder(copyLo, 1), 1); + + inPrimitive.setInstructionRoot(&extHiInsn); +} + +// poLimit(poConst_I, Vint) throw if poConst_I >= Vint OK +// form cmp reg, 10 throw if poConst_I <= Vint jbe +// so skip if !be ==> jnbe +void x86Win32Emitter:: +emit_LimitR(Primitive& inPrimitive) +{ + Uint32 constant = nthInputConstantUint32(inPrimitive, 1); + + // compare + x86Instruction& compare = *new(mPool) x86Instruction(&inPrimitive, mPool, iaCmpImm, constant, atRegDirect, 1, 1 ); + useProducer(inPrimitive.nthInputVariable(1), compare, 0); + compare.addDefine(0, udCond); + + // branch + // reversed -- jump to exception handler if below or equal ie ccJBE (ok) + InsnSysCallCondBranch& branch = *new(mPool) InsnSysCallCondBranch(&inPrimitive, mPool, ccJNBE, (void (*)())sysThrowArrayIndexOutOfBoundsException); + branch.addUse(0, udCond); + branch.getInstructionUseBegin()->src = &compare; + inPrimitive.setInstructionRoot(&branch); +} + +void x86Win32Emitter:: +emit_St_I(Primitive& inPrimitive) +{ + InsnDoubleOpDir& newInsn = *new(mPool) InsnDoubleOpDir(&inPrimitive, mPool, raStoreI, atRegisterIndirect, atRegDirect, 3, 1); + useProducer(inPrimitive.nthInputVariable(1), newInsn, 0); // adress + useProducer(inPrimitive.nthInputVariable(2), newInsn, 1); // data + useProducer(inPrimitive.nthInputVariable(0), newInsn, 2); // memory edge in + defineProducer(inPrimitive, newInsn, 0); // memory edge out +} + +void x86Win32Emitter:: +emit_St_B(Primitive& inPrimitive) +{ + InsnDoubleOpDir& newInsn = *new(mPool) InsnDoubleOpDir(&inPrimitive, mPool, raStoreB, atRegisterIndirect, atRegDirect, 3, 1); + useProducer(inPrimitive.nthInputVariable(1), newInsn, 0); // address + + // FIX precolouring until register classes are introduced + InsnDoubleOpDir& copyInsn = newCopyInstruction(inPrimitive, mPool); + + useProducer(inPrimitive.nthInputVariable(2), copyInsn, 0); // data + VirtualRegister& copyOfInput = defineTemporary(copyInsn, 0); + + copyOfInput.preColorRegister(x86GPRToColor[EAX]); + + useProducer(inPrimitive.nthInputVariable(0), newInsn, 2); // memory edge in + useTemporaryVR(newInsn, copyOfInput, 1); // precolored register containing the data + defineProducer(inPrimitive, newInsn, 0); // memory edge out +} + +void x86Win32Emitter:: +emit_St_H(Primitive& inPrimitive) +{ + InsnDoubleOpDir& newInsn = *new(mPool) InsnDoubleOpDir(&inPrimitive, mPool, raStoreH, atRegisterIndirect, atRegDirect, 3, 1); + useProducer(inPrimitive.nthInputVariable(1), newInsn, 0); // adress + useProducer(inPrimitive.nthInputVariable(2), newInsn, 1); // data + useProducer(inPrimitive.nthInputVariable(0), newInsn, 2); // memory edge in + defineProducer(inPrimitive, newInsn, 0); // memory edge out +} + +void x86Win32Emitter:: +emit_StI_I(Primitive& inPrimitive) +{ + Uint32 constant = nthInputConstantUint32(inPrimitive, 2); + + x86Instruction& newInsn = *new(mPool) x86Instruction(&inPrimitive, mPool, eMoveImm, constant, atRegisterIndirect, 2, 1); + useProducer(inPrimitive.nthInputVariable(1), newInsn, 0); // address + useProducer(inPrimitive.nthInputVariable(0), newInsn, 1); // memory edge in + defineProducer(inPrimitive, newInsn, 0); // memory edge out +} + +//----------------------------------------------------------------------------------------------------------- +// MemDisp +void x86Win32Emitter:: +emit_St_I_MemDisp(Primitive& inPrimitive) +{ + DataNode& addSource = inPrimitive.nthInput(1).getVariable(); + Uint32 disp = nthInputConstantUint32(addSource, 1); + + // store + InsnDoubleOpDir& newInsn = + *new(mPool) InsnDoubleOpDir(&inPrimitive, mPool, raStoreI, disp, atRegisterIndirect, atRegDirect, 3, 1); + useProducer(addSource.nthInputVariable(0), newInsn, 0); // base address + useProducer(inPrimitive.nthInputVariable(2), newInsn, 1); // value to store + useProducer(inPrimitive.nthInputVariable(0), newInsn, 2); // memory edge in + defineProducer(inPrimitive, newInsn, 0); // memory edge out +} + +void x86Win32Emitter:: +emit_StI_I_MemDisp(Primitive& inPrimitive) +{ + Uint32 constant = nthInputConstantUint32(inPrimitive, 2); + + DataNode& addSource = inPrimitive.nthInput(1).getVariable(); + Uint32 disp = nthInputConstantUint32(addSource, 1); + + // store + x86Instruction& newInsn = *new(mPool) x86Instruction(&inPrimitive, mPool, eMoveImm, constant, atRegisterIndirect, disp, 2, 1); + useProducer(addSource.nthInputVariable(0), newInsn, 0); // base address + useProducer(inPrimitive.nthInputVariable(0), newInsn, 1); // memory edge in + defineProducer(inPrimitive, newInsn, 0); // memory edge out +} + +void x86Win32Emitter:: +emit_Ld_I_MemDisp(Primitive& inPrimitive) +{ + DataNode& addSource = inPrimitive.nthInput(1).getVariable(); + Uint32 disp = nthInputConstantUint32(addSource, 1); + + // load + InsnDoubleOpDir& newInsn = *new(mPool) InsnDoubleOpDir(&inPrimitive, mPool, raLoadI, disp, atRegisterIndirect, atRegDirect); + useProducer(addSource.nthInputVariable(0), newInsn, 0); // base address + useProducer(inPrimitive.nthInputVariable(0), newInsn, 1); // memory edge + defineProducer(inPrimitive, newInsn, 0); // loaded value +} + +// poLimit(poConst_I, MemDisp) throw if poConst_I >= MemDisp OK +// form cmp [eax + 4], 10 throw if MemDisp <= poConst_I jbe +// so skip if !be ==> jnbe +void x86Win32Emitter:: +emit_LimitR_MemDisp(Primitive& inPrimitive) +{ + Uint32 constant = nthInputConstantUint32(inPrimitive, 0); + + DataNode& loadSource = inPrimitive.nthInput(1).getVariable(); + DataNode& addSource = loadSource.nthInput(1).getVariable(); + Uint32 displacement = nthInputConstantUint32(addSource, 1); + + x86Instruction& compare = *new(mPool) x86Instruction(&inPrimitive, mPool, iaCmpImm, constant, atRegisterIndirect, displacement, 1, 1); + useProducer(addSource.nthInputVariable(0), compare, 0); + compare.addDefine(0, udCond); + + // reversed -- jump to exception handler if below ie ccJBE + InsnSysCallCondBranch& branch = *new(mPool) InsnSysCallCondBranch(&inPrimitive, mPool, ccJNBE, (void (*)())sysThrowArrayIndexOutOfBoundsException); + branch.addUse(0, udCond); + branch.getInstructionUseBegin()->src = &compare; + inPrimitive.setInstructionRoot(&branch); +} + +// poLimit(Vint, MemDisp) throw if Vint >= MemDisp OK +// form cmp eax, [reg + 4] throw if Vint >= MemDisp jnb +// so skip if !nb ==> jb +void x86Win32Emitter:: +emit_Limit_MemDisp(Primitive& inPrimitive) +{ + DataNode& loadSource = inPrimitive.nthInput(1).getVariable(); + DataNode& addSource = loadSource.nthInput(1).getVariable(); + Uint32 displacement = nthInputConstantUint32(addSource, 1); + + // compare + InsnDoubleOpDir& compare = *new(mPool) InsnDoubleOpDir(&inPrimitive, mPool, raCmp, displacement, atRegDirect, atRegisterIndirect); + useProducer(inPrimitive.nthInputVariable(0), compare, 0); + useProducer(addSource.nthInputVariable(0), compare, 1); + compare.addDefine(0, udCond); + + // branch + InsnSysCallCondBranch& branch = *new(mPool) InsnSysCallCondBranch(&inPrimitive, mPool, ccJB, (void (*)())sysThrowArrayIndexOutOfBoundsException); + branch.addUse(0, udCond); + branch.getInstructionUseBegin()->src = &compare; + inPrimitive.setInstructionRoot(&branch); +} + +//----------------------------------------------------------------------------------------------------------- +// MemDSI -- lots more factoring out to do + +// poCmp_I(MemDSI, Vint) +void x86Win32Emitter:: +emit_Cmp_I_MemDSI(Primitive& inPrimitive) +{ + DataNode& loadPrimitive = inPrimitive.nthInput(0).getVariable(); + MemDSIParameters parms(loadPrimitive); + assert(parms.scale <= 3); // eventually MemDSI will be limited to scale <=3 + + InsnDoubleOpDir& newInsn = + *new(mPool) InsnDoubleOpDir(&inPrimitive, mPool, raCmp, parms.displacement, memDSIAddressingModes[parms.scale], atRegDirect, 4, 1); + useProducer(parms.baseProducer, newInsn, 0); // <- base + useProducer(parms.indexProducer, newInsn, 1); // <- index + useProducer(inPrimitive.nthInputVariable(1), newInsn, 2); // <- compare value + useProducer(loadPrimitive.nthInputVariable(0), newInsn, 3); // <- memory + defineProducer(inPrimitive, newInsn, 0); // -> compare result +} + +void x86Win32Emitter:: +emit_CmpI_I_MemDSI(Primitive& inPrimitive) +{ + Uint32 constant = nthInputConstantUint32(inPrimitive, 1); + + DataNode& loadPrimitive = inPrimitive.nthInput(0).getVariable(); + MemDSIParameters parms(loadPrimitive); + assert(parms.scale <= 3); // eventually MemDSI will be limited to scale <=3 + + x86Instruction& newInsn = *new(mPool) x86Instruction(&inPrimitive, mPool, iaCmpImm, constant, memDSIAddressingModes[parms.scale], parms.displacement, 3, 1); + useProducer(parms.baseProducer, newInsn, 0); // <- base + useProducer(parms.indexProducer, newInsn, 1); // <- index + useProducer(loadPrimitive.nthInputVariable(0), newInsn, 2); // <- memory + defineProducer(inPrimitive, newInsn, 0); // -> compare result +} + +void x86Win32Emitter:: +emit_St_I_MemDSI(Primitive& inPrimitive) +{ + MemDSIParameters parms(inPrimitive); + assert(parms.scale <= 3); // eventually MemDSI will be limited to scale <=3 + + InsnDoubleOpDir& newInsn = + *new(mPool) InsnDoubleOpDir(&inPrimitive, mPool, raStoreI, parms.displacement, memDSIAddressingModes[parms.scale], atRegDirect, 4, 1); + useProducer(parms.baseProducer, newInsn, 0); // <- base + useProducer(parms.indexProducer, newInsn, 1); // <- index + useProducer(inPrimitive.nthInputVariable(2), newInsn, 2); // <- value reg + useProducer(inPrimitive.nthInputVariable(0), newInsn, 3); // <- memory edge + defineProducer(inPrimitive, newInsn, 0); // -> memory edge +} + +void x86Win32Emitter:: +emit_Ld_I_MemDSI(Primitive& inPrimitive) +{ + MemDSIParameters parms(inPrimitive); + assert(parms.scale <= 3); // eventually MemDSI will be limited to scale <=3 + + InsnDoubleOpDir& newInsn = + *new(mPool) InsnDoubleOpDir(&inPrimitive, mPool, raLoadI, parms.displacement, memDSIAddressingModes[parms.scale], atRegDirect, 3, 1); + + useProducer(parms.baseProducer, newInsn, 0); // <- base + useProducer(parms.indexProducer, newInsn, 1); // <- index + useProducer(inPrimitive.nthInputVariable(0), newInsn, 2); // <- memory edge + defineProducer(inPrimitive, newInsn, 0); // -> value +} + +//----------------------------------------------------------------------------------------------------------- +// Monitors + +void x86Win32Emitter:: +emit_MonitorEnter(Primitive& inPrimitive) +{ + // temporary, until we get syscall guard frames working on linux +#ifdef _WIN32 + new(mPool) CallS_V(&inPrimitive, mPool, CallS_V::numberOfArguments(inPrimitive), true, *this, (void (*)())guardedsysMonitorEnter); +#else + new(mPool) CallS_V(&inPrimitive, mPool, CallS_V::numberOfArguments(inPrimitive), true, *this, (void (*)())sysMonitorEnter); +#endif +} + +void x86Win32Emitter:: +emit_MonitorExit(Primitive& inPrimitive) +{ +#ifdef _WIN32 + new(mPool) CallS_V(&inPrimitive, mPool, CallS_V::numberOfArguments(inPrimitive), true, *this, (void (*)())guardedsysMonitorExit); +#else + new(mPool) CallS_V(&inPrimitive, mPool, CallS_V::numberOfArguments(inPrimitive), true, *this, (void (*)())sysMonitorExit); +#endif +} diff --git a/ef/Compiler/CodeGenerator/md/x86/x86Win32Emitter.h b/ef/Compiler/CodeGenerator/md/x86/x86Win32Emitter.h new file mode 100644 index 000000000000..9b1e8dcde12d --- /dev/null +++ b/ef/Compiler/CodeGenerator/md/x86/x86Win32Emitter.h @@ -0,0 +1,333 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +// +// x86Win32Emitter.h +// +// Peter DeSantis +// Simon Holmes a Court +// + +#ifndef X86_WIN32_EMITTER +#define X86_WIN32_EMITTER + +#include "InstructionEmitter.h" +#include "VirtualRegister.h" +#include "ControlNodes.h" + +#include "x86Opcode.h" + +class x86Instruction; +class InsnFloatMemory; +class x86ArgListInstruction; +class InsnDoubleOpDir; + +//----------------------------------------------------------------------------------------------------------- +inline Uint32 nthInputConstantUint32(/* const */ DataNode& inPrimitive, size_t inWhich) +{ + PrimConst* primConst = static_cast(&inPrimitive.nthInputVariable(inWhich)); + assert(primConst->hasCategory(pcConst)); + + Uint32 constant; + bool test = extractU32(primConst->value, constant); + assert(test); + return constant; +} + +//----------------------------------------------------------------------------------------------------------- +// MemDSIParameters +// common operations performed by all MemDSI modes +class MemDSIParameters +{ + public: + DataNode& addImmPrimitive; + DataNode& addPrimitive; + DataNode& shiftPrimitive; + + DataNode& baseProducer; + DataNode& indexProducer; + + uint32 displacement; + uint32 scale; + + MemDSIParameters(DataNode& inNode) : // should be load or store + addImmPrimitive(inNode.nthInputVariable(1)), + addPrimitive(addImmPrimitive.nthInputVariable(0)), + shiftPrimitive(addPrimitive.nthInputVariable(1)), + baseProducer(addPrimitive.nthInputVariable(0)), + indexProducer(shiftPrimitive.nthInputVariable(0)) + { + displacement = nthInputConstantUint32(addImmPrimitive, 1); + scale = nthInputConstantUint32(shiftPrimitive, 1); + } +}; + +//----------------------------------------------------------------------------------------------------------- +enum x86AddressModeType +{ + amNormal, + amMemDisp, + amMemDSI +}; + +enum RawConditionCode +{ + rawLt, + rawEq, + rawLe, + rawGt, + rawLgt, + rawGe +}; + +//----------------------------------------------------------------------------------------------------------- +// x86Win32Emitter +class x86Win32Emitter : + public InstructionEmitter +{ + friend class x86Instruction; + friend class x86Formatter; + +public: + x86Win32Emitter(Pool& inPool, VirtualRegisterManager& vrMan) : + InstructionEmitter(inPool, vrMan) + { } + + void emitPrimitive(Primitive& inPrimitive, NamedRule inRule); + + VirtualRegister& emit_CopyOfInput(x86ArgListInstruction& inInsn, DataNode& inPrimitive, Uint8 inWhichInput, VirtualRegisterID inID = vidLow); + + void emitArguments(ControlNode::BeginExtra& inBeginNode); + bool emitCopyAfter(DataNode& inDataNode, InstructionList::iterator where, VirtualRegister& fromVr, VirtualRegister& toVr); + void emitLoadAfter(DataNode& inDataNode, InstructionList::iterator where, VirtualRegister& loadedReg, VirtualRegister& stackReg); + void emitStoreAfter(DataNode& inDataNode, InstructionList::iterator where, VirtualRegister& storedReg, VirtualRegister& stackReg); + virtual Instruction& emitAbsoluteBranch(DataNode& inDataNode, ControlNode& inTarget); + + void emit_CallReturnF(InsnUseXDefineYFromPool& callInsn, DataNode& callPrimitive, DataNode& returnValProducer); + void emit_CallReturnD(InsnUseXDefineYFromPool& callInsn, DataNode& callPrimitive, DataNode& returnValProducer); + void emit_ArgF(PrimArg& arg, InstructionDefine& order, int curStackOffset); + void emit_ArgD(PrimArg& arg, InstructionDefine& order, int curStackOffset); + +private: + void emit_LoadAddress(Primitive& inPrimitive); + + // break + void emit_Break(Primitive& inPrimitive); + + // result + void emit_Result_I(Primitive& inPrimitive); + void emit_Result_L(Primitive& inPrimitive); + void emit_Result_F(Primitive& inPrimitive); + void emit_Result_D(Primitive& inPrimitive); + + void emit_Ld_I_MemDisp(Primitive& inPrimitive); + void emit_LimitR(Primitive& inPrimitive); + void emit_Limit(Primitive& inPrimitive); + + void emit_ExceptionCheck(Primitive& inPrimitive, x86ConditionCode condType, Uint32 constant, + void (*throwExceptionFunction)()); + + void emit_LimCast(Primitive& inPrimitive); + + void emit_ChkCast(Primitive& inPrimitive); + void emit_ChkCast_Const(Primitive& inPrimitive); + void emit_ChkNull(Primitive& inPrimitive); + + void emit_LoadConstant_I(Primitive& inPrimitive); + void emit_LoadConstant_L(Primitive& inPrimitive); + + void emit_LoadConstant_F(Primitive& inPrimitive); + void emit_LoadConstant_D(Primitive& inPrimitive); + + void genLdC_I(Primitive& inPrimitive); + void genLd_I(Primitive& inPrimitive); + + void emit_Ld_L(Primitive& inPrimitive); + void emit_St_L(Primitive& inPrimitive); + + // condition consumers + void emit_B(Primitive& inPrimitive, RawConditionCode rawCondType); + void emit_Cond(Primitive& inPrimitive, RawConditionCode rawCondType); + + // logical operator helpers + void genLogicI_I(Primitive& inPrimitive, x86ImmediateArithType iaType); + void genLogic_I(Primitive& inPrimitive, x86DoubleOpDirCode raType); + void emit_Logic_L(Primitive& inPrimitive, x86DoubleOpDirCode insnType); + + // and + void emit_AndI_I(Primitive& inPrimitive); + void emit_And_I(Primitive& inPrimitive); + void emit_And_L(Primitive& inPrimitive); + + // or + void emit_OrI_I(Primitive& inPrimitive); + void emit_Or_I(Primitive& inPrimitive); + void emit_Or_L(Primitive& inPrimitive); + + // xor + void emit_XorI_I(Primitive& inPrimitive); + void emit_Xor_I(Primitive& inPrimitive); + void emit_Xor_L(Primitive& inPrimitive); + + // shift helpers + void genShiftI_I(Primitive& inPrimitive, x86ExtendedType eByImmediate, x86ExtendedType eBy1); + void genShift_I(Primitive& inPrimitive, x86ExtendedType eByCl); + + // shl + void emit_ShlI_I(Primitive& inPrimitive); + void emit_Shl_I(Primitive& inPrimitive); + void emit_Shl_L(Primitive& inPrimitive); + + // sar + void emit_SarI_I(Primitive& inPrimitive); + void emit_Sar_I(Primitive& inPrimitive); + void emit_Sar_L(Primitive& inPrimitive); + + // shr + void emit_ShrI_I(Primitive& inPrimitive); + void emit_Shr_I(Primitive& inPrimitive); + void emit_Shr_L(Primitive& inPrimitive); + + // mul + void emit_Mul_I(Primitive& inPrimitive); +// void emit_MulI_I(Primitive& inPrimitive); // not yet implemented + void emit_Mul_L(Primitive& inPrimitive); + + void emit_Add_I(Primitive& inPrimitive); + void emit_AddI_I(Primitive& inPrimitive); + void emit_Add_L(Primitive& inPrimitive); + + void emit_Arithmetic_L(Primitive& inPrimitive, x86DoubleOpDirCode insnTypeLo, + x86DoubleOpDirCode insnTypeHi); + + void emit_Sub_I(Primitive& inPrimitive); + void emit_Sub_L(Primitive& inPrimitive); + + void emit_SubR_I(Primitive& inPrimitive); + + void emit_Cmp_I(Primitive& inPrimitive); + void emit_CmpI_I(Primitive& inPrimitive); + + void emit_3wayCmpL_L(Primitive& inPrimitive); + void emit_3wayCmpCL_L(Primitive& inPrimitive); + + void emit_3wayCmpF_L(Primitive& inPrimitive); + void emit_3wayCmpF_G(Primitive& inPrimitive); + void emit_3wayCmpD_L(Primitive& inPrimitive); + void emit_3wayCmpD_G(Primitive& inPrimitive); + void emit_3wayCmpCF_L(Primitive& inPrimitive); + void emit_3wayCmpCF_G(Primitive& inPrimitive); + void emit_3wayCmpCD_L(Primitive& inPrimitive); + void emit_3wayCmpCD_G(Primitive& inPrimitive); + + void emit_Limit_MemDisp(Primitive& inPrimitive); + void emit_LimitR_MemDisp(Primitive& inPrimitive); + void emit_CmpI_I_MemDSI(Primitive& inPrimitive); + void emit_Cmp_I_MemDSI(Primitive& inPrimitive); + + // div/mod + void emit_Div_L(Primitive& inPrimitive); + void emit_Mod_L(Primitive& inPrimitive); + + void emit_Div_I(Primitive& inPrimitive); + void emit_DivU_I(Primitive& inPrimitive); + void emit_Mod_I(Primitive& inPrimitive); + void emit_ModU_I(Primitive& inPrimitive); + + void emit_Div_I_MemDSI(Primitive& inPrimitive); + void emit_DivU_I_MemDSI(Primitive& inPrimitive); + void emit_Mod_I_MemDSI(Primitive& inPrimitive); + void emit_ModU_I_MemDSI(Primitive& inPrimitive); + + // div/mod helpers + x86Instruction& genDivMod_FrontEnd(Primitive& inPrimitive, x86ExtendedType insnType); + x86Instruction& genDivMod_FrontEnd_MemDSI(Primitive& inPrimitive, x86ExtendedType insnType); + x86Instruction& genDivMod_FrontEnd_CInt(Primitive& inPrimitive, x86ExtendedType insnType); + void genDivBackEnd(x86Instruction& inInsn); + void genModBackEnd(x86Instruction& inInsn); + + // extract + void emit_Ext_I(Primitive& inPrimitive); + void emit_Ext_L(Primitive& inPrimitive); + + // Floating Point Utilities + void emit_BinaryFloat(Primitive& inPrimitive, + x86FloatMemoryType binary_op, x86FloatMemoryType load_op, x86FloatMemoryType store_op, + VRClass vrClass); + void emit_BinaryFloat32(Primitive& inPrimitive, + x86FloatMemoryType binary_op); + void emit_BinaryFloat64(Primitive& inPrimitive, + x86FloatMemoryType binary_op); + void emit_3wayCmpF(Primitive& inPrimitive, DataNode& first_operand, DataNode& second_operand, + bool negate_result, x86FloatMemoryType load_op, x86FloatMemoryType cmpOp, VRClass vrClass); + + InsnDoubleOpDir& copyFromFloatToIntegerRegister(DataNode& inDataNode, InsnUseXDefineYFromPool& defInsn); + InsnDoubleOpDir& copyFromIntegerRegisterToFloat(DataNode& inDataNode, InsnUseXDefineYFromPool& defInsn); + + // Floating Point + void emit_FAdd_F(Primitive& inPrimitive); + void emit_FAdd_D(Primitive& inPrimitive); + void emit_FMul_F(Primitive& inPrimitive); + void emit_FMul_D(Primitive& inPrimitive); + void emit_FSub_F(Primitive& inPrimitive); + void emit_FSub_D(Primitive& inPrimitive); + void emit_FDiv_F(Primitive& inPrimitive); + void emit_FDiv_D(Primitive& inPrimitive); + + void emit_FRem_F(Primitive& inPrimitive); + void emit_FRem_D(Primitive& inPrimitive); + + // convert + void emit_ConvI_L(Primitive& inPrimitive); + void emit_ConvL_I(Primitive& inPrimitive); + + void emit_FConv(Primitive& inPrimitive); + + // load + void emit_Ld_I_MemDSI(Primitive& inPrimitive); + void emit_LdS_B(Primitive& inPrimitive); + void emit_LdU_B(Primitive& inPrimitive); + void emit_LdS_H(Primitive& inPrimitive); + void emit_LdU_H(Primitive& inPrimitive); + + void emit_Ld_F(Primitive& inPrimitive); + void emit_Ld_D(Primitive& inPrimitive); + + // store + void emit_St_B(Primitive& inPrimitive); + void emit_St_H(Primitive& inPrimitive); + void emit_StI_I(Primitive& inPrimitive); + void emit_St_I(Primitive& inPrimitive); + void emit_St_I_MemDSI(Primitive& inPrimitive); + void emit_StI_I_MemDisp(Primitive& inPrimitive); + void emit_St_I_MemDisp(Primitive& inPrimitive); + + void emit_St_F(Primitive& inPrimitive); + void emit_St_D(Primitive& inPrimitive); + + // catch + void emit_Catch(Primitive& inPrimitive); + + // switch + void emit_Switch(Primitive& inPrimitive); + + // monitors + void emit_MonitorEnter(Primitive& inPrimitive); + void emit_MonitorExit(Primitive& inPrimitive); +}; + +#endif // X86_WIN32_EMITTER diff --git a/ef/Compiler/CodeGenerator/md/x86/x86Win32Instruction.cpp b/ef/Compiler/CodeGenerator/md/x86/x86Win32Instruction.cpp new file mode 100644 index 000000000000..3d044e253648 --- /dev/null +++ b/ef/Compiler/CodeGenerator/md/x86/x86Win32Instruction.cpp @@ -0,0 +1,695 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +// +// x86Win32Instruction.cpp +// +// Simon Holmes a Court +// Peter DeSantis + +#include "prtypes.h" +#include "x86Win32Instruction.h" +#include "InstructionEmitter.h" +#include "x86Formatter.h" + +class x86Win32Emitter; +extern char* x86GPRText[]; + +UT_DEFINE_LOG_MODULE(x86Spill); + + +//================================================================================ +// Debugging Structures +#ifdef DEBUG_LOG + +char* conditionalSuffixes[] = +{ + "o", // ccJO + "no", // ccJNO + "b", // ccJB + "nb", // ccJNB + "e", // ccJE + "ne", // ccJNE + "be", // ccJBE + "nbe", // ccJNBE + "s", // ccJS + "ns", // ccJNS + "p", // ccJP + "np", // ccJNP + "l", // ccJL + "nl", // ccJNL + "le", // ccJLE + "nle", // ccJNLE +}; + +#endif // DEBUG_LOG + +//================================================================================ +// x86ArgListInstruction Methods + +// For now this is a member of x86ArgListInstruction, but it really should be available for all +// instructions on the x86 platform + +// Method: x86StandardUseDefine +// Caller: Emitter +// Purpose: Due to x86 behaviour of modifying source register, we must make a copy of the source before +// the operation. Unnecessary copies can be removed by the register allocator. +void x86ArgListInstruction:: +x86StandardUseDefine(x86Win32Emitter& inEmitter) +{ + InstructionUse* instructionUseBegin = getInstructionUseBegin(); + InstructionDefine* instructionDefineBegin = getInstructionDefineBegin(); + Uint8 curIndex; + + // Copy the virtual register which will be overwritten + VirtualRegister& vrToBeOverwritten = inEmitter.emit_CopyOfInput(*this, *mSrcPrimitive, 0); + + inEmitter.useProducer(*mSrcPrimitive, *this, 0); + + // Set the rest of the uses. + InstructionUse* curUse; + for (curUse = instructionUseBegin + 1, curIndex = 1; curUse < getInstructionUseEnd(); curUse++, curIndex++) + addStandardUse(inEmitter, curIndex); + + // Now redefine the copied register. + inEmitter.redefineTemporary(*this, vrToBeOverwritten, 0); + + assert(instructionDefineBegin + 1 >= getInstructionDefineEnd()); + //// Set the rest of the defines. + //InstructionDefine* curDefine; + //for (curDefine = instructionDefineBegin + 1, curIndex = 1; curDefine < getInstructionDefineEnd(); curDefine++, curIndex++) + // inEmitter.defineProducer(nthOutputProducer(*mSrcPrimitive, curIndex), *this, curIndex); +} + +// Method: switchUseToSpill +// Caller: Register Allocator +// Purpose: Folds the spill into the instruction if possible. +// Returns: Returns true if possible, false otherwise +bool x86ArgListInstruction:: +switchUseToSpill(Uint8 inWhichUse, VirtualRegister& inVR) +{ +#ifdef DEBUG_LOG + UT_LOG(x86Spill, PR_LOG_DEBUG, (" spill use %d of (%p)'", inWhichUse, this)); + printOpcode(UT_LOG_MODULE(x86Spill)); +#endif + DEBUG_ONLY(checkIntegrity();) + + if (!opcodeAcceptsSpill()) + goto SpillFail; + + // Ask the argument list if it can switch the current argument + if (iArgumentList->alSwitchArgumentTypeToSpill(inWhichUse, *this)) // has side effect! + { + // Tell the Opcode that the argumentlist has been switched to a spill + switchOpcodeToSpill(); + + // Replace the old virtual register with a new one which contains the colored stack slot. + InstructionUse& use = getInstructionUseBegin()[inWhichUse]; + InstructionDefine& define = getInstructionDefineBegin()[0]; + assert(use.isVirtualRegister()); + + if(inWhichUse == 0 && define.isVirtualRegister() && use.getVirtualRegister().getRegisterIndex() == define.getVirtualRegister().getRegisterIndex()) + // this virtual register is also redefined by this instruction so we must reinitialize the define also + define.getVirtualRegisterPtr().initialize(inVR); + use.getVirtualRegisterPtr().initialize(inVR); + DEBUG_ONLY(checkIntegrity();) + + goto SpillSuccess; + } + + // by default we fail +SpillFail: + UT_LOG(x86Spill, PR_LOG_DEBUG, ("': false\n")); + DEBUG_ONLY(checkIntegrity();) + return false; + +SpillSuccess: + UT_LOG(x86Spill, PR_LOG_DEBUG, ("': true\n")); + DEBUG_ONLY(checkIntegrity();) + return true; +} + +// Method: switchDefineToSpill +// Caller: Register Allocator +// Purpose: Folds the spill into the instruction if possible. +// Returns: Returns true if possible, false otherwise +bool x86ArgListInstruction:: +switchDefineToSpill(Uint8 inWhichDefine, VirtualRegister& inVR) +{ +#ifdef DEBUG_LOG + UT_LOG(x86Spill, PR_LOG_DEBUG, (" spill def %d of (%p)'", inWhichDefine, this)); + printOpcode(UT_LOG_MODULE(x86Spill)); +#endif + DEBUG_ONLY(checkIntegrity();) + + assert(inWhichDefine == 0); // can only switch the first define + + InstructionUse& use = getInstructionUseBegin()[0]; + InstructionUse* useEnd = getInstructionUseEnd(); + InstructionDefine& define = getInstructionDefineBegin()[inWhichDefine]; + + assert(define.isVirtualRegister()); // cannot call this routine on anything other than a virtual register + + // some instructions cannot spill + if (!opcodeAcceptsSpill()) + goto SpillFail; + + // If this register is being redefined then it should correspond to the first use + // Make sure that there is a first use + if(&use < useEnd) + { + // If it is indeed the same virtual register + if(use.isVirtualRegister() && use.getVirtualRegister().getRegisterIndex() == define.getVirtualRegister().getRegisterIndex()) + { + // define == first use, try to switch the first argument to spill type + if(opcodeAcceptsSpill() && iArgumentList->alSwitchArgumentTypeToSpill(0, *this)) + { + switchOpcodeToSpill(); // Tell the Opcode that the argumentlist has been switched to a spill + // Replace the old virtual register with a new one which contains the colored stack slot + // The define is also the same as the use so we need to reinitialize both the use and the define VR. + use.getVirtualRegisterPtr().initialize(inVR); + define.getVirtualRegisterPtr().initialize(inVR); + goto SpillSuccess; + } + } + else + { + // There are no other VRs in the uses, define is the second argument + if(opcodeAcceptsSpill() && iArgumentList->alSwitchArgumentTypeToSpill(1, *this)) + { + switchOpcodeToSpill(); // Tell the Opcode that the argumentlist has been switched to a spill + // Replace the old virtual register with a new one which contains the colored stack slot + define.getVirtualRegisterPtr().initialize(inVR); + goto SpillSuccess; + } + } + } + else + { + // There are no VRs in the uses so we need to try to switch the first argument + if(opcodeAcceptsSpill() && iArgumentList->alSwitchArgumentTypeToSpill(0, *this)) + { + switchOpcodeToSpill(); // Tell the Opcode that the argumentlist has been switched to a spill + // Replace the old virtual register with a new one which contains the colored stack slot + define.getVirtualRegisterPtr().initialize(inVR); + goto SpillSuccess; + } + } + + // by default we fail +SpillFail: + UT_LOG(x86Spill, PR_LOG_DEBUG, ("': false\n")); + DEBUG_ONLY(checkIntegrity();) + return false; + +SpillSuccess: + UT_LOG(x86Spill, PR_LOG_DEBUG, ("': true\n")); + DEBUG_ONLY(checkIntegrity();) + return true; +} + +//================================================================================ +// x86Instruction + +void x86Instruction:: +formatToMemory(void* inStart, Uint32 inOffset, MdFormatter& inFormatter) +{ + assert(iOpcode != NULL && iArgumentList != NULL); + // Format the opcode to memory + iOpcode->opFormatToMemory(inStart, *iArgumentList, *this); + // Find the location of the argumnet list and format it to memory + Uint8* argLocation = (Uint8*)inStart + iOpcode->opSize(); + iArgumentList->alFormatToMemory((void*)argLocation , inOffset, *this, inFormatter); + // If the opcode has an opcode extension then or it into the proper place. ( the reg field of the modr/m byte.) + if(iOpcode->opHasRegFieldExtension( *iArgumentList, *this )) + { + Uint8 temp = iOpcode->opGetRegFieldExtension(); + *argLocation = *argLocation | temp; + } +} + +//================================================================================ +// InsnSwitch + +InsnSwitch:: +InsnSwitch(DataNode* inPrimitive, Pool& inPool) : + InsnUseXDefineYFromPool(inPrimitive, inPool, 1, 0 ) +{ + mControlNode = inPrimitive->getContainer(); + assert(mControlNode); + mNumCases = mControlNode->nSuccessors(); +} + +void InsnSwitch:: +formatToMemory(void* inStartAddress, Uint32 /*inOffset*/, MdFormatter& inFormatter) +{ + Uint8* start = (Uint8*)inStartAddress; + + // calculate position of jump table + mTableAddress = start + 7; + + // get the register + Uint8 reg = useToRegisterNumber(*getInstructionUseBegin()); + assert (reg != ESP); // ESP is an invalid index + + // calculate the SIB + Uint8 SIB = 0x80 | ( reg << 3) | 0x05; + + // write out instruction + *start++ = 0xff; // opcode for jump + *start++ = 0x24; // mod/ext/rm for jmp disp32[reg * 4] + *start++ = SIB; + + // write address of jump table + writeLittleWordUnaligned(start, (int)mTableAddress); + + // write out table + Uint8* methodBegin = inFormatter.getMethodBegin(); + ControlEdge* edgesEnd = mControlNode->getSuccessorsEnd(); + for(ControlEdge* edge = mControlNode->getSwitchSuccessors(); edge != edgesEnd; edge++) + { + Uint8* destAddress = methodBegin + edge->getTarget().getNativeOffset(); + start += 4; + writeLittleWordUnaligned(start, (Uint32)destAddress); + } +} + +size_t InsnSwitch:: +getFormattedSize(MdFormatter& /*inFormatter*/) +{ + // reserve 7 bytes for the indexed jump, plus 4 bytes per entry + return 7 + (4 * mNumCases); +} + +#ifdef DEBUG_LOG +void InsnSwitch:: +printPretty(LogModuleObject &f) +{ + Uint8 reg = useToRegisterNumber(*getInstructionUseBegin()); + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("jmp 0x%x[4 * %s]", Uint32(mTableAddress), x86GPRText[reg])); + + // print table + ControlEdge* edgesEnd = mControlNode->getSuccessorsEnd(); + for(ControlEdge* edge = mControlNode->getSwitchSuccessors(); edge != edgesEnd; edge++) + { + Uint32 destAddress = edge->getTarget().getNativeOffset(); + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("\n Method Start + 0x%x [N%d]", + destAddress, edge->getTarget().dfsNum, edge->getTarget().dfsNum)); + } +} +#endif + +//================================================================================ +// InsnCondBranch + +void InsnCondBranch:: +formatToMemory(void* inStart, Uint32 inOffset, MdFormatter& /*inFormatter*/) +{ + uint8* start = (uint8*) inStart; + + *start++ = 0x0f; + *start++ = 0x80 | condType; + + // find destination + ControlNode& cnoTarget = cnoSource.getTrueSuccessor().getTarget(); + + // To compute the relative branch we subtract our current address from out target address. Then we subtract the size + // of our instruction because our current IP is actually there. This is the sum of the size of the opcode and the size of the + // argumentlist. NOTE: If we use 1 byte jumps in the future then this needs to be fixed from a constant 4. + const int opcodeSize = 2; + Int32 jumpOffset = cnoTarget.getNativeOffset() - inOffset - opcodeSize - 4; + writeLittleWordUnaligned(start, jumpOffset); +} + +#ifdef DEBUG_LOG + +void InsnCondBranch:: +printPretty(LogModuleObject &f) +{ + ControlNode& cnoTarget = cnoSource.getTrueSuccessor().getTarget(); + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("j%-7s start+%0d [N%d]", + conditionalSuffixes[condType], cnoTarget.getNativeOffset(), cnoTarget.dfsNum, cnoTarget.dfsNum)); +} + +#endif + +//================================================================================ +// Set + +// Can only be EAX, ECX, EDX or EBX +void InsnSet:: +formatToMemory(void* inStart, Uint32 /*inOffset*/, MdFormatter& /*inFormatter*/ ) +{ + uint8* start = (uint8*) inStart; + + // format the opcode to memory + *start++ = 0x0f; + *start++ = 0x90 | condType; + + // find the register + InstructionDefine* defineBegin = getInstructionDefineBegin(); + +#ifdef DEBUG + InstructionUse* useBegin = getInstructionUseBegin(); + InstructionUse* useEnd = getInstructionUseEnd(); + assert(useBegin < useEnd); // condition code always used + + InstructionDefine* defineEnd = getInstructionDefineEnd(); + assert((defineBegin < defineEnd) && defineBegin->isVirtualRegister()); +#endif + + Uint8 reg = defineToRegisterNumber(*defineBegin); + assert(/* (reg >= 0) && */ (reg <= 3)); // these are the only legal registers + + // format the register + Uint8 modRM = 0xc0 | reg; + *start = modRM; +} + +#ifdef DEBUG_LOG + +void InsnSet:: +printPretty(LogModuleObject &f) +{ + InstructionDefine* defineBegin = getInstructionDefineBegin(); + Uint8 reg = defineToRegisterNumber(*defineBegin); + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("set%-5s %s", conditionalSuffixes[condType], x86GPRText[reg])); +} + +#endif + +//================================================================================ +// InsnCondSysCallBranch +#ifdef DEBUG_LOG +void InsnSysCallCondBranch:: +printPretty(LogModuleObject &f) +{ + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("j%-7s (over next)\n call %p", conditionalSuffixes[condType], functionAddress)); +} +#endif + +//================================================================================ +// InsnCondSysCallBranch +struct x86NoArgsInfo +{ + uint8 opcode; // generally the opcode, but can have additional info + // eventually will be in DEBUG_LOG build only + char* text; // string for fake disassembly +}; + +x86NoArgsInfo noArgsInfo[] = +{ + { 0x99, "cdq" }, //opCdq 99 + { 0xcc, "int 3" }, //opBreak cc + { 0x9e, "sahf" }, //opSahf 9e +}; + +void InsnNoArgs:: +formatToMemory(void* inStart, Uint32 /*inOffset*/, MdFormatter& /*inFormatter*/) +{ + *((Uint8*)inStart) = (Uint8) noArgsInfo[code].opcode; +} + +#ifdef DEBUG_LOG +void InsnNoArgs:: +printPretty(LogModuleObject &f) +{ + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("%-8s", noArgsInfo[code].text)); +} +#endif + +//================================================================================ +// InsnDoubleOp Methods +struct x86DoubleOpInfo +{ + uint8 opcode; // generally the opcode, but can have additional info + bool hasPrefix; // does the opcode needs to be prefixed with 0x0f + + // eventually will be in DEBUG_LOG build only + char* text; // string for fake disassembly +}; + +x86DoubleOpInfo doubleOpInfo[] = +{ + { 0xaf, true, "imul " }, //opIMul 0f af + { 0xbe, true, "movsxB "}, //opMovSxB 0f be + { 0xbf, true, "movsxH "}, //opMovSxH 0f bf + { 0xb6, true, "movzxB "}, //opMovZxB 0f b6 + { 0xb7, true, "movzxH "} //opMovZxH 0f b7 +}; + +InsnDoubleOp:: +InsnDoubleOp( DataNode* inPrimitive, Pool& inPool, x86DoubleOpCode inCodeType, + x86ArgumentType inArgType1, x86ArgumentType inArgType2, + Uint8 uses, Uint8 defines ) : + x86ArgListInstruction (inPrimitive, inPool, uses, defines ), + codeType(inCodeType) +{ + iArgumentList = new x86DoubleArgumentList(inArgType1, inArgType2); + DEBUG_ONLY(debugType = kInsnDoubleOp); +} + +InsnDoubleOp:: +InsnDoubleOp( DataNode* inPrimitive, Pool& inPool, x86DoubleOpCode inCodeType, + Uint32 inDisplacement, + x86ArgumentType inArgType1, x86ArgumentType inArgType2, + Uint8 uses, Uint8 defines) : + x86ArgListInstruction (inPrimitive, inPool, uses, defines ), + codeType(inCodeType) +{ + iArgumentList = new x86DoubleArgumentList(inArgType1, inArgType2, inDisplacement); + DEBUG_ONLY(debugType = kInsnDoubleOp); +} + +void InsnDoubleOp:: +formatToMemory(void* inStart, Uint32 inOffset, MdFormatter& inFormatter) +{ + uint8* start = (uint8*) inStart; + assert(iArgumentList); + + // Format the opcode to memory + if(doubleOpInfo[codeType].hasPrefix) + *start++ = kPrefix_For_2_Byte; + *start = doubleOpInfo[codeType].opcode; + + // Find the location of the argumnet list and format it to memory + Uint8* argLocation = (Uint8*)inStart + opcodeSize(); + iArgumentList->alFormatToMemory((void*)argLocation , inOffset, *this, inFormatter); +} + +Uint8 InsnDoubleOp:: +opcodeSize() +{ + return (doubleOpInfo[codeType].hasPrefix) ? 2 : 1; +} + +#ifdef DEBUG_LOG +void InsnDoubleOp:: +printOpcode(LogModuleObject &f) +{ + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("%-8s ", doubleOpInfo[codeType].text)); +} +#endif + +//================================================================================ +// InsnDoubleOpDir Methods + +// used for debugging only (for now) +enum raType +{ + kArith, + kLoad, + kStore, + kCopy +}; + +struct x86RAOpcodeInfo +{ + uint8 opcode; // generally the opcode, but can have additional info + bool needs16BitPrefix; // does the opcode need the 'force to 16 bit' opcode? + raType type; // is it a move + + // eventually will be in DEBUG_LOG build only + char* text; // string for fake disassembly +}; + +// note: store dest, source +// note: copy +x86RAOpcodeInfo raInfo[] = +{ + { 0x01, false, kArith, "add " }, //raAdd + { 0x11, false, kArith, "adc " }, //raAdc + { 0x29, false, kArith, "sub " }, //raSub + { 0x19, false, kArith, "sbb " }, //raSbb + { 0x21, false, kArith, "and " }, //raAnd + { 0x09, false, kArith, "or " }, //raOr + { 0x31, false, kArith, "xor " }, //raXor + { 0x39, false, kArith, "cmp " }, //raCmp + + { 0x89, false, kLoad, "mov(ld) " }, //raLoadI + { 0x89, false, kCopy, "mov(cp) " }, //raCopyI + { 0x89, false, kStore, "mov(st) " }, //raStoreI + { 0x89, false, kStore, "mov(sv) " }, //raSaveReg + + { 0x88, false, kStore, "movB "}, //raStoreB + { 0x89, true, kStore, "movH "}, //raStoreH +}; + +InsnDoubleOpDir:: +InsnDoubleOpDir(DataNode* inPrimitive, Pool& inPool, x86DoubleOpDirCode inCodeType, + x86ArgumentType inArgType1, x86ArgumentType inArgType2, + Uint8 uses, Uint8 defines ) : + x86ArgListInstruction (inPrimitive, inPool, uses, defines ), + codeType(inCodeType) +{ + iArgumentList = new x86DoubleArgumentList(inArgType1, inArgType2); + DEBUG_ONLY(debugType = kInsnDoubleOpDir); + + // temp for asserts + getDirectionBit(); +} + +InsnDoubleOpDir:: +InsnDoubleOpDir(DataNode* inPrimitive, Pool& inPool, x86DoubleOpDirCode inCodeType, + Uint32 inDisplacement, x86ArgumentType inArgType1, x86ArgumentType inArgType2, + Uint8 uses, Uint8 defines) : + x86ArgListInstruction (inPrimitive, inPool, uses, defines ), + codeType(inCodeType) +{ + iArgumentList = new x86DoubleArgumentList(inArgType1, inArgType2, inDisplacement); + DEBUG_ONLY(debugType = kInsnDoubleOpDir); + + // temp for asserts + getDirectionBit(); +} + +// copy flag should only be set if insn is a copy and the use and define are registerDirect -- no other flags can be set +InstructionFlags InsnDoubleOpDir:: +getFlags() const +{ + return (codeType == raCopyI && iArgumentList->alIsRegisterDirect()) ? ifCopy : ifNone; +} + +bool InsnDoubleOpDir:: +getDirectionBit() +{ + x86DoubleArgumentList* arglist = (x86DoubleArgumentList*)iArgumentList; + bool arg1isDirect = arglist->akIsArg1Direct(); + bool arg2isDirect = arglist->akIsArg2Direct(); + assert(arg1isDirect || arg2isDirect); // at least one has to be register direct + + bool dirBit; + + switch(codeType) + { + case raSaveReg: + // Save Instructions + // saves use (first arg) to stack slot (define) + // mov r1 -> M => mov r1 -> M dir = false + assert(arg1isDirect); + assert(!arg2isDirect); + dirBit = false; + break; + + case raCopyI: + // Copy Instructions + /* OLD + // copies use (first arg) to define (second arg) + // mov r1 -> r2 => mov r1 -> r2 dir = false + // mov r1 -> M => mov r1 -> M dir = false + // mov M -> r2 => mov r2 <- M dir = true + // ie direction bit is clear iff argument 1 is registerDirect + dirBit = !arg1isDirect; + break; + */ + + // copies use (first arg) to define (second arg) + // mov r1 -> r2 => mov r2 <- r1 dir = true + // mov r1 -> M => mov r1 -> M dir = false + // mov M -> r2 => mov r2 <- M dir = true + // ie direction bit is clear iff argument 1 is registerDirect + dirBit = arg2isDirect; + break; + + case raStoreB: + case raStoreH: + case raStoreI: + // Store Instruction + // stores second use into first use memory + // mov M <- r2 => mov r2 -> M dir = false + dirBit = false; + assert(!arg1isDirect); + assert(arg2isDirect); + break; + + case raLoadI: + // Load Instruction + // loads from memory address (use, first arg) into register (define, second arg) + // mov M -> r1 => mov r1 <- M dir = true + dirBit = true; + assert(!arg1isDirect); + assert(arg2isDirect); + break; + + default: + // Arithmetic Instructions + // add r1, r2 => add r1, r2 dir = true + // add r1, M => add r1, M dir = true + // add M, r2 => add r2, M dir = false + // ie direction bit is set iff argument 1 is registerDirect + assert(raInfo[codeType].type == kArith); + dirBit = arg1isDirect; + } + + return dirBit; +} + +void InsnDoubleOpDir:: +formatToMemory(void* inStart, Uint32 inOffset, MdFormatter& inFormatter) +{ + uint8* start = (uint8*) inStart; + assert(iArgumentList); + + // Format the opcode to memory + if(raInfo[codeType].needs16BitPrefix) + *start++ = kPrefix_For_16_Bits; + + // calculate opcode + Uint8 direction = getDirectionBit() ? 2 : 0; + Uint8 opcode = raInfo[codeType].opcode | direction; + *start = opcode; + + // Find the location of the argumnet list and format it to memory + Uint8* argLocation = (Uint8*)inStart + opcodeSize(); + iArgumentList->alFormatToMemory((void*)argLocation , inOffset, *this, inFormatter); +} + +Uint8 InsnDoubleOpDir:: +opcodeSize() +{ + return (raInfo[codeType].needs16BitPrefix) ? 2 : 1; +} + +#ifdef DEBUG_LOG +void InsnDoubleOpDir:: +printOpcode(LogModuleObject &f) +{ + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("%-8s ", raInfo[codeType].text)); +} +#endif + +//================================================================================ diff --git a/ef/Compiler/CodeGenerator/md/x86/x86Win32Instruction.h b/ef/Compiler/CodeGenerator/md/x86/x86Win32Instruction.h new file mode 100644 index 000000000000..b630d38d847e --- /dev/null +++ b/ef/Compiler/CodeGenerator/md/x86/x86Win32Instruction.h @@ -0,0 +1,655 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +// +// x86Win32Instruction.h +// +// Peter DeSantis +// Simon Holmes a Court + +#ifndef X86_WIN32_INSTRUCTION +#define X86_WIN32_INSTRUCTION + +#include "CatchAssert.h" +#include + +#include "prtypes.h" +#include "Instruction.h" +#include "InstructionEmitter.h" +#include "VirtualRegister.h" +#include "Value.h" +#include "x86Opcode.h" +#include "x86ArgumentList.h" +#include "MemoryAccess.h" +#include "LogModule.h" +#include "NativeCodeCache.h" + + +#ifdef DEBUG +enum instructionObjType +{ + kx86Instruction, + kSetInstruction, + + kInsnDoubleOpDir, + kInsnDoubleOp, + + kStandardArith, + kStandardArithDisp, + kNotKnown +}; +#endif +//================================================================================ +/* + + x86Instruction(being eliminated) InsnSet + InsnDoubleOp InsnSwitch + InsnDoubleOpDir InsnSysCallCondBranch + | InsnCondBranch + | InsnNoArgs + x86ArglistInstruction Call + \ / + \ / + \ / + InsnUseXDefineYFromPool + | + Instruction (can't spill) +*/ +//================================================================================ +// x86ArgListInstruction + +class x86ArgListInstruction : + public InsnUseXDefineYFromPool +{ +public: + x86ArgListInstruction(DataNode* inPrimitive, Pool& inPool, Uint8 inX, Uint8 inY) : + InsnUseXDefineYFromPool (inPrimitive, inPool, inX, inY ) + { + DEBUG_ONLY(debugType = kNotKnown); + } + + // utility + void x86StandardUseDefine(x86Win32Emitter& inEmitter); + + // virtual methods that must be written + virtual Uint8 opcodeSize() = 0; + + // defaults to (result of opcodeSize() + iArgumentList->alSize(*this)) + virtual size_t getFormattedSize(MdFormatter& /*inFormatter*/); + virtual void formatToMemory(void * /*inStart*/, Uint32 /*inCurOffset*/, MdFormatter& /*inFormatter*/) = 0; + + // flags + InstructionFlags getFlags() const { return ifNone; } + + // spilling + virtual bool switchUseToSpill(Uint8 inWhichUse, VirtualRegister&inVR); + virtual bool switchDefineToSpill(Uint8 inWhichDefine, VirtualRegister& inVR); + + // Control Spilling + // eg switch cannot spill (at least for now) + // eg special mem-reg type does funky things when spilling + virtual bool opcodeAcceptsSpill() { return true; } // most instructions can spill + virtual void switchOpcodeToSpill() { } // most opcodes don't change on spilling + + // simple arithmetic and move instructions have a direction bit + virtual bool canReverseOperands() { return false; } // most instructions can't reverse their operands + + // immediates + virtual bool opcodeCanAccept1ByteImmediate() { return false; } + virtual bool opcodeCanAccept4ByteImmediate() { return false; } + virtual bool opcodeCanAcceptImmediate() { return (opcodeCanAccept1ByteImmediate() || opcodeCanAccept4ByteImmediate()); } + + // condensable + virtual bool regOperandCanBeCondensed() { return false; } + +protected: + x86ArgumentList* iArgumentList; + +public: +#ifdef DEBUG_LOG + // Debugging Methods + virtual void printPretty(LogModuleObject &f); + virtual void printOpcode(LogModuleObject &f) = 0; +#endif // DEBUG_LOG + +#ifdef DEBUG + instructionObjType debugType; // used so we know what type of object we are in the debugger + void checkIntegrity() { iArgumentList->alCheckIntegrity(*this); } + void printArgs() { iArgumentList->alPrintArgs(*this); } +#endif // DEBUG +}; + +inline size_t x86ArgListInstruction:: +getFormattedSize(MdFormatter& inFormatter) +{ + assert(iArgumentList != NULL); + size_t size = opcodeSize() + iArgumentList->alSize(*this, inFormatter); + return size; +} + +#ifdef DEBUG_LOG + +inline void x86ArgListInstruction:: +printPretty(LogModuleObject &f) +{ + printOpcode(f); + assert(iArgumentList != NULL); + iArgumentList->alPrintPretty(f, *this ); +} + +#endif // DEBUG_LOG + +//================================================================================ +// x86Instruction +// This mega-class will eventually be phased out as it is split up into smaller classes + +class x86Instruction : + public x86ArgListInstruction +{ +public: + //-------------------------------------------------------------------------------- + // ImmediateArithType Instructions + + x86Instruction (DataNode* inPrimitive, Pool& inPool, ControlNode& inControlNode) : + x86ArgListInstruction (inPrimitive, inPool, 0, 0 ) , flags(ifNone) + { + iOpcode = new x86Opcode_ImmArith( iaJmp ); + iArgumentList = new x86ControlNodeOffsetArgumentList( inControlNode ); + } + + x86Instruction (DataNode* inPrimitive, Pool& inPool, x86ImmediateArithType inOpInfo, Uint32 inConstant, x86ArgumentType inArgType1, Uint8 inX, Uint8 inY) : + x86ArgListInstruction (inPrimitive, inPool, inX, inY ) , flags(ifNone) + { + iOpcode = new x86Opcode_ImmArith( inOpInfo ); + iArgumentList = new x86ImmediateArgumentList( inArgType1, inConstant ); + } + + x86Instruction (DataNode* inPrimitive, Pool& inPool, x86ImmediateArithType inOpInfo, Uint32 inConstant, x86ArgumentType inArgType1, Uint32 inDisplacement, Uint8 inX, Uint8 inY) : + x86ArgListInstruction (inPrimitive, inPool, inX, inY ) , flags(ifNone) + { iOpcode = new x86Opcode_ImmArith( inOpInfo ); + iArgumentList = new x86ImmediateArgumentList( inArgType1, inDisplacement, inConstant ); } + + //-------------------------------------------------------------------------------- + // ExtendedType Instructions + + x86Instruction (DataNode* inPrimitive, Pool& inPool, x86ExtendedType inOpInfo, Uint32 inConstant, x86ArgumentType inArgType1, Uint8 inX, Uint8 inY) : + x86ArgListInstruction (inPrimitive, inPool, inX, inY ) , flags(ifNone) + { iOpcode = new x86Opcode_Reg( inOpInfo ); + iArgumentList = new x86ImmediateArgumentList( inArgType1, inConstant ); } + + x86Instruction (DataNode* inPrimitive, Pool& inPool, x86ExtendedType inOpInfo, Uint32 inConstant, x86ArgumentType inArgType1, Uint32 inDisplacement, Uint8 inX, Uint8 inY) : + x86ArgListInstruction (inPrimitive, inPool, inX, inY ) , flags(ifNone) + { iOpcode = new x86Opcode_Reg( inOpInfo ); + iArgumentList = new x86ImmediateArgumentList( inArgType1, inDisplacement, inConstant ); } + + x86Instruction (DataNode* inPrimitive, Pool& inPool, x86ExtendedType inOpInfo, x86ArgumentType inArgType1, Uint8 inX, Uint8 inY ) : + x86ArgListInstruction (inPrimitive, inPool, inX, inY ) , flags(ifNone) + { iOpcode = new x86Opcode_Reg( inOpInfo ); + iArgumentList = new x86SingleArgumentList( inArgType1 ); } + + x86Instruction (DataNode* inPrimitive, Pool& inPool, x86ExtendedType inOpInfo, x86ArgumentType inArgType1, Uint32 inDisplacement, Uint8 inX, Uint8 inY) : + x86ArgListInstruction (inPrimitive, inPool, inX, inY ) , flags(ifNone) + { iOpcode = new x86Opcode_Reg( inOpInfo ); + iArgumentList = new x86SingleArgumentList( inArgType1, inDisplacement ); } + + //-------------------------------------------------------------------------------- + // CondensableExtendedType Instructions + x86Instruction (DataNode* inPrimitive, Pool& inPool, x86CondensableExtendedType inOpInfo, Uint32 inConstant, x86ArgumentType inArgType1, Uint8 inX, Uint8 inY) : + x86ArgListInstruction (inPrimitive, inPool, inX, inY ) , flags(ifNone) + { iOpcode = new x86Opcode_Condensable_Reg( inOpInfo ); + iArgumentList = new x86CondensableImmediateArgumentList( inArgType1, inConstant ); } + + x86Instruction (DataNode* inPrimitive, Pool& inPool, x86CondensableExtendedType inOpInfo, x86ArgumentType inArgType1, Uint8 inX, Uint8 inY) : + x86ArgListInstruction (inPrimitive, inPool, inX, inY ) , flags(ifNone) + { iOpcode = new x86Opcode_Condensable_Reg( inOpInfo ); + iArgumentList = new x86SingleArgumentList( inArgType1 ); } + + //-------------------------------------------------------------------------------- + // SpecialRegMemType Instruction + x86Instruction (DataNode* inPrimitive, Pool& inPool, x86SpecialRegMemType inType, Uint32 inImmediate, Uint8 inX, Uint8 inY ) : + x86ArgListInstruction (inPrimitive, inPool, inX, inY ) , flags(ifNone) + { iOpcode = new x86Opcode_SpecialRegMem( inType ); + iArgumentList = new x86SpecialRegMemArgumentList( inImmediate ); } + + size_t getFormattedSize(MdFormatter& /*inFormatter*/); + virtual void formatToMemory(void * /*inStart*/, Uint32 /*inCurOffset*/, MdFormatter& /*inFormatter*/); + + // access flags + InstructionFlags getFlags() const { return flags; } + void setFlags(InstructionFlags f) { flags = f; } + + // Allows ArgumentList access to opcode without passing the extra reference to the opcode. + Uint8 opcodeSize(){ return iOpcode->opSize(); } + bool opcodeCanAccept1ByteImmediate() { return iOpcode->opCanAccept1ByteImmediate(); } + bool opcodeCanAccept4ByteImmediate() { return iOpcode->opCanAccept4ByteImmediate(); } + bool regOperandCanBeCondensed() { return iOpcode->opRegOperandCanBeCondensed(); } + + + virtual bool opcodeAcceptsSpill() { return true; } + virtual void switchOpcodeToSpill() { iOpcode->opSwitchToRegisterIndirect(); } + +protected: + x86Opcode* iOpcode; + InstructionFlags flags; // Used to mark copy instructions so the register allocator can remove them. + +public: +#ifdef DEBUG_LOG + void printOpcode(LogModuleObject &f); +#endif // DEBUG_LOG +}; + +//-------------------------------------------------------------------------------- + +// FIX these two methods should be removed (third method replaces them) +inline Uint8 useToRegisterNumber(InstructionUse& inUse) +{ + return colorTox86GPR[inUse.getVirtualRegister().getColor()]; +} + +inline Uint8 defineToRegisterNumber(InstructionDefine& inDefine) +{ + Uint8 color = inDefine.getVirtualRegister().getColor(); + return colorTox86GPR[color]; +} + +inline Uint8 getRegisterNumber(VirtualRegister* vreg) +{ + Uint8 color = vreg->getColor(); + assert(color < 6); + return colorTox86GPR[color]; +} + +//-------------------------------------------------------------------------------- +inline size_t x86Instruction:: +getFormattedSize(MdFormatter& inFormatter) +{ + assert(iOpcode != NULL && iArgumentList != NULL); + return (iOpcode->opSize() + iArgumentList->alSize(*this, inFormatter)); +} + +#ifdef DEBUG_LOG +inline void x86Instruction:: +printOpcode(LogModuleObject &f) +{ + iOpcode->opPrintPretty(f); +} +#endif DEBUG_LOG + +//================================================================================ +// InsnNoArgs +class InsnNoArgs : + public InsnUseXDefineYFromPool +{ +public: + InsnNoArgs(DataNode* inPrimitive, Pool& inPool, x86NoArgsCode inCode, Uint8 inUses, Uint8 inDefines) : + InsnUseXDefineYFromPool(inPrimitive, inPool, inUses, inDefines), + code(inCode) + {} + + virtual void formatToMemory(void* inStart, Uint32 /*inOffset*/, MdFormatter& /*inFormatter*/); + virtual size_t getFormattedSize(MdFormatter& /*inFormatter*/) { return 1; } + InstructionFlags getFlags() const { return ifNone; } + virtual bool opcodeAcceptsSpill() { return false; } + virtual void switchOpcodeToSpill() { assert(false); } + +protected: + x86NoArgsCode code; +#ifdef DEBUG_LOG +public: + virtual void printPretty(LogModuleObject &f); +#endif +}; + +//================================================================================ +// InsnSwitch +class InsnSwitch : + public InsnUseXDefineYFromPool +{ +public: + InsnSwitch(DataNode* inPrimitive, Pool& inPool); + + virtual void formatToMemory(void* inStart, Uint32 inOffset, MdFormatter& /*inFormatter*/); + virtual size_t getFormattedSize(MdFormatter& /*inFormatter*/); + + InstructionFlags getFlags() const { return ifNone; } + + // can't spill + virtual bool opcodeAcceptsSpill() { return false; } + virtual void switchOpcodeToSpill() { assert(false); } + +protected: + Uint32 mNumCases; + ControlNode* mControlNode; + Uint8* mTableAddress; + +#ifdef DEBUG_LOG +public: + virtual void printPretty(LogModuleObject &f); +#endif +}; + +//================================================================================ +// InsnCondBranch +// FIX For now all branches take 4 bytes immediates -- eventually we want this to take +// the minimum possible +class InsnCondBranch : + public InsnUseXDefineYFromPool +{ +public: + InsnCondBranch(DataNode* inPrimitive, Pool& inPool, x86ConditionCode condType, ControlNode& inControlNode) : + InsnUseXDefineYFromPool(inPrimitive, inPool, 1, 0), + condType(condType), + cnoSource(inControlNode) + {}; + + virtual void formatToMemory(void* inStart, Uint32 inOffset, MdFormatter& /*inFormatter*/); + virtual size_t getFormattedSize(MdFormatter& /*inFormatter*/) { return 6; } + InstructionFlags getFlags() const { return ifNone; } + virtual bool opcodeAcceptsSpill() { return false; } // spilling makes no sense here + virtual void switchOpcodeToSpill() { assert(false); } + +protected: + x86ConditionCode condType; // x86 condition codes + ControlNode& cnoSource; // the source of the branch + +#ifdef DEBUG_LOG +public: + virtual void printPretty(LogModuleObject &f); +#endif +}; + +//================================================================================ +// InsnSysCallCondBranch +// emit +// jcc OK +// call inFunc +// OK: +// +class InsnSysCallCondBranch : + public InsnUseXDefineYFromPool +{ +public: + InsnSysCallCondBranch(DataNode* inPrimitive, Pool& inPool, x86ConditionCode inCondType, void (*inFunc)()) : + InsnUseXDefineYFromPool(inPrimitive, inPool, 1, 0), + functionAddress(inFunc), + condType(inCondType) + {}; + + virtual void formatToMemory(void* inStart, Uint32 /*inOffset*/, MdFormatter& /*inFormatter*/) + { + Uint8* start = (Uint8*) inStart; + + // emit jump + *start++ = 0x0f; + *start++ = 0x80 + condType; + writeLittleWordUnaligned((void*)start, 5); + start += 4; + + // emit call + Uint8* callStart = start; + *start++ = 0xe8; + int32 branchOffset = (Uint32)functionAddress - (Uint32) callStart - 5; + writeLittleWordUnaligned((void*)start, branchOffset); + } + + virtual size_t getFormattedSize(MdFormatter& /*inFormatter*/) { return 6 + 5; } + + InstructionFlags getFlags() const { return ifNone; } + virtual bool opcodeAcceptsSpill() { return false; } // spilling makes no sense here + virtual void switchOpcodeToSpill() { assert(false); } + +protected: + void* functionAddress; + x86ConditionCode condType; + +#ifdef DEBUG_LOG +public: + virtual void printPretty(LogModuleObject &f); +#endif +}; + +//================================================================================ +// Set on condition flags +// cannot spill + +// uses a condition +class InsnSet : + public InsnUseXDefineYFromPool +{ +public: + InsnSet(DataNode* inPrimitive, Pool& inPool, x86ConditionCode condType, int inX = 2, int inY = 1) : + InsnUseXDefineYFromPool(inPrimitive, inPool, inX, inY ), + condType(condType) + {} + + virtual void formatToMemory(void* inStart, Uint32 inOffset, MdFormatter& /* inFormatter */ ); + virtual size_t getFormattedSize(MdFormatter& /*inFormatter*/) { return 3; } // 0xff 0x90 reg + virtual Uint8 opcodeSize() { return 2; } + +protected: + x86ConditionCode condType; // x86 condition codes + +#ifdef DEBUG_LOG +public: + virtual void printPretty(LogModuleObject &f); +#endif +}; + +//================================================================================ +/* InsnDoubleOp + 0110 1001:11 reg1 reg2: immdata register1 with immediate to register2 + 0110 1001:mod reg r/m: immdata register with immediate to register + + 0000 1111:1010 1111: 11 reg1 reg2 register1 with register2 + 0000 1111:1010 1111: mod reg r/m register with memory +*/ +class InsnDoubleOp : + public x86ArgListInstruction +{ +public: + InsnDoubleOp( DataNode* inPrimitive, Pool& inPool, x86DoubleOpCode inCodeType, + x86ArgumentType inArgType1 = atRegDirect, x86ArgumentType inArgType2 = atRegDirect, + Uint8 uses = 2, Uint8 defines = 1 ); + + InsnDoubleOp( DataNode* inPrimitive, Pool& inPool, x86DoubleOpCode inCodeType, + Uint32 inDisplacement, + x86ArgumentType inArgType1 = atRegDirect, x86ArgumentType inArgType2 = atRegDirect, + Uint8 uses = 2, Uint8 defines = 1 ); + + virtual bool canReverseOperands() { return false; } + virtual void formatToMemory(void* inStart, Uint32 inOffset, MdFormatter& inFormatter); + virtual Uint8 opcodeSize(); + +protected: + x86DoubleOpCode codeType; + +public: +#ifdef DEBUG_LOG + virtual void printOpcode(LogModuleObject &f); +#endif +}; + +//================================================================================ +// InsnDoubleOpDir + +// use the default spilling behaviour for x86ArgListInstruction +class InsnDoubleOpDir : + public x86ArgListInstruction +{ +public: + InsnDoubleOpDir(DataNode* inPrimitive, Pool& inPool, x86DoubleOpDirCode inCodeType, + x86ArgumentType inArgType1 = atRegDirect, x86ArgumentType inArgType2 = atRegDirect, + Uint8 uses = 2, Uint8 defines = 1 ); + + InsnDoubleOpDir(DataNode* inPrimitive, Pool& inPool, x86DoubleOpDirCode inCodeType, + Uint32 inDisplacement, + x86ArgumentType inArgType1 = atRegDirect, x86ArgumentType inArgType2 = atRegDirect, + Uint8 uses = 2, Uint8 defines = 1 ); + + // the main feature of these instructions is their ability to reverse operands + virtual bool canReverseOperands() { return true; } + virtual void formatToMemory(void* inStart, Uint32 inOffset, MdFormatter& inFormatter); + virtual Uint8 opcodeSize(); + InstructionFlags getFlags() const; // ifCopy if we are an unspilt move, ifNone otherwise + +protected: + bool getDirectionBit(); + x86DoubleOpDirCode codeType; + +public: +#ifdef DEBUG_LOG + virtual void printOpcode(LogModuleObject &f); +#endif +}; + +//================================================================================ +// Utililty +// Returns a new copy instruction +inline InsnDoubleOpDir& +newCopyInstruction(DataNode& inDataNode, Pool& inPool, Uint8 uses = 1, Uint8 defines = 1) +{ + return *new(inPool) InsnDoubleOpDir(&inDataNode, inPool, raCopyI, atRegDirect, atRegDirect, uses, defines); +} + +//================================================================================ +// Calls + +template +class Call : + public InsnUseXDefineYFromPool +{ +public: + static inline bool hasReturnValue(DataNode& inDataNode); + static inline Uint8 numberOfArguments(DataNode& inDataNode); + + + Call( DataNode* inDataNode, + Pool& inPool, + Uint8 inRegisterArguments, + bool inHasReturnValue, + x86Win32Emitter& inEmitter, + void (*inFunc)() = NULL, + DataNode* inUseDataNode = NULL ); + +public: + virtual void formatToMemory(void* inStart, Uint32 inOffset, MdFormatter& /*inFormatter*/); + virtual size_t getFormattedSize(MdFormatter& /*inFormatter*/) { return (5); } + virtual InstructionFlags getFlags() const { return (ifCall); } + +protected: + Uint32 mCalleeAddress; + +#ifdef DEBUG_LOG +public: + virtual void printPretty(LogModuleObject &f) + { + CacheEntry* ce = NativeCodeCache::getCache().lookupByRange((Uint8*)mCalleeAddress); + if(ce) + { + Method* method = ce->descriptor.method; + assert(method); + const char* name = method->getName(); + const char* tag = method->getHTMLName(); + UT_OBJECTLOG(f, PR_LOG_ALWAYS, (" call %s", tag, name)); + } + else + UT_OBJECTLOG(f, PR_LOG_ALWAYS, (" call %p", (Uint32 *)mCalleeAddress)); + } +#endif +}; + +template +class CallS : + public Call +{ +public: + + inline CallS( DataNode* inDataNode, + Pool& inPool, + Uint8 inRegisterArguments, + bool inHasReturnValue, + x86Win32Emitter& inEmitter, + void (*inFunc)(), + DataNode* inUseDataNode = NULL ) : + Call(inDataNode, inPool, inRegisterArguments, inHasReturnValue, inEmitter, inFunc, inUseDataNode) { } +}; + +typedef CallS CallS_V; +typedef CallS CallS_; +typedef CallS CallS_C; +typedef Call Call_; + +// Dynamically dispatched call +class CallD_ : + public Call +{ +public: + inline CallD_(DataNode* inDataNode, Pool& inPool, Uint8 inRegisterArguments, bool inHasReturnValue, x86Win32Emitter& inEmitter) : + Call(inDataNode, inPool, inRegisterArguments, inHasReturnValue, inEmitter) { } + + inline virtual void formatToMemory(void* inStart, Uint32 /*inOffset*/, MdFormatter& inEmitter); + virtual size_t getFormattedSize(MdFormatter& /*inFormatter*/) { return (2); } + +#ifdef DEBUG_LOG + virtual void printPretty(LogModuleObject &f) { UT_OBJECTLOG(f, PR_LOG_ALWAYS, (" call ???")); } +#endif +}; + +template bool +Call:: +hasReturnValue(DataNode& inDataNode) +{ + bool hasReturnValue = (inDataNode.getOutgoingEdgesBegin() + tHasOutgoingStore < inDataNode.getOutgoingEdgesEnd()); + + return (hasReturnValue); +} + +template Uint8 +Call:: +numberOfArguments(DataNode& inDataNode) +{ + DataConsumer* firstArg; + DataConsumer* lastArg; + + assert(!(tHasFunctionAddress && !tHasIncomingStore)); // no such primitive + firstArg = inDataNode.getInputsBegin() + tHasFunctionAddress + tHasIncomingStore; + lastArg = inDataNode.getInputsEnd(); + + return (lastArg - firstArg); +} + +template +void Call:: +formatToMemory(void* inStart, Uint32 /*inOffset*/, MdFormatter& /*inFormatter*/) +{ + Uint8* start = (Uint8*)inStart; + int32 branchOffset = mCalleeAddress - (Uint32) inStart - 5; + *start++ = 0xe8; + writeLittleWordUnaligned((void*)start, branchOffset); +} + + +inline void CallD_:: +formatToMemory(void* inStart, Uint32 /*inOffset*/, MdFormatter& /*inFormatter*/) +{ + Uint8 *curPC = (Uint8 *) inStart; + + *curPC++ = 0xff; + *curPC++ = 0xd0 | useToRegisterNumber(getInstructionUseBegin()[0]); +} + +#endif diff --git a/ef/Compiler/CodeGenerator/md/x86/x86Win32_Support.cpp b/ef/Compiler/CodeGenerator/md/x86/x86Win32_Support.cpp new file mode 100644 index 000000000000..4c673f33fe86 --- /dev/null +++ b/ef/Compiler/CodeGenerator/md/x86/x86Win32_Support.cpp @@ -0,0 +1,435 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +// +// File: x86Win32_support.cpp +// +// Authors: Peter DeSantis +// Simon Holmes a Court +// + +#include "NativeCodeCache.h" +#include +#include "Fundamentals.h" +#include "MemoryAccess.h" + + +void* JNIenv = 0; + +extern ClassWorld world; + +#define Naked __declspec( naked ) + +/* + +-------------------------------+ + | return address | + ========+===============================+======== + | EBP link | + +-------------------------------+ + | Saved Non-volatiles | + | eg. EDI | + | ESI | + | EBX | + +-------------------------------+ +*/ + +// Fucntion: staticCompileStub +// +// WARNING: if you change this method, you must change compileStubReEntryPoint below. +// It must point to the instruction after the invokation of compileAndBackPatchMethod +static Naked void staticCompileStub() +{ + _asm + { + // remove cache entry from the stack + pop eax + + // make frame + push ebp + mov ebp,esp + + // save all volatiles (especially for exception handler) + push edi + push esi + push ebx + + // call compileAndBackPatchMethod with args + // third argument is not used + push [esp + 16] // second argument -- return address + push eax // first argument -- cacheEntry + call compileAndBackPatchMethod + + // remove args + pop edx // <--- compileStubReEntryPoint + pop edx + + pop ebx // Restore volatiles + pop esi + pop edi + + // remove frame + mov esp,ebp + pop ebp + + // jump to the compiled method + push eax // ret will jump to this address + ret // Jump to function leaving the return address at the top of the stack + } +} + +#ifdef DEBUG +// Pointer to the instruction after the call (used by exception handler to check +// I wanted to use: +// void* compileStubReEntryPoint = (void*) ((Uint8*)staticCompileStub + 17); +// but MSDev appears to have a bug, in that compileStubReEntryPoint will be set == (void*)staticCompileStub +// which is clearly wrong. +void* compileStubAddress = (void*)staticCompileStub; +void* compileStubReEntryPoint = (Uint8*)compileStubAddress + 17; +#endif // DEBUG + +static Naked void compileStub() +{ + _asm { + push 0xEFBEADDE // This is a dummy immediate that will be filled in by + jmp staticCompileStub // generateCompileStub with the cacheEntry. + } +} + +void * +generateNativeStub(NativeCodeCache& inCache, const CacheEntry& inCacheEntry, void *nativeFunction) +{ + Method* method = inCacheEntry.descriptor.method; + //Uint32 nWords = method->getSignature().nArguments; + Uint32 nWords = method->getArgsSize()/sizeof(Int32); + + assert(method->getModifiers() & CR_METHOD_NATIVE); + assert(nWords <= 256); + + extern void *sysInvokeNativeStubs[]; + Uint8 stubSize = 10; + void* stub; + + // Write out the native stub + stub = inCache.acquireMemory(stubSize); + Uint8* where = (Uint8*)stub; + *where++ = 0x68; // pushl + writeLittleWordUnaligned(where, (uint32)(nativeFunction)); + where += 4; + *where++ = 0xe9; // jmp + writeLittleWordUnaligned(where, (Uint8 *) sysInvokeNativeStubs[nWords] - (where + 4)); + + // Return the address of the stub. + return ((void*)stub); +} + +void* +generateCompileStub(NativeCodeCache& inCache, const CacheEntry& inCacheEntry) +{ + void* stub; + uint8 stubSize; + uint8 argumentOffset; + uint32 locationOfCompileStub; + + stubSize = 10; + + // Write out the dynamic compile stub + stub = inCache.acquireMemory(stubSize); + argumentOffset = 1; + locationOfCompileStub = (uint32)compileStub ; + + // Copy the stub into the allocated memory + memcpy(stub, (void*)locationOfCompileStub, stubSize); + + // Write your cacheEntry into the proper spot in the stub + uint8* loadCacheEntryInstruction = (uint8*)stub + argumentOffset; + writeLittleWordUnaligned((void*)loadCacheEntryInstruction, (uint32)(&inCacheEntry)); + + // Fix the new dynamic stub to jump to the static stub + uint32* relativeCallLocation = (uint32*)(loadCacheEntryInstruction + 5); + uint32 newRelativeDisplacement = locationOfCompileStub - (uint32)stub + *(uint32*)relativeCallLocation; + writeLittleWordUnaligned((void*)relativeCallLocation, newRelativeDisplacement); + + // Return the address of the dynamic stub. + return ((void*)stub); +} + +void* +backPatchMethod(void* inMethodAddress, void* inLastPC, void* /*inUserDefined*/) +{ + + uint32 curAddress = (uint32) inLastPC; + uint32 methodAddress = (uint32) inMethodAddress; + + // Compute the relative branch + uint32* relativeBranch = ((uint32*)inLastPC)-1; + int32 offset = methodAddress - curAddress; + + // Backpatch the method. + writeLittleWordUnaligned((void*)relativeBranch, offset); + + return (inMethodAddress); +} + +// Warning silencing stuff +// #pragma warning( disable : 4035) +// #pragma warning( default : 4035) + + +//================================================================================ +// 64bit Arithmetic Support Functions + +// x86Extract64Bit +// +// Purpose: signed right-aligned field extraction +// In: 64 bit source (on stack) +// 32 bit extraction size (on stack) +// Out: 64 bit result +// Note: Only works in range 1 <= b <= 63, b is extraction amount +Naked void x86Extract64Bit() +{ + __asm + { + mov eax, [esp+4] // load low byte of a + + mov ecx, [esp+12] // load shift amount + cmp ecx, 0x20 + jg greater32 + + // extract <= than 32 bits + // shift amount = 32 - extract + neg ecx + add ecx, 0x20 // ecx = 32 - extract + shl eax, cl + sar eax, cl + cdq // sign extend into EDX:EAX + ret 12 + +greater32: + // ext > 32 bits + // shift amount = 64 - extract + mov edx, [esp+8] // load high byte of a + neg ecx + add ecx, 0x40 // ecx = 64 - extract + shl edx, cl + sar edx, cl + ret 12 + } +} + +// 3WayCompare +// +// Purpose: compare two longs +// In: two longs on the stack +// Out: depends on condition flags: +// less = -1 +// equal = 0 +// greater = 1 +Naked void x86ThreeWayCMP_L() +{ + // edx:eax is tos, ecx:ebx is nos + __asm + { + mov ecx,[esp+8] + mov edx,[esp+16] + + cmp ecx,edx + jl lcmp_m1 + + jg lcmp_1 + + mov ecx,[esp+4] + mov edx,[esp+12] + + cmp ecx,edx + ja lcmp_1 + + mov eax,0 + jb lcmp_m1 + + ret 16 + + align 4 + lcmp_m1: + mov eax,-1 + + ret 16 + + align 4 + lcmp_1: + mov eax,1 + + ret 16 + } +} + +// 3WayCompare +// +// Purpose: compare two longs +// In: two longs on the stack +// Out: depends on condition flags: +// less = 1 +// equal = 0 +// greater = -1 +Naked void x86ThreeWayCMPC_L() +{ + // edx:eax is tos, ecx:ebx is nos + __asm + { + mov ecx,[esp+8] + mov edx,[esp+16] + + cmp ecx,edx + jl lcmp_m1 + + jg lcmp_1 + + mov ecx,[esp+4] + mov edx,[esp+12] + + cmp ecx,edx + ja lcmp_1 + + mov eax,0 + jb lcmp_m1 + + ret 16 + + align 4 + lcmp_m1: + mov eax,1 + + ret 16 + + align 4 + lcmp_1: + mov eax,-1 + + ret 16 + } +} + +// llmul +// +// Purpose: long multiply (same for signed/unsigned) +// In: args are passed on the stack: +// 1st pushed: multiplier (QWORD) +// 2nd pushed: multiplicand (QWORD) +// Out: EDX:EAX - product of multiplier and multiplicand +// Note: parameters are removed from the stack +// Uses: ECX +Naked void x86Mul64Bit() +{ + // IMPLEMENT: Needs to be written + _asm + { + int 3 + } +} + +// lldiv +// +// Purpose: signed long divide +// In: args are passed on the stack: +// 1st pushed: divisor (QWORD) +// 2nd pushed: dividend (QWORD) +// Out: EDX:EAX contains the quotient (dividend/divisor) +// Note: parameters are removed from the stack +// Uses: ECX +Naked void x86Div64Bit() +{ + // IMPLEMENT: Needs to be written + _asm + { + int 3 + } +} + +// llrem +// +// Purpose: signed long remainder +// In: args are passed on the stack: +// 1st pushed: divisor (QWORD) +// 2nd pushed: dividend (QWORD) +// Out: EDX:EAX contains the quotient (dividend/divisor) +// Note: parameters are removed from the stack +// Uses: ECX +Naked void x86Mod64Bit() +{ + // IMPLEMENT: Needs to be written + _asm + { + int 3 + } +} + +// llshl +// +// Purpose: long shift left +// In: args are passed on the stack: (FIX make fastcall) +// 1st pushed: amount (int) +// 2nd pushed: source (long) +// Out: EDX:EAX contains the result +// Note: parameters are removed from the stack +// Uses: ECX, destroyed +Naked void x86Shl64Bit() +{ + // IMPLEMENT: Needs to be written + _asm + { + int 3 + } +} + +// llshr +// +// Origin: MSDev. modified +// Purpose: long shift right +// In: args are passed on the stack: (FIX make fastcall) +// 1st pushed: amount (int) +// 2nd pushed: source (long) +// Out: EDX:EAX contains the result +// Note: parameters are removed from the stack +// Uses: ECX, destroyed +Naked void x86Shr64Bit() +{ + // IMPLEMENT: Needs to be written + _asm + { + int 3 + } +} + +// llsar +// +// Origin: MSDev. modified +// Purpose: long shift right signed +// In: args are passed on the stack: (FIX make fastcall) +// 1st pushed: amount (int) +// 2nd pushed: source (long) +// Out: EDX:EAX contains the result +// Note: parameters are removed from the stack +// Uses: ECX, destroyed +Naked void x86Sar64Bit() +{ + // IMPLEMENT: Needs to be written + _asm + { + int 3 + } +} + +//================================================================================ diff --git a/ef/Compiler/FrontEnd/BytecodeGraph.cpp b/ef/Compiler/FrontEnd/BytecodeGraph.cpp new file mode 100644 index 000000000000..27a59e3751fd --- /dev/null +++ b/ef/Compiler/FrontEnd/BytecodeGraph.cpp @@ -0,0 +1,1087 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#include "BytecodeVerifier.h" +#include "MemoryAccess.h" +#include "GraphUtils.h" +#include "ErrorHandling.h" +#include "DebugUtils.h" + + +// ---------------------------------------------------------------------------- +// BasicBlock + + +#ifdef DEBUG_LOG +// +// Print a reference to this BasicBlock for debugging purposes. +// Return the number of characters printed. +// +int BasicBlock::printRef(LogModuleObject &f, const BytecodeGraph &bg) const +{ + if (bg.dfsBlockNumbersValid() && dfsNum >= 0) + return UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("B%d", dfsNum)); + else + return UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("B%p", this)); +} + + +// +// Print this BasicBlock for debugging purposes. +// f should be at the beginning of a line. +// If c is non-nil, disassemble constant pool indices symbolically using the information +// in c. +// +void BasicBlock::printPretty(LogModuleObject &f, const BytecodeGraph &bg, const ConstantPool *c, int margin) const +{ + printMargin(f, margin); + printRef(f, bg); + UT_OBJECTLOG(f, PR_LOG_ALWAYS, (" (%p): %d predecessors", this, nPredecessors)); + #ifdef DEBUG + if (hasIncomingBackEdges) + UT_OBJECTLOG(f, PR_LOG_ALWAYS, (" (cycle header)")); + #endif + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("\n")); + + switch (kind) { + case bbEnd: + printMargin(f, margin + 4); + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("End block\n")); + break; + case bbBytecode: + { + const BytecodeBlock *bb = static_cast(this); + if (!bb->hasSubkind(BytecodeBlock::skNormal)) { + const char *subkindName; + switch (bb->subkind) { + case BytecodeBlock::skReturn: + subkindName = "Return"; + break; + case BytecodeBlock::skJsr: + subkindName = "Jsr"; + break; + case BytecodeBlock::skJsrNoRet: + subkindName = "JsrNoRet"; + break; + case BytecodeBlock::skRet: + subkindName = "Ret"; + break; + case BytecodeBlock::skForward: + subkindName = "Forward"; + break; + default: + subkindName = "????"; + } + printMargin(f, margin + 4); + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("%s bytecode block\n", subkindName)); + } + disassembleBytecodes(f, bb->bytecodesBegin, bb->bytecodesEnd, bg.bytecodesBegin, c, margin + 4); + } + break; + case bbCatch: + printMargin(f, margin + 4); + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("Catch block\n")); + break; + } + + bool printSeparator; + if (successorsBegin != successorsEnd) { + printMargin(f, margin); + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("Successors: ")); + printSeparator = false; + for (BasicBlock **s = successorsBegin; s != successorsEnd; s++) { + if (printSeparator) + UT_OBJECTLOG(f, PR_LOG_ALWAYS, (", ")); + printSeparator = true; + (*s)->printRef(f, bg); + } + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("\n")); + } + if (successorsEnd != handlersEnd) { + printMargin(f, margin); + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("Exception handlers: ")); + printSeparator = false; + assert(kind == bbBytecode); + const Class **exceptionClass = static_cast(this)->exceptionClasses; + for (BasicBlock **s = successorsEnd; s != handlersEnd; s++) { + if (printSeparator) + printMargin(f, margin + 20); + printSeparator = true; + (*exceptionClass++)->printRef(f); + UT_OBJECTLOG(f, PR_LOG_ALWAYS, (" -> ")); + (*s)->printRef(f, bg); + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("\n")); + } + assert(exceptionClass == static_cast(this)->exceptionClassesEnd); + } + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("\n")); +} +#endif + + +// ---------------------------------------------------------------------------- +// EndBlock + + +// +// Initialize this EndBlock contained in the given BytecodeGraph. +// +inline EndBlock::EndBlock(BytecodeGraph &bytecodeGraph): + BasicBlock(bytecodeGraph, bbEnd, sn0) +{ + successorsBegin = 0; + successorsEnd = 0; + handlersEnd = 0; + #ifdef DEBUG + successorsPhysicalEnd = 0; + #endif +} + + +// ---------------------------------------------------------------------------- +// BytecodeBlock + + +// +// Make a copy of the src BytecodeBlock pointing to the same successors and CatchBlock +// as src and add it to the given graph. However, do not copy or initialize the +// VerificationTemps or TranslationTemps in the copy. +// +BytecodeBlock::BytecodeBlock(BytecodeGraph &bytecodeGraph, const BytecodeBlock &src): + BasicBlock(bytecodeGraph, bbBytecode, src.stackNormalization), + bytecodesBegin(src.bytecodesBegin), + bytecodesEnd(src.bytecodesEnd), + catchBlock(src.catchBlock), + subkind(src.subkind) +{ + Uint32 nSuccessors = src.nSuccessors(); + Uint32 nSuccessorsAndHandlers = src.handlersEnd - src.successorsBegin; + BasicBlock **successorsAndHandlers = nSuccessorsAndHandlers ? new(bytecodeGraph.bytecodeGraphPool) BasicBlock *[nSuccessorsAndHandlers] : 0; + successorsBegin = successorsAndHandlers; + handlersEnd = copy(src.successorsBegin, src.handlersEnd, successorsAndHandlers); + successorsEnd = successorsAndHandlers + nSuccessors; + #ifdef DEBUG + successorsPhysicalEnd = handlersEnd; + #endif + + Uint32 nHandlers = nSuccessorsAndHandlers - nSuccessors; + exceptionClasses = nHandlers ? new(bytecodeGraph.bytecodeGraphPool) const Class *[nHandlers] : 0; + exceptionClassesEnd = copy(src.exceptionClasses, src.exceptionClassesEnd, exceptionClasses); +} + + +// +// Set up the successors and handlers arrays for this BytecodeBlock. The caller should +// have allocated the successors array whose first nSuccessors entries are the normal +// successors and next nActiveHandlers entries are the exceptional successors. The +// caller should have initialized the normal successors already. nActiveHandlers must +// be no less than the number of exception handlers active for this BytecodeBlock. +// bytecodeGraphPool is used to allocate the exceptionClasses array. +// +inline void BytecodeBlock::initSuccessors(BasicBlock **successors, Uint32 nSuccessors, Int32 nActiveHandlers, Pool &bytecodeGraphPool) +{ + successorsBegin = successors; + successorsEnd = successors + nSuccessors; + handlersEnd = successorsEnd; + exceptionClasses = nActiveHandlers ? new(bytecodeGraphPool) const Class *[nActiveHandlers] : 0; + exceptionClassesEnd = exceptionClasses; + #ifdef DEBUG + successorsPhysicalEnd = handlersEnd + nActiveHandlers; + #endif +} + + +// ---------------------------------------------------------------------------- +// BytecodeGraph + +static const bytecode returnBytecodes[nValueKinds] = { + bcReturn, // vkVoid + bcIReturn, // vkInt + bcLReturn, // vkLong + bcFReturn, // vkFloat + bcDReturn, // vkDouble + bcAReturn, // vkAddr + bcNop, // vkCond + bcNop, // vkMemory + bcNop // vkTuple +}; + +static const BasicBlock::StackNormalization returnNormalizations[nValueKinds] = { + BasicBlock::sn0, // vkVoid + BasicBlock::sn1, // vkInt + BasicBlock::sn2, // vkLong + BasicBlock::sn1, // vkFloat + BasicBlock::sn2, // vkDouble + BasicBlock::sn1, // vkAddr + BasicBlock::snNoChange, // vkCond + BasicBlock::snNoChange, // vkMemory + BasicBlock::snNoChange // vkTuple +}; + + +// +// Create a new BytecodeGraph for the given function using the given pool. +// bytecodesBegin must be word-aligned. +// +BytecodeGraph::BytecodeGraph(ClassFileSummary &cfs, Pool &bytecodeGraphPool, bool isInstanceMethod, + bool isSynchronized, uint nArguments, const ValueKind *argumentKinds, ValueKind resultKind, + Uint32 nLocals, Uint32 stackSize, const bytecode *bytecodesBegin, Uint32 bytecodesSize, Uint32 nExceptionEntries, + const ExceptionItem *exceptionEntries, Method& _method): + bytecodeGraphPool(bytecodeGraphPool), + classFileSummary(cfs), + method(_method), + nLocals(nLocals), + stackSize(stackSize), + isInstanceMethod(isInstanceMethod), + isSynchronized(isSynchronized), + nArguments(nArguments), + argumentKinds(argumentKinds), + resultKind(resultKind), + bytecodesBegin(bytecodesBegin), + bytecodesEnd(bytecodesBegin + bytecodesSize), + bytecodesSize(bytecodesSize), + nExceptionEntries(nExceptionEntries), + exceptionEntries(exceptionEntries), + returnBlock(0), + nBlocks(0), + dfsList(0), + returnBytecode(returnBytecodes[resultKind]) +{ + // Make sure that the bytecodes are word-aligned. If not, the switchAlign function + // and its clients must be changed to handle unaligned word reads. + assert(((size_t)bytecodesBegin & 3) == 0); + assert(returnBytecode != bcNop); +} + + + +// +// followGotos returns the ultimate target of a goto or goto_w and changes the +// blocks array to make the source of the first and every intermediate goto/goto_w +// into an alias of the ultimate target. +// +// initialOffset is the offset of a goto or goto_w bytecode whose displacement is +// also given. initialOffset is guaranteed to be less than bytecodesSize, but the +// caller does not make any assertions about displacement. +// +// If the first goto/goto_w points to a chain of zero or more intermediate goto/goto_ws +// that ends at bytecode X that is something other than a goto/goto_w, then the +// BytecodeBlock corresponding to bytecode X is the ultimate target. +// If the first goto/goto_w points to a chain of zero or more intermediate goto/goto_ws +// that completes a cycle of goto/goto_ws, then the first goto/goto_w whose target is +// either the first goto/goto_w or is a member of the chain becomes the ultimate target. +// +BytecodeBlock &BytecodeGraph::followGotos(Uint32 initialOffset, Int32 displacement, BytecodeBlock **blocks) +{ + // Create a unique marker to mark the locations of the gotos as we follow them. + // If we ever encounter the same marker as a target of one of our gotos, we know + // that the gotos form a cycle. + BytecodeBlock *marker = reinterpret_cast(endBlock); + assert(marker); + + BytecodeBlock *finalBlock; + Uint32 prevOffset = initialOffset; + Uint32 offset = initialOffset + displacement; + while (true) { + assert(!blocks[prevOffset]); + blocks[prevOffset] = marker; // Mark the sources of the goto/goto_ws we've already seen. + if (offset >= bytecodesSize) + verifyError(VerifyError::badBytecodeOffset); + BytecodeBlock *b = blocks[offset]; + if (b) { + if (b == marker) { + finalBlock = new(bytecodeGraphPool) BytecodeBlock(*this, bytecodesBegin + prevOffset, BasicBlock::snNoChange); + blocks[prevOffset] = finalBlock; + } else + finalBlock = b; + break; + } + prevOffset = offset; + const bytecode *bc = bytecodesBegin + offset; + bytecode e = *bc; + if (e == bcGoto) + // We don't bother to check that offset <= bytecodesSize-3 here because we'll check + // that inside createBlocks; the worst that can happen here is that we'll read a few + // bytes past the end of the method's bytecodes. + offset += readBigSHalfwordUnaligned(bc+1); + else if (e == bcGoto_W) + // We don't bother to check that offset <= bytecodesSize-5 here because we'll check + // that inside createBlocks; the worst that can happen here is that we'll read a few + // bytes past the end of the method's bytecodes. + offset += readBigSWordUnaligned(bc+1); + else { + finalBlock = ¬eBlockBoundary(offset, blocks); + break; + } + } + + // Convert all remaining markers into aliases of the ultimate target. + offset = initialOffset; + while (blocks[offset] == marker) { + blocks[offset] = finalBlock; + const bytecode *bc = bytecodesBegin + offset; + bytecode e = *bc; + if (e == bcGoto) + offset += readBigSHalfwordUnaligned(bc+1); + else { + assert(e == bcGoto_W); + offset += readBigSWordUnaligned(bc+1); + } + } + assert(blocks[offset] == finalBlock); + return *finalBlock; +} + + +// +// If the blocks array doesn't already contain a BytecodeBlock corresponding to the +// given bytecode offset, create a new BytecodeBlock at that offset and add it to the blocks array. +// Verify that the offset is less than bytecodesSize. +// Return the existing or created BytecodeBlock. +// +// After returnBlock is created any subsequent blocks starting with a return instruction are aliased +// to the existing returnBlock. Gotos are aliased out (i.e. the source of a goto gets the same +// BytecodeBlock as the target of that goto); as a consequence no BytecodeBlock can contain a goto +// except in the case of a cycle consisting entirely of gotos. A goto_w is considered to be a goto. +// +BytecodeBlock &BytecodeGraph::noteBlockBoundary(Uint32 offset, BytecodeBlock **blocks) +{ + if (offset >= bytecodesSize) + verifyError(VerifyError::badBytecodeOffset); + BytecodeBlock *&bb = blocks[offset]; + BytecodeBlock *b = bb; + if (!b) { + const bytecode *bc = bytecodesBegin + offset; + bytecode e = *bc; + if (e == bcGoto) + // Make the goto's source BytecodeBlock to be an alias of its target BytecodeBlock. + // We don't bother to check that offset <= bytecodesSize-3 here because we'll check + // that inside createBlocks; the worst that can happen here is that we'll read a few + // bytes past the end of the method's bytecodes. + b = &followGotos(offset, readBigSHalfwordUnaligned(bc+1), blocks); + + else if (e == bcGoto_W) + // Make the goto_w's source BytecodeBlock to be an alias of its target BytecodeBlock. + // We don't bother to check that offset <= bytecodesSize-5 here because we'll check + // that inside createBlocks; the worst that can happen here is that we'll read a few + // bytes past the end of the method's bytecodes. + b = &followGotos(offset, readBigSWordUnaligned(bc+1), blocks); + + else if (e == returnBytecode) { + b = returnBlock; + if (!b) { + b = new(bytecodeGraphPool) BytecodeBlock(*this, bc, returnNormalizations[resultKind]); + returnBlock = b; + } + bb = b; + } else { + b = new(bytecodeGraphPool) BytecodeBlock(*this, bc, BasicBlock::snNoChange); + bb = b; + } + } + return *b; +} + + +// +// Call noteBlockBoundary on the start_pc, end_pc, and handler_pc value of +// every exception handler in this function. Create a CatchBlock for each handler. +// Add 1 to each entry in the activeHandlerDeltas array for each exception handler whose +// start_pc is at that entry's offset, and subtract 1 from each entry in the activeHandlerDeltas +// array for each exception handler whose end_pc is at that entry's offset. +// +void BytecodeGraph::noteExceptionBoundaries(BytecodeBlock **blocks, Int32 *activeHandlerDeltas) +{ + const ExceptionItem *e = exceptionEntries; + const ExceptionItem *eEnd = e + nExceptionEntries; + while (e != eEnd) { + Uint32 startPC = e->startPc; + Uint32 endPC = e->endPc; + if (startPC >= endPC) + verifyError(VerifyError::badBytecodeOffset); + noteBlockBoundary(startPC, blocks); + activeHandlerDeltas[startPC]++; + if (endPC != bytecodesSize) + noteBlockBoundary(endPC, blocks); + activeHandlerDeltas[endPC]--; + BytecodeBlock &handler = noteBlockBoundary(e->handlerPc, blocks); + if (!handler.catchBlock) + handler.catchBlock = new(bytecodeGraphPool) CatchBlock(*this, handler); + e++; + } +} + + +// +// Call noteBlockBoundary on every target of this tableswitch instruction. +// bc points to the tableswitch instruction's opcode. +// Return the address of the following instruction. +// +const bytecode *BytecodeGraph::noteTableSwitchTargets(const bytecode *bc, BytecodeBlock **blocks) +{ + Uint32 baseOffset = bc - bytecodesBegin; + const bytecode *bcDefault = switchAlign(bc + 1); // Skip past padding. + noteBlockBoundary(baseOffset + readBigSWord(bcDefault), blocks); + + Int32 low = readBigSWord(bcDefault + 4); + Int32 high = readBigSWord(bcDefault + 8); + if (low > high) + verifyError(VerifyError::badSwitchBytecode); + bcDefault += 12; + Uint32 nCases = high - low + 1; + // The nCases == 0 check ensures that we don't have overflow from low = 0x80000000 and high = 0x7FFFFFFF. + if (bcDefault > bytecodesEnd || nCases == 0 || nCases > (Uint32)(bytecodesEnd - bcDefault) >> 2) + verifyError(VerifyError::badBytecodeOffset); + while (nCases--) { + noteBlockBoundary(baseOffset + readBigSWord(bcDefault), blocks); + bcDefault += 4; + } + return bcDefault; +} + + +// +// Call noteBlockBoundary on every target of this lookupswitch instruction. +// bc points to the lookupswitch instruction's opcode. +// Return the address of the following instruction. +// +const bytecode *BytecodeGraph::noteLookupSwitchTargets(const bytecode *bc, BytecodeBlock **blocks) +{ + Uint32 baseOffset = bc - bytecodesBegin; + const bytecode *bcDefault = switchAlign(bc + 1); // Skip past padding. + noteBlockBoundary(baseOffset + readBigSWord(bcDefault), blocks); + + Int32 nPairs = readBigSWord(bcDefault + 4); + if (nPairs < 0) + verifyError(VerifyError::badSwitchBytecode); + bcDefault += 8; + if (bcDefault > bytecodesEnd || nPairs > (bytecodesEnd - bcDefault) >> 3) + verifyError(VerifyError::badBytecodeOffset); + // ****** TO DO: verify that each target match value is unique ******* + while (nPairs--) { + noteBlockBoundary(baseOffset + readBigSWord(bcDefault + 4), blocks); + bcDefault += 8; + } + return bcDefault; +} + + +// +// Allocate an array of the target BasicBlocks of this tableswitch instruction. +// bc points to the tableswitch instruction's opcode. +// Return the address of the following instruction, the array of BasicBlocks in +// successors, and the size of this array (not including the nActiveHandlers exception +// handlers at its end) in nSuccessors. Do not initialize the successor array entries +// corresponding to the exception handlers. +// +const bytecode *BytecodeGraph::recordTableSwitchTargets(const bytecode *bc, BytecodeBlock **blocks, + BasicBlock **&successors, Uint32 &nSuccessors, Int32 nActiveHandlers) +{ + const bytecode *bcDefault = switchAlign(bc + 1); // Skip past padding. + + Int32 low = readBigSWord(bcDefault + 4); + Int32 high = readBigSWord(bcDefault + 8); + assert(low <= high); + Uint32 nCases = high - low + 1; + nSuccessors = nCases + 1; + BasicBlock **s = new(bytecodeGraphPool) BasicBlock *[nCases + 1 + nActiveHandlers]; + successors = s; + + BytecodeBlock *bb = blocks[bc + readBigSWord(bcDefault) - bytecodesBegin]; + assert(bb); + *s++ = bb; + bcDefault += 12; + while (nCases--) { + bb = blocks[bc + readBigSWord(bcDefault) - bytecodesBegin]; + assert(bb); + *s++ = bb; + bcDefault += 4; + } + return bcDefault; +} + + +// +// Allocate an array of the target BasicBlocks of this lookupswitch instruction. +// bc points to the lookupswitch instruction's opcode. +// Return the address of the following instruction, the array of BasicBlocks in +// successors, and the size of this array (not including the nActiveHandlers exception +// handlers at its end) in nSuccessors. Do not initialize the successor array entries +// corresponding to the exception handlers. +// +const bytecode *BytecodeGraph::recordLookupSwitchTargets(const bytecode *bc, BytecodeBlock **blocks, + BasicBlock **&successors, Uint32 &nSuccessors, Int32 nActiveHandlers) +{ + const bytecode *bcDefault = switchAlign(bc + 1); // Skip past padding. + + Int32 nPairs = readBigSWord(bcDefault + 4); + assert(nPairs >= 0); + nSuccessors = nPairs + 1; + BasicBlock **s = new(bytecodeGraphPool) BasicBlock *[nPairs + 1 + nActiveHandlers]; + successors = s; + + BytecodeBlock *bb = blocks[bc + readBigSWord(bcDefault) - bytecodesBegin]; + assert(bb); + *s++ = bb; + bcDefault += 8; + while (nPairs--) { + bb = blocks[bc + readBigSWord(bcDefault + 4) - bytecodesBegin]; + assert(bb); + *s++ = bb; + bcDefault += 8; + } + return bcDefault; +} + + +// +// Initialize the handler successors of each BasicBlock in this function according +// to the start_pc, end_pc, and handler_pc values of every exception handler in this +// function. Memory for the handler pointers (as indicated by the BasicBlocks' +// successorsPhysicalEnd fields) and for the exceptionClasses arrays must have been allocated. +// On entry each BasicBlock's handlersEnd value should be equal to its successorsEnd; +// on exit the handlersEnd value will be advanced past all of that block's handler pointers. +// +void BytecodeGraph::recordHandlerTargets(BytecodeBlock **blocks) +{ + const bytecode *const bytecodesBegin = BytecodeGraph::bytecodesBegin; + const ExceptionItem *e = exceptionEntries; + const ExceptionItem *eEnd = e + nExceptionEntries; + while (e != eEnd) { + Uint32 pc = e->startPc; + Uint32 endPC = e->endPc; + BytecodeBlock *handlerBytecodeBlock = blocks[e->handlerPc]; + assert(handlerBytecodeBlock); + CatchBlock *handler = handlerBytecodeBlock->catchBlock; + assert(handler); + ConstantPoolIndex c = e->catchType; + const Class *filter = &Standard::get(cThrowable); + if (c) { + filter = &classFileSummary.lookupClass(c); + if (!filter->implements(Standard::get(cThrowable))) + verifyError(VerifyError::nonThrowableCatch); + } + + do { + BytecodeBlock *block = blocks[pc]; + assert(block); + if (block->bytecodesBegin == bytecodesBegin + pc) { + // Add the handler to the list of this block's handlers. + if (!block->handlersForbidden()) { + assert(block->handlersEnd < block->successorsPhysicalEnd); + *block->handlersEnd++ = handler; + *block->exceptionClassesEnd++ = filter; + } + // Skip to the next BytecodeBlock + pc = block->bytecodesEnd - bytecodesBegin; + } else { + // We have a forwarded return, goto, or goto_w bytecode. + const BytecodeControlInfo &bci = normalBytecodeControlInfos[bytecodesBegin[pc]]; + assert(bci.kind == BytecodeControlInfo::bckGoto || + bci.kind == BytecodeControlInfo::bckGoto_W || + bci.kind == BytecodeControlInfo::bckReturn); + pc += bci.size; + } + assert(pc <= endPC); + } while (pc != endPC); + e++; + } +} + + +// +// Verify that no bytecode basic blocks begin between bc1 and bc2, exclusive. +// This ensures that nothing jumps into the middle of a bytecode instruction. +// +inline void BytecodeGraph::verifyNoBoundariesBetween(const bytecode *bc1, const bytecode *bc2, BytecodeBlock **blocks) const +{ + assert(bc1 < bc2); + BytecodeBlock **bb1 = blocks + (bc1 - bytecodesBegin); + BytecodeBlock **bb2 = blocks + (bc2 - bytecodesBegin); + for (bb1++; bb1 != bb2; bb1++) + if(*bb1) + verifyError(VerifyError::badBytecodeOffset); +} + + +// +// Create the BasicBlocks for this function and initialize their links to +// each other and their pointers to bytecodes. Initialize beginBlock and endBlock +// and set returnBlock if present. +// Allocate temporary storage that can be discarded after this function finishes +// from tempPool. +// +void BytecodeGraph::createBlocks(Pool &tempPool) +{ + // Entry i of the blocks array will contain either: + // null if a BytecodeBlock does not begin at bytecode offset i, or + // a pointer to a BytecodeBlock that begins at bytecode offset i, or + // a pointer to the return BytecodeBlock if one of the return instructions is present at bytecode + // offset i and that is not the last return instruction in the function (Only a one-byte-long + // return instruction can be forwarded in this manner), or + // a pointer to a BytecodeBlock that is the ultimate target of a goto (or goto_w) or a chain of + // gotos or goto_ws that begins at bytecode offset i. + // Every conditional, branch or exception target, or beginning or end of + // a range protected by an exception handler introduces a bytecode block + // boundary. + // We can detect the third and fourth cases above (a forwarded return or goto BytecodeBlock) by + // checking whether the BytecodeBlock's bytecodesBegin corresponds to the index i of its blocks array entry. + BytecodeBlock **blocks = new(tempPool) BytecodeBlock *[bytecodesSize]; + BytecodeBlock **blocksEnd = blocks + bytecodesSize; + // Clear the blocks array. + for (BytecodeBlock **bb = blocks; bb != blocksEnd; bb++) + *bb = 0; + + // Entry i of the activeHandlerDeltas array will contains the difference between the + // number of exception handlers that apply to the bytecode instruction just before + // bytecode offset i (zero if i is zero) and the number of exception handlers that + // apply to the bytecode instruction at bytecode offset i. + Int32 *activeHandlerDeltas = new(tempPool) Int32[bytecodesSize+1]; + Int32 *activeHandlerDeltasEnd = activeHandlerDeltas + bytecodesSize + 1; + // Clear the activeHandlerDeltas array. + for (Int32 *rl = activeHandlerDeltas; rl != activeHandlerDeltasEnd; rl++) + *rl = 0; + + const bytecode *const bytecodesBegin = BytecodeGraph::bytecodesBegin; + const bytecode *const bytecodesEnd = BytecodeGraph::bytecodesEnd; + + // Allocate the end block. + endBlock = new(bytecodeGraphPool) EndBlock(*this); + + // First pass: + // Collect all branch destinations and statements after conditional branches + // and make sure that each starts a BytecodeBlock. At this time only fill + // in the bytecodesBegin fields of the newly created BasicBlocks. + hasJSRs = false; + noteBlockBoundary(0, blocks); // Allocate the first basic block. + const bytecode *bc = bytecodesBegin; + while (true) { // We know there must be at least one bytecode. + if (bc >= bytecodesEnd) + verifyError(VerifyError::badBytecodeOffset); + Uint32 baseOffset = bc - bytecodesBegin; + const BytecodeControlInfo &bci = getBytecodeControlInfo(bc); + bc += bci.size; + + switch (bci.kind) { + case BytecodeControlInfo::bckNormal: + case BytecodeControlInfo::bckExc: + continue; // Don't force a new BytecodeBlock to start right after this bytecode. + + case BytecodeControlInfo::bckGoto: + assert(bci.size == 3); + if (!blocks[baseOffset]) + followGotos(baseOffset, readBigSHalfwordUnaligned(bc-2), blocks); + break; + case BytecodeControlInfo::bckGoto_W: + assert(bci.size == 5); + if (!blocks[baseOffset]) + followGotos(baseOffset, readBigSWordUnaligned(bc-4), blocks); + break; + + case BytecodeControlInfo::bckJsr: + hasJSRs = true; + // Put the jsr into its own block. + noteBlockBoundary(baseOffset, blocks); + case BytecodeControlInfo::bckIf: + assert(bci.size == 3); + noteBlockBoundary(baseOffset + readBigSHalfwordUnaligned(bc-2), blocks); + break; + case BytecodeControlInfo::bckJsr_W: + hasJSRs = true; + // Put the jsr_w into its own block. + noteBlockBoundary(baseOffset, blocks); + assert(bci.size == 5); + noteBlockBoundary(baseOffset + readBigSWordUnaligned(bc-4), blocks); + break; + + case BytecodeControlInfo::bckTableSwitch: + assert(bci.size == 1); + bc = noteTableSwitchTargets(bc-1, blocks); + break; + case BytecodeControlInfo::bckLookupSwitch: + assert(bci.size == 1); + bc = noteLookupSwitchTargets(bc-1, blocks); + break; + + case BytecodeControlInfo::bckReturn: + assert(bci.size == 1); + // Ensure that all return instructions in this method return the correct kind. + if (bc[-1] != returnBytecode) + verifyError(VerifyError::badReturn); + // noteBlockBoundary handles and combines return blocks + noteBlockBoundary(baseOffset, blocks); + break; + + case BytecodeControlInfo::bckThrow: + break; + + case BytecodeControlInfo::bckRet: + case BytecodeControlInfo::bckRet_W: + // Put the ret or ret_w into its own block. + noteBlockBoundary(baseOffset, blocks); + break; + + default: + verifyError(VerifyError::badBytecode); + } + // A new BytecodeBlock starts right after this bytecode. + if (bc == bytecodesEnd) + break; + noteBlockBoundary(bc - bytecodesBegin, blocks); + } + + // Note the boundaries of try blocks and start addresses of exception handlers. + // Also calculate the activeHandlerDeltas array values. + noteExceptionBoundaries(blocks, activeHandlerDeltas); + + // Second pass: + // Fill in the bytecodesEnd, successorsBegin, successorsEnd, and successors of the + // BasicBlocks. Initialize handlersEnd to be the same as successorsEnd for now. + BytecodeBlock *thisBlock = blocks[0]; + assert(thisBlock); + Int32 nActiveHandlers = activeHandlerDeltas[0]; + bc = bytecodesBegin; + while (true) { + assert(bc < bytecodesEnd && nActiveHandlers >= 0); + const BytecodeControlInfo &bci = getBytecodeControlInfo(bc); + uint instSize = bci.size; + if (instSize != 1) + verifyNoBoundariesBetween(bc, bc + instSize, blocks); + bc += instSize; + Uint32 bcOffset = bc - bytecodesBegin; + + BasicBlock **successors; + Uint32 nSuccessors; + BasicBlock *bb1; + BasicBlock *bb2; + + switch (bci.kind) { + case BytecodeControlInfo::bckNormal: + case BytecodeControlInfo::bckExc: + // Continue processing this BytecodeBlock if it's not finished. + bb1 = blocks[bcOffset]; + if (!bb1) + continue; + processOneSuccessor: + assert(bb1); + successors = new(bytecodeGraphPool) BasicBlock *[1 + nActiveHandlers]; + successors[0] = bb1; + nSuccessors = 1; + break; + + case BytecodeControlInfo::bckThrow: + successors = nActiveHandlers ? new(bytecodeGraphPool) BasicBlock *[nActiveHandlers] : 0; + nSuccessors = 0; + break; + + case BytecodeControlInfo::bckGoto: + assert(instSize == 3 && blocks[bcOffset - 3]); + // Don't generate anything for this goto if it's an alias. + if (blocks[bcOffset - 3]->bytecodesBegin != bc-3) + // thisBlock is an alias to the target of the goto, which is somewhere else. + goto startNewBlock; + bb1 = blocks[bcOffset - 3 + readBigSHalfwordUnaligned(bc-2)]; + goto processOneSuccessor; + + case BytecodeControlInfo::bckGoto_W: + assert(instSize == 5 && blocks[bcOffset - 5]); + // Don't generate anything for this goto_w if it's an alias. + if (blocks[bcOffset - 5]->bytecodesBegin != bc-5) + // thisBlock is an alias to the target of the goto_w, which is somewhere else. + goto startNewBlock; + bb1 = blocks[bcOffset - 5 + readBigSWordUnaligned(bc-4)]; + goto processOneSuccessor; + + case BytecodeControlInfo::bckIf: + bb1 = blocks[bcOffset]; + assert(instSize == 3); + bb2 = blocks[bcOffset - 3 + readBigSHalfwordUnaligned(bc-2)]; + assert(bb1 && bb2); + successors = new(bytecodeGraphPool) BasicBlock *[2 + nActiveHandlers]; + successors[0] = bb1; + successors[1] = bb2; + nSuccessors = 2; + break; + + case BytecodeControlInfo::bckTableSwitch: + assert(instSize == 1); + bc = recordTableSwitchTargets(bc-1, blocks, successors, nSuccessors, nActiveHandlers); + bcOffset = bc - bytecodesBegin; + break; + + case BytecodeControlInfo::bckLookupSwitch: + assert(instSize == 1); + bc = recordLookupSwitchTargets(bc-1, blocks, successors, nSuccessors, nActiveHandlers); + bcOffset = bc - bytecodesBegin; + break; + + case BytecodeControlInfo::bckReturn: + assert(instSize == 1 && blocks[bcOffset - 1]); + // Don't generate anything for this return if it's an alias. + if (thisBlock->bytecodesBegin != bc-1) + // thisBlock is an alias to the true return block, which is somewhere else. + goto startNewBlock; + // The last return jumps to the end block. + thisBlock->subkind = BytecodeBlock::skReturn; // Forbid handlers here to help avoid creating false loops; + successors = new(bytecodeGraphPool) BasicBlock *[1]; // we can therefore also omit space for handlers. + successors[0] = endBlock; + nSuccessors = 1; + break; + + case BytecodeControlInfo::bckJsr: + assert(instSize == 3); + bb1 = blocks[bcOffset - 3 + readBigSHalfwordUnaligned(bc-2)]; + processJSR: + bb2 = blocks[bcOffset]; + assert(bb1 && bb2); + thisBlock->subkind = BytecodeBlock::skJsr; // Forbid handlers here; + successors = new(bytecodeGraphPool) BasicBlock *[2]; // we can therefore also omit space for handlers. + successors[0] = bb1; + successors[1] = bb2; + nSuccessors = 2; + break; + case BytecodeControlInfo::bckJsr_W: + assert(instSize == 5); + bb1 = blocks[bcOffset - 5 + readBigSWordUnaligned(bc-4)]; + goto processJSR; + + case BytecodeControlInfo::bckRet: + case BytecodeControlInfo::bckRet_W: + thisBlock->subkind = BytecodeBlock::skRet; // Forbid handlers here; + successors = 0; // we can therefore also omit space for handlers. + nSuccessors = 0; // We don't know the actual successors of the ret yet. + break; + + default: + trespass("Reached bad BytecodeControlInfo"); + } + + {// Braces needed because Visual C++ complains about the bc2 variable without them. + // Finish the previous BytecodeBlock. + thisBlock->initSuccessors(successors, nSuccessors, nActiveHandlers, bytecodeGraphPool); + thisBlock->bytecodesEnd = bc; + #ifdef DEBUG + // Assert that we defined BytecodeBlocks in such a way as to make + // exception ranges begin and end only at BytecodeBlock boundaries. + for (const bytecode *bc2 = thisBlock->bytecodesBegin; ++bc2 != bc; ) + assert(activeHandlerDeltas[bc2 - bytecodesBegin] == 0); + #endif + } + + startNewBlock: + // Start a new BytecodeBlock. + nActiveHandlers += activeHandlerDeltas[bcOffset]; + if (bc == bytecodesEnd) + break; + thisBlock = blocks[bcOffset]; + assert(thisBlock); + } + // The counts of exception range begins and ends must be equal. + assert(nActiveHandlers == 0); + + // Third pass: + // Fill in the handler successors of the BasicBlocks. + recordHandlerTargets(blocks); + + beginBlock = blocks[0]; + assert(beginBlock); +} + + +class BytecodeDFSHelper +{ + public: + typedef BasicBlock *Successor; + typedef BasicBlock *NodeRef; + + bool hasBackEdges; // True if the graph contains a cycle + bool hasBackExceptionEdges; // True if the graph contains a cycle + private: + BasicBlock **dfsList; // Alias to dfsList from the BytecodeGraph + + public: + BytecodeDFSHelper(BasicBlock **dfsList): hasBackEdges(false), hasBackExceptionEdges(false), dfsList(dfsList) {} + + static Successor *getSuccessorsBegin(NodeRef n) {return n->successorsBegin;} + static Successor *getSuccessorsEnd(NodeRef n) {return n->handlersEnd;} + static bool isNull(const Successor s) {return s == 0;} + static NodeRef getNodeRef(Successor s) {return s;} + static bool isMarked(NodeRef n) {return n->dfsNum != BasicBlock::unmarked;} + static bool isUnvisited(NodeRef n) {return n->dfsNum == BasicBlock::unvisited;} + static bool isNumbered(NodeRef n) {return n->dfsNum >= 0;} + static void setMarked(NodeRef n) {n->dfsNum = BasicBlock::unvisited;} + static void setVisited(NodeRef n) {n->dfsNum = BasicBlock::unnumbered;} + void setNumbered(NodeRef n, Int32 i) {assert(i >= 0); n->dfsNum = i; dfsList[i] = n;} + void notePredecessor(NodeRef n) {n->nPredecessors++;} + void noteIncomingBackwardEdge(NodeRef); +}; + +// +// depthFirstSearchWithEnd calls this when it notices that node n has an incoming +// backward edge. Note the fact that this graph has a cycle by setting hasBackEdges. +// If this node is a catch node, also note the fact that we will need a second pass +// to split this catch node so as to make all exception edges go forward only. +// +inline void BytecodeDFSHelper::noteIncomingBackwardEdge(NodeRef n) +{ + hasBackEdges = true; + if (!n->hasKind(BasicBlock::bbBytecode)) + hasBackExceptionEdges = true; + #ifdef DEBUG + n->hasIncomingBackEdges = true; + #endif +} + + +// +// Allocate dfsList and fill it out with pointers to the BasicBlocks ordered +// by depth-first search. Fill out each BasicBlock's dfsNum to be its index +// into dfsList. Set or clear hasBackEdges depending on whether the graph has +// any back edges. Return true if the graph has backward exception edges. +// +// tempPool is a pool for temporary allocations that are no longer needed after +// depthFirstSearch terminates. +// +bool BytecodeGraph::depthFirstSearch(Pool &tempPool) +{ + // Initialize the blocks. + Uint32 maxNBlocks = 0; + for (DoublyLinkedList::iterator i = blocks.begin(); !blocks.done(i); i = blocks.advance(i)) { + BasicBlock &n = blocks.get(i); + n.dfsNum = BasicBlock::unmarked; + n.nPredecessors = 0; + #ifdef DEBUG + n.hasIncomingBackEdges = false; + #endif + maxNBlocks++; + } + + // Count the blocks reachable from beginBlock. + assert(beginBlock); + dfsList = new(bytecodeGraphPool) BasicBlock *[maxNBlocks]; + BytecodeDFSHelper dfsHelper(dfsList); + SearchStackEntry *searchStack = new(tempPool) SearchStackEntry[maxNBlocks]; + BasicBlock *begin = beginBlock; + BasicBlock *end = endBlock; + nBlocks = graphSearchWithEnd(dfsHelper, begin, end, maxNBlocks, searchStack); + + // Now do the actual depth-first search. + depthFirstSearchWithEnd(dfsHelper, begin, end, nBlocks, searchStack); + hasBackEdges = dfsHelper.hasBackEdges; + return dfsHelper.hasBackExceptionEdges; +} + + +// +// Split CatchBlocks with incoming backward edges into multiple CatchBlocks +// with a separate CatchBlock for each incoming backward edge. This should +// eliminate any backward exception edges from the graph. +// +void BytecodeGraph::splitCatchNodes() +{ + BasicBlock **block = dfsList; + BasicBlock **dfsListEnd = block + nBlocks; + while (block != dfsListEnd) { + BasicBlock *b = *block; + Int32 dfsNum = b->dfsNum; + BasicBlock **handler = b->successorsEnd; + BasicBlock **handlersEnd = b->handlersEnd; + while (handler != handlersEnd) { + BasicBlock *h = *handler; + if (dfsNum >= h->dfsNum) { + // We have a backward exception edge from b to h. + // Make a copy of h and point this edge to that copy. + assert(h->hasKind(BasicBlock::bbCatch)); + *handler = new(bytecodeGraphPool) CatchBlock(*this, static_cast(h)->getHandler()); + } + handler++; + } + block++; + } +} + + +// +// Create the BasicBlocks for this function and then call depthFirstSearch. +// tempPool is a pool for temporary allocations that are no longer needed after +// divideIntoBlocks terminates. +// +void BytecodeGraph::divideIntoBlocks(Pool &tempPool) +{ + if (!bytecodesSize) + verifyError(VerifyError::noBytecodes); + createBlocks(tempPool); + if (true /******* hasJSRs ***********/) { + depthFirstSearch(tempPool); + BytecodeVerifier::inlineSubroutines(*this, tempPool); + } + #ifdef DEBUG + bool didSplit = false; + #endif + while (depthFirstSearch(tempPool)) { + // We have some backward exception edges. Split catch nodes to eliminate them. + splitCatchNodes(); + #ifdef DEBUG + // We expect to only have to run the split phase at most once given the current + // deterministic implementation of depth-first search; however, if the depth-first + // search becomes nondeterministic, this assumption may no longer hold for + // irreducible graphs, so we put splitCatchNodes into a loop and add asserts + // to warn about the weird case where calling it once isn't enough. + assert(!didSplit); + didSplit = true; + #endif + } +} + + +#ifdef DEBUG_LOG +// +// Print a BytecodeGraph for debugging purposes. +// If c is non-nil, disassemble constant pool indices symbolically using the information +// in c. +// +void BytecodeGraph::print(LogModuleObject &f, const ConstantPool *c) const +{ + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("BytecodeGraph %p\n", this)); + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("isInstanceMethod: %d\n", isInstanceMethod)); + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("Arguments: ")); + bool printSeparator = false; + const ValueKind *kEnd = argumentKinds + nArguments; + for (const ValueKind *k = argumentKinds; k != kEnd; k++) { + if (printSeparator) + UT_OBJECTLOG(f, PR_LOG_ALWAYS, (", ")); + printSeparator = true; + ::print(f, *k); + } + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("\nResult: ")); + ::print(f, resultKind); + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("\nhasBackEdges: %d\n", hasBackEdges)); + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("\nhasJSRs: %d\n", hasJSRs)); + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("beginBlock: ")); + beginBlock->printRef(f, *this); + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("\nendBlock: ")); + endBlock->printRef(f, *this); + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("\n%d BasicBlocks:\n\n", nBlocks)); + if (dfsList) + for (Uint32 i = 0; i != nBlocks; i++) + dfsList[i]->printPretty(f, *this, c, 4); + else + for (DoublyLinkedList::iterator i = blocks.begin(); !blocks.done(i); i = blocks.advance(i)) + blocks.get(i).printPretty(f, *this, c, 4); + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("End BytecodeGraph\n\n")); +} +#endif diff --git a/ef/Compiler/FrontEnd/BytecodeGraph.h b/ef/Compiler/FrontEnd/BytecodeGraph.h new file mode 100644 index 000000000000..3dbc293e5e41 --- /dev/null +++ b/ef/Compiler/FrontEnd/BytecodeGraph.h @@ -0,0 +1,521 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#ifndef BYTECODEGRAPH_H +#define BYTECODEGRAPH_H + +#include "DoublyLinkedList.h" +#include "JavaBytecodes.h" +#include "TranslationEnv.h" +#include "VerificationEnv.h" +#include "ControlGraph.h" +#include "ClassFileSummary.h" +#include "LogModule.h" +#include "CheckedUnion.h" + +// +// Invariants for a BytecodeGraph: +// +// 1. The BytecodeGraph starts with the beginBlock BytecodeBlock. +// +// 2. The BytecodeGraph contains exactly one EndBlock. +// That block has no bytecodes and no successors. +// +// 3. Every BytecodeBlock whose subkind is not skForward contains at least one bytecode. +// A BytecodeBlock's subkind is skNormal unless specified otherwise below. +// The EndBlock and CatchBlocks contain no bytecodes. +// +// 4. The BytecodeGraph contains at most one BytecodeBlock that contains a return instruction +// (return, ireturn, areturn, etc.). The return instruction must be the only one in that +// BytecodeBlock. That BytecodeBlock must have exactly one successor, the EndBlock, and +// no exceptional successors. That BytecodeBlock's subkind must be skReturn. +// +// 5. An instruction of kind bckIf can only occur if it is the last one in a BytecodeBlock. +// That BytecodeBlock must have exactly two successors, the first of which is the false +// branch and the second the true branch. +// +// 6. An instruction of kind bckGoto or bckGoto_W may occur only if it is the last one in a +// BytecodeBlock. That BytecodeBlock must have exactly one successor. +// +// 7. An instruction of kind bckTableSwitch or bckLookupSwitch may occur only if it is the +// last one in a BytecodeBlock. That BytecodeBlock must have n+1 successors, where n +// is the number of cases. The first successor is the default, while the remaining ones +// correspond to the cases in the order they are listed in the tableswitch or lookupswitch +// instruction. +// +// 8. An instruction of kind bckThrow may occur only if it is the last one in a +// BytecodeBlock. That BytecodeBlock must have no successors. +// +// 9. A jsr (or jsr_w) instruction must be the only one in its BytecodeBlock. That BytecodeBlock +// must have either one or two successors and no exceptional successors. The first successor +// is the first BytecodeBlock of the subroutine (also called the subroutine's header). +// The second successor, if present, is the BytecodeBlock containing instructions after the jsr. +// The second successor is absent if verification determines that the subroutine never returns +// via a BytecodeBlock of kind skRet. The jsr BytecodeBlock's subkind must be skJsr if it has +// two successors or skJsrNoRet if it has one successor. +// +// 10. A ret (or wide ret) instruction must be the only one in its BytecodeBlock. That BytecodeBlock +// must have no successors and no exceptional successors. This BytecodeBlock's subkind must be +// skRet. +// +// 11. A BytecodeBlock with subkind skForward must not have any instructions. That BytecodeBlock +// must have exactly one successor and no exceptional successors and is treated as an +// unconditional branch to that one successor. +// +// 12. No BytecodeBlock may contain an instruction of kind bckIllegal. +// +// 13. Every BytecodeBlock that ends with one of the remaining instructions (kinds bckNormal +// or bckExc) must have exactly one successor. +// +// 14. Exceptional successors are only allowed in BytecodeBlocks that do not contain return, +// ret, or jsr instructions. Every exceptional successor must be either a CatchBlock or the +// EndBlock. +// +// 15. Non-exceptional successors may not refer to a CatchBlock. +// +// 16. The one successor of a CatchBlock must be a BytecodeBlock. That BytecodeBlock's catchBlock +// must point back to that CatchBlock. +// + +class BytecodeGraph; +struct BytecodeBlock; +struct BasicBlock: DoublyLinkedEntry // Links to other BasicBlocks in the same graph +{ + // Persistent fields + enum Kind {bbEnd, bbBytecode, bbCatch}; + enum StackNormalization {snNoChange, sn0, sn1, sn2}; // Number of words to leave on the stack when entering a BasicBlock. + // snNoChange means to leave the stack as is (the normal case); + // sn0, sn1, and sn2 mean to leave only the *top* 0, 1, or 2 words on the stack. + // These are needed so we can combine all return bytecodes into one block. + + const Kind kind ENUM_8; // Kind of this BasicBlock (EndBlock, BytecodeBlock, or CatchBlock) + const StackNormalization stackNormalization ENUM_8; // Number of words to leave on the stack when entering this BasicBlock + BasicBlock **successorsBegin; // Array of pointers to successors (nil if this is the end block) + BasicBlock **successorsEnd; // Last normal successor pointer + 1; (nil if this is the end block) + // also first exceptional successor pointer + BasicBlock **handlersEnd; // Last exceptional successor pointer + 1 (nil if this is the end block; + #ifdef DEBUG // same as successorsEnd if this is a catch block) + BasicBlock **successorsPhysicalEnd; // End of storage allocated for this successors array + #endif + + // Fields computed by depthFirstSearch + enum {unmarked = -3, unvisited = -2, unnumbered = -1}; + Int32 dfsNum; // Serial number assigned by depth-first search (-3 is unmarked, -2 is unvisited, -1 is unnumbered) + Uint32 nPredecessors; // Number of BasicBlock successor pointers that refer to this BasicBlock + // (often different from the number of ControlNodes that jump to this + // BasicBlock's ControlNodes because some BasicBlocks may be discovered + // to be dead and hence generate no ControlNodes, while others may generate + // code that has multiple branches to their successors.) + // The beginBlock pointer is also considered to be a successor pointer (so + // nPredecessors of the first block is always at least one). + // The implicit exception edges going to the EndBlock are not counted + #ifdef DEBUG // in the end BasicBlock's nPredecessors. + bool hasIncomingBackEdges; // True if this block has incoming backward edges + #endif + + private: + // Temporary fields for verification + struct VerificationTemps + { + Uint32 generation; // Number of last dataflow pass to have changed verificationEnvIn; 0 if none yet + VerificationEnv verificationEnvIn; // State of locals and stack at beginning of block + BytecodeBlock *subroutineHeader; // If this is a ret block, points to the entry point (header) of the subroutine; + // nil if not known or this is not a ret block. + BytecodeBlock *subroutineRet; // If this is a subroutine header, points to the ret block of that subroutine; + // nil if the ret block hasn't been found yet or this is not a subroutine header. + union { + BasicBlock *clone; // The copy of this BasicBlock, temporarily stored here while copying a subgraph of this graph + bool recompute; // True if verificationEnvIn has changed since it was last propagated to successors + }; + + VerificationTemps(VerificationEnv::Common &c): + generation(0), verificationEnvIn(c), subroutineHeader(0), subroutineRet(0), recompute(false) {} + VerificationTemps(const VerificationEnv &env, Function1 &translator, + BytecodeBlock *subroutineHeader, BytecodeBlock *subroutineRet): + generation(0), verificationEnvIn(env, translator), subroutineHeader(subroutineHeader), subroutineRet(subroutineRet) {} + }; + + // Temporary fields for translation into a primitive graph + struct TranslationTemps + { + Uint32 nSeenPredecessors; // Number of already seen BasicBlock successor pointers that refer to this BasicBlock + TranslationEnv translationEnvIn; // State of locals and stack at beginning of block + // For efficiency, the end block's envIn contains information only about memory bindings. + bool envInInitialized BOOL_8; // True if envIn has already been initialized; if false, no ControlNodes point to + #ifdef DEBUG // firstControlNode yet. + bool generatedControlNodes BOOL_8; // True if ControlNodes have already been generated or optimized out for this BasicBlock + #endif + mutable ControlNode *firstControlNode; // First ControlNode generated for this BasicBlock or nil if none yet or optimized out + DoublyLinkedList predecessors; // List of predecessors of this block's first generated control node + // (Moved into firstControlNode when the ControlNodes for this BasicBlock are created.) + TranslationTemps(TranslationCommonEnv &commonEnv); + }; + + CheckedUnion2(VerificationTemps, TranslationTemps) temps; + public: + + BasicBlock(BytecodeGraph &bytecodeGraph, Kind kind, StackNormalization stackNormalization); + + bool hasKind(Kind k) const {return k == kind;} + Uint32 nSuccessors() const {return successorsEnd - successorsBegin;} + BytecodeBlock &getSuccessor(Uint32 n) const; + + // Accessors for temporary fields for verification + void initVerification(VerificationEnv::Common &c); + void initVerification(BasicBlock &src, Function1 &translator); + Uint32 &getGeneration() {return temps.getVerificationTemps().generation;} + VerificationEnv &getVerificationEnvIn() {return temps.getVerificationTemps().verificationEnvIn;} + BytecodeBlock *&getSubroutineHeader() {return temps.getVerificationTemps().subroutineHeader;} + BytecodeBlock *&getSubroutineRet() {return temps.getVerificationTemps().subroutineRet;} + BasicBlock *&getClone() {return temps.getVerificationTemps().clone;} + bool &getRecompute() {return temps.getVerificationTemps().recompute;} + + // Accessors for temporary fields for primitive graph translation + void initTranslation(TranslationCommonEnv &commonEnv); + Uint32 &getNSeenPredecessors() {return temps.getTranslationTemps().nSeenPredecessors;} + bool &getEnvInInitialized() {return temps.getTranslationTemps().envInInitialized;} + #ifdef DEBUG + bool getGeneratedControlNodes() const {return temps.getTranslationTemps().generatedControlNodes;} + bool &getGeneratedControlNodes() {return temps.getTranslationTemps().generatedControlNodes;} + #endif + ControlNode *&getFirstControlNode() const {return temps.getTranslationTemps().firstControlNode;} + DoublyLinkedList &getPredecessors() {return temps.getTranslationTemps().predecessors;} + public: + TranslationEnv &getTranslationEnvIn() {return temps.getTranslationTemps().translationEnvIn;} + const TranslationEnv &getTranslationEnvIn() const {return temps.getTranslationTemps().translationEnvIn;} + + // Debugging + #ifdef DEBUG_LOG + int printRef(LogModuleObject &f, const BytecodeGraph &bg) const; + void printPretty(LogModuleObject &f, const BytecodeGraph &bg, const ConstantPool *c, int margin) const; + #endif +}; + + +struct EndBlock: BasicBlock +{ + EndBlock(BytecodeGraph &bytecodeGraph); +}; + + +struct CatchBlock: BasicBlock +{ + private: + BasicBlock *successor; // The handler of exceptions caught here + public: + + CatchBlock(BytecodeGraph &bytecodeGraph, BytecodeBlock &handler); + CatchBlock(BytecodeGraph &bytecodeGraph, const CatchBlock &src); + + BytecodeBlock &getHandler() const; +}; + + +struct BytecodeBlock: BasicBlock +{ + enum Subkind + { + skNormal, // A BytecodeBlock that does not contain any return, ret, or jsr instructions + skReturn, // A BytecodeBlock consisting entirely of one of the return instructions + skJsr, // A BytecodeBlock consisting entirely of a jsr or jsr_w instruction whose subroutine may or may not return + skJsrNoRet, // A BytecodeBlock consisting entirely of a jsr or jsr_w instruction whose subroutine is known never to return + skRet, // A BytecodeBlock consisting entirely of a ret or wide ret instruction + skForward // A formerly skRet BytecodeBlock that is known to unconditionally branch to its one successor + }; + + const bytecode *const bytecodesBegin; // Pointer to first bytecode in this block + const bytecode *bytecodesEnd; // End of last bytecode + 1 + CatchBlock *catchBlock; // If a catch handler begins at bytecodesBegin, a CatchBlock that points back to + // this block; nil otherwise. + const Class **exceptionClasses; // Array of exception classes; an exception matching the nth exception class + const Class **exceptionClassesEnd; // would transfer control to the nth exceptional successor + Subkind subkind ENUM_8; // Description of contents of this BytecodeBlock + + BytecodeBlock(BytecodeGraph &bytecodeGraph, const bytecode *bytecodesBegin, StackNormalization stackNormalization); + BytecodeBlock(BytecodeGraph &bytecodeGraph, const BytecodeBlock &src); + + bool hasSubkind(Subkind sk) const {return sk == subkind;} + bool handlersForbidden() const; + + void initSuccessors(BasicBlock **successors, Uint32 nSuccessors, Int32 nActiveHandlers, Pool &bytecodeGraphPool); + BasicBlock **transformToJsrNoRet(); + void transformToForward(BasicBlock **successor); +}; + + +class BytecodeGraph +{ + public: + // Persistent fields + Pool &bytecodeGraphPool; // Pool for allocating this BytecodeGraph's nodes (blocks) + ClassFileSummary &classFileSummary; // Java class file descriptor + Method& method; // The method this + // BytecodeGraph represents + const Uint32 nLocals; // Number of words of local variables + const Uint32 stackSize; // Number of words of local stack space + const bool isInstanceMethod BOOL_8; // True if this method has a "this" argument + const bool isSynchronized BOOL_8; // True if this method is synchronized + const uint nArguments; // Number of incoming arguments (including "this") + const ValueKind *const argumentKinds; // Kinds of incoming arguments (including "this") + const ValueKind resultKind; // Kind of result + const bytecode *const bytecodesBegin; // Pointer to first bytecode in this function (must be word-aligned) + const bytecode *const bytecodesEnd; // End of last bytecode in this function + 1 + const Uint32 bytecodesSize; // bytecodesEnd - bytecodesBegin + const Uint32 nExceptionEntries; // Number of exception table entries + const ExceptionItem *const exceptionEntries;// Exception table + BytecodeBlock *beginBlock; // Starting basic block in function + EndBlock *endBlock; // The end BasicBlock + BytecodeBlock *returnBlock; // The return BytecodeBlock or nil if none + private: + DoublyLinkedList blocks; // List of basic blocks (may include unreachable blocks) + Uint32 nBlocks; // Number of reachable basic blocks + + // Fields computed by depthFirstSearch + BasicBlock **dfsList; // Array of reachable basic blocks ordered by depth-first search; + // each block's dfsNum is an index into this array. + const bytecode returnBytecode; // The kind of return bytecode that corresponds to resultKind + bool hasBackEdges BOOL_8; // True if this graph contains a cycle + bool hasJSRs BOOL_8; // True if this graph contains a jsr or jsr_w instruction + + public: + BytecodeGraph(ClassFileSummary &cfs, Pool &bytecodeGraphPool, bool isInstanceMethod, bool isSynchronized, + uint nArguments, const ValueKind *argumentKinds, ValueKind resultKind, Uint32 nLocals, Uint32 stackSize, + const bytecode *bytecodesBegin, Uint32 bytecodesSize, Uint32 nExceptionEntries, + const ExceptionItem *exceptionEntries, Method& method); + private: + BytecodeGraph(const BytecodeGraph &); // Copying forbidden + void operator=(const BytecodeGraph &); // Copying forbidden + public: + + BasicBlock **getDFSList() const {assert(dfsList); return dfsList;} + Uint32 getDFSListLength() const {assert(dfsList); return nBlocks;} + void invalidateDFSList() {DEBUG_ONLY(dfsList = 0);} + void addBlock(BasicBlock &block) {blocks.addLast(block); invalidateDFSList();} + + static const bytecode *switchAlign(const bytecode *bc); + + private: + BytecodeBlock &followGotos(Uint32 initialOffset, Int32 displacement, BytecodeBlock **blocks); + BytecodeBlock ¬eBlockBoundary(Uint32 offset, BytecodeBlock **blocks); + void noteExceptionBoundaries(BytecodeBlock **blocks, Int32 *activeHandlerDeltas); + const bytecode *noteTableSwitchTargets(const bytecode *bc, BytecodeBlock **blocks); + const bytecode *noteLookupSwitchTargets(const bytecode *bc, BytecodeBlock **blocks); + const bytecode *recordTableSwitchTargets(const bytecode *bc, BytecodeBlock **blocks, BasicBlock **&successors, + Uint32 &nSuccessors, Int32 nActiveHandlers); + const bytecode *recordLookupSwitchTargets(const bytecode *bc, BytecodeBlock **blocks, BasicBlock **&successors, + Uint32 &nSuccessors, Int32 nActiveHandlers); + void recordHandlerTargets(BytecodeBlock **blocks); + void verifyNoBoundariesBetween(const bytecode *bc1, const bytecode *bc2, BytecodeBlock **blocks) const; + void createBlocks(Pool &tempPool); + bool depthFirstSearch(Pool &tempPool); + void splitCatchNodes(); + public: + void divideIntoBlocks(Pool &tempPool); + + #ifdef DEBUG_LOG + bool dfsBlockNumbersValid() const {return dfsList != 0;} + void print(LogModuleObject &f, const ConstantPool *c) const; + #endif +}; + + +// --- INLINES ---------------------------------------------------------------- + + +// +// Initialize BasicBlock fields used for translation into a primitive graph. +// +inline BasicBlock::TranslationTemps::TranslationTemps(TranslationCommonEnv &commonEnv): + nSeenPredecessors(0), + translationEnvIn(commonEnv), + envInInitialized(false), + firstControlNode(0) +{ + #ifdef DEBUG + generatedControlNodes = false; + #endif +} + + +// +// Initialize this BasicBlock contained in the given BytecodeGraph. +// +inline BasicBlock::BasicBlock(BytecodeGraph &bytecodeGraph, Kind kind, StackNormalization stackNormalization): + kind(kind), + stackNormalization(stackNormalization) +{ + bytecodeGraph.addBlock(*this); +} + + +// +// Return the nth regular (non-exceptional) successor. +// Don't call this to get the successor of the return node, because it is not +// a BytecodeBlock. +// +inline BytecodeBlock &BasicBlock::getSuccessor(Uint32 n) const +{ + assert(n < nSuccessors() && successorsBegin[n]->hasKind(bbBytecode)); + return *static_cast(successorsBegin[n]); +} + + +// +// Prepare this BasicBlock for verification. +// +inline void BasicBlock::initVerification(VerificationEnv::Common &c) +{ + new(temps.initVerificationTemps()) VerificationTemps(c); +} + + +// +// Prepare this BasicBlock for verification using a copy of src's env, subroutineHeader, +// and subroutineRet fields. Translate any BasicBlock pointers using the given +// translator. Set the generation to zero. +// +inline void BasicBlock::initVerification(BasicBlock &src, Function1 &translator) +{ + new(temps.initVerificationTemps()) VerificationTemps(src.getVerificationEnvIn(), translator, + translator(src.getSubroutineHeader()), translator(src.getSubroutineRet())); +} + + +// +// Prepare this BasicBlock for translation into a primitive graph. +// +inline void BasicBlock::initTranslation(TranslationCommonEnv &commonEnv) +{ + new(temps.initTranslationTemps()) TranslationTemps(commonEnv); +} + + +// +// Initialize this CatchBlock contained in the given BytecodeGraph. +// The CatchBlock's successor is given. +// +inline CatchBlock::CatchBlock(BytecodeGraph &bytecodeGraph, BytecodeBlock &handler): + BasicBlock(bytecodeGraph, bbCatch, sn0), + successor(&handler) +{ + successorsBegin = &successor; + successorsEnd = &successor + 1; + handlersEnd = successorsEnd; + #ifdef DEBUG + successorsPhysicalEnd = handlersEnd; + #endif +} + + +// +// Make a copy of the src CatchBlock pointing to the same handler as src and add it +// to the given graph. However, do not copy or initialize the VerificationTemps or +// TranslationTemps in the copy. +// +inline CatchBlock::CatchBlock(BytecodeGraph &bytecodeGraph, const CatchBlock &src): + BasicBlock(bytecodeGraph, bbCatch, sn0), + successor(src.successor) +{ + successorsBegin = &successor; + successorsEnd = &successor + 1; + handlersEnd = successorsEnd; + #ifdef DEBUG + successorsPhysicalEnd = handlersEnd; + #endif +} + + +// +// Return the handler passed to this CatchBlock's constructor. +// +inline BytecodeBlock &CatchBlock::getHandler() const +{ + return *static_cast(successor); +} + + +// +// Initialize this BytecodeBlock contained in the given BytecodeGraph. +// The caller should later call initSuccessors to set up this block's successors. +// +inline BytecodeBlock::BytecodeBlock(BytecodeGraph &bytecodeGraph, const bytecode *bytecodesBegin, StackNormalization stackNormalization): + BasicBlock(bytecodeGraph, bbBytecode, stackNormalization), + bytecodesBegin(bytecodesBegin), + catchBlock(0), + subkind(skNormal) +{} + + +// +// Return true if this block must not have any handlers and createBlocks should not +// allocates any room for handlers. +// +inline bool BytecodeBlock::handlersForbidden() const +{ + return !hasSubkind(skNormal); +} + + +// +// Change this skJsr block to a skJsrNoRet block. Return a pointer suitable as an +// argument to transformToForward. +// +inline BasicBlock **BytecodeBlock::transformToJsrNoRet() +{ + assert(hasSubkind(skJsr)); + subkind = skJsrNoRet; + BasicBlock **e = successorsEnd - 1; + successorsEnd = e; + handlersEnd = e; + #ifdef DEBUG + successorsPhysicalEnd = e; + #endif + return e; +} + + +// +// Change this skRet block to a skForward block. successor must point to a one-word +// block of memory allocated from this bytecode graph's pool that points to this block's +// unique successor. +// +inline void BytecodeBlock::transformToForward(BasicBlock **successor) +{ + assert(hasSubkind(skRet)); + subkind = skForward; + successorsBegin = successor; + BasicBlock **e = successor + 1; + successorsEnd = e; + handlersEnd = e; + #ifdef DEBUG + successorsPhysicalEnd = e; + #endif + bytecodesEnd = bytecodesBegin; +} + + +// +// Return bc word-aligned as needed for a tableswitch or lookupswitch bytecode. +// +inline const bytecode *BytecodeGraph::switchAlign(const bytecode *bc) +{ + // Assumes that bytecodesBegin is word-aligned. + return (const bytecode *)((size_t)bc + 3 & -4); +} + + +#endif diff --git a/ef/Compiler/FrontEnd/BytecodeTranslator.cpp b/ef/Compiler/FrontEnd/BytecodeTranslator.cpp new file mode 100644 index 000000000000..f34e2e12cbe8 --- /dev/null +++ b/ef/Compiler/FrontEnd/BytecodeTranslator.cpp @@ -0,0 +1,2666 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#include "BytecodeTranslator.h" +#include "PrimitiveBuilders.h" +#include "MemoryAccess.h" +#include "FieldOrMethod.h" + +static const UnaryBuilder *const unaryBuilders[] = +{ + &builder_Neg_II, // bcINeg + &builder_Neg_LL, // bcLNeg + &builder_Neg_FF, // bcFNeg + &builder_Neg_DD, // bcDNeg + 0, // bcIShl + 0, // bcLShl + 0, // bcIShr + 0, // bcLShr + 0, // bcIUShr + 0, // bcLUShr + 0, // bcIAnd + 0, // bcLAnd + 0, // bcIOr + 0, // bcLOr + 0, // bcIXor + 0, // bcLXor + 0, // bcIInc + &builder_Conv_IL, // bcI2L + &builder_Conv_IF, // bcI2F + &builder_Conv_ID, // bcI2D + &builder_Conv_LI, // bcL2I + &builder_Conv_LF, // bcL2F + &builder_Conv_LD, // bcL2D + &builder_Conv_FI, // bcF2I + &builder_Conv_FL, // bcF2L + &builder_Conv_FD, // bcF2D + &builder_Conv_DI, // bcD2I + &builder_Conv_DL, // bcD2L + &builder_Conv_DF, // bcD2F + &builder_ExtB_II, // bcInt2Byte + &builder_ExtC_II, // bcInt2Char + &builder_ExtS_II // bcInt2Short +}; + +static const BinaryBuilder *const binaryBuilders[] = +{ + &builder_AddCoal_III, // bcIAdd + &builder_AddCoal_LLL, // bcLAdd + &builder_Add_FFF, // bcFAdd + &builder_Add_DDD, // bcDAdd + &builder_SubCoal_III, // bcISub + &builder_SubCoal_LLL, // bcLSub + &builder_Sub_FFF, // bcFSub + &builder_Sub_DDD, // bcDSub + &builder_Mul_III, // bcIMul + &builder_Mul_LLL, // bcLMul + &builder_Mul_FFF, // bcFMul + &builder_Mul_DDD, // bcDMul + &builder_Div_III, // bcIDiv + &builder_Div_LLL, // bcLDiv + &builder_Div_FFF, // bcFDiv + &builder_Div_DDD, // bcDDiv + &builder_Mod_III, // bcIRem + &builder_Mod_LLL, // bcLRem + &builder_Rem_FFF, // bcFRem + &builder_Rem_DDD, // bcDRem + 0, // bcINeg + 0, // bcLNeg + 0, // bcFNeg + 0, // bcDNeg + &builder_Shl_III, // bcIShl + &builder_Shl_LIL, // bcLShl + &builder_Shr_III, // bcIShr + &builder_Shr_LIL, // bcLShr + &builder_UShr_III, // bcIUShr + &builder_UShr_LIL, // bcLUShr + &builder_And_III, // bcIAnd + &builder_And_LLL, // bcLAnd + &builder_Or_III, // bcIOr + &builder_Or_LLL, // bcLOr + &builder_Xor_III, // bcIXor + &builder_Xor_LLL, // bcLXor + 0, // bcIInc + 0, // bcI2L + 0, // bcI2F + 0, // bcI2D + 0, // bcL2I + 0, // bcL2F + 0, // bcL2D + 0, // bcF2I + 0, // bcF2L + 0, // bcF2D + 0, // bcD2I + 0, // bcD2L + 0, // bcD2F + 0, // bcInt2Byte + 0, // bcInt2Char + 0, // bcInt2Short + &builder_Cmp3_LLI, // bcLCmp + &builder_Cmp3L_FFI, // bcFCmpL + &builder_Cmp3G_FFI, // bcFCmpG + &builder_Cmp3L_DDI, // bcDCmpL + &builder_Cmp3G_DDI // bcDCmpG +}; + +static const ComparisonBuilder *const unaryComparisonBuilders[] = +{ + &builder_CmpEq_IIC, // bcIfEq + &builder_CmpEq_IIC, // bcIfNe + &builder_Cmp_IIC, // bcIfLt + &builder_Cmp_IIC, // bcIfGe + &builder_Cmp_IIC, // bcIfGt + &builder_Cmp_IIC // bcIfLe +}; + +static const BinaryBuilder *const binaryComparisonBuilders[] = +{ + &builder_CmpEq_IIC, // bcIf_ICmpEq + &builder_CmpEq_IIC, // bcIf_ICmpNe + &builder_Cmp_IIC, // bcIf_ICmpLt + &builder_Cmp_IIC, // bcIf_ICmpGe + &builder_Cmp_IIC, // bcIf_ICmpGt + &builder_Cmp_IIC, // bcIf_ICmpLe + &builder_CmpUEq_AAC, // bcIf_ACmpEq + &builder_CmpUEq_AAC // bcIf_ACmpNe +}; + + +static const Condition2 bytecodeConditionals[] = +{ + condEq, // bcIfEq + condNe, // bcIfNe + condLt, // bcIfLt + condGe, // bcIfGe + condGt, // bcIfGt + condLe, // bcIfLe + condEq, // bcIf_ICmpEq + condNe, // bcIf_ICmpNe + condLt, // bcIf_ICmpLt + condGe, // bcIf_ICmpGe + condGt, // bcIf_ICmpGt + condLe, // bcIf_ICmpLe + condEq, // bcIf_ACmpEq + condNe, // bcIf_ACmpNe + cond0, // bcGoto + cond0, // bcJsr + cond0, // bcRet + cond0, // bcTableSwitch + cond0, // bcLookupSwitch + cond0, // bcIReturn + cond0, // bcLReturn + cond0, // bcFReturn + cond0, // bcDReturn + cond0, // bcAReturn + cond0, // bcReturn + cond0, // bcGetStatic + cond0, // bcPutStatic + cond0, // bcGetField + cond0, // bcPutField + cond0, // bcInvokeVirtual + cond0, // bcInvokeSpecial + cond0, // bcInvokeStatic + cond0, // bcInvokeInterface + cond0, // bc_unused_ + cond0, // bcNew + cond0, // bcNewArray + cond0, // bcANewArray + cond0, // bcArrayLength + cond0, // bcAThrow + cond0, // bcCheckCast + cond0, // bcInstanceOf + cond0, // bcMonitorEnter + cond0, // bcMonitorExit + cond0, // bcWide + cond0, // bcMultiANewArray + condEq, // bcIfNull + condNe // bcIfNonnull +}; + + +const TypeKind arrayAccessTypeKinds[] = +{ + tkInt, // bcIALoad, bcIAStore + tkLong, // bcLALoad, bcLAStore + tkFloat, // bcFALoad, bcFAStore + tkDouble, // bcDALoad, bcDAStore + tkObject, // bcAALoad, bcAAStore + tkByte, // bcBALoad, bcBAStore + tkChar, // bcCALoad, bcCAStore + tkShort // bcSALoad, bcSAStore +}; + + +const LoadBuilder *const loadBuilders[] = +{ + 0, // tkVoid + &builder_LdU_AB, // tkBoolean + &builder_LdU_AB, // tkUByte + &builder_LdS_AB, // tkByte + &builder_LdU_AH, // tkChar + &builder_LdS_AH, // tkShort + &builder_Ld_AI, // tkInt + &builder_Ld_AL, // tkLong + &builder_Ld_AF, // tkFloat + &builder_Ld_AD, // tkDouble + &builder_Ld_AA, // tkObject + &builder_Ld_AA, // tkSpecial + &builder_Ld_AA, // tkArray + &builder_Ld_AA // tkInterface +}; + + +const StoreBuilder *const storeBuilders[] = +{ + 0, // tkVoid + &builder_St_AB, // tkBoolean + &builder_St_AB, // tkUByte + &builder_St_AB, // tkByte + &builder_St_AH, // tkChar + &builder_St_AH, // tkShort + &builder_St_AI, // tkInt + &builder_St_AL, // tkLong + &builder_St_AF, // tkFloat + &builder_St_AD, // tkDouble + &builder_St_AA, // tkObject + &builder_St_AA, // tkSpecial + &builder_St_AA, // tkArray + &builder_St_AA // tkInterface +}; + + +static const SysCall *const newArrayCalls[natLimit - natMin] = +{ + &scNewBooleanArray, // natBoolean + &scNewCharArray, // natChar + &scNewFloatArray, // natFloat + &scNewDoubleArray, // natDouble + &scNewByteArray, // natByte + &scNewShortArray, // natShort + &scNewIntArray, // natInt + &scNewLongArray // natLong +}; + + +static const SysCall *const typeToArrayCalls[nPrimitiveTypeKinds] = +{ + NULL, // tkVoid + &scNewBooleanArray, // tkBoolean + &scNewByteArray, // tkUByte + &scNewByteArray, // tkByte + &scNewCharArray, // tkChar + &scNewShortArray, // tkShort + &scNewIntArray, // tkInt + &scNewLongArray, // tkLong + &scNewFloatArray, // tkFloat + &scNewDoubleArray // tkDouble +}; + + +// ---------------------------------------------------------------------------- +// BytecodeTranslator::BlockTranslator + + +// +// Create a new, empty control node to hold the rest of this BytecodeBlock and set cn +// to be that control node. Make edge e be the one predecessor (so far) of the +// new control node. +// +void BytecodeTranslator::BlockTranslator::appendControlNode(ControlEdge &e) +{ + ControlNode &nextControlNode = getControlGraph().newControlNode(); + nextControlNode.addPredecessor(e); + cn = &nextControlNode; +} + + +// +// Designate this ControlNode to be an Exc, Throw, or AExc node, depending on the given +// ControlKind. This node will have zero (Throw) or one (Exc or AExc) normal successors +// (whose targets are not initialized -- the caller will have to do that) followed by as +// many exceptional successors as there are possible handlers for an exception of class +// exceptionClass thrown from within this BytecodeBlock. The exceptional successor edges are +// fully initialized, as is the ExceptionExtra node's handlerFilters array. +// +// If the ControlNode will be an Exc or Throw node, tryPrimitive must be a primitive +// located inside this node that can throw an exception; if the ControlNode will be an +// AExc node, tryPrimitive must be nil. +// +// translationEnv's stack is ignored. +// This routine assumes ownership of translationEnv if canOwnEnv is true (thereby sometimes eliminating +// an unnecessary copy). +// +void BytecodeTranslator::BlockTranslator::genException(ControlKind ck, Primitive *tryPrimitive, const Class &exceptionClass, + bool canOwnEnv) const +{ + assert(cn && hasExceptionOutgoingEdges(ck)); + Uint32 nNormalSuccessors = ck != ckThrow; + Uint32 maxNHandlers = block.handlersEnd - block.successorsEnd + 1; + const Class **filters = new(primitivePool) const Class *[maxNHandlers]; + ControlEdge *successors = new(primitivePool) ControlEdge[nNormalSuccessors + maxNHandlers]; + + // Copy the list of handlers from the BytecodeBlock to the ExceptionExtra. + // Remove any handlers that can't apply. + const Class **srcFilter = block.exceptionClasses; + const Class **dstFilter = filters; + BasicBlock **srcSuccessor = block.successorsEnd; + ControlEdge *dstSuccessor = successors + nNormalSuccessors; + BasicBlock *successor; + while (--maxNHandlers) { + const Class *filter = *srcFilter++; + successor = *srcSuccessor++; + + assert(filter->implements(Standard::get(cThrowable))); + if (filter == &Standard::get(cThrowable)) + goto haveCatchAll; + if (exceptionClass.implements(*filter) || filter->implements(exceptionClass)) { + *dstFilter++ = filter; + bt.linkPredecessor(*successor, *dstSuccessor++, getEnv(), false); + } + } + // We haven't reached a catch-all handler, so direct remaining exceptions to + // the End block, which indicates that they are propagated out of this function. + successor = bt.bytecodeGraph.endBlock; + + haveCatchAll: + // Fill in the catch-all handler. + *dstFilter++ = &Standard::get(cThrowable); + bt.linkPredecessor(*successor, *dstSuccessor, getEnv(), canOwnEnv); + + cn->setControlException(ck, dstFilter - filters, filters, tryPrimitive, successors); +} + + +// +// Generate an unconditional throw of the given exception, which is guaranteed not to +// have a null value. The exception's class must be a subclass of exceptionClass, which +// must be a subclass of Throwable; exceptionClass is not checked for integrity. +// +// Set cn to nil to indicate that no more control nodes should be generated. +// +// This routine assumes ownership of translationEnv if canOwnEnv is true (thereby sometimes eliminating +// an unnecessary copy). +// +void BytecodeTranslator::BlockTranslator::genThrowCommon(const VariableOrConstant &exception, const Class &exceptionClass, + bool canOwnEnv) +{ + // asharma - fix me + Primitive &prim = makeSysCall(scThrow, 0, 1, &exception, 0, 0, *cn, 0); + genException(ckThrow, &prim, exceptionClass, canOwnEnv); + cn = 0; +} + + +// +// Generate an unconditional throw of the given exception, which is a system-defined +// instance of Throwable or one of its subclasses; exceptionObject is not checked for +// integrity. Set cn to nil to indicate that no more control nodes should be generated. +// +// This routine assumes ownership of translationEnv if canOwnEnv is true (thereby sometimes eliminating +// an unnecessary copy). +// +void BytecodeTranslator::BlockTranslator::genSimpleThrow(cobj exceptionObject, bool canOwnEnv) +{ + VariableOrConstant exception; + exception.setConstant(objectAddress(exceptionObject)); + genThrowCommon(exception, exceptionObject->getClass(), canOwnEnv); +} + + +// +// Generate an exc node that indicates that prim might throw an exception +// of the given class or one of its subclasses; exceptionClass must be Throwable +// or one of its subclasses and is not checked for integrity. +// prim is the primitive inside cn that can throw exceptions. There must be no +// other primitives in cn that rely on prim's outgoing data edge, if any. +// +// Set cn to a control node to use for the next portion of this BytecodeBlock; +// that control node is always empty. +// +// This routine does not assume ownership of translationEnv. +// +void BytecodeTranslator::BlockTranslator::genPossibleThrow(Primitive &prim, const Class &exceptionClass) +{ + genException(ckExc, &prim, exceptionClass, false); + appendControlNode(cn->getNormalSuccessor()); +} + + +// +// Make cn into a basic block control node. Allocate its ControlExtra record +// and link it to the successor BasicBlock. +// Set cn to nil to indicate that no more control nodes should be generated. +// +// If the basic block would be empty and have only one predecessor, eliminate it +// and instead link the successor to the predecessor. +// +void BytecodeTranslator::BlockTranslator::createBasicBlock(BasicBlock &successor) +{ + ControlEdge *edge; + + if (cn->empty() && cn->getPredecessors().lengthIs(1)) { + // Eliminate this basic block and recycle its ControlNode. + edge = &cn->getPredecessors().first(); + assert(block.getGeneratedControlNodes()); + if (block.getFirstControlNode() == cn) + block.getFirstControlNode() = 0; + edge->clearTarget(); // Clear cn's predecessor linked list. + getControlGraph().recycle(*cn); + } else { + cn->setControlBlock(); + edge = &cn->getNormalSuccessor(); + } + bt.linkPredecessor(successor, *edge, *translationEnv, true); + cn = 0; +} + + +// +// Make cn into an IF control node. Allocate its ControlExtra record and +// link it to the successor BasicBlocks. c contains the condition variable. +// If c satisfies cond2 (or reverse(cond2) if reverseCond2 is true), the IF +// will branch to the true successor; otherwise, it will branch to the false +// successor. On exit set cn to nil. +// +void BytecodeTranslator::BlockTranslator::createIf(Condition2 cond2, + bool reverseCond2, + VariableOrConstant &c, + BasicBlock &successorFalse, + BasicBlock &successorTrue, + Uint32 bci) +{ + if (reverseCond2) + cond2 = reverse(cond2); + + bool constResult; + DataNode *cp = partialComputeComparison(cond2, c, constResult); + if (cp) { + // The value of the selector is not known at compile time. + cn->setControlIf(cond2, *cp, bci); + bt.linkPredecessor(successorTrue, cn->getTrueSuccessor(), *translationEnv, false); + bt.linkPredecessor(successorFalse, cn->getFalseSuccessor(), *translationEnv, true); + cn = 0; + } else + // The comparison result is known at compile time. + createBasicBlock(constResult ? successorTrue : successorFalse); +} + + +// +// Same as createIf except that if the selector is false, continue processing this +// BytecodeBlock using the new control node in cn. If the selector is true, go to +// successorTrue as in createIf. +// +// Set cn to a control node to use for the next portion of this BytecodeBlock or +// nil if the selector is known to always be true. +// +void +BytecodeTranslator::BlockTranslator::createContinuedIf(Condition2 cond2, + bool reverseCond2, + VariableOrConstant &c, + BasicBlock &successorTrue, + Uint32 bci) +{ + if (reverseCond2) + cond2 = reverse(cond2); + + bool constResult; + DataNode *cp = partialComputeComparison(cond2, c, constResult); + if (cp) { + // The value of the selector is not known at compile time. + cn->setControlIf(cond2, *cp, bci); + bt.linkPredecessor(successorTrue, cn->getTrueSuccessor(), *translationEnv, false); + appendControlNode(cn->getFalseSuccessor()); + } else if (constResult) + // The condition is always true. + createBasicBlock(successorTrue); +} + + +// +// Create control and data flow nodes to make sure that arg (which must have +// pointer kind) is non-null. +// +// Set cn to a control node to use for the next portion of this BytecodeBlock or +// nil if the rest of this BytecodeBlock is dead. +// +void BytecodeTranslator::BlockTranslator::genNullGuard(const VariableOrConstant &arg, Uint32 bci) +{ + Primitive *prim; + + switch (makeChkNull(arg, prim, cn, bci)) { + case chkAlwaysOK: + break; + case chkNeverOK: + genSimpleThrow(&Standard::get(oNullPointerException), true); + break; + default: + genPossibleThrow(*prim, Standard::get(cNullPointerException)); + } +} + + +// +// Create control and data flow nodes for a tableswitch bytecode. +// bc points immediately after the tableswitch opcode. +// +// Set cn to nil to indicate that no more control nodes should be generated. +// +void BytecodeTranslator::BlockTranslator::genTableSwitch(const bytecode *bc, + Uint32 bci) +{ + VariableOrConstant arg1; + VariableOrConstant arg2; + VariableOrConstant arg3; + TranslationEnv &env = *translationEnv; + + env.pop().extract(arg1, bci); + bc = BytecodeGraph::switchAlign(bc) + 4; // Skip past padding and default target. + Int32 low = readBigSWord(bc); + Int32 high = readBigSWord(bc + 4); + bc += 8; + assert(low <= high); + Uint32 nCases = high - low + 1; + bc += nCases * 4; + assert(bc == block.bytecodesEnd); + assert(block.nSuccessors() == nCases + 1); + + // Do the range check; jump to the default case if out of range. + builder_AddCoal_III.specializeArgConst(arg1, -low, arg2, cn); + Primitive *prim = builder_CmpU_IIC.specializeArgConst(arg2, (Int32)nCases, arg3, cn); + createContinuedIf(condGe, prim != 0, arg3, block.getSuccessor(0), bci); + + BasicBlock **successorsEnd = block.successorsEnd; + BasicBlock **nextSuccessor = block.successorsBegin + 1; + if (cn) + if (arg2.isConstant()) + // The switch argument is a constant, so go directly to the corresponding target. + createBasicBlock(block.getSuccessor(1 + arg2.getConstant().i - low)); + else { + // The value of the switch argument is not known at compile time. + cn->setControlSwitch(arg2.getVariable(), nCases, bci); + ControlEdge *ce = cn->getSwitchSuccessors(); + while (nextSuccessor != successorsEnd) + bt.linkPredecessor(**nextSuccessor++, *ce++, env, false); + cn = 0; + } +} + + +// +// Create control and data flow nodes for a lookupswitch bytecode. +// bc points immediately after the lookupswitch opcode. +// +// Set cn to nil to indicate that no more control nodes should be generated. +// +void BytecodeTranslator::BlockTranslator::genLookupSwitch(const bytecode *bc, + Uint32 bci) +{ + VariableOrConstant arg; + + translationEnv->pop().extract(arg, bci); + bc = BytecodeGraph::switchAlign(bc) + 4; // Skip past padding and default target. + Uint32 nPairs = readBigUWord(bc); + bc += 4; + assert(block.nSuccessors() == nPairs + 1); + if (nPairs == 0) + createBasicBlock(block.getSuccessor(0)); + else { + BasicBlock **nextSuccessor = block.successorsBegin + 1; + while (true) { + VariableOrConstant result; + Int32 match = readBigSWord(bc); + bc += 8; + Primitive *prim = builder_CmpEq_IIC.specializeArgConst(arg, match, result, cn); + nPairs--; + if (nPairs) { + createContinuedIf(condEq, prim != 0, result, + **nextSuccessor++, bci); + if (!cn) { + // We're done early. + bc += nPairs * 8; + break; + } + } else { + createIf(condEq, prim != 0, result, block.getSuccessor(0), + **nextSuccessor, bci); + break; + } + } + } + assert(bc == block.bytecodesEnd); +} + + +// +// Create data flow nodes to read the type of an object. The object pointer should +// already have been checked to make sure it is not null. +// +inline void +BytecodeTranslator::BlockTranslator::genReadObjectType(const VariableOrConstant &object, VariableOrConstant &type, Uint32 bci) const { + assert(objectTypeOffset == 0); + builder_Ld_AA.makeLoad(0, object, type, false, true, cn, bci); +} + + +// +// Create data flow nodes for a getstatic bytecode. +// cpi is the constant table index of the static variable entry. +// +void BytecodeTranslator::BlockTranslator::genGetStatic(ConstantPoolIndex cpi, Uint32 bci) const +{ + ValueKind vk; + addr address; + bool isVolatile; + bool isConstant; + TypeKind tk = classFileSummary.lookupStaticField(cpi, vk, address, isVolatile, isConstant); + TranslationEnv &env = *translationEnv; + + DataNode *memory = &env.memory().extract(bci); + VariableOrConstant result; + loadBuilders[tk]->makeLoad(&memory, address, result, isVolatile, + isConstant, cn, bci); + env.memory().define(*memory); + env.push1or2(isDoublewordKind(vk)).define(result, cn, envPool); +} + + +// +// Create data flow nodes for a putstatic bytecode. +// cpi is the constant table index of the static variable entry. +// +void BytecodeTranslator::BlockTranslator::genPutStatic(ConstantPoolIndex cpi, + Uint32 bci) const +{ + ValueKind vk; + addr address; + bool isVolatile; + bool isConstant; + TypeKind tk = classFileSummary.lookupStaticField(cpi, vk, address, isVolatile, isConstant); + TranslationEnv &env = *translationEnv; + + if (isConstant) + verifyError(VerifyError::writeToConst); + VariableOrConstant a; + a.setConstant(address); + VariableOrConstant value; + env.pop1or2(isDoublewordKind(vk)).extract(value, bci); + Primitive &memoryOut = storeBuilders[tk]->makeStore(env.memory().extract(bci), a, value, + isVolatile, cn, bci); + env.memory().define(memoryOut); +} + + +// +// Create control and data flow nodes for a getfield bytecode. +// cpi is the constant table index of the field entry. +// +// Set cn to a control node to use for the next statement of this BytecodeBlock or +// nil if the rest of this BytecodeBlock is dead. +// +void BytecodeTranslator::BlockTranslator::genGetField(ConstantPoolIndex cpi, + Uint32 bci) +{ + ValueKind vk; + Uint32 offset; + bool isVolatile; + bool isConstant; + TypeKind tk = classFileSummary.lookupInstanceField(cpi, vk, offset, isVolatile, isConstant); + TranslationEnv &env = *translationEnv; + + VariableOrConstant objectAddr; + env.pop().extract(objectAddr, bci); + genNullGuard(objectAddr, bci); + if (cn) { + // Get the address of the field. + VariableOrConstant fieldAddr; + builder_Add_AIA.specializeArgConst(objectAddr, (Int32)offset, fieldAddr, cn); + + // Emit the load instruction. + DataNode *memory = &env.memory().extract(bci); + VariableOrConstant result; + loadBuilders[tk]->makeLoad(&memory, fieldAddr, result, isVolatile, isConstant, cn, bci); + env.memory().define(*memory); + env.push1or2(isDoublewordKind(vk)).define(result, cn, envPool); + } +} + + +// +// Create control and data flow nodes for a putfield bytecode. +// cpi is the constant table index of the field entry. +// +// Set cn to a control node to use for the next statement of this BytecodeBlock or +// nil if the rest of this BytecodeBlock is dead. +// +void BytecodeTranslator::BlockTranslator::genPutField(ConstantPoolIndex cpi, + Uint32 bci) +{ + ValueKind vk; + Uint32 offset; + bool isVolatile; + bool isConstant; + TypeKind tk = classFileSummary.lookupInstanceField(cpi, vk, offset, isVolatile, isConstant); + TranslationEnv &env = *translationEnv; + + if (isConstant) + verifyError(VerifyError::writeToConst); + VariableOrConstant value; + VariableOrConstant objectAddr; + env.pop1or2(isDoublewordKind(vk)).extract(value, bci); + env.pop().extract(objectAddr, bci); + genNullGuard(objectAddr, bci); + if (cn) { + // Get the address of the field. + VariableOrConstant fieldAddr; + builder_Add_AIA.specializeArgConst(objectAddr, (Int32)offset, fieldAddr, cn); + + // Emit the store instruction. + Primitive &memoryOut = + storeBuilders[tk]->makeStore(env.memory().extract(bci), fieldAddr, + value, isVolatile, cn, bci); + env.memory().define(memoryOut); + } +} + + +// +// Create control and data flow nodes to read the length of an array. +// Make sure that arrayAddr isn't nil and return the array length in arrayLength. +// +// Set cn to a control node to use for the next portion of this BytecodeBlock or +// nil if the rest of this BytecodeBlock is dead. +// +void BytecodeTranslator::BlockTranslator::genReadArrayLength(const VariableOrConstant &arrayAddr, VariableOrConstant &arrayLength, Uint32 bci) +{ + genNullGuard(arrayAddr, bci); + if (cn) { + // Get the address of the field. + VariableOrConstant fieldAddr; + builder_Add_AIA.specializeArgConst(arrayAddr, arrayLengthOffset, fieldAddr, cn); + + // Emit the load instruction. + builder_Ld_AI.makeLoad(0, fieldAddr, arrayLength, false, true, cn, bci); + } +} + + +// +// Create control and data flow nodes to make sure that the object can be +// written into the object array, which should already have been checked to +// make sure it is not null. +// +// Set cn to a control node to use for the next portion of this BytecodeBlock or +// nil if the rest of this BytecodeBlock is dead. +// +void BytecodeTranslator::BlockTranslator::genArrayCastGuard(const VariableOrConstant &array, const VariableOrConstant &object) +{ + assert(object.hasKind(vkAddr) && array.hasKind(vkAddr)); + // We can write nil into any object array so we don't bother issuing a check + // if we know that we're writing a nil. + if (!object.isConstant() || !object.getConstant().a) { + // Do we know the actual types of both the object and the array? + Type *objectType = object.getDynamicType(); + if (objectType) { + Type *arrayType = array.getDynamicType(); + if (arrayType) { + // Yes. Perform the check statically. + assert(arrayType->typeKind == tkArray); + if (!implements(*objectType, static_cast(arrayType)->componentType)) + genSimpleThrow(&Standard::get(oArrayStoreException), true); + return; + } + } + + VariableOrConstant args[2]; + args[0] = array; + args[1] = object; + // asharma - fix me + Primitive &prim = makeSysCall(scCheckArrayStore, 0, 2, args, 0, 0, *cn, 0); + genPossibleThrow(prim, Standard::get(cArrayStoreException)); + } +} + + +// +// Create control and data flow nodes for an array read or write bytecode. +// If write is true, the access is a write; otherwise it's a read. +// +// Set cn to a control node to use for the next portion of this BytecodeBlock or +// nil if the rest of this BytecodeBlock is dead. +// +void BytecodeTranslator::BlockTranslator::genArrayEltAccess(TypeKind tk, bool + write, Uint32 bci) +{ + VariableOrConstant value; + VariableOrConstant index; + VariableOrConstant length; // Array length + VariableOrConstant arrayAddrAndOffset[2]; // [0] is array address; [1] is index times element size + TranslationEnv &env = *translationEnv; + + if (write) + env.pop1or2(isDoublewordKind(tk)).extract(value, bci); + env.pop().extract(index, bci); + env.pop().extract(arrayAddrAndOffset[0], bci); + genReadArrayLength(arrayAddrAndOffset[0], length, bci); + + if (cn) { + // Check bounds + Primitive *prim; + CheckResult chkRes = makeLimit(index, length, prim, cn); + if (chkRes == chkNeverOK) + genSimpleThrow(&Standard::get(oArrayIndexOutOfBoundsException), true); + else { + if (chkRes != chkAlwaysOK) + genPossibleThrow(*prim, Standard::get(cArrayIndexOutOfBoundsException)); + + // Check cast if needed + assert(isPrimitiveKind(tk) || tk == tkObject); + if (write && tk == tkObject) + genArrayCastGuard(arrayAddrAndOffset[0], value); + + if (cn) { + // Get the address of the element. + VariableOrConstant elementAddr; + builder_Shl_III.specializeArgConst(index, getLgTypeKindSize(tk), arrayAddrAndOffset[1], cn); + builder_Add_AIA.makeBinaryGeneric(arrayAddrAndOffset, elementAddr, cn); + builder_AddCoal_AIA.specializeArgConst(elementAddr, arrayEltsOffset(tk), elementAddr, cn); + + DataNode *memory = &env.memory().extract(bci); + if (write) + // Emit the store instruction. + env.memory().define(storeBuilders[tk]->makeStore(*memory, elementAddr, value, false, cn, bci)); + else { + // Emit the load instruction. + loadBuilders[tk]->makeLoad(&memory, elementAddr, value, false, false, cn, bci); + env.push1or2(isDoublewordKind(tk)).define(value, cn, envPool); + } + } + } + } +} + + +// +// Create data flow nodes to check if a reference with class pointed +// at by the type argument is assignable to another reference of type +// targetInterface, which is either an interface type or the type of +// an array of interfaces. type should be a variable, not a constant. +// +// results should be an array of two VariableOrConstants. On exit +// results[0] and results[1] will be initialized to two integer variables +// that, if equal, indicate that the interface check succeeds and, +// if not equal, indicate that the interface check fails. +// +void BytecodeTranslator::BlockTranslator::genCheckInterfaceAssignability(VariableOrConstant &type, const Type &targetInterface, + VariableOrConstant *results, Uint32 bci) const +{ + assert(cn && type.isVariable()); + + // Get the address of the class-specific interface assignability table used + // to determine whether an instance of that class can be assigned to a + // given interface (or interface array) type. + VariableOrConstant vPointerToAssignableTableAddr; + builder_Add_AIA.specializeArgConst(type, offsetof(Type, interfaceAssignableTable), vPointerToAssignableTableAddr, cn); + VariableOrConstant vAssignableTableAddr; + builder_Ld_AA.makeLoad(0, vPointerToAssignableTableAddr, vAssignableTableAddr, false, true, cn, bci); + + // Compute the address of the interface assignability table entry + // corresponding to the given interface. + Uint32 interfaceNumber = targetInterface.getInterfaceNumber(); + VariableOrConstant vAssignableTableEntryAddr; + builder_Add_AIA.specializeArgConst(vAssignableTableAddr, interfaceNumber * sizeof(Uint16), vAssignableTableEntryAddr, cn); + + // Load the selected table entry, which will contain a value that we must match against + VariableOrConstant &vAssignableValue = results[0]; + VariableOrConstant &vMatchValue = results[1]; + builder_LdU_AH.makeLoad(0, vAssignableTableEntryAddr, vAssignableValue, false, true, cn, bci); + + // Load the class-specific match value for comparison with the value found in the table + VariableOrConstant vAddrOfAssignableMatchValue; + builder_Add_AIA.specializeVarConst(type.getVariable(), offsetof(Type, assignableMatchValue), vAddrOfAssignableMatchValue, cn); + builder_LdU_AH.makeLoad(0, vAddrOfAssignableMatchValue, vMatchValue, false, true, cn, bci); +} + + +// +// Create control and data flow nodes for a checkcast bytecode that checks +// that object arg is a member of type t. Type t is guaranteed not to be Object, +// and arg is guaranteed to be nonnull. +// +// Set cn to a new, empty node to use for the next portion of this BytecodeBlock or +// to nil if an exception is always thrown. +// +void BytecodeTranslator::BlockTranslator::genCheckCastNonNull(const Type &t, const VariableOrConstant &arg, Uint32 bci) +{ + assert(!isPrimitiveKind(t.typeKind)); + + VariableOrConstant type; + genReadObjectType(arg, type, bci); + + if (type.isConstant()) { + // We determined the type of arg at compile time. Do nothing if it a subtype of t; + // otherwise, always throw ClassCastException. + if (!implements(addressAsType(type.getConstant().a), t)) + genSimpleThrow(&Standard::get(oClassCastException), true); + } else { + DataNode &dp = type.getVariable(); + Primitive *prim; + + if (t.final) + // We're testing against a final type. Emit a simple equality test + // that ensures that arg is the same as the given final type. + prim = makeChkCastA(dp, t, cn); + else if ((t.typeKind == tkObject) || + ((t.typeKind == tkArray) && (asArray(t).getElementType().typeKind != tkInterface))) { + + // We're testing against an object or an array type that is not an array of + // interfaces. Emit a vtable-based test that passes the given type and its subtypes. + // The given type and each of its subtypes will have a pointer to type t + // in the ventry at index nVTableSlots-1. + + // Make sure that we have a sufficient number of vEntries. + VariableOrConstant nVEntriesAddr; + builder_Add_AIA.specializeVarConst(dp, offsetof(Type, nVTableSlots), nVEntriesAddr, cn); + VariableOrConstant nVEntries; + builder_Ld_AI.makeLoad(0, nVEntriesAddr, nVEntries, false, true, cn, bci); + Primitive *limPrim; + CheckResult chkRes = makeLimCast(nVEntries, t.nVTableSlots, limPrim, cn); + if (chkRes == chkNeverOK) { + genSimpleThrow(&Standard::get(oClassCastException), true); + return; + } + if (chkRes != chkAlwaysOK) + genPossibleThrow(*limPrim, Standard::get(cClassCastException)); + + // Get the value of the vEntry at index nVTableSlots-1. + VariableOrConstant vEntryAddr; + builder_Add_AIA.specializeVarConst(dp, vTableIndexToOffset(t.nVTableSlots - 1), vEntryAddr, cn); + VariableOrConstant vEntryValue; + builder_Ld_AA.makeLoad(0, vEntryAddr, vEntryValue, false, true, cn, bci); + + // Emit a test to make sure that the vEntry value is the type we desire. + prim = makeChkCastA(vEntryValue.getVariable(), t, cn); + } else { + // We're testing against an interface or an array whose element type is an interface. + assert((t.typeKind == tkInterface) || ((t.typeKind == tkArray) && (asArray(t).getElementType().typeKind == tkInterface))); + + // Generate a runtime assignability check + VariableOrConstant cmpArgs[2]; + genCheckInterfaceAssignability(type, t, cmpArgs, bci); + prim = makeChkCastI(cmpArgs[0].getVariable(), cmpArgs[1].getVariable(), cn); + } + genPossibleThrow(*prim, Standard::get(cClassCastException)); + } +} + + +// +// Create control and data flow nodes for a checkcast bytecode that checks +// that object arg satisfies the type represented by cpi. +// +// Set cn to a control node to use for the next portion of this BytecodeBlock or +// nil if the checkcast always throws an exception. +// +void BytecodeTranslator::BlockTranslator::genCheckCast(ConstantPoolIndex cpi, const VariableOrConstant &arg, Uint32 bci) +{ + const Type &t = classFileSummary.lookupType(cpi); + + // A cast to the type Object always succeeds. + if (&t != &Standard::get(cObject)) { + // Try to statically check whether the object is null. + bool constResult; + VariableOrConstant cond; + builder_CmpUEq_AAC.specializeArgConst(arg, nullAddr, cond, cn); + DataNode *cp = partialComputeComparison(condEq, cond, constResult); + if (cp) { + // We have to check whether the object is null at runtime. + ControlNode *cnIf = cn; + cnIf->setControlIf(condEq, *cp, bci); + + // Create a new ControlNode to hold the check code. + appendControlNode(cnIf->getFalseSuccessor()); + genCheckCastNonNull(t, arg, bci); + if (!cn) + cn = &getControlGraph().newControlNode(); + + // Attach the true arm of the if to the latest control node, which should + // be empty at this point. + assert(cn->empty()); + cn->addPredecessor(cnIf->getTrueSuccessor()); + } else + // The object is either always or never null. If it's always null, don't + // bother emitting any code. + if (!constResult) + // The object is never null. + genCheckCastNonNull(t, arg, bci); + } +} + + +// +// Create control and data flow nodes for an instanceof bytecode that checks +// whether object arg is a member of type t and returns the int result (1 if arg is +// a member of type t, 0 if not) in result. Type t is guaranteed not to be Object, +// and arg is guaranteed to be nonnull. +// cnFalse is either nil or a pointer to a control node that will store false in the +// result. +// +// Set cn to a control node to use for the next portion of this BytecodeBlock. +// The outgoing cn will never be nil. +// +void BytecodeTranslator::BlockTranslator::genInstanceOfNonNull(const Type &t, const VariableOrConstant &arg, VariableOrConstant &result, ControlNode *cnFalse, Uint32 bci) +{ + assert(!isPrimitiveKind(t.typeKind)); + + VariableOrConstant type; + genReadObjectType(arg, type, bci); + + if (type.isConstant()) + // We determined the type of arg at compile time. + // Return the constant 0 or 1, as appropriate. + result.setConstant((Int32)implements(addressAsType(type.getConstant().a), t)); + + else { + DataNode &dp = type.getVariable(); + VariableOrConstant args[2]; + args[0].setVariable(dp); + args[1].setConstant(objectAddress(&t)); + + if (t.final) + // We're testing against a final type. Emit a simple equality test + // that checks whether arg is the same as the given final type. + builder_Eq_AAI.makeBinaryGeneric(args, result, cn); + + else if ((t.typeKind == tkObject) || + ((t.typeKind == tkArray) && (asArray(t).getElementType().typeKind != tkInterface))) { + + // We're testing against an object or an array type where the elements + // of the array are not interfaces. + // Emit a vtable-based test that passes the given type and its subtypes. + // The given type and each of its subtypes will have a pointer to type t + // in the ventry at index nVTableSlots-1. + + // Make sure that we have a sufficient number of vEntries. + VariableOrConstant nVEntriesAddr; + builder_Add_AIA.specializeVarConst(dp, offsetof(Type, nVTableSlots), nVEntriesAddr, cn); + VariableOrConstant nVEntries; + builder_Ld_AI.makeLoad(0, nVEntriesAddr, nVEntries, false, true, cn, bci); + + // Emit the comparison and if node. + VariableOrConstant argCmp; + Primitive *reverseCmp = builder_Cmp_IIC.specializeArgConst(nVEntries, t.nVTableSlots, argCmp, cn); + Condition2 cond2 = reverseCmp ? condGt : condLt; + bool constResult; + DataNode *cp = partialComputeComparison(cond2, argCmp, constResult); + bool needJoin = false; + if (!cp) { + // The result of the if is known at compile time. + // (This should not be possible, because we've already + // tested for a type known at compile-time, above, but + // this code might be purposeful in the future.) + if (constResult) { + // The if is always true, so the result is always false. + result.setConstant((Int32)0); + return; + } + // The if is always false, so don't emit the if. + } else { + ControlNode *cnIf = cn; + cnIf->setControlIf(cond2, *cp, bci); + + // Create a new control node for the false branch of the if and store it in cn. + appendControlNode(cnIf->getFalseSuccessor()); + if (!cnFalse) { + cnFalse = &getControlGraph().newControlNode(); + needJoin = true; + } + cnFalse->addPredecessor(cnIf->getTrueSuccessor()); + } + + // Get the value of the vEntry at index nVTableSlots-1. + VariableOrConstant vEntryAddr; + builder_Add_AIA.specializeVarConst(dp, vTableIndexToOffset(t.nVTableSlots - 1), vEntryAddr, cn); + builder_Ld_AA.makeLoad(0, vEntryAddr, args[0], false, true, cn, bci); + + // Emit a test to make sure that the vEntry value is the type we desire. + builder_Eq_AAI.makeBinaryGeneric(args, result, cn); + + // If we created our own control node for the true branch of the if, we must now join it + // with the control flow leaving the false branch. + if (needJoin) { + ControlNode *predecessors[2]; + args[0] = result; + args[1].setConstant((Int32)0); + predecessors[0] = cn; + predecessors[1] = cnFalse; + cn = &joinControlFlows(2, predecessors, getControlGraph()); + joinDataFlows(2, *cn, args, result); + } + + } else { + // We're testing against an interface or an array whose element type is an interface. + assert((t.typeKind == tkInterface) || ((t.typeKind == tkArray) && (asArray(t).getElementType().typeKind == tkInterface))); + + VariableOrConstant cmpArgs[2]; + genCheckInterfaceAssignability(type, asInterface(t), cmpArgs, bci); + builder_Eq_III.makeBinaryGeneric(cmpArgs, result, cn); + } + } +} + + +// +// Create control and data flow nodes for an instanceof bytecode that checks +// whether object arg is a member of the type represented by cpi. However, +// unlike checkcast, nil is not considered to be a member of any type. +// The result VariableOrConstant gets an int result that is 1 if arg is a member +// of the type or 0 if not. +// +// Set cn to a control node to use for the next portion of this BytecodeBlock. +// The outgoing cn will never be nil. +// +void BytecodeTranslator::BlockTranslator::genInstanceOf(ConstantPoolIndex cpi, const VariableOrConstant &arg, VariableOrConstant &result, Uint32 bci) +{ + const Type &t = classFileSummary.lookupType(cpi); + + if (&t == &Standard::get(cObject)) + // "x instanceof Object" succeeds if and only if x is non-nil. + builder_Ne0_AI.makeUnaryGeneric(arg, result, cn); + else { + // Try to statically check whether the object is null. + bool constResult; + VariableOrConstant cond; + builder_CmpUEq_AAC.specializeArgConst(arg, nullAddr, cond, cn); + DataNode *cp = partialComputeComparison(condEq, cond, constResult); + if (cp) { + // We have to check whether the object is null at runtime. + ControlNode *cnIf = cn; + cnIf->setControlIf(condEq, *cp, bci); + + // Create a new ControlNode to hold the instanceof code for the null case. + VariableOrConstant args[2]; + ControlNode *predecessors[2]; + appendControlNode(cnIf->getTrueSuccessor()); + args[1].setConstant((Int32)0); + predecessors[1] = cn; + + // Create a new ControlNode to hold the instanceof code for the non-null case. + appendControlNode(cnIf->getFalseSuccessor()); + genInstanceOfNonNull(t, arg, args[0], predecessors[1], bci); + predecessors[0] = cn; + + // Merge the outputs of the above two ControlNodes. + cn = &joinControlFlows(2, predecessors, getControlGraph()); + joinDataFlows(2, *cn, args, result); + } else + // The object is either always or never null. + if (constResult) + // The object is always null. + result.setConstant((Int32)0); + else + // The object is never null. + genInstanceOfNonNull(t, arg, result, 0, bci); + } +} + + +// +// Create control and data flow nodes for a system call that receives +// a memory argument together with the given arguments and outputs a new +// memory state together with one one-word result and can throw any exception. +// Push the result onto the environment. +// +// Set cn to a control node to use for the next portion of this BytecodeBlock. +// +void BytecodeTranslator::BlockTranslator::genNewCommon(const SysCall &sysCall, uint nArgs, const VariableOrConstant *args, Uint32 bci) +{ + VariableOrConstant result; + TranslationEnv &env = *translationEnv; + DataNode *memory = &env.memory().extract(bci); + Primitive &prim = makeSysCall(sysCall, &memory, nArgs, args, 1, &result, *cn, bci); + env.memory().define(*memory); + env.push().define(result.getVariable()); // OK because result cannot be a constant here. + genPossibleThrow(prim, Standard::get(sysCall.exceptionClass)); +} + + +// +// Create code to allocate a temporary array for storing all the dimensions +// of a multi-dimensional array, which is pushed onto the environment. +// +// Set cn to a control node to use for the next portion of this BytecodeBlock or +// nil if the rest of this BytecodeBlock is dead. +// +void BytecodeTranslator::BlockTranslator::genTempArrayOfDim(Int32 dim, Uint32 bci) +{ + VariableOrConstant args[2], arg, *dimargs; + Int32 i; + TranslationEnv &env = *translationEnv; + + // Pull all the dimensions out of the environment. + dimargs = new(primitivePool) VariableOrConstant[dim]; + for (i=dim-1; i>=0; i--) { + env.pop().extract(dimargs[i], bci); + // check for negative dimension here + assert(dimargs[i].hasKind(vkInt)); + if (dimargs[i].isConstant() && dimargs[i].getConstant().i < 0) { + genSimpleThrow(&Standard::get(oNegativeArraySizeException), true); + return; + } + } + args[0].setConstant(dim); // the number of ints to allocate + genNewCommon(*typeToArrayCalls[tkInt], 1, args, bci); + env.pop().extract(args[0], bci); // array now stored in args[0] + // Now loop through dimensions and generate code to fill the array. + // We need to do the following: + // for each argument (picked from the environment in reverse order), + // store it in the array using the code for iastore + // (genArrayEltAccess(tkInt, 1)). + // We proceed by pushing the array, followed by i, and dimargs[i]. + // Then, generate a call to genArrayEltAccess(). + // Return the resulting control node. + for (i=0; istackNth(sig.nArgumentSlots()).extract(receiver, bci); + genNullGuard(receiver, bci); +} + + +// +// Generate code to perform a virtual method lookup. The receiver object +// is the "this" object and is guaranteed to be nonnull. vIndex is the index +// (not offset!) of the virtual table entry. +// Store the looked-up function address in functionAddr. +// +void BytecodeTranslator::BlockTranslator::genVirtualLookup(const VariableOrConstant &receiver, Uint32 vIndex, + VariableOrConstant &functionAddr, Uint32 bci) const +{ + VariableOrConstant type; + genReadObjectType(receiver, type, bci); + + // Get the address of the vEntry. + VariableOrConstant vEntryAddr; + builder_Add_AIA.specializeArgConst(type, vTableIndexToOffset(vIndex), vEntryAddr, cn); + + // Emit the load instruction. + builder_Ld_AA.makeLoad(0, vEntryAddr, functionAddr, false, true, cn, bci); +} + + +// +// Generate code to perform an interface method lookup. The receiver object +// is the "this" object and is guaranteed to be nonnull. vIndex is the index +// (not offset!) of the virtual table entry. +// Store the looked-up function address in functionAddr. +// +void BytecodeTranslator::BlockTranslator::genInterfaceLookup(const VariableOrConstant &receiver, + Uint32 interfaceNumber, + Uint32 vIndex, + const Method *interfaceMethod, + VariableOrConstant &functionAddr, + Uint32 bci) const +{ + VariableOrConstant type; + genReadObjectType(receiver, type, bci); + + // Check for a receiver object of type known at compile-time. + // In this case, we can statically determine the method within the + // receiver's type that implements the interface method. + if (type.isConstant()) { + Type &receiverType = addressAsType(type.getConstant().a); + ClassFileSummary *receiverSummary = NULL; + + if (receiverType.typeKind == tkObject) { + receiverSummary = asClass(receiverType).summary; + } else { + assert(receiverType.typeKind == tkArray); + /* Arrays never have interface methods */ + verifyError(VerifyError::noSuchMethod); + } + + // Get the class method that implements the given interface method + addr a; + Uint32 vIndex; + const Method *method; + method = receiverSummary->lookupImplementationOfInterfaceMethod(interfaceMethod, vIndex, a); + if (!method) + verifyError(VerifyError::noSuchMethod); + + // Generate normal virtual function dispatch or set function address if it's + // known at compile-time. + if (method) + functionAddr.setConstant(a); + else + genVirtualLookup(receiver, vIndex, functionAddr, bci); + + } else { + + VariableOrConstant vVars[2]; + VariableOrConstant &vSubVTableOffset = vVars[1]; + VariableOrConstant &vEntryOffset = vVars[0]; + + // Get the address of the class-specific interface table used to locate + // the sub-vtable dedicated to the given interface within the class' vtable + VariableOrConstant vPointerToInterfaceTableAddr; + builder_Add_AIA.specializeArgConst(type, offsetof(Type, interfaceVIndexTable), + vPointerToInterfaceTableAddr, cn); + VariableOrConstant vInterfaceTableAddr; + builder_Ld_AA.makeLoad(0, vPointerToInterfaceTableAddr, vInterfaceTableAddr, false, true, cn, bci); + + // Compute the address of the interface table entry corresponding to the + // given interface. + VariableOrConstant vInterfaceTableEntryAddr; + assert(sizeof(VTableOffset) == 4); + builder_Add_AIA.specializeArgConst(vInterfaceTableAddr, interfaceNumber * sizeof(VTableOffset), + vInterfaceTableEntryAddr, cn); + + // Compute the offset into the class's VTable which corresponds to the base + // of the sub-vtable for this interface + builder_Ld_AI.makeLoad(0, vInterfaceTableEntryAddr, vSubVTableOffset, false, true, cn, bci); + + // Get the offset of the vEntry within the interface's sub-vtable. + builder_Add_AIA.specializeArgConst(type, vIndex * sizeof(VTableEntry), vEntryOffset, cn); + + // Compute the address of the vtable entry + VariableOrConstant vVTableEntryAddr; + builder_Add_AIA.makeBinaryGeneric(vVars, vVTableEntryAddr, cn); + + // Emit the load instruction to get the function's address from the vtable entry. + builder_Ld_AA.makeLoad(0, vVTableEntryAddr, functionAddr, false, true, cn, bci); + } +} + +// +// Generate a function call. opcode should be one of the four opcodes +// invokevirtual, invokespecial, invokestatic, or invokeinterface. +// cpi is the constant pool index of the method. +// If opcode is bcInvokeInterface, nArgs is the number of arguments. +// +// Set cn to a control node to use for the next portion of this BytecodeBlock or +// nil if the rest of this BytecodeBlock is dead. +// +void BytecodeTranslator::BlockTranslator::genInvoke(bytecode opcode, ConstantPoolIndex cpi, uint nArgs, Uint32 bci) +{ + Signature sig; + VariableOrConstant receiver; + VariableOrConstant function; + const Method *method; + TranslationEnv &env = *translationEnv; + + function.setConstant(nullAddr); + switch (opcode) { + case bcInvokeVirtual: + { + Uint32 vIndex; + method = classFileSummary.lookupVirtualMethod(cpi, sig, vIndex, function.getConstant().a); + genReceiverNullCheck(sig, receiver, bci); + if (!cn) + return; + if (!method) + genVirtualLookup(receiver, vIndex, function, bci); + } + break; + case bcInvokeSpecial: + { + bool isInit; + method = &classFileSummary.lookupSpecialMethod(cpi, sig, isInit, function.getConstant().a); + genReceiverNullCheck(sig, receiver, bci); + if (!cn) + return; + } + break; + case bcInvokeStatic: + method = &classFileSummary.lookupStaticMethod(cpi, sig, function.getConstant().a); + break; + case bcInvokeInterface: + { + Uint32 vIndex, interfaceNumber; + method = classFileSummary.lookupInterfaceMethod(cpi, sig, vIndex, interfaceNumber, + function.getConstant().a, nArgs); + genReceiverNullCheck(sig, receiver, bci); + if (!cn) + return; + assert(!method); + genInterfaceLookup(receiver, interfaceNumber, vIndex, method, function, bci); + } + break; + default: + trespass("Bad invoke opcode"); + return; + } + + VariableOrConstant result; + VariableOrConstant args20[20]; // Hold arguments here if there are fewer than 20. + VariableOrConstant *args = args20; + uint nArguments = sig.nArguments; + if (nArguments > 20) + args = new(envPool) VariableOrConstant[nArguments]; + + // Pop the arguments off the environment stack. + const Type **argumentType = sig.argumentTypes + nArguments; + VariableOrConstant *arg = args + nArguments; + while (arg != args) + env.pop1or2(isDoublewordKind((*--argumentType)->typeKind)).extract(*--arg, bci); + + // Create the call primitive. + DataNode *memory = &env.memory().extract(bci); + Primitive &prim = makeCall(sig, memory, function, method, args, &result, *cn, bci); + env.memory().define(*memory); + + // Push the result onto the environment stack. + if (sig.getNResults()) + env.push1or2(isDoublewordKind(result.getKind())).define(result, cn, envPool); + genPossibleThrow(prim, Standard::get(cThrowable)); +} + + +// +// Create control and data flow nodes for the primitives inside this BytecodeBlock. +// Use and modify translationEnv to keep track of the locals' and stack temporaries' values. +// +// Set cn to nil when done. +// +void BytecodeTranslator::BlockTranslator::genLivePrimitives() +{ + BytecodeGraph &bg = bt.bytecodeGraph; + TranslationEnv &env = *translationEnv; + const AttributeCode *code = (AttributeCode *) + bg.method.getMethodInfo().getAttribute("Code"); + AttributeLocalVariableTable *localVariableTable = + (AttributeLocalVariableTable *) code->getAttribute("LocalVariableTable"); + const bytecode *const bytecodesEnd = block.bytecodesEnd; + const bytecode *bc = block.bytecodesBegin; + + while (bc != bytecodesEnd) { + assert(bc < bytecodesEnd); + bytecode opcode = *bc++; + ValueKind vk; + Value v; + Uint32 i; + ConstantPoolIndex cpi; + Int32 j; + TranslationBinding *tb; + VariableOrConstant args[4]; + VariableOrConstant result; + Primitive *prim; + const Type *cl; + IntervalMapping *mapping; + Uint32 bci = bc - bg.bytecodesBegin; + + switch (opcode) { + + case bcNop: + break; + + case bcAConst_Null: + env.push().definePtr(nullAddr, cn, envPool); + break; + case bcIConst_m1: + case bcIConst_0: + case bcIConst_1: + case bcIConst_2: + case bcIConst_3: + case bcIConst_4: + case bcIConst_5: + env.push().defineInt(opcode - bcIConst_0, cn, envPool); + break; + case bcLConst_0: + env.push2().defineLong(0, cn, envPool); + break; + case bcLConst_1: + env.push2().defineLong(1, cn, envPool); + break; + case bcFConst_0: + env.push().defineFloat(0.0, cn, envPool); + break; + case bcFConst_1: + env.push().defineFloat(1.0, cn, envPool); + break; + case bcFConst_2: + env.push().defineFloat(2.0, cn, envPool); + break; + case bcDConst_0: + env.push2().defineDouble(0.0, cn, envPool); + break; + case bcDConst_1: + env.push2().defineDouble(1.0, cn, envPool); + break; + case bcBIPush: + env.push().defineInt(*(Int8 *)bc, cn, envPool); + bc++; + break; + case bcSIPush: + env.push().defineInt(readBigSHalfwordUnaligned(bc), cn, envPool); + bc += 2; + break; + case bcLdc: + cpi = *(Uint8 *)bc; + bc++; + goto pushConst1; + case bcLdc_W: + cpi = readBigUHalfwordUnaligned(bc); + bc += 2; + pushConst1: + vk = classFileSummary.lookupConstant(cpi, v); + assert(isWordKind(vk)); + env.push().define(vk, v, cn, envPool); + break; + case bcLdc2_W: + vk = classFileSummary.lookupConstant(readBigUHalfwordUnaligned(bc), v); + bc += 2; + assert(isDoublewordKind(vk)); + env.push2().define(vk, v, cn, envPool); + break; + + case bcILoad: + case bcFLoad: + case bcALoad: + i = *(Uint8 *)bc; + bc++; + pushLoad1: + env.push() = env.local(i); + break; + case bcLLoad: + case bcDLoad: + i = *(Uint8 *)bc; + bc++; + pushLoad2: + assert(env.local(i+1).isSecondWord()); + env.push2() = env.local(i); + break; + case bcILoad_0: + case bcILoad_1: + case bcILoad_2: + case bcILoad_3: + i = opcode - bcILoad_0; + goto pushLoad1; + case bcLLoad_0: + case bcLLoad_1: + case bcLLoad_2: + case bcLLoad_3: + i = opcode - bcLLoad_0; + goto pushLoad2; + case bcFLoad_0: + case bcFLoad_1: + case bcFLoad_2: + case bcFLoad_3: + i = opcode - bcFLoad_0; + goto pushLoad1; + case bcDLoad_0: + case bcDLoad_1: + case bcDLoad_2: + case bcDLoad_3: + i = opcode - bcDLoad_0; + goto pushLoad2; + case bcALoad_0: + case bcALoad_1: + case bcALoad_2: + case bcALoad_3: + i = opcode - bcALoad_0; + goto pushLoad1; + + case bcIALoad: + case bcLALoad: + case bcFALoad: + case bcDALoad: + case bcAALoad: + case bcBALoad: + case bcCALoad: + case bcSALoad: + genArrayEltAccess(arrayAccessTypeKinds[opcode - bcIALoad], false, bci); + goto checkDeadRestOfBlock; + + case bcIStore: + case bcFStore: + case bcAStore: + i = *(Uint8 *)bc; + bc++; + popStore1: + // asharma - label this one + if (localVariableTable) { + DoublyLinkedList &mappings = + localVariableTable->getEntry(i)->mappings; + IntervalMapping *prev; + + mapping = new IntervalMapping(); // Fix me! + mapping->setStart((Uint32) (bc - bg.bytecodesBegin)); + if (!mappings.empty()) { + prev = &mappings.get(mappings.end()); + prev->setEnd((Uint32) (bc - bg.bytecodesBegin)); + } + mappings.addLast(*mapping); + tb = (TranslationBinding *) &env.stackNth(1); + if (tb->isDataEdge()) { + tb->extract(bci).mapping = mapping; + } + } + env.local(i) = env.pop(); + break; + case bcLStore: + case bcDStore: + i = *(Uint8 *)bc; + bc++; + popStore2: + // asharma label this one + env.local(i) = env.pop2(); + env.local(i+1).defineSecondWord(); + break; + case bcIStore_0: + case bcIStore_1: + case bcIStore_2: + case bcIStore_3: + i = opcode - bcIStore_0; + goto popStore1; + case bcLStore_0: + case bcLStore_1: + case bcLStore_2: + case bcLStore_3: + i = opcode - bcLStore_0; + goto popStore2; + case bcFStore_0: + case bcFStore_1: + case bcFStore_2: + case bcFStore_3: + i = opcode - bcFStore_0; + goto popStore1; + case bcDStore_0: + case bcDStore_1: + case bcDStore_2: + case bcDStore_3: + i = opcode - bcDStore_0; + goto popStore2; + case bcAStore_0: + case bcAStore_1: + case bcAStore_2: + case bcAStore_3: + i = opcode - bcAStore_0; + goto popStore1; + + case bcIAStore: + case bcLAStore: + case bcFAStore: + case bcDAStore: + case bcAAStore: + case bcBAStore: + case bcCAStore: + case bcSAStore: + genArrayEltAccess(arrayAccessTypeKinds[opcode - bcIAStore], true, bci); + goto checkDeadRestOfBlock; + + case bcPop: + env.drop(1); + break; + case bcPop2: + env.drop(2); + break; + case bcDup: + tb = &env.stackNth(1); + env.push() = *tb; + break; + case bcDup_x1: + env.raise(1); + tb = env.stackTopN(3); + tb[-1] = tb[-2]; + tb[-2] = tb[-3]; + tb[-3] = tb[-1]; + break; + case bcDup_x2: + env.raise(1); + tb = env.stackTopN(4); + tb[-1] = tb[-2]; + tb[-2] = tb[-3]; + tb[-3] = tb[-4]; + tb[-4] = tb[-1]; + break; + case bcDup2: + env.raise(2); + tb = env.stackTopN(4); + tb[-1] = tb[-3]; + tb[-2] = tb[-4]; + break; + case bcDup2_x1: + env.raise(2); + tb = env.stackTopN(5); + tb[-1] = tb[-3]; + tb[-2] = tb[-4]; + tb[-3] = tb[-5]; + tb[-4] = tb[-1]; + tb[-5] = tb[-2]; + break; + case bcDup2_x2: + env.raise(2); + tb = env.stackTopN(6); + tb[-1] = tb[-3]; + tb[-2] = tb[-4]; + tb[-3] = tb[-5]; + tb[-4] = tb[-6]; + tb[-5] = tb[-1]; + tb[-6] = tb[-2]; + break; + case bcSwap: + { + TranslationBinding tempBinding; + tb = env.stackTopN(2); + tempBinding = tb[-1]; + tb[-1] = tb[-2]; + tb[-2] = tempBinding; + } + break; + + case bcIAdd: + case bcFAdd: + case bcISub: + case bcFSub: + case bcIMul: + case bcFMul: + case bcFDiv: + case bcFRem: + case bcIShl: + case bcIShr: + case bcIUShr: + case bcIAnd: + case bcIOr: + case bcIXor: + case bcFCmpL: + case bcFCmpG: + env.pop().extract(args[1], bci); + tb = env.stackTopN(1) - 1; + genGenericBinary: + tb->extract(args[0], bci); + genExtractedBinary: + binaryBuilders[opcode - bcIAdd]->makeBinaryGeneric(args, result, cn); + tb->define(result, cn, envPool); + break; + case bcLAdd: + case bcDAdd: + case bcLSub: + case bcDSub: + case bcLMul: + case bcDMul: + case bcDDiv: + case bcDRem: + case bcLAnd: + case bcLOr: + case bcLXor: + env.pop2().extract(args[1], bci); + genLongShift: + tb = env.stackTopN(2) - 2; + assert(tb[1].isSecondWord()); + goto genGenericBinary; + case bcLShl: + case bcLShr: + case bcLUShr: + env.pop().extract(args[1], bci); + goto genLongShift; + case bcLCmp: + case bcDCmpL: + case bcDCmpG: + env.pop2().extract(args[1], bci); + env.pop2().extract(args[0], bci); + tb = &env.push(); + goto genExtractedBinary; + + case bcIDiv: + case bcIRem: + env.pop().extract(args[1], bci); + tb = env.stackTopN(1) - 1; + assert(args[1].hasKind(vkInt)); + if (args[1].isConstant() && args[1].getConstant().i == 0) { + // If the second argument is always zero, this operation becomes an unconditional throw. + genSimpleThrow(&Standard::get(oArithmeticException), true); + // The rest of this BytecodeBlock is dead. + return; + } + genIntegerDivRem: + tb->extract(args[0], bci); + prim = binaryBuilders[opcode - bcIAdd]->makeBinaryGeneric(args, result, cn); + tb->define(result, cn, envPool); + if (prim && prim->canRaiseException()) + genPossibleThrow(*prim, Standard::get(cArithmeticException)); + break; + case bcLDiv: + case bcLRem: + env.pop2().extract(args[1], bci); + tb = env.stackTopN(2) - 2; + assert(tb[1].isSecondWord()); + assert(args[1].hasKind(vkLong)); + if (args[1].isConstant() && args[1].getConstant().l == 0) { + // If the second argument is always zero, this operation becomes an unconditional throw. + genSimpleThrow(&Standard::get(oArithmeticException), true); + // The rest of this BytecodeBlock is dead. + return; + } + goto genIntegerDivRem; + + case bcINeg: + case bcFNeg: + case bcI2F: + case bcF2I: + case bcInt2Byte: + case bcInt2Char: + case bcInt2Short: + tb = env.stackTopN(1) - 1; + genGenericUnary: + tb->extract(args[0], bci); + genExtractedUnary: + unaryBuilders[opcode - bcINeg]->makeUnaryGeneric(args[0], result, cn); + tb->define(result, cn, envPool); + break; + case bcLNeg: + case bcDNeg: + case bcL2D: + case bcD2L: + tb = env.stackTopN(2) - 2; + assert(tb[1].isSecondWord()); + goto genGenericUnary; + case bcI2L: + case bcI2D: + case bcF2L: + case bcF2D: + env.pop().extract(args[0], bci); + tb = &env.push2(); + goto genExtractedUnary; + case bcL2I: + case bcL2F: + case bcD2I: + case bcD2F: + env.pop2().extract(args[0], bci); + tb = &env.push(); + goto genExtractedUnary; + + case bcIInc: + i = *(Uint8 *)bc; + bc++; + j = *(Int8 *)bc; + bc++; + incLocal: + // asharma label this one + env.local(i).extract(args[0], bci); + builder_AddCoal_III.specializeArgConst(args[0], j, result, cn); + env.local(i).define(result, cn, envPool); + break; + + case bcIfEq: + case bcIfNe: + case bcIfLt: + case bcIfGe: + case bcIfGt: + case bcIfLe: + env.pop().extract(args[0], bci); + prim = unaryComparisonBuilders[opcode - bcIfEq]->specializeArgConst(args[0], 0, result, cn); + genIf: + // We should have exactly two successors. + createIf(bytecodeConditionals[opcode - bcIfEq], prim != 0, result, block.getSuccessor(0), block.getSuccessor(1), bci); + // We should be at the end of the basic block. + assert(bc + 2 == bytecodesEnd); + return; + case bcIf_ICmpEq: + case bcIf_ICmpNe: + case bcIf_ICmpLt: + case bcIf_ICmpGe: + case bcIf_ICmpGt: + case bcIf_ICmpLe: + case bcIf_ACmpEq: + case bcIf_ACmpNe: + env.pop().extract(args[1], bci); + env.pop().extract(args[0], bci); + prim = binaryComparisonBuilders[opcode - bcIf_ICmpEq]->makeBinaryGeneric(args, result, cn); + goto genIf; + + case bcGoto_W: + bc += 2; + case bcGoto: + bc += 2; + // We should be at the end of the basic block. + assert(bc == bytecodesEnd); + break; + + case bcJsr_W: + bc += 2; + case bcJsr: + bc += 2; + env.push().clear(); // Push the return address, which is not used since we eliminated all ret's already. + // We should be at the end of the basic block. + assert(bc == bytecodesEnd); + break; + + case bcTableSwitch: + genTableSwitch(bc, bci); + return; + case bcLookupSwitch: + genLookupSwitch(bc, bci); + return; + + case bcLReturn: + case bcDReturn: + env.pop2().extract(args[0], bci); + goto genValueReturn; + case bcIReturn: + case bcFReturn: + case bcAReturn: + env.pop().extract(args[0], bci); + genValueReturn: + vk = args[0].getKind(); + cn->setControlReturn(1, &vk, bci); + cn->getReturnExtra()[0].getInput() = args[0]; + goto genReturn; + case bcReturn: + cn->setControlReturn(0, 0, bci); + genReturn: + assert(block.nSuccessors() == 1); + bt.linkPredecessor(*block.successorsBegin[0], cn->getReturnSuccessor(), env, true); + cn = 0; + assert(bc == bytecodesEnd); + return; + + case bcGetStatic: + genGetStatic(readBigUHalfwordUnaligned(bc), bci); + bc += 2; + break; + case bcPutStatic: + genPutStatic(readBigUHalfwordUnaligned(bc), bci); + bc += 2; + break; + case bcGetField: + genGetField(readBigUHalfwordUnaligned(bc), bci); + add2CheckDeadRestOfBlock: + bc += 2; + // Exit if the rest of this BytecodeBlock is dead. + checkDeadRestOfBlock: + if (!cn) { + // The rest of this BytecodeBlock is dead. + assert(bc < bytecodesEnd); + return; + } + break; + case bcPutField: + genPutField(readBigUHalfwordUnaligned(bc), bci); + goto add2CheckDeadRestOfBlock; + + case bcInvokeVirtual: + case bcInvokeSpecial: + case bcInvokeStatic: + genInvoke(opcode, readBigUHalfwordUnaligned(bc), 0, bci); + goto add2CheckDeadRestOfBlock; + case bcInvokeInterface: + genInvoke(opcode, readBigUHalfwordUnaligned(bc), *(Uint8 *)(bc + 2), bci); + bc += 4; + goto checkDeadRestOfBlock; + + case bcNew: + args[0].setConstant(objectAddress(&classFileSummary.lookupClass(readBigUHalfwordUnaligned(bc)))); + genNewCommon(scNew, 1, args, bci); + goto add2CheckDeadRestOfBlock; + + case bcNewArray: + i = *(Uint8 *)bc; + bc++; + i -= natMin; + if (i >= natLimit - natMin) + verifyError(VerifyError::badNewArrayType); + env.pop().extract(args[0], bci); + genNewCommon(*newArrayCalls[i], 1, args, bci); + goto checkDeadRestOfBlock; + + case bcANewArray: + args[0].setConstant(objectAddress(&classFileSummary.lookupType(readBigUHalfwordUnaligned(bc)))); + env.pop().extract(args[1], bci); + genNewCommon(scNewObjectArray, 2, args, bci); + goto add2CheckDeadRestOfBlock; + + case bcMultiANewArray: + cl = &classFileSummary.lookupType(readBigUHalfwordUnaligned(bc)); + args[0].setConstant(objectAddress(cl)); // array type argument + i = *(Uint8 *)(bc+2); // dimension + bc += 3; + switch (i) { + case 1: + cl = &asArray(*cl).getElementType(); + if (isPrimitiveKind(cl->typeKind)) { // converted to a base type + env.pop().extract(args[0], bci); // number of elements + genNewCommon(*typeToArrayCalls[cl->typeKind], 1, args, bci); + } + else { // converted to a class type + env.pop().extract(args[1], bci); // number of elements + genNewCommon(scNewObjectArray, 2, args, bci); + } + break; + case 2: + env.pop().extract(args[2], bci); // first dimension + env.pop().extract(args[1], bci); // second dimension + genNewCommon(scNew2DArray, 3, args, bci); + break; + case 3: + env.pop().extract(args[3], bci); // as above + env.pop().extract(args[2], bci); + env.pop().extract(args[1], bci); + genNewCommon(scNew3DArray, 4, args, bci); + break; + default: + // i>=4 + // generate temporary array to store all the dimensions in, and + // push it onto the environment + genTempArrayOfDim(i, bci); + if (!cn) + return; // temporary array construction will throw exception + env.pop().extract(args[1], bci); + genNewCommon(scNewNDArray, 2, args, bci); + break; + } + goto checkDeadRestOfBlock; + + case bcArrayLength: + env.pop().extract(args[0], bci); + genReadArrayLength(args[0], result, bci); + if (!cn) + return; // The rest of this BytecodeBlock is dead. + env.push().define(result, cn, envPool); + break; + + case bcAThrow: + env.pop().extract(args[0], bci); + genThrow(args[0]); + // The rest of this BytecodeBlock is dead, and we should be at the end of it. + assert(bc == bytecodesEnd); + return; + + case bcCheckCast: + env.stackNth(1).extract(args[0], bci); + genCheckCast(readBigUHalfwordUnaligned(bc), args[0], bci); + goto add2CheckDeadRestOfBlock; + + case bcInstanceOf: + env.pop().extract(args[0], bci); + genInstanceOf(readBigUHalfwordUnaligned(bc), args[0], result, bci); + assert(cn); // instanceof can't throw exceptions. + bc += 2; + env.push().define(result, cn, envPool); + break; + + case bcMonitorEnter: + env.pop().extract(args[0], bci); + genNullGuard(args[0], bci); + if (cn) + genPossibleThrow(genMonitor(poMEnter, args[0], bci), Standard::get(cError)); + else { + // The rest of this BytecodeBlock is dead. + assert(bc < bytecodesEnd); + return; + } + break; + + case bcMonitorExit: + env.pop().extract(args[0], bci); + genMonitor(poMExit, args[0], bci); + break; + + case bcWide: + opcode = *bc++; + i = readBigUHalfwordUnaligned(bc); + bc += 2; + switch (opcode) { + case bcILoad: + case bcFLoad: + case bcALoad: + goto pushLoad1; + case bcLLoad: + case bcDLoad: + goto pushLoad2; + + case bcIStore: + case bcFStore: + case bcAStore: + goto popStore1; + case bcLStore: + case bcDStore: + goto popStore2; + + case bcIInc: + j = readBigSHalfwordUnaligned(bc); + bc += 2; + goto incLocal; + + // We should not see these here; they should have been taken out by now. + // case bcRet: + default: + verifyError(VerifyError::badBytecode); + } + break; + + case bcIfNull: + case bcIfNonnull: + env.pop().extract(args[0], bci); + prim = builder_CmpUEq_AAC.specializeArgConst(args[0], nullAddr, result, cn); + goto genIf; + + case bcBreakpoint: + // Ignore breakpoints. + break; + + // We should not see these here; they should have been taken out by now. + // case bcRet: + default: + verifyError(VerifyError::badBytecode); + } + } + + // We fell off the last opcode of this basic block of bytecodes. + // We should have exactly one successor. + assert(block.nSuccessors() == 1); + createBasicBlock(block.getSuccessor(0)); +} + + +// +// Adjust this BytecodeBlock's local environment to allow primitives to be generated +// for this BytecodeBlock before all of its predecessors have been generated. +// This means that local and stack variable bindings may have to be replaced by +// phantom phi nodes. [This is inefficient, so this code should be revised to +// do a prepass figuring out exactly which phi nodes are needed.] +// +// Also create an aexc header node for the cycle. Set cn to the ControlNode to use for +// the rest of this BytecodeBlock. +// +void BytecodeTranslator::BlockTranslator::genCycleHeader() +{ + translationEnv->anticipate(block); + genException(ckAExc, 0, Standard::get(cThreadDeath), false); + appendControlNode(cn->getNormalSuccessor()); +} + + +// ---------------------------------------------------------------------------- +// BytecodeTranslator + + +// +// If stackNormalization is either sn0, sn1, or sn2, pop all except the top +// zero, one, or two words from env, modifying it in place. +// +void BytecodeTranslator::normalizeEnv(TranslationEnv &env, BasicBlock::StackNormalization stackNormalization) +{ + TranslationBinding tempBinding; + + switch (stackNormalization) { + case BasicBlock::snNoChange: + return; + case BasicBlock::sn0: + break; + case BasicBlock::sn1: + tempBinding = env.pop(); + break; + case BasicBlock::sn2: + tempBinding = env.pop2(); + break; + } + env.dropAll(); + switch (stackNormalization) { + case BasicBlock::sn0: + break; + case BasicBlock::sn1: + env.push() = tempBinding; + break; + case BasicBlock::sn2: + env.push2() = tempBinding; + break; + default: + trespass("Bad stackNormalization"); + } +} + + +// +// Take notice that the control node(s) generated from BasicBlock block will have +// another predecessor, as given by controlEdge. The controlEdge should be allocated +// out of the control graph's memory pool. +// Merge the BasicBlock's environment with predecessorEnv, adding phi nodes or +// phantom phi nodes as needed. If canOwnEnv is true, the BasicBlock can assume +// ownership of predecessorEnv (thereby sometimes eliminating an unnecessary copy). +// +void BytecodeTranslator::linkPredecessor(BasicBlock &block, ControlEdge &controlEdge, TranslationEnv &predecessorEnv, bool canOwnEnv) +{ + BasicBlock::StackNormalization stackNormalization = block.stackNormalization; + if (stackNormalization != BasicBlock::snNoChange && predecessorEnv.getSP() != (Uint32)(stackNormalization-BasicBlock::sn0)) + // We have to normalize the stack inside predecessorEnv. + if (canOwnEnv) + normalizeEnv(predecessorEnv, stackNormalization); + else { + TranslationEnv envCopy(predecessorEnv); + normalizeEnv(envCopy, stackNormalization); + linkPredecessor(block, controlEdge, envCopy, true); + return; + } + + ControlNode *first = block.getFirstControlNode(); + assert(block.getGeneratedControlNodes() == (first != 0)); + if (first) { + // Only aexc nodes can be targets of backward edges. + assert(block.hasIncomingBackEdges && first->hasControlKind(ckAExc)); + first->disengagePhis(); + first->addPredecessor(controlEdge); + } else + block.getPredecessors().addLast(controlEdge); + + if (block.getEnvInInitialized()) + block.getTranslationEnvIn().meet(predecessorEnv, block.hasKind(BasicBlock::bbEnd), block); + else { + if (canOwnEnv) + block.getTranslationEnvIn().move(predecessorEnv); + else + block.getTranslationEnvIn() = predecessorEnv; + block.getEnvInInitialized() = true; + } + #ifdef DEBUG + if (first) + first->reengagePhis(); + #endif +} + + + +// +// Call finishedOnePredecessor on every successor. +// +void BytecodeTranslator::finishedOutgoingEdges(BasicBlock &block) +{ + BasicBlock **handlersEnd = block.handlersEnd; + for (BasicBlock **bp = block.successorsBegin; bp != handlersEnd; bp++) + finishedOnePredecessor(**bp); +} + + +// +// Create a new ControlNode for BasicBlock block. +// BasicBlock block must not be dead. +// Return the ControlNode to use for the rest of BasicBlock block. +// If mergeBlock is true and there is only one predecessor node that is a Block node, +// continue to use that Block node instead of making a new ControlNode. +// +ControlNode *BytecodeTranslator::createControlNode(BasicBlock &block, bool mergeBlock) const +{ + assert(!block.getGeneratedControlNodes()); // We shouldn't have generated anything for this node yet. + + if (mergeBlock && block.nPredecessors == block.getNSeenPredecessors() && block.getPredecessors().lengthIs(1)) { + ControlNode &predNode = DoublyLinkedList::get(block.getPredecessors().begin()).getSource(); + if (predNode.hasControlKind(ckBlock)) { + // This node has only one predecessor and it was a ckBlock node, so + // merge this node and its predecessor now. + predNode.unsetControlKind(); + #ifdef DEBUG + block.getGeneratedControlNodes() = true; + #endif + return &predNode; + } + } + + ControlNode *cn = &controlGraph.newControlNode(); + block.getFirstControlNode() = cn; + cn->movePredecessors(block.getPredecessors()); + #ifdef DEBUG + block.getGeneratedControlNodes() = true; + #endif + return cn; +} + + +// +// Create control and data flow nodes out of the EndBlock. genPrimitives must +// have been called on every other BasicBlock before calling this. +// +void BytecodeTranslator::genPrimitives(EndBlock &block) const +{ + // We should have seen all other blocks by now. + assert(block.getNSeenPredecessors() == block.nPredecessors && !block.hasIncomingBackEdges); + // The end block is never dead; either normal control flow or exceptions can always reach it. + assert(block.getEnvInInitialized()); + + assert(!block.getGeneratedControlNodes()); // We shouldn't have generated anything for this node yet. + ControlNode &endNode = controlGraph.getEndNode(); + block.getFirstControlNode() = &endNode; + block.getFirstControlNode()->movePredecessors(block.getPredecessors()); + #ifdef DEBUG + block.getGeneratedControlNodes() = true; + #endif + + // Initialize the finalMemory in the EndNode. + // asharma - fix me + endNode.getEndExtra().finalMemory.getInput().setVariable(block.getTranslationEnvIn().memory().extract(0)); +} + + +// +// Create control and data flow nodes out of the CatchBlock. +// +void BytecodeTranslator::genPrimitives(CatchBlock &block) const +{ + // CatchBlocks cannot be targets of backward control edges. + assert(block.getNSeenPredecessors() == block.nPredecessors); + if (block.getEnvInInitialized()) { + // This isn't a dead CatchBlock if some predecessor already jumps here. + assert(block.getNSeenPredecessors()); + assert(block.nSuccessors() == 1); + ControlNode *cn = createControlNode(block, false); + // asharma fix me! + block.getTranslationEnvIn().push().define(cn->setControlCatch(0)); + linkPredecessor(block.getHandler(), cn->getNormalSuccessor(), block.getTranslationEnvIn(), true); + } + + // Adjust the nPredecessors counts of the successor BasicBlock. + finishedOutgoingEdges(block); +} + + +// +// Create control and data flow nodes out of the BytecodeBlock. +// +void BytecodeTranslator::genPrimitives(BytecodeBlock &block) const +{ + assert(block.getNSeenPredecessors() <= block.nPredecessors); + if (block.getNSeenPredecessors() != block.nPredecessors || block.getEnvInInitialized()) { + // This isn't a dead BytecodeBlock if either some predecessor already jumps + // here or we haven't examined all of the predecessor BasicBlocks yet. + assert(block.getNSeenPredecessors()); + BlockTranslator translator(*this, block.getTranslationEnvIn(), block, createControlNode(block, true)); + + if (block.getNSeenPredecessors() == block.nPredecessors) + // We've seen all the predecessors already. Modify envIn directly -- we won't + // need it any more for merging additional predecessors. + translator.genLivePrimitives(); + else { + // If this block has unseen predecessors in the depth-first order, + // then this block must be the header of a cycle. Use a copy of envIn to + // process this block's primitives. + assert(block.hasIncomingBackEdges); + translator.genCycleHeader(); + TranslationEnv cycleEnv(block.getTranslationEnvIn()); + translator.setEnv(cycleEnv); + translator.genLivePrimitives(); + // cycleEnv must be live up to this point. + } + assert(translator.translatorDone()); + } + + // Adjust the nPredecessors counts of successor BasicBlocks. + finishedOutgoingEdges(block); +} + + +// +// Create control and data flow nodes out of this BytecodeGraph. +// +void BytecodeTranslator::genRawPrimitiveGraph() const +{ + BasicBlock **blockArray = bytecodeGraph.getDFSList(); + for (Uint32 i = bytecodeGraph.getDFSListLength() - 1; i; i--) { + BasicBlock *block = *blockArray++; + assert(block->hasKind(BasicBlock::bbBytecode) || block->hasKind(BasicBlock::bbCatch)); + if (block->hasKind(BasicBlock::bbBytecode)) + genPrimitives(*static_cast(block)); + else + genPrimitives(*static_cast(block)); + } + assert((*blockArray)->hasKind(BasicBlock::bbEnd)); + genPrimitives(*static_cast(*blockArray)); +} + + +// +// Add a synchronization primitive to acquire the syncHolder object's lock on +// method entry. Return the exc control node that contains the MEnter primitive. +// +static ControlNode &addEnterNode(ControlGraph &cg, VariableOrConstant &syncHolder) +{ + Pool &pool = cg.pool; + DoublyLinkedList::iterator where; + ControlNode &beginNode = cg.getBeginNode(); + ControlNode &endNode = cg.getEndNode(); + ControlNode *secondNode; + DataNode &beginMemory = beginNode.getBeginExtra().initialMemory; + + // Insert a new exc node (called enterNode) immediately after the begin node. + // The exc node's normal outgoing edge will go to the node (secondNode) that used to + // be the successor of the begin node. The exc node will also have one outgoing exception + // edge that goes directly to the end node. + ControlNode &enterNode = insertControlNodeAfter(beginNode, secondNode, where); // Disengages secondNode's phi nodes. + const Class **filter = new(pool) const Class *; + filter[0] = &Standard::get(cThrowable); + ControlEdge *enterSuccessors = new(pool) ControlEdge[2]; + // asharma - fix me + Primitive &primEnter = makeMonitorPrimitive(poMEnter, beginMemory, syncHolder, 0, &enterNode, 0); + enterNode.setControlException(ckExc, 1, filter, &primEnter, enterSuccessors); + + // Link the enterNode to its normal successor. + secondNode->addPredecessor(enterSuccessors[0], where); + secondNode->reengagePhis(); + + // Link the enterNode's exception edge to the end node, + // adjusting the end node's memory phi node as necessary. + VariableOrConstant memoryOutVOC; + memoryOutVOC.setVariable(primEnter); + endNode.disengagePhis(); + endNode.addPredecessor(enterSuccessors[1]); + addDataFlow(endNode, endNode.getEndExtra().finalMemory.getInput(), memoryOutVOC); + endNode.reengagePhis(); + + // Replace the function's incoming memory edge by the memory edge (primEnter) generated by the MEnter + // everywhere except in the MEnter itself. + const DoublyLinkedList &beginMemoryConsumers = beginMemory.getConsumers(); + for (DoublyLinkedList::iterator i = beginMemoryConsumers.begin(); !beginMemoryConsumers.done(i);) { + DataConsumer &c = beginMemoryConsumers.get(i); + i = beginMemoryConsumers.advance(i); + if (&c.getNode() != &primEnter) { + c.clearVariable(); + c.setVariable(primEnter); + } + } + return enterNode; +} + + +// +// Add a synchronization primitive to release the syncHolder object's lock on +// normal method exit via the return node if there is one. +// +static void addNormalExitNode(ControlGraph &cg, VariableOrConstant &syncHolder) +{ + ControlNode *returnNode = cg.getReturnNode(); + if (returnNode) { + ControlNode &endNode = cg.getEndNode(); + ControlEdge &returnEdge = returnNode->getReturnSuccessor(); + + // Add an MExit primitive to the return node, consuming the return node's + // current outgoing memory edge and producing a new memory edge. + DataConsumer &finalMemory = endNode.getEndExtra().finalMemory.getInput(); + DataNode &returnMemory = followVariableBack(finalMemory, endNode, returnEdge).getVariable(); + // asharma - fix me + Primitive &returnMemoryOut = makeMonitorPrimitive(poMExit, returnMemory, syncHolder, 0, returnNode, 0); + + // Fix up the end node's memory phi node (creating one if needed) to receive the + // memory edge outgoing from our new MonitorExit primitive when control comes to the end + // node from the return node. + VariableOrConstant returnMemoryOutVOC; + returnMemoryOutVOC.setVariable(returnMemoryOut); + changeDataFlow(endNode, returnEdge, finalMemory, returnMemoryOutVOC); + } +} + + +class ExceptionEdgeIteratee: public Function1 +{ + ControlNode *enterNode; + + public: + explicit ExceptionEdgeIteratee(ControlNode *enterNode): enterNode(enterNode) {} + + bool operator()(ControlEdge &e); +}; + + +// +// Edge e is an edge pointing to the end node in a synchronized method. +// Return true if that method's synchronization lock should be released if +// control follows edge e. +// Given our implementation of addEnterNode and addNormalExitNode, this +// method returns false for edges originating in: +// the return node, +// the node at the beginning of the method that acquires the monitor, and +// the node just before the return node that releases the monitor on normal exit. +// For all other edges this method returns true. +// +bool ExceptionEdgeIteratee::operator()(ControlEdge &e) +{ + ControlNode &source = e.getSource(); + return !(source.hasControlKind(ckReturn) || &source == enterNode); +} + + +// +// Add a synchronization primitive to release the syncHolder object's lock on +// exceptional method exit. +// +static void addExceptionalExitNode(ControlGraph &cg, VariableOrConstant &syncHolder, ControlNode &enterNode, Uint32 bci) +{ + ExceptionEdgeIteratee eei(&enterNode); + ControlNode &endNode = cg.getEndNode(); + ControlNode *exitCatchNode = insertControlNodeBefore(endNode, eei); // Disengages endNode's phi nodes if returns non-nil. + if (exitCatchNode) { + // We have at least one exceptional method exit path that doesn't come from + // the (already inserted) MEnter exc node. + + // Make the newly inserted node into a catch node that intercepts all exceptions + // thrown out of this method except those coming from our new MEnter exc node. + // Connect this catch node's outgoing edge directly to the end node for now. + PrimCatch &primCatch = exitCatchNode->setControlCatch(bci); + ControlEdge &exitCatchSuccessorEdge = exitCatchNode->getNormalSuccessor(); + endNode.addPredecessor(exitCatchSuccessorEdge); + endNode.reengagePhis(); + + // exitMemoryIn will be the memory input to the MonitorExit primitive we're + // about to insert. + DataConsumer &finalMemory = endNode.getEndExtra().finalMemory.getInput(); + DataNode &exitMemoryIn = followVariableBack(finalMemory, endNode, exitCatchSuccessorEdge).getVariable(); + + // Insert a new throw node (called exitNode) immediately after the catch node. + // The throw node will have an MExit primitive followed by a throw primitive that + // rethrows the caught exception. The throw node will have one outgoing exception + // edge that goes directly to the end node. + ControlNode *successor; + DoublyLinkedList::iterator where; + ControlNode &exitNode = insertControlNodeAfter(*exitCatchNode, successor, where); // Disengages endNode's phi nodes. + assert(successor == &endNode); + // asharma - fix me + Primitive &exitMemoryOut = makeMonitorPrimitive(poMExit, exitMemoryIn, syncHolder, 0, &exitNode, 0); + + // Initialize the throw primitive to rethrow the caught exception. + Pool &pool = cg.pool; + const Class **filter = new(pool) const Class *; + filter[0] = &Standard::get(cThrowable); + ControlEdge *throwSuccessors = new(pool) ControlEdge; + VariableOrConstant primCatchVOC; + primCatchVOC.setVariable(primCatch); + Primitive &throwPrim = makeSysCall(scThrow, 0, 1, &primCatchVOC, 0, 0, exitNode, bci); + exitNode.setControlException(ckThrow, 1, filter, &throwPrim, throwSuccessors); + + // Link the throw node's outgoing edge to the end node at location where, + // adjusting the end node's memory phi node as necessary. + VariableOrConstant exitMemoryOutVOC; + exitMemoryOutVOC.setVariable(exitMemoryOut); + endNode.addPredecessor(throwSuccessors[0], where); + endNode.reengagePhis(); + changeDataFlow(endNode, throwSuccessors[0], finalMemory, exitMemoryOutVOC); + } +} + + +// +// Add synchronization primitives to acquire the syncHolder object's lock on method +// entry and release that lock on normal or exceptional method exit. The ControlGraph +// should already have been generated for this method. +// +void BytecodeTranslator::addSynchronization(VariableOrConstant &syncHolder, Uint32 bci) const +{ + ControlGraph &cg = controlGraph; + ControlNode &enterNode = addEnterNode(cg, syncHolder); + addNormalExitNode(cg, syncHolder); + addExceptionalExitNode(cg, syncHolder, enterNode, bci); +} + + +// +// Create a ControlGraph with data flow nodes out of this BytecodeGraph. +// Return the newly allocated ControlGraph or nil if an illegal bytecode was found. +// The BytecodeGraph must be complete and depthFirstSearch must have been called +// before calling this function; the usual way to do these is to call divideIntoBlocks. +// +ControlGraph *BytecodeTranslator::genPrimitiveGraph(BytecodeGraph &bytecodeGraph, Pool &primitivePool, Pool &tempPool) +{ + ControlGraph &cg = *new(primitivePool) + ControlGraph(primitivePool, bytecodeGraph.nArguments, bytecodeGraph.argumentKinds, bytecodeGraph.isInstanceMethod, 1 /***** FIX ME *****/); + + BytecodeTranslator translator(bytecodeGraph, cg, tempPool); + BasicBlock **block = bytecodeGraph.getDFSList(); + BasicBlock **dfsListEnd = block + bytecodeGraph.getDFSListLength(); + while (block != dfsListEnd) + (*block++)->initTranslation(translator); + + BytecodeBlock *beginBlock = bytecodeGraph.beginBlock; + if (beginBlock) { + // Set up the locals and arguments + TranslationEnv env(translator); + + env.init(); + ControlNode::BeginExtra &beginExtra = cg.getBeginNode().getBeginExtra(); + env.memory().define(beginExtra.initialMemory); + uint nArgs = bytecodeGraph.nArguments; + uint slotOffset = 0; + const ValueKind *ak = bytecodeGraph.argumentKinds; + for (uint n = 0; n != nArgs; n++) { + env.local(slotOffset++).define(beginExtra[n]); + if (isDoublewordKind(*ak++)) + env.local(slotOffset++).defineSecondWord(); + } + translator.linkPredecessor(*beginBlock, cg.getBeginNode().getNormalSuccessor(), env, true); + translator.finishedOnePredecessor(*beginBlock); + } + + translator.genRawPrimitiveGraph(); + if (bytecodeGraph.isSynchronized) { + VariableOrConstant sync; + if (bytecodeGraph.isInstanceMethod) + sync.setVariable(cg.getBeginNode().getBeginExtra()[0]); + else + sync.setConstant(objectAddress(bytecodeGraph.classFileSummary.getThisClass())); + // asharma fix me! + translator.addSynchronization(sync, 0); + } + return &cg; +} + diff --git a/ef/Compiler/FrontEnd/BytecodeTranslator.h b/ef/Compiler/FrontEnd/BytecodeTranslator.h new file mode 100644 index 000000000000..577561cf64b2 --- /dev/null +++ b/ef/Compiler/FrontEnd/BytecodeTranslator.h @@ -0,0 +1,161 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#ifndef BYTECODETRANSLATOR_H +#define BYTECODETRANSLATOR_H + +#include "BytecodeGraph.h" + +class BytecodeTranslator: public TranslationCommonEnv +{ + // Helper for translating a BytecodeBlock + class BlockTranslator + { + const BytecodeTranslator &bt; // Backpointer to the current BytecodeTranslator + Pool &envPool; // The pool for allocating translation environment parts (disappears after primitives are generated) + Pool &primitivePool; // The pool for allocating new parts of the primitive graph + ClassFileSummary &classFileSummary; // The BytecodeGraph's ClassFileSummary + TranslationEnv *translationEnv; // The current state of local and stack variables; never nil + BytecodeBlock █ // The block which we're currently translating + ControlNode *cn; // The control node currently being generated or nil if we are done + + public: + BlockTranslator(const BytecodeTranslator &bt, TranslationEnv &env, BytecodeBlock &block, ControlNode *cn); + + TranslationEnv &getEnv() const {return *translationEnv;} + void setEnv(TranslationEnv &env) {translationEnv = &env;} + ControlGraph &getControlGraph() const {return bt.controlGraph;} + + private: + void appendControlNode(ControlEdge &e); + void genException(ControlKind ck, Primitive *tryPrimitive, const Class &exceptionClass, bool canOwnEnv) const; + void genThrowCommon(const VariableOrConstant &exception, const Class &exceptionClass, bool canOwnEnv); + void genSimpleThrow(cobj exceptionObject, bool canOwnEnv); + void genPossibleThrow(Primitive &prim, const Class &exceptionClass); + void createBasicBlock(BasicBlock &successor); + void createIf(Condition2 cond2, bool reverseCond2, + VariableOrConstant &c, BasicBlock &successorFalse, + BasicBlock &successorTrue, Uint32 bci); + void createContinuedIf(Condition2 cond2, bool reverseCond2, + VariableOrConstant &c, + BasicBlock &successorTrue, Uint32 bci); + void genNullGuard(const VariableOrConstant &arg, Uint32 bci); + void genTableSwitch(const bytecode *bc, Uint32 bci); + void genLookupSwitch(const bytecode *bc, Uint32 bci); + void genReadObjectType(const VariableOrConstant &object, + VariableOrConstant &type, Uint32 bci) const; + void genGetStatic(ConstantPoolIndex cpi, Uint32 bci) const; + void genPutStatic(ConstantPoolIndex cpi, Uint32 bci) const; + void genGetField(ConstantPoolIndex cpi, Uint32 bci); + void genPutField(ConstantPoolIndex cpi, Uint32 bci); + void genReadArrayLength(const VariableOrConstant &arrayAddr, VariableOrConstant &arrayLength, Uint32 bci); + void genArrayCastGuard(const VariableOrConstant &array, const VariableOrConstant &object); + void genArrayEltAccess(TypeKind tk, bool write, Uint32 bci); + void genCheckInterfaceAssignability(VariableOrConstant &type, const Type &targetInterface, VariableOrConstant *results, Uint32 bci) const; + void genCheckCastNonNull(const Type &t, const VariableOrConstant &arg, Uint32 bci); + void genCheckCast(ConstantPoolIndex cpi, const VariableOrConstant &arg, Uint32 bci); + void genInstanceOfNonNull(const Type &t, const VariableOrConstant &arg, VariableOrConstant &result, ControlNode *cnFalse, Uint32 bci); + void genInstanceOf(ConstantPoolIndex cpi, const VariableOrConstant &arg, VariableOrConstant &result, Uint32 bci); + void genNewCommon(const SysCall &sysCall, uint nArgs, const VariableOrConstant *args, Uint32 bci); + void genTempArrayOfDim(Int32 dim, Uint32 bci); + Primitive &genMonitor(PrimitiveOperation op, const VariableOrConstant &arg, Uint32 bci) const; + void genThrow(const VariableOrConstant &exception); + void genReceiverNullCheck(const Signature &sig, VariableOrConstant &receiver, Uint32 bci); + void genVirtualLookup(const VariableOrConstant &receiver, Uint32 vIndex, VariableOrConstant &functionAddr, Uint32 bci) const; + void genInterfaceLookup(const VariableOrConstant &receiver, Uint32 interfaceNumber, Uint32 vIndex, const Method *method, + VariableOrConstant &functionAddr, Uint32 bci) const; + void genInvoke(bytecode opcode, ConstantPoolIndex cpi, uint nArgs, Uint32 bci); + public: + void genLivePrimitives(); + void genCycleHeader(); + + #ifdef DEBUG + bool translatorDone() const {return !cn;} + #endif + }; + + BytecodeGraph &bytecodeGraph; // The BytecodeGraph from which we're translating + ControlGraph &controlGraph; // The primitive graph to which we're translating + + BytecodeTranslator(BytecodeGraph &bytecodeGraph, ControlGraph &controlGraph, Pool &envPool); + + static void normalizeEnv(TranslationEnv &env, BasicBlock::StackNormalization stackNormalization); + static void linkPredecessor(BasicBlock &block, ControlEdge &controlEdge, TranslationEnv &predecessorEnv, bool canOwnEnv); + static void finishedOnePredecessor(BasicBlock &block); + static void finishedOutgoingEdges(BasicBlock &block); + ControlNode *createControlNode(BasicBlock &block, bool mergeBlock) const; + + void genPrimitives(EndBlock &block) const; + void genPrimitives(CatchBlock &block) const; + void genPrimitives(BytecodeBlock &block) const; + void genRawPrimitiveGraph() const; + void addSynchronization(VariableOrConstant &syncHolder, Uint32 bci) const; + public: + static ControlGraph *genPrimitiveGraph(BytecodeGraph &bytecodeGraph, Pool &primitivePool, Pool &tempPool); + + friend class BytecodeTranslator::BlockTranslator; // BlockTranslator calls the private methods above +}; + + +// --- INLINES ---------------------------------------------------------------- + + +// +// Initialize a translator that will translate a single BytecodeBlock. +// +inline BytecodeTranslator::BlockTranslator::BlockTranslator(const BytecodeTranslator &bt, TranslationEnv &env, BytecodeBlock &block, + ControlNode *cn): + bt(bt), + envPool(bt.envPool), + primitivePool(bt.primitivePool), + classFileSummary(bt.bytecodeGraph.classFileSummary), + translationEnv(&env), + block(block), + cn(cn) +{} + + +// +// Initialize a translator that will construct the control graph out of the given +// bytecode graph. +// envPool will be used for temporary allocation of TranslationEnvs and the data +// structures they contain; all of these can be deallocated when the BytecodeTranslator +// is done. +// +inline BytecodeTranslator::BytecodeTranslator(BytecodeGraph &bytecodeGraph, ControlGraph &controlGraph, Pool &envPool): + TranslationCommonEnv(envPool, controlGraph.pool, bytecodeGraph.nLocals, bytecodeGraph.stackSize), + bytecodeGraph(bytecodeGraph), + controlGraph(controlGraph) +{} + + +// +// Take note that we just completely generated code for a BasicBlock b +// that is one of the predecessors of BasicBlock block. If b jumps to +// BasicBlock block, then BasicBlock block's environment should have been +// adjusted accordingly by now. +// This method lets BasicBlock block keep track of how many other +// BasicBlocks remain that can jump to BasicBlock block and whose +// environments have not yet been merged into BasicBlock block. +// +inline void BytecodeTranslator::finishedOnePredecessor(BasicBlock &block) +{ + assert(block.getNSeenPredecessors() != block.nPredecessors); + block.getNSeenPredecessors()++; +} + +#endif diff --git a/ef/Compiler/FrontEnd/BytecodeVerifier.cpp b/ef/Compiler/FrontEnd/BytecodeVerifier.cpp new file mode 100644 index 000000000000..521fcaa0a4de --- /dev/null +++ b/ef/Compiler/FrontEnd/BytecodeVerifier.cpp @@ -0,0 +1,1365 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#include "BytecodeVerifier.h" +#include "FieldOrMethod.h" +#include "MemoryAccess.h" +#include "GraphUtils.h" + + +static const VerificationEnv::BindingKind localAccessKinds[] = +{ + VerificationEnv::bkInt, // bcILoad, bcIStore + VerificationEnv::bkLong, // bcLLoad, bcLStore + VerificationEnv::bkFloat, // bcFLoad, bcFStore + VerificationEnv::bkDouble, // bcDLoad, bcDStore + VerificationEnv::bkAddr, // bcALoad, bcAStore + VerificationEnv::bkInt, // bcILoad_0, bcIStore_0 + VerificationEnv::bkInt, // bcILoad_1, bcIStore_1 + VerificationEnv::bkInt, // bcILoad_2, bcIStore_2 + VerificationEnv::bkInt, // bcILoad_3, bcIStore_3 + VerificationEnv::bkLong, // bcLLoad_0, bcLStore_0 + VerificationEnv::bkLong, // bcLLoad_1, bcLStore_1 + VerificationEnv::bkLong, // bcLLoad_2, bcLStore_2 + VerificationEnv::bkLong, // bcLLoad_3, bcLStore_3 + VerificationEnv::bkFloat, // bcFLoad_0, bcFStore_0 + VerificationEnv::bkFloat, // bcFLoad_1, bcFStore_1 + VerificationEnv::bkFloat, // bcFLoad_2, bcFStore_2 + VerificationEnv::bkFloat, // bcFLoad_3, bcFStore_3 + VerificationEnv::bkDouble, // bcDLoad_0, bcDStore_0 + VerificationEnv::bkDouble, // bcDLoad_1, bcDStore_1 + VerificationEnv::bkDouble, // bcDLoad_2, bcDStore_2 + VerificationEnv::bkDouble, // bcDLoad_3, bcDStore_3 + VerificationEnv::bkAddr, // bcALoad_0, bcAStore_0 + VerificationEnv::bkAddr, // bcALoad_1, bcAStore_1 + VerificationEnv::bkAddr, // bcALoad_2, bcAStore_2 + VerificationEnv::bkAddr // bcALoad_3, bcAStore_3 +}; + + +static const VerificationEnv::BindingKind arrayAccessKinds[] = +{ + VerificationEnv::bkInt, // bcIALoad, bcIAStore, bcIReturn + VerificationEnv::bkLong, // bcLALoad, bcLAStore, bcLReturn + VerificationEnv::bkFloat, // bcFALoad, bcFAStore, bcFReturn + VerificationEnv::bkDouble, // bcDALoad, bcDAStore, bcDReturn + VerificationEnv::bkAddr, // bcAALoad, bcAAStore, bcAReturn + VerificationEnv::bkInt, // bcBALoad, bcBAStore + VerificationEnv::bkInt, // bcCALoad, bcCAStore + VerificationEnv::bkInt // bcSALoad, bcSAStore +}; + + +static const VerificationEnv::BindingKind bytecodeSignatures[][3] = +{ // Argument 1 Argument 2 Result + {VerificationEnv::bkInt, VerificationEnv::bkInt, VerificationEnv::bkInt}, // bcIAdd + {VerificationEnv::bkLong, VerificationEnv::bkLong, VerificationEnv::bkLong}, // bcLAdd + {VerificationEnv::bkFloat, VerificationEnv::bkFloat, VerificationEnv::bkFloat}, // bcFAdd + {VerificationEnv::bkDouble, VerificationEnv::bkDouble, VerificationEnv::bkDouble}, // bcDAdd + {VerificationEnv::bkInt, VerificationEnv::bkInt, VerificationEnv::bkInt}, // bcISub + {VerificationEnv::bkLong, VerificationEnv::bkLong, VerificationEnv::bkLong}, // bcLSub + {VerificationEnv::bkFloat, VerificationEnv::bkFloat, VerificationEnv::bkFloat}, // bcFSub + {VerificationEnv::bkDouble, VerificationEnv::bkDouble, VerificationEnv::bkDouble}, // bcDSub + {VerificationEnv::bkInt, VerificationEnv::bkInt, VerificationEnv::bkInt}, // bcIMul + {VerificationEnv::bkLong, VerificationEnv::bkLong, VerificationEnv::bkLong}, // bcLMul + {VerificationEnv::bkFloat, VerificationEnv::bkFloat, VerificationEnv::bkFloat}, // bcFMul + {VerificationEnv::bkDouble, VerificationEnv::bkDouble, VerificationEnv::bkDouble}, // bcDMul + {VerificationEnv::bkInt, VerificationEnv::bkInt, VerificationEnv::bkInt}, // bcIDiv + {VerificationEnv::bkLong, VerificationEnv::bkLong, VerificationEnv::bkLong}, // bcLDiv + {VerificationEnv::bkFloat, VerificationEnv::bkFloat, VerificationEnv::bkFloat}, // bcFDiv + {VerificationEnv::bkDouble, VerificationEnv::bkDouble, VerificationEnv::bkDouble}, // bcDDiv + {VerificationEnv::bkInt, VerificationEnv::bkInt, VerificationEnv::bkInt}, // bcIRem + {VerificationEnv::bkLong, VerificationEnv::bkLong, VerificationEnv::bkLong}, // bcLRem + {VerificationEnv::bkFloat, VerificationEnv::bkFloat, VerificationEnv::bkFloat}, // bcFRem + {VerificationEnv::bkDouble, VerificationEnv::bkDouble, VerificationEnv::bkDouble}, // bcDRem + {VerificationEnv::bkInt, VerificationEnv::bkVoid, VerificationEnv::bkInt}, // bcINeg + {VerificationEnv::bkLong, VerificationEnv::bkVoid, VerificationEnv::bkLong}, // bcLNeg + {VerificationEnv::bkFloat, VerificationEnv::bkVoid, VerificationEnv::bkFloat}, // bcFNeg + {VerificationEnv::bkDouble, VerificationEnv::bkVoid, VerificationEnv::bkDouble}, // bcDNeg + {VerificationEnv::bkInt, VerificationEnv::bkInt, VerificationEnv::bkInt}, // bcIShl + {VerificationEnv::bkLong, VerificationEnv::bkInt, VerificationEnv::bkLong}, // bcLShl + {VerificationEnv::bkInt, VerificationEnv::bkInt, VerificationEnv::bkInt}, // bcIShr + {VerificationEnv::bkLong, VerificationEnv::bkInt, VerificationEnv::bkLong}, // bcLShr + {VerificationEnv::bkInt, VerificationEnv::bkInt, VerificationEnv::bkInt}, // bcIUShr + {VerificationEnv::bkLong, VerificationEnv::bkInt, VerificationEnv::bkLong}, // bcLUShr + {VerificationEnv::bkInt, VerificationEnv::bkInt, VerificationEnv::bkInt}, // bcIAnd + {VerificationEnv::bkLong, VerificationEnv::bkLong, VerificationEnv::bkLong}, // bcLAnd + {VerificationEnv::bkInt, VerificationEnv::bkInt, VerificationEnv::bkInt}, // bcIOr + {VerificationEnv::bkLong, VerificationEnv::bkLong, VerificationEnv::bkLong}, // bcLOr + {VerificationEnv::bkInt, VerificationEnv::bkInt, VerificationEnv::bkInt}, // bcIXor + {VerificationEnv::bkLong, VerificationEnv::bkLong, VerificationEnv::bkLong}, // bcLXor + {VerificationEnv::bkVoid, VerificationEnv::bkVoid, VerificationEnv::bkVoid}, // bcIInc + {VerificationEnv::bkInt, VerificationEnv::bkVoid, VerificationEnv::bkLong}, // bcI2L + {VerificationEnv::bkInt, VerificationEnv::bkVoid, VerificationEnv::bkFloat}, // bcI2F + {VerificationEnv::bkInt, VerificationEnv::bkVoid, VerificationEnv::bkDouble}, // bcI2D + {VerificationEnv::bkLong, VerificationEnv::bkVoid, VerificationEnv::bkInt}, // bcL2I + {VerificationEnv::bkLong, VerificationEnv::bkVoid, VerificationEnv::bkFloat}, // bcL2F + {VerificationEnv::bkLong, VerificationEnv::bkVoid, VerificationEnv::bkDouble}, // bcL2D + {VerificationEnv::bkFloat, VerificationEnv::bkVoid, VerificationEnv::bkInt}, // bcF2I + {VerificationEnv::bkFloat, VerificationEnv::bkVoid, VerificationEnv::bkLong}, // bcF2L + {VerificationEnv::bkFloat, VerificationEnv::bkVoid, VerificationEnv::bkDouble}, // bcF2D + {VerificationEnv::bkDouble, VerificationEnv::bkVoid, VerificationEnv::bkInt}, // bcD2I + {VerificationEnv::bkDouble, VerificationEnv::bkVoid, VerificationEnv::bkLong}, // bcD2L + {VerificationEnv::bkDouble, VerificationEnv::bkVoid, VerificationEnv::bkFloat}, // bcD2F + {VerificationEnv::bkInt, VerificationEnv::bkVoid, VerificationEnv::bkInt}, // bcInt2Byte + {VerificationEnv::bkInt, VerificationEnv::bkVoid, VerificationEnv::bkInt}, // bcInt2Char + {VerificationEnv::bkInt, VerificationEnv::bkVoid, VerificationEnv::bkInt}, // bcInt2Short + {VerificationEnv::bkLong, VerificationEnv::bkLong, VerificationEnv::bkInt}, // bcLCmp + {VerificationEnv::bkFloat, VerificationEnv::bkFloat, VerificationEnv::bkInt}, // bcFCmpL + {VerificationEnv::bkFloat, VerificationEnv::bkFloat, VerificationEnv::bkInt}, // bcFCmpG + {VerificationEnv::bkDouble, VerificationEnv::bkDouble, VerificationEnv::bkInt}, // bcDCmpL + {VerificationEnv::bkDouble, VerificationEnv::bkDouble, VerificationEnv::bkInt} // bcDCmpG +}; + + +// ---------------------------------------------------------------------------- +// SubroutineCallSiteList + + +// +// Return true if this Association is less than a2 in the "dictionary" ordering with +// the subroutine being the major key and callSite being the minor key. A nil callSite +// is considered to be less than ony other callSite. +// +bool SubroutineCallSiteList::Association::operator<(const Association &a2) const +{ + // According to ANSI C++, we can't compare subroutine addresses directly because + // they are not elements of the same array. Instead, we compare their bytecodesBegin + // values, which do point into the same array. + const bytecode *begin1 = subroutine.bytecodesBegin; + const bytecode *begin2 = a2.subroutine.bytecodesBegin; + return begin1 < begin2 || + begin1 == begin2 && a2.callSite && (!callSite || callSite->bytecodesBegin < a2.callSite->bytecodesBegin); +} + + +// +// Create an Iterator that will return all known call sites for the given subroutine. +// +SubroutineCallSiteList::Iterator::Iterator(SubroutineCallSiteList &csList, BytecodeBlock &subroutine): + subroutine(subroutine) +{ + Association a(subroutine); + Node *n = csList.tree.findAfter(a); + if (n && &n->getKey().subroutine != &subroutine) + n = 0; + node = n; +} + + +// +// Advance the iterator to the next call site. +// +void SubroutineCallSiteList::Iterator::operator++() +{ + assert(node); + Node *n = node->next(); + if (n && &n->getKey().subroutine != &subroutine) + n = 0; + node = n; +} + + +// +// Add callSite to the list of subroutine's call sites if it is not there already. +// Allocate additional storage from pool if needed. +// +void SubroutineCallSiteList::addAssociation(BytecodeBlock &subroutine, BytecodeBlock &callSite, Pool &pool) +{ + Association a(subroutine, callSite); + Node *where; + bool right; + if (!tree.find(a, where, right)) + tree.attach(*new(pool) Node(a), where, right); +} + + +// +// Remove callSite to the list of subroutine's call sites. callSite must have been +// previously added (and not yet removed) to the list of subroutine's call sites. +// +void SubroutineCallSiteList::removeAssociation(BytecodeBlock &subroutine, BytecodeBlock &callSite) +{ + Association a(subroutine, callSite); + Node *n = tree.find(a); + assert(n); + tree.remove(*n); +} + + +// +// Return a callSite and its subroutine of one association present in this +// SubroutineCallSiteList. At the same time remove that association from this +// SubroutineCallSiteList. Also return a flag that is true if this was the only +// association for this subroutine. +// If this SubroutineCallSiteList is already empty, return nil. +// +BytecodeBlock *SubroutineCallSiteList::popAssociation(BytecodeBlock *&subroutine, bool &onlyOneCallSite) +{ + Node *n = tree.firstNode(); + if (!n) { + subroutine = 0; + return 0; + } + subroutine = &n->getKey().subroutine; + BytecodeBlock *callSite = n->getKey().callSite; + Node *n2 = n->next(); + onlyOneCallSite = !(n2 && &n2->getKey().subroutine == subroutine); + tree.remove(*n); + return callSite; +} + + +// ---------------------------------------------------------------------------- +// BytecodeVerifier + + +// +// Initialize the BytecodeVerifier and set up all BasicBlocks in the bytecode +// graph for verification. +// +BytecodeVerifier::BytecodeVerifier(BytecodeGraph &bytecodeGraph, Pool &envPool): + VerificationEnv::Common(envPool, 0, bytecodeGraph.nLocals, bytecodeGraph.stackSize), + bytecodeGraph(bytecodeGraph), + classFileSummary(bytecodeGraph.classFileSummary) +{ + BasicBlock **block = bytecodeGraph.getDFSList(); + BasicBlock **dfsListEnd = block + bytecodeGraph.getDFSListLength(); + while (block != dfsListEnd) + (*block++)->initVerification(*this); +} + + +// +// If stackNormalization is either sn0, sn1, or sn2, pop all except the top +// zero, one, or two words from env, modifying it in place. +// +void BytecodeVerifier::normalizeEnv(VerificationEnv &env, BasicBlock::StackNormalization stackNormalization) +{ + VerificationEnv::Binding tempBinding1; + VerificationEnv::Binding tempBinding2; + + switch (stackNormalization) { + case BasicBlock::snNoChange: + return; + case BasicBlock::sn0: + break; + case BasicBlock::sn1: + tempBinding1 = env.pop1(); + break; + case BasicBlock::sn2: + env.pop2(tempBinding1, tempBinding2); + break; + } + env.dropAll(); + switch (stackNormalization) { + case BasicBlock::sn0: + break; + case BasicBlock::sn1: + env.push1(tempBinding1); + break; + case BasicBlock::sn2: + env.push2(tempBinding1, tempBinding2); + break; + default: + trespass("Bad stackNormalization"); + } +} + + +// +// Intersect block's current incoming environment with predecessorEnv, updating the +// block's incoming environment. Return true if both conditions below are true: +// the block's incoming environment changed, and +// the block's generation is already equal to the given generation. +// When this method returns true, a block already examined on this pass through the +// depth-first list has changed, so another pass is needed. +// +// Set this block's recompute flag if its incoming environment changed. +// +// If canOwnEnv is true, the BasicBlock can assume ownership of predecessorEnv +// (thereby sometimes eliminating an unnecessary copy). +// +// Throw a verification error if the environments cannot be intersected. +// +bool BytecodeVerifier::predecessorChanged(BasicBlock &block, VerificationEnv &predecessorEnv, Uint32 generation, bool canOwnEnv) +{ + assert(predecessorEnv.live()); + BasicBlock::StackNormalization stackNormalization = block.stackNormalization; + if (stackNormalization != BasicBlock::snNoChange && predecessorEnv.getSP() != (Uint32)(stackNormalization-BasicBlock::sn0)) + // We have to normalize the stack inside predecessorEnv. + if (canOwnEnv) + normalizeEnv(predecessorEnv, stackNormalization); + else { + VerificationEnv envCopy(predecessorEnv); + normalizeEnv(envCopy, stackNormalization); + return predecessorChanged(block, envCopy, generation, true); + } + + bool changed = block.getGeneration() == generation; + if (block.getVerificationEnvIn().live()) + if (block.getVerificationEnvIn().meet(predecessorEnv)) + block.getRecompute() = true; + else + changed = false; + else { + block.getRecompute() = true; + if (canOwnEnv) + block.getVerificationEnvIn().move(predecessorEnv); + else + block.getVerificationEnvIn() = predecessorEnv; + } + return changed; +} + + +// +// Call predecessorChanged on every BasicBlock between blocksBegin (inclusive) +// and blocksEnd (exclusive). Return true if any predecessorChanged call returned +// true. Of course, canOwnEnv applies only to the last call to predecessorChanged. +// +bool BytecodeVerifier::predecessorChanged(BasicBlock **blocksBegin, BasicBlock **blocksEnd, VerificationEnv &predecessorEnv, + Uint32 generation, bool canOwnEnv) +{ + bool changed = false; + while (blocksBegin != blocksEnd) { + BasicBlock *block = *blocksBegin++; + changed |= predecessorChanged(*block, predecessorEnv, generation, blocksBegin == blocksEnd && canOwnEnv); + } + return changed; +} + + +// +// Compute the verificationEnvIn, subroutineHeader, and subroutineRet fields of +// the block. Verify the block's stack and type discpiline. Return true if +// calling predecessorChanged on at least one of this block's successors returned true. +// +bool BytecodeVerifier::propagateDataflow(CatchBlock &block, Uint32 generation) +{ + VerificationEnv env(block.getVerificationEnvIn()); + env.push1(VerificationEnv::bkAddr); + return predecessorChanged(block.getHandler(), env, generation, true); +} + + +// +// Compute the verificationEnvIn, subroutineHeader, and subroutineRet fields of +// the block. Verify the block's stack and type discipline. Return true if +// calling predecessorChanged on at least one of this block's successors returned true. +// +bool BytecodeVerifier::propagateDataflow(BytecodeBlock &block, Uint32 generation) +{ + VerificationEnv env(block.getVerificationEnvIn()); + // Follow exception handlers from this block at the beginning of this block and + // after each change of a local variable. + bool changed = predecessorChanged(block.successorsEnd, block.handlersEnd, env, generation, false); + + const bytecode *const bytecodesEnd = block.bytecodesEnd; + const bytecode *bc = block.bytecodesBegin; + assert(bc != bytecodesEnd); + while (bc != bytecodesEnd) { + assert(bc < bytecodesEnd); + bytecode opcode = *bc++; + ValueKind vk; + TypeKind tk; + Value v; + Uint32 i; + ConstantPoolIndex cpi; + const VerificationEnv::Binding *b; + const VerificationEnv::BindingKind *bk; + VerificationEnv::Binding b1; + VerificationEnv::Binding b2; + VerificationEnv::Binding b3; + VerificationEnv::Binding b4; + Signature sig; + Uint32 offset; + Uint32 interfaceNumber; + addr address; + bool isVolatile; + bool isConstant; + bool isInit; + BytecodeBlock *sub; + + switch (opcode) { + + case bcNop: + break; + + case bcAConst_Null: + env.push1(VerificationEnv::bkAddr); + break; + case bcIConst_m1: + case bcIConst_0: + case bcIConst_1: + case bcIConst_2: + case bcIConst_3: + case bcIConst_4: + case bcIConst_5: + pushInt: + env.push1(VerificationEnv::bkInt); + break; + case bcLConst_0: + case bcLConst_1: + env.push2(VerificationEnv::bkLong); + break; + case bcFConst_0: + case bcFConst_1: + case bcFConst_2: + env.push1(VerificationEnv::bkFloat); + break; + case bcDConst_0: + case bcDConst_1: + env.push2(VerificationEnv::bkDouble); + break; + case bcBIPush: + bc++; + goto pushInt; + case bcSIPush: + bc += 2; + goto pushInt; + case bcLdc: + cpi = *(Uint8 *)bc; + bc++; + goto pushConst1; + case bcLdc_W: + cpi = readBigUHalfwordUnaligned(bc); + bc += 2; + pushConst1: + vk = classFileSummary.lookupConstant(cpi, v); + if (!isWordKind(vk)) + verifyError(VerifyError::badType); + env.push1(VerificationEnv::valueKindToBindingKind(vk)); + break; + case bcLdc2_W: + vk = classFileSummary.lookupConstant(readBigUHalfwordUnaligned(bc), v); + bc += 2; + if (!isDoublewordKind(vk)) + verifyError(VerifyError::badType); + env.push2(VerificationEnv::valueKindToBindingKind(vk)); + break; + + case bcILoad: + case bcFLoad: + case bcALoad: + i = *(Uint8 *)bc; + bc++; + pushLoad1: + b = &env.getLocal1(i); + if (!b->hasKind(localAccessKinds[opcode - bcILoad])) + verifyError(VerifyError::badType); + env.push1(*b); + break; + case bcLLoad: + case bcDLoad: + i = *(Uint8 *)bc; + bc++; + pushLoad2: + b = &env.getLocal2(i); + if (!b->hasKind(localAccessKinds[opcode - bcILoad])) + verifyError(VerifyError::badType); + env.push2(*b); + break; + case bcILoad_0: + case bcILoad_1: + case bcILoad_2: + case bcILoad_3: + i = opcode - bcILoad_0; + goto pushLoad1; + case bcLLoad_0: + case bcLLoad_1: + case bcLLoad_2: + case bcLLoad_3: + i = opcode - bcLLoad_0; + goto pushLoad2; + case bcFLoad_0: + case bcFLoad_1: + case bcFLoad_2: + case bcFLoad_3: + i = opcode - bcFLoad_0; + goto pushLoad1; + case bcDLoad_0: + case bcDLoad_1: + case bcDLoad_2: + case bcDLoad_3: + i = opcode - bcDLoad_0; + goto pushLoad2; + case bcALoad_0: + case bcALoad_1: + case bcALoad_2: + case bcALoad_3: + i = opcode - bcALoad_0; + goto pushLoad1; + + case bcIALoad: + case bcLALoad: + case bcFALoad: + case bcDALoad: + case bcAALoad: + case bcBALoad: + case bcCALoad: + case bcSALoad: + env.pop1(VerificationEnv::bkInt); + env.pop1(VerificationEnv::bkAddr); + env.push1or2(arrayAccessKinds[opcode - bcIALoad]); + break; + + case bcIStore: + case bcFStore: + i = *(Uint8 *)bc; + bc++; + popStore1: + env.setLocal1(i, env.pop1(localAccessKinds[opcode - bcIStore])); + recheckHandlers: + // We changed the local environment, so propagate the environment to the + // exception handlers again. + changed |= predecessorChanged(block.successorsEnd, block.handlersEnd, env, generation, false); + break; + case bcAStore: + i = *(Uint8 *)bc; + bc++; + popAStore1: + b = &env.pop1(); + if (!(b->hasKind(VerificationEnv::bkAddr) || b->hasKind(VerificationEnv::bkReturn))) + verifyError(VerifyError::badType); + env.setLocal1(i, *b); + goto recheckHandlers; + case bcLStore: + case bcDStore: + i = *(Uint8 *)bc; + bc++; + popStore2: + env.setLocal2(i, env.pop2(localAccessKinds[opcode - bcIStore])); + goto recheckHandlers; + + case bcIStore_0: + case bcIStore_1: + case bcIStore_2: + case bcIStore_3: + i = opcode - bcIStore_0; + goto popStore1; + case bcLStore_0: + case bcLStore_1: + case bcLStore_2: + case bcLStore_3: + i = opcode - bcLStore_0; + goto popStore2; + case bcFStore_0: + case bcFStore_1: + case bcFStore_2: + case bcFStore_3: + i = opcode - bcFStore_0; + goto popStore1; + case bcDStore_0: + case bcDStore_1: + case bcDStore_2: + case bcDStore_3: + i = opcode - bcDStore_0; + goto popStore2; + case bcAStore_0: + case bcAStore_1: + case bcAStore_2: + case bcAStore_3: + i = opcode - bcAStore_0; + goto popAStore1; + + case bcIAStore: + case bcLAStore: + case bcFAStore: + case bcDAStore: + case bcAAStore: + case bcBAStore: + case bcCAStore: + case bcSAStore: + env.pop1or2(arrayAccessKinds[opcode - bcIAStore]); + env.pop1(VerificationEnv::bkInt); + env.pop1(VerificationEnv::bkAddr); + break; + + case bcPop: + env.pop1(); + break; + case bcPop2: + env.pop2(b1, b2); + break; + case bcDup: + b1 = env.pop1(); + env.push1(b1); + env.push1(b1); + break; + case bcDup_x1: + b1 = env.pop1(); + b2 = env.pop1(); + env.push1(b1); + env.push1(b2); + env.push1(b1); + break; + case bcDup_x2: + b1 = env.pop1(); + env.pop2(b2, b3); + env.push1(b1); + env.push2(b2, b3); + env.push1(b1); + break; + case bcDup2: + env.pop2(b1, b2); + env.push2(b1, b2); + env.push2(b1, b2); + break; + case bcDup2_x1: + env.pop2(b1, b2); + b3 = env.pop1(); + env.push2(b1, b2); + env.push1(b3); + env.push2(b1, b2); + break; + case bcDup2_x2: + env.pop2(b1, b2); + env.pop2(b3, b4); + env.push2(b1, b2); + env.push2(b3, b4); + env.push2(b1, b2); + break; + case bcSwap: + b1 = env.pop1(); + b2 = env.pop1(); + env.push1(b1); + env.push1(b2); + break; + + case bcIAdd: + case bcLAdd: + case bcFAdd: + case bcDAdd: + case bcISub: + case bcLSub: + case bcFSub: + case bcDSub: + case bcIMul: + case bcLMul: + case bcFMul: + case bcDMul: + case bcIDiv: + case bcLDiv: + case bcFDiv: + case bcDDiv: + case bcIRem: + case bcLRem: + case bcFRem: + case bcDRem: + case bcIShl: + case bcLShl: + case bcIShr: + case bcLShr: + case bcIUShr: + case bcLUShr: + case bcIAnd: + case bcLAnd: + case bcIOr: + case bcLOr: + case bcIXor: + case bcLXor: + case bcLCmp: + case bcFCmpL: + case bcFCmpG: + case bcDCmpL: + case bcDCmpG: + bk = bytecodeSignatures[opcode - bcIAdd]; + env.pop1or2(bk[1]); + goto popPushUnary; + + case bcINeg: + case bcLNeg: + case bcFNeg: + case bcDNeg: + case bcI2L: + case bcI2F: + case bcI2D: + case bcL2I: + case bcL2F: + case bcL2D: + case bcF2I: + case bcF2L: + case bcF2D: + case bcD2I: + case bcD2L: + case bcD2F: + case bcInt2Byte: + case bcInt2Char: + case bcInt2Short: + bk = bytecodeSignatures[opcode - bcIAdd]; + popPushUnary: + env.pop1or2(bk[0]); + env.push1or2(bk[2]); + break; + + case bcIInc: + i = *(Uint8 *)bc; + bc += 2; + incLocal: + if (!env.getLocal1(i).hasKind(VerificationEnv::bkInt)) + verifyError(VerifyError::badType); + break; + + case bcIf_ICmpEq: + case bcIf_ICmpNe: + case bcIf_ICmpLt: + case bcIf_ICmpGe: + case bcIf_ICmpGt: + case bcIf_ICmpLe: + env.pop1(VerificationEnv::bkInt); + case bcIfEq: + case bcIfNe: + case bcIfLt: + case bcIfGe: + case bcIfGt: + case bcIfLe: + env.pop1(VerificationEnv::bkInt); + bc += 2; + // We should be at the end of the basic block. + assert(bc == bytecodesEnd); + break; + case bcIf_ACmpEq: + case bcIf_ACmpNe: + env.pop1(VerificationEnv::bkAddr); + case bcIfNull: + case bcIfNonnull: + env.pop1(VerificationEnv::bkAddr); + bc += 2; + // We should be at the end of the basic block. + assert(bc == bytecodesEnd); + break; + + case bcGoto_W: + bc += 2; + case bcGoto: + bc += 2; + // We should be at the end of the basic block. + assert(bc == bytecodesEnd); + break; + + case bcTableSwitch: + case bcLookupSwitch: + env.pop1(VerificationEnv::bkInt); + bc = bytecodesEnd; + break; + + case bcIReturn: + case bcLReturn: + case bcFReturn: + case bcDReturn: + case bcAReturn: + env.pop1or2(arrayAccessKinds[opcode - bcIReturn]); + case bcReturn: + // We should be at the end of the basic block. + assert(bc == bytecodesEnd); + break; + + case bcGetStatic: + env.push1or2(VerificationEnv::typeKindToBindingKind( + classFileSummary.lookupStaticField(readBigUHalfwordUnaligned(bc), vk, address, isVolatile, isConstant))); + bc += 2; + break; + case bcPutStatic: + env.pop1or2(VerificationEnv::typeKindToBindingKind( + classFileSummary.lookupStaticField(readBigUHalfwordUnaligned(bc), vk, address, isVolatile, isConstant))); + bc += 2; + break; + case bcGetField: + env.pop1(VerificationEnv::bkAddr); + env.push1or2(VerificationEnv::typeKindToBindingKind( + classFileSummary.lookupInstanceField(readBigUHalfwordUnaligned(bc), vk, offset, isVolatile, isConstant))); + bc += 2; + break; + case bcPutField: + env.pop1or2(VerificationEnv::typeKindToBindingKind( + classFileSummary.lookupInstanceField(readBigUHalfwordUnaligned(bc), vk, offset, isVolatile, isConstant))); + env.pop1(VerificationEnv::bkAddr); + bc += 2; + break; + + case bcInvokeVirtual: + classFileSummary.lookupVirtualMethod(readBigUHalfwordUnaligned(bc), sig, offset, address); + popPushInvoke: + bc += 2; + i = sig.nArguments; + while (i--) + env.pop1or2(VerificationEnv::typeKindToBindingKind(sig.argumentTypes[i]->typeKind)); + tk = sig.resultType->typeKind; + if (tk != tkVoid) + env.push1or2(VerificationEnv::typeKindToBindingKind(tk)); + break; + case bcInvokeSpecial: + classFileSummary.lookupSpecialMethod(readBigUHalfwordUnaligned(bc), sig, isInit, address); + goto popPushInvoke; + case bcInvokeStatic: + classFileSummary.lookupStaticMethod(readBigUHalfwordUnaligned(bc), sig, address); + goto popPushInvoke; + case bcInvokeInterface: + classFileSummary.lookupInterfaceMethod(readBigUHalfwordUnaligned(bc), sig, offset, interfaceNumber, address, *(Uint8 *)(bc + 2)); + bc += 2; + goto popPushInvoke; + + case bcNew: + classFileSummary.lookupClass(readBigUHalfwordUnaligned(bc)); + bc += 2; + env.push1(VerificationEnv::bkAddr); + break; + + case bcNewArray: + i = *(Uint8 *)bc; + bc++; + i -= natMin; + if (i >= natLimit - natMin) + verifyError(VerifyError::badNewArrayType); + env.pop1(VerificationEnv::bkInt); + env.push1(VerificationEnv::bkAddr); + break; + + case bcANewArray: + classFileSummary.lookupType(readBigUHalfwordUnaligned(bc)); + bc += 2; + env.pop1(VerificationEnv::bkInt); + env.push1(VerificationEnv::bkAddr); + break; + + case bcMultiANewArray: + classFileSummary.lookupType(readBigUHalfwordUnaligned(bc)); + i = *(Uint8 *)(bc+2); // Number of dimensions + bc += 3; + if (i == 0) + verifyError(VerifyError::badNewArrayType); + while (i--) + env.pop1(VerificationEnv::bkInt); + env.push1(VerificationEnv::bkAddr); + break; + + case bcArrayLength: + env.pop1(VerificationEnv::bkAddr); + env.push1(VerificationEnv::bkInt); + break; + + case bcAThrow: + env.pop1(VerificationEnv::bkAddr); + // The rest of this BytecodeBlock is dead, and we should be at the end of it. + assert(bc == bytecodesEnd); + break; + + case bcCheckCast: + classFileSummary.lookupType(readBigUHalfwordUnaligned(bc)); + bc += 2; + env.pop1(VerificationEnv::bkAddr); + env.push1(VerificationEnv::bkAddr); + break; + + case bcInstanceOf: + classFileSummary.lookupType(readBigUHalfwordUnaligned(bc)); + bc += 2; + env.pop1(VerificationEnv::bkAddr); + env.push1(VerificationEnv::bkInt); + break; + + case bcMonitorEnter: + case bcMonitorExit: + env.pop1(VerificationEnv::bkAddr); + break; + + case bcWide: + opcode = *bc++; + i = readBigUHalfwordUnaligned(bc); + bc += 2; + switch (opcode) { + case bcILoad: + case bcFLoad: + case bcALoad: + goto pushLoad1; + case bcLLoad: + case bcDLoad: + goto pushLoad2; + + case bcIStore: + case bcFStore: + goto popStore1; + case bcLStore: + case bcDStore: + goto popStore2; + case bcAStore: + goto popAStore1; + + case bcIInc: + bc += 2; + goto incLocal; + + case bcRet: + goto handleRet; + + default: + verifyError(VerifyError::badBytecode); + } + break; + + case bcBreakpoint: + // Ignore breakpoints. + break; + + case bcJsr_W: + bc += 2; + case bcJsr: + bc += 2; + // We have two successors to a jsr bytecode's basic block. The first is the + // code that follows the jsr bytecode, while the second is the beginning of the + // subroutine. + // At this point we do not propagate the environment to the code that follows + // the jst bytecode because we don't know the state of the registers, and, besides, + // the subroutine might not return at all. Instead, we only propagate the environment + // into the subroutine and rely on ret to propagate it to the instructions after + // all jsr's that could have called that subroutine. + assert(block.hasSubkind(BytecodeBlock::skJsr)); + sub = &block.getSuccessor(0); + env.enterSubroutine(sub); + b1.setReturn(sub); + env.push1(b1); + + subroutineCallSiteList.addAssociation(*sub, block, envPool); + + // We should be at the end of the basic block. + assert(bc == bytecodesEnd); + changed |= predecessorChanged(*sub, env, generation, true); + return changed; + + case bcRet: + i = *(Uint8 *)bc; + bc++; + handleRet: + b = &env.getLocal1(i); + if (!b->hasKind(VerificationEnv::bkReturn)) + verifyError(VerifyError::badType); + sub = b->getSubroutine(); + // We have to figure out the successors dynamically using the subroutine's address. + assert(block.hasSubkind(BytecodeBlock::skRet) && block.nSuccessors() == 0); + { + // This can be an assert instead of an if/verifyError because if we really did have + // two jsr's going to this ret, the return address local's BindingKind would become + // bkVoid instead of bkReturn and we would catch this above. + assert(!block.getSubroutineHeader() || block.getSubroutineHeader() == sub); + block.getSubroutineHeader() = sub; + BytecodeBlock *oldRet = sub->getSubroutineRet(); + if (oldRet && oldRet != &block) + verifyError(VerifyError::multipleRet); + sub->getSubroutineRet() = █ + + for (SubroutineCallSiteList::Iterator iter(subroutineCallSiteList, *sub); iter.more(); ++iter) { + BytecodeBlock &succ = *iter; + assert(succ.hasSubkind(BytecodeBlock::skJsr)); + VerificationEnv succEnv(env); + succEnv.exitSubroutine(sub, succ.getVerificationEnvIn()); + changed |= predecessorChanged(succ.getSuccessor(1), succEnv, generation, true); + } + } + // We should be at the end of the basic block. + assert(bc == bytecodesEnd); + return changed; + + default: + verifyError(VerifyError::badBytecode); + } + } + + // Propagate dataflow information to all non-exceptional successors. + changed |= predecessorChanged(block.successorsBegin, block.successorsEnd, env, generation, true); + return changed; +} + + +// +// Compute the verificationEnvIn, subroutineHeader, and subroutineRet fields of +// each block in the bytecode graph. This will verify the method's stack and +// type discpiline and match each ret (and wide ret) bytecode in the method with +// the entry address of the subroutine to which it corresponds. +// Set all retReachable fields of Context structures in the verification environments +// to false. +// +// depthFirstSearch should have been called on entry to this function. The +// subroutineHeader and subroutineRet fields of each bytecode graph block should +// be nil on entry. +// +// This function uses the generation and recompute fields of bytecode graph blocks +// as temporaries. It expects all recompute flags to be false on entry, and it +// leaves them that way on exit. +// +void BytecodeVerifier::computeDataflow() +{ + Pool bindingPool; + setBindingPool(bindingPool); + + BasicBlock **dfsList = bytecodeGraph.getDFSList(); + BasicBlock **dfsListEnd = dfsList + bytecodeGraph.getDFSListLength() - 1; + assert(bytecodeGraph.getDFSListLength() > 0); + + Uint32 generation = 0; + + // Set up the locals and arguments + VerificationEnv env(*this); + env.initLive(); + uint nArgs = bytecodeGraph.nArguments; + uint slotOffset = 0; + const ValueKind *ak = bytecodeGraph.argumentKinds; + for (uint n = 0; n != nArgs; n++) { + VerificationEnv::Binding b; + b.setKind(VerificationEnv::valueKindToBindingKind(*ak++)); + if (b.isOneWord()) + env.setLocal1(slotOffset++, b); + else { + env.setLocal2(slotOffset, b); + slotOffset += 2; + } + } + + bool changed = predecessorChanged(*bytecodeGraph.beginBlock, env, generation, true); + while (changed) { + generation++; + changed = false; + BasicBlock **blockPtr = dfsList; + while (blockPtr != dfsListEnd) { + BasicBlock *block = *blockPtr++; + block->getGeneration() = generation; + if (block->getRecompute()) { + block->getRecompute() = false; + assert(block->getVerificationEnvIn().live()); + assert(block->hasKind(BasicBlock::bbBytecode) || block->hasKind(BasicBlock::bbCatch)); + if (block->hasKind(BasicBlock::bbBytecode)) + changed |= propagateDataflow(*static_cast(block), generation); + else + changed |= propagateDataflow(*static_cast(block), generation); + } + } + } + + assert((*dfsListEnd)->hasKind(BasicBlock::bbEnd)); + (*dfsListEnd)->getRecompute() = false; + #ifdef DEBUG + // There shouldn't be any blocks left to recompute. + for (BasicBlock **blockPtr = dfsList; blockPtr != dfsListEnd+1; blockPtr++) + assert(!(*blockPtr)->getRecompute()); + #endif + clearBindingPool(); +} + + +// +// Do two things: +// +// 1. Compute the retReachable fields of Context structures in the verification environments +// in each block in the bytecode graph. The rest of the environments should have been +// computed by computeDataflow. +// +// Let B be a block with one or more Contexts in its verification environment and let +// C be one of those Contexts and S be C's subroutine. On output C's retReachable will +// be set if S's ret can be reached from B without going through S's jsr again. +// If C's retReachable is not set, we can consider B to not really be a part of S +// because there is no way to reach S's ret from B; instead, we consider S to have +// exited via a jump before it got to B. +// +// 2. Convert each BytecodeBlocks with a jsr's for which there is no ret into a +// skJsrNoRet-subkind block. That block will have one successor instead of two because +// the subroutine it calls cannot return. +// +// This function uses the generation fields of bytecode graph blocks as temporaries. +// +void BytecodeVerifier::computeRetReachables() +{ + BasicBlock **dfsList = bytecodeGraph.getDFSList(); + BasicBlock **dfsListEnd = dfsList + bytecodeGraph.getDFSListLength(); + + bool changed = false; + BasicBlock **blockPtr = dfsList; + while (blockPtr != dfsListEnd) { + BasicBlock *block = *blockPtr++; + block->getGeneration() = 0; + if (block->hasKind(BasicBlock::bbBytecode) && block->getVerificationEnvIn().live()) { + BytecodeBlock::Subkind subkind = static_cast(block)->subkind; + if (subkind == BytecodeBlock::skRet) { + block->getVerificationEnvIn().setRetReachable(block->getSubroutineHeader()); + block->getGeneration() = 1; + changed = true; + } else if (subkind == BytecodeBlock::skJsr) { + assert(block->nSuccessors() == 2); + if (!block->getSuccessor(0).getSubroutineRet()) { + static_cast(block)->transformToJsrNoRet(); + subroutineCallSiteList.removeAssociation(block->getSuccessor(0), *static_cast(block)); + } + } + } + } + + dfsListEnd--; // Ignore the end block from now on. + Uint32 generation = 1; + while (changed) { + Uint32 oldGeneration = generation; + generation++; + changed = false; + // We're doing a backward analysis, so traverse the DFS list in reverse order. + // This isn't quite as good as computing the DFS of the reverse graph, but it works; + // figuring out the real DFS of the reverse graph would require reversing the graph's + // edges and be quite messy. + blockPtr = dfsListEnd; + while (blockPtr != dfsList) { + BasicBlock *block = *--blockPtr; + // For each live block propagate retReachable information backward from successors + // (including exceptional successors) that have changed in either this or the previous + // generation. Set the generation of any blocks that change as a result to the current + // generation so that they can be propagated further. + if (block->getVerificationEnvIn().live()) { + BasicBlock **succPtr = block->successorsBegin; + BasicBlock **succEnd = block->handlersEnd; + BytecodeBlock *sub = 0; + if (block->hasKind(BasicBlock::bbBytecode) && static_cast(block)->hasSubkind(BytecodeBlock::skJsr)) + sub = &block->getSuccessor(0); + while (succPtr != succEnd) { + BasicBlock *succ = *succPtr++; + if (succ->getGeneration() >= oldGeneration) + if (block->getVerificationEnvIn().mergeRetReachables(succ->getVerificationEnvIn(), sub)) { + changed = true; + block->getGeneration() = generation; + } + sub = 0; + } + } + } + } +} + + +struct DuplicateHelper +{ + typedef BasicBlock *Successor; + typedef BasicBlock *NodeRef; + + const Uint32 generation; // currentGeneration from BytecodeVerifier::duplicateSubroutines + + explicit DuplicateHelper(Uint32 generation): generation(generation) {} + + static Successor *getSuccessorsBegin(NodeRef n) {return n->successorsBegin;} + static Successor *getSuccessorsEnd(NodeRef n) {return n->handlersEnd;} + static NodeRef getNodeRef(Successor s) {return s;} +}; + + +struct DuplicatePass1Helper: DuplicateHelper +{ + BytecodeGraph &bytecodeGraph; // The BytecodeGraph which we're examining + BytecodeBlock *subroutine; // Header of the subroutine whose body we're marking + + DuplicatePass1Helper(BytecodeGraph &bytecodeGraph, BytecodeBlock *subroutine, Uint32 generation): + DuplicateHelper(generation), bytecodeGraph(bytecodeGraph), subroutine(subroutine) {} + + bool isMarked(NodeRef n) {return n->getGeneration() == generation || !n->getVerificationEnvIn().isRetReachable(subroutine);} + void setMarked(NodeRef n); +}; + + +// +// Make a clone of block n and store a pointer to that clone in n's clone field. +// Make the clone's successors and handlers point to the same blocks to which n's +// successors and handlers point. +// Also set n's generation to the current generation. +// +void DuplicatePass1Helper::setMarked(BasicBlock *n) +{ + assert(n->getGeneration() != generation); + n->getGeneration() = generation; + BasicBlock *clone; + Pool &bytecodeGraphPool = bytecodeGraph.bytecodeGraphPool; + if (n->hasKind(BasicBlock::bbBytecode)) + clone = new(bytecodeGraphPool) BytecodeBlock(bytecodeGraph, *static_cast(n)); + else { + assert(n->hasKind(BasicBlock::bbCatch)); + clone = new(bytecodeGraphPool) CatchBlock(bytecodeGraph, *static_cast(n)); + } + n->getClone() = clone; +} + + +struct DuplicatePass2Helper: DuplicateHelper, Function1 +{ + SubroutineCallSiteList &subroutineCallSiteList; // Reference to BytecodeVerifier::subroutineCallSiteList + Pool &envPool; // Reference to BytecodeVerifier::envPool + + DuplicatePass2Helper(SubroutineCallSiteList &subroutineCallSiteList, Pool &envPool, Uint32 generation): + DuplicateHelper(generation), subroutineCallSiteList(subroutineCallSiteList), envPool(envPool) {} + + bool isMarked(NodeRef n) {return n->getGeneration() != generation;} + void setMarked(NodeRef n); + + BytecodeBlock *operator()(BytecodeBlock *arg); +}; + + +// +// This block has an already created clone saved in its clone field. +// For each of this block's successors and catch handlers s, if s points to +// a block in this subroutine (which we can tell by checking whether s's generation +// is greater than or equal to this DuplicatePass2Helper's generation), replace s +// by s's clone. +// If this block has subkind skJsr, update the subroutineCallSiteList to also include +// this block's clone, which is a newly created call site. +// +// Set this block's generation to this DuplicatePass2Helper's generation plus one to +// mark this block so that setMarked is not called on it again. +// +void DuplicatePass2Helper::setMarked(BasicBlock *n) +{ + assert(n->getGeneration() == generation); + n->getGeneration() = generation + 1; + BasicBlock *const clone = n->getClone(); + assert(clone); + + // Fix up the VerificationTemps. + clone->initVerification(*n, *this); + + // Fix up the successor and handler pointers. + BasicBlock **successor = clone->successorsBegin; + BasicBlock **limit = clone->handlersEnd; + while (successor != limit) { + BasicBlock *s = *successor; + assert(s); + if (s->getGeneration() >= generation) + *successor = s->getClone(); + successor++; + } + + if (clone->hasKind(BasicBlock::bbBytecode)) { + BytecodeBlock *const bytecodeClone = static_cast(clone); + + // Fix up the catchBlock pointer. If it's non-nil, it must point inside this subroutine. + CatchBlock *c = bytecodeClone->catchBlock; + if (c) { + assert(c->getGeneration() >= generation); + bytecodeClone->catchBlock = static_cast(c->getClone()); + } + + // If clone has subkind skJsr, update the subroutineCallSiteList. + if (bytecodeClone->hasSubkind(BytecodeBlock::skJsr)) { + subroutineCallSiteList.addAssociation(bytecodeClone->getSuccessor(0), *bytecodeClone, envPool); + } + } else + assert(clone->hasKind(BasicBlock::bbCatch)); +} + + +// +// If arg points inside the subroutine currently being duplicated, return its clone; +// if arg is nil or points outside that subroutine, return it unchanged. +// +BytecodeBlock *DuplicatePass2Helper::operator()(BytecodeBlock *arg) +{ + if (arg && arg->getGeneration() >= generation) + arg = static_cast(arg->getClone()); + return arg; +} + + +// +// Duplicate each subroutine called by jsr's inside skJsr-kind (not skJsrNoRet-kind) blocks. +// This function relies on the bytecode graph being set up by computeRetReachables. +// Furthermore, no blocks should have been added to the graph since its last DFS search. +// On exit the graph will contain no unforwarded ret's and every jsr will be inside a +// skJsrNoRet-kind block. +// +// This function uses the generation and clone fields of bytecode graph blocks as temporaries. +// +void BytecodeVerifier::duplicateSubroutines() +{ + Pool searchPool; + Uint32 nGraphBlocks = bytecodeGraph.getDFSListLength(); // Upper bound on the current number of blocks in the graph + SearchStackEntry *searchStack = 0; + Uint32 searchStackSize = 0; + + BasicBlock **block = bytecodeGraph.getDFSList(); + BasicBlock **dfsListEnd = block + nGraphBlocks; + while (block != dfsListEnd) + (*block++)->getGeneration() = 0; + + Uint32 currentGeneration = 2; + BytecodeBlock *callSite; + BytecodeBlock *subroutine; + bool onlyOneCallSite; + while ((callSite = subroutineCallSiteList.popAssociation(subroutine, onlyOneCallSite)) != 0) { + BytecodeBlock *subroutineRet = subroutine->getSubroutineRet(); + assert(subroutineRet && callSite->hasSubkind(BytecodeBlock::skJsr)); + + if (!onlyOneCallSite) { + // There is more than one jsr remaining to this subroutine, so we copy the entire + // subroutine. + if (nGraphBlocks > searchStackSize) { + searchStackSize = nGraphBlocks * 2; + searchStack = new(searchPool) SearchStackEntry[searchStackSize]; + } + { + // Make a clone of every BasicBlock in the subroutine and store a pointer to that + // clone in the original BasicBlock's clone field. The clones' successors will still + // point to the original blocks; we'll take care of that later. + // To recognize which blocks we've cloned already we set the generation field of + // every visited block in the subroutine to currentGeneration. + DuplicatePass1Helper pass1Helper(bytecodeGraph, subroutine, currentGeneration); + graphSimpleSearch(pass1Helper, static_cast(subroutine), searchStackSize, searchStack); + } + + // Now change all successor and catch block pointers in the cloned blocks point to + // the clones of their successors/catch blocks if there are any. Leave pointers to + // blocks outside the subroutine as they are. Change the generation of each block + // whose clone we transform this way to currentGeneration+1 to mark it so we don't + // transform it twice. + DuplicatePass2Helper pass2Helper(subroutineCallSiteList, envPool, currentGeneration); + graphSimpleSearch(pass2Helper, static_cast(subroutine), searchStackSize, searchStack); + + // Change the subroutine pointer of our call site. + assert(subroutine->getGeneration() >= currentGeneration && callSite->nSuccessors() == 2); + callSite->successorsBegin[0] = subroutine->getClone(); + // Set up subroutineRet to point to the clone of the original ret. + assert(subroutineRet->getGeneration() >= currentGeneration); + subroutineRet = static_cast(subroutineRet->getClone()); + + // Advance the generation. + currentGeneration += 2; + // Throw an error if we went through 2^32 generations so far (unlikely, but it's better to be safe!). + if (currentGeneration < 2) + verifyError(VerifyError::jsrNestingError); + } + + // At this point we've already copied the subroutine if needed. Now we + // just forward its ret to the successor of the jsr. + subroutineRet->transformToForward(callSite->transformToJsrNoRet()); + } +} + + +// +// Inline all jsr-ret subroutines in this BytecodeGraph, eliminating all +// jsr and ret bytecodes. depthFirstSearch should have been called on entry +// to this function, and it needs to be called again after this function exits. +// +void BytecodeVerifier::inlineSubroutines(BytecodeGraph &bytecodeGraph, Pool &tempPool) +{ + BytecodeVerifier verifier(bytecodeGraph, tempPool); + + verifier.computeDataflow(); + verifier.computeRetReachables(); + verifier.duplicateSubroutines(); + bytecodeGraph.invalidateDFSList(); +} diff --git a/ef/Compiler/FrontEnd/BytecodeVerifier.h b/ef/Compiler/FrontEnd/BytecodeVerifier.h new file mode 100644 index 000000000000..541ceabe9811 --- /dev/null +++ b/ef/Compiler/FrontEnd/BytecodeVerifier.h @@ -0,0 +1,98 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#ifndef BYTECODEVERIFIER_H +#define BYTECODEVERIFIER_H + +#include "BytecodeGraph.h" +#include "Tree.h" + + +// A data structure for keeping track of all call sites for each subroutine. +// Only includes mappings for skJsr call sites; skJsrNoRet call sites are deleted +// from this association list as soon as they are discovered not to have a ret. +class SubroutineCallSiteList +{ + struct Association + { + BytecodeBlock &subroutine; // A subroutine (never nil) ... + BytecodeBlock *const callSite; // ... and one of its call sites (may be nil) + + Association(BytecodeBlock &subroutine, BytecodeBlock &callSite): subroutine(subroutine), callSite(&callSite) {} + explicit Association(BytecodeBlock &subroutine): subroutine(subroutine), callSite(0) {} + + bool operator<(const Association &a2) const; + }; + + class Node: public TreeNode + { + Association association; // An association of a subroutine with one of its call sites + + public: + explicit Node(Association &association): association(association) {} + const Association &getKey() const {return association;} + }; + + public: + class Iterator + { + BytecodeBlock &subroutine; // The subroutine whose call sites we're iterating + Node *node; // The node currently at the iterator's position or nil if none + + public: + Iterator(SubroutineCallSiteList &csList, BytecodeBlock &subroutine); + bool more() const {return node != 0;} + BytecodeBlock &operator*() const {assert(node); return *node->getKey().callSite;} + void operator++(); + }; + + private: + SortedTree tree; // The actual container of all associations in this SubroutineCallSiteList + public: + + void addAssociation(BytecodeBlock &subroutine, BytecodeBlock &callSite, Pool &pool); + void removeAssociation(BytecodeBlock &subroutine, BytecodeBlock &callSite); + BytecodeBlock *popAssociation(BytecodeBlock *&subroutine, bool &onlyOneCallSite); + + friend class Iterator; +}; + + +class BytecodeVerifier: public VerificationEnv::Common +{ + BytecodeGraph &bytecodeGraph; // The BytecodeGraph which we're examining + ClassFileSummary &classFileSummary; // The BytecodeGraph's ClassFileSummary + SubroutineCallSiteList subroutineCallSiteList; // A mapping from subroutines to their call sites + + BytecodeVerifier(BytecodeGraph &bytecodeGraph, Pool &envPool); + + // Inlining subroutines + void normalizeEnv(VerificationEnv &env, BasicBlock::StackNormalization stackNormalization); + bool predecessorChanged(BasicBlock &block, VerificationEnv &predecessorEnv, Uint32 generation, bool canOwnEnv); + bool predecessorChanged(BasicBlock **blocksBegin, BasicBlock **blocksEnd, VerificationEnv &predecessorEnv, + Uint32 generation, bool canOwnEnv); + bool propagateDataflow(CatchBlock &block, Uint32 generation); + bool propagateDataflow(BytecodeBlock &block, Uint32 generation); + void computeDataflow(); + void computeRetReachables(); + void duplicateSubroutines(); + + public: + static void inlineSubroutines(BytecodeGraph &bytecodeGraph, Pool &tempPool); +}; + +#endif diff --git a/ef/Compiler/FrontEnd/ErrorHandling.cpp b/ef/Compiler/FrontEnd/ErrorHandling.cpp new file mode 100644 index 000000000000..cc5119c4ae81 --- /dev/null +++ b/ef/Compiler/FrontEnd/ErrorHandling.cpp @@ -0,0 +1,103 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#include "Fundamentals.h" +#include "ErrorHandling.h" + + +#ifdef DEBUG + +char* verifyErrorString[] = +{ + "Unknown cause", + "Functionality not implemented yet", + "Error in reading class file: file not found, or has errors", + "Badly formatted class file", + "Class does not have permissions to access a particular field/method", + "Field not found in class", + "Method not found in class", + "No bytecodes in a function", + "Bad bytecode opcode", + "Bad offset to a bytecode instruction", + "Bad type passed to newarray instruction", + "Constant pool index out of range", + "Wrong return instruction used in this function", + "Bad tableswitch or lookupswitch bytecode", + "More than one ret bytecode for the same subroutine", + "Recursive call to a subroutine or multiple returns from the same subroutine", + "Bad combination of types in a bytecode", + "Attempt to pop from an empty bytecode stack", + "Attempt to push onto a full bytecode stack", + "Stack depth at a point differs based on how execution got there", + "Index of local variable out of range", + "Attempt to write to a constant (final) field", + "Given class not found in class file", + "Catch filter class not a subclass of Throwable", + "Class can be its own superclass", + "Compiler internal limits reached", + "Attempt to invoke abstract method", + "Binary incompatibility / incompatibleClassChange" +}; + +char* runtimeErrorString[] = +{ + "Unknown cause", + "Internal error", + "Functionality not implemented yet", + "incorrect argument to a method", + "prohibited operation", + "Security violation", + "IO Error", + "fileNotFound", + "Unable to link method", + "Null Pointer argument", + "Attempt to instantiate an abstract class" +}; + +#endif + +// +// This is called when there's something wrong with a class. +// +NS_EXTERN void +verifyError(VerifyError::Cause cause) +{ +#ifdef DEBUG + fprintf(stderr, "\n*** VERIFY ERROR *** [%d] %s\n", cause, verifyErrorString[cause]); +#endif + +#ifdef __GNUC__ + exit(cause); +#endif + throw VerifyError(cause); +} + +// +// This is called when there is an error during runtime. +// +NS_EXTERN void +runtimeError(RuntimeError::Cause cause) +{ +#ifdef DEBUG + fprintf(stderr, "\n*** RUNTIME ERROR *** [%d] %s\n", cause, runtimeErrorString[cause]); +#endif + +#ifdef __GNUC__ + exit(cause); +#endif + throw RuntimeError(cause); +} diff --git a/ef/Compiler/FrontEnd/ErrorHandling.h b/ef/Compiler/FrontEnd/ErrorHandling.h new file mode 100644 index 000000000000..906d1f4d014e --- /dev/null +++ b/ef/Compiler/FrontEnd/ErrorHandling.h @@ -0,0 +1,91 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#ifndef ERRORHANDLING_H +#define ERRORHANDLING_H + +#include "NativeDefs.h" + +struct VerifyError +{ + enum Cause + { + unknown, // Unknown cause + notImplemented, // Functionality not implemented yet + noClassDefFound, // Error in reading class file: file not found, or has errors + badClassFormat, // Badly formatted class file + illegalAccess, // Class does not have permissions to access a particular field/method + noSuchField, // Field not found in class + noSuchMethod, // Method not found in class + noBytecodes, // No bytecodes in a function + badBytecode, // Bad bytecode opcode + badBytecodeOffset, // Bad offset to a bytecode instruction + badNewArrayType, // Bad type passed to newarray instruction + badConstantPoolIndex, // Constant pool index out of range + badReturn, // Wrong return instruction used in this function + badSwitchBytecode, // Bad tableswitch or lookupswitch bytecode + multipleRet, // More than one ret bytecode for the same subroutine + jsrNestingError, // Recursive call to a subroutine or multiple returns from the same subroutine + badType, // Bad combination of types in a bytecode + bytecodeStackUnderflow, // Attempt to pop from an empty bytecode stack + bytecodeStackOverflow, // Attempt to push onto a full bytecode stack + bytecodeStackDynamic, // Stack depth at a point differs based on how execution got there + noSuchLocal, // Index of local variable out of range + writeToConst, // Attempt to write to a constant (final) field + classNotFound, // Given class not found in class file + nonThrowableCatch, // Catch filter class not a subclass of Throwable + classCircularity, // Class can be its own superclass + resourceExhausted, // Compiler internal limits reached + abstractMethod, // Attempt to invoke abstract method + incompatibleClassChange // Binary incompatibility + }; + + const Cause cause; + + VerifyError(Cause cause): cause(cause) {} +}; + +NS_EXTERN +void verifyError(VerifyError::Cause cause); + +struct RuntimeError +{ + enum Cause + { + unknown, // Unknown cause + internal, // Internal error + notImplemented, // Functionality not implemented yet + illegalArgument, // incorrect argument to a method + illegalAccess, // prohibited operation + securityViolation, // Security violation + IOError, // IO Error + fileNotFound, + linkError, // Unable to link method + nullPointer, // Null Pointer argument + notInstantiable // Attempt to instantiate an abstract class + }; + + const Cause cause; + + RuntimeError(Cause cause): cause(cause) {} +}; + +NS_EXTERN +void runtimeError(RuntimeError::Cause cause); + + +#endif diff --git a/ef/Compiler/FrontEnd/LocalEnv.h b/ef/Compiler/FrontEnd/LocalEnv.h new file mode 100644 index 000000000000..72ac4e6edfcb --- /dev/null +++ b/ef/Compiler/FrontEnd/LocalEnv.h @@ -0,0 +1,215 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#ifndef LOCALENV_H +#define LOCALENV_H + +#include "Fundamentals.h" + + +// Information common to all environments in a graph +struct CommonEnv +{ + Pool &envPool; // Memory pool from which to allocate + const Uint32 nLocals; // Number of words of local variables + const Uint32 stackBase; // Index of first stack temporary + const Uint32 stackSize; // Number of words of local stack space + const Uint32 nEnvSlots; // nMemoryBindings + nLocals + stackSize + + CommonEnv(Pool &envPool, Uint32 nMemoryBindings, Uint32 nLocals, Uint32 stackSize): + envPool(envPool), nLocals(nLocals), stackBase(nMemoryBindings + nLocals), stackSize(stackSize), + nEnvSlots(nMemoryBindings + nLocals + stackSize) {} +}; + + +// A single environment containings bindings of class Binding. +// Class Common, which should be derived from CommonEnv, contains information +// common to all environments in a graph. +template +class LocalEnv +{ + protected: + const Common &commonEnv; // Backpointer to information shared among all LocalEnvs in a graph + private: + Binding *bindings; // Array of: + // nMemoryBindings memory bindings + // nLocals local variable bindings + // stackSize stack temporaries' bindings + // (the bindings may be nil). + Uint32 sp; // Stack pointer (index within bindings array of first unused temporary) + // Bindings at indices 0..sp-1 are valid; others are ignored + + public: + explicit LocalEnv(const Common &commonEnv); + LocalEnv(const LocalEnv &env): commonEnv(env.commonEnv) {copyEnv(env);} + void operator=(const LocalEnv &env) {assert(!bindings); copyEnv(env);} + void move(LocalEnv &env); + + void init(); + + protected: + void copyEnv(const LocalEnv &env); + Binding *bindingsBegin() const {return bindings;} // Return the first valid binding + Binding *bindingsEnd() const {return bindings + sp;} // Return the last valid binding + 1 + Binding *bindingsMemoryEnd() const {return bindings + nMemoryBindings;} // Return the last memory binding + 1 + public: + + Pool &envPool() const {return commonEnv.envPool;} + Binding &memory() const {return bindings[0];} + Binding &local(Uint32 n) const {assert(n < commonEnv.nLocals); return bindings[nMemoryBindings + n];} + Binding &stackNth(Uint32 n) const {assert(n > 0 && sp >= commonEnv.stackBase + n); return bindings[sp - n];} + Binding *stackTopN(Uint32 DEBUG_ONLY(n)) const {assert(sp >= commonEnv.stackBase + n); return bindings + sp;} + + // Stack operations + Uint32 getSP() const {return sp - commonEnv.stackBase;} + void dropAll() {sp = commonEnv.stackBase;} + void drop(uint n) {assert(sp >= commonEnv.stackBase + n); sp -= n;} + void raise(uint n) {assert(sp + n <= commonEnv.nEnvSlots); sp += n;} + Binding &pop() {assert(sp > commonEnv.stackBase); return bindings[--sp];} // Note: Result invalidated by next push! + Binding &push() {assert(sp < commonEnv.nEnvSlots); return bindings[sp++];} + Binding &pop2(); + Binding &push2(); + Binding &pop1or2(bool two); + Binding &push1or2(bool two); + + protected: + bool compatible(const LocalEnv &env) {return bindings && env.bindings && &commonEnv == &env.commonEnv && sp == env.sp;} +}; + + +// --- INLINES ---------------------------------------------------------------- + +// +// Construct a new LocalEnv for the method described by commonEnv. +// The LocalEnv cannot be used unless init is called first or another LocalEnv +// is copied to this one. +// +template +inline LocalEnv::LocalEnv(const Common &commonEnv): + commonEnv(commonEnv), + bindings(0) +{} + + +// +// Destructively move the given LocalEnv (which must have been initialized) +// to this LocalEnv, which must be uninitialized. The given LocalEnv is +// left uninitialized. +// +template +inline void LocalEnv::move(LocalEnv &env) +{ + assert(!bindings && env.bindings); + bindings = env.bindings; + sp = env.sp; + #ifdef DEBUG + env.bindings = 0; + #endif +} + + +// +// Pop and return a long or double binding from the stack. The two words on the top of +// the stack must contain a long or double value. +// Note that the returned reference will be invalidated by the next push. +// +template +inline Binding &LocalEnv::pop2() +{ + assert(sp > commonEnv.stackBase+1 && bindings[sp-1].isSecondWord()); + return bindings[sp -= 2]; +} + + +// +// Push a long or double binding outo the stack. The return value is a reference to +// a new stack slot; the caller must initialize it to refer to the long or double's first word. +// +template +inline Binding &LocalEnv::push2() +{ + assert(sp < commonEnv.nEnvSlots-1); + Binding *b = &bindings[sp]; + b[1].defineSecondWord(); + sp += 2; + return *b; +} + + +// +// Do pop() if two is false or pop2() if two is true. +// +template +inline Binding &LocalEnv::pop1or2(bool two) +{ + assert(sp > commonEnv.stackBase+two && (!two || bindings[sp-1].isSecondWord())); + if (two) + --sp; + return bindings[--sp]; +} + + +// +// Do push() if two is false or push2() if two is true. +// +template +inline Binding &LocalEnv::push1or2(bool two) +{ + assert(sp < commonEnv.nEnvSlots-two); + Binding &b = bindings[sp++]; + if (two) + bindings[sp++].defineSecondWord(); + return b; +} + + +// --- TEMPLATES -------------------------------------------------------------- + + +// +// Initialize every entry in this LocalEnv to be empty and the stack to have no +// temporaries. This LocalEnv must not have been initialized before. +// +template +void LocalEnv::init() +{ + assert(!bindings); + Binding *lb = new(commonEnv.envPool) Binding[commonEnv.nEnvSlots]; + bindings = lb; + Uint32 stackBase = commonEnv.stackBase; + sp = stackBase; + Binding *lbEnd = lb + stackBase; + while (lb != lbEnd) + lb++->clear(); +} + + +// +// Assign a copy of the given LocalEnv (which must have been initialized) +// to this LocalEnv, which is known to be uninitialized. +// +template +void LocalEnv::copyEnv(const LocalEnv &env) +{ + assert(env.bindings); + Binding *lbDst = new(commonEnv.envPool) Binding[commonEnv.nEnvSlots]; + copy(env.bindingsBegin(), env.bindingsEnd(), lbDst); + bindings = lbDst; + sp = env.sp; +} + +#endif diff --git a/ef/Compiler/FrontEnd/Makefile b/ef/Compiler/FrontEnd/Makefile new file mode 100644 index 000000000000..9ff0a3933769 --- /dev/null +++ b/ef/Compiler/FrontEnd/Makefile @@ -0,0 +1,67 @@ +#!gmake +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +####################################################################### +# (1) Directory specific info # +####################################################################### + +DEPTH = ../.. + + +CPPSRCS = BytecodeGraph.cpp \ + TranslationEnv.cpp \ + ErrorHandling.cpp \ + BytecodeTranslator.cpp \ + VerificationEnv.cpp \ + BytecodeVerifier.cpp \ + $(NULL) + +LOCAL_EXPORTS = BytecodeGraph.h \ + BytecodeTranslator.h \ + BytecodeVerifier.h \ + ErrorHandling.h \ + LocalEnv.h \ + TranslationEnv.h \ + VerificationEnv.h \ + $(NULL) + +MODULE_NAME = EF + +####################################################################### +# (2) Include "component" configuration information. # +####################################################################### + +include $(DEPTH)/config/config.mk + +####################################################################### +# (3) Include "local" platform-dependent assignments (OPTIONAL). # +####################################################################### + + + +####################################################################### +# (4) Execute "component" rules. (OPTIONAL) # +####################################################################### + +include $(DEPTH)/config/rules.mk + +####################################################################### +# (7) Execute "local" rules. (OPTIONAL). # +####################################################################### + + + diff --git a/ef/Compiler/FrontEnd/Reader.h b/ef/Compiler/FrontEnd/Reader.h new file mode 100644 index 000000000000..2c29b9e6a015 --- /dev/null +++ b/ef/Compiler/FrontEnd/Reader.h @@ -0,0 +1,84 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#ifndef READER_H +#define READER_H + +#include "NativeDefs.h" + +struct VerifyError +{ + enum Cause + { + unknown, // Unknown cause + notImplemented, // Functionality not implemented yet + noClassDefFound, // Error in reading class file: file not found, or has errors + badClassFormat, // Badly formatted class file + illegalAccess, // Class does not have permissions to access a particular field/method + noSuchField, // Field not found in class + noSuchMethod, // Method not found in class + noBytecodes, // No bytecodes in a function + badBytecode, // Bad bytecode opcode + badBytecodeOffset, // Bad offset to a bytecode instruction + badNewArrayType, // Bad type passed to newarray instruction + badConstantPoolIndex, // Constant pool index out of range + badReturn, // Wrong return instruction used in this function + writeToConst, // Attempt to write to a constant (final) field + classNotFound, // Given class not found in class file + nonThrowableCatch, // Catch filter class not a subclass of Throwable + classCircularity, // Class can be its own superclass + resourceExhausted, // Compiler internal limits reached + abstractMethod, // Attempt to invoke abstract method + incompatibleClassChange // Binary incompatibility + }; + + const Cause cause; + + VerifyError(Cause cause): cause(cause) {} +}; + +NS_EXTERN +void verifyError(VerifyError::Cause cause); + +struct RuntimeError +{ + enum Cause + { + unknown, // Unknown cause + internal, // Internal error + notImplemented, // Functionality not implemented yet + illegalArgument, // incorrect argument to a method + illegalAccess, // prohibited operation + securityViolation, // Security violation + IOError, // IO Error + fileNotFound, + linkError, // Unable to link method + nullPointer, // Null Pointer argument + notInstantiable, // Attempt to instantiate an abstract class + outOfMemory + }; + + const Cause cause; + + RuntimeError(Cause cause): cause(cause) {} +}; + +NS_EXTERN +void runtimeError(RuntimeError::Cause cause); + + +#endif diff --git a/ef/Compiler/FrontEnd/TranslationEnv.cpp b/ef/Compiler/FrontEnd/TranslationEnv.cpp new file mode 100644 index 000000000000..c3ed4a1f2dea --- /dev/null +++ b/ef/Compiler/FrontEnd/TranslationEnv.cpp @@ -0,0 +1,516 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#include "BytecodeGraph.h" + + +// ---------------------------------------------------------------------------- +// TranslationCommonEnv + + +// +// Create a new, empty phi node in the block's first control node. +// nExpectedInputs is the estimated number of inputs that the phi node will +// eventually have; however, there is no guarantee that the actual number of +// inputs won't be higher or lower. +// This method disengages the phi nodes in the block's first control node +// and must be balanced by a call to finishPhiNode. +// +PhiNode *TranslationCommonEnv::genEmptyPhiNode(const BasicBlock &block, ValueKind kind, Uint32 nExpectedInputs) const +{ + PhiNode *phiNode = new(primitivePool) PhiNode(nExpectedInputs, kind, primitivePool); + ControlNode *cn = block.getFirstControlNode(); + assert(cn); + cn->disengagePhis(); + cn->addPhiNode(*phiNode); + return phiNode; +} + + +// +// Balance a call to genEmptyPhiNode. The caller should have set up the +// (formerly) empty phi node's inputs by now. +// +inline void TranslationCommonEnv::finishPhiNode(const BasicBlock &block) const +{ + ControlNode *cn = block.getFirstControlNode(); + assert(cn); + cn->reengagePhis(); +} + + +// ---------------------------------------------------------------------------- +// TranslationBinding + + +// +// Create the real constant primitive node for this Constant. Allocate the +// primitive node out of the given pool. +// +void TranslationBinding::Constant::genRealNode(Pool &primitivePool, Uint32 bci) +{ + assert(!producerExists); + + PrimConst *primConst = new(primitivePool) PrimConst(kind, value, bci); + placeForDataNode->appendPrimitive(*primConst); + producerExists = true; + dataNode = primConst; +} + + +// +// Create a new PhantomPhi record with room for size arguments. Ouf of these, +// set the first nInitialArgs (which may be zero) to initialArgs, and set the +// next argument to arg. Clearly, nInitialArgs must be less than size. +// container is the BasicBlock in which this phantom phi node is defined. +// If alwaysNonzero is true, the value of the PhantomPhi is known to never be +// zero. +// Allocate needed storage from pool. +// +TranslationBinding::PhantomPhi::PhantomPhi(ValueKind kind, Uint32 size, Uint32 nInitialArgs, const TranslationBinding &initialArgs, + const TranslationBinding &arg, const BasicBlock &container, bool alwaysNonzero, Pool &pool): + container(container), + nArgs(nInitialArgs + 1), + realPhiExists(false), + kind(kind), + alwaysNonzero(alwaysNonzero) +{ + TranslationBinding *a = new(pool) TranslationBinding[size]; + args = a; + while (nInitialArgs--) + *a++ = initialArgs; + *a = arg; +} + + +// +// Return true if the value of this PhantomPhi is known to never be zero. +// +bool TranslationBinding::PhantomPhi::isAlwaysNonzero() const +{ + return realPhiExists ? realPhi->isAlwaysNonzero() : alwaysNonzero; +} + + +// +// Inform this PhantomPhi about whether its value is never zero. +// +void TranslationBinding::PhantomPhi::setAlwaysNonzero(bool nz) +{ + if (realPhiExists) + realPhi->setAlwaysNonzero(nz); + else + alwaysNonzero = nz; +} + + +// +// Append a new argument arg to this PhantomPhi's array. If expand is true, +// the array first needs to be physically expanded to size newSize (which is +// guaranteed to hold all of its elements). +// +void TranslationBinding::PhantomPhi::append(bool expand, Uint32 newSize, + const TranslationBinding &arg, + Uint32 bci) +{ + if (realPhiExists) { + Pool &primitivePool = container.getTranslationEnvIn().getCommonEnv().primitivePool; + realPhi->addInput(arg.extract(primitivePool, bci), primitivePool); + } else { + Uint32 n = nArgs; + if (expand) { + TranslationBinding *newArgs = new(container.getTranslationEnvIn().envPool()) TranslationBinding[newSize]; + copy(args, args + n, newArgs); + args = newArgs; + assert(newSize > n); + } + args[n] = arg; + nArgs = n + 1; + if (alwaysNonzero) + alwaysNonzero = arg.isAlwaysNonzero(); + } +} + + +// +// Create the real phi node for this PhantomPhi. +// +void TranslationBinding::PhantomPhi::genRealPhi(Uint32 bci) +{ + assert(!realPhiExists); + TranslationBinding *a = args; + const TranslationEnv &env = container.getTranslationEnvIn(); + const TranslationCommonEnv &commonEnv = env.getCommonEnv(); + Pool &primitivePool = commonEnv.primitivePool; + Uint32 n = getNArgs(); + + // Carefully create a new phi node before calling extract on the arguments + // because one of the arguments could refer back to this phi node. + realPhi = commonEnv.genEmptyPhiNode(container, kind, env.getPhiSize()); + realPhiExists = true; + while (n--) + realPhi->addInput(a++->extract(primitivePool, bci), primitivePool); + commonEnv.finishPhiNode(container); +} + + +// +// Return the kind of value represented by this binding. +// +ValueKind TranslationBinding::getKind() const +{ + switch (category) { + case tbConstant: + return constant->kind; + case tbDataEdge: + return dataNode->getKind(); + case tbPhantomPhi: + case tbConstantPhi: + return phantomPhi->kind; + default: + return vkVoid; + } +} + + +// +// Return true if the value of this binding is known to never be zero. +// +bool TranslationBinding::isAlwaysNonzero() const +{ + switch (category) { + case tbConstant: + return constant->isNonzero(); + case tbDataEdge: + return dataNode->isAlwaysNonzero(); + case tbPhantomPhi: + case tbConstantPhi: + return phantomPhi->isAlwaysNonzero(); + default: + return true; + } +} + + +// +// Bind this TranslationBinding to represent the given int constant. +// If a primitive to explicitly generate the constant is needed, it will +// be placed in the given ControlNode. +// Allocate needed storage from pool. +// +void TranslationBinding::defineInt(Int32 v, ControlNode *placeForDataNode, Pool &pool) +{ + category = tbConstant; + Constant *c = new(pool) Constant(vkInt, placeForDataNode); + c->value.i = v; + constant = c; +} + + +// +// Bind this TranslationBinding to represent the first word of the given long constant. +// If a primitive to explicitly generate the constant is needed, it will +// be placed in the given ControlNode. +// Allocate needed storage from pool. +// +void TranslationBinding::defineLong(Int64 v, ControlNode *placeForDataNode, Pool &pool) +{ + category = tbConstant; + Constant *c = new(pool) Constant(vkLong, placeForDataNode); + c->value.l = v; + constant = c; +} + + +// +// Bind this TranslationBinding to represent the given float constant. +// If a primitive to explicitly generate the constant is needed, it will +// be placed in the given ControlNode. +// Allocate needed storage from pool. +// +void TranslationBinding::defineFloat(Flt32 v, ControlNode *placeForDataNode, Pool &pool) +{ + category = tbConstant; + Constant *c = new(pool) Constant(vkFloat, placeForDataNode); + c->value.f = v; + constant = c; +} + + +// +// Bind this TranslationBinding to represent the first word of the given double constant. +// If a primitive to explicitly generate the constant is needed, it will +// be placed in the given ControlNode. +// Allocate needed storage from pool. +// +void TranslationBinding::defineDouble(Flt64 v, ControlNode *placeForDataNode, Pool &pool) +{ + category = tbConstant; + Constant *c = new(pool) Constant(vkDouble, placeForDataNode); + c->value.d = v; + constant = c; +} + + +// +// Bind this TranslationBinding to represent the given pointer constant. +// If a primitive to explicitly generate the constant is needed, it will +// be placed in the given ControlNode. +// Allocate needed storage from pool. +// +void TranslationBinding::definePtr(addr v, ControlNode *placeForDataNode, Pool &pool) +{ + category = tbConstant; + Constant *c = new(pool) Constant(vkAddr, placeForDataNode); + c->value.a = v; + constant = c; +} + + +// +// Bind this TranslationBinding to represent the constant (or first word of the constant +// if it takes two words). +// If a primitive to explicitly generate the constant is needed, it will +// be placed in the given ControlNode. +// Allocate needed environment storage from pool. +// +void TranslationBinding::define(ValueKind kind, const Value &v, ControlNode *placeForDataNode, Pool &pool) +{ + category = tbConstant; + Constant *c = new(pool) Constant(kind, placeForDataNode); + c->value = v; + constant = c; +} + + +// ---------------------------------------------------------------------------- +// TranslationEnv + + +#ifdef DEBUG +// +// Assert that none of the PhantomPhi or ConstantPhi nodes referring to the current container +// are shared. +// +void TranslationEnv::assertNoSharedPhantomPhis(const BasicBlock &container) +{ + TranslationBinding *dst = bindingsBegin(); + TranslationBinding *dstEnd = bindingsEnd(); + for (; dst != dstEnd; dst++) + if (dst->category == TranslationBinding::tbPhantomPhi || dst->category == TranslationBinding::tbConstantPhi) + dst->phantomPhi->duplicate = false; + for (dst = bindingsBegin(); dst != dstEnd; dst++) + if (dst->category == TranslationBinding::tbPhantomPhi || dst->category == TranslationBinding::tbConstantPhi) { + TranslationBinding::PhantomPhi *phi = dst->phantomPhi; + assert(&phi->getContainer() != &container || !phi->duplicate); + phi->duplicate = true; + } +} +#endif + + +// +// Intersect the given TranslationEnv (which must have been initialized) +// into this TranslationEnv, which must also be initialized. +// This environment must be part of the given container. +// If memoryOnly is true, only intersect the memory binding. +// +void TranslationEnv::meet(const TranslationEnv &env, bool memoryOnly, const BasicBlock &container) +{ + #ifdef DEBUG + assert(this == &container.getTranslationEnvIn()); + assert(compatible(env)); + assertNoSharedPhantomPhis(container); + #endif + TranslationBinding *dst = bindingsBegin(); + TranslationBinding *dstEnd = memoryOnly ? bindingsMemoryEnd() : bindingsEnd(); + const TranslationBinding *src = env.bindingsBegin(); + Pool &pool = commonEnv.envPool; + Uint32 oldPhiOffset = phiOffset; + Uint32 newPhiSize = phiSize; + bool expandThis = false; + if (oldPhiOffset >= newPhiSize) { + newPhiSize = oldPhiOffset*2 + 1; + expandThis = true; + } + + while (dst != dstEnd) { + TranslationBinding::Category cDst = dst->category; + TranslationBinding::Category cSrc = src->category; + ValueKind kind; + + if (cSrc == TranslationBinding::tbNone) { + assert(!anticipated || cDst == TranslationBinding::tbNone); + dst->clear(); + } else + switch (cDst) { + + case TranslationBinding::tbNone: + break; + + case TranslationBinding::tbSecondWord: + if (cSrc != TranslationBinding::tbSecondWord) { + assert(!anticipated); + dst->clear(); + } + break; + + case TranslationBinding::tbConstantPhi: + { + TranslationBinding::ConstantPhi *phi = dst->constantPhi; + kind = phi->kind; + if (src->getKind() != kind) { + assert(!anticipated); + dst->clear(); + break; + } + const TranslationBinding::Constant *srcConstant = src->constantValue(); + bool constantMatches = srcConstant && *phi->constant == *srcConstant; + + if (&phi->getContainer() == &container) + if (constantMatches) + // asharma - fix this! + phi->append(expandThis, newPhiSize, *src, 0); + else { + // The constant doesn't match, so turn this into a regular phantom phi node. + assert(!anticipated); + dst->category = TranslationBinding::tbPhantomPhi; + goto phantomPhi; + } + else + // Don't merge if both source and destination are the same and they don't refer to + // this container. + if (cSrc != TranslationBinding::tbConstantPhi || src->constantPhi != phi) + if (constantMatches) { + assert(!anticipated); + dst->define(new(pool) TranslationBinding::ConstantPhi(kind, newPhiSize, oldPhiOffset, + *dst, *src, container, srcConstant, pool)); + } else + goto createPhi; + } + break; + + case TranslationBinding::tbPhantomPhi: + if (src->getKind() != dst->phantomPhi->kind) { + assert(!anticipated); + dst->clear(); + break; + } + phantomPhi: + { + TranslationBinding::PhantomPhi *phi = dst->phantomPhi; + + if (&phi->getContainer() == &container) { + // Use existing phantom phi node in this node + assert(!phi->isAlwaysNonzero() || src->isAlwaysNonzero() || !anticipated); + // asharma - fix this! + phi->append(expandThis, newPhiSize, *src, 0); + break; + } + + // Don't merge if both source and destination are the same and they don't refer to + // this container. + if (cSrc != TranslationBinding::tbPhantomPhi || src->phantomPhi != phi) { + kind = phi->kind; + goto createPhi; + } + } + break; + + case TranslationBinding::tbDataEdge: + if (cSrc != TranslationBinding::tbDataEdge || src->dataNode != dst->dataNode) { + kind = dst->dataNode->getKind(); + if (src->getKind() != kind) { + assert(!anticipated); + dst->clear(); + break; + } + createPhi: + assert(!anticipated); + dst->define(new(pool) TranslationBinding::PhantomPhi(kind, newPhiSize, oldPhiOffset, *dst, *src, container, + dst->isAlwaysNonzero() && src->isAlwaysNonzero(), pool)); + } + break; + + case TranslationBinding::tbConstant: + if (cSrc != TranslationBinding::tbConstant || src->constant != dst->constant) { + kind = dst->constant->kind; + if (src->getKind() != kind) { + assert(!anticipated); + dst->clear(); + break; + } + const TranslationBinding::Constant *srcConstant = src->constantValue(); + if (srcConstant && *dst->constant == *srcConstant) { + dst->define(new(pool) TranslationBinding::ConstantPhi(kind, newPhiSize, oldPhiOffset, + *dst, *src, container, srcConstant, pool)); + break; + } + goto createPhi; + } + } + src++; + dst++; + } + phiOffset = oldPhiOffset + 1; + phiSize = newPhiSize; +} + + +// +// Add phantom phi nodes to all variables in this local environment because we'd like +// to use this environment without knowing all of its predecessors yet. +// This environment must be part of the given container. +// +void TranslationEnv::anticipate(const BasicBlock &container) +{ + #ifdef DEBUG + assert(this == &container.getTranslationEnvIn()); + assertNoSharedPhantomPhis(container); + assert(!anticipated); + anticipated = true; + #endif + TranslationBinding *dst = bindingsBegin(); + TranslationBinding *dstEnd = bindingsEnd(); + Pool &pool = commonEnv.envPool; + + while (dst != dstEnd) { + switch (dst->category) { + case TranslationBinding::tbNone: + case TranslationBinding::tbSecondWord: + break; + case TranslationBinding::tbConstantPhi: + if (&dst->constantPhi->getContainer() != &container) + goto createPhi; + dst->constantPhi->setAlwaysNonzero(false); + dst->category = TranslationBinding::tbPhantomPhi; + break; + case TranslationBinding::tbPhantomPhi: + if (&dst->phantomPhi->getContainer() == &container) + break; // We already have an appropriate phi node. + // Fall into default case because we need to create a new phi node; the current + // value was a phi node from another control node. + default: + createPhi: + assert(phiOffset > 0 && phiSize >= phiOffset); + dst->define(new(pool) TranslationBinding::PhantomPhi(dst->getKind(), phiSize, phiOffset-1, + *dst, *dst, container, false, pool)); + break; + } + dst++; + } +} diff --git a/ef/Compiler/FrontEnd/TranslationEnv.h b/ef/Compiler/FrontEnd/TranslationEnv.h new file mode 100644 index 000000000000..6129f1025bcb --- /dev/null +++ b/ef/Compiler/FrontEnd/TranslationEnv.h @@ -0,0 +1,465 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#ifndef TRANSLATIONENV_H +#define TRANSLATIONENV_H + +#include "ControlNodes.h" +#include "LocalEnv.h" + +struct BasicBlock; + + +struct TranslationCommonEnv: CommonEnv +{ + Pool &primitivePool; // Pool for allocating phi and constant data flow nodes + + PhiNode *genEmptyPhiNode(const BasicBlock &block, ValueKind kind, Uint32 nExpectedInputs) const; + void finishPhiNode(const BasicBlock &block) const; + + TranslationCommonEnv(Pool &envPool, Pool &primitivePool, Uint32 nLocals, Uint32 stackSize): + CommonEnv(envPool, 1, nLocals, stackSize), primitivePool(primitivePool) {} +}; + + +class TranslationBinding +{ + public: + enum Category + { + tbNone, // Unknown contents + tbSecondWord, // This variable is the second word of a long or double + tbConstant, // This variable is a constant constVal defined in basic block definer + tbDataEdge, // This variable was defined by the given DataNode + tbPhantomPhi, // This variable was defined by the given phantom phi node + tbConstantPhi // This variable was defined by the given phantom phi node that always evaluates to a constant + }; + + static bool isPhi(Category c) {return c == tbPhantomPhi || c == tbConstantPhi;} + + + private: + struct Constant + { + const ValueKind kind ENUM_8; // Kind of constant + bool producerExists BOOL_8; // If true, a data flow node exists for this constant and can be found + //short unused SHORT_16; // using dataNode below. If false, the data flow node can be created + union { // in the placeForDataNode control node if needed. + ControlNode *placeForDataNode; // Control node inside which the constant was defined + DataNode *dataNode; // Link to data flow node that defined this constant + }; + Value value; // Constant's value + + Constant(ValueKind kind, ControlNode *placeForDataNode); + + bool operator==(const Constant &c) const {ValueKind k = kind; return k == c.kind && value.eq(k, c.value);} + bool operator!=(const Constant &c) const {ValueKind k = kind; return k != c.kind || !value.eq(k, c.value);} + + private: + void genRealNode(Pool &primitivePool, Uint32 bci); + public: + bool isNonzero() const {return value.isNonzero(kind);} + DataNode &realize(Pool &primitivePool, Uint32 bci); + }; + + + class PhantomPhi + { + const BasicBlock &container; // Block in which this phantom phi node is defined + Uint32 nArgs; // Number of occupied arguments in the args array below (valid only when realPhiExists is false) + bool realPhiExists BOOL_8; // If true, a real phi node exists and can be found using realPhi below. + public: + const ValueKind kind ENUM_8; // Kind of value stored in this phi node + DEBUG_ONLY(bool duplicate BOOL_8;) // Flag used for assertNoSharedPhantomPhis + private: + bool alwaysNonzero BOOL_8; // If true, the value of this PhantomPhi is known to always be nonzero + union { // (valid only if realPhiExists is false) + TranslationBinding *args; // Array of phiSize TranslationBinding records for the arguments of a phantom phi node + PhiNode *realPhi; // Real phi node if one has been generated + }; + + PhantomPhi(const PhantomPhi &); // Copying forbidden + void operator=(const PhantomPhi &); // Copying forbidden + public: + PhantomPhi(ValueKind kind, Uint32 size, Uint32 nInitialArgs, const TranslationBinding &initialArgs, const TranslationBinding &arg, + const BasicBlock &container, bool alwaysNonzero, Pool &pool); + + const BasicBlock &getContainer() const {return container;} + Uint32 getNArgs() const {assert(!realPhiExists); return nArgs;} + bool isAlwaysNonzero() const; + void setAlwaysNonzero(bool nz); + void append(bool expand, Uint32 newSize, + const TranslationBinding &arg, Uint32 bci); + private: + void genRealPhi(Uint32 bci); + public: + DataNode &realize(Uint32 bci); + }; + + + // A ConstantPhi is a PhantomPhi with the added restriction that all of its arguments are + // either the same constant or other ConstantPhis of the same constant. + struct ConstantPhi: PhantomPhi + { + const Constant *constant; // Constant to which all of the arguments of this phantom phi node evaluate + + ConstantPhi(ValueKind kind, Uint32 size, Uint32 nInitialArgs, const TranslationBinding &initialArgs, const TranslationBinding &arg, + const BasicBlock &container, const Constant *constant, Pool &pool); + }; + + + Category category ENUM_8; // TranslationBinding category (determines interpretation of union below) + //bool unused BOOL_8; + //short unused SHORT_16; + union { + Constant *constant; // Constant value (Constant may be shared among different bindings) + DataNode *dataNode; // Place where this variable is defined + PhantomPhi *phantomPhi; // Phantom phi node (PhantomPhi may be shared among different bindings) + ConstantPhi *constantPhi; // Phantom phi node all of whose arguments evaluate to the same constant (may be shared) + void *data; // Used for comparing constNum, constAddr, etc. + // Note: The phantomPhi and constantPhi pointers from several different bindings in an environment + // may point to a common PhantomPhi or ConstantPhi record under the following circumstances: + // 1. phantomPhi->container (or constantPhi->container) is not the current environment's container + // 2. All calls to meet and anticipate have completed (at this point sharing can be + // introduced, for instance, by assigning one local to another). + // Sharing of PhantomPhi or ConstantPhi records in the current environment while meet or + // anticipate is running would cause trouble because these routines extend the phantom phi arrays. + }; + + public: + bool operator==(const TranslationBinding &b) const + {return category == b.category && data == b.data;} + bool operator!=(const TranslationBinding &b) const + {return category != b.category || data != b.data;} + + bool isDataEdge() const { return category == tbDataEdge; } + bool isSecondWord() const {return category == tbSecondWord;} + const Constant *constantValue() const; + ValueKind getKind() const; + bool isAlwaysNonzero() const; + + void extract(VariableOrConstant &result, Uint32 bci) const; + DataNode &extract(Pool &primitivePool, Uint32 bci) const; + DataNode &extract(Uint32 bci) const; + + void clear(); + inline void defineSecondWord(); + void defineInt(Int32 v, ControlNode *placeForDataNode, Pool &pool); + void defineLong(Int64 v, ControlNode *placeForDataNode, Pool &pool); + void defineFloat(Flt32 v, ControlNode *placeForDataNode, Pool &pool); + void defineDouble(Flt64 v, ControlNode *placeForDataNode, Pool &pool); + void definePtr(addr v, ControlNode *placeForDataNode, Pool &pool); + void define(ValueKind kind, const Value &v, ControlNode *placeForDataNode, Pool &pool); + void define(DataNode &dataNode); + void define(const VariableOrConstant &poc, ControlNode *placeForDataNode, Pool &pool); + private: + void define(PhantomPhi *p) {category = tbPhantomPhi; phantomPhi = p;} + void define(ConstantPhi *p) {category = tbConstantPhi; constantPhi = p;} + + friend class TranslationEnv; +}; + + +class TranslationEnv: public LocalEnv +{ + Uint32 phiSize; // Number of LocalBindings allocated in this environment's phantom phi bindings + Uint32 phiOffset; // Next index to be allocated in this environment's phantom phi bindings + #ifdef DEBUG + bool anticipated; // True if anticipate has been called on this environment + #endif + + public: + TranslationEnv(TranslationCommonEnv &commonEnv); + TranslationEnv(const TranslationEnv &env); + void operator=(const TranslationEnv &env); + void move(TranslationEnv &env); + + Uint32 getPhiSize() const {return phiSize;} + const TranslationCommonEnv &getCommonEnv() const {return commonEnv;} + + #ifdef DEBUG + void assertNoSharedPhantomPhis(const BasicBlock &container); + #endif + void meet(const TranslationEnv &env, bool memoryOnly, const BasicBlock &container); + void anticipate(const BasicBlock &container); +}; + + +// --- INLINES ---------------------------------------------------------------- + + +// +// Initialize a Constant of the given kind. The constant starts out with no +// real data flow node, but if one is needed, it will be created in placeForDataNode. +// +inline TranslationBinding::Constant::Constant(ValueKind kind, ControlNode *placeForDataNode): + kind(kind), + producerExists(false), + placeForDataNode(placeForDataNode) +{ + assert(placeForDataNode); + // Prevent this ControlNode from being recycled because a real data flow node could be + // created in it at any time. + placeForDataNode->inhibitRecycling(); +} + + +// +// Create if necessary and return a real data flow node for this constant. +// Allocate the primitive node out of the given pool. +// +inline DataNode &TranslationBinding::Constant::realize(Pool &primitivePool, + Uint32 bci) +{ + if (!producerExists) + genRealNode(primitivePool, bci); + return *dataNode; +} + + +// +// Create if necessary and return the real phi node for this PhantomPhi. +// +inline DataNode &TranslationBinding::PhantomPhi::realize(Uint32 bci) +{ + if (!realPhiExists) + genRealPhi(bci); + return *realPhi; +} + + +// +// Create a new ConstantPhi record with room for size arguments. Ouf of these, +// set the first nInitialArgs (which may be zero) to initialArgs, and set the +// next argument to arg. Clearly, nInitialArgs must be less than size. +// container is the BasicBlock in which this constant phantom phi node is defined. +// Every argument of this ConstantPhi must evaluate to constant. +// Allocate needed storage from pool. +// +inline TranslationBinding::ConstantPhi::ConstantPhi(ValueKind kind, Uint32 size, Uint32 nInitialArgs, const TranslationBinding &initialArgs, + const TranslationBinding &arg, const BasicBlock &container, const Constant *constant, Pool &pool): + PhantomPhi(kind, size, nInitialArgs, initialArgs, arg, container, constant->isNonzero(), pool), + constant(constant) +{} + + +// +// If this TranslationBinding would always evaluate to the same constant, return that +// constant; otherwise, return nil. +// +inline const TranslationBinding::Constant *TranslationBinding::constantValue() const +{ + switch (category) { + case tbConstant: + return constant; + case tbConstantPhi: + return constantPhi->constant; + default: + return 0; + } +} + + +// +// If this TranslationBinding would always evaluate to the same constant, return that +// constant in result. Otherwise, return the producer in result, creating phi +// nodes for the producer if necessary. +// +inline void TranslationBinding::extract(VariableOrConstant &result, + Uint32 bci) const +{ + const Constant *c; + + switch (category) { + case tbConstant: + c = constant; + result.setConstant(c->kind, c->value); + break; + case tbDataEdge: + result.setVariable(*dataNode); + break; + case tbPhantomPhi: + result.setVariable(phantomPhi->realize(bci)); + break; + case tbConstantPhi: + c = constantPhi->constant; + result.setConstant(c->kind, c->value); + break; + default: + trespass("Can't extract this binding"); + } +} + + +// +// Return the producer for this TranslationBinding, creating phi nodes or +// constant nodes if necessary. Create a producer even if it's just a +// constant. +// +inline DataNode & +TranslationBinding::extract(Pool &primitivePool, Uint32 bci) const +{ + switch (category) { + case tbConstant: + return constant->realize(primitivePool, bci); + case tbPhantomPhi: + case tbConstantPhi: + return phantomPhi->realize(bci); + case tbDataEdge: + return *dataNode; + default: + trespass("Can't extract this binding"); + return *(DataNode *)0; + } +} + + +// +// Return the producer for this TranslationBinding, creating phi nodes if +// necessary. It is an error if the producer is a constant. +// +inline DataNode &TranslationBinding::extract(Uint32 bci) const +{ + switch (category) { + case tbPhantomPhi: + case tbConstantPhi: + return phantomPhi->realize(bci); + case tbDataEdge: + return *dataNode; + default: + trespass("Can't extract this binding"); + return *(DataNode *)0; + } +} + + +// +// Clear any previous binding from this TranslationBinding. +// +inline void TranslationBinding::clear() +{ + category = tbNone; + data = 0; +} + + +// +// Bind this TranslationBinding to represent the second word of a long or double. +// This TranslationBinding won't carry any more descriptive information about that +// long or double -- all such information is carried by the first word's binding. +// +inline void TranslationBinding::defineSecondWord() +{ + category = tbSecondWord; + data = 0; +} + + +// +// Bind this TranslationBinding to be the result (first word if it's a long or double) +// of the given DataNode. +// +inline void TranslationBinding::define(DataNode &dataNode) +{ + category = tbDataEdge; + TranslationBinding::dataNode = &dataNode; +} + + +// +// Bind this TranslationBinding to be the result (first word if it's a long or double) +// of the given DataNode or Constant. +// Allocate needed environment storage from pool. +// +inline void TranslationBinding::define(const VariableOrConstant &poc, ControlNode *placeForDataNode, Pool &pool) +{ + if (poc.isConstant()) + define(poc.getKind(), poc.getConstant(), placeForDataNode, pool); + else + define(poc.getVariable()); +} + + +// ---------------------------------------------------------------------------- + + +const initialPhiSize = 3; + +// +// Create a new translation binding environment. +// The environment starts with one predecessor for the purpose of tracking +// the origins of phi nodes' entries. +// +inline TranslationEnv::TranslationEnv(TranslationCommonEnv &commonEnv): + LocalEnv(commonEnv), + phiSize(initialPhiSize), + phiOffset(1) + #ifdef DEBUG + , anticipated(false) + #endif +{} + + +// +// Copy a translation binding environment. +// The copy starts with one predecessor for the purpose of tracking +// the origins of phi nodes' entries. +// +inline TranslationEnv::TranslationEnv(const TranslationEnv &env): + LocalEnv(env), + phiSize(initialPhiSize), + phiOffset(1) + #ifdef DEBUG + , anticipated(false) + #endif +{} + + +// +// Assign the given translation binding environment to this one. +// The copy starts with one predecessor for the purpose of tracking +// the origins of phi nodes' entries. +// +inline void TranslationEnv::operator=(const TranslationEnv &env) +{ + phiSize = initialPhiSize; + phiOffset = 1; + #ifdef DEBUG + anticipated = false; + #endif + LocalEnv::operator=(env); +} + + +// +// Destructively move the given LocalEnv (which must have been initialized) +// to this LocalEnv, which must be uninitialized. The given LocalEnv is +// left uninitialized. +// The moved environment is reset to have only one predecessor for the purpose +// of tracking the origins of phi nodes' entries. +// +inline void TranslationEnv::move(TranslationEnv &env) +{ + phiSize = initialPhiSize; + phiOffset = 1; + #ifdef DEBUG + anticipated = false; + #endif + LocalEnv::move(env); +} + +#endif diff --git a/ef/Compiler/FrontEnd/VerificationEnv.cpp b/ef/Compiler/FrontEnd/VerificationEnv.cpp new file mode 100644 index 000000000000..186fd1746db2 --- /dev/null +++ b/ef/Compiler/FrontEnd/VerificationEnv.cpp @@ -0,0 +1,657 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#include "VerificationEnv.h" + + +const VerificationEnv::BindingKind VerificationEnv::valueKindBindingKinds[nValueKinds] = +{ + bkVoid, // vkVoid + bkInt, // vkInt + bkLong, // vkLong + bkFloat, // vkFloat + bkDouble, // vkDouble + bkAddr, // vkAddr + bkVoid, // vkCond + bkVoid, // vkMemory + bkVoid // vkTuple +}; + + +const VerificationEnv::BindingKind VerificationEnv::typeKindBindingKinds[nTypeKinds] = +{ + bkVoid, // tkVoid + bkInt, // tkBoolean + bkInt, // tkUByte + bkInt, // tkByte + bkInt, // tkChar + bkInt, // tkShort + bkInt, // tkInt + bkLong, // tkLong + bkFloat, // tkFloat + bkDouble, // tkDouble + bkAddr, // tkObject + bkAddr, // tkSpecial + bkAddr, // tkArray + bkAddr // tkInterface +}; + + +// ---------------------------------------------------------------------------- +// VerificationEnv::Context + + +// +// Create a new, empty Context that holds information about which variables a subroutine +// has modified. Clear the modified array (indicating that no variables have been accessed +// yet) and the link to the next context. +// +VerificationEnv::Context::Context(Subroutine subroutine, const Common &common): + next(0), + subroutine(subroutine), + retReachable(false) + #ifdef DEBUG + , common(common) + #endif +{ + assert(common.bindingPool); + modified = new(*common.bindingPool) char[common.nEnvSlots]; + fill(modified, modified + common.nEnvSlots, 0); +} + + +// +// Create a copy of the given context. Clear the link to the next context. +// +VerificationEnv::Context::Context(const Context &src, const Common &common): + next(0), + subroutine(src.subroutine), + retReachable(src.retReachable) + #ifdef DEBUG + , common(common) + #endif +{ + assert(common.bindingPool); + modified = new(*common.bindingPool) char[common.nEnvSlots]; + copy(src.modified, src.modified + common.nEnvSlots, modified); +} + + +// +// Create a partial copy of the given context. Do not copy the contents of the +// modified array. Translate the Subroutine value using the given translator. +// Clear the link to the next context. +// +inline VerificationEnv::Context::Context(const Context &src, const Common &common, Function1 &translator): + next(0), + subroutine(translator(src.subroutine)), + retReachable(src.retReachable) + #ifdef DEBUG + , common(common) + #endif +{} + + +// +// Merge this context with the src context. A slot in the merged context is +// set to the modified state if it was modified in either this or the src context. +// Return true if the resulting context differs from the original contents of this +// context. +// +bool VerificationEnv::Context::meet(const Context &src, Uint32 nSlots) +{ + assert(subroutine == src.subroutine && common.bindingPool); + bool changed = false; + char *dstModified = modified; + const char *srcModified = src.modified; + for (Uint32 slot = 0; slot != nSlots; slot++) + if (srcModified[slot] && !dstModified[slot]) { + dstModified[slot] = true; + changed = true; + } + return changed; +} + + +// +// If a context corresponding to the given subroutine is in the linked list of +// contexts, return that context. If not, return nil. list can be nil. +// +VerificationEnv::Context *VerificationEnv::Context::find(Context *list, const Subroutine subroutine) +{ + while (list && list->subroutine != subroutine) + list = list->next; + return list; +} + + +// ---------------------------------------------------------------------------- +// VerificationEnv + + +const VerificationEnv::InitBinding VerificationEnv::secondWordBinding(bkSecondWord); + + +// +// Assign a partial copy of the given VerificationEnv (which must have been initialized) +// to this VerificationEnv, which is known to be uninitialized. Do not copy the +// bindings nor the modified arrays inside Contexts. Translate all Subroutine values +// using the given translator. +// +VerificationEnv::VerificationEnv(const VerificationEnv &env, Function1 &translator): + common(env.common) +{ + assert(env.live()); + + // Copy the bindings pointer (which is now only relevant to indicate whether this + // environment is live or not). + bindings = env.bindings; + sp = env.sp; + + // Copy the context hierarchy. + activeContexts = 0; + Context *srcContext = env.activeContexts; + Context **dstContext = &activeContexts; + while (srcContext) { + *dstContext = new(common.envPool) Context(*srcContext, common, translator); + dstContext = &(*dstContext)->next; + srcContext = srcContext->next; + } +} + + +// +// Make this VerificationEnv (which must not have been initialized) live, +// assigning bkVoid to every slot. +// +void VerificationEnv::initLive() +{ + assert(!live() && common.bindingPool); + + // Create and initialize the bindings. + Binding *bdgs = new(*common.bindingPool) Binding[common.nEnvSlots]; + bindings = bdgs; + Binding *bdgsEnd = bdgs + common.nEnvSlots; + while (bdgs != bdgsEnd) + bdgs++->setVoid(); + sp = common.stackBase; + activeContexts = 0; +} + + +// +// Assign a copy of the given VerificationEnv (which must have been initialized) +// to this VerificationEnv, which is known to be uninitialized. +// +void VerificationEnv::copyEnv(const VerificationEnv &env) +{ + assert(env.live() && common.bindingPool); + + // Copy the bindings. + bindings = new(*common.bindingPool) Binding[common.nEnvSlots]; + copy(env.bindings, env.bindings + common.nEnvSlots, bindings); + sp = env.sp; + + // Copy the context hierarchy. + activeContexts = 0; + Context *srcContext = env.activeContexts; + Context **dstContext = &activeContexts; + while (srcContext) { + *dstContext = new(common.envPool) Context(*srcContext, common); + dstContext = &(*dstContext)->next; + srcContext = srcContext->next; + } +} + + +// +// Set the value of the given environment slot, adding that slot to +// the list of slots modified by all currently active subroutines. +// +void VerificationEnv::setSlot(Uint32 slot, const Binding &binding) +{ + assert(slot < common.nEnvSlots); + bindings[slot] = binding; + for (Context *c = activeContexts; c; c = c->next) + c->modify(slot); +} + + +// +// Return the value of the one-word local variable in the given slot. +// Throw a verification error if the slot number is out of bounds or the value +// is undefined or a part of a two-word value. +// +const VerificationEnv::Binding &VerificationEnv::getLocal1(Uint32 n) const +{ + assert(live() && common.bindingPool); + if (n >= common.nLocals) + verifyError(VerifyError::noSuchLocal); + Binding &b = bindings[n]; + if (!b.isOneWord()) + verifyError(VerifyError::badType); + return b; +} + + +// +// Return the value of the two-word local variable in the given slot. +// Throw a verification error if the slot number is out of bounds or the value +// is undefined or not a two-word value. +// +const VerificationEnv::Binding &VerificationEnv::getLocal2(Uint32 n) const +{ + assert(live() && common.bindingPool); + if (n+1 >= common.nLocals) + verifyError(VerifyError::noSuchLocal); + Binding &b = bindings[n]; + if (!b.isTwoWord()) + verifyError(VerifyError::badType); + assert(bindings[n+1].hasKind(bkSecondWord)); + return b; +} + + +// +// Set the value of the one-word local variable in the given slot. +// Throw a verification error if the slot number is out of bounds. +// The given binding must have a one-word kind. +// +void VerificationEnv::setLocal1(Uint32 n, const Binding &binding) +{ + assert(live() && binding.isOneWord() && common.bindingPool); + if (n >= common.nLocals) + verifyError(VerifyError::noSuchLocal); + Binding *b = &bindings[n]; + + // If we're writing into an existing half of a doubleword, + // invalidate the other half of that doubleword. + BindingKind bk = b->getKind(); + if (isTwoOrSecondWordKind(bk)) + b[bk == bkSecondWord ? -1 : 1].setVoid(); + + setSlot(n, binding); +} + + +// +// Set the value of the two-word local variable in the given slot. +// Throw a verification error if the slot number is out of bounds. +// The given binding must have a two-word kind. +// +void VerificationEnv::setLocal2(Uint32 n, const Binding &binding) +{ + assert(live() && binding.isTwoWord() && common.bindingPool); + if (n+1 >= common.nLocals) + verifyError(VerifyError::noSuchLocal); + Binding *b = &bindings[n]; + + // If we're writing into an existing half of a doubleword, + // invalidate the other half of that doubleword. + if (b[0].hasKind(bkSecondWord)) + b[-1].setVoid(); + if (b[1].isTwoWord()) + b[2].setVoid(); + + setSlot(n, binding); + setSlot(n+1, secondWordBinding); +} + + +// +// Pop and return a one-word value from the stack. +// Throw a verification error if the stack underflows or the value +// is undefined or a part of a two-word value. +// Note that the returned reference will be invalidated by the next push. +// +const VerificationEnv::Binding &VerificationEnv::pop1() +{ + assert(live() && common.bindingPool); + if (sp == common.stackBase) + verifyError(VerifyError::bytecodeStackUnderflow); + Binding &b = bindings[--sp]; + if (!b.isOneWord()) + verifyError(VerifyError::badType); + return b; +} + + +// +// Pop and return a one-word value from the stack. +// Throw a verification error if the stack underflows or the value +// is undefined or has a kind other than the given kind. +// Note that the returned reference will be invalidated by the next push. +// +const VerificationEnv::Binding &VerificationEnv::pop1(BindingKind bk) +{ + assert(live() && isOneWordKind(bk) && common.bindingPool); + if (sp == common.stackBase) + verifyError(VerifyError::bytecodeStackUnderflow); + Binding &b = bindings[--sp]; + if (!b.hasKind(bk)) + verifyError(VerifyError::badType); + return b; +} + + +// +// Pop and return a two-word value or two one-word values from the stack. +// Throw a verification error if the stack underflows or the value +// is undefined or a part of a two-word value that includes one of the two +// stack slots but not the other. +// +void VerificationEnv::pop2(Binding &binding1, Binding &binding2) +{ + assert(live() && common.bindingPool); + if (sp <= common.stackBase+1) + verifyError(VerifyError::bytecodeStackUnderflow); + sp -= 2; + Binding *b = &bindings[sp]; + BindingKind bk1 = b[0].getKind(); + BindingKind bk2 = b[1].getKind(); + if (!(isOneWordKind(bk1) && isOneWordKind(bk2) || isTwoWordKind(bk1))) + verifyError(VerifyError::badType); + assert(!isTwoWordKind(bk1) || bk2 == bkSecondWord); + binding1 = b[0]; + binding2 = b[1]; +} + + +// +// Pop and return a two-word value from the stack. +// Throw a verification error if the stack underflows or the value +// is undefined or has a kind other than the given kind. +// Note that the returned reference will be invalidated by the next push. +// +const VerificationEnv::Binding &VerificationEnv::pop2(BindingKind bk) +{ + assert(live() && isTwoWordKind(bk) && common.bindingPool); + if (sp <= common.stackBase+1) + verifyError(VerifyError::bytecodeStackUnderflow); + sp -= 2; + Binding *b = &bindings[sp]; + if (!b[0].hasKind(bk)) + verifyError(VerifyError::badType); + assert(b[1].hasKind(bkSecondWord)); + return *b; +} + + +// +// Pop and return a one or two-word value from the stack, depending on bk. +// Throw a verification error if the stack underflows or the value +// is undefined or has a kind other than the given kind. +// Note that the returned reference will be invalidated by the next push. +// +const VerificationEnv::Binding &VerificationEnv::pop1or2(BindingKind bk) +{ + return isTwoWordKind(bk) ? pop2(bk) : pop1(bk); +} + + +// +// Push a one-word value onto the stack. +// Throw a verification error if the stack overflows. +// The given binding must have a one-word kind. +// +void VerificationEnv::push1(const Binding &binding) +{ + assert(live() && binding.isOneWord() && common.bindingPool); + if (sp == common.nEnvSlots) + verifyError(VerifyError::bytecodeStackOverflow); + setSlot(sp++, binding); +} + + +// +// Push a one-word value that contains a new binding of the given kind onto the stack. +// Throw a verification error if the stack overflows. +// +void VerificationEnv::push1(BindingKind bk) +{ + // Note: bkAddr will be outlawed here once we start to distinguish among types of + // pointers. + assert(bk == bkVoid || bk == bkInt || bk == bkFloat || bk == bkAddr); + InitBinding b(bk); + push1(b); +} + + +// +// Push a two-word value onto the stack. +// Throw a verification error if the stack overflows. +// The given binding must have a two-word kind. +// +void VerificationEnv::push2(const Binding &binding) +{ + assert(live() && binding.isTwoWord() && common.bindingPool); + if (sp+1 >= common.nEnvSlots) + verifyError(VerifyError::bytecodeStackOverflow); + setSlot(sp++, binding); + setSlot(sp++, secondWordBinding); +} + + +// +// Push a two-word value that contains a new binding of the given kind onto the stack. +// Throw a verification error if the stack overflows. +// +void VerificationEnv::push2(BindingKind bk) +{ + assert(bk == bkLong || bk == bkDouble); + InitBinding b(bk); + push2(b); +} + + +// +// Push a two-word value or two one-word values onto the stack. +// Throw a verification error if the stack overflows. +// The given bindings must be the two words of a two-word value +// or both be one-word values. +// +void VerificationEnv::push2(const Binding &binding1, const Binding &binding2) +{ + assert(live() && (binding1.isTwoWord() && binding2.hasKind(bkSecondWord) || + binding1.isOneWord() && binding2.isOneWord()) + && common.bindingPool); + if (sp+1 >= common.nEnvSlots) + verifyError(VerifyError::bytecodeStackOverflow); + setSlot(sp++, binding1); + setSlot(sp++, binding2); +} + + +// +// Push a one or two-word value that contains a new binding of the +// given kind onto the stack. +// Throw a verification error if the stack overflows. +// +void VerificationEnv::push1or2(BindingKind bk) +{ + // Note: bkAddr will be outlawed here once we start to distinguish among types of + // pointers. + assert(bk == bkVoid || bk == bkInt || bk == bkFloat || bk == bkAddr || bk == bkLong || bk == bkDouble); + InitBinding b(bk); + if (isTwoWordKind(bk)) + push2(b); + else + push1(b); +} + + +// +// Push the context of the given subroutine onto the list of currently active +// contexts. Initialize that context to record all bindings written to this +// environment after this enterSubroutine call. +// +// Throw a verification error if the given subroutine already is on the list +// of active contexts. This rejects bytecode programs that call subroutines +// recursively. It also rejects some "valid" bytecode programs that do not call +// subroutines recursively (for instance, if subroutine A exits via a jump +// instead of a ret and then calls subroutine A again), but, fortunately, the +// current definition of the Java language does not generate such programs. +// (Specifically, each Java try block has a single entry point and the finally +// handler -- say, subroutine A -- for that try block is outside that block. In +// order for subroutine A to be called again, execution must proceed again +// through the entry point of the try block, and we know that at that point +// subroutine A is not one of the active contexts.) +// +void VerificationEnv::enterSubroutine(Subroutine s) +{ + assert(live() && s && common.bindingPool); + if (Context::find(activeContexts, s)) + verifyError(VerifyError::jsrNestingError); + + Context *c = new(common.envPool) Context(s, common); + c->next = activeContexts; + activeContexts = c; +} + + +// +// Pop the context of the given subroutine from the list of currently active +// contexts, and replace environment bindings that were not modified by the +// subroutine by their contenst from entryEnv, which represents the environment +// as it was just before entry to the subroutine. Also pop any contexts more +// recent than that of the given subroutine -- these subroutines apparently +// exited using a jump instead of a ret. +// +// Throw a verification error if the subroutine is not on the list of active +// contexts, which indicates that there is some program path along which this +// ret could be reached without this subroutine having been called first. +// +void VerificationEnv::exitSubroutine(Subroutine s, const VerificationEnv &entryEnv) +{ + assert(live() && s && entryEnv.live() && common.bindingPool); + Context *c = Context::find(activeContexts, s); + if (!c) + verifyError(VerifyError::jsrNestingError); + activeContexts = c->next; + + // Replace unmodified environment bindings. + Uint32 nSlots = sp; + const Binding *srcBindings = entryEnv.bindings; + Binding *dstBindings = bindings; + for (Uint32 slot = 0; slot != nSlots; slot++) + if (!c->isModified(slot)) + dstBindings[slot] = srcBindings[slot]; +} + + +// +// Intersect the given VerificationEnv (which must be live) into this +// VerificationEnv, which must also be live. The two environments may have +// different sets of active subroutine contexts, in which case leave the maximal +// common set (for instance, intersecting a->b with b yields b, while +// intersecting a->b->d->e with a->c->d yields a->d). Because each subroutine has +// only one entry point and cannot be recursive, we don't have to worry about +// cases such as intersecting a->b with b->a -- nesting of subroutines follows a +// partial order. +// +// Return true if this VerificationEnv changed. +// +// Throw a verification error if the environments have different stack depths. +// +bool VerificationEnv::meet(const VerificationEnv &env) +{ + assert(live() && env.live() && common.bindingPool); + Uint32 nSlots = sp; + if (nSlots != env.sp) + verifyError(VerifyError::bytecodeStackDynamic); + bool changed = false; + + // Merge context lists + Context **dstContextPtr = &activeContexts; + Context *srcContext = env.activeContexts; + Context *dstContext; + while ((dstContext = *dstContextPtr) != 0) { + Context *c = Context::find(srcContext, dstContext->subroutine); + if (c) { + srcContext = c; + changed |= dstContext->meet(*c, nSlots); + dstContextPtr = &dstContext->next; + } else { + // Remove this destination context. + *dstContextPtr = dstContext->next; + changed = true; + } + } + + // Merge bindings + const Binding *srcBinding = env.bindings; + Binding *dstBinding = bindings; + Binding *dstBindingsEnd = dstBinding + nSlots; + while (dstBinding != dstBindingsEnd) { + if (*dstBinding != *srcBinding && !dstBinding->hasKind(bkVoid)) { + dstBinding->setVoid(); + changed = true; + } + srcBinding++; + dstBinding++; + } + return changed; +} + + +// +// This VerificationEnv (which must be live) is the entry environment to a ret +// bytecode that returns from subroutine s. That subroutine's context is one +// of the active contexts in this VerificationEnv. Set that context's retReachable +// flag because clearly subroutine s's ret is reachable from here. +// +void VerificationEnv::setRetReachable(Subroutine s) +{ + assert(live()); + Context *c = Context::find(activeContexts, s); + assert(c); + c->retReachable = true; +} + + +// +// Merge the retReachable flags of env into this VerificationEnv. env is the +// environment of a successor of this VerificationEnv's block. If s is non-nil, +// this VerificationEnv's block is a jsr instruction that calls subroutine s, +// and env belongs to s's first block; in this case don't set this environment's +// retReachable flag for s's context because this environment is outside s. +// +// Return true if this VerificationEnv changed. +// +bool VerificationEnv::mergeRetReachables(const VerificationEnv &env, Subroutine s) +{ + assert(live() && env.live()); + bool changed = false; + + Context *srcContext = env.activeContexts; + Context *dstContext = activeContexts; + while (srcContext) { + if (srcContext->retReachable) { + Subroutine srcSubroutine = srcContext->subroutine; + if (srcSubroutine != s) { + dstContext = Context::find(dstContext, srcSubroutine); + assert(dstContext); + if (!dstContext->retReachable) { + dstContext->retReachable = true; + changed = true; + } + } + } + srcContext = srcContext->next; + } + return changed; +} diff --git a/ef/Compiler/FrontEnd/VerificationEnv.h b/ef/Compiler/FrontEnd/VerificationEnv.h new file mode 100644 index 000000000000..9d029b6a6d33 --- /dev/null +++ b/ef/Compiler/FrontEnd/VerificationEnv.h @@ -0,0 +1,210 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#ifndef VERIFICATIONENV_H +#define VERIFICATIONENV_H + +#include "LocalEnv.h" +#include "Value.h" +#include "ErrorHandling.h" + +struct BytecodeBlock; + +class VerificationEnv +{ + public: + typedef BytecodeBlock *Subroutine; // A subroutine is represented by a pointer to its entry BytecodeBlock + + enum BindingKind + { + bkVoid, // Undefined stack word + bkReturn, // jsr/ret return value + bkInt, // int value + bkFloat, // float value + bkAddr, // Object pointer value + bkLong, // First word of a long value + bkDouble, // First word of a double value + bkSecondWord // Second word of a long or double value + }; + + private: + static const BindingKind valueKindBindingKinds[nValueKinds]; + static const BindingKind typeKindBindingKinds[nTypeKinds]; + public: + static bool isOneWordKind(BindingKind kind) {return (uint)(kind - bkReturn) <= (uint)(bkAddr - bkReturn);} + static bool isTwoWordKind(BindingKind kind) {return (uint)(kind - bkLong) <= (uint)(bkDouble - bkLong);} + static bool isTwoOrSecondWordKind(BindingKind kind) {return (uint)(kind - bkLong) <= (uint)(bkSecondWord - bkLong);} + static BindingKind valueKindToBindingKind(ValueKind kind) {return valueKindBindingKinds[kind];} + static BindingKind typeKindToBindingKind(TypeKind kind) {return typeKindBindingKinds[kind];} + + class Binding + { + BindingKind kind; // Kind of value held in this stack slot + union { + Subroutine subroutine; // If kind is bkReturn, the subroutine that was called + }; + + public: + BindingKind getKind() {return kind;} + bool hasKind(BindingKind k) const {return kind == k;} + bool isOneWord() const {return isOneWordKind(kind);} + bool isTwoWord() const {return isTwoWordKind(kind);} + bool isTwoOrSecondWord() const {return isTwoOrSecondWordKind(kind);} + + bool operator==(const Binding &b2) const {return kind == b2.kind && (kind != bkReturn || subroutine == b2.subroutine);} + bool operator!=(const Binding &b2) const {return !operator==(b2);} + + void setVoid() {kind = bkVoid;} + void setReturn(Subroutine s) {kind = bkReturn; subroutine = s;} + void setKind(BindingKind k) {assert(k != bkReturn); kind = k;} + + Subroutine getSubroutine() const {assert(kind == bkReturn); return subroutine;} + }; + + struct InitBinding: Binding + { + explicit InitBinding(BindingKind kind) {setKind(kind);} + }; + + struct Common: CommonEnv + { + Pool *bindingPool; // Pool used for allocating arrays of bindings and 'modified' arrays inside Contexts; nil if none + + Common(Pool &envPool, Pool *bindingPool, Uint32 nLocals, Uint32 stackSize): + CommonEnv(envPool, 0, nLocals, stackSize), bindingPool(bindingPool) {} + + void setBindingPool(Pool &pool) {assert(!bindingPool); bindingPool = &pool;} + void clearBindingPool() {bindingPool = 0;} // Trashes bindings arrays and 'modified' arrays inside Contexts + }; + + private: + struct Context + { + Context *next; // Link to next outer subroutine context or nil if none + const Subroutine subroutine; // Pointer to the first instruction of a subroutine that was called and not yet returned + private: + char *modified; // Array of nLocals+stackSize bytes; each is set if the corresponding local variable + // or stack temporary has been modified since entry to the subroutine; + public: // undefined if common.bindingPool is nil. + bool retReachable; // True if subroutine's ret is reachable from this block (without going through subroutine's jsr) + #ifdef DEBUG + const Common &common; // Backpointer to information shared among all VerificationEnvs in a graph + #endif + + Context(Subroutine subroutine, const Common &common); + Context(const Context &src, const Common &common); + Context(const Context &src, const Common &common, Function1 &translator); + + void modify(Uint32 slot) {assert(common.bindingPool); modified[slot] = 1;} + bool isModified(Uint32 slot) {assert(common.bindingPool); return modified[slot] != 0;} + bool meet(const Context &src, Uint32 nSlots); + + static Context *find(Context *list, const Subroutine subroutine); + }; + + Common &common; // Backpointer to information shared among all VerificationEnvs in a graph + Binding *bindings; // Array of: + // nLocals local variable bindings + // stackSize stack temporaries' bindings; + // bindings==nil means no information is available yet. + // If common.bindingPool is nil, bindings is either nil or non-nil but does not point to anything. + Uint32 sp; // Stack pointer (index within bindings array of first unused temporary) + // Bindings at indices 0..sp-1 are valid; others are ignored + Context *activeContexts; // Linked list of all currently active subroutines from inner to outer + + static const InitBinding secondWordBinding; // Always contains a bkSecondWord binding + + public: + explicit VerificationEnv(Common &common): common(common), bindings(0) {} + VerificationEnv(const VerificationEnv &env): common(env.common) {copyEnv(env);} + VerificationEnv(const VerificationEnv &env, Function1 &translator); + void operator=(const VerificationEnv &env) {assert(!live()); copyEnv(env);} + void move(VerificationEnv &env); + + void initLive(); + bool live() const {return bindings != 0;} + + private: + void copyEnv(const VerificationEnv &env); + void setSlot(Uint32 slot, const Binding &binding); + + public: + // Local variable operations + const Binding &getLocal1(Uint32 n) const; + const Binding &getLocal2(Uint32 n) const; + void setLocal1(Uint32 n, const Binding &binding); + void setLocal2(Uint32 n, const Binding &binding); + + // Stack operations + Uint32 getSP() const {return sp - common.stackBase;} + void dropAll() {sp = common.stackBase;} + const Binding &pop1(); + const Binding &pop1(BindingKind bk); + void pop2(Binding &binding1, Binding &binding2); + const Binding &pop2(BindingKind bk); + const Binding &pop1or2(BindingKind bk); + void push1(const Binding &binding); + void push1(BindingKind bk); + void push2(const Binding &binding); + void push2(BindingKind bk); + void push2(const Binding &binding1, const Binding &binding2); + void push1or2(BindingKind bk); + + void enterSubroutine(Subroutine s); + void exitSubroutine(Subroutine s, const VerificationEnv &entryEnv); + + bool meet(const VerificationEnv &env); + + bool isRetReachable(Subroutine s); + void setRetReachable(Subroutine s); + bool mergeRetReachables(const VerificationEnv &env, Subroutine s); +}; + + +// --- INLINES ---------------------------------------------------------------- + + +// +// Destructively move the given VerificationEnv (which must have been initialized) +// to this VerificationEnv, which must be uninitialized. The given VerificationEnv is +// left uninitialized. +// +inline void VerificationEnv::move(VerificationEnv &env) +{ + assert(!live() && env.live()); + bindings = env.bindings; + sp = env.sp; + activeContexts = env.activeContexts; + #ifdef DEBUG + env.bindings = 0; + env.activeContexts = 0; + #endif +} + + +// +// Return true if Subroutine s is one of the active contexts in this VerificationEnv +// and that context's retReachable flag is true. +// +inline bool VerificationEnv::isRetReachable(Subroutine s) +{ + assert(live()); + Context *c = Context::find(activeContexts, s); + return c && c->retReachable; +} + +#endif diff --git a/ef/Compiler/Makefile b/ef/Compiler/Makefile new file mode 100644 index 000000000000..c45ff5ebc429 --- /dev/null +++ b/ef/Compiler/Makefile @@ -0,0 +1,56 @@ +#!gmake +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +####################################################################### +# (1) Directory specific info # +####################################################################### + +DEPTH = .. + +DIRS = CodeGenerator FrontEnd PrimitiveGraph Optimizer RegisterAllocator + +SUBMODULES = $(DIRS) + +MODULE_NAME = EF + +NO_PROGRAM_IN_SUBDIRS = 1 +NO_INSTALL_IN_SUBDIRS = 1 + +####################################################################### +# (2) Include "component" configuration information. # +####################################################################### + +include $(DEPTH)/config/config.mk + +####################################################################### +# (3) Include "local" platform-dependent assignments (OPTIONAL). # +####################################################################### + + + +####################################################################### +# (4) Execute "component" rules. (OPTIONAL) # +####################################################################### + +include $(DEPTH)/config/rules.mk + +####################################################################### +# (7) Execute "local" rules. (OPTIONAL). # +####################################################################### + + + diff --git a/ef/Compiler/Optimizer/Makefile b/ef/Compiler/Optimizer/Makefile new file mode 100644 index 000000000000..c7aeb0e85044 --- /dev/null +++ b/ef/Compiler/Optimizer/Makefile @@ -0,0 +1,56 @@ +#!gmake +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +####################################################################### +# (1) Directory specific info # +####################################################################### + +DEPTH = ../.. + + +CPPSRCS = PrimitiveOptimizer.cpp \ + $(NULL) + +LOCAL_EXPORTS = PrimitiveOptimizer.h \ + $(NULL) + +MODULE_NAME = EF + +####################################################################### +# (2) Include "component" configuration information. # +####################################################################### + +include $(DEPTH)/config/config.mk + +####################################################################### +# (3) Include "local" platform-dependent assignments (OPTIONAL). # +####################################################################### + + + +####################################################################### +# (4) Execute "component" rules. (OPTIONAL) # +####################################################################### + +include $(DEPTH)/config/rules.mk + +####################################################################### +# (7) Execute "local" rules. (OPTIONAL). # +####################################################################### + + + diff --git a/ef/Compiler/Optimizer/PrimitiveOptimizer.cpp b/ef/Compiler/Optimizer/PrimitiveOptimizer.cpp new file mode 100644 index 000000000000..3780b475cf5d --- /dev/null +++ b/ef/Compiler/Optimizer/PrimitiveOptimizer.cpp @@ -0,0 +1,57 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#include "PrimitiveOptimizer.h" +#include "ControlGraph.h" + +// +// Quickly trim primitives whose results are not used from the graph. +// This is a quick-and-dirty implementation that misses some opportunities; +// for example, cycles of dead primitives are not detected. +// +void simpleTrimDeadPrimitives(ControlGraph &cg) +{ + cg.dfsSearch(); + ControlNode **dfsList = cg.dfsList; + ControlNode **pcn = dfsList + cg.nNodes; + + while (pcn != dfsList) { + ControlNode &cn = **--pcn; + + // Search the primitives backwards; remove any whose outputs are not used + // and which are not roots. + DoublyLinkedList &primitives = cn.getPrimitives(); + DoublyLinkedList::iterator primIter = primitives.end(); + while (!primitives.done(primIter)) { + Primitive &p = primitives.get(primIter); + primIter = primitives.retreat(primIter); + if (!p.isRoot() && !p.hasConsumers()) + p.destroy(); + } + + // Search the phi nodes backwards; remove any whose outputs are not used. + DoublyLinkedList &phiNodes = cn.getPhiNodes(); + DoublyLinkedList::iterator phiIter = phiNodes.end(); + while (!phiNodes.done(phiIter)) { + PhiNode &n = phiNodes.get(phiIter); + phiIter = phiNodes.retreat(phiIter); + if (!n.hasConsumers()) + n.remove(); + } + } +} + diff --git a/ef/Compiler/Optimizer/PrimitiveOptimizer.h b/ef/Compiler/Optimizer/PrimitiveOptimizer.h new file mode 100644 index 000000000000..15cbaf8b4316 --- /dev/null +++ b/ef/Compiler/Optimizer/PrimitiveOptimizer.h @@ -0,0 +1,25 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#ifndef PRIMITIVEOPTIMIZER_H +#define PRIMITIVEOPTIMIZER_H + +class ControlGraph; + +void simpleTrimDeadPrimitives(ControlGraph &cg); + +#endif diff --git a/ef/Compiler/PrimitiveGraph/.cvsignore b/ef/Compiler/PrimitiveGraph/.cvsignore new file mode 100644 index 000000000000..f0eb9a68785c --- /dev/null +++ b/ef/Compiler/PrimitiveGraph/.cvsignore @@ -0,0 +1 @@ +PrimitiveOperations.* diff --git a/ef/Compiler/PrimitiveGraph/Address.cpp b/ef/Compiler/PrimitiveGraph/Address.cpp new file mode 100644 index 000000000000..c68df6d01de0 --- /dev/null +++ b/ef/Compiler/PrimitiveGraph/Address.cpp @@ -0,0 +1,157 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#include "Value.h" + +#if BATCH_COMPILATION +const ConstructedAddress nullAddr(0); +#endif + + +#ifdef DEBUG_LOG +// +// Print this addr for debugging purposes. +// Return the number of characters printed. +// +int print(LogModuleObject &f, addr a) +{ + if (!a) + return UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("null")); + else + #if BATCH_COMPILATION + return UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("0x%.8X+%d", (size_t)a.getBase(), a.getOffset())); + #else + return UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("0x%.8X", (size_t)a)); + #endif +} +#endif + + +#if BATCH_COMPILATION + inline void *addrToPointer(addr a) {return (char *)a.getBase() + a.getOffset();} +#else + inline void *addrToPointer(addr a) {return a;} +#endif + +// +// Read a field of the given TypeKind at a and store it in v. +// Return true if the value was read successfully or false if it cannot +// be read at compile time. +// +// The current implementation never returns false, but it could be modified +// to do so if needed to support late binding in the batch compiler. +// +bool read(TypeKind tk, addr a, Value &v) +{ + const void *p = addrToPointer(a); + assert(p); + switch (tk) { + case tkVoid: + break; + case tkBoolean: + case tkUByte: + v.i = *static_cast(p); + break; + case tkByte: + v.i = *static_cast(p); + break; + case tkChar: + v.i = *static_cast(p); + break; + case tkShort: + v.i = *static_cast(p); + break; + case tkInt: + v.i = *static_cast(p); + break; + case tkLong: + v.l = *static_cast(p); + break; + case tkFloat: + v.f = *static_cast(p); + break; + case tkDouble: + v.d = *static_cast(p); + break; + case tkObject: + case tkSpecial: + case tkArray: + case tkInterface: + v.a = objectAddress(*static_cast(p)); + break; + } + return true; +} + + +// +// Write v into a field of the given TypeKind at a. +// +void write(TypeKind tk, addr a, const Value &v) +{ + void *p = addrToPointer(a); + assert(p); + switch (tk) { + case tkVoid: + break; + case tkBoolean: + assert((v.i & -2) == 0); + case tkUByte: + case tkByte: + *static_cast(p) = (Uint8)v.i; + break; + case tkChar: + case tkShort: + *static_cast(p) = (Uint16)v.i; + break; + case tkInt: + *static_cast(p) = v.i; + break; + case tkLong: + *static_cast(p) = v.l; + break; + case tkFloat: + *static_cast(p) = v.f; + break; + case tkDouble: + *static_cast(p) = v.d; + break; + case tkObject: + case tkSpecial: + case tkArray: + case tkInterface: + *static_cast(p) = addrToPointer(v.a); + break; + } +} + +// +// If known, return the type of the object at the given address. If not known, +// return nil. +// +Type *objectAddressType(addr a) +{ + if (!a) + return 0; + + Value type; + assert(objectTypeOffset == 0); + if (!read(tkObject, a, type)) + return 0; + return &addressAsType(type.a); +} + diff --git a/ef/Compiler/PrimitiveGraph/Address.h b/ef/Compiler/PrimitiveGraph/Address.h new file mode 100644 index 000000000000..291098abacd0 --- /dev/null +++ b/ef/Compiler/PrimitiveGraph/Address.h @@ -0,0 +1,184 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#ifndef ADDRESS_H +#define ADDRESS_H + +#include "JavaObject.h" +#include "LogModule.h" + +union Value; + +// +// If we do batch compilation, we may not be able to emit code that references raw physical +// addresses because they may move around by the time the generated code is loaded. +// Thus, in a batch compiler we represent immediate pointers by Address structures instead +// of ptr constants. The addr type is an abstraction for either an Address (if batch- +// compiling) or a ptr (if JIT-compiling). +// +#if BATCH_COMPILATION +// +// The value of an Address is reloc(base)+offset. It is not legal to construct an Address +// whose offset is outside the base object's bounds. Two Addresses are comparable for inequality +// only if their base is the same. +// +class Address +{ + obj base; // Base address that will be relocated by loader + Int32 offset; // Offset from relocated base + + public: + obj getBase() const {return base;} + Int32 getOffset() const {return offset;} + + void setBase(obj b) {base = b; offset = 0;} + void setBase(obj b, Int32 o) {base = b; offset = o;} + + bool operator!() const {return base == 0 && offset == 0;} + bool operator==(const Address &a) const {return base == a.base && offset == a.offset;} + bool operator!=(const Address &a) const {return base != a.base || offset != a.offset;} + bool operator<(const Address &a) const {assert(base == a.base); return offset < a.offset;} + bool operator<=(const Address &a) const {assert(base == a.base); return offset <= a.offset;} + bool operator>(const Address &a) const {assert(base == a.base); return offset > a.offset;} + bool operator>=(const Address &a) const {assert(base == a.base); return offset >= a.offset;} + + void operator+=(Int32 d) {offset += d;} + void operator-=(Int32 d) {offset += d;} // BUG + + Address operator+(Int32 d) const {Address a; a.setBase(base, offset + d); return a;} + Address operator-(Int32 d) const {Address a; a.setBase(base, offset - d); return a;} + Int32 operator-(const Address &a) const {assert(base == a.base); return offset - a.offset;} +}; + +typedef Address addr; + +// Private structure for nullAddr. +struct ConstructedAddress: Address +{ + ConstructedAddress(obj b) {setBase(b);} + ConstructedAddress(obj b, Int32 o) {setBase(b, o);} +}; +extern const ConstructedAddress nullAddr; + +#else + +typedef ptr addr; +#define nullAddr ((ptr)0) + +#endif + +#ifdef DEBUG_LOG +int print(LogModuleObject &f, addr a); +#endif +inline addr staticAddress(void *s); +inline addr functionAddress(void (*f)()); +inline addr objectAddress(cobj o); +inline obj addressObject(addr a); +inline void* addressFunction(addr a); +bool read(TypeKind tk, addr a, Value &v); +void write(TypeKind tk, addr a, const Value &v); +inline Type &addressAsType(addr a); +Type *objectAddressType(addr a); +addr lookupInterface(Type &type, Uint32 interfaceIndex); + + +// --- INLINES ---------------------------------------------------------------- + +// +// Return the addr, possibly with relocation information, of the given static variable. +// +inline addr staticAddress(void *s) +{ + #if BATCH_COMPILATION + Address a; + a.setBase(reinterpret_cast(s)); + return a; + #else + return reinterpret_cast(s); + #endif +} + + +// +// Return the addr, possibly with relocation information, of the given function. +// +inline addr functionAddress(void (*f)()) +{ + #if BATCH_COMPILATION + Address a; + a.setBase(reinterpret_cast(f)); + return a; + #else + return reinterpret_cast(f); + #endif +} + + +// +// Return the addr, possibly with relocation information, of the given object. +// +inline addr objectAddress(cobj o) +{ + #if BATCH_COMPILATION + Address a; + a.setBase(const_cast(o)); + return a; + #else + return reinterpret_cast(const_cast(o)); + #endif +} + + +// +// Return the object at the given addr (which must have been obtained by objectAddress). +// +inline obj addressObject(addr a) +{ + #if BATCH_COMPILATION + assert(a.getOffset() == 0); + return a.getBase(); + #else + return reinterpret_cast(a); + #endif +} + + +// +// Return the function at the given addr (which must have been obtained by objectAddress). +// +inline void* addressFunction(addr a) +{ + #if BATCH_COMPILATION + assert(a.getOffset() == 0); + return (void*) a.getBase(); + #else + return reinterpret_cast(a); + #endif +} + + +// +// Assert that this addr is really a Type and return that Type. +// +inline Type &addressAsType(addr a) +{ + JavaObject *o = addressObject(a); + assert(o); + return asType(*o); +} + +#endif diff --git a/ef/Compiler/PrimitiveGraph/ControlGraph.cpp b/ef/Compiler/PrimitiveGraph/ControlGraph.cpp new file mode 100644 index 000000000000..547e6a66b763 --- /dev/null +++ b/ef/Compiler/PrimitiveGraph/ControlGraph.cpp @@ -0,0 +1,824 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#include "ControlGraph.h" +#include "GraphUtils.h" +#if defined(DEBUG) && (defined(WIN32) || defined(USE_MESA)) && defined(IGVISUALIZE) +#include "IGVisualizer.h" +#endif +#include + +// ---------------------------------------------------------------------------- +// ControlGraph + + +#ifdef _WIN32 + #pragma warning(disable: 4355) +#endif +// +// Create a new ControlGraph that contains only the BEGIN and END nodes. +// The graph has nArguments incoming arguments whose kinds are given by argumentKinds. +// If hasSelfArgument is true, the first argument is the 'this' argument. +// The graph initially has nMonitorSlots slots allocated for MEnter/MExit pairs. +// The graph starts with no control or data edges. +// +ControlGraph::ControlGraph(Pool &pool, uint nArguments, const ValueKind *argumentKinds, bool hasSelfArgument, Uint32 nMonitorSlots): + pool(pool), + nMonitorSlots(nMonitorSlots), + beginNode(*this), + endNode(*this), + returnNode(0), + recycleBuffer(0), + dfsList(0), + lndList(0) +{ + beginNode.setControlBegin(nArguments, argumentKinds, hasSelfArgument, 0); + // asharma - fix this! - bci needs to be set properly here. + endNode.setControlEnd(0); + controlNodes.addFirst(beginNode); + controlNodes.addLast(endNode); +} +#ifdef _WIN32 + #pragma warning(default: 4355) +#endif + + +// +// Create a new ControlNode in this graph and return it. The ControlNode +// will have no ControlExtra; the caller is responsible for creating that. +// +ControlNode &ControlGraph::newControlNode() +{ + ControlNode *cn; + if (recycleBuffer) { + cn = recycleBuffer; + recycleBuffer = 0; + } else + cn = new(pool) ControlNode(*this); + controlNodes.addLast(*cn); + return *cn; +} + + +// +// Assign a unique producerNumber to each outgoing data edge in the ControlGraph. +// The first number assigned will be base; return the last number assigned + 1. +// +Uint32 ControlGraph::assignProducerNumbers(Uint32 base) +{ + for (DoublyLinkedList::iterator ci = controlNodes.begin(); !controlNodes.done(ci); ci = controlNodes.advance(ci)) { + ControlNode &cn = controlNodes.get(ci); + + DoublyLinkedList &phn = cn.getPhiNodes(); + for (DoublyLinkedList::iterator phi = phn.begin(); !phn.done(phi); phi = phn.advance(phi)) + base = phn.get(phi).assignProducerNumbers(base); + + DoublyLinkedList &prn = cn.getPrimitives(); + for (DoublyLinkedList::iterator pri = prn.begin(); !prn.done(pri); pri = prn.advance(pri)) + base = prn.get(pri).assignProducerNumbers(base); + } + return base; +} + + +class ControlDFSHelper +{ + public: + typedef ControlEdge Successor; + typedef ControlNode *NodeRef; + + bool hasBackEdges; // True if the graph contains a cycle + private: + ControlNode **dfsList; // Alias to dfsList from the ControlGraph + + public: + ControlDFSHelper(ControlNode **dfsList): hasBackEdges(false), dfsList(dfsList) {} + + static Successor *getSuccessorsBegin(NodeRef n) {return n->getSuccessorsBegin();} + static Successor *getSuccessorsEnd(NodeRef n) {return n->getSuccessorsEnd();} + static bool isNull(Successor &) {return false;} + static NodeRef getNodeRef(const Successor& s) {return &s.getTarget();} + static bool isMarked(NodeRef n) {return n->dfsNum != ControlNode::unmarked;} + static bool isUnvisited(NodeRef n) {return n->dfsNum == ControlNode::unvisited;} + static bool isNumbered(NodeRef n) {return n->dfsNum >= 0;} + static void setMarked(NodeRef n) {n->dfsNum = ControlNode::unvisited;} + static void setVisited(NodeRef n) {n->dfsNum = ControlNode::unnumbered;} + void setNumbered(NodeRef n, Int32 i) {assert(i >= 0); n->dfsNum = i; dfsList[i] = n;} + void notePredecessor(NodeRef) {} + void noteIncomingBackwardEdge(NodeRef) {hasBackEdges = true;} +}; + + +// +// Initialize the dfsNum field of each ControlNode in this ControlGraph +// to the ControlNode's serial number. Also set up dfsList so that +// if n is ControlNode c's dfsNum, then dfsList[n] = &c. +// +#include "NativeFormatter.h" +void ControlGraph::dfsSearch() +{ + // Initialize the ControlNodes' dfsNum fields. + Uint32 maxNControlNodes = 0; + for (DoublyLinkedList::iterator i = controlNodes.begin(); !controlNodes.done(i); i = controlNodes.advance(i)) { + controlNodes.get(i).dfsNum = ControlNode::unmarked; + maxNControlNodes++; + } + + // Count the ControlNodes reachable from beginNode. + dfsList = new(pool) ControlNode *[maxNControlNodes]; + ControlDFSHelper dfsHelper(dfsList); + ControlEdge beginEdge; + ControlEdge endEdge; + beginEdge.setTarget(beginNode); + endEdge.setTarget(endNode); + SearchStackEntry *searchStack = new SearchStackEntry[maxNControlNodes]; + nNodes = graphSearchWithEnd(dfsHelper, beginEdge, endEdge, maxNControlNodes, searchStack); + + // Now do the actual depth-first search. + depthFirstSearchWithEnd(dfsHelper, beginEdge, endEdge, nNodes, searchStack); + hasBackEdges = dfsHelper.hasBackEdges; +#ifndef WIN32 // ***** Visual C++ has a bug in the code for delete[]. + delete[] searchStack; +#endif +} + + +#include "CodeGenerator.h" + +struct LoopSearchDepthInfo +{ + Uint32 begin; + Uint32 count; +}; + +void ControlGraph::lndSearch() +{ + Uint32 i; + + if (!dfsListIsValid()) + dfsSearch(); + + lndList = new(pool) ControlNode *[nNodes]; + + // Initialize the control node's depth info. + for (i = 0; i < nNodes; i++) + { + dfsList[i]->loopId = 0; + dfsList[i]->loopDepth = 0; + lndList[i] = dfsList[i]; + } + + if (!hasBackEdges) + return; + + LoopSearchDepthInfo *depthInfo = new LoopSearchDepthInfo[nNodes + 1]; + for (i = 1; i < nNodes + 1; i++) depthInfo[i].count = 0; + depthInfo[0].begin = 0; + depthInfo[0].count = nNodes; + + ControlNode** stack = new ControlNode *[nNodes]; +#ifdef DEBUG + ControlNode** stackEnd = &stack[nNodes]; +#endif + Uint32 loopId = 1; + + for (Uint32 n = 0; n < nNodes; n++) + { + ControlNode* node = dfsList[n]; + ControlEdge* successors_limit = node->getSuccessorsEnd(); + + for (ControlEdge* successor = node->getSuccessorsBegin(); successor != successors_limit; successor++) + if (successor->getTarget().dfsNum < node->dfsNum) // retreating edge. + { + ControlNode** sp = stack; + depthInfo[successor->getTarget().loopDepth++].count--; + depthInfo[successor->getTarget().loopDepth].count++; + successor->getTarget().loopId = ++loopId; + + depthInfo[node->loopDepth++].count--; + depthInfo[node->loopDepth].count++; + node->loopId = loopId; + + *sp++ = node; // push the first element on the stack. + while (sp != stack) + { + const DoublyLinkedList& predecessors = (*--sp)->getPredecessors(); + for (DoublyLinkedList::iterator predecessor = predecessors.begin(); + !predecessors.done(predecessor); + predecessor = predecessors.advance(predecessor)) + { + ControlNode &prev_node = predecessors.get(predecessor).getSource(); + if (prev_node.loopId != loopId) + { + depthInfo[prev_node.loopDepth].count--; + prev_node.loopDepth++; + depthInfo[prev_node.loopDepth].count++; + prev_node.loopId = loopId; + *sp++ = &prev_node; +#ifdef DEBUG + assert(sp < stackEnd); +#endif + } + } + } + } + } + + // summarize + for(Uint32 d = 1; d < nNodes + 1; d++) + depthInfo[d].begin = depthInfo[d - 1].begin + depthInfo[d - 1].count; + + for(Int32 j = nNodes - 1; j >= 0; j--) + { + ControlNode* node = dfsList[j]; + lndList[depthInfo[node->loopDepth].begin++] = node; + node->nVisited = (float) pow(10.0, (int) node->loopDepth); + } + + delete[] stack; + delete[] depthInfo; +} + + +#ifdef DEBUG_LOG +// +// Print a ControlGraph for debugging purposes. +// +void ControlGraph::print(LogModuleObject &f) +{ + dfsSearch(); + + Uint32 nProducers = assignProducerNumbers(1) - 1; + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("ControlGraph %p (%d producers)\n", this, nProducers)); + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("beginNode: ")); + beginNode.printRef(f); + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("\nendNode: ")); + endNode.printRef(f); + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("\nreturnNode: ")); + if (returnNode) + returnNode->printRef(f); + else + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("none")); + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("\nControl nodes:\n\n")); + for (Uint32 i = 0; i != nNodes; i++) + dfsList[i]->printPretty(f, 4); + + bool printedHeader = false; + for (DoublyLinkedList::iterator j = controlNodes.begin(); !controlNodes.done(j); j = controlNodes.advance(j)) { + ControlNode &cn = controlNodes.get(j); + if (cn.dfsNum < 0) { + if (!printedHeader) { + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("Unreachable control nodes:\n\n")); + printedHeader = true; + } + cn.printPretty(f, 4); + } + } + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("End ControlGraph\n\n")); +} +#endif + + +// ---------------------------------------------------------------------------- +// Control flow builders and utilities + + +// +// Return input coerced to a variable. If input is already a variable, return +// its variable. If it is a constant, allocate a PrimConst node in the given +// control node with the constant's value and return that PrimConst. +// +DataNode &makeVariable(const VariableOrConstant &input, ControlNode &cn, + Uint32 bci) +{ + if (input.isConstant()) { + PrimConst &primConst = *new(cn.getPrimitivePool()) + PrimConst(input.getKind(), input.getConstant(), bci); + cn.appendPrimitive(primConst); + return primConst; + } else + return input.getVariable(); +} + + +// +// This method follows a variable's value backwards through a phi node. +// +// Edge e is one of the incoming edges of node cn. input is a variable or +// constant available in cn. If input is a constant, return it unchanged; +// if it is a variable, return the VariableOrConstant representing its value +// in e's source. The result may be different from input when node cn +// contains a phi node that outputs input. +// +// Note that the returned value is a reference and may change if input or +// one of the phi node's inputs changes. +// +const VariableOrConstant &followVariableBack(const VariableOrConstant &input, ControlNode &cn, ControlEdge &e) +{ + assert(&e.getTarget() == &cn); + if (input.isVariable()) { + DataNode &inputVar = input.getVariable(); + if (inputVar.hasCategory(pcPhi) && inputVar.getContainer() == &cn) + return inputVar.nthInput(cn.getPredecessors().index(e)); + } + return input; +} + + +// +// Make a control flow merge of nPredecessors predecessor control nodes into a +// new control node. Return the new control node, which may be the incoming +// control node if nPredecessors is 1. +// The caller is responsible for creating any phi nodes in the new control node; +// joinDataFlows is a convenient way of creating such phi nodes. +// +ControlNode &joinControlFlows(uint nPredecessors, ControlNode *const*predecessors, ControlGraph &cg) +{ + #ifdef DEBUG + assert(nPredecessors != 0); + // Make sure that none of the predecessors is null. + for (uint i = 0; i != nPredecessors; i++) + assert(predecessors[i]); + #endif + + if (nPredecessors == 1) + return *predecessors[0]; + + ControlNode &cn = cg.newControlNode(); + while (nPredecessors--) { + ControlNode &pred = **predecessors++; + pred.setControlBlock(); + cn.addPredecessor(pred.getNormalSuccessor()); + } + return cn; +} + + +// +// Merge a set of variables (inputs) into a single variable (output) on a +// control flow merge entering node cn. This usually generates a phi node +// with the given inputs and output inside cn, but it might just return one +// of the inputs if all of the inputs are the same. +// The inputs must be given in the same order as the predecessors were added +// to cn; the i-th input must be generated by the i-th predecessor. +// +// nPredecessors==1 is a special case to match the optimization inside joinControlFlows: +// if nPredecessors is 1, then the input is simply copied to the output and +// it is guaranteed that no phi nodes will be created in this case. +// +void joinDataFlows(uint nPredecessors, ControlNode &cn, const VariableOrConstant *inputs, VariableOrConstant &output) +{ + assert(nPredecessors != 0); + if (nPredecessors != 1) { + assert(cn.getPredecessors().lengthIs(nPredecessors)); + const VariableOrConstant *inputsLimit = inputs + nPredecessors; + ValueKind kind = inputs->getKind(); + + #ifdef DEBUG + // Assert that all inputs have the same kind. + for (const VariableOrConstant *i = inputs + 1; i != inputsLimit; i++) + assert(i->hasKind(kind)); + #endif + + // Are all of the inputs the same? + for (const VariableOrConstant *input = inputs + 1; input != inputsLimit; input++) + if (*input != *inputs) { + + // At least one input is different. Generate a phi node. + Pool &pool = cn.getPrimitivePool(); + PhiNode &phiNode = *new(pool) PhiNode(nPredecessors, kind, pool); + DoublyLinkedList::iterator pred = cn.getPredecessors().begin(); + for (input = inputs; input != inputsLimit; input++) { + // asharma - fix me + phiNode.addInput(makeVariable(*input, cn.getPredecessors().get(pred).getSource(), 0), pool); + pred = cn.getPredecessors().advance(pred); + } + cn.addPhiNode(phiNode); + output.setVariable(phiNode); + return; + } + } + + // All of the inputs are the same. Just return the first one. + output = inputs[0]; +} + + +// +// cn is a control node that recently acquired an additional predecessor p via +// addPredecessor; that predecessor is now cn's last predecessor. +// consumer is a DataConsumer in cn or one of its control descendants that +// consumes a variable live at the entry to cn. +// +// This method adds or modifies the phi nodes in cn as appropriate so that: +// if control comes into cn via one of its original predecessors, consumer +// will have its original value; +// if control comes into cn from its last predecessor p, consumer will have +// the value given by newSource (which must originate in p or one of its +// control ancestors). +// +// consumer may or may not have a phi node in cn; if it does, then that phi +// node should not have an input corresponding to predecessor p; this method +// will add such an input. +// +// addDataFlow or a similar method should be called on every variable live on +// entry to an existing control node that just acquired a new predecessor. +// +void addDataFlow(ControlNode &cn, DataConsumer &consumer, const VariableOrConstant &newSource) +{ + assert(newSource.hasKind(consumer.getKind())); + + // If consumer is a phi node inside cn, set dn to that phi node; + // if not, set dn to nil. + DataNode *dn = 0; + if (consumer.isVariable()) { + dn = &consumer.getVariable(); + if (!(dn->hasCategory(pcPhi) && dn->getContainer() == &cn)) + dn = 0; + } + + if (dn || consumer != newSource) { + Pool &pool = cn.getPrimitivePool(); + // asharma - fix me + DataNode &newSourceVar = makeVariable(newSource, cn.getPredecessors().last().getSource(), 0); + + if (dn) + // We already have a phi node in cn for this variable. Add that last input. + PhiNode::cast(*dn).addInput(newSourceVar, pool); + else { + // We don't have a phi node in cn for this variable. + // We shall create one. + Uint32 nPredecessors = cn.getPredecessors().length(); + PhiNode &phiNode = *new(pool) PhiNode(nPredecessors, consumer.getKind(), pool); + DoublyLinkedList::iterator pred = cn.getPredecessors().begin(); + while (--nPredecessors) { + // asharma - fix me + phiNode.addInput(makeVariable(consumer, cn.getPredecessors().get(pred).getSource(), 0), pool); + pred = cn.getPredecessors().advance(pred); + } + phiNode.addInput(newSourceVar, pool); + cn.addPhiNode(phiNode); + consumer.clear(); + consumer.setVariable(phiNode); + } + } +} + + +// +// cn is a control node with an incoming edge e. consumer is a DataConsumer +// in cn or one of its control descendants that consumes a variable live at the +// entry to cn. +// +// This method adds or modifies the phi nodes in cn as appropriate so that: +// if control comes into cn via an edge other than e, consumer will have +// the same value it does now; +// if control comes into cn via edge e, consumer will have the value given +// by newSource. +// +// consumer may or may not have a phi node in cn; if it does, then that phi +// node should have an input corresponding to edge e. +// +void changeDataFlow(ControlNode &cn, ControlEdge &e, DataConsumer &consumer, const VariableOrConstant &newSource) +{ + assert(&e.getTarget() == &cn && newSource.hasKind(consumer.getKind())); + + // If consumer is a phi node inside cn, set dn to that phi node; + // if not, set dn to nil. + DataNode *dn = 0; + if (consumer.isVariable()) { + dn = &consumer.getVariable(); + if (!(dn->hasCategory(pcPhi) && dn->getContainer() == &cn)) + dn = 0; + } + + if (dn || consumer != newSource) { + // asharma - fix me + DataNode &newSourceVar = makeVariable(newSource, e.getSource(), 0); + Uint32 eIndex = cn.getPredecessors().index(e); + + if (dn) { + // We already have a phi node in cn for this variable. + DataConsumer &input = PhiNode::cast(*dn).nthInput(eIndex); + input.clear(); + input = newSource; + } else { + // We don't have a phi node in cn for this variable. + // We shall create one. + Pool &pool = cn.getPrimitivePool(); + Uint32 nPredecessors = cn.getPredecessors().length(); + assert(eIndex < nPredecessors); + PhiNode &phiNode = *new(pool) PhiNode(nPredecessors, consumer.getKind(), pool); + DoublyLinkedList::iterator pred = cn.getPredecessors().begin(); + for (Uint32 i = 0; i != nPredecessors; i++) { + // asharma - fix me + phiNode.addInput(i == eIndex ? newSourceVar : makeVariable(consumer, cn.getPredecessors().get(pred).getSource(), 0), pool); + pred = cn.getPredecessors().advance(pred); + } + cn.addPhiNode(phiNode); + consumer.clear(); + consumer.setVariable(phiNode); + } + } +} + + +// +// Return a ControlNode appropriate for placing new DataNodes that should be +// executed immediately after all of this ControlNode's DataNodes if this +// ControlNode's execution leaves along the successor edge with the given number. +// The returned ControlNode may be a new ControlNode spliced into the control +// graph between this ControlNode and its given successor, or it may be an +// existing ControlNode -- either this one or its successor -- if that existing +// ControlNode can be legally used to hold the extra DataNodes. +// +// The edge with the given successorNumber should not be an exception or return edge. +// +ControlNode &obtainSuccessorSite(ControlNode &cn, Uint32 successorNumber) +{ + assert(successorNumber < cn.nNormalSuccessors()); + switch (cn.getControlKind()) { + case ckBlock: + + return cn; // We can add more DataNodes to the end of this node. + case ckBegin: + case ckIf: + case ckSwitch: + case ckExc: + case ckAExc: + case ckCatch: + { + ControlEdge &successorEdge = cn.nthSuccessor(successorNumber); + ControlNode &successor = successorEdge.getTarget(); + assert(hasNormalInputs(successor.getControlKind())); + if (successor.getPredecessors().lengthIs(1)) + // The successor has only one input, so we can add more DataNodes to its beginning. + return successor; + else { + // Make an intermediate block node and insert it between cn and + // its designated successor. + ControlGraph &cg = cn.controlGraph; + ControlNode &intermediate = cg.newControlNode(); + intermediate.setControlBlock(); + intermediate.getNormalSuccessor().substituteTarget(successorEdge); + intermediate.addPredecessor(successorEdge); + return intermediate; + } + } + case ckNone: + case ckEnd: + case ckThrow: + case ckReturn: + break; // These nodes have no normal successors. + } + trespass("Bad control node"); + return cn; +} + + +// +// Return a ControlNode appropriate for placing new DataNodes that should be +// executed immediately after all of this ControlNode's DataNodes if this +// ControlNode's execution leaves along the successor edge with the given number. +// Unlike obtainSuccessorSite, the returned ControlNode has no kind (although it may +// have existing phi nodes and primitives). The caller should set that +// ControlNode's kind and set its normal successor to successor by calling +// successor->addPredecessor(..., *where) using the where value returned from +// this method. +// +// This method disengages successor's phi nodes; the caller should reengage them +// after calling addPredecessor as above. +// +// The returned ControlNode may be a new ControlNode spliced into the control +// graph between this ControlNode and its given successor, or it may be the +// given ControlNode if it can be legally used. +// +ControlNode &insertControlNodeAfter(ControlNode &cn, ControlNode *&successor, DoublyLinkedList::iterator &where, + Uint32 successorNumber) +{ + assert(successorNumber < cn.nNormalSuccessors()); + ControlEdge &successorEdge = cn.nthSuccessor(successorNumber); + successor = &successorEdge.getTarget(); + successor->disengagePhis(); + + switch (cn.getControlKind()) { + case ckBlock: + where = cn.clearControlKindOne(); + return cn; // We can add more DataNodes to the end of this node. + case ckBegin: + case ckIf: + case ckSwitch: + case ckExc: + case ckAExc: + case ckCatch: + { + // Make an intermediate block node and insert it between cn and + // its designated successor. + ControlNode &intermediate = cn.controlGraph.newControlNode(); + where = successorEdge.clearTarget(); + intermediate.addPredecessor(successorEdge); + return intermediate; + } + case ckNone: + case ckEnd: + case ckThrow: + case ckReturn: + break; // These nodes have no normal successors. + } + trespass("Bad control node"); + return cn; +} + + +// +// Insert a new ControlNode immediately before ControlNode cn and return the new +// ControlNode. The returned ControlNode has no kind (although it may +// have existing phi nodes, which are moved there from ControlNode cn). +// The caller should set that ControlNode's kind and optionally set its normal +// successor(s) to point to ControlNode cn. The modified cn is guaranteed to +// have no phi nodes, so the caller can call addPredecessor on cn with impunity. +// +// Any incoming control edges pointing to cn are moved to the new control node. +// It is the caller's responsibility to ensure that that new control node can +// accept these edges (i.e., if cn is an aexc node and the new control node cannot +// accept backward edges, the control graph may become inconsistent). +// +ControlNode &insertControlNodeBefore(ControlNode &cn) +{ + ControlNode &newNode = cn.controlGraph.newControlNode(); + DoublyLinkedList &phiNodes = cn.getPhiNodes(); + cn.disengagePhis(); + newNode.disengagePhis(); + + // Move all predecessors from cn to the newNode. + const DoublyLinkedList &predecessors = cn.getPredecessors(); + DoublyLinkedList::iterator i = predecessors.begin(); + while (!predecessors.done(i)) { + ControlEdge &e = predecessors.get(i); + i = predecessors.advance(i); + e.clearTarget(); + newNode.addPredecessor(e); + } + + // Move all phi nodes from cn to the newNode. + DoublyLinkedList::iterator j = phiNodes.begin(); + while (!phiNodes.done(j)) { + PhiNode &phi = phiNodes.get(j); + j = phiNodes.advance(j); + newNode.movePhiNode(phi); + } + + newNode.reengagePhis(); + cn.reengagePhis(); + return newNode; +} + + +class InsertControlNodeBeforeIteratee: public Function2 +{ + Function1 &f; // Test function passed into insertControlNodeBefore + ControlNode &newNode; // New control node being created by insertControlNodeBefore + const Uint32 nTrueEdges; // Number of true edges + VariableOrConstant uniqueInput; // If all inputs for which f is true seen so far are the same, the value of that input + Uint32 nUniqueInputs; // Number of times uniqueInput has been seen. + PhiNode *builtPhi; // Phi node being build if inputs for which f is true are not all the same + + public: + InsertControlNodeBeforeIteratee(Function1 &f, ControlNode &newNode, Uint32 nTrueEdges): + f(f), newNode(newNode), nTrueEdges(nTrueEdges), nUniqueInputs(0), builtPhi(0) {} + + bool operator()(DataConsumer &input, ControlEdge &e); + DataNode &getInput(); +}; + + +// +// Return true if this input to the phi node should be removed. +// As a side effect keep track of the removed inputs and build a new +// phi node for the new control node that insertControlNodeBefore is creating. +// +bool InsertControlNodeBeforeIteratee::operator()(DataConsumer &input, ControlEdge &e) +{ + if (!f(e)) + return false; + + Pool &pool = newNode.getPrimitivePool(); + if (!builtPhi) { + if (nUniqueInputs == 0) { + uniqueInput = input; + nUniqueInputs = 1; + return true; + } + if (uniqueInput == input) { + nUniqueInputs++; + return true; + } + assert(nUniqueInputs > 0 && nUniqueInputs < nTrueEdges); + builtPhi = new(pool) PhiNode(nTrueEdges, input.getKind(), pool); + while (nUniqueInputs--) + builtPhi->addInput(uniqueInput.getVariable(), pool); + newNode.addPhiNode(*builtPhi); + } + + builtPhi->addInput(input.getVariable(), pool); + return true; +} + + +// +// Return the phi node or the unique input encountered by calls to this iterator. +// +inline DataNode &InsertControlNodeBeforeIteratee::getInput() +{ + if (builtPhi) + return *builtPhi; + assert(nUniqueInputs); + return uniqueInput.getVariable(); +} + + +// +// Insert a new ControlNode immediately before some incoming edges into ControlNode cn +// and return the new ControlNode. This function calls f on each edge coming into cn +// and only relocates the edges for which f returns true. If f returns false for all +// edges coming into cn, this function does nothing and returns nil; if f returns true +// for at least one edge, this function creates and returns one new ControlNode shared +// among all the edges for which f returned true. The returned ControlNode has no kind +// (although it may have existing phi nodes if cn had phi nodes). +// +// The caller should set that ControlNode's kind and set one of its successors to +// point to ControlNode cn by calling addPredecessor once on cn. The caller should +// then call reengagePhis on cn (but not if this function returned nil). This function +// may construct phi nodes inside cn that assume that the edge from the new ControlNode +// to cn will be the last edge, so it is important to call addPredecessor once on cn to +// add that edge before making other predecessor modifications on cn. +// +// Any incoming control edges pointing to cn for which f returned true are moved to the +// new control node. It is the caller's responsibility to ensure that that new control +// node can accept these edges (i.e., if cn is an aexc node and the new control node +// cannot accept backward edges, the control graph may become inconsistent). +// +// Function f should have no side effects and the order in which it is called is not +// guaranteed. +// +ControlNode *insertControlNodeBefore(ControlNode &cn, Function1 &f) +{ + const DoublyLinkedList &predecessors = cn.getPredecessors(); + for (DoublyLinkedList::iterator i = predecessors.begin(); !predecessors.done(i); i = predecessors.advance(i)) + if (f(predecessors.get(i))) { + // We have at least one edge for which f returned true. + // Disengage cn's phis and create the new control node. + ControlNode &newNode = cn.controlGraph.newControlNode(); + DoublyLinkedList &phiNodes = cn.getPhiNodes(); + cn.disengagePhis(); + newNode.disengagePhis(); + + // Count the edges for which f returned true. + DoublyLinkedList::iterator k = i; + Uint32 nTrueEdges = 0; + do { + if (f(predecessors.get(k))) + nTrueEdges++; + k = predecessors.advance(k); + } while (!predecessors.done(k)); + + // Split all phi nodes between cn and the newNode. + DoublyLinkedList::iterator j = phiNodes.begin(); + while (!phiNodes.done(j)) { + PhiNode &phi = phiNodes.get(j); + j = phiNodes.advance(j); + InsertControlNodeBeforeIteratee iter(f, newNode, nTrueEdges); + phi.removeSomeInputs(iter); + phi.addInput(iter.getInput(), cn.getPrimitivePool()); + } + + // Move the predecessors for which f returns true from cn to the newNode. + do { + ControlEdge &e = predecessors.get(i); + i = predecessors.advance(i); + if (f(e)) { + e.clearTarget(); + newNode.addPredecessor(e); + } + } while (!predecessors.done(i)); + + newNode.reengagePhis(); + return &newNode; + } + return 0; +} diff --git a/ef/Compiler/PrimitiveGraph/ControlGraph.h b/ef/Compiler/PrimitiveGraph/ControlGraph.h new file mode 100644 index 000000000000..b9d716aaaf30 --- /dev/null +++ b/ef/Compiler/PrimitiveGraph/ControlGraph.h @@ -0,0 +1,141 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#ifndef CONTROLGRAPH_H +#define CONTROLGRAPH_H + +#include "ControlNodes.h" +#include "LogModule.h" + +struct MethodDescriptor; + +class ControlGraph +{ + public: + Pool &pool; // Memory pool from which this graph is allocated + DoublyLinkedList controlNodes; // List of control nodes in this graph + Uint32 nMonitorSlots; // Number of slots needed for MEnter/MExit primitives in this graph + + private: + ControlNode beginNode; // The Begin node + ControlNode endNode; // The End node + ControlNode *returnNode; // The graph's Return node or nil if none + ControlNode *recycleBuffer; // A free ControlNode ready for reuse or nil if none + + public: + ControlNode** dfsList; // List of control nodes in depth first search order. + Uint32 nNodes; + bool hasBackEdges; + ControlNode** lndList; // List of control nodes in loop nesting depth order. + + ControlGraph(Pool &pool, uint nArguments, const ValueKind *argumentKinds, bool hasSelfArgument, Uint32 nMonitorSlots); + private: + ControlGraph(const ControlGraph &); // Copying forbidden + void operator=(const ControlGraph &); // Copying forbidden + public: + + ControlNode &newControlNode(); + void recycle(ControlNode &cn); + + ControlNode &getBeginNode() {return beginNode;} + ControlNode &getEndNode() {return endNode;} + ControlNode *getReturnNode() const {return returnNode;} + void setReturnNode(ControlNode &cr) {assert(!returnNode && cr.hasControlKind(ckReturn)); returnNode = &cr;} + Uint32 assignProducerNumbers(Uint32 base); + + bool dfsListIsValid() const {return dfsList != 0;} + void dfsSearch(); + bool lndListIsValid() const {return lndList != 0;} + void lndSearch(); + + #ifdef DEBUG_LOG + void print(LogModuleObject &f); + #endif + +#ifdef DEBUG + void validate(); // verifies that this control graph is 'correct' +#endif + +}; + + +// ---------------------------------------------------------------------------- +// Control flow builders and utilities + + +DataNode &makeVariable(const VariableOrConstant &input, ControlNode &cn, Uint32 bci); +const VariableOrConstant &followVariableBack(const VariableOrConstant &input, ControlNode &cn, ControlEdge &e); + +ControlNode &joinControlFlows(uint nPredecessors, ControlNode *const*predecessors, ControlGraph &cg); +void joinDataFlows(uint nPredecessors, ControlNode &cn, const VariableOrConstant *inputs, VariableOrConstant &output); +void addDataFlow(ControlNode &cn, DataConsumer &consumer, const VariableOrConstant &newSource); +void changeDataFlow(ControlNode &cn, ControlEdge &e, DataConsumer &consumer, const VariableOrConstant &newSource); + +ControlNode &obtainSuccessorSite(ControlNode &cn, Uint32 successorNumber = 0); +ControlNode &insertControlNodeAfter(ControlNode &cn, ControlNode *&successor, DoublyLinkedList::iterator &where, + Uint32 successorNumber = 0); +ControlNode &insertControlNodeBefore(ControlNode &cn); +ControlNode *insertControlNodeBefore(ControlNode &cn, Function1 &f); + + +// --- INLINES ---------------------------------------------------------------- + +// +// Initialize a ControlNode. +// Don't call this directly; call ControlGraph::newControlNode instead. +// +inline ControlNode::ControlNode(ControlGraph &cg): + noRecycle(false), + controlGraph(cg), + generation(0), + liveAtBegin(cg.pool), + liveAtEnd(cg.pool), + workingNode(false) +{ + #if defined(DEBUG) || defined(DEBUG_LOG) + controlKind = ckNone; + #endif + #ifdef DEBUG + successorsBegin = 0; + successorsEnd = 0; + phisDisengaged = 0; + #endif +} + + +// +// Return the pool for allocating primitives in this control node. +// +inline Pool &ControlNode::getPrimitivePool() const +{ + return controlGraph.pool; +} + + +// +// Recycle the ControlNode so that it can be reused by newControlNode. +// The given ControlNode must satisfy the empty() method; have no predecessors, +// instructions, extra, or generation; and belong to this ControlGraph. +// +inline void ControlGraph::recycle(ControlNode &cn) +{ + assert(&cn.controlGraph == this); + cn.remove(); + cn.recycle(); + recycleBuffer = &cn; +} +#endif diff --git a/ef/Compiler/PrimitiveGraph/ControlNodes.cpp b/ef/Compiler/PrimitiveGraph/ControlNodes.cpp new file mode 100644 index 000000000000..0af9fa269ba9 --- /dev/null +++ b/ef/Compiler/PrimitiveGraph/ControlNodes.cpp @@ -0,0 +1,573 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#include "ControlGraph.h" +#include "DebugUtils.h" + + +const ControlKindProperties controlKindProperties[nControlKinds] = +{// Incoming--- Outgoing---------- + // Norml? Exc? Norml? Exc? One? + {false, false, false, false, false}, // ckNone + {false, false, true, false, true}, // ckBegin + {false, true, false, false, false}, // ckEnd + {true, false, true, false, true}, // ckBlock + {true, false, true, false, false}, // ckIf + {true, false, true, false, false}, // ckSwitch + {true, false, true, true, true}, // ckExc + {true, false, false, true, false}, // ckThrow + {true, false, true, true, true}, // ckAExc + {false, true, true, false, true}, // ckCatch + {true, false, false, false, false} // ckReturn +}; + + +#ifdef DEBUG_LOG +const char controlKindNames[][8] = +{ + "????", // ckNone + "Begin", // ckBegin + "End", // ckEnd + "Block", // ckBlock + "If", // ckIf + "Switch", // ckSwitch + "Exc", // ckExc + "Throw", // ckThrow + "AExc", // ckAExc + "Catch", // ckCatch + "Return" // ckReturn +}; + + +// +// Print the name of the ControlKind onto the output stream f. +// Return the number of characters printed. +// +int print(LogModuleObject &f, ControlKind ck) +{ + return UT_OBJECTLOG(f, PR_LOG_ALWAYS, ((uint)ck > ckReturn ? "????" : controlKindNames[ck])); +} +#endif + + +// ---------------------------------------------------------------------------- +// ControlNode::BeginExtra + +// +// Initialize a new BeginExtra record with nArguments incoming arguments whose +// kinds are given by argumentKinds. If the method isn't static, the this +// parameter must be listed as an incoming argument in the argumentKinds array +// as well and hasSelfArgument must be set to true; otherwise hasSelfArgument +// should be false. +// Allocate additional storage for the arguments array from the given pool. +// +ControlNode::BeginExtra::BeginExtra(ControlNode &controlNode, Pool &pool, + uint nArguments, + const ValueKind *argumentKinds, + bool hasSelfArgument, Uint32 bci) + : nArguments(nArguments), + arguments(nArguments ? new(pool) PrimArg[nArguments] : 0) +{ + initialMemory.initOutgoingEdge(vkMemory, true); + controlNode.appendPrimitive(initialMemory); + PrimArg *a = arguments; + bool isThis = hasSelfArgument; + for (uint i = 0; i != nArguments; i++) { + // Set the bytecode index. This can't be done in the constructor + // because initializers can't be specified for an array of objects + // allocated through the new operator + a->setBytecodeIndex(bci); + a->initOutgoingEdge(*argumentKinds++, isThis); + isThis = false; + controlNode.appendPrimitive(*a); + a++; + } +} + + +// ---------------------------------------------------------------------------- +// ControlNode::ReturnExtra + +// +// Initialize a new ReturnExtra record with nResults results whose kinds are +// given in the resultKinds array. +// Allocate additional storage for the results array from the given pool. +// +ControlNode::ReturnExtra::ReturnExtra(ControlNode &controlNode, Pool &pool, + uint nResults, + const ValueKind *resultKinds, Uint32 bci) + : nResults(nResults), results((PrimResult * const)pool.allocate(nResults * sizeof(PrimResult))) +{ + uint i; + PrimResult *r = results; + for (i = 0; i != nResults; i++) { + new (r) PrimResult(bci); + r->setResultKind(*resultKinds++); + controlNode.appendPrimitive(*r++); + } +} + + +// ---------------------------------------------------------------------------- +// ControlNode + +Uint32 ControlNode::nextGeneration = 1; + + +#ifdef DEBUG +// +// Return true if each phi node in this ControlNode has the same number of +// inputs as this ControlNode has predecessors. +// If phisDisengaged is nonzero, always return true. +// +bool ControlNode::phisConsistent() const +{ + if (phisDisengaged) + return true; + Uint32 nPredecessors = predecessors.length(); + for (DoublyLinkedList::iterator i = phiNodes.begin(); !phiNodes.done(i); i = phiNodes.advance(i)) + if (phiNodes.get(i).nInputs() != nPredecessors) + return false; + return true; +} +#endif + + +// +// Return the number of successor edges that are not exception or return edges. +// Multiple edges to the same node are counted multiple times. +// +Uint32 ControlNode::nNormalSuccessors() const +{ + switch (controlKind) { + case ckEnd: + case ckThrow: + case ckReturn: + return 0; + case ckBegin: + case ckBlock: + case ckExc: + case ckAExc: + case ckCatch: + return 1; + case ckIf: + return 2; + case ckSwitch: + return nSuccessors(); + case ckNone:; + } + trespass("Bad control node"); + return 0; +} + + +// +// Allocate exactly one successor for this ControlNode. +// +void ControlNode::setOneSuccessor() +{ + ControlEdge *successor = new(getPrimitivePool()) ControlEdge; + successor->setSource(*this); + setSuccessors(successor, successor + 1); +} + + +// +// Allocate n successors for this ControlNode. +// +void ControlNode::setNSuccessors(Uint32 n) +{ + ControlEdge *successors = new(getPrimitivePool()) ControlEdge[n]; + ControlEdge *successors2 = successors; + while (n--) + successors2++->setSource(*this); + setSuccessors(successors, successors2); +} + + +// +// Use n preallocated successors for this ControlNode. +// Make the successors's sources point to this ControlNode. +// +inline void ControlNode::setNSuccessors(Uint32 n, ControlEdge *successors) +{ + setSuccessors(successors, successors + n); + while (n--) + successors++->setSource(*this); +} + + +// +// Unset the control node's kind so that the node can get a new kind. +// The primitives and phi nodes remain attached to this control node, but +// the control kind-specific data disappears. +// The successor ControlEdges' targets must have been initialized prior +// to calling this method; this method clears them. +// +void ControlNode::clearControlKind() +{ + #if defined(DEBUG) || defined(DEBUG_LOG) + controlKind = ckNone; + #endif + for (ControlEdge *e = successorsBegin; e != successorsEnd; e++) + e->clearTarget(); + #ifdef DEBUG + successorsBegin = 0; + successorsEnd = 0; + #endif +} + + +// +// Unset the control node's kind so that the node can get a new kind. +// The primitives and phi nodes remain attached to this control node, but +// the control kind-specific data disappears. +// The successor ControlEdges' targets must have been initialized prior +// to calling this method; this method clears them. +// +// Return a location suitable for relinking another edge to the control +// node's normal outgoing edge's target in place of the existing normal +// outgoing edge without disturbing the order of that target's +// predecessors (changing that order would disrupt the target's phi nodes). +// This control node must have exactly one normal outgoing edge. +// +DoublyLinkedList::iterator ControlNode::clearControlKindOne() +{ + assert(hasOneNormalOutgoingEdge(getControlKind()) && successorsBegin); + #if defined(DEBUG) || defined(DEBUG_LOG) + controlKind = ckNone; + #endif + ControlEdge *e = successorsBegin; + DoublyLinkedList::iterator where = e->clearTarget(); + while (++e != successorsEnd) + e->clearTarget(); + #ifdef DEBUG + successorsBegin = 0; + successorsEnd = 0; + #endif + return where; +} + + +// +// Designate the ControlNode to be a Begin node with nArguments incoming arguments +// whose kinds are given by argumentKinds. If the method isn't static, the this +// parameter must be listed as an incoming argument in the argumentKinds array +// as well and hasSelfArgument must be set to true; otherwise hasSelfArgument +// should be false. +// Afterwards the caller must initialize the successor ControlEdge's target. +// +void ControlNode::setControlBegin(uint nArguments, + const ValueKind *argumentKinds, + bool hasSelfArgument, Uint32 bci) +{ + assert(controlKind == ckNone); + + setOneSuccessor(); + Pool &pool = getPrimitivePool(); + beginExtra = new(pool) BeginExtra(*this, pool, nArguments, argumentKinds, + hasSelfArgument, bci); + controlKind = ckBegin; +} + + +// +// Designate the ControlNode to be an End node. +// The caller must subsequently initialize the finalMemory's incoming edge. +// +void ControlNode::setControlEnd(Uint32 bci) +{ + assert(controlKind == ckNone); + + ControlEdge e; + setSuccessors(&e, &e); // No successors. + endExtra = new(getPrimitivePool()) EndExtra(bci); + appendPrimitive(endExtra->finalMemory); + controlKind = ckEnd; +} + + +// +// Designate the ControlNode to be a Block node. +// Afterwards the caller must initialize the successor ControlEdge's target. +// +void ControlNode::setControlBlock() +{ + assert(controlKind == ckNone); + + setOneSuccessor(); + controlKind = ckBlock; +} + +// +// Designate the ControlNode to be an If node that tests the given +// conditional. condition must be a DataNode that generates a condition +// value. Afterwards the caller must initialize the two successor +// ControlEdges' targets. +// +void +ControlNode::setControlIf(Condition2 conditional, DataNode &condition, + Uint32 bci) +{ + assert(controlKind == ckNone && condition.hasKind(vkCond)); + + setNSuccessors(2); + PrimControl *pc = new(getPrimitivePool()) + PrimControl(condition2ToIfCond(conditional), bci); + pc->getInput().setVariable(condition); + appendPrimitive(*pc); + controlPrimExtra = pc; + controlKind = ckIf; +} + + +// +// Designate the ControlNode to be a Switch node with nCases cases. selector +// must be a DataNode that generates an int value. Afterwards the caller +// must initialize all the successor ControlEdges' targets. +// +void +ControlNode::setControlSwitch(DataNode &selector, Uint32 nCases, Uint32 bci) +{ + assert(controlKind == ckNone && selector.hasKind(vkInt) && nCases > 0); + + setNSuccessors(nCases); + PrimControl *pc = new(getPrimitivePool()) PrimControl(poSwitch, bci); + pc->getInput().setVariable(selector); + appendPrimitive(*pc); + controlPrimExtra = pc; + controlKind = ckSwitch; +} + + +// +// Designate the ControlNode to be an Exc, Throw, or AExc node, depending on +// the given ControlKind. The node will have nHandlers exception handlers +// with that many filter classes listed in the handlerFilters array. The +// exception classes are considered in order when dispatching an exception, +// so their order is significant. If the ControlNode will be an Exc or Throw +// node, tryPrimitive must be a primitive located inside this node that can +// throw an exception; if the ControlNode will be an AExc node, tryPrimitive +// must be nil. successors must be a preallocated array of nHandlers or +// nHandlers+1 successor edges, including the edge referring to the normal +// successor for Exc and AExc nodes. +// +// The caller must initialize all the successor ControlEdges' targets either +// before or after calling this method. +// +void +ControlNode::setControlException(ControlKind ck, Uint32 nHandlers, + const Class **handlerFilters, + Primitive *tryPrimitive, + ControlEdge *successors) +{ + assert(controlKind == ckNone && + hasExceptionOutgoingEdges(ck) && nHandlers > 0 && + (tryPrimitive == 0) == (ck == ckAExc)); + + bool hasNormalExit = ck != ckThrow; + setNSuccessors(hasNormalExit + nHandlers, successors); + + ExceptionExtra *ee; + if (tryPrimitive) + ee = new(getPrimitivePool()) TryExtra(tryPrimitive); + else + ee = new(getPrimitivePool()) ExceptionExtra; + ee->nHandlers = nHandlers; + ee->handlerFilters = handlerFilters; + exceptionExtra = ee; + controlKind = ck; +} + + +// +// Designate the ControlNode to be a Catch node. Return the node's PrimCatch +// primitive. Afterwards the caller must initialize the successor +// ControlEdge's target. +// +PrimCatch & +ControlNode::setControlCatch(Uint32 bci) +{ + assert(controlKind == ckNone); + + setOneSuccessor(); + catchExtra = new(getPrimitivePool()) CatchExtra(bci); + PrimCatch &cause = catchExtra->cause; + prependPrimitive(cause); + controlKind = ckCatch; + return cause; +} + + +// +// Designate the ControlNode to be a Return node with nResults results whose +// kinds are given in the resultKinds array. Afterwards the caller must +// initialize the successor ControlEdge's target to point to the End node and +// call getReturnExtra()[...].getInput() = ... for each result +// +void ControlNode::setControlReturn(uint nResults, + const ValueKind *resultKinds, Uint32 bci) +{ + assert(controlKind == ckNone); + + setOneSuccessor(); + Pool &pool = getPrimitivePool(); + returnExtra = new(pool) ReturnExtra(*this, pool, nResults, resultKinds, + bci); + controlKind = ckReturn; + controlGraph.setReturnNode(*this); +} + + +// +// Move the predecessors from the given list to this ControlNode. +// This ControlNode must have no current predecessors. +// On return, the src list will be made empty because the ControlEdges can +// be linked into only one DoublyLinkedList at a time. +// +void ControlNode::movePredecessors(DoublyLinkedList &src) +{ + assert(phisDisengaged || phiNodes.empty()); + predecessors.move(src); + for (DoublyLinkedList::iterator i = predecessors.begin(); + !predecessors.done(i); + i = predecessors.advance(i)) + predecessors.get(i).setTarget(*this); +} + + + +#ifdef DEBUG +// +// Temporary routine to print out the list of instructions which are valid after scheduling. +// +void ControlNode::printScheduledInstructions(LogModuleObject &f) +{ + for(InstructionList::iterator i = instructions.begin(); !instructions.done(i); i = instructions.advance(i)) + { + instructions.get(i).getPrimitive()->printPretty(f, 2); + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("\t\t")); + instructions.get(i).printDebug(f); + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("\n")); + } +} +#endif + + +#ifdef DEBUG_LOG +// +// Print a reference to this ControlNode for debugging purposes. +// Return the number of characters printed. +// +int ControlNode::printRef(LogModuleObject &f) const +{ + if (controlGraph.dfsListIsValid() && dfsNum >= 0) + return UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("N%d", dfsNum)); + else + return UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("N%p", this)); +} + + +// +// Print a ControlNode for debugging purposes. +// f should be at the beginning of a line. +// +void ControlNode::printPretty(LogModuleObject &f, int margin) const +{ + printMargin(f, margin); + if (controlKind != ckNone) { + print(f, controlKind); + UT_OBJECTLOG(f, PR_LOG_ALWAYS, (" ")); + } + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("Node ")); + printRef(f); + UT_OBJECTLOG(f, PR_LOG_ALWAYS, (" (%p):\n", this)); + + printMargin(f, margin); + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("Predecessors: ")); + bool printSeparator = false; + for (DoublyLinkedList::iterator i = predecessors.begin(); !predecessors.done(i); i = predecessors.advance(i)) { + ControlEdge &e = predecessors.get(i); + if (printSeparator) + UT_OBJECTLOG(f, PR_LOG_ALWAYS, (", ")); + printSeparator = true; + assert(&e.getTarget() == this); + e.getSource().printRef(f); + } + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("\n")); + + if (!phiNodes.empty()) { + printMargin(f, margin); + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("Phi nodes:\n")); + for (DoublyLinkedList::iterator i = phiNodes.begin(); !phiNodes.done(i); i = phiNodes.advance(i)) { + PhiNode &n = phiNodes.get(i); + assert(n.getContainer() == this); + n.printPretty(f, margin + 4); + } + } + + if (!primitives.empty()) { + printMargin(f, margin); + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("Primitives:\n")); + for (DoublyLinkedList::iterator i = primitives.begin(); !primitives.done(i); i = primitives.advance(i)) { + Primitive &n = primitives.get(i); + assert(n.getContainer() == this); + n.printPretty(f, margin + 4); + } + } + + if (successorsBegin && successorsEnd) { + ControlEdge *e = successorsBegin; + ControlEdge *eEnd = e + nNormalSuccessors() + hasControlKind(ckReturn); + if (e != eEnd) { + printMargin(f, margin); + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("Successors: ")); + bool printSeparator = false; + while (e != eEnd) { + if (printSeparator) + UT_OBJECTLOG(f, PR_LOG_ALWAYS, (", ")); + printSeparator = true; + assert(&e->getSource() == this); + e->getTarget().printRef(f); + e++; + } + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("\n")); + } + if (e != successorsEnd) { + ExceptionExtra *ee = &getExceptionExtra(); + assert((Uint32)(successorsEnd - e) == ee->nHandlers); + printMargin(f, margin); + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("Exception handlers: ")); + bool printSeparator = false; + const Class **exceptionClass = ee->handlerFilters; + while (e != successorsEnd) { + if (printSeparator) + printMargin(f, margin + 20); + printSeparator = true; + assert(&e->getSource() == this); + (*exceptionClass++)->printRef(f); + UT_OBJECTLOG(f, PR_LOG_ALWAYS, (" -> ")); + e->getTarget().printRef(f); + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("\n")); + e++; + } + } + } + + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("\n")); +} +#endif diff --git a/ef/Compiler/PrimitiveGraph/ControlNodes.h b/ef/Compiler/PrimitiveGraph/ControlNodes.h new file mode 100644 index 000000000000..f50e32ecc118 --- /dev/null +++ b/ef/Compiler/PrimitiveGraph/ControlNodes.h @@ -0,0 +1,512 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#ifndef CONTROLNODES_H +#define CONTROLNODES_H + +#include "Instruction.h" +#include "ClassWorld.h" +#include "Multiset.h" +#include "FastBitSet.h" +#include "CheckedUnion.h" + +class ControlGraph; + +class ControlEdge: public DoublyLinkedEntry // Links to other ControlEdges that go to the same target +{ + ControlNode *source; // The node that owns this outgoing control edge (in DEBUG versions nil if not explicitly set) + ControlNode *target; // The node to which control goes from this node (in DEBUG versions nil if not explicitly set) + public: + bool longFlag; // States whether the edge is a short or long edge (for ControlNodeScheduler). + + #ifdef DEBUG + ControlEdge(): source(0), target(0) {} + #endif + + ControlNode &getSource() const {assert(source); return *source;} + ControlNode &getTarget() const {assert(target); return *target;} + void setSource(ControlNode &n) {assert(!source); source = &n;} // For use by ControlNode only. + void setTarget(ControlNode &n) {assert(!target); target = &n;} // For use by ControlNode only. + DoublyLinkedList::iterator clearTarget(); + void substituteTarget(ControlEdge &src); + #ifdef DEBUG + bool hasTarget() const {return target != 0;} // Only works in DEBUG versions! + #endif +}; + + +enum ControlKind // NormalIncoming? NormalOutgoing? OneNormalOutgoing? +{ // ExceptionIncoming? ExceptionOutgoing? + ckNone, // no no no no no + ckBegin, // no no yes no yes + ckEnd, // no yes no no no + ckBlock, // yes no yes no yes + ckIf, // yes no yes no no + ckSwitch, // yes no yes no no + ckExc, // yes no yes yes yes + ckThrow, // yes no no yes no + ckAExc, // yes no yes yes yes + ckCatch, // no yes yes no yes + ckReturn // yes no no no no +}; +const nControlKinds = ckReturn + 1; + +struct ControlKindProperties +{ + bool normalInputs BOOL_8; // Does this control node kind allow normal forward or backward incoming edges? + bool exceptionInputs BOOL_8; // Does this control node kind allow exception incoming edges? + bool normalOutgoingEdges BOOL_8; // Does this control node kind allow normal forward or backward outgoing edges? + bool exceptionOutgoingEdges BOOL_8; // Does this control node kind allow exception outgoing edges? + bool oneNormalOutgoingEdge BOOL_8; // Does this control node kind have exactly one forward or backward outgoing edge? +}; + +extern const ControlKindProperties controlKindProperties[nControlKinds]; + +inline bool hasNormalInputs(ControlKind ck) {return controlKindProperties[ck].normalInputs;} +inline bool hasExceptionInputs(ControlKind ck) {return controlKindProperties[ck].exceptionInputs;} +inline bool hasNormalOutgoingEdges(ControlKind ck) {return controlKindProperties[ck].normalOutgoingEdges;} +inline bool hasExceptionOutgoingEdges(ControlKind ck) {return controlKindProperties[ck].exceptionOutgoingEdges;} +inline bool hasOneNormalOutgoingEdge(ControlKind ck) {return controlKindProperties[ck].oneNormalOutgoingEdge;} +inline bool hasTryPrimitive(ControlKind ck) {return ck == ckExc || ck == ckThrow;} + +#ifdef DEBUG_LOG +int print(LogModuleObject &f, ControlKind ck); +#endif + + +class ControlNode: public DoublyLinkedEntry // Links to other ControlNodes in the same graph +{ + public: + struct BeginExtra + { + PrimArg initialMemory; // Initial memory value for this method + const uint nArguments; // Number of incoming arguments + private: + PrimArg *const arguments; // Array of nArguments incoming arguments + public: + + BeginExtra(ControlNode &controlNode, Pool &pool, uint nArguments, + const ValueKind *argumentKinds, bool hasSelfArgument, + Uint32 bci); + + PrimArg &operator[](uint n) const {assert(n < nArguments); return arguments[n];} + }; + + struct EndExtra + { + PrimResult finalMemory; // Final memory value for this method + EndExtra(Uint32 bci) : finalMemory(bci) {}; + }; + + struct ExceptionExtra + { + Uint32 nHandlers; // The last nHandlers successors go to exception handlers. nHandlers is always + // greater than zero, and every exception must be handled (possibly just by + // jumping to the control End node if no other handler applies). + const Class **handlerFilters; // Array of nHandlers exception classes that are handled by the exception handlers + // guarding this control node. These are in the same order as the last nHandlers + // successors. An exception thrown inside this ControlNode will be passed to + }; // the first matching handler. + + struct TryExtra: ExceptionExtra + { + Primitive *tryPrimitive; // The primitive in this control node that can cause exceptions + + explicit TryExtra(Primitive *tryPrimitive): tryPrimitive(tryPrimitive) {} + }; + + struct CatchExtra + { + PrimCatch cause; // Exception that was thrown here + CatchExtra(Uint32 bci) : cause(bci) {}; + }; + + struct ReturnExtra + { + const uint nResults; // Number of results + private: + PrimResult *const results; // Array of nResults variables containing the results + public: + + ReturnExtra(ControlNode &controlNode, Pool &pool, uint nResults, + const ValueKind *resultKinds, Uint32 bci); + PrimResult &operator[](uint n) const {assert(n < nResults); return results[n];} + }; + + + private: + DoublyLinkedList predecessors; // List of possible predecessors of this control node + ControlEdge *successorsBegin; // Array of edges to successors (in DEBUG versions nil if not explicitly set) + ControlEdge *successorsEnd; // Last element + 1 (in DEBUG versions nil if not explicitly set) + DoublyLinkedList phiNodes; // List of phi nodes inside this control node + DoublyLinkedList primitives; // List of primitives inside this control node + DoublyLinkedList instructions; // List of scheduled instructions inside this control node + + ControlKind controlKind ENUM_8; // The kind of this control node (in DEBUG or DEBUG_LOG versions ckNone if not explicitly set) + bool noRecycle BOOL_8; // True if this node should not be recycled + + #ifdef DEBUG // If zero, the phi nodes correspond to the predecessors list. If nonzero, + Uint32 phisDisengaged; // set to number of nested disengagePhis calls while working on the predecessor + #endif // or phi lists. + + union { // Kind-specific data for: + BeginExtra *beginExtra; // ckBegin + EndExtra *endExtra; // ckEnd + PrimControl *controlPrimExtra; // ckIf, ckSwitch + ReturnExtra *returnExtra; // ckReturn + ExceptionExtra *exceptionExtra; // ckExc (TryExtra *), ckThrow (TryExtra *), ckAExc + CatchExtra *catchExtra; // ckCatch + }; + + public: + ControlGraph &controlGraph; // Graph that contains this control node + Uint32 generation; // General-purpose variable used for marking nodes while traversing the graph + private: + static Uint32 nextGeneration; // Generation value to be used for next graph traversal; each graph traversal + // should increment this by one. + public: + enum {unmarked = -3, unvisited = -2, unnumbered = -1}; + Int32 dfsNum; // Control number assigned by depth-first search + Uint32 loopDepth; // Loop nesting depth + Uint32 loopId; // Temp variable for loop search. + + // ********* Fields below will be moved to RegisterAllocationTemps + Uint32 schedulePos; + Flt32 nVisited; // Approx. the number of time this node is visited (10^loopDepth) + FastBitSet liveAtBegin; // Virtual registers live at begin + FastBitSet liveAtEnd; // Virtual registers live at end + bool hasNewLiveAtEnd; // if true get the new interferences. + bool liveAtBeginIsValid; // if true liveAtBegin has been updated. + // ********* Fields above will be moved to RegisterAllocationTemps + + // ********* Fields below will be moved to FormatterTemps + bool workingNode; // True if this node is seen as a working node for the ControlNodeScheduler. + Uint32 nativeOffset; + // ********* Fields above will be moved to FormatterTemps + + private: + // Temporary fields for matching monitorenters with monitorexits + struct MonitorAnalysisTemps + { + SimpleMultiset *monitorsHeld; // Multiset of objects whose monitors are currently held; nil if not known yet + }; + + // Temporary fields for register allocation + struct RegisterAllocationTemps + { + Uint32 schedulePos; + Flt32 nVisited; // Approx. the number of time this node is visited (10^loopDepth) + FastBitSet liveAtBegin; // Virtual registers live at begin + FastBitSet liveAtEnd; // Virtual registers live at end + bool hasNewLiveAtEnd; // if true get the new interferences. + bool liveAtBeginIsValid; // if true liveAtBegin has been updated. + }; + + // Temporary fields for scheduling and formatting code + struct FormatterTemps + { + bool workingNode; // True if this node is seen as a working node for the ControlNodeScheduler. + Uint32 nativeOffset; + }; + + CheckedUnion3(MonitorAnalysisTemps, RegisterAllocationTemps, FormatterTemps) temps; + + + explicit ControlNode(ControlGraph &cg); // Call ControlGraph::newControlNode instead to create a ControlNode + void recycle(); + public: + + Pool &getPrimitivePool() const; + + #ifdef DEBUG + bool getPhisDisengaged() const {return phisDisengaged || phiNodes.empty();} + bool phisConsistent() const; + #endif + void disengagePhis() {assert(phisConsistent()); DEBUG_ONLY(phisDisengaged++);} + void reengagePhis() {assert(phisDisengaged); DEBUG_ONLY(phisDisengaged--); assert(phisConsistent());} + + const DoublyLinkedList &getPredecessors() const {return predecessors;} + void addPredecessor(ControlEdge &e) {assert(phisDisengaged || phiNodes.empty()); e.setTarget(*this); predecessors.addLast(e);} + void addPredecessor(ControlEdge &e, DoublyLinkedList::iterator where); + void movePredecessors(DoublyLinkedList &src); + + ControlEdge *getSuccessorsBegin() const {assert(successorsBegin); return successorsBegin;} + ControlEdge *getSuccessorsEnd() const {assert(successorsEnd); return successorsEnd;} + Uint32 nSuccessors() const {assert(successorsBegin && successorsEnd); return successorsEnd - successorsBegin;} + Uint32 nNormalSuccessors() const; + ControlEdge &nthSuccessor(Uint32 n) const {assert(n < nSuccessors()); return successorsBegin[n];} + ControlEdge &getNormalSuccessor() const; + ControlEdge &getFalseSuccessor() const; + ControlEdge &getTrueSuccessor() const; + ControlEdge *getSwitchSuccessors() const; + ControlEdge &getReturnSuccessor() const; + void setSuccessors(ControlEdge *newSuccessorsBegin, ControlEdge *newSuccessorsEnd); + private: + void setOneSuccessor(); + void setNSuccessors(Uint32 n); + void setNSuccessors(Uint32 n, ControlEdge *successors); + public: + + DoublyLinkedList &getPhiNodes() {assert(!phisDisengaged); return phiNodes;} + void addPhiNode(PhiNode &p) {assert(phisDisengaged || p.nInputs() == predecessors.length()); p.setContainer(this); phiNodes.addLast(p);} + void movePhiNode(PhiNode &p); + + DoublyLinkedList &getPrimitives() {return primitives;} + void appendPrimitive(Primitive &p) {p.setContainer(this); primitives.addLast(p);} + void prependPrimitive(Primitive &p) {p.setContainer(this); primitives.addFirst(p);} + void movePrimitiveToBack(Primitive &p); + void movePrimitiveToFront(Primitive &p); + + bool hasControlKind(ControlKind ck) const {assert(controlKind != ckNone); return controlKind == ck;} + ControlKind getControlKind() const {assert(controlKind != ckNone); return controlKind;} + void unsetControlKind(); + void clearControlKind(); + DoublyLinkedList::iterator clearControlKindOne(); + void setControlBegin(uint nArguments, const ValueKind *argumentKinds, + bool hasSelfArgument, Uint32 bci); + void setControlEnd(Uint32 bci); + void setControlBlock(); + void setControlIf(Condition2 conditional, DataNode &condition, Uint32 bci); + void setControlSwitch(DataNode &selector, Uint32 nCases, Uint32 bci); + void setControlException(ControlKind ck, Uint32 nHandlers, const Class **handlerFilters, Primitive *tryPrimitive, + ControlEdge *successors); + PrimCatch &setControlCatch(Uint32 bci); + void setControlReturn(uint nResults, const ValueKind *resultKinds, + Uint32 bci); + + BeginExtra &getBeginExtra() const {assert(hasControlKind(ckBegin)); return *beginExtra;} + EndExtra &getEndExtra() const {assert(hasControlKind(ckEnd)); return *endExtra;} + PrimControl &getControlPrimExtra() const {assert(hasControlKind(ckIf) || hasControlKind(ckSwitch)); return *controlPrimExtra;} + ExceptionExtra &getExceptionExtra() const {assert(hasExceptionOutgoingEdges(getControlKind())); return *exceptionExtra;} + TryExtra &getTryExtra() const {assert(hasTryPrimitive(getControlKind())); return *static_cast(exceptionExtra);} + CatchExtra &getCatchExtra() const {assert(hasControlKind(ckCatch)); return *catchExtra;} + ReturnExtra &getReturnExtra() const {assert(hasControlKind(ckReturn)); return *returnExtra;} + + bool empty() const {assert(!phisDisengaged); return !noRecycle && primitives.empty() && phiNodes.empty();} + void inhibitRecycling() {noRecycle = true;} + + InstructionList &getInstructions() {return instructions;} + void addScheduledInstruction(Instruction& i) {instructions.addLast(i);} + bool haveScheduledInstruction(Instruction& i) {return instructions.exists(i);} + void setNativeOffset(Uint32 offset) { nativeOffset = offset; } + Uint32 getNativeOffset() { return nativeOffset; } + static Uint32 getNextGeneration() {return nextGeneration++;} + + #ifdef DEBUG + void printScheduledInstructions(LogModuleObject &f); + void validate(FastBitSet **reachingSet); // perform consistency checks on self + #endif + #ifdef DEBUG_LOG + bool hasControlKind() const {return controlKind != ckNone;} // Only use for debug logging code! Doesn't work in release builds. + int printRef(LogModuleObject &f) const; + void printPretty(LogModuleObject &f, int margin) const; + #endif + + friend class ControlGraph; // ControlGraph can call the ControlNode constructor and recycle +}; + + +// --- INLINES ---------------------------------------------------------------- + + +// +// Unlink this edge from the target to which it is linked. +// Return a location suitable for relinking another edge to the target +// in place of this edge without disturbing the order of the target's +// predecessors (changing that order would disrupt the target's phi nodes). +// +inline DoublyLinkedList::iterator ControlEdge::clearTarget() +{ + assert(target && target->getPhisDisengaged()); + #ifdef DEBUG + target = 0; + #endif + DoublyLinkedList::iterator where = prev; + remove(); + return where; +} + + +// +// Unlink src from the target to which it is linked and link this edge to that target +// in src's place. This edge must not currently have a target. +// +// This is essentially equivalent to, but faster than: +// +// ControlNode &target = src.getTarget(); +// target.disengagePhis(); +// DoublyLinkedList::iterator where = src.clearTarget(); +// target.addPredecessor(*this, where); +// target.reengagePhis(); +// +inline void ControlEdge::substituteTarget(ControlEdge &src) +{ + assert(!target && src.target); + substitute(src); + target = src.target; + #ifdef DEBUG + src.target = 0; + #endif +} + + +// +// Bring the ControlNode back to the state it's in immediately after it's constructed. +// The given ControlNode must satisfy the empty() method and have no predecessors, +// instructions, control kind, or generation. +// +inline void ControlNode::recycle() +{ + assert(!noRecycle && controlKind == ckNone && predecessors.empty() && empty() && instructions.empty() && generation == 0); +} + + +// +// Return the normal outgoing edge of this node. This node must have exactly one +// normal outgoing edge. +// +inline ControlEdge &ControlNode::getNormalSuccessor() const +{ + assert(hasOneNormalOutgoingEdge(getControlKind()) && successorsBegin); + return successorsBegin[0]; +} + + +// +// Return the false outgoing edge of this if node. +// +inline ControlEdge &ControlNode::getFalseSuccessor() const +{ + assert(hasControlKind(ckIf) && successorsBegin); + return successorsBegin[0]; +} + + +// +// Return the true outgoing edge of this if node. +// +inline ControlEdge &ControlNode::getTrueSuccessor() const +{ + assert(hasControlKind(ckIf) && successorsBegin); + return successorsBegin[1]; +} + + +// +// Return the array of nSuccessors() outgoing edges of this switch node. +// +inline ControlEdge *ControlNode::getSwitchSuccessors() const +{ + assert(hasControlKind(ckSwitch) && successorsBegin); + return successorsBegin; +} + + +// +// Return the outgoing edge of this return node. +// +inline ControlEdge &ControlNode::getReturnSuccessor() const +{ + assert(hasControlKind(ckReturn) && successorsBegin); + return successorsBegin[0]; +} + + +// +// Add a new predecessor to this control node in the specified location. +// The node will be added to this control node's list of predecessors after the +// where predecessor, which should be the result of a clearTarget or +// clearControlKindOne call on this node. The where predecessor can be this +// node's root, in which case the new control node will become the first predecessor. +// +inline void ControlNode::addPredecessor(ControlEdge &e, DoublyLinkedList::iterator where) +{ + assert(phisDisengaged || phiNodes.empty()); + e.setTarget(*this); + predecessors.insertAfter(e, where); +} + + +// +// Designate the successors array for this control node. This can be done only +// once afer the control node is created and once after it each time it is +// reset with clearControlKind or one of its cousins. +// +inline void ControlNode::setSuccessors(ControlEdge *newSuccessorsBegin, ControlEdge *newSuccessorsEnd) +{ + assert(!successorsBegin && !successorsEnd && newSuccessorsBegin && newSuccessorsEnd && + newSuccessorsEnd >= newSuccessorsBegin); + successorsBegin = newSuccessorsBegin; + successorsEnd = newSuccessorsEnd; +} + + +// +// Move the phi node so that it becomes the last phi node in this control node. +// The phi node must have been part of some control node (not necessarily this one). +// +inline void ControlNode::movePhiNode(PhiNode &p) +{ + assert(phisDisengaged || p.nInputs() == predecessors.length()); + p.changeContainer(this); + phiNodes.addLast(p); +} + + +// +// Move the primitive so that it becomes the last primitive in this control node. +// The primitive must have been part of some control node (not necessarily this one). +// +inline void ControlNode::movePrimitiveToBack(Primitive &p) +{ + p.changeContainer(this); + primitives.addLast(p); +} + + +// +// Move the primitive so that it becomes the first primitive in this control node. +// The primitive must have been part of some control node (not necessarily this one). +// +inline void ControlNode::movePrimitiveToFront(Primitive &p) +{ + p.changeContainer(this); + primitives.addFirst(p); +} + + +// +// Unset the control node's kind so that the node can get a new kind. +// The primitives and phi nodes remain attached to this control node, but +// the control kind-specific data disappears. +// Unlike clearControlKind, the successor ControlEdges' targets must not +// have been initialized prior to calling this method. +// +inline void ControlNode::unsetControlKind() +{ + #if defined(DEBUG) || defined(DEBUG_LOG) + controlKind = ckNone; + #endif + #ifdef DEBUG + for (ControlEdge *e = successorsBegin; e != successorsEnd; e++) + assert(!e->hasTarget()); + successorsBegin = 0; + successorsEnd = 0; + #endif +} + +#endif diff --git a/ef/Compiler/PrimitiveGraph/Makefile b/ef/Compiler/PrimitiveGraph/Makefile new file mode 100644 index 000000000000..1ff6497314e1 --- /dev/null +++ b/ef/Compiler/PrimitiveGraph/Makefile @@ -0,0 +1,71 @@ +#!gmake +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +####################################################################### +# (1) Directory specific info # +####################################################################### + +DEPTH = ../.. + + +CPPSRCS = Address.cpp \ + ControlNodes.cpp \ + Primitives.cpp \ + SysCalls.cpp \ + PrimitiveBuilders.cpp \ + Value.cpp \ + ControlGraph.cpp \ + PrimitiveGraphVerifier.cpp \ + $(NULL) + +LOCAL_EXPORTS = Address.h \ + ControlGraph.h \ + ControlNodes.h \ + PrimitiveBuilders.h \ + Primitives.h \ + SysCalls.h \ + Value.h \ + $(NULL) + +MODULE_NAME = EF + +####################################################################### +# (2) Include "component" configuration information. # +####################################################################### + +include $(DEPTH)/config/config.mk + +####################################################################### +# (3) Include "local" platform-dependent assignments (OPTIONAL). # +####################################################################### + + + +####################################################################### +# (4) Execute "component" rules. (OPTIONAL) # +####################################################################### + +include $(DEPTH)/config/rules.mk + +####################################################################### +# (7) Execute "local" rules. (OPTIONAL). # +####################################################################### + +realclean clobber_all:: + rm -f PrimitiveOperations.h PrimitiveOperations.cpp + + diff --git a/ef/Compiler/PrimitiveGraph/PrimitiveBuilders.cpp b/ef/Compiler/PrimitiveGraph/PrimitiveBuilders.cpp new file mode 100644 index 000000000000..316c0f7167c9 --- /dev/null +++ b/ef/Compiler/PrimitiveGraph/PrimitiveBuilders.cpp @@ -0,0 +1,1406 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#include "PrimitiveBuilders.h" +#include "Method.h" +#include // include'ed for fmod() + +// ---------------------------------------------------------------------------- +// UnaryGenericBuilder + +// +// Allocate a primitive with the given argument, which is known to be a variable. +// The kind of primitive operation comes from this UnaryGenericBuilder record. +// Return the last new primitive that generates the result or 0 if none (when the +// result is a constant or copied directly from the argument). +// + +Primitive *UnaryGenericBuilder::makeOneProducerGeneric(const VariableOrConstant &arg, VariableOrConstant &result, + ControlNode *container) const +{ + PrimUnaryGeneric *prim = new(container->getPrimitivePool()) PrimUnaryGeneric(op, false); + prim->getInput().setVariable(arg.getVariable()); + result.setVariable(*prim); + container->appendPrimitive(*prim); + return prim; +} + + +// ---------------------------------------------------------------------------- +// BinaryGenericBuilder + +// +// Allocate a primitive with the two given arguments, both of which are known to +// be variables. +// The kind of primitive operation comes from this BinaryGenericBuilder record. +// Return the last new primitive that generates the result or 0 if none (when the +// result is a constant or copied directly from one of the arguments). +// +Primitive *BinaryGenericBuilder::makeTwoProducerGeneric(const VariableOrConstant *args, VariableOrConstant &result, + ControlNode *container) const +{ + PrimBinaryGeneric *prim = new(container->getPrimitivePool()) PrimBinaryGeneric(op, false); + prim->getInputs()[0].setVariable(args[0].getVariable()); + prim->getInputs()[1].setVariable(args[1].getVariable()); + result.setVariable(*prim); + container->appendPrimitive(*prim); + return prim; +} + + +// ---------------------------------------------------------------------------- +// NegBuilder + +template +Primitive *NegBuilder::makeUnaryGeneric(const VariableOrConstant &arg, VariableOrConstant &result, + ControlNode *container) const +{ + return TypeGetSubBuilder(T).specializeConstArg(TypeGetAdditiveIdentity(T), arg, result, container); +} + +#ifdef MANUAL_TEMPLATES + template class NegBuilder; + template class NegBuilder; + template class NegBuilder; + template class NegBuilder; +#endif + +const NegBuilder builder_Neg_II; +const NegBuilder builder_Neg_LL; +const NegBuilder builder_Neg_FF; +const NegBuilder builder_Neg_DD; + + +// ---------------------------------------------------------------------------- +// ConvBuilder + +template +Primitive *ConvBuilder::makeUnaryGeneric(const VariableOrConstant &arg, + VariableOrConstant &result, ControlNode *container) const +{ + assert(arg.hasKind(TypeValueKind(TA))); + + Primitive *prim; + + if (arg.isConstant()) { + TR res; + convertNumber(arg.getConstant().TypeGetValueContents(TA), res); + result.setConstant(res); + prim = 0; + } else + prim = makeOneProducerGeneric(arg, result, container); + assert(result.hasKind(TypeValueKind(TR))); + return prim; +} + +#ifdef MANUAL_TEMPLATES + template class ConvBuilder; + template class ConvBuilder; + template class ConvBuilder; + template class ConvBuilder; + template class ConvBuilder; + template class ConvBuilder; + template class ConvBuilder; + template class ConvBuilder; + template class ConvBuilder; + template class ConvBuilder; + template class ConvBuilder; + template class ConvBuilder; +#endif + +const ConvBuilder builder_Conv_IL(poConvL_I); +const ConvBuilder builder_Conv_IF(poFConvF_I); +const ConvBuilder builder_Conv_ID(poFConvD_I); +const ConvBuilder builder_Conv_LI(poConvI_L); +const ConvBuilder builder_Conv_LF(poFConvF_L); +const ConvBuilder builder_Conv_LD(poFConvD_L); +const ConvBuilder builder_Conv_FI(poFConvI_F); +const ConvBuilder builder_Conv_FL(poFConvL_F); +const ConvBuilder builder_Conv_FD(poFConvD_F); +const ConvBuilder builder_Conv_DI(poFConvI_D); +const ConvBuilder builder_Conv_DL(poFConvL_D); +const ConvBuilder builder_Conv_DF(poFConvF_D); + + +// ---------------------------------------------------------------------------- +// ExtBuilder + +Primitive *ExtBuilder::makeUnaryGeneric(const VariableOrConstant &arg, VariableOrConstant &result, ControlNode *container) const +{ + if (isSigned) + return builder_Ext_III.specializeArgConst(arg, width, result, container); + else + return builder_And_III.specializeArgConst(arg, ((Int32)1< +Primitive *BinarySpecializedBuilder::makeBinaryGeneric(const VariableOrConstant *args, + VariableOrConstant &result, ControlNode *container) const +{ + assert(args[0].hasKind(TypeValueKind(T1)) && args[1].hasKind(TypeValueKind(T2))); + + bool constArg2 = args[1].isConstant(); + Primitive *prim; + + if (args[0].isConstant()) + if (constArg2) + prim = specializeConstConst(args[0].getConstant().TypeGetValueContents(T1), + args[1].getConstant().TypeGetValueContents(T2), result); + else + prim = specializeConstVar(args[0].getConstant().TypeGetValueContents(T1), args[1].getVariable(), result, container); + else + if (constArg2) + prim = specializeVarConst(args[0].getVariable(), args[1].getConstant().TypeGetValueContents(T2), result, container); + else + prim = makeTwoProducerGeneric(args, result, container); + assert(result.hasKind(TypeValueKind(TR))); + return prim; +} + + +// +// Allocate or evaluate a primitive with the two given arguments, the first of which +// is a constant and the second a variable. +// Return the last new primitive that generates the result or 0 if none (when the +// result is a constant or copied directly from one of the arguments). +// This is a virtual method. The default simply creates the appropriate PrimBinaryGeneric node. +// +template +Primitive *BinarySpecializedBuilder::specializeConstVar(T1 arg1, DataNode &arg2, + VariableOrConstant &result, ControlNode *container) const +{ + PrimBinaryGeneric *prim = new(container->getPrimitivePool()) PrimBinaryGeneric(op, false); + prim->getInputs()[0].setConstant(arg1); + prim->getInputs()[1].setVariable(arg2); + result.setVariable(*prim); + container->appendPrimitive(*prim); + return prim; +} + + +// +// Allocate or evaluate a primitive with the two given arguments, the first of which +// is a variable and the second a constant. +// Return the last new primitive that generates the result or 0 if none (when the +// result is a constant or copied directly from one of the arguments). +// This is a virtual method. The default simply creates the appropriate PrimBinaryGeneric node. +// +template +Primitive *BinarySpecializedBuilder::specializeVarConst(DataNode &arg1, T2 arg2, + VariableOrConstant &result, ControlNode *container) const +{ + PrimBinaryGeneric *prim = new(container->getPrimitivePool()) PrimBinaryGeneric(op, false); + prim->getInputs()[0].setVariable(arg1); + prim->getInputs()[1].setConstant(arg2); + result.setVariable(*prim); + container->appendPrimitive(*prim); + return prim; +} + + +#ifdef MANUAL_TEMPLATES + template class BinarySpecializedBuilder; + template class BinarySpecializedBuilder; + template class BinarySpecializedBuilder; + template class BinarySpecializedBuilder; + template class BinarySpecializedBuilder; + + template class BinarySpecializedBuilder; + template class BinarySpecializedBuilder; + template class BinarySpecializedBuilder; + template class BinarySpecializedBuilder; + template class BinarySpecializedBuilder; + template class BinarySpecializedBuilder; +#endif + + +// ---------------------------------------------------------------------------- +// CommutativeBuilder + +// +// In a commutative operation, always make the constant into the second argument. +// +template +Primitive *CommutativeBuilder::specializeConstVar(TA arg1, DataNode &arg2, + VariableOrConstant &result, ControlNode *container) const +{ + return specializeVarConst(arg2, arg1, result, container); +} + +#ifdef MANUAL_TEMPLATES + template class CommutativeBuilder; + template class CommutativeBuilder; + template class CommutativeBuilder; + template class CommutativeBuilder; +#endif + + +// ---------------------------------------------------------------------------- +// AddBuilder + +template +void AddBuilder::evaluate(T arg1, T arg2, T &result) const +{ + result = arg1 + arg2; +} + +template +Primitive *AddBuilder::specializeVarConst(DataNode &arg1, T arg2, + VariableOrConstant &result, ControlNode *container) const +{ + DataNode *a1 = &arg1; + while (true) { + if (isAdditiveAnnihilator(arg2)) { + result.setConstant(arg2); + return 0; + } else if (isAdditiveIdentity(arg2)) { + result.setVariable(*a1); + return 0; + } else if (coalesce && a1->hasOperation(op)) { + PrimBinaryGeneric &node = PrimBinaryGeneric::cast(*a1); + DataConsumer *inputs = node.getInputs(); + if (inputs[1].isConstant()) { + a1 = &inputs[0].getVariable(); + assert(inputs[1].hasKind(TypeValueKind(T))); + arg2 += inputs[1].getConstant().TypeGetValueContents(T); + continue; + } + } + return CommutativeBuilder::specializeVarConst(*a1, arg2, result, container); + } +} + +#ifdef MANUAL_TEMPLATES + template class AddBuilder; + template class AddBuilder; + template class AddBuilder; + template class AddBuilder; +#endif + +const AddBuilder builder_Add_III(poAdd_I, false); +const AddBuilder builder_Add_LLL(poAdd_L, false); +const AddBuilder builder_Add_FFF(poFAdd_F, false); +const AddBuilder builder_Add_DDD(poFAdd_D, false); + +const AddBuilder builder_AddCoal_III(poAdd_I, true); +const AddBuilder builder_AddCoal_LLL(poAdd_L, true); + + +// ---------------------------------------------------------------------------- +// AddABuilder + +void AddABuilder::evaluate(addr arg1, Int32 arg2, addr &result) const +{ + result = arg1 + arg2; +} + +Primitive *AddABuilder::specializeVarConst(DataNode &arg1, Int32 arg2, + VariableOrConstant &result, ControlNode *container) const +{ + DataNode *a1 = &arg1; + while (true) { + if (arg2 == 0) { + result.setVariable(*a1); + return 0; + } else if (coalesce && a1->hasOperation(poAdd_A)) { + PrimBinaryGeneric &node = PrimBinaryGeneric::cast(*a1); + DataConsumer *inputs = node.getInputs(); + if (inputs[1].isConstant()) { + a1 = &inputs[0].getVariable(); + assert(inputs[1].hasKind(vkInt)); + arg2 += inputs[1].getConstant().i; + continue; + } + } + return BinarySpecializedBuilder::specializeVarConst(*a1, arg2, result, container); + } +} + +Primitive *AddABuilder::specializeConstVar(addr arg1, DataNode &arg2, + VariableOrConstant &result, ControlNode *container) const +{ + if (!arg1) + result.setVariable(arg2); + else + return BinarySpecializedBuilder::specializeConstVar(arg1, arg2, result, container); + return 0; +} + +const AddABuilder builder_Add_AIA(false); +const AddABuilder builder_AddCoal_AIA(true); + + +// ---------------------------------------------------------------------------- +// SubBuilder + +template +void SubBuilder::evaluate(T arg1, T arg2, T &result) const +{ + result = arg1 - arg2; +} + +template +Primitive *SubBuilder::specializeConstVar(T arg1, DataNode &arg2, + VariableOrConstant &result, ControlNode *container) const +{ + if (isAdditiveAnnihilator(arg1)) + result.setConstant(arg1); + else + return BinarySpecializedBuilder::specializeConstVar(arg1, arg2, result, container); + return 0; +} + +template +Primitive *SubBuilder::specializeVarConst(DataNode &arg1, T arg2, + VariableOrConstant &result, ControlNode *container) const +{ + return TypeGetAddBuilder(T, coalesce).specializeVarConst(arg1, -arg2, result, container); +} + +#ifdef MANUAL_TEMPLATES + template class SubBuilder; + template class SubBuilder; + template class SubBuilder; + template class SubBuilder; +#endif + +const SubBuilder builder_Sub_III(poSub_I, false); +const SubBuilder builder_Sub_LLL(poSub_L, false); +const SubBuilder builder_Sub_FFF(poFSub_F, false); +const SubBuilder builder_Sub_DDD(poFSub_D, false); + +const SubBuilder builder_SubCoal_III(poSub_I, true); +const SubBuilder builder_SubCoal_LLL(poSub_L, true); + + +// ---------------------------------------------------------------------------- +// MulBuilder + +template +void MulBuilder::evaluate(T arg1, T arg2, T &result) const +{ + result = arg1 * arg2; +} + +template +Primitive *MulBuilder::specializeVarConst(DataNode &arg1, T arg2, + VariableOrConstant &result, ControlNode *container) const +{ + if (isMultiplicativeAnnihilator(arg2)) + result.setConstant(arg2); + else if (isMultiplicativeIdentity(arg2)) + result.setVariable(arg1); + else if (isMultiplicativeNegator(arg2)) + return TypeGetSubBuilder(T).specializeConstVar(TypeGetAdditiveIdentity(T), arg1, result, container); + else + return CommutativeBuilder::specializeVarConst(arg1, arg2, result, container); + return 0; +} + +#ifdef MANUAL_TEMPLATES + template class MulBuilder; + template class MulBuilder; + template class MulBuilder; + template class MulBuilder; +#endif + +const MulBuilder builder_Mul_III(poMul_I); +const MulBuilder builder_Mul_LLL(poMul_L); +const MulBuilder builder_Mul_FFF(poFMul_F); +const MulBuilder builder_Mul_DDD(poFMul_D); + + +// ---------------------------------------------------------------------------- +// InternalDivBuilder + +template +struct InternalDivBuilder: BinarySpecializedBuilder +{ + void evaluate(T arg1, T arg2, T &result) const; + Primitive *specializeVarConst(DataNode &arg1, T arg2, VariableOrConstant &result, ControlNode *container) const; + + InternalDivBuilder(PrimitiveOperation op): + BinarySpecializedBuilder(op) {} +}; + + +template +void InternalDivBuilder::evaluate(T arg1, T arg2, T &result) const +{ + assert(!isZero(arg2)); + + // the test JCK-114a|vm|instr|irem|irem001|irem00101|irem00101|Test1 tests boundary cases + // for division. Eventually we may have a more elegant way of dealing with these kinds off errors, + // but for now we'll explicitly check + if(arg1 == 0x80000000 && arg2 == 0xffffffff) { + result = arg1; // see pg 243 of JVM Spec + return; + } + + result = arg1 / arg2; +} + +template +Primitive *InternalDivBuilder::specializeVarConst(DataNode &arg1, T arg2, + VariableOrConstant &result, ControlNode *container) const +{ + assert(!isZero(arg2)); + if (isMultiplicativeIdentity(arg2)) + result.setVariable(arg1); + else if (isMultiplicativeNegator(arg2)) + return TypeGetSubBuilder(T).specializeConstVar(TypeGetAdditiveIdentity(T), arg1, result, container); + else + return BinarySpecializedBuilder::specializeVarConst(arg1, arg2, result, container); + return 0; +} + +#ifdef MANUAL_TEMPLATES + template class InternalDivBuilder; + template class InternalDivBuilder; +#endif + +static const InternalDivBuilder internalBuilder_Div_III(poDivE_I); +static const InternalDivBuilder internalBuilder_Div_LLL(poDivE_L); +static const InternalDivBuilder internalBuilder_DivNZ_III(poDiv_I); +static const InternalDivBuilder internalBuilder_DivNZ_LLL(poDiv_L); + + + +// ---------------------------------------------------------------------------- +// InternalModBuilder + +template +struct InternalModBuilder: BinarySpecializedBuilder +{ + void evaluate(T arg1, T arg2, T &result) const; + Primitive *specializeVarConst(DataNode &arg1, T arg2, VariableOrConstant &result, ControlNode *container) const; + + InternalModBuilder(PrimitiveOperation op): + BinarySpecializedBuilder(op) {} +}; + + +template +void InternalModBuilder::evaluate(T arg1, T arg2, T &result) const +{ + assert(!isZero(arg2)); + + // see comment in InternalDivBuilder + if(arg1 == 0x80000000 && arg2 == 0xffffffff) { + result = 0; // see pg 271 of JVM Spec + return; + } + + result = arg1 % arg2; +} + +template +Primitive *InternalModBuilder::specializeVarConst(DataNode &arg1, T arg2, + VariableOrConstant &result, ControlNode *container) const +{ + assert(!isZero(arg2)); + if (isMultiplicativeIdentity(arg2) || isMultiplicativeNegator(arg2)) + // Dividing by 1 or -1 always yields a remainder of 0. + result.setConstant(TypeGetZero(T)); + else + return BinarySpecializedBuilder::specializeVarConst(arg1, arg2, result, container); + return 0; +} + +#ifdef MANUAL_TEMPLATES + template class InternalModBuilder; + template class InternalModBuilder; +#endif + +static const InternalModBuilder internalBuilder_Mod_III(poModE_I); +static const InternalModBuilder internalBuilder_Mod_LLL(poModE_L); +static const InternalModBuilder internalBuilder_ModNZ_III(poMod_I); +static const InternalModBuilder internalBuilder_ModNZ_LLL(poMod_L); + +// ---------------------------------------------------------------------------- +// DivModBuilder + +Primitive *DivModBuilder::makeBinaryGeneric(const VariableOrConstant *args, VariableOrConstant &result, + ControlNode *container) const +{ + // Select a builder depending on whether the divisor can be zero. + return (args[1].isAlwaysNonzero() ? nonZeroBuilder : generalBuilder).makeBinaryGeneric(args, result, container); +} + +const DivModBuilder builder_Div_III(internalBuilder_Div_III, internalBuilder_DivNZ_III); +const DivModBuilder builder_Div_LLL(internalBuilder_Div_LLL, internalBuilder_DivNZ_LLL); +const DivModBuilder builder_Mod_III(internalBuilder_Mod_III, internalBuilder_ModNZ_III); +const DivModBuilder builder_Mod_LLL(internalBuilder_Mod_LLL, internalBuilder_ModNZ_LLL); + + +// ---------------------------------------------------------------------------- +// FDivBuilder + +template +void FDivBuilder::evaluate(T arg1, T arg2, T &result) const +{ + result = arg1 / arg2; +} + +template +Primitive *FDivBuilder::specializeConstVar(T arg1, DataNode &arg2, + VariableOrConstant &result, ControlNode *container) const +{ + if (isNaN(arg1)) + result.setConstant(arg1); + else + return BinarySpecializedBuilder::specializeConstVar(arg1, arg2, result, container); + return 0; +} + +template +Primitive *FDivBuilder::specializeVarConst(DataNode &arg1, T arg2, + VariableOrConstant &result, ControlNode *container) const +{ + if (isNaN(arg2)) + result.setConstant(arg2); + else if (isMultiplicativeIdentity(arg2)) + result.setVariable(arg1); + else if (isMultiplicativeNegator(arg2)) + return TypeGetSubBuilder(T).specializeConstVar(TypeGetAdditiveIdentity(T), arg1, result, container); + else + return BinarySpecializedBuilder::specializeVarConst(arg1, arg2, result, container); + return 0; +} + +#ifdef MANUAL_TEMPLATES + template class FDivBuilder; + template class FDivBuilder; +#endif + +const FDivBuilder builder_Div_FFF(poFDiv_F); +const FDivBuilder builder_Div_DDD(poFDiv_D); + + +// ---------------------------------------------------------------------------- +// FRemBuilder + +template +void FRemBuilder::evaluate(T arg1, T arg2, T &result) const +{ + result = (T)javaFMod((double)arg1, (double)arg2); +} + +template +Primitive *FRemBuilder::specializeConstVar(T arg1, DataNode &arg2, + VariableOrConstant &result, ControlNode *container) const +{ + if (isNaN(arg1) || isInfinite(arg1)) + result.setConstant(TypeGetNaN(T)); + else + return BinarySpecializedBuilder::specializeConstVar(arg1, arg2, result, container); + return 0; +} + +template +Primitive *FRemBuilder::specializeVarConst(DataNode &arg1, T arg2, + VariableOrConstant &result, ControlNode *container) const +{ + if (isNaN(arg2) || isZero(arg2)) + result.setConstant(TypeGetNaN(T)); + else + return BinarySpecializedBuilder::specializeVarConst(arg1, arg2, result, container); + return 0; +} + +#ifdef MANUAL_TEMPLATES + template class FRemBuilder; + template class FRemBuilder; +#endif + +const FRemBuilder builder_Rem_FFF(poFRem_F); +const FRemBuilder builder_Rem_DDD(poFRem_D); + + +// ---------------------------------------------------------------------------- +// ShiftBuilder + +inline Int32 shiftMask(Int32) {return 31;} +inline Int32 shiftMask(Int64) {return 63;} + +template +void ShiftBuilder::evaluate(T arg1, Int32 arg2, T &result) const +{ + arg2 &= shiftMask(arg1); + switch (shiftDir) { + case sdLeft: + result = arg1 << arg2; + break; + case sdRightArithmetic: + result = arg1 >> arg2; + break; + case sdRightLogical: + result = toSigned(toUnsigned(arg1) >> arg2); + break; + case sdSignedExtract: + arg2 = -arg2 & shiftMask(arg1); + result = arg1 << arg2 >> arg2; + break; + } +} + +template +Primitive *ShiftBuilder::specializeConstVar(T arg1, DataNode &arg2, + VariableOrConstant &result, ControlNode *container) const +{ + if (isZero(arg1) || shiftDir == sdRightArithmetic && isMultiplicativeNegator(arg1)) + result.setConstant(arg1); + else + return BinarySpecializedBuilder::specializeConstVar(arg1, arg2, result, container); + return 0; +} + +template +Primitive *ShiftBuilder::specializeVarConst(DataNode &arg1, Int32 arg2, + VariableOrConstant &result, ControlNode *container) const +{ + arg2 &= shiftMask((T)0); + if (arg2 == 0) + result.setVariable(arg1); + else + return BinarySpecializedBuilder::specializeVarConst(arg1, arg2, result, container); + return 0; +} + +template +ShiftBuilder::ShiftBuilder(PrimitiveOperation op, ShiftDir shiftDir): + BinarySpecializedBuilder(op), + shiftDir(shiftDir) +{} + + +#ifdef MANUAL_TEMPLATES + template class ShiftBuilder; + template class ShiftBuilder; +#endif + +const ShiftBuilder builder_Shl_III(poShl_I, sdLeft); +const ShiftBuilder builder_Shl_LIL(poShl_L, sdLeft); +const ShiftBuilder builder_Shr_III(poShr_I, sdRightArithmetic); +const ShiftBuilder builder_Shr_LIL(poShr_L, sdRightArithmetic); +const ShiftBuilder builder_UShr_III(poShrU_I, sdRightLogical); +const ShiftBuilder builder_UShr_LIL(poShrU_L, sdRightLogical); +const ShiftBuilder builder_Ext_III(poExt_I, sdSignedExtract); +const ShiftBuilder builder_Ext_LIL(poExt_L, sdSignedExtract); + + +// ---------------------------------------------------------------------------- +// LogicalBuilder + +template +void LogicalBuilder::evaluate(T arg1, T arg2, T &result) const +{ + switch(logicalOp) { + case loAnd: + result = arg1 & arg2; + break; + case loOr: + result = arg1 | arg2; + break; + case loXor: + result = arg1 ^ arg2; + break; + } +} + +template +Primitive *LogicalBuilder::specializeVarConst(DataNode &arg1, T arg2, + VariableOrConstant &result, ControlNode *container) const +{ + if (arg2 == identity) + result.setVariable(arg1); + else if (arg2 == annihilator) + result.setConstant(arg2); + else + return CommutativeBuilder::specializeVarConst(arg1, arg2, result, container); + return 0; +} + +template +LogicalBuilder::LogicalBuilder(PrimitiveOperation op, LogicalOp logicalOp, T identity, T annihilator): + CommutativeBuilder(op), + logicalOp(logicalOp), + identity(identity), + annihilator(annihilator) +{} + + +#ifdef MANUAL_TEMPLATES + template class LogicalBuilder; + template class LogicalBuilder; +#endif + +const LogicalBuilder builder_And_III(poAnd_I, loAnd, -1, 0); +const LogicalBuilder builder_And_LLL(poAnd_L, loAnd, (Int64)-1, (Int64)0); +const LogicalBuilder builder_Or_III(poOr_I, loOr, 0, -1); +const LogicalBuilder builder_Or_LLL(poOr_L, loOr, (Int64)0, (Int64)-1); +const LogicalBuilder builder_Xor_III(poXor_I, loXor, 0, 0); +const LogicalBuilder builder_Xor_LLL(poXor_L, loXor, (Int64)0, (Int64)0); + + +// ---------------------------------------------------------------------------- +// ComparisonBuilder + +template +void ComparisonBuilder::evaluate(T arg1, T arg2, Condition &result) const +{ + Condition res = compare(arg1, arg2, isUnsigned); + if (equalityOnly && res != cEq) + res = cUn; + result = res; +} + +// Return nil if the comparison was generated normally, non-nil if its arguments were reversed. +template +Primitive *ComparisonBuilder::specializeConstVar(T arg1, DataNode &arg2, + VariableOrConstant &result, ControlNode *container) const +{ + Primitive *p = specializeVarConst(arg2, arg1, result, container); + assert(p == 0); + return static_cast(&result.getVariable()); +} + +// Return nil if the comparison was generated normally, non-nil if its arguments were reversed. +template +Primitive *ComparisonBuilder::specializeVarConst(DataNode &arg1, T arg2, + VariableOrConstant &result, ControlNode *container) const +{ + bool isNeverEqual = arg1.isAlwaysNonzero() && isZero(arg2); + if (equalityOnly && isNeverEqual) + result.setConstant(cUn); + else { + PrimBinaryGeneric *prim = new(container->getPrimitivePool()) PrimBinaryGeneric(op, isNeverEqual); + prim->getInputs()[0].setVariable(arg1); + prim->getInputs()[1].setConstant(arg2); + result.setVariable(*prim); + container->appendPrimitive(*prim); + } + return 0; +} + +// Return nil if the comparison was generated normally, non-nil if its arguments were reversed. +template +Primitive *ComparisonBuilder::makeTwoProducerGeneric(const VariableOrConstant *args, VariableOrConstant &result, + ControlNode *container) const +{ + BinaryGenericBuilder::makeTwoProducerGeneric(args, result, container); + return 0; +} + +template +ComparisonBuilder::ComparisonBuilder(PrimitiveOperation op, bool isUnsigned, bool equalityOnly): + BinarySpecializedBuilder(op), + isUnsigned(isUnsigned), + equalityOnly(equalityOnly) +{} + + +#ifdef MANUAL_TEMPLATES + template class ComparisonBuilder; + template class ComparisonBuilder; + template class ComparisonBuilder; + template class ComparisonBuilder; + template class ComparisonBuilder; +#endif + +const ComparisonBuilder builder_Cmp_IIC(poCmp_I, false, false); +const ComparisonBuilder builder_Cmp_LLC(poCmp_L, false, false); +const ComparisonBuilder builder_Cmp_FFC(poFCmp_F, false, false); +const ComparisonBuilder builder_Cmp_DDC(poFCmp_D, false, false); + +const ComparisonBuilder builder_CmpU_IIC(poCmpU_I, true, false); +const ComparisonBuilder builder_CmpU_AAC(poCmpU_A, true, false); + +const ComparisonBuilder builder_CmpEq_IIC(poCmp_I, false, true); +const ComparisonBuilder builder_CmpUEq_AAC(poCmpU_A, true, true); + + +// ---------------------------------------------------------------------------- +// Cond2Builder + +Primitive *Cond2Builder::makeBinaryGeneric(const VariableOrConstant *args, VariableOrConstant &result, + ControlNode *container) const +{ + VariableOrConstant c; + + // If non-nil, the comparer reversed its arguments so we must use the reverse condition. + PrimitiveOperation condKind = comparer.makeBinaryGeneric(args, c, container) ? opReverse : opNormal; + + bool constResult; + DataNode *cp = partialComputeComparison(cond2ToCondition2(condKind), c, constResult); + if (cp) { + PrimUnaryGeneric *prim = new(container->getPrimitivePool()) PrimUnaryGeneric(condKind, false); + prim->getInput().setVariable(*cp); + result.setVariable(*prim); + container->appendPrimitive(*prim); + return prim; + } else { + result.setConstant((Int32)constResult); + return 0; + } +} + +Cond2Builder::Cond2Builder(PrimitiveOperation opNormal, PrimitiveOperation opReverse, const BinaryBuilder &comparer): + opNormal(opNormal), + opReverse(opReverse), + comparer(comparer) +{} + + +const Cond2Builder builder_Eq_III(poEq_I, poEq_I, builder_CmpEq_IIC); +const Cond2Builder builder_Ne_III(poNe_I, poNe_I, builder_CmpEq_IIC); +const Cond2Builder builder_Lt_III(poLt_I, poGt_I, builder_Cmp_IIC); +const Cond2Builder builder_Ge_III(poGe_I, poLe_I, builder_Cmp_IIC); +const Cond2Builder builder_Gt_III(poGt_I, poLt_I, builder_Cmp_IIC); +const Cond2Builder builder_Le_III(poLe_I, poGe_I, builder_Cmp_IIC); +const Cond2Builder builder_LtU_III(poLt_I, poGt_I, builder_CmpU_IIC); +const Cond2Builder builder_GeU_III(poGe_I, poLe_I, builder_CmpU_IIC); +const Cond2Builder builder_GtU_III(poGt_I, poLt_I, builder_CmpU_IIC); +const Cond2Builder builder_LeU_III(poLe_I, poGe_I, builder_CmpU_IIC); +const Cond2Builder builder_Eq_AAI(poEq_I, poEq_I, builder_CmpUEq_AAC); +const Cond2Builder builder_Ne_AAI(poNe_I, poNe_I, builder_CmpUEq_AAC); + + +// ---------------------------------------------------------------------------- +// Cond3Builder + +Primitive *Cond3Builder::makeBinaryGeneric(const VariableOrConstant *args, VariableOrConstant &result, + ControlNode *container) const +{ + VariableOrConstant c; + + // If non-nil, the comparer reversed its arguments so we must use the reverse condition. + PrimitiveOperation condKind = comparer.makeBinaryGeneric(args, c, container) ? opReverse : opNormal; + assert(c.hasKind(vkCond)); + + if (c.isConstant()) { + result.setConstant((Int32)applyCondition(cond3ToCondition3(condKind), c.getConstant().c)); + return 0; + } else { + DataNode &cp = c.getVariable(); + PrimUnaryGeneric *prim = new(container->getPrimitivePool()) PrimUnaryGeneric(condKind, cp.isAlwaysNonzero()); + prim->getInput().setVariable(cp); + result.setVariable(*prim); + container->appendPrimitive(*prim); + return prim; + } +} + +Cond3Builder::Cond3Builder(PrimitiveOperation opNormal, PrimitiveOperation opReverse, const BinaryBuilder &comparer): + opNormal(opNormal), + opReverse(opReverse), + comparer(comparer) +{} + + +const Cond3Builder builder_Cmp3_LLI(poCatL_I, poCatCL_I, builder_Cmp_LLC); +const Cond3Builder builder_Cmp3L_FFI(poCatL_I, poCatCL_I, builder_Cmp_FFC); +const Cond3Builder builder_Cmp3G_FFI(poCatG_I, poCatCG_I, builder_Cmp_FFC); +const Cond3Builder builder_Cmp3L_DDI(poCatL_I, poCatCL_I, builder_Cmp_DDC); +const Cond3Builder builder_Cmp3G_DDI(poCatG_I, poCatCG_I, builder_Cmp_DDC); + + +// ---------------------------------------------------------------------------- +// TestBuilder + +template +Primitive *TestBuilder::makeUnaryGeneric(const VariableOrConstant &arg, VariableOrConstant &result, + ControlNode *container) const +{ + VariableOrConstant args[2]; + args[0] = arg; + args[1].setConstant(TypeGetZero(T)); + return condBuilder.makeBinaryGeneric(args, result, container); +} + +template +TestBuilder::TestBuilder(const BinaryBuilder &condBuilder): + condBuilder(condBuilder) +{} + + +#ifdef MANUAL_TEMPLATES + template class TestBuilder; + template class TestBuilder; +#endif + +const TestBuilder builder_Eq0_II(builder_Eq_III); +const TestBuilder builder_Ne0_II(builder_Ne_III); +const TestBuilder builder_Lt0_II(builder_Lt_III); +const TestBuilder builder_Ge0_II(builder_Ge_III); +const TestBuilder builder_Gt0_II(builder_Gt_III); +const TestBuilder builder_Le0_II(builder_Le_III); +const TestBuilder builder_Eq0_AI(builder_Eq_AAI); +const TestBuilder builder_Ne0_AI(builder_Ne_AAI); + + +// ---------------------------------------------------------------------------- +// ChkNull and Limit primitive builders + +// +// Construct a primitive to throw NullPointerException if arg is null. +// arg must have kind vkAddr. If the test of arg against null can be done statically, +// return either chkAlwaysOK (if arg is never null) or chkNeverOK (if arg is always +// null), don't emit any primitives, and set prim to nil; otherwise, return +// chkMaybeOK, emit the check primitive, and set prim to point to the emitted +// primitive. +// +CheckResult +makeChkNull(const VariableOrConstant &arg, Primitive *&prim, + ControlNode *container, Uint32 bci) +{ + assert(arg.hasKind(vkAddr)); + + prim = 0; + if (arg.isConstant()) + return !arg.getConstant().a ? chkNeverOK : chkAlwaysOK; + DataNode &dp = arg.getVariable(); + if (dp.isAlwaysNonzero()) + return chkAlwaysOK; + PrimUnaryGeneric *p = new(container->getPrimitivePool()) PrimUnaryGeneric(poChkNull, bci); + p->getInput().setVariable(dp); + container->appendPrimitive(*p); + prim = p; + return chkMaybeOK; +} + + +// +// Construct a primitive to throw ArrayIndexOutOfBounds if arg1 >= arg2, treating +// both arg1 and arg2 as unsigned integers. Both arguments must have kind vkInt. +// If the test can be done statically, return either chkAlwaysOK (if the test is +// always false) or chkNeverOK (if the test is always true), don't emit any primitives, +// and set prim to nil; otherwise, return chkMaybeOK, emit the limit primitive, +// and set prim to point to the emitted primitive. +// +CheckResult makeLimit(const VariableOrConstant &arg1, const VariableOrConstant &arg2, Primitive *&prim, ControlNode *container) +{ + assert(arg1.hasKind(vkInt) && arg2.hasKind(vkInt)); + + prim = 0; + if (arg2.isConstant()) { + if (arg2.getConstant().i == 0) + return chkNeverOK; + if (arg1.isConstant()) + return (Uint32)arg1.getConstant().i < (Uint32)arg2.getConstant().i ? chkAlwaysOK : chkNeverOK; + } + PrimBinaryGeneric *p = new(container->getPrimitivePool()) PrimBinaryGeneric(poLimit, false); + p->getInputs()[0] = arg1; + p->getInputs()[1] = arg2; + container->appendPrimitive(*p); + prim = p; + return chkMaybeOK; +} + + +// +// Construct a primitive to throw ClassCastException if the value of arg1 is not equal +// to the value of arg2. Both arg1 and arg2 must have kind vkInt. +// Return the emitted primitive. +// +Primitive *makeChkCastI(DataNode &arg1, DataNode &arg2, ControlNode *container) +{ + assert(arg1.hasKind(vkInt) && arg2.hasKind(vkInt)); + + PrimBinaryGeneric *p = new(container->getPrimitivePool()) PrimBinaryGeneric(poChkCast_I, false); + p->getInputs()[0].setVariable(arg1); + p->getInputs()[1].setVariable(arg2); + container->appendPrimitive(*p); + return p; +} + + +// +// Construct a primitive to throw ClassCastException if the value of dp is not equal +// to the given type object. dp must have kind vkAddr. +// Return the emitted primitive. +// +Primitive *makeChkCastA(DataNode &dp, const Type &type, ControlNode *container) +{ + assert(dp.hasKind(vkAddr)); + + PrimBinaryGeneric *p = new(container->getPrimitivePool()) PrimBinaryGeneric(poChkCast_A, false); + p->getInputs()[0].setVariable(dp); + p->getInputs()[1].setConstant(objectAddress(&type)); + container->appendPrimitive(*p); + return p; +} + + +// +// Construct a primitive to throw ClassCastException if arg1 < limit, treating +// both arg1 and limit as either signed or unsigned integers. arg1 must have kind vkInt. +// If the test can be done statically, return either chkAlwaysOK (if the test is +// always false) or chkNeverOK (if the test is always true), don't emit any primitives, +// and set prim to nil; otherwise, return chkMaybeOK, emit the limit primitive, +// and set prim to point to the emitted primitive. +// +CheckResult makeLimCast(const VariableOrConstant &arg1, Int32 limit, Primitive *&prim, ControlNode *container) +{ + assert(arg1.hasKind(vkInt)); + + prim = 0; + if (arg1.isConstant()) + return arg1.getConstant().i >= limit ? chkAlwaysOK : chkNeverOK; + PrimBinaryGeneric *p = new(container->getPrimitivePool()) PrimBinaryGeneric(poLimCast, false); + p->getInputs()[0] = arg1; + p->getInputs()[1].setConstant(limit); + container->appendPrimitive(*p); + prim = p; + return chkMaybeOK; +} + + +// ---------------------------------------------------------------------------- +// LoadBuilder + + +// +// This subroutine is used by both variants of makeLoad below to actually +// create and return the PrimLoad primitive. +// +PrimLoad * +LoadBuilder::createLoad(PrimitiveOperation op, DataNode **memory, + VariableOrConstant &result, bool isVolatile, + bool isConstant, ControlNode *container, Uint32 bci) + const +{ + Pool &pool = container->getPrimitivePool(); + if (isVolatile) + op = (PrimitiveOperation)(op + poLdV_I - poLd_I); + PrimLoad *prim = new(pool) PrimLoad(op, isVolatile, bci); + if (isConstant) + prim->getIncomingMemory().setConstant(mConstant); + else + prim->getIncomingMemory().setVariable(**memory); + container->appendPrimitive(*prim); + + // If this is a volatile load, the result is a tuple, so create the + // projection nodes to extract the memory and value results. + DataNode *res = prim; + if (isVolatile) { + PrimProj *proj = new(pool) PrimProj(poProj_M, tcMemory, true, bci); + container->appendPrimitive(*proj); + proj->getInput().setVariable(*prim); + *memory = proj; + proj = new(pool) PrimProj(typeKindToValueKind(outputType), tcValue, + false, bci); + container->appendPrimitive(*proj); + proj->getInput().setVariable(*prim); + res = proj; + } + + result.setVariable(*res); + return prim; +} + + +// +// Make a Load primitive that reads the given constant address and store the +// value in result. If isVolatile is true, obtain an incoming memory edge +// from memory, and store the outgoing memory edge there. If isConstant is +// true, the memory argument is ignored. If both isVolatile and isConstant +// are false, obtain incoming memory edge from memory but don't update it. +// It's not legal for both isVolatile and isConstant to be true. +// +void +LoadBuilder::makeLoad(DataNode **memory, addr address, + VariableOrConstant &result, bool isVolatile, + bool isConstant, ControlNode *container, Uint32 bci) + const +{ + assert(!(isVolatile && isConstant)); + assert(!memory || (*memory)->hasKind(vkMemory)); + + Value v; + if (isConstant && read(outputType, address, v)) + result.setConstant(typeKindToValueKind(outputType), v); + else { + PrimLoad *prim = createLoad(op, memory, result, isVolatile, + isConstant, container, bci); + prim->getAddress().setConstant(address); + } +} + + +// +// Make a Load primitive that reads the given address and store the value +// in result. If isVolatile is true, obtain an incoming memory edge from +// memory, and store the outgoing memory edge there. If isConstant is true, +// the memory argument is ignored. If both isVolatile and isConstant are false, +// obtain incoming memory edge from memory but don't update it. It's not +// legal for both isVolatile and isConstant to be true. +// +void +LoadBuilder::makeLoad(DataNode **memory, const VariableOrConstant &address, + VariableOrConstant &result, bool isVolatile, + bool isConstant, ControlNode *container, Uint32 bci) const +{ + assert(!(isVolatile && isConstant)); + assert((!memory || (*memory)->hasKind(vkMemory)) && address.hasKind(vkAddr)); + if (address.isConstant()) + makeLoad(memory, address.getConstant().a, result, isVolatile, + isConstant, container, bci); + else { + PrimLoad *prim = createLoad(op, memory, result, isVolatile, + isConstant, container, bci); + prim->getAddress().setVariable(address.getVariable()); + } +} + + +LoadBuilder::LoadBuilder(PrimitiveOperation op, TypeKind outputType): + op(op), + outputType(outputType) +{} + + +const LoadBuilder builder_Ld_AI(poLd_I, tkInt); +const LoadBuilder builder_Ld_AL(poLd_L, tkLong); +const LoadBuilder builder_Ld_AF(poLd_F, tkFloat); +const LoadBuilder builder_Ld_AD(poLd_D, tkDouble); +const LoadBuilder builder_Ld_AA(poLd_A, tkObject); +const LoadBuilder builder_LdS_AB(poLdS_B, tkByte); +const LoadBuilder builder_LdS_AH(poLdS_H, tkShort); +const LoadBuilder builder_LdU_AB(poLdU_B, tkUByte); +const LoadBuilder builder_LdU_AH(poLdU_H, tkChar); + + +// ---------------------------------------------------------------------------- +// StoreBuilder + + +// +// Make a Store primitive that writes the given value into the given address. +// Obtain an incoming memory edge from memoryIn, and return the outgoing +// memory edge. If isVolatile is true, the store is volatile +// (which currently doesn't make any difference). +// +Primitive &StoreBuilder::makeStore(DataNode &memoryIn, + const VariableOrConstant &address, + const VariableOrConstant &value, + bool isVolatile, ControlNode *container, + Uint32 bci) const +{ + assert(memoryIn.hasKind(vkMemory) && address.hasKind(vkAddr) && value.hasKind(inputKind)); + + PrimitiveOperation op = opPure; + if (isVolatile) + op = (PrimitiveOperation)(op + poStV_B - poSt_B); + PrimStore &prim = *new(container->getPrimitivePool()) PrimStore(op, bci); + prim.getIncomingMemory().setVariable(memoryIn); + prim.getAddress() = address; + prim.getData() = value; + container->appendPrimitive(prim); + return prim; +} + + +StoreBuilder::StoreBuilder(PrimitiveOperation opPure, ValueKind inputKind): + opPure(opPure), + inputKind(inputKind) +{} + + +const StoreBuilder builder_St_AB(poSt_B, vkInt); +const StoreBuilder builder_St_AH(poSt_H, vkInt); +const StoreBuilder builder_St_AI(poSt_I, vkInt); +const StoreBuilder builder_St_AL(poSt_L, vkLong); +const StoreBuilder builder_St_AF(poSt_F, vkFloat); +const StoreBuilder builder_St_AD(poSt_D, vkDouble); +const StoreBuilder builder_St_AA(poSt_A, vkAddr); + + +// ---------------------------------------------------------------------------- +// Monitor primitive builders + + +// +// Construct an MEnter or MExit primitive using the given arg and saves subheader +// slot index. Return the emitted primitive, which is also the outgoing memory edge. +// +Primitive & +makeMonitorPrimitive(PrimitiveOperation op, DataNode &memoryIn, + const VariableOrConstant &arg, Uint32 slot, + ControlNode *container, Uint32 bci) +{ + assert(memoryIn.hasKind(vkMemory) && arg.hasKind(vkAddr)); + + PrimMonitor &prim = *new(container->getPrimitivePool()) + PrimMonitor(op, slot, bci); + prim.getIncomingMemory().setVariable(memoryIn); + prim.getMonitor() = arg; + container->appendPrimitive(prim); + return prim; +} + + +// ---------------------------------------------------------------------------- +// Call builders + + +// +// Make a system call primitive that takes zero or more arguments (given in +// the args array) and produces zero or more results (returned in the results +// array). If memory is nonnil, obtain an incoming memory edge from memory, +// and store the outgoing memory edge there; if memory is nil, then the +// primitive does not read or write memory. Put the system call primitive +// into the given container and return that system call primitive. This +// function does not simplify primitives all of whose arguments are +// constants; the caller should do so if desired. The returned primitive is +// guaranteed to be the only one generated by this function that uses the +// incoming memory edge, if any. +// +Primitive & +makeSysCall(const SysCall &sysCall, DataNode **memory, + const VariableOrConstant *args, + VariableOrConstant *results, ControlNode &container, Uint32 bci) +{ + Pool &pool = container.getPrimitivePool(); + PrimSysCall &prim = *new(pool) PrimSysCall(sysCall, pool, bci); + container.appendPrimitive(prim); + + uint i = sysCall.nInputs; + DataConsumer *inputs = prim.getInputsBegin(); + #ifdef DEBUG + const ValueKind *inputKinds = sysCall.inputKinds; + #endif + if (memory) { + #ifdef DEBUG + assert(i && isMemoryKind(*inputKinds)); + inputKinds++; + #endif + inputs++->setVariable(**memory); + i--; + } + while (i--) { + #ifdef DEBUG + assert(!args->hasKind(vkMemory) && args->hasKind(*inputKinds)); + inputKinds++; + #endif + *inputs++ = *args++; + } + assert(inputs == prim.getInputsEnd()); + + i = sysCall.nOutputs; + const ValueKind *outputKind = sysCall.outputKinds; + const bool *outputNonzero = sysCall.outputsNonzero; + if (memory) { + assert(i && isMemoryKind(sysCall.outputKinds[0])); + PrimProj *proj = new(pool) PrimProj(poProj_M, tcMemory, true, bci); + container.appendPrimitive(*proj); + proj->getInput().setVariable(prim); + *memory = proj; + i--; + outputKind++; + outputNonzero++; + } + TupleComponent tc = tcFirstResult; + while (i--) { + PrimProj *proj = new(pool) PrimProj(*outputKind++, tc, + *outputNonzero++, bci); + container.appendPrimitive(*proj); + proj->getInput().setVariable(prim); + results++->setVariable(*proj); + tc = (TupleComponent)(tc + 1); + } + + return prim; +} + + +// +// Make a call primitive that calls the given function. The call takes zero +// or more arguments (given in the args array, with the count stored in the +// signature) and produces zero or one result (returned in the results +// array). Obtain an incoming memory edge from memory, and store the +// outgoing memory edge there. Put the call primitive into the given +// container and return that primitive. +// +// If the Method object is known for this function, the method argument +// should point to it; if not, the method argument must be nil. +// +Primitive &makeCall(const Signature &sig, DataNode *&memory, + const VariableOrConstant &function, const Method *method, + const VariableOrConstant *args, VariableOrConstant *results, + ControlNode &container, Uint32 bci) +{ + Pool &pool = container.getPrimitivePool(); + uint nArguments = sig.nArguments; + uint nResults = sig.getNResults(); + + // We can't know the Method for dynamic function calls! + assert(!method || function.isConstant()); + + PrimCall &prim = *new(pool) PrimCall(poCall, method, nArguments, + nResults, pool, bci); + container.appendPrimitive(prim); + + prim.getIncomingMemory().setVariable(*memory); + prim.getFunction() = function; + DataConsumer *inputs = prim.getArguments(); + #ifdef DEBUG + const Type **argumentTypes = sig.argumentTypes; + #endif + while (nArguments--) { + #ifdef DEBUG + assert(args->hasKind(typeKindToValueKind((*argumentTypes)->typeKind))); + argumentTypes++; + #endif + *inputs++ = *args++; + } + + PrimProj *proj = new(pool) PrimProj(poProj_M, tcMemory, true, bci); + container.appendPrimitive(*proj); + proj->getInput().setVariable(prim); + memory = proj; + if (nResults) { + proj = new(pool) + PrimProj(typeKindToValueKind(sig.resultType->typeKind), + tcFirstResult, false, bci); + container.appendPrimitive(*proj); + proj->getInput().setVariable(prim); + results->setVariable(*proj); + } + + return prim; +} + diff --git a/ef/Compiler/PrimitiveGraph/PrimitiveBuilders.h b/ef/Compiler/PrimitiveGraph/PrimitiveBuilders.h new file mode 100644 index 000000000000..2ac36923aa3c --- /dev/null +++ b/ef/Compiler/PrimitiveGraph/PrimitiveBuilders.h @@ -0,0 +1,651 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#ifndef PRIMITIVEBUILDERS_H +#define PRIMITIVEBUILDERS_H + +#include "ControlGraph.h" +#include "SysCalls.h" + +struct Signature; + + +struct UnaryBuilder +{ + virtual Primitive *makeUnaryGeneric(const VariableOrConstant &arg, VariableOrConstant &result, ControlNode *container) const = 0; +}; + + +class UnaryGenericBuilder: public UnaryBuilder +{ + protected: + const PrimitiveOperation op; // Kind of primitive operation + + Primitive *makeOneProducerGeneric(const VariableOrConstant &arg, VariableOrConstant &result, ControlNode *container) const; + + public: + UnaryGenericBuilder(PrimitiveOperation op): op(op) {} +}; + + +struct BinaryBuilder +{ + virtual Primitive *makeBinaryGeneric(const VariableOrConstant *args, VariableOrConstant &result, ControlNode *container) const = 0; +}; + + +class BinaryGenericBuilder: public BinaryBuilder +{ + protected: + const PrimitiveOperation op; // Kind of primitive operation + + virtual Primitive *makeTwoProducerGeneric(const VariableOrConstant *args, VariableOrConstant &result, ControlNode *container) const; + + public: + BinaryGenericBuilder(PrimitiveOperation op): op(op) {} +}; + + +// ---------------------------------------------------------------------------- +// NegBuilder +// Builder of negations + +template +struct NegBuilder: UnaryBuilder +{ + Primitive *makeUnaryGeneric(const VariableOrConstant &arg, VariableOrConstant &result, ControlNode *container) const; +}; + +extern const NegBuilder builder_Neg_II; +extern const NegBuilder builder_Neg_LL; +extern const NegBuilder builder_Neg_FF; +extern const NegBuilder builder_Neg_DD; + + +// ---------------------------------------------------------------------------- +// ConvBuilder +// Builder of numeric conversions + +template +struct ConvBuilder: UnaryGenericBuilder +{ + Primitive *makeUnaryGeneric(const VariableOrConstant &arg, VariableOrConstant &result, ControlNode *container) const; + + ConvBuilder(PrimitiveOperation op): UnaryGenericBuilder(op) {} +}; + +extern const ConvBuilder builder_Conv_IL; +extern const ConvBuilder builder_Conv_IF; +extern const ConvBuilder builder_Conv_ID; +extern const ConvBuilder builder_Conv_LI; +extern const ConvBuilder builder_Conv_LF; +extern const ConvBuilder builder_Conv_LD; +extern const ConvBuilder builder_Conv_FI; +extern const ConvBuilder builder_Conv_FL; +extern const ConvBuilder builder_Conv_FD; +extern const ConvBuilder builder_Conv_DI; +extern const ConvBuilder builder_Conv_DL; +extern const ConvBuilder builder_Conv_DF; + + +// ---------------------------------------------------------------------------- +// ExtBuilder +// Builder of integer bit field extractions + +struct ExtBuilder: UnaryBuilder +{ + const bool isSigned; // True indicates the bit field is signed + const int width; // Width of the right-justified bit field (between 1 and 31) + + Primitive *makeUnaryGeneric(const VariableOrConstant &arg, VariableOrConstant &result, ControlNode *container) const; + + ExtBuilder(bool isSigned, int width): isSigned(isSigned), width(width) {} +}; + +extern const ExtBuilder builder_ExtB_II; +extern const ExtBuilder builder_ExtC_II; +extern const ExtBuilder builder_ExtS_II; + + +// ---------------------------------------------------------------------------- +// BinarySpecializedBuilder + +template +struct BinarySpecializedBuilder: BinaryGenericBuilder +{ + virtual void evaluate(T1 arg1, T2 arg2, TR &result) const = 0; + Primitive *specializeConstConst(T1 arg1, T2 arg2, VariableOrConstant &result) const; + virtual Primitive *specializeConstVar(T1 arg1, DataNode &arg2, VariableOrConstant &result, ControlNode *container) const; + virtual Primitive *specializeVarConst(DataNode &arg1, T2 arg2, VariableOrConstant &result, ControlNode *container) const; + Primitive *specializeConstArg(T1 arg1, const VariableOrConstant &arg2, VariableOrConstant &result, ControlNode *container) const; + Primitive *specializeArgConst(const VariableOrConstant &arg1, T2 arg2, VariableOrConstant &result, ControlNode *container) const; + Primitive *makeBinaryGeneric(const VariableOrConstant *args, VariableOrConstant &result, ControlNode *container) const; + + BinarySpecializedBuilder(PrimitiveOperation op): BinaryGenericBuilder(op) {} +}; + + +// +// Allocate or evaluate the primitive with the two given arguments, both of which +// are constants. The result will be a constant as well. +// Return the last new primitive that generates the result or 0 if none (when the +// result is a constant or copied directly from one of the arguments). +// +template +inline Primitive *BinarySpecializedBuilder::specializeConstConst(T1 arg1, T2 arg2, VariableOrConstant &result) const +{ + TR res; + evaluate(arg1, arg2, res); + result.setConstant(res); + return 0; +} + + +// +// Allocate or evaluate the primitive with the two given arguments, the first of which +// is a constant and the second either a constant or a variable. +// Return the last new primitive that generates the result or 0 if none (when the +// result is a constant or copied directly from one of the arguments). +// +template +inline Primitive *BinarySpecializedBuilder::specializeConstArg(T1 arg1, const VariableOrConstant &arg2, + VariableOrConstant &result, ControlNode *container) const +{ + assert(arg2.hasKind(TypeValueKind(T2))); + Primitive *prim; + + if (arg2.isConstant()) + prim = specializeConstConst(arg1, arg2.getConstant().TypeGetValueContents(T2), result); + else + prim = specializeConstVar(arg1, arg2.getVariable(), result, container); + assert(result.hasKind(TypeValueKind(TR))); + return prim; +} + + +// +// Allocate or evaluate the primitive with the two given arguments, the second of which +// is a constant and the first either a constant or a variable. +// Return the last new primitive that generates the result or 0 if none (when the +// result is a constant or copied directly from one of the arguments). +// +template +inline Primitive *BinarySpecializedBuilder::specializeArgConst(const VariableOrConstant &arg1, T2 arg2, + VariableOrConstant &result, ControlNode *container) const +{ + assert(arg1.hasKind(TypeValueKind(T1))); + Primitive *prim; + + if (arg1.isConstant()) + prim = specializeConstConst(arg1.getConstant().TypeGetValueContents(T1), arg2, result); + else + prim = specializeVarConst(arg1.getVariable(), arg2, result, container); + assert(result.hasKind(TypeValueKind(TR))); + return prim; +} + + +// ---------------------------------------------------------------------------- +// CommutativeBuilder +// Builder of commutative operations + +template +struct CommutativeBuilder: BinarySpecializedBuilder +{ + Primitive *specializeConstVar(TA arg1, DataNode &arg2, VariableOrConstant &result, ControlNode *container) const; + + CommutativeBuilder(PrimitiveOperation op): BinarySpecializedBuilder(op) {} +}; + + +// ---------------------------------------------------------------------------- +// AddBuilder +// Builder of homogeneous additions + +template +struct AddBuilder: CommutativeBuilder +{ + const bool coalesce; // If true, this add may be coalesced with an add in one of the arguments + + void evaluate(T arg1, T arg2, T &result) const; + Primitive *specializeVarConst(DataNode &arg1, T arg2, VariableOrConstant &result, ControlNode *container) const; + + AddBuilder(PrimitiveOperation op, bool coalesce): CommutativeBuilder(op), coalesce(coalesce) {} +}; + +extern const AddBuilder builder_Add_III; +extern const AddBuilder builder_Add_LLL; +extern const AddBuilder builder_Add_FFF; +extern const AddBuilder builder_Add_DDD; + +// Coalescing versions of the above; these automatically convert expressions +// like (x+c)+d where c and d are constants into x+(c+d). +extern const AddBuilder builder_AddCoal_III; +extern const AddBuilder builder_AddCoal_LLL; +// Coalescing is not available for floating point because floating point addition +// is not associative. + +inline const AddBuilder &getAddBuilder(Int32, bool coalesce) {return coalesce ? builder_AddCoal_III : builder_Add_III;} +inline const AddBuilder &getAddBuilder(Int64, bool coalesce) {return coalesce ? builder_AddCoal_LLL : builder_Add_LLL;} +inline const AddBuilder &getAddBuilder(Flt32, bool) {return builder_Add_FFF;} +inline const AddBuilder &getAddBuilder(Flt64, bool) {return builder_Add_DDD;} +#define TypeGetAddBuilder(T, coalesce) getAddBuilder((T)0, coalesce) + + +// ---------------------------------------------------------------------------- +// AddABuilder +// Builder of pointer additions + +struct AddABuilder: BinarySpecializedBuilder +{ + const bool coalesce; // If true, this add may be coalesced with an add in one of the arguments + + void evaluate(addr arg1, Int32 arg2, addr &result) const; + Primitive *specializeConstVar(addr arg1, DataNode &arg2, VariableOrConstant &result, ControlNode *container) const; + Primitive *specializeVarConst(DataNode &arg1, Int32 arg2, VariableOrConstant &result, ControlNode *container) const; + + explicit AddABuilder(bool coalesce): BinarySpecializedBuilder(poAdd_A), coalesce(coalesce) {} +}; + +extern const AddABuilder builder_Add_AIA; +// Coalescing version of the above; this automatically converts expressions +// like (x+c)+d where c and d are constants into x+(c+d). +extern const AddABuilder builder_AddCoal_AIA; + + +// ---------------------------------------------------------------------------- +// SubBuilder +// Builder of homogeneous subtractions + +template +struct SubBuilder: BinarySpecializedBuilder +{ + const bool coalesce; // If true, this add may be coalesced with an add in one of the arguments + + void evaluate(T arg1, T arg2, T &result) const; + Primitive *specializeConstVar(T arg1, DataNode &arg2, VariableOrConstant &result, ControlNode *container) const; + Primitive *specializeVarConst(DataNode &arg1, T arg2, VariableOrConstant &result, ControlNode *container) const; + + SubBuilder(PrimitiveOperation op, bool coalesce): BinarySpecializedBuilder(op), coalesce(coalesce) {} +}; + +extern const SubBuilder builder_Sub_III; +extern const SubBuilder builder_Sub_LLL; +extern const SubBuilder builder_Sub_FFF; +extern const SubBuilder builder_Sub_DDD; + +// Coalescing versions of the above; these automatically convert expressions +// like (x-c)-d where c and d are constants into x-(c+d). +extern const SubBuilder builder_SubCoal_III; +extern const SubBuilder builder_SubCoal_LLL; +// Coalescing is not available for floating point because floating point addition +// is not associative. + +inline const SubBuilder &getSubBuilder(Int32) {return builder_Sub_III;} +inline const SubBuilder &getSubBuilder(Int64) {return builder_Sub_LLL;} +inline const SubBuilder &getSubBuilder(Flt32) {return builder_Sub_FFF;} +inline const SubBuilder &getSubBuilder(Flt64) {return builder_Sub_DDD;} +#define TypeGetSubBuilder(T) getSubBuilder((T)0) + + +// ---------------------------------------------------------------------------- +// MulBuilder +// Builder of homogeneous multiplications + +template +struct MulBuilder: CommutativeBuilder +{ + void evaluate(T arg1, T arg2, T &result) const; + Primitive *specializeVarConst(DataNode &arg1, T arg2, VariableOrConstant &result, ControlNode *container) const; + + MulBuilder(PrimitiveOperation op): CommutativeBuilder(op) {} +}; + +extern const MulBuilder builder_Mul_III; +extern const MulBuilder builder_Mul_LLL; +extern const MulBuilder builder_Mul_FFF; +extern const MulBuilder builder_Mul_DDD; + + +// ---------------------------------------------------------------------------- +// DivModBuilder +// Builder of integer divisions and modulos + +class DivModBuilder: public BinaryBuilder +{ + const BinaryBuilder &generalBuilder; // Builder to use when we don't know whether the divisor is zero + const BinaryBuilder &nonZeroBuilder; // Builder to use when we know that the divisor is nonzero + + public: + Primitive *makeBinaryGeneric(const VariableOrConstant *args, VariableOrConstant &result, ControlNode *container) const; + + DivModBuilder(const BinaryBuilder &generalBuilder, const BinaryBuilder &nonZeroBuilder): + generalBuilder(generalBuilder), nonZeroBuilder(nonZeroBuilder) {} +}; + +extern const DivModBuilder builder_Div_III; +extern const DivModBuilder builder_Div_LLL; +extern const DivModBuilder builder_Mod_III; +extern const DivModBuilder builder_Mod_LLL; + + +// ---------------------------------------------------------------------------- +// FDivBuilder +// Builder of floating point divisions + +template +struct FDivBuilder: BinarySpecializedBuilder +{ + void evaluate(T arg1, T arg2, T &result) const; + Primitive *specializeConstVar(T arg1, DataNode &arg2, VariableOrConstant &result, ControlNode *container) const; + Primitive *specializeVarConst(DataNode &arg1, T arg2, VariableOrConstant &result, ControlNode *container) const; + + FDivBuilder(PrimitiveOperation op): BinarySpecializedBuilder(op) {} +}; + +extern const FDivBuilder builder_Div_FFF; +extern const FDivBuilder builder_Div_DDD; + + +// ---------------------------------------------------------------------------- +// FRemBuilder +// Builder of floating point remainders + +template +struct FRemBuilder: BinarySpecializedBuilder +{ + void evaluate(T arg1, T arg2, T &result) const; + Primitive *specializeConstVar(T arg1, DataNode &arg2, VariableOrConstant &result, ControlNode *container) const; + Primitive *specializeVarConst(DataNode &arg1, T arg2, VariableOrConstant &result, ControlNode *container) const; + + FRemBuilder(PrimitiveOperation op): BinarySpecializedBuilder(op) {} +}; + +extern const FRemBuilder builder_Rem_FFF; +extern const FRemBuilder builder_Rem_DDD; + + +// ---------------------------------------------------------------------------- +// ShiftBuilder +// Builder of arithmetic and logical shifts + +enum ShiftDir {sdLeft, sdRightArithmetic, sdRightLogical, sdSignedExtract}; + +template +struct ShiftBuilder: BinarySpecializedBuilder +{ + const ShiftDir shiftDir; + + void evaluate(T arg1, Int32 arg2, T &result) const; + Primitive *specializeConstVar(T arg1, DataNode &arg2, VariableOrConstant &result, ControlNode *container) const; + Primitive *specializeVarConst(DataNode &arg1, Int32 arg2, VariableOrConstant &result, ControlNode *container) const; + + ShiftBuilder(PrimitiveOperation op, ShiftDir shiftDir); +}; + +extern const ShiftBuilder builder_Shl_III; +extern const ShiftBuilder builder_Shl_LIL; +extern const ShiftBuilder builder_Shr_III; +extern const ShiftBuilder builder_Shr_LIL; +extern const ShiftBuilder builder_UShr_III; +extern const ShiftBuilder builder_UShr_LIL; +extern const ShiftBuilder builder_Ext_III; +extern const ShiftBuilder builder_Ext_LIL; + + +// ---------------------------------------------------------------------------- +// LogicalBuilder +// Builder of homogeneous logical operations + +enum LogicalOp {loAnd, loOr, loXor}; + +template +struct LogicalBuilder: CommutativeBuilder +{ + const LogicalOp logicalOp; // The logical operation op that this builder builds + const T identity; // A value i such that for all x: x op i, i op x, and x are all equal. + const T annihilator; // A value a such that for all x: x op a, a op x, and a are all equal. + // If there is no such a, set annihilator to the same value as identity. + + void evaluate(T arg1, T arg2, T &result) const; + Primitive *specializeVarConst(DataNode &arg1, T arg2, VariableOrConstant &result, ControlNode *container) const; + + LogicalBuilder(PrimitiveOperation op, LogicalOp logicalOp, T identity, T annihilator); +}; + +extern const LogicalBuilder builder_And_III; +extern const LogicalBuilder builder_And_LLL; +extern const LogicalBuilder builder_Or_III; +extern const LogicalBuilder builder_Or_LLL; +extern const LogicalBuilder builder_Xor_III; +extern const LogicalBuilder builder_Xor_LLL; + + +// ---------------------------------------------------------------------------- +// ComparisonBuilder +// Builder of two-argument comparisons + +template +struct ComparisonBuilder: BinarySpecializedBuilder +{ + const bool isUnsigned; // Is the comparison unsigned? + const bool equalityOnly; // Do we only care about equality/inequality? + + void evaluate(T arg1, T arg2, Condition &result) const; + Primitive *specializeConstVar(T arg1, DataNode &arg2, VariableOrConstant &result, ControlNode *container) const; + Primitive *specializeVarConst(DataNode &arg1, T arg2, VariableOrConstant &result, ControlNode *container) const; + Primitive *makeTwoProducerGeneric(const VariableOrConstant *args, VariableOrConstant &result, ControlNode *container) const; + + ComparisonBuilder(PrimitiveOperation op, bool isUnsigned, bool equalityOnly); +}; + +extern const ComparisonBuilder builder_Cmp_IIC; +extern const ComparisonBuilder builder_Cmp_LLC; +extern const ComparisonBuilder builder_Cmp_FFC; +extern const ComparisonBuilder builder_Cmp_DDC; + +extern const ComparisonBuilder builder_CmpU_IIC; +extern const ComparisonBuilder builder_CmpU_AAC; + +// Same as Cmp or CmpU except that the comparison only compares for equality +// so the resulting condition is always either cEq or cUn; these may be slightly +// faster than Cmp or CmpU when they do apply. +extern const ComparisonBuilder builder_CmpEq_IIC; +extern const ComparisonBuilder builder_CmpUEq_AAC; + + +// ---------------------------------------------------------------------------- +// Cond2Builder +// Builder of two-argument two-way conditionals that yield an integer + +class Cond2Builder: public BinaryBuilder +{ + const PrimitiveOperation opNormal ENUM_16; // Kind of condition primitive when the comparison is done normally + const PrimitiveOperation opReverse ENUM_16; // Kind of condition primitive when the comparison's arguments are reversed + const BinaryBuilder &comparer; // Builder of the comparison + + public: + Primitive *makeBinaryGeneric(const VariableOrConstant *args, VariableOrConstant &result, ControlNode *container) const; + + Cond2Builder(PrimitiveOperation opNormal, PrimitiveOperation opReverse, const BinaryBuilder &comparer); +}; + +extern const Cond2Builder builder_Eq_III; +extern const Cond2Builder builder_Ne_III; +extern const Cond2Builder builder_Lt_III; +extern const Cond2Builder builder_Ge_III; +extern const Cond2Builder builder_Gt_III; +extern const Cond2Builder builder_Le_III; +extern const Cond2Builder builder_LtU_III; +extern const Cond2Builder builder_GeU_III; +extern const Cond2Builder builder_GtU_III; +extern const Cond2Builder builder_LeU_III; +extern const Cond2Builder builder_Eq_AAI; +extern const Cond2Builder builder_Ne_AAI; + + +// ---------------------------------------------------------------------------- +// Cond3Builder +// Builder of two-argument three-way conditionals that yield an integer + +class Cond3Builder: public BinaryBuilder +{ + const PrimitiveOperation opNormal ENUM_16; // Kind of condition primitive when the comparison is done normally + const PrimitiveOperation opReverse ENUM_16; // Kind of condition primitive when the comparison's arguments are reversed + const BinaryBuilder &comparer; // Builder of the comparison + + public: + Primitive *makeBinaryGeneric(const VariableOrConstant *args, VariableOrConstant &result, ControlNode *container) const; + + Cond3Builder(PrimitiveOperation opNormal, PrimitiveOperation opReverse, const BinaryBuilder &comparer); +}; + +extern const Cond3Builder builder_Cmp3_LLI; +extern const Cond3Builder builder_Cmp3L_FFI; +extern const Cond3Builder builder_Cmp3G_FFI; +extern const Cond3Builder builder_Cmp3L_DDI; +extern const Cond3Builder builder_Cmp3G_DDI; + + +// ---------------------------------------------------------------------------- +// TestBuilder +// Builder of one-argument three-way and two-way comparisons against zero + +template +class TestBuilder: public UnaryBuilder +{ + const BinaryBuilder &condBuilder; // Two-argument version of the same comparison + + public: + Primitive *makeUnaryGeneric(const VariableOrConstant &arg, VariableOrConstant &result, ControlNode *container) const; + + explicit TestBuilder(const BinaryBuilder &condBuilder); +}; + +extern const TestBuilder builder_Eq0_II; +extern const TestBuilder builder_Ne0_II; +extern const TestBuilder builder_Lt0_II; +extern const TestBuilder builder_Ge0_II; +extern const TestBuilder builder_Gt0_II; +extern const TestBuilder builder_Le0_II; +extern const TestBuilder builder_Eq0_AI; +extern const TestBuilder builder_Ne0_AI; + + +// ---------------------------------------------------------------------------- +// Check primitive builders + +enum CheckResult {chkAlwaysOK, chkNeverOK, chkMaybeOK}; + +CheckResult makeChkNull(const VariableOrConstant &arg, Primitive *&prim, + ControlNode *container, Uint32 bci); +CheckResult makeLimit(const VariableOrConstant &arg1, const VariableOrConstant &arg2, Primitive *&prim, ControlNode *container); +Primitive *makeChkCastI(DataNode &arg1, DataNode &arg2, ControlNode *container); +Primitive *makeChkCastA(DataNode &dp, const Type &type, ControlNode *container); +CheckResult makeLimCast(const VariableOrConstant &arg1, Int32 limit, Primitive *&prim, ControlNode *container); + + +// ---------------------------------------------------------------------------- +// LoadBuilder +// Builder of memory loads + +class LoadBuilder +{ + const PrimitiveOperation op ENUM_16; // Kind of load primitive + const TypeKind outputType ENUM_8; // The type of the value that we're loading + + PrimLoad *createLoad(PrimitiveOperation op, DataNode **memory, + VariableOrConstant &result, bool isVolatile, bool + isConstant, ControlNode *container, Uint32 bci) + const; + public: + void makeLoad(DataNode **memory, addr address, + VariableOrConstant &result, bool isVolatile, + bool isConstant, ControlNode *container, Uint32 bci) const; + void makeLoad(DataNode **memory, const VariableOrConstant &address, + VariableOrConstant &result, bool isVolatile, + bool isConstant, ControlNode *container, Uint32 bci) const; + + LoadBuilder(PrimitiveOperation op, TypeKind outputType); +}; + +extern const LoadBuilder builder_Ld_AI; +extern const LoadBuilder builder_Ld_AL; +extern const LoadBuilder builder_Ld_AF; +extern const LoadBuilder builder_Ld_AD; +extern const LoadBuilder builder_Ld_AA; +extern const LoadBuilder builder_LdS_AB; +extern const LoadBuilder builder_LdS_AH; +extern const LoadBuilder builder_LdU_AB; +extern const LoadBuilder builder_LdU_AH; + + +// ---------------------------------------------------------------------------- +// StoreBuilder +// Builder of memory stores + +class StoreBuilder +{ + const PrimitiveOperation opPure ENUM_16; // Kind of store primitive when the arguments are variables + const ValueKind inputKind ENUM_8; // The kind of the value that we're storing + + public: + Primitive &makeStore(DataNode &memoryIn, const VariableOrConstant + &address, const VariableOrConstant &value, + bool isVolatile, ControlNode *container, Uint32 bci) + const; + + StoreBuilder(PrimitiveOperation opPure, ValueKind inputKind); +}; + +extern const StoreBuilder builder_St_AB; +extern const StoreBuilder builder_St_AH; +extern const StoreBuilder builder_St_AI; +extern const StoreBuilder builder_St_AL; +extern const StoreBuilder builder_St_AF; +extern const StoreBuilder builder_St_AD; +extern const StoreBuilder builder_St_AA; + +// ---------------------------------------------------------------------------- +// Monitor primitive builders + +Primitive &makeMonitorPrimitive(PrimitiveOperation op, DataNode &memoryIn, const VariableOrConstant &arg, Uint32 slot, + ControlNode *container, Uint32 bci); + + +// ---------------------------------------------------------------------------- +// Call builders + +// Use the checked inline version below instead of this makeSysCall. +Primitive &makeSysCall(const SysCall &sysCall, DataNode **memory, const VariableOrConstant *args, + VariableOrConstant *results, ControlNode &container, Uint32 bci); + +inline Primitive &makeSysCall(const SysCall &sysCall, DataNode **memory, uint DEBUG_ONLY(nArgs), const VariableOrConstant *args, + uint DEBUG_ONLY(nResults), VariableOrConstant *results, ControlNode &container, Uint32 bci) +{ + assert(nArgs == sysCall.nInputs - sysCall.hasMemoryInput() && + nResults == sysCall.nOutputs - sysCall.hasMemoryOutput() && + sysCall.hasMemoryInput() == (memory != 0) && + sysCall.hasMemoryOutput() == (memory != 0)); + return makeSysCall(sysCall, memory, args, results, container, bci); +} + + +Primitive &makeCall(const Signature &sig, DataNode *&memory, const VariableOrConstant &function, const Method *method, + const VariableOrConstant *args, VariableOrConstant *results, ControlNode &container, Uint32 bci); + +#endif diff --git a/ef/Compiler/PrimitiveGraph/PrimitiveGraphVerifier.cpp b/ef/Compiler/PrimitiveGraph/PrimitiveGraphVerifier.cpp new file mode 100644 index 000000000000..af6edf6c028c --- /dev/null +++ b/ef/Compiler/PrimitiveGraph/PrimitiveGraphVerifier.cpp @@ -0,0 +1,599 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#include "ControlGraph.h" +#include "GraphUtils.h" + +#ifdef DEBUG + +UT_DEFINE_LOG_MODULE(GraphVerifier); + +//#define CARRY_ON_VERIFYING + +#ifdef CARRY_ON_VERIFYING +#define VERIFY_ASSERT(cond) ( (!(cond)) ? UT_LOG(GraphVerifier, PR_LOG_ALWAYS, ("Verify failure - '%s' @ %s %d \n", #cond, __FILE__, __LINE__)) : 0 ) +#else +#define VERIFY_ASSERT(cond) assert((cond)) +#endif + + + +void ControlGraph::validate() +{ + UT_LOG(GraphVerifier, PR_LOG_ALWAYS, ("\n*** Verifying control graph 0x%p\n", this)); + + + VERIFY_ASSERT(!controlNodes.empty()); + VERIFY_ASSERT(nNodes >= 2); + + dfsSearch(); // we use the dfs numbers to enforce the backward edge constraint, and as indices + // into handy-dandy tables of marks and reachingSets, thus... + + Uint32 *connectedSearchMark = new Uint32[nNodes]; + FastBitSet **reachingSet = new FastBitSet *[nNodes]; + + + // prove that there's only one begin and end node, and optionally one return node, + // and that they're on the graph + bool foundBeginNode = false, foundEndNode = false, foundReturnNode = false; + DoublyLinkedList::iterator cni; + Uint32 controlNodeCount = 0; + for (cni = controlNodes.begin(); !controlNodes.done(cni); cni = controlNodes.advance(cni)) + { + ControlNode &cn = controlNodes.get(cni); + controlNodeCount++; + connectedSearchMark[cn.dfsNum] = ControlNode::unmarked; // prepare for the connected search below + if (cn.hasControlKind(ckBegin)) { + VERIFY_ASSERT(!foundBeginNode); /* CONSTRAINT 'BEGIN1' */ + VERIFY_ASSERT(&cn == &beginNode); + foundBeginNode = true; + } + if (cn.hasControlKind(ckEnd)) { + VERIFY_ASSERT(!foundEndNode); /* CONSTRAINT 'END1' */ + VERIFY_ASSERT(&cn == &endNode); + foundEndNode = true; + } + if (cn.hasControlKind(ckReturn)) { + VERIFY_ASSERT(!foundReturnNode); /* CONSTRAINT 'RETURN1' */ + VERIFY_ASSERT(&cn == returnNode); + foundReturnNode = true; + } + } + VERIFY_ASSERT(foundBeginNode); /* CONSTRAINT 'BEGIN1' */ + VERIFY_ASSERT(foundEndNode); /* CONSTRAINT 'END1' */ + + + // following only the forward edges, mark every reached node, starting with the begin node + ControlNode **stack = new ControlNode *[controlNodeCount]; + ControlNode **sp = stack; + *sp++ = &beginNode; + Uint32 markedCount = 0; + while (sp != stack) { + ControlNode *n = *--sp; + connectedSearchMark[n->dfsNum] = 1; // 'marked' + markedCount++; + for (ControlEdge *s = n->getSuccessorsBegin(); s != n->getSuccessorsEnd(); s++) { + if (n->dfsNum < s->getTarget().dfsNum) { // a forward edge + if (connectedSearchMark[s->getTarget().dfsNum] == ControlNode::unmarked) { + connectedSearchMark[s->getTarget().dfsNum] = ControlNode::unvisited; + // so that this doesn't get pushed twice + *sp++ = &s->getTarget(); + assert(sp < &stack[controlNodeCount]); + } + } + } + } + // now assert that every node on the graph was marked + if (markedCount != controlNodeCount) + VERIFY_ASSERT(false); + for (cni = controlNodes.begin(); !controlNodes.done(cni); cni = controlNodes.advance(cni)) + { + ControlNode &cn = controlNodes.get(cni); + VERIFY_ASSERT(connectedSearchMark[cn.dfsNum] == 1); /* CONSTRAINT 'CONNECTED1' */ + connectedSearchMark[cn.dfsNum] = ControlNode::unmarked; // prepare for the next search, below + } + + // likewise, but starting with the end node and reach back through all the predecessor links + markedCount = 0; + sp = stack; + *sp++ = &endNode; + while (sp != stack) { + ControlNode *n = *--sp; + connectedSearchMark[n->dfsNum] = 1; // 'marked' + markedCount++; + const DoublyLinkedList &nPredecessors = n->getPredecessors(); + for (DoublyLinkedList::iterator predi = nPredecessors.begin(); + !nPredecessors.done(predi); + predi = nPredecessors.advance(predi)) { + ControlEdge &e = nPredecessors.get(predi); + if (connectedSearchMark[e.getSource().dfsNum] == ControlNode::unmarked) { + connectedSearchMark[e.getSource().dfsNum] = ControlNode::unvisited; + *sp++ = &e.getSource(); + assert(sp < &stack[controlNodeCount]); + } + } + } + // again, assert that every node was marked + if (markedCount != controlNodeCount) + VERIFY_ASSERT(false); + for (cni = controlNodes.begin(); !controlNodes.done(cni); cni = controlNodes.advance(cni)) + { + ControlNode &cn = controlNodes.get(cni); + VERIFY_ASSERT(connectedSearchMark[cn.dfsNum] == 1); /* CONSTRAINT 'CONNECTED2' */ + connectedSearchMark[cn.dfsNum] = ControlNode::unmarked; // prepare for the next search, below + } + + // we do a recursive search on all the forward, return and exception edges to spot cycles therein + SearchStackEntry *searchStack = new SearchStackEntry[controlNodeCount]; + SearchStackEntry *stackEnd = searchStack + controlNodeCount; + SearchStackEntry *esp = searchStack; + + // Prepare to visit the root. + ControlEdge *n = beginNode.getSuccessorsBegin(); + ControlEdge *l = beginNode.getSuccessorsEnd(); + + while (true) { + if (n == l) { + // We're done with all successors between n and l, so number the + // source node (which is on the stack) and pop up one level. + // Finish when we've marked the root. + if (esp == searchStack) + break; + --esp; + n = esp->next; + l = esp->limit; + connectedSearchMark[n[-1].getTarget().dfsNum] = 1; + } + else { + // We still have to visit more successors between n and l. Visit the + // next successor and advance n. + // But - only visit successors if the edge is a forward, return or exception edge + if ((n->getSource().dfsNum < n->getTarget().dfsNum) + || (n->getSource().hasControlKind(ckReturn) && n->getTarget().hasControlKind(ckEnd)) + || ((n->getSource().hasControlKind(ckExc) + || n->getSource().hasControlKind(ckAExc) + || n->getSource().hasControlKind(ckThrow)) + && (n->getTarget().hasControlKind(ckEnd) || n->getTarget().hasControlKind(ckCatch)))) { + ControlNode &node = n->getTarget(); + n++; + if (connectedSearchMark[node.dfsNum] == ControlNode::unmarked) { + // Visit the successor, saving the current place on the stack. + connectedSearchMark[node.dfsNum] = ControlNode::unvisited; + assert(esp < stackEnd); + esp->next = n; + esp->limit = l; + esp++; + n = node.getSuccessorsBegin(); + l = node.getSuccessorsEnd(); + } + else + VERIFY_ASSERT(connectedSearchMark[node.dfsNum] == 1); /* CONSTRAINT 'CYCLES1' */ + + } + else + n++; + } + } +#ifndef WIN32 // ***** Visual C++ has a bug in the code for delete[]. + delete[] searchStack; +#endif + + + // in order to prove that every primtive's inputs are available we calculate + // the reaching nodes for each node. Then if an input is not in the current node + // we need simply ask if it's in a reaching node instead. + + + for (cni = controlNodes.begin(); !controlNodes.done(cni); cni = controlNodes.advance(cni)) + { + ControlNode &cn = controlNodes.get(cni); + connectedSearchMark[cn.dfsNum] = ControlNode::unmarked; + } + + sp = stack; + *sp++ = &beginNode; + reachingSet[beginNode.dfsNum] = new FastBitSet(controlNodeCount); + while (sp != stack) { + ControlNode *n = *--sp; + reachingSet[n->dfsNum]->set(n->dfsNum); // reaching ourselves is o.k. and this is the input to the successors + connectedSearchMark[n->dfsNum] = 1; // mark as having been processed + for (ControlEdge *s = n->getSuccessorsBegin(); s != n->getSuccessorsEnd(); s++) { + if (connectedSearchMark[s->getTarget().dfsNum] == ControlNode::unmarked) { // not been processed, ever simply set it to the current + reachingSet[s->getTarget().dfsNum] = new FastBitSet(*reachingSet[n->dfsNum]); + connectedSearchMark[s->getTarget().dfsNum] = ControlNode::unvisited; + *sp++ = &s->getTarget(); + assert(sp < &stack[controlNodeCount]); + } + else { + FastBitSet *old = new FastBitSet(*reachingSet[s->getTarget().dfsNum]); + *reachingSet[s->getTarget().dfsNum] &= *reachingSet[n->dfsNum]; // we intersect because we want pessimistic data + if (*old != *reachingSet[s->getTarget().dfsNum]) { // if we have new data... + if (connectedSearchMark[s->getTarget().dfsNum] != ControlNode::unvisited) { // ...and not already scheduled for visiting + connectedSearchMark[s->getTarget().dfsNum] = ControlNode::unvisited; + *sp++ = &s->getTarget(); // then add it + assert(sp < &stack[controlNodeCount]); + } + } + delete old; // REMIND - better would've been an & operator that returned a 'changed' flag + } + } + } +/* + for (cni = controlNodes.begin(); !controlNodes.done(cni); cni = controlNodes.advance(cni)) + { + ControlNode &cn = controlNodes.get(cni); + fprintf(stderr, "For ControlNode N%d ", cn.dfsNum); + reachingSet[cn.dfsNum]->printPretty(stderr); + } +*/ + + delete stack; + + // ask each control node to validate itself + + for (cni = controlNodes.begin(); !controlNodes.done(cni); cni = controlNodes.advance(cni)) + { + ControlNode &cn = controlNodes.get(cni); + cn.validate(reachingSet); + delete reachingSet[cn.dfsNum]; + } + + delete reachingSet; + delete connectedSearchMark; + + UT_LOG(GraphVerifier, PR_LOG_ALWAYS, ("\n*** Verify succeeded \n\n", this)); + + // REMIND - assert(foundReturnNode == (method != void_return)); how to get the return type ? + // REMIND - assert that all successors/predecessors are in this graph ? + +} + +void ControlNode::validate(FastBitSet **reachingSet) +{ + // check that all contained primitives have this as their container and that all inputs + // to each primtive are available (either precede their use in this node, or come from + // a reaching node) + DoublyLinkedList::iterator pi; + + if (!primitives.empty()) { + for (pi = primitives.begin(); + !primitives.done(pi); + pi = primitives.advance(pi)) { + Primitive& prim = primitives.get(pi); + VERIFY_ASSERT(prim.getContainer() == this); + prim.mark = false; + } + for (pi = primitives.begin(); + !primitives.done(pi); + pi = primitives.advance(pi)) { + Primitive& prim = primitives.get(pi); + VERIFY_ASSERT(prim.getContainer() == this); + for (DataConsumer *input = prim.getInputsBegin(); input != prim.getInputsEnd(); input++) { + if (input->isVariable()) { + if (input->getVariable().getContainer() == this) { + VERIFY_ASSERT(input->getVariable().mark); + } + else { + VERIFY_ASSERT(reachingSet[dfsNum]->test(input->getVariable().getContainer()->dfsNum)); + } + } + } + prim.mark = true; + } + } + + // count the number of incoming/outgoing exception, normal and backward (etc) edges + + Uint32 incomingExceptionEdges = 0, incomingNormalEdges = 0, incomingBackwardEdges = 0, incomingReturnEdges = 0; + Uint32 outgoingExceptionEdges = 0, outgoingNormalEdges = 0, outgoingEndEdges = 0; + + if (!predecessors.empty()) { + for (DoublyLinkedList::iterator predi = predecessors.begin(); + !predecessors.done(predi); + predi = predecessors.advance(predi)) { + ControlEdge &e = predecessors.get(predi); + if (e.getSource().dfsNum > dfsNum) incomingBackwardEdges++; + if (e.getSource().hasControlKind(ckReturn)) + incomingReturnEdges++; + else + if (e.getSource().hasControlKind(ckThrow)) + incomingExceptionEdges++; + else + if (e.getSource().hasControlKind(ckExc) || e.getSource().hasControlKind(ckAExc)) // the first successor from an Exc node is normal + if (&e.getSource().getSuccessorsBegin()->getTarget() == this) + incomingNormalEdges++; + else + incomingExceptionEdges++; + else + incomingNormalEdges++; + } + } + for (ControlEdge *successor = successorsBegin; successor != successorsEnd; successor++) { + if (successor->getTarget().hasControlKind(ckCatch)) + outgoingExceptionEdges++; + else + if (successor->getTarget().hasControlKind(ckEnd)) + outgoingEndEdges++; + else + outgoingNormalEdges++; + } + + if (!hasExceptionInputs(controlKind)) VERIFY_ASSERT(incomingExceptionEdges == 0); /* CONSTRAINT 'BEGIN3' */ + if (!hasNormalInputs(controlKind)) VERIFY_ASSERT(incomingNormalEdges == 0); /* CONSTRAINT 'BEGIN3', 'END2' */ + if (!hasExceptionOutgoingEdges(controlKind)) VERIFY_ASSERT(outgoingExceptionEdges == 0); /* CONSTRAINT 'END3', 'EDGE2' */ + if (!hasNormalOutgoingEdges(controlKind)) VERIFY_ASSERT(outgoingNormalEdges == 0); /* CONSTRAINT 'END3' */ + if (hasOneNormalOutgoingEdge(controlKind)) VERIFY_ASSERT(outgoingNormalEdges == 1); /* CONSTRAINT 'BEGIN2' */ + if (controlKind != ckEnd) VERIFY_ASSERT(incomingReturnEdges == 0); /* CONSTRAINT 'BEGIN3', 'END2' */ + if (controlKind == ckReturn) VERIFY_ASSERT(outgoingEndEdges == 1); /* CONSTRAINT 'RETURN2' */ + else + if ((controlKind != ckAExc) + && (controlKind != ckExc) + && (controlKind != ckThrow)) VERIFY_ASSERT(outgoingEndEdges == 0); /* CONSTRAINT 'END3', 'RETURN2' */ + if (controlKind != ckAExc) VERIFY_ASSERT(incomingBackwardEdges == 0); /* CONSTRAINT 'EDGE1' */ + + if ((controlKind != ckBegin) && (controlKind != ckEnd) && (controlKind != ckCatch)) { + Uint32 totalOutgoingEdges = outgoingExceptionEdges + outgoingNormalEdges + outgoingEndEdges; + ControlNode &theSuccessorNode = successorsBegin->getTarget(); + if ((totalOutgoingEdges == 1) + && (!theSuccessorNode.hasControlKind(ckEnd)) + && (!theSuccessorNode.hasControlKind(ckCatch))) { + // this node has a single output, prove that it's successor has more than a single input + const DoublyLinkedList &theSuccessorsPredecessors = theSuccessorNode.getPredecessors(); + DoublyLinkedList::iterator predi = theSuccessorsPredecessors.begin(); + predi = theSuccessorsPredecessors.advance(predi); + VERIFY_ASSERT(!theSuccessorsPredecessors.done(predi)); /* CONSTRAINT 'COALESCE1' */ + } + } + + // now perform control-kind specific primitive checks... + switch (controlKind) { + case ckNone : // shouldn't have any of these + VERIFY_ASSERT(false); + break; + case ckBegin : // all primitives are Args + { + for (DoublyLinkedList::iterator pi = primitives.begin(); + !primitives.done(pi); + pi = primitives.advance(pi)) { + Primitive& prim = primitives.get(pi); + VERIFY_ASSERT(prim.hasCategory(pcArg)); + } + // REMIND - assert that the correct number of args is here (does it equal beginExtra.nArguments ?) + // REMIND - assert that a memory arg is present ? + } + break; + case ckEnd : // only a result memory primitive (and maybe a phi for it) + { + bool foundTheResult = false; + for (DoublyLinkedList::iterator pi = primitives.begin(); + !primitives.done(pi); + pi = primitives.advance(pi)) { + Primitive& prim = primitives.get(pi); + if (prim.hasOperation(poResult_M)) { + VERIFY_ASSERT(!foundTheResult); // insist on only one such + foundTheResult = true; + } + else + VERIFY_ASSERT(prim.hasOperation(poPhi_M)); + } + VERIFY_ASSERT(foundTheResult); + } + break; + case ckBlock : // no exception raising primitives, no control flow primitives + { + for (DoublyLinkedList::iterator pi = primitives.begin(); + !primitives.done(pi); + pi = primitives.advance(pi)) { + Primitive& prim = primitives.get(pi); + VERIFY_ASSERT(!prim.hasFormat(pfControl)); + VERIFY_ASSERT(!prim.canRaiseException()); + } + } + break; + case ckIf : // exactly two exits + { // no exception raising primitives, no control flow primitives other than the one If + VERIFY_ASSERT(successorsEnd == (successorsBegin + 2)); + Primitive *theIf = NULL; + for (DoublyLinkedList::iterator pi = primitives.begin(); + !primitives.done(pi); + pi = primitives.advance(pi)) { + Primitive& prim = primitives.get(pi); + if (prim.hasFormat(pfControl)) { + if (prim.hasCategory(pcIfCond)) { + VERIFY_ASSERT(theIf == NULL); + theIf = &prim; + } + else + VERIFY_ASSERT(false); + } + VERIFY_ASSERT(!prim.canRaiseException()); + } + VERIFY_ASSERT(theIf != NULL); + // the source for the if condition must be in the same control node + VERIFY_ASSERT(theIf->nthInputVariable(0).getContainer() == this); + } + break; + case ckSwitch : // no exception raising primitives, no control flow primitives other than the one Switch + { + bool foundTheSwitch = false; + for (DoublyLinkedList::iterator pi = primitives.begin(); + !primitives.done(pi); + pi = primitives.advance(pi)) { + Primitive& prim = primitives.get(pi); + if (prim.hasFormat(pfControl)) { + if (prim.hasCategory(pcSwitch)) { + VERIFY_ASSERT(!foundTheSwitch); + foundTheSwitch = true; + } + else + VERIFY_ASSERT(false); + } + VERIFY_ASSERT(!prim.canRaiseException()); + } + VERIFY_ASSERT(foundTheSwitch); + } + break; + case ckAExc : // no exception raising primitives, no control nodes + { + for (DoublyLinkedList::iterator pi = primitives.begin(); + !primitives.done(pi); + pi = primitives.advance(pi)) { + Primitive& prim = primitives.get(pi); + VERIFY_ASSERT(!prim.hasFormat(pfControl)); + VERIFY_ASSERT(!prim.canRaiseException()); + } + } + break; + case ckThrow : // contains no control primitives + { + for (DoublyLinkedList::iterator pi = primitives.begin(); + !primitives.done(pi); + pi = primitives.advance(pi)) { + Primitive& prim = primitives.get(pi); + VERIFY_ASSERT(!prim.hasFormat(pfControl)); + } + } + break; + case ckExc : // contains only one exception raising primitive, no control primitives + { + bool foundTheExceptionPrimitive = false; + for (DoublyLinkedList::iterator pi = primitives.begin(); + !primitives.done(pi); + pi = primitives.advance(pi)) { + Primitive& prim = primitives.get(pi); + VERIFY_ASSERT(!prim.hasFormat(pfControl)); + if (prim.canRaiseException()) { + VERIFY_ASSERT(!foundTheExceptionPrimitive); + foundTheExceptionPrimitive = true; + } + } + if (!foundTheExceptionPrimitive) { + printPretty(UT_LOG_MODULE(GraphVerifier), 0); + } + VERIFY_ASSERT(foundTheExceptionPrimitive); + } + break; + case ckCatch : // at most one primitive, must be a catch (with optional phi's), no control primitives + { + bool foundTheCatch = false; + for (DoublyLinkedList::iterator pi = primitives.begin(); + !primitives.done(pi); + pi = primitives.advance(pi)) { + Primitive& prim = primitives.get(pi); + VERIFY_ASSERT(!prim.hasFormat(pfControl)); + if (prim.hasCategory(pcCatch)) { + VERIFY_ASSERT(!foundTheCatch); + foundTheCatch = true; + } + else + VERIFY_ASSERT(prim.hasCategory(pcPhi)); + } + VERIFY_ASSERT(foundTheCatch); + } + break; + case ckReturn : // no exception raising primitives, no control flow primitives + { + for (DoublyLinkedList::iterator pi = primitives.begin(); + !primitives.done(pi); + pi = primitives.advance(pi)) { + Primitive& prim = primitives.get(pi); + VERIFY_ASSERT(!prim.hasFormat(pfControl)); + VERIFY_ASSERT(!prim.canRaiseException()); + } + } + break; + default : + VERIFY_ASSERT(false); + break; + } + + // make sure that all a primitive's inputs come from primitives outside of this node + // or one that is before the primitive within the control node + + + // now ask each contained primitive to validate itself + + for (pi = primitives.begin(); + !primitives.done(pi); + pi = primitives.advance(pi)) { + Primitive& prim = primitives.get(pi); + prim.validate(); + } + +} + +void DataNode::validate() +{ + InputConstraintPattern theConstraint = inputConstraintPatterns[operation]; + + int inputIndex = 0; + DataConsumer *input = inputsBegin; + if (input == NULL) { + if (theConstraint.nInputConstraints != 0) + printPretty(UT_LOG_MODULE(GraphVerifier), 0); + VERIFY_ASSERT(theConstraint.nInputConstraints == 0); + } + else + while (true) { + +// something about tuples and exceptions ???? + + VERIFY_ASSERT((theConstraint.inputConstraints[inputIndex].kind == vkVoid) + || (input->getKind() == theConstraint.inputConstraints[inputIndex].kind)); + /* + if (! ((theConstraint.inputConstraints[inputIndex].origin == aoEither) + || (input->isVariable() == (theConstraint.inputConstraints[inputIndex].origin == aoVariable))) ) + printPretty(UT_LOG_MODULE(GraphVerifier), 0); +*/ + VERIFY_ASSERT((theConstraint.inputConstraints[inputIndex].origin == aoEither) + || (input->isVariable() == (theConstraint.inputConstraints[inputIndex].origin == aoVariable))); + inputIndex++; + input++; + if (inputIndex == theConstraint.nInputConstraints) { + if (input == inputsEnd) + break; // all's well, and we ended together + else + if (theConstraint.repeat) + inputIndex--; // keep matching on the last pattern + else + VERIFY_ASSERT(false); // there are no more patterns, but there are more inputs + } + else { + // if we still have more patterns, make sure there are inputs to match OR that we're on + // the 'zero or more times' repeatable last pattern and in which case, break out of the loop. + if (input == inputsEnd) { + VERIFY_ASSERT((inputIndex == (theConstraint.nInputConstraints - 1)) && theConstraint.repeat); + break; + } + } + } + +} + +void PrimConst::validate() +{ + InputConstraintPattern theConstraint = getInputConstraintPattern(); + VERIFY_ASSERT(theConstraint.inputConstraints[0].origin == aoConstant); + + if (getKind() != theConstraint.inputConstraints[0].kind) { + printPretty(UT_LOG_MODULE(GraphVerifier), 0); + } + VERIFY_ASSERT(getKind() == theConstraint.inputConstraints[0].kind); +} + + +#endif // DEBUG diff --git a/ef/Compiler/PrimitiveGraph/PrimitiveOperations b/ef/Compiler/PrimitiveGraph/PrimitiveOperations new file mode 100644 index 000000000000..dbac81ba0762 --- /dev/null +++ b/ef/Compiler/PrimitiveGraph/PrimitiveOperations @@ -0,0 +1,353 @@ +// -*- 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.0 (the "NPL"); you may not use this file except in +// compliance with the NPL. You may obtain a copy of the NPL at +// http://www.mozilla.org/NPL/ +// +// Software distributed under the NPL is distributed on an "AS IS" basis, +// WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +// for the specific language governing rights and limitations under the +// NPL. +// +// The Initial Developer of this code under the NPL is Netscape +// Communications Corporation. Portions created by Netscape are +// Copyright (C) 1998 Netscape Communications Corporation. All Rights +// Reserved. +// +// Here's the syntax of the PrimitiveOperations table entries expressed as a BNF grammar. +// These entries are converted into several different tables inside DataNodeTemplates.cpp +// and PrimitiveOperations.h. +// +// table-entry ::= '{' primitiveOperation ',' primitiveCategory ',' usage '}' +// +// usage ::= '"' outputs ':' inputs '"' | null-usage +// +// null-usage ::= '""' // indicates that this is not a legal primitive +// +// outputs ::= exception | arg | exception arg | root +// +// inputs ::= arg* | arg* repeat-arg | root +// +// repeat-arg ::= arg '*' // zero or more arguments that satisfy the given arg pattern +// +// arg ::= arg-origin arg-kind | short-arg +// +// arg-origin ::= 'V' | // variable +// 'C' | // constant +// 'A' // either variable or constant +// +// arg-kind ::= 'v' | // void +// 'i' | // integer +// 'l' | // long +// 'f' | // float +// 'd' | // double +// 'a' | // address +// 'c' | // condition +// 'm' | // memory +// 't' | // tuple +// '@' // any of the above arg-kinds except memory or tuple +// +// short-arg ::= 'M' | // same as 'Vm' +// 'T' // same as 'Vt' +// +// exception ::= 'E' // flag that indicates that this primitive causes exceptions +// // (sets fnCanRaiseException and fnIsRoot) +// +// root ::= 'Z' // flag that indicates that this primitive is attached to a control node (sets fnIsRoot) +// + +ARG-ORIGIN 'V' aoVariable; +ARG-ORIGIN 'C' aoConstant; +ARG-ORIGIN 'A' aoEither; + +ARG-KIND 'v' vkVoid; +ARG-KIND 'i' vkInt; +ARG-KIND 'l' vkLong; +ARG-KIND 'f' vkFloat; +ARG-KIND 'd' vkDouble; +ARG-KIND 'a' vkAddr; +ARG-KIND 'c' vkCond; +ARG-KIND 'm' vkMemory; +ARG-KIND 't' vkTuple; + +SHORT-ARG 'M' vkMemory; +SHORT-ARG 'T' vkTuple; + + +{poNone, pcNone, ""} + +{poPhi_I, pcPhi, "Vi:Ai*"} // 32-bit integer phi node Aint ... Aint -> Vint +{poPhi_L, pcPhi, "Vl:Al*"} // 64-bit integer phi node Along ... Along -> Vlong +{poPhi_F, pcPhi, "Vf:Af*"} // 32-bit float phi node Afloat ... Afloat -> Vfloat +{poPhi_D, pcPhi, "Vd:Ad*"} // 64-bit float phi node Adouble ... Adouble -> Vdouble +{poPhi_A, pcPhi, "Va:Aa*"} // Pointer phi node Aaddr ... Aaddr -> Vaddr +{poPhi_C, pcPhi, "Vc:Ac*"} // Condition phi node Acond ... Acond -> Vcond +{poPhi_M, pcPhi, "M:M*"} // Memory phi node M ... M -> M + +{poConst_I, pcConst, "Vi:Ci"} // 32-bit integer constant Cint -> Vint +{poConst_L, pcConst, "Vl:Cl"} // 64-bit integer constant Clong -> Vlong +{poConst_F, pcConst, "Vf:Cf"} // 32-bit float constant Cfloat -> Vfloat +{poConst_D, pcConst, "Vd:Cd"} // 64-bit float constant Cdouble -> Vdouble +{poConst_A, pcConst, "Va:Ca"} // Pointer constant Caddr -> Vaddr +{poConst_C, pcConst, "Vc:Cc"} // Condition constant Ccond -> Vcond +{poConst_M, pcConst, "M:Cm"} // Memory constant Cmemory -> M + +{poProj_I, pcProj, "Vi:T"} // 32-bit integer extracted from tuple T -> Vint +{poProj_L, pcProj, "Vl:T"} // 64-bit integer extracted from tuple T -> Vlong +{poProj_F, pcProj, "Vf:T"} // 32-bit float extracted from tuple T -> Vfloat +{poProj_D, pcProj, "Vd:T"} // 64-bit float extracted from tuple T -> Vdouble +{poProj_A, pcProj, "Va:T"} // Pointer extracted from tuple T -> Vaddr +{poProj_C, pcNone, ""} // Condition extracted from tuple T -> Vcond (not used) +{poProj_M, pcProj, "M:T"} // Memory extracted from tuple T -> M + +{poDebug, pcDebug, "M:MA@*"} // Breakpoint M, ... -> M +{poBreak, pcDebug, "M:MA@*"} // Breakpoint M, ... -> M + +{poArg_I, pcArg, "Vi:Z"} // 32-bit integer argument -> Vint +{poArg_L, pcArg, "Vl:Z"} // 64-bit integer argument -> Vlong +{poArg_F, pcArg, "Vf:Z"} // 32-bit float argument -> Vfloat +{poArg_D, pcArg, "Vd:Z"} // 64-bit float argument -> Vdouble +{poArg_A, pcArg, "Va:Z"} // Pointer argument -> Vaddr +{poArg_C, pcNone, ""} // Condition argument -> Vcond (not used) +{poArg_M, pcArg, "M:Z"} // Argument representing all of memory -> M + +{poResult_I, pcResult, "Z:Ai"} // 32-bit integer result Aint -> +{poResult_L, pcResult, "Z:Al"} // 64-bit integer result Along -> +{poResult_F, pcResult, "Z:Af"} // 32-bit float result Afloat -> +{poResult_D, pcResult, "Z:Ad"} // 64-bit float result Adouble -> +{poResult_A, pcResult, "Z:Aa"} // Pointer result Aaddr -> +{poResult_C, pcNone, ""} // Condition result Acond -> (not used) +{poResult_M, pcResult, "Z:M"} // Result representing all of memory M -> + + // Cond lt eq gt un +{poIfLt, pcIfCond, "Z:Vc"} // If condition 1 0 0 0 Vcond -> +{poIfEq, pcIfCond, "Z:Vc"} // If condition 0 1 0 0 Vcond -> +{poIfLe, pcIfCond, "Z:Vc"} // If condition 1 1 0 0 Vcond -> +{poIfGt, pcIfCond, "Z:Vc"} // If condition 0 0 1 0 Vcond -> +{poIfLgt, pcIfCond, "Z:Vc"} // If condition 1 0 1 0 Vcond -> +{poIfGe, pcIfCond, "Z:Vc"} // If condition 0 1 1 0 Vcond -> +{poIfOrd, pcIfCond, "Z:Vc"} // If condition 1 1 1 0 Vcond -> +{poIfUnord, pcIfCond, "Z:Vc"} // If condition 0 0 0 1 Vcond -> +{poIfULt, pcIfCond, "Z:Vc"} // If condition 1 0 0 1 Vcond -> +{poIfUEq, pcIfCond, "Z:Vc"} // If condition 0 1 0 1 Vcond -> +{poIfULe, pcIfCond, "Z:Vc"} // If condition 1 1 0 1 Vcond -> +{poIfUGt, pcIfCond, "Z:Vc"} // If condition 0 0 1 1 Vcond -> +{poIfNe, pcIfCond, "Z:Vc"} // If condition 1 0 1 1 Vcond -> +{poIfUGe, pcIfCond, "Z:Vc"} // If condition 0 1 1 1 Vcond -> + +{poSwitch, pcSwitch, "Z:Vi"} // Switch index node Vint -> + +{poCatch, pcCatch, "Va:Z"} // Catch exception producer -> Vaddr + +{poAnd_I, pcGeneric, "Vi:ViAi"} // Logical AND Vint & Aint -> Vint +{poAnd_L, pcGeneric, "Vl:VlAl"} // Logical AND Vlong & Along -> Vlong + +{poOr_I, pcGeneric, "Vi:ViAi"} // Logical OR Vint | Aint -> Vint +{poOr_L, pcGeneric, "Vl:VlAl"} // Logical OR Vlong | Along -> Vlong + +{poXor_I, pcGeneric, "Vi:ViAi"} // Logical XOR Vint ^ Aint -> Vint +{poXor_L, pcGeneric, "Vl:VlAl"} // Logical XOR Vlong ^ Along -> Vlong + +{poAdd_I, pcGeneric, "Vi:ViAi"} // Add Vint + Aint -> Vint +{poAdd_L, pcGeneric, "Vl:VlAl"} // Add Vlong + Along -> Vlong +{poAdd_A, pcGeneric, "Va:AaAi"} // Add Aaddr + exts(Aint) -> Vaddr +{poAddU_A, pcGeneric, "Va:AaAi"} // Add Aaddr + extu(Aint) -> Vaddr + +{poSub_I, pcGeneric, "Vi:AiVi"} // Subtract Aint - Vint -> Vint +{poSub_L, pcGeneric, "Vl:AlVl"} // Subtract Along - Vlong -> Vlong +{poSub_A, pcGeneric, "Va:AaVi"} // Subtract Aaddr - exts(Vint) -> Vaddr +{poSubU_A, pcGeneric, "Va:AaVi"} // Subtract Aaddr - extu(Vint) -> Vaddr +{poSubA_I, pcGeneric, "Vi:AaAa"} // Subtract addresses Aaddr - Aaddr -> Vint + +{poMul_I, pcGeneric, "Vi:ViAi"} // Multiply Vint * Aint -> Vint +{poMul_L, pcGeneric, "Vl:VlAl"} // Multiply Vlong * Along -> Vlong + +{poDiv_I, pcDivMod, "Vi:AiAi"} // Divide signed Aint /s Aint -> Vint +{poDiv_L, pcDivMod, "Vl:AlAl"} // Divide signed Along /s Along -> Vlong +{poDivE_I, pcDivMod, "EVi:AiVi"} // Divide signed exc Aint /s Vint -> Vint, E +{poDivE_L, pcDivMod, "EVl:AlVl"} // Divide signed exc Along /s Vlong -> Vlong, E +{poDivU_I, pcDivMod, "Vi:AiAi"} // Divide unsigned Aint /u Aint -> Vint +{poDivU_L, pcDivMod, "Vl:AlAl"} // Divide unsigned Along /u Along -> Vlong +{poDivUE_I, pcDivMod, "EVi:AiVi"} // Divide unsigned exc Aint /u Vint -> Vint, E +{poDivUE_L, pcDivMod, "EVl:AlVl"} // Divide unsigned exc Along /u Vlong -> Vlong, E + +{poMod_I, pcDivMod, "Vi:AiAi"} // Modulo signed Aint %s Aint -> Vint +{poMod_L, pcDivMod, "Vl:AlAl"} // Modulo signed Along %s Along -> Vlong +{poModE_I, pcDivMod, "EVi:AiVi"} // Modulo signed exc Aint %s Vint -> Vint, E +{poModE_L, pcDivMod, "EVl:AlVl"} // Modulo signed exc Along %s Vlong -> Vlong, E +{poModU_I, pcDivMod, "Vi:AiAi"} // Modulo unsigned Aint %u Aint -> Vint +{poModU_L, pcDivMod, "Vl:AlAl"} // Modulo unsigned Along %u Along -> Vlong +{poModUE_I, pcDivMod, "EVi:AiVi"} // Modulo unsigned exc Aint %u Vint -> Vint, E +{poModUE_L, pcDivMod, "EVl:AlVl"} // Modulo unsigned exc Along %u Vlong -> Vlong, E + +{poShl_I, pcShift, "Vi:AiAi"} // Shift left Aint << Aint -> Vint +{poShl_L, pcShift, "Vl:AlAi"} // Shift left Along << Aint -> Vlong + +{poShr_I, pcShift, "Vi:AiAi"} // Shift right signed Aint >>s Aint -> Vint +{poShr_L, pcShift, "Vl:AlAi"} // Shift right signed Along >>s Aint -> Vlong +{poShrU_I, pcShift, "Vi:AiAi"} // Shift right unsigned Aint >>u Aint -> Vint +{poShrU_L, pcShift, "Vl:AlAi"} // Shift right unsigned Along >>u Aint -> Vlong + +{poExt_I, pcExt, "Vi:ViCi"} // Signed field extract Vint, Cint -> Vint +{poExt_L, pcExt, "Vl:VlCi"} // Signed field extract Vlong, Cint -> Vlong + +{poFAdd_F, pcFGeneric, "Vf:VfAf"} // FP add Vfloat + Afloat -> Vfloat +{poFAdd_D, pcFGeneric, "Vd:VdAd"} // FP add Vdouble + Adouble -> Vdouble + +{poFSub_F, pcFGeneric, "Vf:AfVf"} // FP subtract Afloat - Vfloat -> Vfloat +{poFSub_D, pcFGeneric, "Vd:AdVd"} // FP subtract Adouble - Vdouble -> Vdouble + +{poFMul_F, pcFGeneric, "Vf:VfAf"} // FP multiply Vfloat * Afloat -> Vfloat +{poFMul_D, pcFGeneric, "Vd:VdAd"} // FP multiply Vdouble * Adouble -> Vdouble + +{poFDiv_F, pcFGeneric, "Vf:AfAf"} // FP divide Afloat / Afloat -> Vfloat +{poFDiv_D, pcFGeneric, "Vd:AdAd"} // FP divide Adouble / Adouble -> Vdouble + +{poFRem_F, pcFGeneric, "Vf:AfAf"} // FP Java remainder Afloat rem Afloat -> Vfloat +{poFRem_D, pcFGeneric, "Vd:AdAd"} // FP Java remainder Adouble rem Adouble -> Vdouble + +{poConvI_L, pcConv, "Vi:Vl"} // Convert Vlong -> Vint +{poConvL_I, pcConv, "Vl:Vi"} // Convert exts(Vint) -> Vlong + +{poFConvI_F, pcFConv, "Vi:Vf"} // FP convert Vfloat -> Vint +{poFConvI_D, pcFConv, "Vi:Vd"} // FP convert Vdouble -> Vint +{poFConvL_F, pcFConv, "Vl:Vf"} // FP convert Vfloat -> Vlong +{poFConvL_D, pcFConv, "Vl:Vd"} // FP convert Vdouble -> Vlong +{poFConvF_I, pcFConv, "Vf:Vi"} // FP convert Vint -> Vfloat +{poFConvF_L, pcFConv, "Vf:Vl"} // FP convert Vlong -> Vfloat +{poFConvF_D, pcFConv, "Vf:Vd"} // FP convert Vdouble -> Vfloat +{poFConvD_I, pcFConv, "Vd:Vi"} // FP convert Vint -> Vdouble +{poFConvD_L, pcFConv, "Vd:Vl"} // FP convert Vlong -> Vdouble +{poFConvD_F, pcFConv, "Vd:Vf"} // FP convert Vfloat -> Vdouble + +{poCmp_I, pcCmp, "Vc:ViAi"} // Compare signed Vint ?s Aint -> Vcond +{poCmp_L, pcCmp, "Vc:VlAl"} // Compare signed Vlong ?s Along -> Vcond +{poCmpU_I, pcCmp, "Vc:ViAi"} // Compare unsigned Vint ?u Aint -> Vcond +{poCmpU_L, pcCmp, "Vc:VlAl"} // Compare unsigned Vlong ?u Along -> Vcond +{poCmpU_A, pcCmp, "Vc:VaAa"} // Compare unsigned Vaddr ?u Aaddr -> Vcond + +{poFCmp_F, pcFCmp, "Vc:VfAf"} // FP compare Vfloat ? Afloat -> Vcond +{poFCmp_D, pcFCmp, "Vc:VdAd"} // FP compare Vdouble ? Adouble -> Vcond + + // Cond lt eq gt un +{poLt_I, pcCond, "Vi:Vc"} // conditional 1 0 0 0 Vcond -> Vint +{poEq_I, pcCond, "Vi:Vc"} // conditional 0 1 0 0 Vcond -> Vint +{poLe_I, pcCond, "Vi:Vc"} // conditional 1 1 0 0 Vcond -> Vint +{poGt_I, pcCond, "Vi:Vc"} // conditional 0 0 1 0 Vcond -> Vint +{poLgt_I, pcCond, "Vi:Vc"} // conditional 1 0 1 0 Vcond -> Vint +{poGe_I, pcCond, "Vi:Vc"} // conditional 0 1 1 0 Vcond -> Vint +{poOrd_I, pcCond, "Vi:Vc"} // conditional 1 1 1 0 Vcond -> Vint +{poUnord_I, pcCond, "Vi:Vc"} // conditional 0 0 0 1 Vcond -> Vint +{poULt_I, pcCond, "Vi:Vc"} // conditional 1 0 0 1 Vcond -> Vint +{poUEq_I, pcCond, "Vi:Vc"} // conditional 0 1 0 1 Vcond -> Vint +{poULe_I, pcCond, "Vi:Vc"} // conditional 1 1 0 1 Vcond -> Vint +{poUGt_I, pcCond, "Vi:Vc"} // conditional 0 0 1 1 Vcond -> Vint +{poNe_I, pcCond, "Vi:Vc"} // conditional 1 0 1 1 Vcond -> Vint +{poUGe_I, pcCond, "Vi:Vc"} // conditional 0 1 1 1 Vcond -> Vint + + // Cond3 lt eq gt un +{poCatL_I, pcCond3, "Vi:Vc"} // conditional -1 0 1 -1 Vcond -> Vint +{poCatG_I, pcCond3, "Vi:Vc"} // conditional -1 0 1 1 Vcond -> Vint +{poCatCL_I, pcCond3, "Vi:Vc"} // conditional 1 0 -1 -1 Vcond -> Vint +{poCatCG_I, pcCond3, "Vi:Vc"} // conditional 1 0 -1 1 Vcond -> Vint + +{poChkNull, pcCheck1, "E:Va"} // Throw NullPointerException if null Vaddr -> E + +{poChkCast_I, pcCheck2, "E:ViAi"} // Throw ClassCastException if != Vint, Aint -> E +{poChkCast_A, pcCheck2, "E:VaAa"} // Throw ClassCastException if != Vaddr, Aaddr -> E + +{poLimit, pcCheck2, "E:AiAi"} // Throw ArrayIndexOutOfBounds if >=u Aint, Aint -> E + +{poLimCast, pcCheck2, "E:ViCi"} // Throw ClassCastException if < Vint, Cint -> E + +{poLd_I, pcLd, "Vi:AmAa"} // Load M, *Aaddr -> Vint +{poLd_L, pcLd, "Vl:AmAa"} // Load M, *Aaddr -> Vlong +{poLd_F, pcLd, "Vf:AmAa"} // Load M, *Aaddr -> Vfloat +{poLd_D, pcLd, "Vd:AmAa"} // Load M, *Aaddr -> Vdouble +{poLd_A, pcLd, "Va:AmAa"} // Load M, *Aaddr -> Vaddr +{poLdE_I, pcLd, "EVi:AmVa"} // Load checked M, *Vaddr -> Vint, E +{poLdE_L, pcLd, "EVl:AmVa"} // Load checked M, *Vaddr -> Vlong, E +{poLdE_F, pcLd, "EVf:AmVa"} // Load checked M, *Vaddr -> Vfloat, E +{poLdE_D, pcLd, "EVd:AmVa"} // Load checked M, *Vaddr -> Vdouble, E +{poLdE_A, pcLd, "EVa:AmVa"} // Load checked M, *Vaddr -> Vaddr, E +{poLdS_B, pcLd, "Vi:AmAa"} // Load signed byte M, exts(*Aaddr) -> Vint +{poLdS_H, pcLd, "Vi:AmAa"} // Load signed halfword M, exts(*Aaddr) -> Vint +{poLdSE_B, pcLd, "EVi:AmVa"} // Load signed checked byte M, exts(*Vaddr) -> Vint, E +{poLdSE_H, pcLd, "EVi:AmVa"} // Load signed checked halfword M, exts(*Vaddr) -> Vint, E +{poLdU_B, pcLd, "Vi:AmAa"} // Load unsigned byte M, extu(*Aaddr) -> Vint +{poLdU_H, pcLd, "Vi:AmAa"} // Load unsigned halfword M, extu(*Aaddr) -> Vint +{poLdUE_B, pcLd, "EVi:AmVa"} // Load unsigned checked byte M, extu(*Vaddr) -> Vint, E +{poLdUE_H, pcLd, "EVi:AmVa"} // Load unsigned checked halfword M, extu(*Vaddr) -> Vint, E +{poLdV_I, pcLd, "T:MAa"} // Load volatile M, *Aaddr -> M, Vint +{poLdV_L, pcLd, "T:MAa"} // Load volatile M, *Aaddr -> M, Vlong +{poLdV_F, pcLd, "T:MAa"} // Load volatile M, *Aaddr -> M, Vfloat +{poLdV_D, pcLd, "T:MAa"} // Load volatile M, *Aaddr -> M, Vdouble +{poLdV_A, pcLd, "T:MAa"} // Load volatile M, *Aaddr -> M, Vaddr +{poLdVE_I, pcLd, "ET:MVa"} // Load volatile checked M, *Vaddr -> M, Vint, E +{poLdVE_L, pcLd, "ET:MVa"} // Load volatile checked M, *Vaddr -> M, Vlong, E +{poLdVE_F, pcLd, "ET:MVa"} // Load volatile checked M, *Vaddr -> M, Vfloat, E +{poLdVE_D, pcLd, "ET:MVa"} // Load volatile checked M, *Vaddr -> M, Vdouble, E +{poLdVE_A, pcLd, "ET:MVa"} // Load volatile checked M, *Vaddr -> M, Vaddr, E +{poLdVS_B, pcLd, "T:MAa"} // Load volatile signed byte M, exts(*Aaddr) -> M, Vint +{poLdVS_H, pcLd, "T:MAa"} // Load volatile signed halfword M, exts(*Aaddr) -> M, Vint +{poLdVSE_B, pcLd, "ET:MVa"} // Load volatile signed checked byte M, exts(*Vaddr) -> M, Vint, E +{poLdVSE_H, pcLd, "ET:MVa"} // Load volatile signed checked hfwrd M, exts(*Vaddr) -> M, Vint, E +{poLdVU_B, pcLd, "T:MAa"} // Load volatile unsigned byte M, extu(*Aaddr) -> M, Vint +{poLdVU_H, pcLd, "T:MAa"} // Load volatile unsigned halfword M, extu(*Aaddr) -> M, Vint +{poLdVUE_B, pcLd, "ET:MVa"} // Load volatile unsigned checked byte M, extu(*Vaddr) -> M, Vint, E +{poLdVUE_H, pcLd, "ET:MVa"} // Load volatile unsigned checked hfwrd M, extu(*Vaddr) -> M, Vint, E + +{poSt_B, pcSt, "M:MAaAi"} // Store byte M, Aaddr, Aint -> M +{poSt_H, pcSt, "M:MAaAi"} // Store halfword M, Aaddr, Aint -> M +{poSt_I, pcSt, "M:MAaAi"} // Store M, Aaddr, Aint -> M +{poSt_L, pcSt, "M:MAaAl"} // Store M, Aaddr, Along -> M +{poSt_F, pcSt, "M:MAaAf"} // Store M, Aaddr, Afloat -> M +{poSt_D, pcSt, "M:MAaAd"} // Store M, Aaddr, Adouble -> M +{poSt_A, pcSt, "M:MAaAa"} // Store M, Aaddr, Aaddr -> M +{poStE_B, pcSt, "EM:MVaAi"} // Store byte checked M, Vaddr, Aint -> M, E +{poStE_H, pcSt, "EM:MVaAi"} // Store halfword checked M, Vaddr, Aint -> M, E +{poStE_I, pcSt, "EM:MVaAi"} // Store checked M, Vaddr, Aint -> M, E +{poStE_L, pcSt, "EM:MVaAl"} // Store checked M, Vaddr, Along -> M, E +{poStE_F, pcSt, "EM:MVaAf"} // Store checked M, Vaddr, Afloat -> M, E +{poStE_D, pcSt, "EM:MVaAd"} // Store checked M, Vaddr, Adouble -> M, E +{poStE_A, pcSt, "EM:MVaAa"} // Store checked M, Vaddr, Aaddr -> M, E +{poStV_B, pcSt, "M:MAaAi"} // Store volatile byte M, Aaddr, Aint -> M +{poStV_H, pcSt, "M:MAaAi"} // Store volatile halfword M, Aaddr, Aint -> M +{poStV_I, pcSt, "M:MAaAi"} // Store volatile M, Aaddr, Aint -> M +{poStV_L, pcSt, "M:MAaAl"} // Store volatile M, Aaddr, Along -> M +{poStV_F, pcSt, "M:MAaAf"} // Store volatile M, Aaddr, Afloat -> M +{poStV_D, pcSt, "M:MAaAd"} // Store volatile M, Aaddr, Adouble -> M +{poStV_A, pcSt, "M:MAaAa"} // Store volatile M, Aaddr, Aaddr -> M +{poStVE_B, pcSt, "EM:MVaAi"} // Store volatile byte checked M, Vaddr, Aint -> M, E +{poStVE_H, pcSt, "EM:MVaAi"} // Store volatile halfword checked M, Vaddr, Aint -> M, E +{poStVE_I, pcSt, "EM:MVaAi"} // Store volatile checked M, Vaddr, Aint -> M, E +{poStVE_L, pcSt, "EM:MVaAl"} // Store volatile checked M, Vaddr, Along -> M, E +{poStVE_F, pcSt, "EM:MVaAf"} // Store volatile checked M, Vaddr, Afloat -> M, E +{poStVE_D, pcSt, "EM:MVaAd"} // Store volatile checked M, Vaddr, Adouble -> M, E +{poStVE_A, pcSt, "EM:MVaAa"} // Store volatile checked M, Vaddr, Aaddr -> M, E + +{poMEnter, pcMonitor, "EM:MAa"} // Acquire a monitor M, Aaddr -> M, E +{poMExit, pcMonitor, "M:MAa"} // Release a monitor M, Aaddr -> M + +{poSync, pcSync, "M:M"} // Memory barrier M -> M + +{poSysCall, pcSysCall, "T:MA@*"} // System call M, ... -> V@ +{poSysCallV, pcSysCall, "T:MA@*"} // Volatile system call M, ... -> M, V@ +{poSysCallC, pcSysCall, "T:A@*"} // Constant system call ... -> V@ +{poSysCallE, pcSysCall, "ET:MA@*"} // System call exc M, ... -> V@, E +{poSysCallEV, pcSysCall, "ET:MA@*"} // Volatile system call exc M, ... -> M, V@, E +{poSysCallEC, pcSysCall, "ET:A@*"} // Constant system call exc ... -> V@, E + +{poCall, pcCall, "ET:MAaA@*"} // Function call M, Va, ... -> M, V@, E + + // code generator specific primitives +{coReg_V, pcNone, ""} // fake register (doesn't exist) +{coReg_I, pcNone, "Vi:"} // fake register ... -> Vint +{coReg_L, pcNone, "Vl:"} // fake register ... -> Vlong +{coReg_F, pcNone, "Vf:"} // fake register ... -> Vfloat +{coReg_D, pcNone, "Vd:"} // fake register ... -> Vdouble +{coReg_A, pcNone, "Va:"} // fake register ... -> Vaddr +{coReg_C, pcNone, "Vc:"} // fake register ... -> Vcond +{coReg_M, pcNone, "M:"} // fake register ... -> M +{coReg_T, pcNone, ""} // fake register (doesn't exist) diff --git a/ef/Compiler/PrimitiveGraph/Primitives.cpp b/ef/Compiler/PrimitiveGraph/Primitives.cpp new file mode 100644 index 000000000000..65feee01051d --- /dev/null +++ b/ef/Compiler/PrimitiveGraph/Primitives.cpp @@ -0,0 +1,858 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#include "Primitives.h" +#include "ControlNodes.h" +#include "SysCalls.h" +#include "FieldOrMethod.h" +#include "DebugUtils.h" + +#include "PrimitiveOperations.cpp" + + +const DataNode VariableOrConstant::constSources[nValueKinds] = +{ + vkVoid, + vkInt, + vkLong, + vkFloat, + vkDouble, + vkAddr, + vkCond, + vkMemory, + vkTuple +}; + +// ---------------------------------------------------------------------------- +// VariableOrConstant + + +// +// Return true if the given VariableOrConstant is equal to this VariableOrConstant. +// Two VariableOrConstants are equal if either they are equal constants or +// the same Producer. +// +bool VariableOrConstant::operator==(const VariableOrConstant &poc2) const +{ + return source == poc2.source && (isVariable() || value.eq(getKind(), poc2.value)); +} + + +// +// Return true if the VariableOrConstant is guaranteed to be nonzero. +// +bool VariableOrConstant::isAlwaysNonzero() const +{ + return isConstant() ? value.isNonzero(source->getKind()) : getVariable().isAlwaysNonzero(); +} + + +// ---------------------------------------------------------------------------- +// DataConsumer + +// +// Set this DataConsumer to the variable or constant contained inside p. +// This DataConsumer should not have been previously initialized. +// +void DataConsumer::operator=(const VariableOrConstant &p) +{ + assert(!(source && source->isVariable())); + if (p.isConstant()) + setConstant(p.getKind(), p.getConstant()); + else + setVariable(p.getVariable()); +} + + +// +// Destructively move the src DataConsumer (which must have been initialized) +// to this DataConsumer, which must be uninitialized. The src DataConsumer is +// unlinked from any linked lists to which it belonged and left uninitialized. +// +void DataConsumer::move(DataConsumer &src) +{ + assert(!(source && source->isVariable())); + source = src.source; + node = src.node; + #ifdef DEBUG + src.source = 0; + src.node = 0; + if (isVariable()) + links.init(); + #endif + if (isConstant()) + value = src.value; + else + links.substitute(src.links); +} + + +#ifdef DEBUG_LOG +// +// Print a reference to this DataConsumer for debugging purposes. +// Return the number of characters printed. +// +int DataConsumer::printRef(LogModuleObject &f) const +{ + if (isConstant()) + return getConstant().print(f, getKind()); + else + return getVariable().printRef(f); +} +#endif + + +// ---------------------------------------------------------------------------- +// DataNode + + +#ifdef DEBUG_LOG +// +// Print a reference to this DataNode for debugging purposes. +// Return the number of characters printed. +// +int DataNode::printRef(LogModuleObject &f) const +{ + int a = UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("%c%c", constant ? 'c' : isAlwaysNonzero() ? 'w' : 'v', valueKindShortName(kind))); + if (producerNumber != (Uint32)-1) + return a + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("%u", producerNumber)); + else + return a + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("%p", this)); +} +#endif + + +// ---------------------------------------------------------------------------- + + +Uint16 gCurLineNumber = 0; + +const PrimitiveFormat categoryFormats[nPrimitiveCategories] = +{ + pfNone, // pcNone + pfPhi, // pcPhi + pfConst, // pcConst + pfDebug, // pcDebug + pfControl, // pcIfCond + pfControl, // pcSwitch + pfCatch, // pcCatch + pfProj, // pcProj + pfArg, // pcArg + pfResult, // pcResult + pfBinaryGeneric, // pcGeneric + pfBinaryGeneric, // pcDivMod + pfBinaryGeneric, // pcShift + pfBinaryGeneric, // pcExt + pfBinaryGeneric, // pcFGeneric + pfUnaryGeneric, // pcConv + pfUnaryGeneric, // pcFConv + pfBinaryGeneric, // pcCmp + pfBinaryGeneric, // pcFCmp + pfUnaryGeneric, // pcCond + pfUnaryGeneric, // pcCond3 + pfUnaryGeneric, // pcCheck1 + pfBinaryGeneric, // pcCheck2 + pfLd, // pcLd + pfSt, // pcSt + pfMonitor, // pcMonitor + pfSync, // pcSync + pfSysCall, // pcSysCall + pfCall // pcCall +}; + + +#ifdef DEBUG_LOG +static const char primitiveFormatNames[nPrimitiveFormats][16] = +{ + "None", // pfNone + "Phi", // pfPhi + "Const", // pfConst + "Debug", // pfDebug + "Control", // pfControl + "Catch", // pfCatch + "Proj", // pfProj + "Arg", // pfArg + "Result", // pfResult + "UnaryGeneric", // pfUnaryGeneric + "BinaryGeneric", // pfBinaryGeneric + "Ld", // pfLd + "St", // pfSt + "Monitor", // pfMonitor + "Sync", // pfSync + "SysCall", // pfSysCall + "Call" // pfCall +}; + + +static const char primitiveCategoryNames[nPrimitiveCategories][16] = +{ + "None", // pcNone + "Phi", // pcPhi + "Const", // pcConst + "Debug", // pcDebug + "IfCond", // pcIfCond + "Switch", // pcSwitch + "Catch", // pcCatch + "Proj", // pcProj + "Arg", // pcArg + "Result", // pcResult + "Generic", // pcGeneric + "DivMod", // pcDivMod + "Shift", // pcShift + "Ext", // pcExt + "FGeneric", // pcFGeneric + "Conv", // pcConv + "FConv", // pcFConv + "Cmp", // pcCmp + "FCmp", // pcFCmp + "Cond", // pcCond + "Cond3", // pcCond3 + "Check1", // pcCheck1 + "Check2", // pcCheck2 + "Ld", // pcLd + "St", // pcSt + "Monitor", // pcMonitor + "Sync", // pcSync + "SysCall", // pcSysCall + "Call" // pcCall +}; + + +// +// Print the name of the PrimitiveFormat onto the output stream f. +// Return the number of characters printed. +// +int print(LogModuleObject &f, PrimitiveFormat pf) +{ + return UT_OBJECTLOG(f, PR_LOG_ALWAYS, ((uint)pf >= nPrimitiveFormats ? "????" : primitiveFormatNames[pf])); +} + + +// +// Print the name of the PrimitiveCategory onto the output stream f. +// Return the number of characters printed. +// +int print(LogModuleObject &f, PrimitiveCategory pc) +{ + return UT_OBJECTLOG(f, PR_LOG_ALWAYS, ((uint)pc >= nPrimitiveCategories ? "????" : primitiveCategoryNames[pc])); +} + + +// +// Print the name of the PrimitiveOperation onto the output stream f. +// Return the number of characters printed. +// +int print(LogModuleObject &f, PrimitiveOperation pk) +{ + return UT_OBJECTLOG(f, PR_LOG_ALWAYS, ((uint)pk >= nPrimitiveOperations ? "????" : primitiveOperationNames[pk])); +} +#endif + + +// +// If the comparison always returns a constant, return nil and store the (true or +// false) result of the comparison in result. Otherwise, return the DataNode +// obtained from c. +// +DataNode *partialComputeComparison(Condition2 cond2, VariableOrConstant c, bool &result) +{ + assert(c.hasKind(vkCond)); + + if (c.isConstant()) { + result = applyCondition(cond2, c.getConstant().c); + return 0; + } + + // Optimize the cases in which we know that cond cannot be cEq. + DataNode &cp = c.getVariable(); + if (cp.isAlwaysNonzero()) + switch (cond2) { + case condEq: + result = false; + return 0; + case condNe: + result = true; + return 0; + default:; + } + return &cp; +} + + +// ---------------------------------------------------------------------------- +// DataNode + + +// +// Destroy this DataNode, which must have been initialized. This DataNode's +// consumers are destroyed as well. +// Don't call this directly; call PhiNode::destroy or Primitive::destroy instead. +// +void DataNode::destroy() +{ + DataConsumer *begin = inputsBegin; + DataConsumer *end = inputsEnd; + while (begin != end) + begin++->destroy(); + + #ifdef DEBUG + kind = vkVoid; + constant = false; + operation = poNone; + category = pcNone; + alwaysNonzero = false; + flags = templates[poNone].flags; + container = 0; + inputsBegin = 0; + inputsEnd = (DataConsumer *)(-1); + #endif +} + + +// +// Returns true if data node is a signed compare, false if unsigned compare +// NB must be a compare (checked by assertion) +// (Used by x86 emitter) +// +bool DataNode::isSignedCompare() const +{ + bool result; + switch(getOperation()) + { + case poCmp_I: // comparison is signed + result = true; + break; + + case poCmpU_I: // comparison is unsigned + case poCmpU_A: + result = false; + break; + + default: + assert(false); + } + return result; +} + + +// +// Assign a unique producerNumber to this DataNode if it produces a value. +// The first number assigned will be base; return the last number assigned + 1. +// +Uint32 DataNode::assignProducerNumbers(Uint32 base) +{ + if (producesVariable()) + producerNumber = base++; + return base; +} + + +#ifdef DEBUG_LOG +// +// Print the outgoing edge, if any, of a DataNode along with the := sign. +// +void DataNode::printOutgoing(LogModuleObject &f) const +{ + if (producesVariable()) { + printRef(f); + UT_OBJECTLOG(f, PR_LOG_ALWAYS, (" := ")); + } +} + + +// +// Print the incoming edges of a DataNode preceded by some white space. +// +void DataNode::printIncoming(LogModuleObject &f) const +{ + if (inputsBegin != inputsEnd) { + UT_OBJECTLOG(f, PR_LOG_ALWAYS, (" ")); + bool printSeparator = false; + for (DataConsumer *dc = inputsBegin; dc != inputsEnd; dc++) { + if (printSeparator) + UT_OBJECTLOG(f, PR_LOG_ALWAYS, (", ")); + printSeparator = true; + assert(&dc->getNode() == this); + dc->printRef(f); + } + } +} + + +// +// Print a DataNode for debugging purposes. +// f should be at the beginning of a line. +// +void DataNode::printPretty(LogModuleObject &f, int margin) const +{ + printMargin(f, margin); + ControlNode *c = getContainer(); + if (c && c->hasControlKind() && hasTryPrimitive(c->getControlKind())) + if (this == c->getTryExtra().tryPrimitive) + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("Exc ")); + printOutgoing(f); + print(f, getOperation()); + printIncoming(f); + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("\n")); +} +#endif + + +// ---------------------------------------------------------------------------- +// PhiNode + +// +// Construct a new phi node. nExpectedInputs is an estimate of the number +// of incoming edges that the phi node will have. The estimate does not have to +// be accurate, but performance will suffer if it is too low. +// The phi node starts with no incoming edges. The caller must explicitly add +// each incoming edge in the same order as the order in which the predecessors of +// the PhiNode's container are listed. +// +PhiNode::PhiNode(Uint32 nExpectedInputs, ValueKind kind, Pool &pool): + DataNode((PrimitiveOperation)(poPhi_I + kind - vkInt)) +{ + assert(hasFormat(pfPhi)); + DataConsumer *edges = new(pool) DataConsumer[nExpectedInputs]; + inputsBegin = edges; + inputsEnd = edges; + inputsLimit = edges + nExpectedInputs; +} + + +// +// Destroy this PhiNode, which must have been initialized. This PhiNode's +// consumers are destroyed and the PhiNode is removed from its container. +// +void PhiNode::destroy() +{ + remove(); + DataNode::destroy(); +} + + +// +// Add a new input to the phi node. The inputs must be added in the same +// order as the order of the predecessors of the PhiNode's container. +// Allocate edges from the given pool. +// +void PhiNode::addInput(DataNode &producer, Pool &pool) +{ + DataConsumer *input = inputsEnd; + if (input == inputsLimit) { + Uint32 newNEdges = (input - inputsBegin) * 2; + if (newNEdges < 4) + newNEdges = 4; + DataConsumer *newInputsBegin = new(pool) DataConsumer[newNEdges]; + input = move(inputsBegin, input, newInputsBegin); + inputsBegin = newInputsBegin; + inputsLimit = newInputsBegin + newNEdges; + } + input->setNode(*this); + input->setVariable(producer); + inputsEnd = input + 1; +} + + +// +// Call f once on each of this phi node's inputs in order. Remove from this phi +// node the inputs for which f returns true. This phi node remains a phi node +// (is not optimized out) even if all or all but one of its inputs are removed. +// The function f also gets each input's corresponding predecessor. +// +// CAUTION: Function f should not cache the DataConsumer reference it obtains +// because that DataConsumer can be destroyed. If it wants to cache the DataConsumer, +// it should make a copy. +// +void PhiNode::removeSomeInputs(Function2 &f) +{ + const DoublyLinkedList &predecessors = getContainer()->getPredecessors(); + assert(predecessors.lengthIs(nInputs())); + DoublyLinkedList::iterator i = predecessors.begin(); + DataConsumer *srcInput = inputsBegin; + DataConsumer *dstInput = srcInput; + DataConsumer *end = inputsEnd; + while (srcInput != end) { + if (f(*srcInput, predecessors.get(i))) + srcInput->destroy(); + else { + if (srcInput != dstInput) + dstInput->move(*srcInput); + dstInput++; + } + srcInput++; + i = predecessors.advance(i); + } + inputsEnd = dstInput; +} + + +// ---------------------------------------------------------------------------- +// Primitive + + +// +// Destroy this Primitive, which must have been initialized. This Primitive's +// consumers are destroyed and the Primitive is removed from its container. +// +void Primitive::destroy() +{ + remove(); + DataNode::destroy(); +} + + +// ---------------------------------------------------------------------------- +// PrimConst + +// +// Create a PrimConst with the given value. +// +PrimConst::PrimConst(ValueKind vk, const Value &value, Uint32 bci): + Primitive0((PrimitiveOperation)(poConst_I + vk - vkInt), bci), + value(value) +{ + assert(isRegOrMemKind(vk) && hasFormat(pfConst)); + setAlwaysNonzero(value.isNonzero(vk)); +} + + +#ifdef DEBUG_LOG +void PrimConst::printIncoming(LogModuleObject &f) const +{ + UT_OBJECTLOG(f, PR_LOG_ALWAYS, (" ")); + value.print(f, getKind()); +} +#endif + + +// ---------------------------------------------------------------------------- +// PrimProj + +// +// Create a PrimProj with the given operation. +// If alwaysNonzero is true, the output is known to never be zero. +// The caller then has to connect the input to the data node that produces the tuple. +// +PrimProj::PrimProj(PrimitiveOperation op, TupleComponent component, bool + alwaysNonzero, Uint32 bci): + Primitive1(op, bci), + component(component) +{ + assert(hasFormat(pfProj)); + setAlwaysNonzero(alwaysNonzero); +} + + +// +// Create a PrimProj with the given value kind, which must be a storable ValueKind. +// If alwaysNonzero is true, the output is known to never be zero. +// The caller then has to connect the input to the data node that produces the tuple. +// +PrimProj::PrimProj(ValueKind vk, TupleComponent component, bool + alwaysNonzero, Uint32 bci): + Primitive1((PrimitiveOperation)(poProj_I + vk - vkInt), bci), + component(component) +{ + assert(isStorableKind(vk)); + setAlwaysNonzero(alwaysNonzero); +} + + +#ifdef DEBUG_LOG +void PrimProj::printIncoming(LogModuleObject &f) const +{ + Primitive1::printIncoming(f); + UT_OBJECTLOG(f, PR_LOG_ALWAYS, (", component%d", component)); +} +#endif + + +// ---------------------------------------------------------------------------- +// PrimArg + +// +// Create a PrimArg. The caller must subsequently call initOutgoingEdge on it. +// +PrimArg::PrimArg(): Primitive0(poArg_M, 0) // initOutgoingEdge will change the operation as appropriate. +{ + assert(hasFormat(pfArg)); +} + + +// +// Set the PrimArg's kind and flag that states whether the PrimArg might +// ever be zero or null. +// +void PrimArg::initOutgoingEdge(ValueKind vk, bool alwaysNonzero) +{ + assert(isStorableKind(vk) || isMemoryKind(vk)); + setOperation((PrimitiveOperation)(poArg_I + vk - vkInt)); + setAlwaysNonzero(alwaysNonzero); +} + + +#ifdef DEBUG_LOG +void PrimArg::printIncoming(LogModuleObject &f) const +{ + UT_OBJECTLOG(f, PR_LOG_ALWAYS, (" arg")); + ControlNode *container = getContainer(); + if (container && container->hasControlKind()) { + ControlNode::BeginExtra &beginExtra = container->getBeginExtra(); + if (this == &beginExtra.initialMemory) + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("MEM")); + else { + for (uint n = 0; n != beginExtra.nArguments; n++) + if (this == &beginExtra[n]) { + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("%d", n)); + return; + } + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("??")); + } + } +} +#endif + + +// ---------------------------------------------------------------------------- +// PrimResult + +// +// Create a PrimResult. +// +PrimResult::PrimResult(Uint32 bci, ValueKind vk) + : Primitive1((PrimitiveOperation)(poResult_I + vk - vkInt), bci) +{ + assert((isStorableKind(vk) || isMemoryKind(vk)) && hasFormat(pfResult)); +} + + +#ifdef DEBUG_LOG +void PrimResult::printOutgoing(LogModuleObject &f) const +{ + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("res")); + ControlNode *container = getContainer(); + if (container && container->hasControlKind()) + if (container->hasControlKind(ckEnd) && this == &container->getEndExtra().finalMemory) + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("MEM")); + else { + ControlNode::ReturnExtra &returnExtra = container->getReturnExtra(); + uint n; + for (n = 0; n != returnExtra.nResults; n++) + if (this == &returnExtra[n]) { + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("%d", n)); + break; + } + if (n == returnExtra.nResults) + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("??")); + } + UT_OBJECTLOG(f, PR_LOG_ALWAYS, (" := ")); +} +#endif + + +// ---------------------------------------------------------------------------- +// PrimControl + +// +// Create a PrimControl node. op should be poSwitch or one of the poIf... kinds. +// The caller then has to connect the input to another data flow node. +// +PrimControl::PrimControl(PrimitiveOperation op, Uint32 bci) + : Primitive1(op, bci) +{ + assert(hasFormat(pfControl)); +} + + +// ---------------------------------------------------------------------------- +// PrimCatch + +// +// Create a PrimCatch. +// +PrimCatch::PrimCatch(Uint32 bci): Primitive0(poCatch, bci) +{ + assert(hasFormat(pfCatch)); + setAlwaysNonzero(true); +} + + +// ---------------------------------------------------------------------------- +// PrimUnaryGeneric + +// +// Create a generic one-argument, one-result primitive with the given PrimitiveOperation. +// If alwaysNonzero is true, the output is known to never be zero. +// The caller then has to connect the input to another data flow node. +// +PrimUnaryGeneric::PrimUnaryGeneric(PrimitiveOperation op, Uint32 bci, bool alwaysNonzero) + : Primitive1(op, bci) +{ + assert(hasFormat(pfUnaryGeneric)); + setAlwaysNonzero(alwaysNonzero); +} + + +// ---------------------------------------------------------------------------- +// PrimBinaryGeneric + +// +// Create a generic two-argument, one-result primitive with the given PrimitiveOperation. +// If alwaysNonzero is true, the output is known to never be zero. +// The caller then has to connect the inputs to other data flow nodes. +// +PrimBinaryGeneric::PrimBinaryGeneric(PrimitiveOperation op, Uint32 bci, + bool alwaysNonzero) + + : Primitive2(op, bci) +{ + assert(hasFormat(pfBinaryGeneric)); + setAlwaysNonzero(alwaysNonzero); +} + + +// ---------------------------------------------------------------------------- +// PrimLoad + +// +// Create a PrimLoad with the given PrimitiveOperation. +// The caller then has to connect the inputs to other data flow nodes. +// +PrimLoad::PrimLoad(PrimitiveOperation op, bool hasOutgoingMemory, Uint32 bci) + : Primitive2(op, bci), hasOutgoingMemory(hasOutgoingMemory) +{ + assert(hasFormat(pfLd)); +} + + +// ---------------------------------------------------------------------------- +// PrimStore + +// +// Create a PrimStore with the given PrimitiveOperation. +// The caller then has to connect the inputs to other data flow nodes. +// +PrimStore::PrimStore(PrimitiveOperation op, Uint32 bci) : Primitive(op, bci) +{ + assert(hasFormat(pfSt)); + inputsBegin = inputs; + inputsEnd = inputs + 3; + inputs[0].setNode(*this); + inputs[1].setNode(*this); + inputs[2].setNode(*this); + + setAlwaysNonzero(true); +} + + +// ---------------------------------------------------------------------------- +// PrimMonitor + +// +// Create a monitor primitive with the given PrimitiveOperation (which should be +// poMEnter or poMExit). slot is the index of the stack slot for the saved subheader. +// +PrimMonitor::PrimMonitor(PrimitiveOperation op, Uint32 slot, Uint32 bci) + : Primitive2(op, bci), slot(slot) +{ + assert(hasFormat(pfMonitor)); + setAlwaysNonzero(true); +} + + +// ---------------------------------------------------------------------------- +// PrimSync + +// +// Create a PrimSync. +// +PrimSync::PrimSync(Uint32 bci): Primitive0(poSync, bci) +{ + assert(hasFormat(pfSync)); + setAlwaysNonzero(true); +} + +// ---------------------------------------------------------------------------- +// PrimSysCall + +// +// Create a system call primitive for the given system call. The incoming edges +// get allocated from the given pool and connected. +// The caller then has to connect the inputs to other data flow nodes. +// +PrimSysCall::PrimSysCall(const SysCall &sysCall, Pool &pool, Uint32 bci) + : Primitive(sysCall.operation, bci), sysCall(sysCall) +{ + assert(hasFormat(pfSysCall)); + uint i = sysCall.nInputs; + DataConsumer *inputs = new(pool) DataConsumer[i]; + inputsBegin = inputs; + while (i--) + inputs++->setNode(*this); + inputsEnd = inputs; +} + + +#ifdef DEBUG_LOG +void PrimSysCall::printIncoming(LogModuleObject &f) const +{ + UT_OBJECTLOG(f, PR_LOG_ALWAYS, (" %s", sysCall.name)); + Primitive::printIncoming(f); +} +#endif + + +// ---------------------------------------------------------------------------- +// PrimCall + +// +// Create a call primitive for the given call. The incoming edges +// get allocated from the given pool and connected. +// The caller then has to connect the inputs to other data flow nodes. +// nArguments and nResults do not include the implicit memory edges or the +// edge carrying the address of the called function. +// +// If the Method object is known for the function being called, method should point to it; +// if not, method must be nil. +// +PrimCall::PrimCall(PrimitiveOperation op, const Method *method, + uint nArguments, uint nResults, Pool &pool, Uint32 bci) + : Primitive(op, bci), nArguments(nArguments), nResults(nResults), method(method) +{ + assert(hasFormat(pfCall)); + nArguments += 2; + DataConsumer *inputs = new(pool) DataConsumer[nArguments]; + inputsBegin = inputs; + while (nArguments--) + inputs++->setNode(*this); + inputsEnd = inputs; +} + + +#ifdef DEBUG_LOG +void PrimCall::printIncoming(LogModuleObject &f) const +{ + if (method) { + UT_OBJECTLOG(f, PR_LOG_ALWAYS, (" [")); + method->printRef(f); + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("]")); + } + Primitive::printIncoming(f); +} +#endif + diff --git a/ef/Compiler/PrimitiveGraph/Primitives.h b/ef/Compiler/PrimitiveGraph/Primitives.h new file mode 100644 index 000000000000..30b983c97e44 --- /dev/null +++ b/ef/Compiler/PrimitiveGraph/Primitives.h @@ -0,0 +1,1016 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#ifndef PRIMITIVES_H +#define PRIMITIVES_H + +#include "Value.h" +#include "DoublyLinkedList.h" +#include "VirtualRegister.h" +#include "LogModule.h" +#include "Attributes.h" + +enum PrimitiveFormat +{ + pfNone, + pfPhi, // Phi node + pfConst, // Constant + pfDebug, // Debug or Break + pfControl, // If condition node or switch index node + pfCatch, // Catch exception producer + pfProj, // Projection + pfArg, // Argument + pfResult, // Result + pfUnaryGeneric, // General one-argument operations + pfBinaryGeneric, // General two-argument operations + pfLd, // Ld + pfSt, // St + pfMonitor, // MEnter and MExit + pfSync, // Sync + pfSysCall, // SysCall + pfCall // Call +}; +const nPrimitiveFormats = pfCall + 1; + +enum PrimitiveCategory +{ + pcNone, + pcPhi, // Phi node + pcConst, // Constant + pcDebug, // Debug or Break + pcIfCond, // If condition node + pcSwitch, // Switch index node + pcCatch, // Catch exception producer + pcProj, // Projection + pcArg, // Argument + pcResult, // Result + pcGeneric, // Two-argument integer arithmetic and logical + pcDivMod, // Div and Mod + pcShift, // Shifts + pcExt, // Ext + pcFGeneric, // Floating-point arithmetic + pcConv, // Conv + pcFConv, // FConv + pcCmp, // Cmp + pcFCmp, // FCmp + pcCond, // Cond + pcCond3, // Cond3 + pcCheck1, // ChkNull + pcCheck2, // ChkCast, Limit, and LimCast + pcLd, // Ld + pcSt, // St + pcMonitor, // MEnter and MExit + pcSync, // Sync + pcSysCall, // SysCall + pcCall // Call +}; +const nPrimitiveCategories = pcCall + 1; + +extern const PrimitiveFormat categoryFormats[nPrimitiveCategories]; + +#include "PrimitiveOperations.h" + +#ifdef DEBUG_LOG +int print(LogModuleObject &f, PrimitiveFormat pf); +int print(LogModuleObject &f, PrimitiveCategory pc); +int print(LogModuleObject &f, PrimitiveOperation pk); +#endif + + +// ---------------------------------------------------------------------------- + + +class DataNode; +class ControlNode; +class ControlEdge; +class Instruction; + +class VariableOrConstant +{ + private: + static const DataNode constSources[nValueKinds]; + + protected: // (In DEBUG versions both variables below are nil if not explicitly set.) + const DataNode *source; // The referenced DataNode or (if pointing to a constant) Source + DataNode *node; // The node to which this DataConsumer belongs (used in DataConsumer only) + union { + DoublyLinkedNode links; // Links to other consumers of a non-constant value (used in DataConsumer only) + Value value; // Constant + }; + + public: + #ifdef DEBUG + VariableOrConstant() {source = 0;} + #endif + bool operator==(const VariableOrConstant &poc2) const; + bool operator!=(const VariableOrConstant &poc2) const {return !(*this == poc2);} + + bool isImmediate() const {return false;} + bool hasKind(ValueKind kind) const; + ValueKind getKind() const; + + bool isConstant() const; + bool isVariable() const; + DataNode &getVariable() const; + const Value &getConstant() const; + Value &getConstant(); + bool isAlwaysNonzero() const; + Type *getDynamicType() const; + + void setConstant(Int32 v); + void setConstant(Int64 v); + void setConstant(Flt32 v); + void setConstant(Flt64 v); + void setConstant(addr v); + void setConstant(Condition v); + void setConstant(Memory v); + void setConstant(ValueKind kind, const Value &v); + void setVariable(DataNode &producer); +}; + + +// A DataConsumer is like a VariableOrConstant except that it belongs to some (consumer) DataNode. +// Also, if the DataConsumer is a variable, it is linked into the source (producer) DataNode's +// doubly-linked list of consumers. +// If the DataConsumer currently contains a variable, do not change its source (for example by +// using either setConstant or setVariable). Instead, call either clearVariable or destroy +// first and then call setConstant or setVariable, thus making sure that the DataNodes' lists +// of consumers are kept consistent. In DEBUG versions asserts will enforce this rule. +class DataConsumer: public VariableOrConstant +{ + #ifdef DEBUG + public: + DataConsumer() {node = 0;} + private: + DataConsumer(const DataConsumer &); // Copying forbidden + void operator=(const DataConsumer &); // Copying forbidden + #endif + public: + void operator=(const VariableOrConstant &p); + void move(DataConsumer &src); + void destroy(); + + DataNode &getNode() const {assert(node); return *node;} + void setNode(DataNode &n) {node = &n;} + + #ifdef DEBUG + void setConstant(Int32 v); + void setConstant(Int64 v); + void setConstant(Flt32 v); + void setConstant(Flt64 v); + void setConstant(addr v); + void setConstant(Condition v); + void setConstant(Memory v); + void setConstant(ValueKind kind, const Value &v); + #endif + void setVariable(DataNode &producer); + void clearVariable(); + void clear() {if (isVariable()) clearVariable();} + + // DoublyLinkedNode administration + static DataConsumer &linkOwner(DoublyLinkedNode &l) {return *(DataConsumer *)((char *)&l - offsetof(DataConsumer, links));} + DoublyLinkedNode &getLinks() {return links;} + + #ifdef DEBUG_LOG + int printRef(LogModuleObject &f) const; + #endif +}; + +inline bool isIfCond(PrimitiveOperation op) {return op >= poIfLt && op <= poIfUGe;} +inline bool isCond2(PrimitiveOperation op) {return op >= poLt_I && op <= poUGe_I;} +inline bool isCond3(PrimitiveOperation op) {return op >= poCatL_I && op <= poCatCG_I;} +inline Condition2 ifCondToCondition2(PrimitiveOperation op) {assert(isIfCond(op)); return (Condition2)(op - poIfLt + condLt);} +inline Condition2 cond2ToCondition2(PrimitiveOperation op) {assert(isCond2(op)); return (Condition2)(op - poLt_I + condLt);} +inline Condition3 cond3ToCondition3(PrimitiveOperation op) {assert(isCond3(op)); return (Condition3)(op - poCatL_I);} +inline PrimitiveOperation condition2ToIfCond(Condition2 cond2) {return (PrimitiveOperation)(cond2 - condLt + poIfLt);} +inline PrimitiveOperation condition2ToCond2(Condition2 cond2) {return (PrimitiveOperation)(cond2 - condLt + poLt_I);} +inline PrimitiveOperation condition3ToCond3(Condition3 cond3) {return (PrimitiveOperation)(cond3 + poCatL_I);} + +DataNode *partialComputeComparison(Condition2 cond2, VariableOrConstant c, bool &result); + + +// ---------------------------------------------------------------------------- + + +extern Uint16 gCurLineNumber; // debug get line number info + +class DataNode +{ + ValueKind kind ENUM_8; // Kind of the constant or the data node's outgoing data edge + bool constant BOOL_8; // True if this value is a constant (held inside the DataConsumer) + + enum DataNodeFlag + { + dnIsReal, // This primitive can be created (as opposed to, say, poNone, which cannot) + dnCanRaiseException, // This primitive can raise an exception + dnIsRoot // This primitive feeds a control node, so it should't be deleted just because its data + }; // output is dead. + + struct Template + { + PrimitiveOperation operation ENUM_16; // Minor kind of primitive + PrimitiveCategory category ENUM_8; // Major kind of primitive + ValueKind kind ENUM_8; // Kind of the constant or the data node's outgoing data edge + Uint16 flags; // DataNodeFlags + }; + + static const Template templates[nPrimitiveOperations]; + + #ifdef DEBUG + public: + enum Origin {aoVariable, aoConstant, aoEither}; + + struct InputConstraint + { + ValueKind kind ENUM_8; // Kinds of an input. vkVoid means "any kind". + Origin origin ENUM_8; // Can the input be a variable, a constant, or either? + }; + private: + + struct InputConstraintPattern + { + const InputConstraint *inputConstraints;// Constraints on the inputs. + Uint8 nInputConstraints; // Number of inputs (repeat input counts here as one input) + bool repeat BOOL_8; // If true, the last input can be repeated zero or more times + }; + + static const InputConstraintPattern inputConstraintPatterns[nPrimitiveOperations]; + #endif + + PrimitiveOperation operation ENUM_16; // Minor kind of primitive + PrimitiveCategory category ENUM_8; // Major kind of primitive + bool alwaysNonzero BOOL_8; // If true, the value of this DataNode is known to always be nonzero + Uint16 flags; // DataNodeFlags + DoublyLinkedList consumers; // List of consumers of data produced by this DataNode + protected: + ControlNode *container; // The ControlNode that contains this DataNode or nil if none + + DataConsumer *inputsBegin; // Array of incoming data flow edges + DataConsumer *inputsEnd; // Last element + 1 + Uint16 lineNumber; // Java source line number + public: + Uint32 producerNumber; // Serial number assigned and used by the register allocator and pretty-printer + + IntervalMapping *mapping; // The localVariable + // corresponding to the + // mapping + private: + struct _annotation + { + VirtualRegisterPtr lowVReg; + VirtualRegisterPtr highVReg; + Instruction *insn; + } annotation; + + + #ifdef DEBUG + // make sure we do not incorrectly use annotations + enum AnnotationKind {anNone, anInsn, anVr}; + AnnotationKind annotationKind; + #endif + + protected: + explicit DataNode(PrimitiveOperation op); + + void destroy(); + + public: + DataNode(ValueKind kind) : kind(kind), constant(true) {}; + + // Use these instead of expressions like "getFormat() == pfLd" because the latter doesn't do + // type checking -- the compiler will happily let you make errors like "getFormat() == pcLd". + inline bool isConstant() const {return constant;} + inline bool isVariable() const {return !constant;} + + bool hasKind(ValueKind k) const {return k == kind;} + bool hasFormat(PrimitiveFormat f) const {return f == categoryFormats[category];} + bool hasCategory(PrimitiveCategory c) const {return c == category;} + bool hasOperation(PrimitiveOperation op) const {return op == operation;} + ValueKind getKind() const {return kind;} + PrimitiveFormat getFormat() const {return categoryFormats[category];} + PrimitiveCategory getCategory() const {return category;} + PrimitiveOperation getOperation() const {return operation;} + void setOperation(PrimitiveOperation op); + + // Flag queries + bool isReal() const {return flags>>dnIsReal & 1;} + bool canRaiseException() const {return flags>>dnCanRaiseException & 1;} + bool isRoot() const {return flags>>dnIsRoot & 1;} + + bool producesVariable() const {return !isVoidKind(kind);} + bool isAlwaysNonzero() const {return alwaysNonzero;} + void setAlwaysNonzero(bool nz) {alwaysNonzero = nz;} + bool hasConsumers() const {return !consumers.empty();} + const DoublyLinkedList &getConsumers() const {return consumers;} + void addConsumer(DataConsumer &consumer) {consumers.addLast(consumer);} + + ControlNode *getContainer() const {return container;} + void setContainer(ControlNode *c) {assert(!container); container = c;} // For use by ControlNode only. + // see also changeContainer in PhiNode and Primitive. + + Uint32 nInputs() const {return inputsEnd - inputsBegin;} + DataConsumer *getInputsBegin() const {return inputsBegin;} + DataConsumer *getInputsEnd() const {return inputsEnd;} + DataConsumer &nthInput(Uint32 n) const {assert(n < nInputs()); return inputsBegin[n];} + bool nthInputIsConstant(Uint32 n) const {return nthInput(n).isConstant();} + DataNode &nthInputVariable(Uint32 n) const; + bool isSignedCompare() const; + Value &nthInputConstant(Uint32 n) const {return nthInput(n).getConstant();} + + Uint16 getLineNumber() const {return lineNumber;} + void setLineNumber(Uint16 lineNumber) {DataNode::lineNumber = lineNumber;} + + inline void annotate(Instruction& insn); + inline void annotate(VirtualRegister& vReg, VRClass cl); + inline void annotateLow(VirtualRegister& vReg, VRClass cl); + inline void annotateHigh(VirtualRegister& vReg, VRClass cl); + inline void annotate(VirtualRegister& lowVReg, VirtualRegister& highVReg, VRClass cl); + inline VirtualRegister* getVirtualRegisterAnnotation(); + inline VirtualRegister* getLowVirtualRegisterAnnotation(); + inline VirtualRegister* getHighVirtualRegisterAnnotation(); + inline VirtualRegisterPtr& getVirtualRegisterPtrAnnotation(); + inline VirtualRegisterPtr& getLowVirtualRegisterPtrAnnotation(); + inline VirtualRegisterPtr& getHighVirtualRegisterPtrAnnotation(); + inline Instruction* getInstructionAnnotation(); + + Uint32 assignProducerNumbers(Uint32 base); + virtual void setInstructionRoot(Instruction* /*inInstructionRoot*/) {} + virtual Instruction* getInstructionRoot() {return NULL;} + +#ifdef DEBUG + virtual void validate(); // perform self-consistency checks + InputConstraintPattern getInputConstraintPattern() { return inputConstraintPatterns[getOperation()]; } + bool mark BOOL_8; // marks this primitive as having been seen during an ordered search +#endif + + #ifdef DEBUG_LOG + protected: + virtual void printOutgoing(LogModuleObject &f) const; + virtual void printIncoming(LogModuleObject &f) const; + public: + int printRef(LogModuleObject &f) const; + void printPretty(LogModuleObject &f, int margin) const; + #endif + + #if 1 + // HACK! These are temporary stubs and will go away soon. + DataNode *getOutgoingEdgesBegin() {return this;} + DataNode *getOutgoingEdgesEnd() {return this + producesVariable();} + #endif +}; + + +class PhiNode: public DataNode, public DoublyLinkedEntry // Links to other PhiNodes in the same ControlNode +{ + DataConsumer *inputsLimit; // Pointer past last entry allocated in the inputsBegin array + // (may include extra slop after inputsEnd) + + public: + PhiNode(Uint32 nExpectedInputs, ValueKind kind, Pool &pool); + void destroy(); + + static PhiNode &cast(DataNode &node) + {assert(node.getFormat() == pfPhi); return *static_cast(&node);} + + void clearContainer() {assert(container); remove(); container = 0;} + void changeContainer(ControlNode *c) {assert(container); remove(); container = c;} // For use by ControlNode only. + + void addInput(DataNode &producer, Pool &pool); + void removeSomeInputs(Function2 &f); +}; + + +class Primitive: public DataNode, public DoublyLinkedEntry // Links to other Primitives in the same ControlNode +{ + protected: + Instruction *instructionRoot; // Instructions which creates this primitive if no outputs + Uint16 burgState; // BURG state given to this node + Uint16 lineNumber; // corresponds to src line# + Uint32 bytecodeIndex; // Bytecode Index + Uint16 debugLineNumber; // contains value >= lineNumber of all children (during InstructionScheduling) + + public: + explicit Primitive(PrimitiveOperation op, Uint32 bci); + void destroy(); + + static Primitive &cast(DataNode &node) + {assert(node.getFormat() >= pfConst); return *static_cast(&node);} + + void clearContainer() {assert(container); remove(); container = 0;} + void changeContainer(ControlNode *c) {assert(container); remove(); container = c;} // For use by ControlNode only. + + Uint16 getBurgState() const { return burgState;} + Uint16 setBurgState(Uint16 newState) {burgState = newState; return newState;} + + Uint16 getLineNumber() {return lineNumber;} + Uint16 setLineNumber(Uint16 newLineNumber) {lineNumber = newLineNumber; return lineNumber;} + + Uint16 getDebugLineNumber() {return debugLineNumber;} + Uint16 setDebugLineNumber(Uint16 newDebugLineNumber) {debugLineNumber = newDebugLineNumber; return debugLineNumber;} + + Uint32 getBytecodeIndex() {return bytecodeIndex;} + void setBytecodeIndex(Uint32 bci) {bytecodeIndex = bci;}; + + void setInstructionRoot(Instruction* inInstructionRoot) {instructionRoot = inInstructionRoot;} + Instruction* getInstructionRoot() {return instructionRoot;} +}; + + +// --- PRIVATE ---------------------------------------------------------------- + + +// A primitive that has no incoming edges +class Primitive0: public Primitive +{ + protected: + explicit Primitive0(PrimitiveOperation op, Uint32 bci); +}; + + +// A primitive that has one incoming edge +class Primitive1: public Primitive +{ + protected: + DataConsumer input; // Incoming data edge + + explicit Primitive1(PrimitiveOperation op, Uint32 bci); + + public: + DataConsumer &getInput() {return input;} +}; + + +// A primitive that has two incoming edges +class Primitive2: public Primitive +{ + protected: + DataConsumer inputs[2]; // Incoming data edges + + explicit Primitive2(PrimitiveOperation op, Uint32 bci); + + public: + DataConsumer *getInputs() {return inputs;} +}; + + +// --- PUBLIC ----------------------------------------------------------------- + + +// Lone constants +class PrimConst: public Primitive0 +{ + public: + const Value value; + + PrimConst(ValueKind vk, const Value &value, Uint32 bci); + + static PrimConst &cast(DataNode &node) + {assert(node.hasFormat(pfConst)); return *static_cast(&node);} + +#ifdef DEBUG + void validate(); // perform self-consistency checks +#endif + + #ifdef DEBUG_LOG + protected: + virtual void printIncoming(LogModuleObject &f) const; + #endif +}; + + +enum TupleComponent +{ + tcMemory = 0, // Outgoing memory edge + tcValue = 1, // Value returned from a volatile load + tcFirstResult = 1, // Component number of first result from a call or system call; subsequent results, if any, + // have TupleComponent numbers starting from 2. + tcMAX = 0x80000000 // (dummy value to force TupleComponent to be 32 bits wide) +}; + +// Projections of tuple values into their components +class PrimProj: public Primitive1 +{ + public: + const TupleComponent component; // Number that indicates which component we're getting from the tuple + + PrimProj(PrimitiveOperation op, TupleComponent component, + bool alwaysNonzero, Uint32 bci); + PrimProj(ValueKind vk, TupleComponent component, bool alwaysNonzero, + Uint32 bci); + + static PrimProj &cast(DataNode &node) + {assert(node.hasFormat(pfProj)); return *static_cast(&node);} + + #ifdef DEBUG_LOG + protected: + virtual void printIncoming(LogModuleObject &f) const; + #endif +}; + + +// Incoming function arguments +class PrimArg: public Primitive0 +{ + public: + PrimArg(); + void initOutgoingEdge(ValueKind vk, bool alwaysNonzero); + + static PrimArg &cast(DataNode &node) + {assert(node.hasFormat(pfArg)); return *static_cast(&node);} + + #ifdef DEBUG_LOG + protected: + virtual void printIncoming(LogModuleObject &f) const; + #endif +}; + + +// Outgoing function results +class PrimResult: public Primitive1 +{ + public: + explicit PrimResult(Uint32 bci, ValueKind vk = vkMemory); + void setResultKind(ValueKind vk); + + static PrimResult &cast(DataNode &node) + {assert(node.hasFormat(pfResult)); return *static_cast(&node);} + + #ifdef DEBUG_LOG + protected: + virtual void printOutgoing(LogModuleObject &f) const; + #endif +}; + + +// Anchor primitives for linking if and switch inputs to their control nodes; +class PrimControl: public Primitive1 +{ + public: + explicit PrimControl(PrimitiveOperation op, Uint32 bci); + + static PrimControl &cast(DataNode &node) + {assert(node.hasFormat(pfControl)); return *static_cast(&node);} +}; + + +// Caught exceptions +class PrimCatch: public Primitive0 +{ + public: + PrimCatch(Uint32 bci); + + static PrimCatch &cast(DataNode &node) + {assert(node.hasFormat(pfCatch)); return *static_cast(&node);} +}; + + +// Unary arithmetic and logical primitives +class PrimUnaryGeneric: public Primitive1 +{ + public: + explicit PrimUnaryGeneric(PrimitiveOperation op, Uint32 bci, + bool alwaysNonzero = false); + + static PrimUnaryGeneric &cast(DataNode &node) + {assert(node.hasFormat(pfUnaryGeneric)); return *static_cast(&node);} +}; + + +// Binary arithmetic and logical primitives, including Div and Mod +class PrimBinaryGeneric: public Primitive2 +{ + public: + explicit PrimBinaryGeneric(PrimitiveOperation op, Uint32 bci, + bool alwaysNonzero = false); + + static PrimBinaryGeneric &cast(DataNode &node) + {assert(node.hasFormat(pfBinaryGeneric)); return *static_cast(&node);} +}; + + +// Memory read primitives +class PrimLoad: public Primitive2 +{ + protected: + bool hasOutgoingMemory; // True if this is a volatile load + + public: + PrimLoad(PrimitiveOperation op, bool hasOutgoingMemory, Uint32 bci); + + static PrimLoad &cast(DataNode &node) + {assert(node.hasFormat(pfLd)); return *static_cast(&node);} + + DataConsumer &getIncomingMemory() {return inputs[0];} + DataConsumer &getAddress() {return inputs[1];} +}; + + +// Memory write primitives +class PrimStore: public Primitive +{ + protected: + DataConsumer inputs[3]; // Incoming data edges (memory, address, and data) + + public: + explicit PrimStore(PrimitiveOperation op, Uint32 bci); + + static PrimStore &cast(DataNode &node) + {assert(node.hasFormat(pfSt)); return *static_cast(&node);} + + DataConsumer &getIncomingMemory() {return inputs[0];} + DataConsumer &getAddress() {return inputs[1];} + DataConsumer &getData() {return inputs[2];} +}; + + +// Monitor access primitives +class PrimMonitor: public Primitive2 +{ + Uint32 slot; // Index of stack slot for the saved subheader + + public: + enum {unknownSlot = (Uint32)-1}; // Value to store in slot if not known yet + + PrimMonitor(PrimitiveOperation op, Uint32 slot, Uint32 bci); + + static PrimMonitor &cast(DataNode &node) + {assert(node.hasFormat(pfMonitor)); return *static_cast(&node);} + + DataConsumer &getIncomingMemory() {return inputs[0];} + DataConsumer &getMonitor() {return inputs[1];} + Uint32 getSlot() const {assert(slot != unknownSlot); return slot;} +}; + + +// Memory synchronization point primitives +class PrimSync: public Primitive0 +{ + public: + PrimSync(Uint32 bci); + + static PrimSync &cast(DataNode &node) + {assert(node.hasFormat(pfSync)); return *static_cast(&node);} +}; + + +struct SysCall; + +// System call primitives +class PrimSysCall: public Primitive +{ + public: + const SysCall &sysCall; // The type of system call represented here + + PrimSysCall(const SysCall &sysCall, Pool &pool, Uint32 bci); + + static PrimSysCall &cast(DataNode &node) + {assert(node.hasFormat(pfSysCall)); return *static_cast(&node);} + + #ifdef DEBUG_LOG + protected: + virtual void printIncoming(LogModuleObject &f) const; + #endif +}; + + +// Function call primitives +class PrimCall: public Primitive +{ + public: + const uint nArguments; // Number of arguments in this call (does not include the function or memory edges) + const uint nResults; // Number of results in this call (does not include the outgoing memory edge) + const Method *const method; // The Method being called or nil if not known + + PrimCall(PrimitiveOperation op, const Method *method, uint nArguments, + uint nResults, Pool &pool, Uint32 bci); + + static PrimCall &cast(DataNode &node) + {assert(node.hasFormat(pfCall)); return *static_cast(&node);} + + DataConsumer &getIncomingMemory() {return inputsBegin[0];} + DataConsumer &getFunction() {return inputsBegin[1];} + DataConsumer *getArguments() {return inputsBegin + 2;} + + #ifdef DEBUG_LOG + protected: + virtual void printIncoming(LogModuleObject &f) const; + #endif +}; + + +// --- INLINES ---------------------------------------------------------------- + + +inline bool VariableOrConstant::hasKind(ValueKind kind) const {assert(source); return source->hasKind(kind);} +inline ValueKind VariableOrConstant::getKind() const {assert(source); return source->getKind();} + +inline bool VariableOrConstant::isConstant() const {assert(source); return source->isConstant();} +inline bool VariableOrConstant::isVariable() const {assert(source); return source->isVariable();} + +inline const Value &VariableOrConstant::getConstant() const {assert(source && source->isConstant()); return value;} +inline Value &VariableOrConstant::getConstant() {assert(source && source->isConstant()); return value;} + +inline void VariableOrConstant::setConstant(Int32 v) {source = constSources + vkInt; value.i = v;} +inline void VariableOrConstant::setConstant(Int64 v) {source = constSources + vkLong; value.l = v;} +inline void VariableOrConstant::setConstant(Flt32 v) {source = constSources + vkFloat; value.f = v;} +inline void VariableOrConstant::setConstant(Flt64 v) {source = constSources + vkDouble; value.d = v;} +inline void VariableOrConstant::setConstant(addr v) {source = constSources + vkAddr; value.a = v;} +inline void VariableOrConstant::setConstant(Condition v) {source = constSources + vkCond; value.c = v;} +inline void VariableOrConstant::setConstant(Memory v) {source = constSources + vkMemory; value.m = v;} +inline void VariableOrConstant::setConstant(ValueKind kind, const Value &v) {source = constSources + kind; value = v;} + +// +// Return the producer linked to this VariableOrConstant or DataConsumer. +// +inline DataNode &VariableOrConstant::getVariable() const +{ + assert(source && source->isVariable()); + return *const_cast(source); +} + + +// +// If known, return the actual type of the object produced by this VariableOrConstant. +// If not known, return nil. +// The returned type is the most specific type of the object, not a conservative statically +// computed bound. +// Currently this method works only on VariableOrConstants of kind vkAddr. +// +inline Type *VariableOrConstant::getDynamicType() const +{ + assert(hasKind(vkAddr)); + // For now, don't infer types of non-constants. + return isConstant() ? objectAddressType(value.a) : 0; +} + + +// +// Set this VariableOrConstant to represent the given producer. +// +inline void VariableOrConstant::setVariable(DataNode &producer) +{ + source = &producer; + links.init(); +} + + +// ---------------------------------------------------------------------------- + + + +#ifdef DEBUG +inline void DataConsumer::setConstant(Int32 v) {assert(!(source && source->isVariable())); VariableOrConstant::setConstant(v);} +inline void DataConsumer::setConstant(Int64 v) {assert(!(source && source->isVariable())); VariableOrConstant::setConstant(v);} +inline void DataConsumer::setConstant(Flt32 v) {assert(!(source && source->isVariable())); VariableOrConstant::setConstant(v);} +inline void DataConsumer::setConstant(Flt64 v) {assert(!(source && source->isVariable())); VariableOrConstant::setConstant(v);} +inline void DataConsumer::setConstant(addr v) {assert(!(source && source->isVariable())); VariableOrConstant::setConstant(v);} +inline void DataConsumer::setConstant(Condition v) {assert(!(source && source->isVariable())); VariableOrConstant::setConstant(v);} +inline void DataConsumer::setConstant(Memory v) {assert(!(source && source->isVariable())); VariableOrConstant::setConstant(v);} +inline void DataConsumer::setConstant(ValueKind kind, const Value &v) {assert(!(source && source->isVariable())); VariableOrConstant::setConstant(kind, v);} +#endif + +inline void DataConsumer::clearVariable() {assert(source && source->isVariable()); links.remove(); DEBUG_ONLY(source = 0);} + +// +// Destroy this DataConsumer, which must have been initialized. This DataConsumer +// is unlinked from any linked lists to which it belonged and left uninitialized. +// +inline void DataConsumer::destroy() +{ + if (isVariable()) + links.remove(); + #ifdef DEBUG + source = 0; + node = 0; + #endif +} + + +// +// Link the DataConsumer located to the given, non-constant source. +// +inline void DataConsumer::setVariable(DataNode &producer) +{ + assert(!(source && source->isVariable())); + VariableOrConstant::setVariable(producer); + producer.addConsumer(*this); +} + + +// ---------------------------------------------------------------------------- + + +// +// Initialize this DataNode, which will contain a primitive or phi node with +// the given operation. +// +inline DataNode::DataNode(PrimitiveOperation op) +{ + const Template &t = templates[op]; + kind = t.kind; + constant = false; + operation = t.operation; + category = t.category; + alwaysNonzero = false; + flags = t.flags; + container = 0; + mapping = 0; + + assert(isReal()); + + #ifdef DEBUG + producerNumber = (Uint32)-1; + annotationKind = anNone; + #endif + annotation.insn = NULL; + lineNumber = gCurLineNumber++; +} + + +// +// Change the operation of a DataNode to the given operation. +// A DataNode's operation can only be changed within the same category. +// +inline void DataNode::setOperation(PrimitiveOperation op) +{ + const Template &t = templates[op]; + assert(hasCategory(t.category)); + kind = t.kind; + operation = t.operation; + alwaysNonzero = false; + flags = t.flags; +} + + +// +// Return the nth input, which must be a variable. +// +inline DataNode &DataNode::nthInputVariable(Uint32 n) const +{ + return nthInput(n).getVariable(); +} + + +inline void DataNode::annotate(Instruction& insn) +{ + annotation.insn = &insn; + DEBUG_ONLY(annotationKind = anInsn); +} + +inline void DataNode::annotateLow(VirtualRegister& vReg, VRClass cl) +{ + annotation.lowVReg.initialize(vReg, cl); + DEBUG_ONLY(annotationKind = anVr); +#ifdef DEBUG + vReg.isAnnotated = true; + if (vReg.isPreColored()) + trespass("This is not a temporary register. It cannot be preColored. !!!"); +#endif +} + +inline void DataNode::annotateHigh(VirtualRegister& vReg, VRClass cl) +{ + annotation.highVReg.initialize(vReg, cl); + DEBUG_ONLY(annotationKind = anVr); +#ifdef DEBUG + vReg.isAnnotated = true; + if (vReg.isPreColored()) + trespass("This is not a temporary register. It cannot be preColored. !!!"); +#endif +} + +inline void DataNode::annotate(VirtualRegister& vReg, VRClass cl) {annotateLow(vReg, cl);} + +inline void DataNode::annotate(VirtualRegister& lowVReg, VirtualRegister& highVReg, VRClass cl) +{ + annotation.lowVReg.initialize(lowVReg, cl); + annotation.highVReg.initialize(highVReg, cl); + DEBUG_ONLY(annotationKind = anVr); +#ifdef DEBUG + lowVReg.isAnnotated = true; + highVReg.isAnnotated = true; + if (lowVReg.isPreColored() || highVReg.isPreColored()) + trespass("This is not a temporary register. It cannot be preColored. !!!"); +#endif +} + +inline VirtualRegister* DataNode::getLowVirtualRegisterAnnotation() +{ + assert(annotationKind == anNone || annotationKind == anVr); + VirtualRegisterPtr& vRegPtr = annotation.lowVReg; + if (vRegPtr.isInitialized()) + return &vRegPtr.getVirtualRegister(); + else + return 0; +} + +inline VirtualRegister* DataNode::getVirtualRegisterAnnotation() {return getLowVirtualRegisterAnnotation();} + +inline VirtualRegister* DataNode::getHighVirtualRegisterAnnotation() +{ + assert(annotationKind == anNone || annotationKind == anVr); + VirtualRegisterPtr& vRegPtr = annotation.highVReg; + if (vRegPtr.isInitialized()) + return &vRegPtr.getVirtualRegister(); + else + return 0; +} + +inline VirtualRegisterPtr& DataNode::getLowVirtualRegisterPtrAnnotation() +{ + assert(annotationKind == anNone || annotationKind == anVr); + return annotation.lowVReg; +} + +inline VirtualRegisterPtr& DataNode::getHighVirtualRegisterPtrAnnotation() +{ + assert(annotationKind == anNone || annotationKind == anVr); + return annotation.highVReg; +} + +inline VirtualRegisterPtr& DataNode::getVirtualRegisterPtrAnnotation() {return getLowVirtualRegisterPtrAnnotation();} + +inline Instruction* DataNode::getInstructionAnnotation() +{ + assert(annotationKind == anNone || annotationKind == anInsn); + return (annotation.insn); +} + + +// ---------------------------------------------------------------------------- + + +// +// Initialize a primitive with the given operation. +// The caller then has to connect the inputs to other data flow nodes. +// +inline Primitive::Primitive(PrimitiveOperation op, Uint32 bci): + DataNode(op), + instructionRoot(0), + bytecodeIndex(bci), + debugLineNumber(0) +{} + + +// +// Initialize a no-input primitive with the given operation. +// +inline Primitive0::Primitive0(PrimitiveOperation op, Uint32 bci) + : Primitive(op, bci) +{ + inputsBegin = 0; + inputsEnd = 0; +} + + +// +// Initialize a one-input primitive with the given operation. +// The caller then has to connect the input to another data flow node. +// +inline Primitive1::Primitive1(PrimitiveOperation op, Uint32 bci) + : Primitive(op, bci) +{ + inputsBegin = &input; + inputsEnd = &input + 1; + input.setNode(*this); +} + + +// +// Initialize a two-input primitive with the given operation. +// The caller then has to connect the inputs to other data flow nodes. +// +inline Primitive2::Primitive2(PrimitiveOperation op, Uint32 bci) + : Primitive(op, bci) +{ + inputsBegin = inputs; + inputsEnd = inputs + 2; + inputs[0].setNode(*this); + inputs[1].setNode(*this); +} + + +// +// Change the value kind of the PrimResult. +// +inline void PrimResult::setResultKind(ValueKind vk) +{ + assert(isStorableKind(vk) || isMemoryKind(vk)); + setOperation((PrimitiveOperation)(poResult_I + vk - vkInt)); +} + +#endif diff --git a/ef/Compiler/PrimitiveGraph/SysCalls.cpp b/ef/Compiler/PrimitiveGraph/SysCalls.cpp new file mode 100644 index 000000000000..0d00e92dfa02 --- /dev/null +++ b/ef/Compiler/PrimitiveGraph/SysCalls.cpp @@ -0,0 +1,74 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#include "SysCalls.h" +#include "JavaObject.h" +#include +#include + + +static const ValueKind kinds_a[] = {vkAddr}; +static const ValueKind kinds_aa[] = {vkAddr, vkAddr}; +static const ValueKind kinds_m[] = {vkMemory}; +static const ValueKind kinds_ma[] = {vkMemory, vkAddr}; +static const ValueKind kinds_mai[] = {vkMemory, vkAddr, vkInt}; +static const ValueKind kinds_maa[] = {vkMemory, vkAddr, vkAddr}; +static const ValueKind kinds_maii[] = {vkMemory, vkAddr, vkInt, vkInt}; +static const ValueKind kinds_maiii[] = {vkMemory, vkAddr, vkInt, vkInt, vkInt}; +static const ValueKind kinds_mi[] = {vkMemory, vkInt}; + +static const bool bools_t[] = {true}; +static const bool bools_tt[] = {true, true}; + +// On x86 platforms we need a guard frame beneath every sys call that generates an exception. +// This is achieved by calling a stub method guarded##name. For now, we use a system dependent macro GUARD +// On platforms that need guard frames we have a stub with the name 'guarded##function', others directly call 'function' +// This will be cleaned up when we bring up exceptions on another platform and understand the issues. +#if defined(_WIN32) // || defined(LINUX) + // FIX -- make MD + #include "x86SysCallsRuntime.h" // declarations + #define GUARD(function) guarded##function +#else + #define GUARD(function) function +#endif + +#ifdef DEBUG_LOG +#define InitSysCall(name, callNumber, operation, nInputs, nOutputs, inputKinds, outputKinds, outputsNonzero, exceptionClass, function) \ + const SysCall sc##name = {callNumber, operation, nInputs, nOutputs, inputKinds, outputKinds, outputsNonzero, exceptionClass, function, #name} +#else +#define InitSysCall(name, callNumber, operation, nInputs, nOutputs, inputKinds, outputKinds, outputsNonzero, exceptionClass, function) \ + const SysCall sc##name = {callNumber, operation, nInputs, nOutputs, inputKinds, outputKinds, outputsNonzero, exceptionClass, function} +#endif + +InitSysCall(Throw, 1, poSysCallEC, 1, 0, kinds_a, 0, 0, cThrowable, sysThrow); // needs no guard +InitSysCall(CheckArrayStore, 6, poSysCallEC, 2, 0, kinds_aa, 0, 0, cArrayStoreException, GUARD(sysCheckArrayStore)); +InitSysCall(MonitorEnter, 7, poSysCallEV, 2, 1, kinds_ma, kinds_m, bools_t, cThrowable, GUARD(sysMonitorEnter)); +InitSysCall(MonitorExit, 8, poSysCallEV, 2, 1, kinds_ma, kinds_m, bools_t, cIllegalMonitorStateException, GUARD(sysMonitorExit)); +InitSysCall(New, 9, poSysCallEV, 2, 2, kinds_ma, kinds_ma, bools_tt, cThrowable, GUARD(sysNew)); +InitSysCall(NewBooleanArray, 10, poSysCallEV, 2, 2, kinds_mi, kinds_ma, bools_tt, cThrowable, GUARD(sysNewBooleanArray)); +InitSysCall(NewByteArray, 11, poSysCallEV, 2, 2, kinds_mi, kinds_ma, bools_tt, cThrowable, GUARD(sysNewByteArray)); +InitSysCall(NewShortArray, 12, poSysCallEV, 2, 2, kinds_mi, kinds_ma, bools_tt, cThrowable, GUARD(sysNewShortArray)); +InitSysCall(NewCharArray, 13, poSysCallEV, 2, 2, kinds_mi, kinds_ma, bools_tt, cThrowable, GUARD(sysNewCharArray)); +InitSysCall(NewIntArray, 14, poSysCallEV, 2, 2, kinds_mi, kinds_ma, bools_tt, cThrowable, GUARD(sysNewIntArray)); +InitSysCall(NewLongArray, 15, poSysCallEV, 2, 2, kinds_mi, kinds_ma, bools_tt, cThrowable, GUARD(sysNewLongArray)); +InitSysCall(NewFloatArray, 16, poSysCallEV, 2, 2, kinds_mi, kinds_ma, bools_tt, cThrowable, GUARD(sysNewFloatArray)); +InitSysCall(NewDoubleArray, 17, poSysCallEV, 2, 2, kinds_mi, kinds_ma, bools_tt, cThrowable, GUARD(sysNewDoubleArray)); +InitSysCall(NewObjectArray, 18, poSysCallEV, 3, 2, kinds_mai, kinds_ma, bools_tt, cThrowable, GUARD(sysNewObjectArray)); +InitSysCall(New2DArray, 19, poSysCallEV, 4, 2, kinds_maii, kinds_ma, bools_tt, cThrowable, GUARD(sysNew2DArray)); +InitSysCall(New3DArray, 20, poSysCallEV, 5, 2, kinds_maiii, kinds_ma, bools_tt, cThrowable, GUARD(sysNew3DArray)); +InitSysCall(NewNDArray, 21, poSysCallEV, 3, 2, kinds_maa, kinds_ma, bools_tt, cThrowable, GUARD(sysNewNDArray)); diff --git a/ef/Compiler/PrimitiveGraph/SysCalls.h b/ef/Compiler/PrimitiveGraph/SysCalls.h new file mode 100644 index 000000000000..e178705f8506 --- /dev/null +++ b/ef/Compiler/PrimitiveGraph/SysCalls.h @@ -0,0 +1,63 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#ifndef SYSCALLS_H +#define SYSCALLS_H + +#include "Primitives.h" +#include "SysCallsRuntime.h" + +struct SysCall +{ + uint callNumber; // Unique number identifying this call type + PrimitiveOperation operation; // The PrimitiveOperation to use for instances of this system call + uint nInputs; // Number of DataConsumers in this system call + uint nOutputs; // Number of outgoing data edges in this system call + const ValueKind *inputKinds; // Kinds of DataConsumers in this system call + const ValueKind *outputKinds; // Kinds of outgoing data edges in this system call + const bool *outputsNonzero; // Array of flags that state whether the outgoing data edges are always nonzero + StandardClass exceptionClass; // Superclass of all possible classes of exceptions thrown by this system call + // or cNone if this system call cannot throw any exceptions + void *function; // Function which implements this system call + + #ifdef DEBUG_LOG + const char *name; // Name of this call + #endif + + bool hasMemoryOutput() const {return operation == poSysCallV || operation == poSysCallEV;} + bool hasMemoryInput() const {return operation == poSysCall || operation == poSysCallE || hasMemoryOutput();} +}; + +extern const SysCall scThrow; +extern const SysCall scCheckArrayStore; +extern const SysCall scMonitorEnter; +extern const SysCall scMonitorExit; +extern const SysCall scNew; +extern const SysCall scNewBooleanArray; +extern const SysCall scNewByteArray; +extern const SysCall scNewShortArray; +extern const SysCall scNewCharArray; +extern const SysCall scNewIntArray; +extern const SysCall scNewLongArray; +extern const SysCall scNewFloatArray; +extern const SysCall scNewDoubleArray; +extern const SysCall scNewObjectArray; +extern const SysCall scNew2DArray; +extern const SysCall scNew3DArray; +extern const SysCall scNewNDArray; + +#endif diff --git a/ef/Compiler/PrimitiveGraph/Value.cpp b/ef/Compiler/PrimitiveGraph/Value.cpp new file mode 100644 index 000000000000..cbe4e5b9c023 --- /dev/null +++ b/ef/Compiler/PrimitiveGraph/Value.cpp @@ -0,0 +1,151 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#include "Value.h" +#include "DebugUtils.h" + +#ifdef DEBUG_LOG +// +// Print the name of the Condition onto the output stream f. +// Return the number of characters printed. +// +int print(LogModuleObject &f, Condition c) +{ + const char *cName = "??"; + switch (c) { + case cLt: + cName = "LT"; + break; + case cEq: + cName = "EQ"; + break; + case cGt: + cName = "GT"; + break; + case cUn: + cName = "UN"; + break; + } + return UT_OBJECTLOG(f, PR_LOG_ALWAYS, (cName)); +} + + +const char valueKindShortNames[nValueKinds] = +{ + 'v', // vkVoid + 'i', // vkInt + 'l', // vkLong + 'f', // vkFloat + 'd', // vkDouble + 'a', // vkAddr + 'c', // vkCond + 'm', // vkMemory + 't' // vkTuple +}; + + +// +// Return the one-character abbreviation for the given ValueKind. +// +char valueKindShortName(ValueKind vk) +{ + return (uint)vk >= nValueKinds ? '?' : valueKindShortNames[vk]; +} + + +const char valueKindNames[nValueKinds][8] = +{ + "void", // vkVoid + "int", // vkInt + "long", // vkLong + "float", // vkFloat + "double", // vkDouble + "addr", // vkAddr + "cond", // vkCond + "memory", // vkMemory + "tuple" // vkTuple +}; + + +// +// Print the name of the ValueKind onto the output stream f. +// Return the number of characters printed. +// +int print(LogModuleObject &f, ValueKind vk) +{ + return UT_OBJECTLOG(f, PR_LOG_ALWAYS, ((uint)vk >= nValueKinds ? "????" : valueKindNames[vk])); +} +#endif + + +const ValueKind typeKindValueKinds[nTypeKinds] = +{ + vkVoid, // tkVoid + vkInt, // tkBoolean + vkInt, // tkUByte + vkInt, // tkByte + vkInt, // tkChar + vkInt, // tkShort + vkInt, // tkInt + vkLong, // tkLong + vkFloat, // tkFloat + vkDouble, // tkDouble + vkAddr, // tkObject + vkAddr, // tkSpecial + vkAddr, // tkArray + vkAddr // tkInterface +}; + + +// ---------------------------------------------------------------------------- +// Value + + +#ifdef DEBUG_LOG +// +// Print this Value for debugging purposes. +// Return the number of characters printed. +// +int Value::print(LogModuleObject &f, ValueKind vk) const +{ + switch (vk) { + case vkVoid: + return UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("VOID")); + case vkInt: + return UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("%d", i)); + case vkLong: + { + int a = printInt64(f, l); + return a + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("L")); + } + case vkFloat: + return UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("%gf", Value::f)); + case vkDouble: + return UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("%gd", Value::d)); + case vkAddr: + return ::print(f, a); + case vkCond: + return ::print(f, c); + case vkMemory: + return UT_OBJECTLOG(f, PR_LOG_ALWAYS, (m == mConstant ? "mConstant" : "????")); + case vkTuple: + return UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("TUPLE")); + default: + return UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("????")); + } +} +#endif diff --git a/ef/Compiler/PrimitiveGraph/Value.h b/ef/Compiler/PrimitiveGraph/Value.h new file mode 100644 index 000000000000..f840ec782bb0 --- /dev/null +++ b/ef/Compiler/PrimitiveGraph/Value.h @@ -0,0 +1,448 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#ifndef VALUE_H +#define VALUE_H + +#include "FloatUtils.h" +#include "Address.h" +#include "LogModule.h" + +enum Memory // Possible values of a vkMemory Value +{ + mConstant // Memory region representing immutable values + // Most memory regions are mutable, but they can never be constants inside a Value, + // so they don't have constant values in the Memory enum. +}; + + +enum Condition // Possible values of a vkCond Value generated by comparing arg1 with arg2 +{ + cLt = 1, // arg1 < arg2 + cEq = 2, // arg1 = arg2 + cGt = 4, // arg1 > arg2 + cUn = 8 // either arg1 or arg2 is a NaN +}; + +#ifdef DEBUG_LOG +int print(LogModuleObject &f, Condition c); +#endif + + +enum Condition2 // Two-way conditional +{ + cond0, // 0000 Always false + condLt, // 0001 arg1 < arg2 + condEq, // 0010 arg1 = arg2 + condLe, // 0011 arg1 <= arg2 + condGt, // 0100 arg1 > arg2 + condLgt, // 0101 arg1 <> arg2 + condGe, // 0110 arg1 >= arg2 + condOrd, // 0111 arg1 <=> arg2 (i.e. arg1 and arg2 are ordered) + condUnord, // 1000 arg1 ? arg2 (i.e. arg1 and arg2 are unordered) + condULt, // 1001 arg1 ?< arg2 + condUEq, // 1010 arg1 ?= arg2 + condULe, // 1011 arg1 ?<= arg2 + condUGt, // 1100 arg1 ?> arg2 + condNe, // 1101 arg1 != arg2 + condUGe, // 1110 arg1 ?>= arg2 + cond1 // 1111 Always true +}; + +// Return a condition c' such that for all arg1, arg2: (arg1 c arg2) = (arg2 c' arg1) +inline Condition2 reverse(Condition2 c) {return (Condition2)(c&0xA | (c&4)>>2 | (c&1)<<2);} + +// Return a condition c' such that for all arg1, arg2: !(arg1 c arg2) = (arg1 c' arg2) +inline Condition2 invert(Condition2 c) {return (Condition2)(c^cond1);} + +// Return the result of applying the Condition2 to the Condition. +inline bool applyCondition(Condition2 comp, Condition c) {return (comp & c) != 0;} + + +enum Condition3 // Three-way conditional +{ // lt eq gt un + cond3L, // -1 0 1 -1 + cond3G, // -1 0 1 1 + cond3CL, // 1 0 -1 -1 + cond3CG // 1 0 -1 1 +}; + +// Return a condition c' such that for all arg1, arg2: (arg1 c arg2) = (arg2 c' arg1) +inline Condition3 reverse(Condition3 c) {return (Condition3)(c^2);} + +// Return a condition c' such that for all arg1, arg2: -(arg1 c arg2) = (arg1 c' arg2) +inline Condition3 invert(Condition3 c) {return (Condition3)(c^cond3CG);} + +// Return the result of applying the Condition3 to the Condition. +inline int applyCondition(Condition3 comp, Condition c) {return c == cEq ? 0 : ((0x91c4>>(comp<<2) & c) != 0)*2 - 1;} + + +// ---------------------------------------------------------------------------- + +enum ValueKind // Concrete? RegOrMem? #words (as defined by the Java stack model) +{ // Java? Storable? + vkVoid, // yes yes no no N/A // No value + vkInt, // yes yes yes yes 1 // 32-bit integer or high or low half of a long + vkLong, // yes yes yes yes 2 // 64-bit integer + vkFloat, // yes yes yes yes 1 // 32-bit float + vkDouble, // yes yes yes yes 2 // 64-bit float + vkAddr, // yes yes yes yes 1 // Pointer + vkCond, // yes no yes no N/A // The result of a compare + vkMemory, // no no yes no N/A // Value representing all of memory in data flow edges + vkTuple // no no no no N/A // Value representing a tuple of other values +}; +const nValueKinds = vkTuple + 1; + +inline ValueKind typeKindToValueKind(TypeKind tk); + +inline bool isConcreteKind(ValueKind vk) {return vk <= vkCond;} +inline bool isJavaKind(ValueKind vk) {return vk <= vkAddr;} +inline bool isRegOrMemKind(ValueKind vk) {return vk != vkVoid && vk <= vkMemory;} +inline bool isStorableKind(ValueKind vk) {return vk != vkVoid && vk <= vkAddr;} + +inline bool isVoidKind(ValueKind vk) {return vk == vkVoid;} +inline bool isIntegerKind(ValueKind vk) {return vk == vkInt || vk == vkLong;} +inline bool isFloatingPointKind(ValueKind vk) {return vk == vkFloat || vk == vkDouble;} +inline bool isMemoryKind(ValueKind vk) {return vk == vkMemory;} +// isWordKind and isDoublewordKind indicate whether a Java ValueKind takes +// one or two words in the Java stack model; this does not necessarily mean +// that that value's actual machine representation takes one or two machine words. +// For example, the Java stack model states that an address is one word, but on +// a 64-bit implementation an address takes two *machine words*. +inline bool isWordKind(ValueKind vk) {return vk == vkInt || vk == vkFloat || vk == vkAddr;} +inline bool isDoublewordKind(ValueKind vk) {return vk == vkLong || vk == vkDouble;} + +#ifdef DEBUG_LOG +char valueKindShortName(ValueKind vk); +int print(LogModuleObject &f, ValueKind vk); +#endif + + +union Value +{ + Int32 i; // Integer value + Int64 l; // Long value + Flt32 f; // Float value + Flt64 d; // Double value + addr a; // Pointer value + Condition c; // Condition value + Memory m; // Memory region value + + bool isNonzero(ValueKind kind) const; + bool eq(ValueKind kind, const Value &v2) const; + + // This should be based on a template instead of a + // dummy argument, but some compilers don't support that yet. + Int32 getValueContents(Int32 *) const {return i;} + #ifdef __MWERKS__ + const Int64 &getValueContents(Int64 *) const {return l;} + #else + Int64 getValueContents(Int64 *) const {return l;} + #endif + Flt32 getValueContents(Flt32 *) const {return f;} + Flt64 getValueContents(Flt64 *) const {return d;} + addr getValueContents(addr *) const {return a;} + Condition getValueContents(Condition *) const {return c;} + Memory getValueContents(Memory *) const {return m;} + #define TypeGetValueContents(T) getValueContents((T *)0) + + void setValueContents(Int32 v) {i = v;} + void setValueContents(Int64 v) {l = v;} + void setValueContents(Flt32 v) {f = v;} + void setValueContents(Flt64 v) {d = v;} + void setValueContents(addr v) {a = v;} + void setValueContents(Condition v) {c = v;} + void setValueContents(Memory v) {m = v;} + + #ifdef DEBUG_LOG + int print(LogModuleObject &f, ValueKind vk) const; + #endif +}; + + +// Return the kind of the value. +#if defined __MWERKS__ || defined __GNUC__ || defined WIN32 + // This should be based on a template instead of a dummy argument, but some compilers don't support that yet. + inline ValueKind valueKind(Int32 *) {return vkInt;} + inline ValueKind valueKind(Int64 *) {return vkLong;} + inline ValueKind valueKind(Flt32 *) {return vkFloat;} + inline ValueKind valueKind(Flt64 *) {return vkDouble;} + inline ValueKind valueKind(addr *) {return vkAddr;} + inline ValueKind valueKind(Condition *) {return vkCond;} + inline ValueKind valueKind(Memory *) {return vkMemory;} + #define TypeValueKind(T) valueKind((T *)0) +#else + template ValueKind valueKind(); + template<> inline ValueKind valueKind() {return vkInt;} + template<> inline ValueKind valueKind() {return vkLong;} + template<> inline ValueKind valueKind() {return vkFloat;} + template<> inline ValueKind valueKind() {return vkDouble;} + template<> inline ValueKind valueKind() {return vkAddr;} + template<> inline ValueKind valueKind() {return vkCond;} + template<> inline ValueKind valueKind() {return vkMemory;} + #define TypeValueKind(T) valueKind() +#endif + + +// Return true if v is (positive or negative) zero or cEq. +inline bool isZero(Int32 v) {return v == 0;} +inline bool isZero(Int64 v) {return v == 0;} +inline bool isZero(Flt32 v) {return v == 0.0f;} +inline bool isZero(Flt64 v) {return v == 0.0;} +inline bool isZero(addr v) {return !v;} +inline bool isZero(Condition v) {return v == cEq;} +inline bool isZero(Memory) {return true;} // Only constant memory regions can be represented as values + +// Return true if v is infinite. (Equivalent functions for floating-point values located in FloatUtils.h) +inline bool isInfinite(Int32) {return false;} +inline bool isInfinite(Int64) {return false;} +inline bool isInfinite(addr) {return false;} +inline bool isInfinite(Condition) {return false;} +inline bool isInfinite(Memory) {return false;} + +// Return true if v is a NaN. +inline bool isNaN(Int32) {return false;} +inline bool isNaN(Int64) {return false;} +//inline bool isNaN(Flt32) // Defined in FloatUtils.h +//inline bool isNaN(Flt64) // Defined in FloatUtils.h +inline bool isNaN(addr) {return false;} +inline bool isNaN(Condition) {return false;} +inline bool isNaN(Memory) {return false;} + + +#define VALUE_FITS(mask, v, out, cast) \ + PR_BEGIN_MACRO \ + if ((~mask & v.i) > 0) \ + return (false); \ + else \ + { \ + out = (cast)(mask & v.i); \ + return (true); \ + } \ + PR_END_MACRO + +inline bool extractU8(const Value& v, Uint8& out) { VALUE_FITS(0xFF, v, out, Uint8); } +inline bool extractU16(const Value& v, Uint16& out) { VALUE_FITS(0xFFFF, v, out, Uint16); } +inline bool extractS16(const Value& v, Int16& out) +{ + if ((v.i >= -32768 && v.i < 32767)) + { + out = (Int16) v.i; + return (true); + } + else + return (false); +} + + +inline bool extractU32(const Value& v, Uint32& out) { out = v.i; return (true); } +inline bool isPowerOfTwo(const Uint32 v) { return (!(v & (v-1)) && v); } + +inline Uint8 leadingZeros(const Uint32 v) +{ +#ifdef __MWERKS__ + return (__cntlzw(v)); +#else + Uint32 mask = 0x80000000; + Uint8 leadingZeros; + + for (leadingZeros = 0; (v & mask) != v; leadingZeros++, mask>>=1) + ; + + return (leadingZeros); +#endif +} + +#ifdef _WIN32 +#pragma warning( disable : 4035 ) +inline uint leastSigBit(Uint32 v) +{ + __asm bsf eax, v +} +#pragma warning( default : 4035 ) +#endif //_WIN32 +inline bool valueIsOneByteSigned(Uint32 inValue) +{ + uint temp = inValue >> 7; + if(temp == 0 || temp == 0x01ffffff) + return true; + return false; +} + + +// Return true if v+x is identical to v for all x of the same type as v. +inline bool isAdditiveAnnihilator(Int32) {return false;} +inline bool isAdditiveAnnihilator(Int64) {return false;} +inline bool isAdditiveAnnihilator(Flt32 v) {return isNaN(v);} +inline bool isAdditiveAnnihilator(Flt64 v) {return isNaN(v);} + +// Return true if v+x is identical to x for all x of the same type as v. +inline bool isAdditiveIdentity(Int32 v) {return v == 0;} +inline bool isAdditiveIdentity(Int64 v) {return v == 0;} +inline bool isAdditiveIdentity(Flt32 v) {return isNegativeZero(v);} // v=+0.0 doesn't work because 0.0+-0.0 !eq -0.0 +inline bool isAdditiveIdentity(Flt64 v) {return isNegativeZero(v);} // v=+0.0 doesn't work because 0.0+-0.0 !eq -0.0 + +// Return true if v*x is identical to v for all x of the same type as v. +inline bool isMultiplicativeAnnihilator(Int32 v) {return v == 0;} +inline bool isMultiplicativeAnnihilator(Int64 v) {return v == 0;} +inline bool isMultiplicativeAnnihilator(Flt32 v) {return isNaN(v);} // v=+0.0 or -0.0 doesn't work because 0.0*-1.0 !eq 0.0*1.0 +inline bool isMultiplicativeAnnihilator(Flt64 v) {return isNaN(v);} // v=+0.0 or -0.0 doesn't work because 0.0*-1.0 !eq 0.0*1.0 + +// Return true if v*x is identical to x for all x of the same type as v. +inline bool isMultiplicativeIdentity(Int32 v) {return v == 1;} +inline bool isMultiplicativeIdentity(Int64 v) {return v == 1;} +inline bool isMultiplicativeIdentity(Flt32 v) {return v == 1.0f;} +inline bool isMultiplicativeIdentity(Flt64 v) {return v == 1.0;} + +// Return true if v*x is identical to -x for all x of the same type as v. +inline bool isMultiplicativeNegator(Int32 v) {return v == -1;} +inline bool isMultiplicativeNegator(Int64 v) {return v == -1;} +inline bool isMultiplicativeNegator(Flt32 v) {return v == -1.0f;} +inline bool isMultiplicativeNegator(Flt64 v) {return v == -1.0;} + +// Return the (positive) zero element v of the given type. +// This should be based on a template instead of a dummy argument, but some compilers don't support that yet. +inline Int32 getZero(Int32 *) {return 0;} +inline Int64 getZero(Int64 *) {return 0;} +inline Flt32 getZero(Flt32 *) {return 0.0f;} +inline Flt64 getZero(Flt64 *) {return 0.0;} +inline addr getZero(addr *) {return nullAddr;} +#define TypeGetZero(T) getZero((T *)0) + +// Return the element v of the given type such that v+x is identical to x for all x of the same type. +// This should be based on a template instead of a dummy argument, but some compilers don't support that yet. +inline Int32 getAdditiveIdentity(Int32 *) {return 0;} +inline Int64 getAdditiveIdentity(Int64 *) {return 0;} +inline Flt32 getAdditiveIdentity(Flt32 *) {return floatNegativeZero;} +inline Flt64 getAdditiveIdentity(Flt64 *) {return doubleNegativeZero;} +#define TypeGetAdditiveIdentity(T) getAdditiveIdentity((T *)0) + +// Return the NaN of the given type. +// This should be based on a template instead of a dummy argument, but some compilers don't support that yet. +inline Int32 getNaN(Int32 *) {trespass("No Int32 NaN"); return 0;} +inline Int64 getNaN(Int64 *) {trespass("No Int64 NaN"); return 0;} +inline Flt32 getNaN(Flt32 *) {return floatNaN;} +inline Flt64 getNaN(Flt64 *) {return doubleNaN;} +#define TypeGetNaN(T) getNaN((T *)0) + + +// Convert the signed integer to unsigned. +inline Uint8 toUnsigned(Int8 i) {return (Uint8)i;} +inline Uint16 toUnsigned(Int16 i) {return (Uint16)i;} +inline Uint32 toUnsigned(Int32 i) {return (Uint32)i;} +inline Uint64 toUnsigned(Int64 i) {return (Uint64)i;} + +// Convert the unsigned integer to signed. +inline Int8 toSigned(Uint8 i) {return (Int8)i;} +inline Int16 toSigned(Uint16 i) {return (Int16)i;} +inline Int32 toSigned(Uint32 i) {return (Int32)i;} +inline Int64 toSigned(Uint64 i) {return (Int64)i;} + +// Convert the argument number to the result number using Java's conventions for conversion. +inline void convertNumber(Int32 arg, Int64 &result) {result = arg;} +inline void convertNumber(Int32 arg, Flt32 &result) {result = int32ToFlt32(arg);} +inline void convertNumber(Int32 arg, Flt64 &result) {result = int32ToFlt64(arg);} +inline void convertNumber(Int64 arg, Int32 &result) {result = (Int32)arg;} +inline void convertNumber(Int64 arg, Flt32 &result) {result = int64ToFlt32(arg);} +inline void convertNumber(Int64 arg, Flt64 &result) {result = int64ToFlt64(arg);} +inline void convertNumber(Flt32 arg, Int32 &result) {result = flt32ToInt32(arg);} +inline void convertNumber(Flt32 arg, Int64 &result) {result = flt32ToInt64(arg);} +inline void convertNumber(Flt32 arg, Flt64 &result) {result = arg;} +inline void convertNumber(Flt64 arg, Int32 &result) {result = flt64ToInt32(arg);} +inline void convertNumber(Flt64 arg, Int64 &result) {result = flt64ToInt64(arg);} +inline void convertNumber(Flt64 arg, Flt32 &result) {result = (Flt32)arg;} + + +// Compare arg1 with arg2. If unsignedCompare is true, the values are treated as unsigned. +inline Condition compare(Int32 arg1, Int32 arg2, bool unsignedCompare) + {return (Condition)((unsignedCompare ? (Uint32)arg1 > (Uint32)arg2 : arg1 > arg2)*(cGt-cLt) + (arg1 == arg2)*(cEq-cLt) + cLt);} +inline Condition compare(Int64 arg1, Int64 arg2, bool unsignedCompare) + {return (Condition)((unsignedCompare ? (Uint64)arg1 > (Uint64)arg2 : arg1 > arg2)*(cGt-cLt) + (arg1 == arg2)*(cEq-cLt) + cLt);} +inline Condition compare(Flt32 arg1, Flt32 arg2, bool) + {return isNaN(arg1) || isNaN(arg2) ? cUn : (Condition)((arg1 > arg2)*(cGt-cLt) + (arg1 == arg2)*(cEq-cLt) + cLt);} +inline Condition compare(Flt64 arg1, Flt64 arg2, bool) + {return isNaN(arg1) || isNaN(arg2) ? cUn : (Condition)((arg1 > arg2)*(cGt-cLt) + (arg1 == arg2)*(cEq-cLt) + cLt);} +inline Condition compare(addr arg1, addr arg2, bool) + {return (Condition)((arg1 > arg2)*(cGt-cLt) + (arg1 == arg2)*(cEq-cLt) + cLt);} + + +// --- INLINES ---------------------------------------------------------------- + + +extern const ValueKind typeKindValueKinds[nTypeKinds]; // ValueKind for each TypeKind + +inline ValueKind typeKindToValueKind(TypeKind tk) +{ + return typeKindValueKinds[tk]; +} + + +// +// Return true if this value is not equal to zero. This is a numerical +// comparison, so if this is a float or double, then this function will +// return true if this value is either +0.0 or -0.0. A condition value +// is considered to be zero if and only if it is cEq. +// +inline bool Value::isNonzero(ValueKind kind) const +{ + switch (kind) { + case vkInt: + return i != 0; + case vkLong: + return l != 0; + case vkFloat: + return f != 0.0f; + case vkDouble: + return d != 0.0; + case vkAddr: + return !a; + case vkCond: + return c != cEq; + default: + return true; + } +} + + +// +// Return true if this and v2 are identical values. Both are assumed +// to have the given kind. +// Note that this is a bitwise identity comparison, not a numerical +// value comparison -- for example, a floating-point NaN will compare +// equal to itself, while the floating-point operator == would return +// false. Moreover, comparing +0.0 with -0.0 will return false, while +// using == to compare them would return true. +// +inline bool Value::eq(ValueKind kind, const Value &v2) const +{ + switch (kind) { + case vkInt: + case vkFloat: + return i == v2.i; + case vkLong: + case vkDouble: + return l == v2.l; + case vkAddr: + return a == v2.a; + case vkCond: + return c == v2.c; + default: + return true; + } +} + +#endif diff --git a/ef/Compiler/PrimitiveGraph/test.cpp b/ef/Compiler/PrimitiveGraph/test.cpp new file mode 100644 index 000000000000..e45725d0e5d5 --- /dev/null +++ b/ef/Compiler/PrimitiveGraph/test.cpp @@ -0,0 +1,73 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +//#include +#include "PrimitiveBuilders.h" +#include "Primitives.h" +#include "Pool.h" +#include "ControlGraph.h" + +#include "CodeGenerator.h" + +void main() +{ + + Pool* myPool = new Pool(8192, 1024); + ValueKind* dummyKinds = NULL; + ControlGraph* myPissAssGraph = new ControlGraph((*myPool), 0, dummyKinds, false); + ControlNode* myNode = &myPissAssGraph->newControlNode(); + + PrimArg* incoming1 = new PrimArg(); + incoming1->initOutgoingEdge(vkInt, false); + + PrimArg* incoming2 = new PrimArg(); + incoming2->initOutgoingEdge(vkInt, false); + + PrimArg* incoming3 = new PrimArg(); + incoming3->initOutgoingEdge(vkInt, false); + + PrimArg* incoming4 = new PrimArg(); + incoming4->initOutgoingEdge(vkInt, false); + + ProducerOrConstant* inputs= new ProducerOrConstant[2]; + ProducerOrConstant* inputs2= new ProducerOrConstant[2]; + + builder_Add_III.specializeConstVar(10, incoming1->getOutgoingEdge(), inputs[0], myNode); + + inputs[1].setVar(incoming2->getOutgoingEdge()); + + builder_Add_III.makeBinaryGeneric(inputs, inputs2[0], myNode); + + + inputs2[1].setVar(incoming3->getOutgoingEdge()); + + builder_Add_III.makeBinaryGeneric(inputs2, inputs2[1], myNode); + + + ProducerOrConstant cond; + builder_Cmp_IIC.makeBinaryGeneric(inputs2, cond, myNode); + + + + + ControlIf* myIfNode = new ControlIf((*myNode), condLt, cond.getProducer()); + + CodeGenerator engine(*myNode, *myPool); + + engine.generate(); +} diff --git a/ef/Compiler/RegisterAllocator/Coloring.cpp b/ef/Compiler/RegisterAllocator/Coloring.cpp new file mode 100644 index 000000000000..846bf058f61d --- /dev/null +++ b/ef/Compiler/RegisterAllocator/Coloring.cpp @@ -0,0 +1,280 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#include "Coloring.h" +#include "VirtualRegister.h" +#include "FastBitSet.h" +#include "FastBitMatrix.h" +#include "CpuInfo.h" + +bool Coloring:: +assignRegisters(FastBitMatrix& interferenceMatrix) +{ + PRUint32 *stackPtr = new(pool) PRUint32[vRegManager.count()]; + + return select(interferenceMatrix, stackPtr, simplify(interferenceMatrix, stackPtr)); +} + +PRInt32 Coloring:: +getLowestSpillCostRegister(FastBitSet& bitset) +{ + PRInt32 lowest = bitset.firstOne(); + if (lowest != -1) + { + Flt32 cost = vRegManager.getVirtualRegister(lowest).spillInfo.spillCost; + for (PRInt32 r = bitset.nextOne(lowest); r != -1; r = bitset.nextOne(r)) + { + VirtualRegister& vReg = vRegManager.getVirtualRegister(r); + if (!vReg.spillInfo.infiniteSpillCost && (vReg.spillInfo.spillCost < cost)) + { + cost = vReg.spillInfo.spillCost; + lowest = r; + } + } + } + return lowest; +} + +PRUint32* Coloring:: +simplify(FastBitMatrix interferenceMatrix, PRUint32* stackPtr) +{ + // first we construct the sets low and high. low contains all nodes of degree + // inferior to the number of register available on the processor. All the + // nodes with an high degree and a finite spill cost are placed in high. + // Nodes of high degree and infinite spill cost are not included in either sets. + + PRUint32 nRegisters = vRegManager.count(); + FastBitSet low(pool, nRegisters); + FastBitSet high(pool, nRegisters); + FastBitSet stack(pool, nRegisters); + + for (VirtualRegisterManager::iterator i = vRegManager.begin(); !vRegManager.done(i); i = vRegManager.advance(i)) + { + VirtualRegister& vReg = vRegManager.getVirtualRegister(i); + + if (vReg.getClass() == vrcStackSlot) + { + stack.set(i); + vReg.colorRegister(nRegisters); + } + else + { + if (vReg.colorInfo.interferenceDegree < NUMBER_OF_REGISTERS) + low.set(i); + else // if (!vReg.spillInfo.infiniteSpillCost) + high.set(i); + + // Set coloring info. + vReg.spillInfo.willSpill = false; + + switch(vReg.getClass()) + { + case vrcInteger: + vReg.colorRegister(LAST_GREGISTER + 1); + break; + case vrcFloatingPoint: + case vrcFixedPoint: + vReg.colorRegister(LAST_FPREGISTER + 1); + break; + default: + PR_ASSERT(false); // Cannot happen. + } + } + } + + // push the stack registers + PRInt32 j; + for (j = stack.firstOne(); j != -1; j = stack.nextOne(j)) + *stackPtr++ = j; + + // simplify + while (true) + { + PRInt32 r; + while ((r = getLowestSpillCostRegister(low)) != -1) + { + VirtualRegister& vReg = vRegManager.getVirtualRegister(r); + + /* update low and high */ + FastBitSet inter(interferenceMatrix.getRow(r), nRegisters); + for (j = inter.firstOne(); j != -1; j = inter.nextOne(j)) + { + VirtualRegister& neighbor = vRegManager.getVirtualRegister(j); + // if the new interference degree of one of his neighbor becomes + // NUMBER_OF_REGISTERS - 1 then it is added to the set 'low'. + + PRUint32 maxInterference = 0; + switch (neighbor.getClass()) + { + case vrcInteger: + maxInterference = NUMBER_OF_GREGISTERS; + break; + case vrcFloatingPoint: + case vrcFixedPoint: + maxInterference = NUMBER_OF_FPREGISTERS; + break; + default: + PR_ASSERT(false); + } + if ((vRegManager.getVirtualRegister(j).colorInfo.interferenceDegree-- == maxInterference)) + { + high.clear(j); + low.set(j); + } + vReg.colorInfo.interferenceDegree--; + interferenceMatrix.clear(r, j); + interferenceMatrix.clear(j, r); + } + low.clear(r); + + // Push this register. + *stackPtr++ = r; + } + if ((r = getLowestSpillCostRegister(high)) != -1) + { + high.clear(r); + low.set(r); + } + else + break; + } + + return stackPtr; +} + +bool Coloring:: +select(FastBitMatrix& interferenceMatrix, PRUint32* stackBase, PRUint32* stackPtr) +{ + PRUint32 nRegisters = vRegManager.count(); + FastBitSet usedRegisters(NUMBER_OF_REGISTERS + 1); // usedRegisters if used for both GR & FPR. + FastBitSet preColoredRegisters(NUMBER_OF_REGISTERS + 1); + FastBitSet usedStack(nRegisters + 1); + bool success = true; + Int32 lastUsedSSR = -1; + + // select + while (stackPtr != stackBase) + { + // Pop one register. + PRUint32 r = *--stackPtr; + VirtualRegister& vReg = vRegManager.getVirtualRegister(r); + + FastBitSet neighbors(interferenceMatrix.getRow(r), nRegisters); + + if (vReg.getClass() == vrcStackSlot) + // Stack slots coloring. + { + usedStack.clear(); + + for (PRInt32 i = neighbors.firstOne(); i != -1; i = neighbors.nextOne(i)) + usedStack.set(vRegManager.getVirtualRegister(i).getColor()); + + Int32 color = usedStack.firstZero(); + vReg.colorRegister(color); + if (color > lastUsedSSR) + lastUsedSSR = color; + } + else + // Integer & Floating point register coloring. + { + usedRegisters.clear(); + preColoredRegisters.clear(); + + for (PRInt32 i = neighbors.firstOne(); i != -1; i = neighbors.nextOne(i)) + { + VirtualRegister& nvReg = vRegManager.getVirtualRegister(i); + usedRegisters.set(nvReg.getColor()); + if (nvReg.isPreColored()) + preColoredRegisters.set(nvReg.getPreColor()); + } + if (vReg.hasSpecialInterference) + usedRegisters |= vReg.specialInterference; + + PRInt8 c = -1; + PRInt8 maxColor = 0; + PRInt8 firstColor = 0; + switch (vReg.getClass()) + { + case vrcInteger: + firstColor = FIRST_GREGISTER; + maxColor = LAST_GREGISTER; + break; + case vrcFloatingPoint: + case vrcFixedPoint: + firstColor = FIRST_FPREGISTER; + maxColor = LAST_FPREGISTER; + break; + default: + PR_ASSERT(false); + } + + if (vReg.isPreColored()) + { + c = vReg.getPreColor(); + if (usedRegisters.test(c)) + c = -1; + } + else + { + for (c = usedRegisters.nextZero(firstColor - 1); (c >= 0) && (c <= maxColor) && (preColoredRegisters.test(c)); + c = usedRegisters.nextZero(c)) {} + } + + if ((c >= 0) && (c <= maxColor)) + { + vReg.colorRegister(c); + } + else + { + VirtualRegister& stackRegister = vRegManager.newVirtualRegister(vrcStackSlot); + vReg.equivalentRegister[vrcStackSlot] = &stackRegister; + vReg.spillInfo.willSpill = true; + success = false; + } + } + } + +#ifdef DEBUG + if (success) + { + for (VirtualRegisterManager::iterator i = vRegManager.begin(); !vRegManager.done(i); i = vRegManager.advance(i)) + { + VirtualRegister& vReg = vRegManager.getVirtualRegister(i); + switch (vReg.getClass()) + { + case vrcInteger: + if (vReg.getColor() > LAST_GREGISTER) + PR_ASSERT(false); + break; + case vrcFloatingPoint: + case vrcFixedPoint: +#if NUMBER_OF_FPREGISTERS != 0 + if (vReg.getColor() > LAST_FPREGISTER) + PR_ASSERT(false); +#endif + break; + default: + break; + } + } + } +#endif + + vRegManager.nUsedStackSlots = lastUsedSSR + 1; + return success; +} diff --git a/ef/Compiler/RegisterAllocator/Coloring.h b/ef/Compiler/RegisterAllocator/Coloring.h new file mode 100644 index 000000000000..f83b6d535aee --- /dev/null +++ b/ef/Compiler/RegisterAllocator/Coloring.h @@ -0,0 +1,46 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#ifndef _COLORING_H_ +#define _COLORING_H_ + +#include "Fundamentals.h" +#include "VirtualRegister.h" +#include "RegisterAssigner.h" +#include "Pool.h" + +class FastBitSet; +class FastBitMatrix; + +class Coloring : public RegisterAssigner +{ +private: + Pool& pool; + +protected: + PRInt32 getLowestSpillCostRegister(FastBitSet& bitset); + PRUint32* simplify(FastBitMatrix interferenceMatrix, PRUint32* stackPtr); + bool select(FastBitMatrix& interferenceMatrix, PRUint32* stackBase, PRUint32* stackPtr); + +public: + Coloring(Pool& p, VirtualRegisterManager& vrMan) : RegisterAssigner(vrMan), pool(p) {} + + virtual bool assignRegisters(FastBitMatrix& interferenceMatrix); +}; + +#endif /* _COLORING_H_ */ diff --git a/ef/Compiler/RegisterAllocator/Liveness.cpp b/ef/Compiler/RegisterAllocator/Liveness.cpp new file mode 100644 index 000000000000..70b7c085bbb7 --- /dev/null +++ b/ef/Compiler/RegisterAllocator/Liveness.cpp @@ -0,0 +1,177 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#include "Fundamentals.h" +#include "Liveness.h" + +#include "FastBitSet.h" +#include "VirtualRegister.h" +#include "ControlGraph.h" +#include "Timer.h" + +// +// Build the liveness analysis. +// +// The liveness is defined by the following data-flow equations: +// LiveIn(n) = LocalLive(n) U (LiveOut(n) - Killed(n)). +// LiveOut(n) = U LiveIn(s) (s a successor of n). +// where LocalLive(n) is the set of used registers in the block n, Killed(n) is the set of defined registers +// in the block n, LiveIn(n) is the set of live registers at the begining a the block n and LiveOut(n) is the +// set of live registers at the end of the block n. +// +// We will compute the liveness analysis in two stages: +// 1- Build LocalLive(n) (wich is an approximation of LiveIn(n)) and Killed(n) for each block n. +// 2- Perform a backward data-flow analysis to propagate the liveness information through the entire control-flow graph. + +void Liveness::buildAcyclicLivenessAnalysis(const ControlGraph& /*controlGraph*/, const VirtualRegisterManager& /*vrManager*/) +{ + trespass("not implemented"); +} + +// +// Build the sets LiveIn & LiveOut for each node of the given cyclic graph (controlGraph). +// +void Liveness::buildCyclicLivenessAnalysis(const ControlGraph& controlGraph, const VirtualRegisterManager& vrManager) +{ + Uint32 nNodes = size = controlGraph.nNodes; // Number of nodes in this graph. + Uint32 nRegisters = vrManager.getSize(); // Number of allocated VirtualRegisters. + + startTimer("liveness"); + + // Allocate and clear the sets LiveIn, LiveOut and Killed (Killed is a temporary, + // it is no longer needed after the liveness analysis). + liveIn = new(pool) FastBitSet[nNodes](pool, nRegisters); + liveOut = new(pool) FastBitSet[nNodes](pool, nRegisters); + FastBitSet* killed = new(pool) FastBitSet[nNodes](pool, nRegisters); + FastBitSet* usedByPhiNodes = new(pool) FastBitSet[nNodes](pool, nRegisters); + + ControlNode** nodes = controlGraph.dfsList; + + // + // First stage of the liveness analysis: Compute the sets LocalLive(stored in LiveIn) and Killed. + // + for (Uint32 n = 0; n < (nNodes - 1); n++) { + ControlNode& node = *nodes[n]; + FastBitSet& currentLocalLive = liveIn[n]; + FastBitSet& currentKilled = killed[n]; + + // If a Virtual Register is defined by a phi node then we add it to the set Killed. Add also the + // used VirtualRegister of this phi node in the set usedByPhiNodes. + DoublyLinkedList& phiNodes = node.getPhiNodes(); + for (DoublyLinkedList::iterator p = phiNodes.begin(); !phiNodes.done(p); p = phiNodes.advance(p)) { + PhiNode& phiNode = phiNodes.get(p); + if (isStorableKind(phiNode.getKind())) { + currentKilled.set(phiNode.getVirtualRegisterAnnotation()->index); + + // Walk the uses. + DataConsumer* consumers = phiNode.getInputsBegin(); + Uint32 predecessorIndex = 0; + + const DoublyLinkedList& predecessors = node.getPredecessors(); + for (DoublyLinkedList::iterator e = predecessors.begin(); !predecessors.done(e); e = predecessors.advance(e)) { + + VirtualRegister& usedRegister = *consumers[predecessorIndex++].getVariable().getVirtualRegisterAnnotation(); + usedByPhiNodes[predecessors.get(e).getSource().dfsNum].set(usedRegister.index); + } + } + } + + // Find the instructions contributions to the sets LocalLive and Killed. + + InstructionList& instructions = node.getInstructions(); + for (InstructionList::iterator i = instructions.begin(); !instructions.done(i); i = instructions.advance(i)) { + Instruction& instruction = instructions.get(i); + + // If a VirtualRegister is 'used' before being 'defined' then we add it to set LocalLive. + InstructionUse* useEnd = instruction.getInstructionUseEnd(); + for (InstructionUse* usePtr = instruction.getInstructionUseBegin(); usePtr < useEnd; usePtr++) + if (usePtr->isVirtualRegister()) { + VirtualRegisterIndex index = usePtr->getVirtualRegister().index; + + if (!currentKilled.test(index)) + currentLocalLive.set(index); + } + + // If a Virtualregister is 'defined' then we add it to the set Killed. + InstructionDefine* defineEnd = instruction.getInstructionDefineEnd(); + for (InstructionDefine* definePtr = instruction.getInstructionDefineBegin(); definePtr < defineEnd; definePtr++) + if (definePtr->isVirtualRegister()) + currentKilled.set(definePtr->getVirtualRegister().index); + } + } + + // + // Second stage of the liveness analysis: We propagate the LiveIn & LiveOut through the entire + // control-flow graph. + // + + FastBitSet temp(pool, nRegisters); + + bool changed; + do { + changed = false; + + for (Int32 n = (nNodes - 2); n >= 0; n--) { // For all nodes in this graph (backward && end block not included). + ControlNode& node = *nodes[n]; + FastBitSet& currentLiveIn = liveIn[n]; + FastBitSet& currentLiveOut = liveOut[n]; + + Uint32 nSuccessors = node.nSuccessors(); + if (nSuccessors != 0) { + temp = liveIn[node.nthSuccessor(0).getTarget().dfsNum]; + for (Uint32 s = 1; s < nSuccessors; s++) + temp |= liveIn[node.nthSuccessor(s).getTarget().dfsNum]; + } else + temp.clear(); + + ControlEdge* successorsEnd = node.getSuccessorsEnd(); + for (ControlEdge* e = node.getSuccessorsBegin(); e < successorsEnd; e++) + temp |= liveIn[e->getTarget().dfsNum]; + + temp |= usedByPhiNodes[n]; + + if (currentLiveOut != temp) { + currentLiveOut = temp; + temp -= killed[n]; + temp |= currentLiveIn; + + if (currentLiveIn != temp) { + currentLiveIn = temp; + changed = true; + } + } + } + } while(changed); + + stopTimer("liveness"); + + DEBUG_LOG_ONLY(printPretty(stdout)); +} + + +#ifdef DEBUG_LOG +void Liveness::printPretty(FILE* f) +{ + for (Uint32 n = 0; n < size; n++) { + fprintf(f, "Node %d: \n\tliveIn=", n); + liveIn[n].printPrettyOnes(f); + fprintf(f, "\tliveOut="); + liveOut[n].printPrettyOnes(f); + } +} +#endif // DEBUG_LOG diff --git a/ef/Compiler/RegisterAllocator/Liveness.h b/ef/Compiler/RegisterAllocator/Liveness.h new file mode 100644 index 000000000000..894214ae5cc0 --- /dev/null +++ b/ef/Compiler/RegisterAllocator/Liveness.h @@ -0,0 +1,64 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#ifndef _LIVENESS_H_ +#define _LIVENESS_H_ + +#include "Fundamentals.h" +#include "ControlGraph.h" + +class Pool; +class FastBitSet; +class VirtualRegisterManager; + +class Liveness +{ +private: + Pool& pool; // Pool for local memory allocation. + FastBitSet* liveIn; // Array of LiveIn bitsets + FastBitSet* liveOut; // Array of LiveOut bitsets + Uint32 size; // Size of the arrays. + +private: + + void buildAcyclicLivenessAnalysis(const ControlGraph& controlGraph, const VirtualRegisterManager& vrManager); + void buildCyclicLivenessAnalysis(const ControlGraph& controlGraph, const VirtualRegisterManager& vrManager); + + void operator = (const Liveness&); // No copy operator. + Liveness(const Liveness&); // No copy constructor. + +public: + + Liveness(Pool& pool) : pool(pool) {} + + inline void buildLivenessAnalysis(const ControlGraph& controlGraph, const VirtualRegisterManager& vrManager); + FastBitSet& getLiveIn(Uint32 blockNumber) {PR_ASSERT(blockNumber < size); return liveIn[blockNumber];} + FastBitSet& getLiveOut(Uint32 blockNumber) {PR_ASSERT(blockNumber < size); return liveOut[blockNumber];} + + DEBUG_LOG_ONLY(void printPretty(FILE* f)); +}; + +inline void Liveness::buildLivenessAnalysis(const ControlGraph& controlGraph, const VirtualRegisterManager& vrManager) +{ + if (controlGraph.hasBackEdges) + buildCyclicLivenessAnalysis(controlGraph, vrManager); + else + buildAcyclicLivenessAnalysis(controlGraph, vrManager); +} + +#endif // _LIVENESS_H_ diff --git a/ef/Compiler/RegisterAllocator/Makefile b/ef/Compiler/RegisterAllocator/Makefile new file mode 100644 index 000000000000..5f8ccc85e7a8 --- /dev/null +++ b/ef/Compiler/RegisterAllocator/Makefile @@ -0,0 +1,64 @@ +#!gmake +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +####################################################################### +# (1) Directory specific info # +####################################################################### + +DEPTH = ../.. + + +CPPSRCS = VirtualRegister.cpp \ + RegisterAllocator.cpp \ + Coloring.cpp \ + Spilling.cpp \ + Timer.cpp \ + $(NULL) + +LOCAL_EXPORTS = Coloring.h \ + Liveness.h \ + RegisterAllocator.h \ + RegisterAssigner.h \ + SSATools.h \ + Spilling.h \ + Timer.h \ + VirtualRegister.h \ + $(NULL) + +MODULE_NAME = EF + +####################################################################### +# (2) Include "component" configuration information. # +####################################################################### + +include $(DEPTH)/config/config.mk + +####################################################################### +# (3) Include "local" platform-dependent assignments (OPTIONAL). # +####################################################################### + + + +####################################################################### +# (4) Execute "component" rules. (OPTIONAL) # +####################################################################### + +include $(DEPTH)/config/rules.mk + +####################################################################### +# (7) Execute "local" rules. (OPTIONAL). # +####################################################################### diff --git a/ef/Compiler/RegisterAllocator/NewRegisterAllocator.cpp b/ef/Compiler/RegisterAllocator/NewRegisterAllocator.cpp new file mode 100644 index 000000000000..9c347f0fa93c --- /dev/null +++ b/ef/Compiler/RegisterAllocator/NewRegisterAllocator.cpp @@ -0,0 +1,659 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#include "Fundamentals.h" + +#define INCLUDE_EMITTER +#include "CpuInfo.h" + +#include "RegisterAllocator.h" +#include "VirtualRegister.h" +#include "DoublyLinkedList.h" +#include "ControlNodes.h" +#include "Instruction.h" + +#include "Liveness.h" + +#if !defined(DEBUG_LOG) || !defined(DEBUG_laurentm) +#define NO_TIMER +#endif // !DEBUG_LOG || !DEBUG_laurentm +#include "Timer.h" + +// +// Annotate the phi nodes. We call an annotation a VirtualRegister assignment to a DataProducer. +// Phi nodes are special data nodes that will not generate an instruction. For this reason, +// it is possible that after code generation, some DataProducer were not annotated. +// The RegisterAllocator assumes that each DataProducer has been annotated. So we must annotate +// the DataProducer that were not. +// +void RegisterAllocator::annotatePhiNodes() +{ + for (Uint32 n = 0; n < nNodes; n++) { // For each nodes in this graph. + DoublyLinkedList& phiNodes = dfsList[n]->getPhiNodes(); + + for (DoublyLinkedList::iterator p = phiNodes.begin(); !phiNodes.done(p); p = phiNodes.advance(p)) { // For each phi nodes. + PhiNode& phiNode = phiNodes.get(p); + + VirtualRegisterKind constraint; + switch (phiNode.getKind()) { + case vkCond: + case vkMemory: + continue; // Condition and Memory phi nodes are not seen after code generation. + + case vkInt: + constraint = IntegerRegister; + break; + case vkLong: + constraint = IntegerRegister; // FIXME: But should annotate 2 registers. + break; + case vkFloat: + constraint = FloatingPointRegister; + break; + case vkDouble: + constraint = FloatingPointRegister; // FIXME: Is it always the case ?. + break; + case vkAddr: + constraint = IntegerRegister; + break; + default: + PR_ASSERT(!"Unhandled kind of phi node"); + } + // Check the outgoing edge annotation. We do not check the consumers because + // they must be or have been defined by either a primitive or another phi node. + if (phiNode.getVirtualRegisterAnnotation() == NULL) + phiNode.annotate(vrManager.newVirtualRegister(constraint)); + } + } +} + +// +// Get the liveness information and build the interference graph. The interference graph +// is represented by a bitmatrix. Each row of this bitmatrix represents a VirtualRegister, +// and each bits on this row an interference with another VirtualRegister. +// 2 registers will interfere if they are live at the same time. A register is alive between +// its definition and its last use. +// +void RegisterAllocator::buildInterferenceGraph() +{ + // To get the number of VirtualRegisters in the manager, we must be sure + // that no one will try to allocate new VirtualRegisters. + // We are locking the manager for the entire method. + DEBUG_ONLY(TIMER_SAFE(vrManager.lockAllocation())); + + Uint32 nVirtualRegisters = vrManager.getSize(); // Maximum of allocated VirtualRegister. + + // ControlNodes hold some fields for the register allocation (liveAtBegin, liveAtEnd, etc ...). + // We need to reset these fields and allocate the memory fro the bitsets. + for (Uint32 n = 0; n < nNodes; n++) { + ControlNode& node = *dfsList[n]; + + node.liveAtBegin.sizeToAndClear(pool, nVirtualRegisters); + node.liveAtEnd.sizeToAndClear(pool, nVirtualRegisters); + node.hasNewLiveAtEnd = true; + node.liveAtBeginIsValid = false; + } + + // Reset the interference matrix. This matrix must hold nVirtualRegisters rows and + // nVirtualRegisters column. + interferenceMatrix.sizeToAndClear(pool, nVirtualRegisters, nVirtualRegisters); + DEBUG_ONLY(interferenceMatrixSize = nVirtualRegisters); + + FastBitSet currentLive(pool, nVirtualRegisters); // Bitset for the registers currently alive. + + while(true) { + bool needsToLoop = false; + + for (Int32 n = (nNodes - 1); n >= 0; n--) { // For each nodes in this graph. + ControlNode& node = *dfsList[n]; + + // We skip the nodes that we already looked at and that do + // not have any new liveness information at the end. + if (node.liveAtBeginIsValid && !node.hasNewLiveAtEnd) + continue; + + // The register currently alive are the register alive at + // the end of this node. + currentLive = node.liveAtEnd; + // We are looking at this node so for now it doesn't have + // any new liveness information at the end. + node.hasNewLiveAtEnd = false; + + // We walk backward all the instructions defined in this node. + // A register becomes alive with its last use (first found), interfere with + // all the registers alive at its definition, and is killed by its definition. + InstructionList& instructions = node.getInstructions(); + for (InstructionList::iterator i = instructions.end(); !instructions.done(i); i = instructions.retreat(i)) { + Instruction& instruction = instructions.get(i); + InstructionUse* useBegin = instruction.getInstructionUseBegin(); + InstructionUse* useEnd = instruction.getInstructionUseEnd(); + InstructionUse* usePtr; + InstructionDefine* defBegin = instruction.getInstructionDefineBegin(); + InstructionDefine* defEnd = instruction.getInstructionDefineEnd(); + InstructionDefine* defPtr; + + InstructionFlags flags = instruction.getFlags(); + + // Move is handled specially to avoid adding an interference between the + // source and the destination. If an interference exists between these + // registers another instruction will set it. For now the source register + // and the destination register will contain the same value. + if (flags & ifCopy) { + PR_ASSERT(useBegin[0].isVirtualRegister()); + currentLive.clear(useBegin[0].getVirtualRegister().index); + } + + // Registers are defined. This definition has an interference with all the + // registers currently alive. + for (defPtr = defBegin; defPtr < defEnd; defPtr++) + if (defPtr->isVirtualRegister()) { + VirtualRegisterIndex index = defPtr->getVirtualRegister().index; + interferenceMatrix.orRows(index, currentLive, index); + } + + // The definition just killed these registers. + for (defPtr = defBegin; defPtr < defEnd; defPtr++) + if (defPtr->isVirtualRegister()) + currentLive.clear(defPtr->getVirtualRegister().index); + + // If this instruction is a Call instruction, we want all the caller-save + // registers to interfere with the current live registers. We do not want an + // interference with the callee-save registers because the call will save & + // restore these registers. + if (flags & ifCall) { + // FIXME + } + + if (flags & ifSpecialCall) { + // FIXME + } + + // Each use of a register makes it alive. + for (usePtr = useBegin; usePtr < useEnd; usePtr++) + if (usePtr->isVirtualRegister()) + currentLive.set(usePtr->getVirtualRegister().index); + } + + // If the liveness information is different than the previous one, we + // need to propagate the changes to each predecessor of this node. + // We also need to add the liveness information from the phi nodes. + if (currentLive != node.liveAtBegin) { + FastBitSet liveAtEnd(pool, nVirtualRegisters); // Bitset for the registers alive at the end of a predecessor of this node. + + DoublyLinkedList& phiNodes = node.getPhiNodes(); + const DoublyLinkedList& predecessors = node.getPredecessors(); + DoublyLinkedList::iterator i; + Uint32 predecessorIndex; + + for (predecessorIndex = 0, i = predecessors.begin(); !predecessors.done(i); predecessorIndex++, i = predecessors.advance(i)) { + ControlNode& predecessor = predecessors.get(i).getSource(); + bool predecessorHasNewLiveAtEnd = false; + + if (!phiNodes.empty()) { + liveAtEnd = currentLive; + + for (DoublyLinkedList::iterator p = phiNodes.end(); !phiNodes.done(p); p = phiNodes.retreat(p)) { + PhiNode& phiNode = phiNodes.get(p); + + if (isStorableKind(phiNode.getKind())) { + DataNode& producer = phiNode.nthInput(predecessorIndex).getVariable(); + VirtualRegisterIndex use = producer.getVirtualRegisterAnnotation()->index; + VirtualRegisterIndex define = phiNode.getVirtualRegisterAnnotation()->index; + + // If this phi node has been coalesced then the producer and the consumer for this + // edge hold the same VirtualRegister. In this case we don't update the liveness + // information. + if (define != use) { + // A phiNode, if not coalesced will generate a Copy instruction. So we do + // not want the use and the definition to interfere. + liveAtEnd.clear(use); + interferenceMatrix.orRows(define, liveAtEnd, define); + liveAtEnd.clear(define); + liveAtEnd.set(use); + } + } + } + predecessorHasNewLiveAtEnd |= predecessor.liveAtEnd.set(liveAtEnd); + } else { // phiNode.empty() == true + predecessorHasNewLiveAtEnd = predecessor.liveAtEnd.set(currentLive); + } + + predecessor.hasNewLiveAtEnd |= predecessorHasNewLiveAtEnd; + needsToLoop |= predecessorHasNewLiveAtEnd; + } + } + node.liveAtBegin = currentLive; + node.liveAtBeginIsValid = true; + } + + // If this graph is an acyclic graph we are sure that after the first pass all + // the interferences are found. We stop this loop in this case and also + // if no new live registers are found. + if (!needsToLoop || isAcyclic) + break; + } + + // Summarize the interference matrix. This matrix must be diagonale and some interferences + // are not valid (i.e. IntegerRegister with FloatingPointRegister, 2 precolored registers + // to different colors. + + FastBitMatrix trans(pool, nVirtualRegisters, nVirtualRegisters); + for (VirtualRegisterIndex r = vrManager.first(); !vrManager.done(r); r = vrManager.advance(r)) { + interferenceMatrix.clear(r, r); // A register do not interfere with itself; + + FastBitSet row(interferenceMatrix.getRowBits(r), nVirtualRegisters); + for (Int32 i = row.firstOne(); !row.done(i); i = row.nextOne(i)) + trans.set(i, r); + } + + for (VirtualRegisterIndex s = vrManager.first(); !vrManager.done(s); s = vrManager.advance(s)) { + interferenceMatrix.orRows(s, FastBitSet(trans.getRowBits(s), nVirtualRegisters), s); + } + + interferenceMatrix &= vrManager.getValidInterferencesMatrix(); + + // Get the interference degrees from the interference matrix. + if (interferenceDegreesSize < nVirtualRegisters) { + interferenceDegreesSize = nVirtualRegisters; + interferenceDegrees = new(pool) Uint32[interferenceDegreesSize]; + } + + for (Uint32 j = 0; j < nVirtualRegisters; j++) + interferenceDegrees[j] = FastBitSet(interferenceMatrix.getRowBits(j), nVirtualRegisters).countOnes(); + + // We are done with this method. We can now unlock the VirtualRegisterManager. + DEBUG_ONLY(TIMER_SAFE(vrManager.unlockAllocation())); +} + +// +// Return true if the VirtualRegisters source to dest were coalesced. +// +bool RegisterAllocator::coalesceRegistersIfPossible(VirtualRegister& sourceRegister, VirtualRegister& destRegister) +{ + VirtualRegisterIndex source = sourceRegister.index; + VirtualRegisterIndex dest = destRegister.index; + + if (source == dest) + return true; + +#ifdef DEBUG + if (sourceRegister.isPreColored()) + PR_ASSERT(destRegister.isPreColored()); +#endif // DEBUG + + if (destRegister.isPreColored() && sourceRegister.isPreColored()) + if (sourceRegister.getPreColor() != destRegister.getPreColor()) + return false; + else // 2 precolored registers cannot interfere. + PR_ASSERT(!interferenceMatrix.test(source, dest)); + else if (interferenceMatrix.test(source, dest)) + return false; + + Uint32 nVirtualRegisters = vrManager.getSize(); + FastBitSet sourceInterferences(interferenceMatrix.getRowBits(source), nVirtualRegisters); + + tempBitSet.sizeTo(pool, nVirtualRegisters); + tempBitSet = sourceInterferences; + tempBitSet -= FastBitSet(interferenceMatrix.getRowBits(dest), nVirtualRegisters); + + Uint32 nNewInterferences = tempBitSet.countOnes(); + if ((nNewInterferences + interferenceDegrees[dest]) >= virtualRegisterClasses[destRegister.kind]->getNumberOfColor()) + return false; + + // Coalesce the registers. + vrManager.coalesceVirtualRegisters(source, dest); + + // Update the interference matrix. + for (Int32 i = sourceInterferences.firstOne(); !sourceInterferences.done(i); i = sourceInterferences.nextOne(i)) { + interferenceMatrix.clear(i, source); + if (tempBitSet.test(i)) // This is a new interference for dest. + interferenceMatrix.set(i, dest); + else + interferenceDegrees[i]--; + } + + interferenceDegrees[dest] += nNewInterferences; + interferenceMatrix.orRows(source, dest, dest); + +#ifdef DEBUG +START_TIMER_SAFE + interferenceMatrix.clear(source); + interferenceDegrees[source] = 0; + + // Check the validity of the dest row. + PR_ASSERT(FastBitSet(interferenceMatrix.getRowBits(dest), nVirtualRegisters).countOnes() == interferenceDegrees[dest]); +END_TIMER_SAFE +#endif + + return true; +} + +// +// Check all Copy instructions & phiNodes for possible register coalescing. +// If two registers are coalesced there's no need to keep the instruction (or the phiNode). +// The ControlFlow graph is analysed from the most executed node to the least. +// +// TODO: loop nesting depth is not good enough (should analyse the program regions instead). +// +void RegisterAllocator::removeUneededCopyInstructions() +{ + for (Int32 n = nNodes - 1; n >= 0; n--) { + ControlNode& node = *lndList[n]; + + // + // Check the Copy in the instruction list. + // + InstructionList& instructions = node.getInstructions(); + InstructionList::iterator i = instructions.begin(); + + while (!instructions.done(i)) { // For each instruction in this node. + Instruction& instruction = instructions.get(i); + i = instructions.advance(i); + + if (instruction.getFlags() & ifCopy) { // This is a Copy Instruction + PR_ASSERT(instruction.getInstructionUseBegin()[0].isVirtualRegister()); + PR_ASSERT(instruction.getInstructionDefineBegin()[0].isVirtualRegister()); + + VirtualRegister& sourceRegister = instruction.getInstructionUseBegin()[0].getVirtualRegister(); + VirtualRegister& destRegister = instruction.getInstructionDefineBegin()[0].getVirtualRegister(); + + // If a VirtualRegister is precolored then this register must be the destination + // register if the coalescing is possible. + if (destRegister.isPreColored()) { + if (coalesceRegistersIfPossible(sourceRegister, destRegister)) + instruction.remove(); + } else { + if (coalesceRegistersIfPossible(destRegister, sourceRegister)) + instruction.remove(); + } + } + } + + // + // Check the phi nodes. + // + DoublyLinkedList& phiNodes = node.getPhiNodes(); + DoublyLinkedList::iterator p = phiNodes.end(); + + while (!phiNodes.done(p)) { // For each phi nodes. + PhiNode& phiNode = phiNodes.get(p); + p = phiNodes.retreat(p); + + if (isStorableKind(phiNode.getKind())) { + bool canRemoveThisPhiNode = true; // Can we remove the phi node from the graph ? + + DataConsumer* limit = phiNode.getInputsEnd(); + for (DataConsumer* consumer = phiNode.getInputsBegin(); consumer < limit; consumer++) { + VirtualRegister& sourceRegister = *phiNode.getVirtualRegisterAnnotation(); + VirtualRegister& destRegister = *consumer->getVariable().getVirtualRegisterAnnotation(); + + + // If a VirtualRegister is precolored then this register must be the destination + // register if the coalescing is possible. + if (destRegister.isPreColored()) { + if (!coalesceRegistersIfPossible(sourceRegister, destRegister)) + canRemoveThisPhiNode = false; + } else { + if (!coalesceRegistersIfPossible(destRegister, sourceRegister)) + canRemoveThisPhiNode = false; + } + } + + if (canRemoveThisPhiNode) + phiNode.remove(); + } + } + } +} + +// +// Replace the remaining phi nodes by their equivalent instruction (Copy, Load, Store). +// Return true if the register allocator needs one more pass. +// +bool RegisterAllocator::replacePhiNodesByCopyInstructions() +{ + bool addedANode = false; + bool needsRebuild = false; + + for (Uint32 n = 0; n < nNodes; n++) { // For all nodes. + ControlNode& node = *dfsList[n]; + + DoublyLinkedList& phiNodes = node.getPhiNodes(); + const DoublyLinkedList& predecessors = node.getPredecessors(); + bool hasOnlyOneInput = predecessors.lengthIs(1); + + // If this node has only one predecessor, it is possible to insert the copy instruction + // at the begining of this node. To respect the interference order, we have to append + // each phiNode in the same order they are in the linked list. + DoublyLinkedList::iterator i = hasOnlyOneInput ? phiNodes.begin() : phiNodes.end(); + while (!phiNodes.done(i)) { + PhiNode& phiNode = phiNodes.get(i); + i = hasOnlyOneInput ? phiNodes.advance(i) : phiNodes.retreat(i); + + if (isStorableKind(phiNode.getKind())) { + VirtualRegister& definedVR = *phiNode.getVirtualRegisterAnnotation(); + + DoublyLinkedList::iterator e = predecessors.begin(); + DataConsumer* limit = phiNode.getInputsEnd(); + for (DataConsumer* consumer = phiNode.getInputsBegin(); consumer < limit; consumer++) { // For each consumer + ControlEdge& edge = predecessors.get(e); + e = predecessors.advance(e); + + VirtualRegister& usedVR = *consumer->getVariable().getVirtualRegisterAnnotation(); + + if (definedVR.index != usedVR.index) { // We have to emit an instruction. + InstructionList::iterator place; + + if (hasOnlyOneInput) + place = node.getInstructions().begin()->prev; + else { + ControlNode& source = edge.getSource(); + if (source.nSuccessors() != 1) { // This predecessor has more than one outgoing edge. We need to add + // a new ControlBlock to insert the copy instruction. + ControlNode& cn = edge.getSource().controlGraph.newControlNode(); + cn.setControlBlock(); + ControlEdge& newEdge = cn.getNormalSuccessor(); + + newEdge.substituteTarget(edge); + cn.addPredecessor(edge); + + // append at the begin of this new node. + place = cn.getInstructions().begin(); + addedANode = true; + } else + place = edge.getSource().getInstructions().end(); + } + + needsRebuild |= emitter.emitCopyAfter(phiNode, place, usedVR, definedVR); + } + } + phiNode.remove(); + } + } + } + + if (addedANode) { + ControlGraph& cg = dfsList[0]->controlGraph; + cg.dfsSearch(); + + if (needsRebuild) { + nNodes = cg.nNodes; + dfsList = cg.dfsList; + cg.lndSearch(); + lndList = cg.lndList; + } + } + + return needsRebuild; +} + +// +// Calculate the spill cost for each VirtualRegister. +// +void RegisterAllocator::calculateSpillCosts() +{ + Uint32 nVirtualRegisters = vrManager.getSize(); + FastBitSet currentLive(pool, nVirtualRegisters); + + // Reset the spillCosts. + for (VirtualRegisterIndex r = vrManager.first(); !vrManager.done(r); r = vrManager.advance(r)) { + VirtualRegister& vReg = vrManager.getVirtualRegister(r); + vReg.spillCosts.copyCosts = 0.; + vReg.spillCosts.loadOrStoreCosts = 0.; + } + + for (Int32 n = (nNodes - 1); n >= 0; n--) { // For each node in this graph. + ControlNode& node = *dfsList[n]; + + currentLive = node.liveAtEnd; + + InstructionList& instructions = node.getInstructions(); + for (InstructionList::iterator i = instructions.end(); !instructions.done(i); i = instructions.retreat(i)) { + Instruction& instruction = instructions.get(i); + InstructionUse* useBegin = instruction.getInstructionUseBegin(); + InstructionUse* useEnd = instruction.getInstructionUseEnd(); + InstructionUse* usePtr; + InstructionDefine* defBegin = instruction.getInstructionDefineBegin(); + InstructionDefine* defEnd = instruction.getInstructionDefineEnd(); + InstructionDefine* defPtr; + + if (instruction.getFlags() & ifCopy) { + PR_ASSERT(useBegin[0].isVirtualRegister() && defBegin[0].isVirtualRegister()); + // If one of these registers are spilled, this instruction will be replaced by a load or a store. + useBegin[0].getVirtualRegister().spillCosts.copyCosts -= node.nVisited; + defBegin[0].getVirtualRegister().spillCosts.copyCosts -= node.nVisited; + } + + // Handle the definition a new VirtualRegister. + for (defPtr = defBegin; defPtr < defEnd; defPtr++) + if (defPtr->isVirtualRegister()) { + VirtualRegister& vReg = defPtr->getVirtualRegister(); + if (virtualRegisterClasses[vReg.kind]->canSpill()) { + } + } + + } + } +} + +void RegisterAllocator::allocateRegisters() +{ + // + // Timer names. + // + const char* ANNOTATE_PHINODES = "RegAlloc.annotatePhiNodes"; + const char* BUILD_INTERFERENCEGRAPH = "RegAlloc.buildInterferenceGraph"; + const char* ALLOCATE_REGISTERS = "RegAlloc.allocateRegisters"; + const char* COALESCE_REGISTERS = "RegAlloc.coalesceRegisters"; + const char* REPLACE_PHI_NODES = "RegAlloc.replacePhiNodesByCopyInstructions"; + + startTimer(ALLOCATE_REGISTERS); + + // Add the missing annotations to the phi nodes. + startTimer(ANNOTATE_PHINODES); + annotatePhiNodes(); + stopTimer(ANNOTATE_PHINODES); + + // Build the interference matrix. + startTimer(BUILD_INTERFERENCEGRAPH); + buildInterferenceGraph(); + stopTimer(BUILD_INTERFERENCEGRAPH); + +#if 0 + // Remove uneeded copy & phi nodes. + startTimer(COALESCE_REGISTERS); + removeUneededCopyInstructions(); + stopTimer(COALESCE_REGISTERS); + + // Just to be sure that the coalescing didn't corrupt the interference matrix. + DEBUG_ONLY(TIMER_SAFE(checkCoalescingValidity())); + + // Get the cost for register spilling. + calculateSpillCosts(); +#endif + +#if 0 + bool successfulColoring = colorRegisters(); + + if (!successfulColoring) + insertSpillCode(); + + // Emit the instructions for the remaining phi nodes in the graph. + startTimer(REPLACE_PHI_NODES); + replacePhiNodesByCopyInstructions(); + stopTimer(REPLACE_PHI_NODES); +#endif + + stopTimer(ALLOCATE_REGISTERS); + + + interferenceMatrix.printPretty(stdout); + +#if 1 + for (VirtualRegisterIndex i = vrManager.first(); !vrManager.done(i); i = vrManager.advance(i)) { + fprintf(stdout, "degree of vr%d = %d\n", i, interferenceDegrees[i]); + vrManager.getVirtualRegister(i).setColor(0); + } + + for (Uint32 m = 0; m < nNodes; m++) { + ControlNode& node = *dfsList[m]; + node.printRef(stdout); + fprintf(stdout, "\n"); + + InstructionList& instructions = node.getInstructions(); + for(InstructionList::iterator i = instructions.begin(); !instructions.done(i); i = instructions.advance(i)) { + instructions.get(i).printDebug(stdout); + fprintf(stdout, "\n"); + } + } +#endif + + ControlGraph& cg = dfsList[0]->controlGraph; + Liveness liveness(pool); + liveness.buildLivenessAnalysis(cg, vrManager); + + exit(-1); +} + +#ifdef DEBUG +// +// +// +void RegisterAllocator::checkCoalescingValidity() +{ + FastBitMatrix backup(pool, interferenceMatrixSize, interferenceMatrixSize); + backup = interferenceMatrix; + + buildInterferenceGraph(); + if (backup != interferenceMatrix) { +#ifdef DEBUG_LOG + fprintf(stdout, "\n" + "!!! RegisterAllocator Warning: Interference matrix is invalid after coalescing.\n" + "!!! The RegisterAllocator will reconstruct a valid interferenceMatrix.\n" + "!!!\n" + "!!! Please mail your java source file to laurentm@netscape.com with\n" + "!!! the subject \"RegAlloc Bug\". Thanks, Laurent.\n" + "\n"); +#ifdef DEBUG_laurentm + interferenceMatrix.printDiff(stdout, backup); +#endif // DEBUG_laurentm +#else // DEBUG_LOG + PR_ASSERT(!"Invalid interferenceMatrix after coalescing"); +#endif // DEBUG_LOG + } +} +#endif // DEBUG diff --git a/ef/Compiler/RegisterAllocator/NewRegisterAllocator.h b/ef/Compiler/RegisterAllocator/NewRegisterAllocator.h new file mode 100644 index 000000000000..188bae9f2d6c --- /dev/null +++ b/ef/Compiler/RegisterAllocator/NewRegisterAllocator.h @@ -0,0 +1,94 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#ifndef _REGISTER_ALLOCATOR_H_ +#define _REGISTER_ALLOCATOR_H_ + + +#include "Fundamentals.h" + +#define INCLUDE_EMITTER +#include "CpuInfo.h" + +#include "FastBitMatrix.h" +#include "ControlGraph.h" + +class Pool; +class VirtualRegisterManager; + +// ---------------------------------------------------------------------------- +// RegisterAllocator + +class RegisterAllocator +{ +private: + Pool& pool; // RegisterAllocator's pool. + ControlNode** dfsList; // List of nodes in a Depth First Search order. + ControlNode** lndList; // List of nodes in a Loop Nesting Depth order. + Uint32 nNodes; // Number of nodes in this graph. + bool isAcyclic; // True if the graph is acyclic. + VirtualRegisterManager& vrManager; // VirtualRegister's manager. + MdEmitter& emitter; // The machine dependant instruction emitter. + + FastBitMatrix interferenceMatrix; // The interference matrix. Each row is assign to a VirtualRegister. +#ifdef DEBUG + Uint32 interferenceMatrixSize; // The number of rows and cols in the interference matrix. +#endif // DEBUG + Uint32* interferenceDegrees; // The interference degree of all the VirtualRegisters in the graph. + Uint32 interferenceDegreesSize; // The size of interferenceDegrees. + + FastBitSet tempBitSet; // Temporary bitset (one time allocation). + + + // Annotate the phi nodes. + void annotatePhiNodes(); + // Get the liveness information and build the interference graph. + void buildInterferenceGraph(); + // Coalesce the VirtualRegisters source to dest if it is possible. + bool coalesceRegistersIfPossible(VirtualRegister& sourceRegister, VirtualRegister& destRegister); + // Remove uneeded compy instructions (when the source and destination don not interfere); + void removeUneededCopyInstructions(); + // Replace the remaining phi nodes by their equivalent instruction (Copy, Load, Store). + bool replacePhiNodesByCopyInstructions(); + // Get the spilling cost for each VirtualRegister. + void calculateSpillCosts(); + +#ifdef DEBUG + // Check if the coalescing didn't corrupt the interferenceMatrix. + void checkCoalescingValidity(); +#endif // DEBUG + +public: + inline RegisterAllocator(Pool& pool, ControlGraph& graph, VirtualRegisterManager& vrManager, MdEmitter& emitter); + + void allocateRegisters(); +}; + +// ---------------------------------------------------------------------------- +// Inlines + +inline RegisterAllocator::RegisterAllocator(Pool& pool, ControlGraph& graph, VirtualRegisterManager& vrManager, MdEmitter& emitter) : + pool(pool), vrManager(vrManager), emitter(emitter), interferenceDegreesSize(0) +{ + dfsList = graph.dfsList; + lndList = graph.lndList; + nNodes = graph.nNodes; + isAcyclic = !graph.hasBackEdges; +} + +#endif // _REGISTER_ALLOCATOR_H_ diff --git a/ef/Compiler/RegisterAllocator/NewVirtualRegister.cpp b/ef/Compiler/RegisterAllocator/NewVirtualRegister.cpp new file mode 100644 index 000000000000..a08eeb237d34 --- /dev/null +++ b/ef/Compiler/RegisterAllocator/NewVirtualRegister.cpp @@ -0,0 +1,240 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#include "Fundamentals.h" +#include "VirtualRegister.h" +#include "FastBitMatrix.h" +#include "FastBitSet.h" + +// ---------------------------------------------------------------------------- +// VirtualRegister + +#ifdef DEBUG_LOG +// +// Print this VirtualRegister. +// +void VirtualRegister::printPretty(FILE* f) const +{ + virtualRegisterClasses[kind]->printPretty(f); + fprintf(f, "%d: ", index); + + if (isPreColored()) + fprintf(f, "preColor = %d ", getPreColor()); + if (isColored()) + fprintf(f, "color = %d ", getColor()); + else + fprintf(f, "not yet colored "); + + fprintf(f, "\n"); +} +#endif // DEBUG_LOG + +// ---------------------------------------------------------------------------- +// VirtualRegisterManager + +static BlocksHeader nullVirtualRegisterHandlesHeader = {0, 0, {NULL}}; +static BlocksHeader nullVirtualRegistersHeader = {0, 0, {NULL}}; + +// +// Create a new VirtualRegisterManager. +// +VirtualRegisterManager::VirtualRegisterManager(Pool& pool) : + pool(pool), machineRegisters(pool, NUMBER_OF_REGISTERS, NUMBER_OF_REGISTERS) +{ + handlesHeader = nullVirtualRegisterHandlesHeader.allocateAnotherBlock(pool); + registersHeader = nullVirtualRegistersHeader.allocateAnotherBlock(pool); + + indexes = new(pool) FastBitSet(pool, registersHeader->numberOfElementsInABlock); + firstFree = 0; + biggestUsed = -1; + + DEBUG_ONLY(lock = false); +} + +inline void *operator new(size_t, VirtualRegister* ptr) {return ptr;} + +// +// Allocate a new VirtualRegister of kind 'kind'. +// +VirtualRegister& VirtualRegisterManager::newVirtualRegister(VirtualRegisterKind kind) +{ + // If we are lock, no new VirtualRegister can be created. + PR_ASSERT(!lock); + + // Get a new VirtualRegister. + Int32 registerIndex = firstFree; + indexes->set(registerIndex); + firstFree = indexes->nextZero(firstFree); + + if (firstFree == -1 || registersHeader->getBlockNumber(registerIndex) >= registersHeader->nBlocks) { + registersHeader = registersHeader->allocateAnotherBlock(pool); + FastBitSet& newIndexes = *new(pool) FastBitSet(pool, registersHeader->nBlocks * registersHeader->numberOfElementsInABlock); + newIndexes = *indexes; + indexes = &newIndexes; + firstFree = indexes->nextZero(registerIndex); + } + if (Uint32(registerIndex) == registersHeader->next) + registersHeader->next++; + + if (registerIndex > biggestUsed) + biggestUsed = registerIndex; + + // Get a new handle. + Uint32 handleIndex = handlesHeader->next++; + if (handlesHeader->getBlockNumber(handleIndex) >= handlesHeader->nBlocks) + handlesHeader = handlesHeader->allocateAnotherBlock(pool); + + VirtualRegisterHandle* handle = handlesHeader->getElementPtr(handleIndex); + + VirtualRegister& vReg = *new(registersHeader->getElementPtr(registerIndex)) VirtualRegister(handle, registerIndex, kind); + + handle->ptr = &vReg; + handle->next = handle; + + return vReg; +} + +// +// Coalesce the VirtualRegister at index from with the VirtualRegister at index to. +// +void VirtualRegisterManager::coalesceVirtualRegisters(VirtualRegisterIndex from, VirtualRegisterIndex to) +{ + // When we coalesce the VirtualRegister 'from' to the VirtualRegister 'to' we must + // update all from's handle to point to. 'from' has an unique handle index, but this + // handle is chain to all the handle also pointing it. + + VirtualRegister* toVR = &getVirtualRegister(to); + + VirtualRegisterHandle* beginOfToChain = toVR->getHandle(); + VirtualRegisterHandle* endOfToChain = beginOfToChain; + + // Get the end of to's handle chain. + while (endOfToChain->next != beginOfToChain) + endOfToChain = endOfToChain->next; + + VirtualRegister* fromVR = &getVirtualRegister(from); + VirtualRegisterHandle* beginOfFromChain = fromVR->getHandle(); + VirtualRegisterHandle* endOfFromChain = beginOfFromChain; + + // For each from's handle update the pointer. + while (true) { + endOfFromChain->ptr = toVR; + + if (endOfFromChain->next == beginOfFromChain) + break; + + endOfFromChain = endOfFromChain->next; + } + + // Merge the chains. + endOfToChain->next = beginOfFromChain; + endOfFromChain->next = beginOfToChain; + + // Free the from register. + indexes->clear(from); + if (from < firstFree) + firstFree = from; + + if (from == biggestUsed) + biggestUsed = indexes->previousOne(from); + + if (fromVR->isPreColored()) + machineRegisters.clear(fromVR->getPreColor(), fromVR->index); +} + +// +// PreColor the VirtualRegister at index with color. +// +void VirtualRegisterManager::preColorVirtualRegister(VirtualRegisterIndex index, VirtualRegisterColor color) +{ + machineRegisters.set(color, index); + getVirtualRegister(index).setPreColor(color); +} + +// +// Return a Matrix of valid interferences. +// +FastBitMatrix& VirtualRegisterManager::getValidInterferencesMatrix() const +{ + const Uint32 matrixSize = getSize(); + FastBitMatrix& matrix = *new(pool) FastBitMatrix(pool, matrixSize, matrixSize); + FastBitSet* classesIndex = new FastBitSet[nVirtualRegisterKind](pool, matrixSize); + + for (VirtualRegisterIndex i = first(); !done(i); i = advance(i)) + classesIndex[getVirtualRegister(i).kind].set(i); + + for (VirtualRegisterIndex j = first(); !done(j); j = advance(j)) + matrix.copyRows(classesIndex[getVirtualRegister(j).kind], j); + + return matrix; +} + +#ifdef DEBUG_LOG +// +// Print all the VirtualRegisters in this manager. +// +void VirtualRegisterManager::printPretty(FILE* f) const +{ + fprintf(f, "----- VirtualRegisters -----\n"); + for (VirtualRegisterIndex i = first(); !done(i); i = advance(i)) + getVirtualRegister(i).printPretty(f); + + fprintf(f, "----- MachineRegisters -----\n"); + for (Uint32 j = 0; j < NUMBER_OF_REGISTERS; j++) { + FastBitSet preColoredRegisters(machineRegisters.getRowBits(j), NUMBER_OF_REGISTERS); + if (!preColoredRegisters.empty()) { + fprintf(f, "preColored to %d: ", j); + preColoredRegisters.printPrettyOnes(f); + } + } + + fprintf(f, "----------------------------\n"); +} +#endif // DEBUG_LOG + +// ---------------------------------------------------------------------------- +// VirtualRegisterClass + +static IntegerRegisterClass integerRegister; +static FloatingPointRegisterClass floatingPointRegister; +static MemoryRegisterClass memoryRegister; + +const VirtualRegisterClass* virtualRegisterClasses[nVirtualRegisterKind] = +{ + NULL, // InvalidRegisterKind + &integerRegister, + &floatingPointRegister, + NULL, // FixedPointRegister + &memoryRegister, + NULL, // StackSlotRegister + NULL, // MemoryArgumentRegister +}; + +// +// Return the kind of register for the given color. +// +VirtualRegisterKind VirtualRegisterClass::getKind(VirtualRegisterColor color) +{ + for (Uint32 i = 0; i < nVirtualRegisterKind; i++) + if (virtualRegisterClasses[i] != NULL) { + const VirtualRegisterClass& vrClass = *virtualRegisterClasses[i]; + if (color >= vrClass.getMinColor() && color <= vrClass.getMaxColor()) + return vrClass.kind; + } + return InvalidRegisterKind; +} diff --git a/ef/Compiler/RegisterAllocator/NewVirtualRegister.h b/ef/Compiler/RegisterAllocator/NewVirtualRegister.h new file mode 100644 index 000000000000..094ca580b298 --- /dev/null +++ b/ef/Compiler/RegisterAllocator/NewVirtualRegister.h @@ -0,0 +1,352 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#ifndef _VIRTUAL_REGISTER_H_ +#define _VIRTUAL_REGISTER_H_ + +#include "Fundamentals.h" +#include "FastBitMatrix.h" +#include "FastBitSet.h" + +class Instruction; +class Pool; + +enum VirtualRegisterKind +{ + InvalidRegisterKind, + IntegerRegister, + FloatingPointRegister, + FixedPointRegister, + MemoryRegister, + StackSlotRegister, + MemoryArgumentRegister, +}; +const nVirtualRegisterKind = MemoryArgumentRegister + 1; + +// ---------------------------------------------------------------------------- +// VirtualRegister + +// A VirtualRegisterIndex is an index to the VirtualRegisterManager table +// of handles. It is an invalid index if its value is 'invalidRegisterIndex'. +typedef Int32 VirtualRegisterIndex; +typedef Uint8 VirtualRegisterColor; + +const VirtualRegisterIndex invalidRegisterIndex = -1; // An invalid register index. +const VirtualRegisterColor invalidRegisterColor = 255; // An invalid register color. + +struct VirtualRegisterHandle; + +const Flt32 copyCost = 1.; +const Flt32 loadCost = 2.; +const Flt32 storeCost = 2.; + +class VirtualRegister +{ +public: + + VirtualRegisterIndex index; // This VirtualRegister's index. + const VirtualRegisterKind kind; // This VirtualRegister kind (i.e. IntegerRegister, FloatingPointRegister ...). + + struct SpillCost + { + Flt32 copyCosts; + Flt32 loadOrStoreCosts; + } spillCosts; + +private: + + Instruction* definingInstruction; // The instruction defining this register. + VirtualRegisterHandle* handle; // This VirtualRegister's handle. + + struct + { + VirtualRegisterColor color; // Register's color + VirtualRegisterColor preColor; // PreColor or 255 if it is not precolored. + } colorInfo; + +private: + + VirtualRegister(const VirtualRegister&); // No copy constructor. + void operator = (const VirtualRegister&); // No copy operator. + +public: + + // Create a new VirtualRegister + inline VirtualRegister(VirtualRegisterHandle* handle, VirtualRegisterIndex index, VirtualRegisterKind kind); + + // Set the defining instruction (for code generation). + void setDefiningInstruction(Instruction& instruction) {definingInstruction = &instruction;} + // Get the defining instruction (for code generation). + Instruction* getDefiningInstruction() {return definingInstruction;} + + // + // Helpers. + // + + // Get this VirtualRegister's handle. + VirtualRegisterHandle* getHandle() {return handle;} + + // Set the Register's color. + void setColor(VirtualRegisterColor color) {colorInfo.color = color;} + // Set the preColor (by setting the preColor this register becomes a preColored register). + void setPreColor(VirtualRegisterColor color) {colorInfo.preColor = color;} + // Return true is this register has been succesfully colored. + bool isColored() const {return colorInfo.color != invalidRegisterColor;} + // Return true is this register is preColored. (If this register is not colored then return invalidRegisterColor). + bool isPreColored() const {return colorInfo.preColor != invalidRegisterColor;} + // Return this register's color. + VirtualRegisterColor getColor() const {return colorInfo.color;} + // Return this register's preColor. (If this register is not preColored then return invalidRegisterColor). + VirtualRegisterColor getPreColor() const {return colorInfo.preColor;} + +#ifdef DEBUG_LOG + // Print the register in the file f. + void printPretty(FILE* f) const; +#endif // DEBUG_LOG +}; + +struct VirtualRegisterHandle +{ + VirtualRegister* ptr; + VirtualRegisterHandle* next; +}; + +// ---------------------------------------------------------------------------- +// VirtualRegisterManager + +template +struct BlocksHeader +{ + const Uint32 numberOfElementsInABlock = 128; // Number of elements in a block. + + Uint32 nBlocks; // Number of available blocks. + Uint32 next; // Next available element. + Class* blocks[1]; // Array of block pointers. + + // Allocate another block and return the new this. + BlocksHeader* allocateAnotherBlock(Pool& pool); + // Get the block number for this element index. + static Uint32 getBlockNumber(Uint32 index) {return index >> 7;} + // Get the element's pointer at index. + Class* getElementPtr(Uint32 index); +}; + +#include "CpuInfo.h" + +class VirtualRegisterManager +{ +private: + + Pool& pool; // This VirtualRegisterManager's allocation pool. + BlocksHeader* handlesHeader; // VirtualRegisterHandles blocks' header. + BlocksHeader* registersHeader; // VirtualRegisters blocks' header. + FastBitMatrix machineRegisters; // Matrix of machine registers. +#ifdef DEBUG + bool lock; // If lock is true then no new register can be created. +#endif // DEBUG + + FastBitSet* indexes; // Register indexes currently used. + + Int32 firstFree; // First free register index. + Int32 biggestUsed; // Biggest used register index. + + VirtualRegisterManager(const VirtualRegisterManager&); // No copy constructor. + void operator = (const VirtualRegisterManager&); // No copy operator. + +public: + // Create a new VirtualRegisterManager. + VirtualRegisterManager(Pool& pool); + + // Return the maximum number of VirtualRegisters currently in use. + Uint32 getSize() const {return biggestUsed + 1;} +#ifdef DEBUG + // Lock the manager. When it is locked no one can create new VirtualRegisters. + void lockAllocation() {PR_ASSERT(!lock); lock = true;} + // Unlock the manager. + void unlockAllocation() {PR_ASSERT(lock); lock = false;} +#endif // DEBUG + + // Return the reference to the VirtualRegister at index. + inline VirtualRegister& getVirtualRegister(VirtualRegisterIndex index) const; + + // Allocate a new VirtualRegister of kind 'kind'. + VirtualRegister& newVirtualRegister(VirtualRegisterKind kind); + // Coalesce the VirtualRegister at index from with the VirtualRegister at index to. + void coalesceVirtualRegisters(VirtualRegisterIndex from, VirtualRegisterIndex to); + // PreColor the VirtualRegister at index with color. + void preColorVirtualRegister(VirtualRegisterIndex index, VirtualRegisterColor color); + + // Return the first valid VirtualRegisterIndex. + VirtualRegisterIndex first() const {return advance(-1);} + // Return the next valid VirtualRegister after index. + inline VirtualRegisterIndex advance(VirtualRegisterIndex index) const {return indexes->nextOne(index);} + // Return true is this index is outside the array of handles. + bool done(VirtualRegisterIndex index) const {return (index < 0 || index > biggestUsed);} + + // Return the matrix of valid interferences (i.e. a IntegerRegister interferes only with others IntegerRegisters). + FastBitMatrix& getValidInterferencesMatrix() const; + +#ifdef DEBUG_LOG + // Print all the VirtualRegisters in this manager. + void printPretty(FILE* f) const; +#endif // DEBUG_LOG +}; + +// ---------------------------------------------------------------------------- +// VirtualRegisterClass(es) + +class VirtualRegisterClass +{ +private: + + VirtualRegisterClass(const VirtualRegisterClass&); // No copy constructor. + void operator = (const VirtualRegisterClass&); // No copy operator. + +public: + + VirtualRegisterKind kind; // This class kind. + + VirtualRegisterClass(VirtualRegisterKind kind) : kind(kind) {} + + // Return the VirtualRegisterKind this class can spill to. + virtual VirtualRegisterKind willSpillTo() const {return InvalidRegisterKind;} + // Return the smallest color index this register class can take. + virtual Uint8 getMinColor() const = 0; + // Return the bigest color index this register class can take. + virtual Uint8 getMaxColor() const = 0; + // Return the number of color available for this class. + Uint8 getNumberOfColor() const {return getMaxColor() - getMinColor() + 1;} + // Return true if this class canSpill; + bool canSpill() const {return willSpillTo() != InvalidRegisterKind;} + + // Return the kind of register for the given color. + static VirtualRegisterKind getKind(VirtualRegisterColor color); +#ifdef DEBUG_LOG + // Print the class string for the VirtualRegisterClass. + virtual void printPretty(FILE* f) const = 0; +#endif // DEBUG_LOG +}; + +// virtualRegisterClasses is an array of VirtualRegisterClass instances. +// Each instance is a different class of registers (i.e. Integer, FP, memory). +extern const VirtualRegisterClass* virtualRegisterClasses[]; + +// +// An IntegerRegister's possible colors are [FIRST_GREGISTER ... LAST_GREGISTER]. +// It can spill in a MemoryRegister. +// +class IntegerRegisterClass : public VirtualRegisterClass +{ +public: + IntegerRegisterClass() : VirtualRegisterClass(IntegerRegister) {} + + virtual VirtualRegisterKind willSpillTo() const {return MemoryRegister;} + virtual Uint8 getMinColor() const {return FIRST_GREGISTER;} + virtual Uint8 getMaxColor() const {return LAST_GREGISTER;} + +#ifdef DEBUG_LOG + virtual void printPretty(FILE* f) const {fprintf(f, "integer register ");} +#endif // DEBUG_LOG +}; + +// +// A FloatingRegister's possible colors are [FIRST_FPREGISTER ... LAST_FPREGISTER]. +// It can spill in a MemoryRegister. +// +class FloatingPointRegisterClass : public VirtualRegisterClass +{ +public: + FloatingPointRegisterClass() : VirtualRegisterClass(FloatingPointRegister) {} + + virtual VirtualRegisterKind willSpillTo() const {return MemoryRegister;} + virtual Uint8 getMinColor() const {return FIRST_FPREGISTER;} + virtual Uint8 getMaxColor() const {return LAST_FPREGISTER;} + +#ifdef DEBUG_LOG + virtual void printPretty(FILE* f) const {fprintf(f, "floating point register ");} +#endif // DEBUG_LOG +}; + +// +// A MemoryRegister has an infinite color space. It cannot spill ! +// +class MemoryRegisterClass : public VirtualRegisterClass +{ +public: + MemoryRegisterClass() : VirtualRegisterClass(MemoryRegister) {} + + virtual Uint8 getMinColor() const {return 0;} + virtual Uint8 getMaxColor() const {return ~0;} // Infinite space for a memory register. + +#ifdef DEBUG_LOG + virtual void printPretty(FILE* f) const {fprintf(f, "memory register ");} +#endif // DEBUG_LOG +}; + +// ---------------------------------------------------------------------------- +// Inlines + +inline VirtualRegister& VirtualRegisterManager::getVirtualRegister(VirtualRegisterIndex index) const +{ + PR_ASSERT(indexes->test(index)); + return *registersHeader->getElementPtr(index); +} + +inline VirtualRegister::VirtualRegister(VirtualRegisterHandle* handle, VirtualRegisterIndex index, VirtualRegisterKind kind) : + index(index), kind(kind), definingInstruction(NULL), handle(handle) +{ + setColor(invalidRegisterColor); + setPreColor(invalidRegisterColor); +} + +// +// Allocate another block and return the new this. +// +template +BlocksHeader* BlocksHeader::allocateAnotherBlock(Pool& pool) +{ + // Get the number of 32bits words needed for this block. A block is composed by: + // [BlockHeader] (nBlocks-1)*[pointers to block] numberOfElementsInABlock*[element Class]. + Uint32 blockSize = ((sizeof(BlocksHeader) + nBlocks * sizeof(Uint32) + + (numberOfElementsInABlock * sizeof(Class))) + 3 & -4) >> 2; + Uint32* ptr = new(pool) Uint32[blockSize]; + fill(ptr, &ptr[blockSize], 0); + + BlocksHeader* newThis = static_cast*>(ptr); + *newThis = *this; + + if (nBlocks > 0) + copy(&blocks[1], &blocks[nBlocks], &newThis->blocks[1]); + + newThis->blocks[nBlocks] = static_cast(&newThis->blocks[nBlocks + 1]); + newThis->nBlocks++; + + return newThis; +} + +// +// Get the element's pointer at index. +// +template +Class* BlocksHeader::getElementPtr(Uint32 index) +{ + PR_ASSERT((getBlockNumber(index) < nBlocks) && (index < next)); + return &(blocks[getBlockNumber(index)])[index & (numberOfElementsInABlock - 1)]; +} + +#endif // _VIRTUAL_REGISTER_H_ diff --git a/ef/Compiler/RegisterAllocator/RegisterAllocator.cpp b/ef/Compiler/RegisterAllocator/RegisterAllocator.cpp new file mode 100644 index 000000000000..8f78dfec9516 --- /dev/null +++ b/ef/Compiler/RegisterAllocator/RegisterAllocator.cpp @@ -0,0 +1,1294 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#define INCLUDE_EMITTER +#include "CpuInfo.h" + +#include "Fundamentals.h" +#include "RegisterAllocator.h" +#include "RegisterAssigner.h" +#include "Spilling.h" +#include "InstructionEmitter.h" + +#include "ControlGraph.h" +#include "Primitives.h" + +#include "VirtualRegister.h" +#include "FastBitMatrix.h" +#include "FastBitSet.h" + +#include "CpuInfo.h" +#include "Attributes.h" + +UT_DEFINE_LOG_MODULE(RegisterAllocator); + +#ifdef DEBUG_LOG +void printGraph(Uint32 nNodes, ControlNode** dfsList) +{ + for (Uint32 m = 0; m < nNodes; m++) { + ControlNode& node = *dfsList[m]; + node.printRef(UT_LOG_MODULE(RegisterAllocator)); + UT_LOG(RegisterAllocator, PR_LOG_ALWAYS, ("\n")); + + DoublyLinkedList& phiNodes = node.getPhiNodes(); + for (DoublyLinkedList::iterator p = phiNodes.begin(); !phiNodes.done(p); p = phiNodes.advance(p)) { + PhiNode& phiNode = phiNodes.get(p); + ValueKind kind = phiNode.getKind(); + if (isStorableKind(kind)) + if (isDoublewordKind(kind)) { + UT_LOG(RegisterAllocator, PR_LOG_ALWAYS, ("PhiNode: (%d,%d) <- ", phiNode.getLowVirtualRegisterAnnotation()->getRegisterIndex(), + phiNode.getHighVirtualRegisterAnnotation()->getRegisterIndex())); + for (DataConsumer *consumer = phiNode.getInputsBegin(); consumer < phiNode.getInputsEnd(); consumer++) + UT_LOG(RegisterAllocator, PR_LOG_ALWAYS, ("%d ", consumer->getVariable().getVirtualRegisterAnnotation()->getRegisterIndex())); + } else { + UT_LOG(RegisterAllocator, PR_LOG_ALWAYS, ("PhiNode: %d <- ", phiNode.getVirtualRegisterAnnotation()->getRegisterIndex())); + for (DataConsumer *consumer = phiNode.getInputsBegin(); consumer < phiNode.getInputsEnd(); consumer++) + UT_LOG(RegisterAllocator, PR_LOG_ALWAYS, ("%d ", consumer->getVariable().getVirtualRegisterAnnotation()->getRegisterIndex())); + } + UT_LOG(RegisterAllocator, PR_LOG_ALWAYS, ("\n")); + } + InstructionList& instructions = node.getInstructions(); +#ifdef DEBUG_LOG + for(InstructionList::iterator i = instructions.begin(); !instructions.done(i); i = instructions.advance(i)) { + instructions.get(i).printDebug(UT_LOG_MODULE(RegisterAllocator)); + UT_LOG(RegisterAllocator, PR_LOG_ALWAYS, ("\n")); + } +#endif + } +} +#endif + + +/* + *-------------------------RegisterAllocator.cpp------------------------- + * + * RegisterAllocator::allocateRegisters -- + * + * Register allocation main loop. + * + * 1- calculate the interference graph. + * 2- coalesce the registers (remove uneeded copy instructions). + * 3- assign a color to each VirtualRegister. + * 4- spill some VirtualRegisters if (3) failed. + * 5- goto (1) if (3) failed. + * + *----------------------------------------------------------------------- + */ +void RegisterAllocator:: +allocateRegisters() +{ + PRUint32 nVirtualRegisters = vRegManager.count(); + + if (nVirtualRegisters == 0) + { + // DEBUG_ONLY(UT_LOG(RegisterAllocator, PR_LOG_ALWAYS, ("**** No register allocation needed ****\n");)) + return; + } + + // DEBUG_ONLY(PRUint32 loopCounter = 0); + // DEBUG_ONLY(UT_LOG(RegisterAllocator, PR_LOG_ALWAYS, ("**** Allocate Registers ****\n");)) + + + // Check if all phiNodes have an allocated VirtualRegister for each outgoing edge. + checkPhiNodesAnnotation(); + + // Resolve any VirtualRegister class conflicts. + checkRegisterClassConflicts(); + + do + { + while(true) + { + // DEBUG_ONLY(UT_LOG(RegisterAllocator, PR_LOG_ALWAYS, ("-- loop %d --\n", ++loopCounter))); + + // We are compacting the VirtualRegister array to minimize the number of bits in the BitSets. + vRegManager.compactMemory(); + + // Build the interference matrix. + buildInterferenceGraph(); + + // remove as many copy instructions as possible. + coalesce(); + + // If we compile a DEBUG target, we want to be sure that the register coalescing + // didn't forget any register interference. + DEBUG_ONLY(FastBitMatrix backupMatrix = interferenceMatrix); + buildInterferenceGraph(); +#ifdef DEBUG + if (backupMatrix != interferenceMatrix) + { +#ifdef DEBUG_LOG + + UT_LOG(RegisterAllocator, PR_LOG_ALWAYS, ("!!!! interference matrix is <> after a 2nd register interference analysis !!!!\n")); +// backupMatrix.printDiff(stdout, interferenceMatrix); +#endif + } +#endif + // Reset the registers. + for (VirtualRegisterManager::iterator i = vRegManager.begin(); !vRegManager.done(i); i = vRegManager.advance(i)) + { + VirtualRegister& vReg = vRegManager.getVirtualRegister(i); + vReg.resetColoringInfo(); + + FastBitSet inter(interferenceMatrix.getRow(i), nVirtualRegisters); + vReg.colorInfo.interferenceDegree = inter.countOnes(); + } + + // Calculate each register's spill cost. + calculateSpillCosts(); + + if (!registerAssigner.assignRegisters(interferenceMatrix)) + { + spilling.insertSpillCode(dfsList, nNodes); + spillPhiNodes(); + } + else + break; + } + } + while (removePhiNodes()); + + // Update the info in the LocalVariableEntry mappings + updateLocalVariableTable(); + + // DEBUG_ONLY(printRegisterDebug(stdout, true)); +} + + +/* + *-------------------------RegisterAllocator.cpp------------------------- + * + * RegisterAllocator::checkPhiNodesAnnotation -- + * + * Check if the phi nodes have valid register annotations. + * + *----------------------------------------------------------------------- + */ +void RegisterAllocator:: +checkPhiNodesAnnotation() +{ + for (PRUint32 n = 0; n < nNodes; n++) + { + ControlNode& node = *dfsList[n]; + DoublyLinkedList& phiNodes = node.getPhiNodes(); + + for (DoublyLinkedList::iterator i = phiNodes.begin(); !phiNodes.done(i); i = phiNodes.advance(i)) + { + PhiNode& phiNode = phiNodes.get(i); + ValueKind kind = phiNode.getKind(); + if (isStorableKind(kind)) + { + DataNode& producer = phiNode; + + if (isDoublewordKind(kind)) { + // Check the outgoing edge. + if (producer.getLowVirtualRegisterAnnotation() == NULL) + producer.annotateLow(vRegManager.newVirtualRegister(), vrcInteger /* FIXME */); + if (producer.getHighVirtualRegisterAnnotation() == NULL) + producer.annotateHigh(vRegManager.newVirtualRegister(), vrcInteger /* FIXME */); + + // Check the incoming edges. + DataConsumer* limit = phiNode.getInputsEnd(); + for (DataConsumer *consumer = phiNode.getInputsBegin(); consumer < limit; consumer++) + { + DataNode& p = consumer->getVariable(); + if (p.getLowVirtualRegisterAnnotation() == NULL) + p.annotateLow(vRegManager.newVirtualRegister(), vrcInteger /* FIXME */); + if (p.getHighVirtualRegisterAnnotation() == NULL) + p.annotateHigh(vRegManager.newVirtualRegister(), vrcInteger /* FIXME */); + } + } else { + // Check the outgoing edge. + if (producer.getVirtualRegisterAnnotation() == NULL) + producer.annotate(vRegManager.newVirtualRegister(), vrcInteger /* FIXME */); + + // Check the incoming edges. + DataConsumer* limit = phiNode.getInputsEnd(); + for (DataConsumer *consumer = phiNode.getInputsBegin(); consumer < limit; consumer++) + { + DataNode& p = consumer->getVariable(); + if (p.getVirtualRegisterAnnotation() == NULL) + p.annotate(vRegManager.newVirtualRegister(), vrcInteger /* FIXME */); + } + } + } + } + } +} + + +/* + *-------------------------RegisterAllocator.cpp------------------------- + * + * RegisterAllocator::checkRegisterClassConflicts -- + * + * Check that each instruction will get the correct kind of register. + * + *----------------------------------------------------------------------- + */ +void RegisterAllocator:: +checkRegisterClassConflicts() +{ +#if GENERATE_FOR_HPPA + // FIXME + + // Reset all equivalents registers for the VirtualRegisters. + for (VirtualRegisterManager::iterator i = vRegManager.begin(); !vRegManager.done(i); i = vRegManager.advance(i)) + fill_n(vRegManager.getVirtualRegister(i).equivalentRegister, nVRClass, (VirtualRegister *) 0); + + for (PRUint32 n = 0; n < nNodes; n++) + { + ControlNode& node = *dfsList[n]; + + InstructionList& instructions = node.getInstructions(); + for (InstructionList::iterator i = instructions.end(); !instructions.done(i); i = instructions.retreat(i)) + { + Instruction& instruction = instructions.get(i); + InstructionUse* useBegin = instruction.getInstructionUseBegin(); + InstructionUse* useEnd = instruction.getInstructionUseEnd(); + InstructionUse* usePtr; + + for (usePtr = useBegin; usePtr < useEnd; usePtr++) + if (usePtr->isVirtualRegister()) + { + VirtualRegister& vReg = usePtr->getVirtualRegister(); + VirtualRegisterPtr& vRegPtr = usePtr->getVirtualRegisterPtr(); + VRClass wanted = vRegPtr.getClassConstraint(); + VRClass current = vReg.getClass(); + if (wanted != current) + { + if (vReg.equivalentRegister[wanted] == NULL) + { + Instruction& definingInstruction = *vReg.getDefiningInstruction(); + vReg.equivalentRegister[wanted] = &vRegManager.newVirtualRegister(wanted); + instructionEmitter.emitCopyAfter(*definingInstruction.getPrimitive(), &definingInstruction.getLinks(), + vReg, *vReg.equivalentRegister[wanted]); + } + vRegPtr.initialize(*vReg.equivalentRegister[wanted], wanted); + } + } + } + } +#endif +} + + +/* + *-------------------------RegisterAllocator.cpp------------------------- + * + * RegisterAllocator::buildInterferenceGraph -- + * + * Build the interferenceMatrix. Each bit in the interferenceMatrix + * corresponds to a register interference. + * + *----------------------------------------------------------------------- + */ +void RegisterAllocator:: +buildInterferenceGraph() +{ + PRUint32 nVirtualRegisters = vRegManager.count(); + + // Reset the Bitsets in each ControlNode. + for (PRUint32 n = 0; n < nNodes; n++) + { + dfsList[n]->liveAtBegin.sizeToAndClear(nVirtualRegisters); + dfsList[n]->liveAtEnd.sizeToAndClear(nVirtualRegisters); + dfsList[n]->hasNewLiveAtEnd = true; + dfsList[n]->liveAtBeginIsValid = false; + } + + // Reset the liveness info. + for (VirtualRegisterManager::iterator i = vRegManager.begin(); !vRegManager.done(i); i = vRegManager.advance(i)) { + VirtualRegister& vReg = vRegManager.getVirtualRegister(i); + vReg.liveness.sizeToAndClear(nNodes); + if (vReg.hasSpecialInterference) { + vReg.specialInterference.clear();; + } + } + + // Reset the interference matrix. + interferenceMatrix.sizeToAndClear(nVirtualRegisters, nVirtualRegisters); + + // Bitset of the VirtualRegisters currently alive. + FastBitSet currentLive(nVirtualRegisters); + // Bitset of the VirtualRegisters alive at the end of a node. + FastBitSet liveAtEnd(nVirtualRegisters); + + for (bool loop = true; loop;) + { + loop = false; + + for (PRInt32 n = (nNodes - 1); n >= 0; n--) + { + ControlNode& node = *dfsList[n]; + bool hasPhiNodes = !node.getPhiNodes().empty(); + + // If liveAtEnd didn't change there's no new interferences to find. Just skip this node. + if ((!node.hasNewLiveAtEnd) && node.liveAtBeginIsValid) + continue; + + node.hasNewLiveAtEnd = false; + currentLive = node.liveAtEnd; + + // All the virtual registers in currentLive are alive in this node. + for (PRInt32 k = currentLive.firstOne(); k != -1; k = currentLive.nextOne(k)) + vRegManager.getVirtualRegister(k).liveness.set(n); + + + // We walk backward all the instructions defined in this node. + // A register becomes alive with its last use (first found), interfere with + // all the registers alive at its definition, and is killed by its definition. + InstructionList& instructions = node.getInstructions(); + for (InstructionList::iterator i = instructions.end(); !instructions.done(i); + i = instructions.retreat(i)) + { + Instruction& instruction = instructions.get(i); + InstructionUse* useBegin = instruction.getInstructionUseBegin(); + InstructionUse* useEnd = instruction.getInstructionUseEnd(); + InstructionUse* usePtr; + InstructionDefine* defBegin = instruction.getInstructionDefineBegin(); + InstructionDefine* defEnd = instruction.getInstructionDefineEnd(); + InstructionDefine* defPtr; + + InstructionFlags flags = instruction.getFlags(); + if (flags & ifCopy) + { + // Move is handled specially to avoid adding an interference between the + // source and the destination. If an interference exists between these + // registers another instruction will set it. For now the source register + // and the destination register will contain the same value. + PR_ASSERT(useBegin[0].isVirtualRegister()); + currentLive.clear(useBegin[0].getRegisterIndex()); + } + + // Registers are defined. This definition has an interference with all the + // registers currently alive. + for (defPtr = defBegin; defPtr < defEnd; defPtr++) + if (defPtr->isVirtualRegister()) + { + VirtualRegister& defReg = defPtr->getVirtualRegister(); + PRUint32 defRegIndex = defReg.getRegisterIndex(); + + interferenceMatrix.orRow(defRegIndex, currentLive); + + // We use the definition of this register to update the precoloring information. + // In a program we can have different VirtualRegisters precolored to the same color. + // During the register coalescing we need to know if a non-precolored register can + // be coalesced with a precolored to C. It is possible to do so only if the non + // precolored register has no interference with any other register also precolored to C. + // For this reason the VirtualRegisterManager will create a PseudoVirtualRegister corresponding + // to one machine register. As the Pseudo VirtualRegister is never seen by the interference graph + // algorithm we can use the row corresponding to its index to store the index of all VirtualRegisters + // precolored to the color C. + if (defReg.isPreColored()) + interferenceMatrix.set(defReg.colorInfo.preColoredRegisterIndex, defRegIndex); + } + + // The definition just killed these registers. + for (defPtr = defBegin; defPtr < defEnd; defPtr++) + if (defPtr->isVirtualRegister()) + currentLive.clear(defPtr->getRegisterIndex()); + + // If this instruction is a Call instruction, we want all the caller-save + // registers to interfere with the current live registers. We do not want an + // interference with the callee-save registers because the call will save & + // restore these registers. + if (flags & ifCall) + { + for (PRInt32 r = currentLive.firstOne(); r != -1; r = currentLive.nextOne(r)) + { + VirtualRegister& vReg = vRegManager.getVirtualRegister(r); + + if (!vReg.hasSpecialInterference) + { + vReg.specialInterference.sizeToAndClear(NUMBER_OF_REGISTERS); + vReg.hasSpecialInterference = true; + } + vReg.specialInterference.set(FIRST_CALLER_SAVED_GR, LAST_CALLER_SAVED_GR); +#if NUMBER_OF_FPREGISTERS != 0 + vReg.specialInterference.set(FIRST_CALLER_SAVED_FPR, LAST_CALLER_SAVED_FPR); +#endif + } + } + +#if FIXME + if (flags & ifSpecialCall) + { + } +#endif + + // Each use of a register makes it alive. + for (usePtr = useBegin; usePtr < useEnd; usePtr++) + if (usePtr->isVirtualRegister()) + { + VirtualRegister& vReg = usePtr->getVirtualRegister(); + currentLive.set(vReg.getRegisterIndex()); + vReg.liveness.set(n); + } + } + + if (currentLive != node.liveAtBegin) + { + const DoublyLinkedList& predecessors = node.getPredecessors(); + PRUint32 edgeIndex = 0; + + for (DoublyLinkedList::iterator i = predecessors.begin(); !predecessors.done(i); i = predecessors.advance(i), edgeIndex++) + { + ControlNode& predecessor = predecessors.get(i).getSource(); + + if (hasPhiNodes) + { + // Add liveness information for the phi nodes. + liveAtEnd = currentLive; + + DoublyLinkedList& phiNodes = node.getPhiNodes(); + for (DoublyLinkedList::iterator p = phiNodes.end(); !phiNodes.done(p); p = phiNodes.retreat(p)) { + PhiNode& phiNode = phiNodes.get(p); + ValueKind kind = phiNode.getKind(); + + if (isStorableKind(kind)) { + PRUint32 in = phiNode.nthInput(edgeIndex).getVariable().getVirtualRegisterAnnotation()->getRegisterIndex(); + PRUint32 out = phiNode.getVirtualRegisterAnnotation()->getRegisterIndex(); + + if (in != out) { + // Handled like a Copy Instruction. + liveAtEnd.clear(in); + interferenceMatrix.orRow(out, liveAtEnd); + liveAtEnd.clear(out); + liveAtEnd.set(in); + + VirtualRegister& outVR = *phiNode.getVirtualRegisterAnnotation(); + if (outVR.isPreColored()) + interferenceMatrix.set(outVR.colorInfo.preColoredRegisterIndex, out); + } + if (isDoublewordKind(kind)) { + in = phiNode.nthInput(edgeIndex).getVariable().getHighVirtualRegisterAnnotation()->getRegisterIndex(); + out = phiNode.getHighVirtualRegisterAnnotation()->getRegisterIndex(); + + if (in != out) { + // Handled like a Copy Instruction. + liveAtEnd.clear(in); + interferenceMatrix.orRow(out, liveAtEnd); + liveAtEnd.clear(out); + liveAtEnd.set(in); + + VirtualRegister& outVR = *phiNode.getHighVirtualRegisterAnnotation(); + if (outVR.isPreColored()) + interferenceMatrix.set(outVR.colorInfo.preColoredRegisterIndex, out); + } + } + } + } + bool changed = predecessor.liveAtEnd.setAndTest(liveAtEnd); + predecessor.hasNewLiveAtEnd |= changed; + loop |= changed; + } else { /* !hasPhiNodes */ + bool changed = predecessor.liveAtEnd.setAndTest(currentLive); + predecessor.hasNewLiveAtEnd |= changed; + loop |= changed; + } + } + } + node.liveAtBegin = currentLive; + node.liveAtBeginIsValid = true; + } + } + + FastBitSet gReg(regAllocPool, nVirtualRegisters); + FastBitSet fpReg(regAllocPool, nVirtualRegisters); + FastBitSet ssReg(regAllocPool, nVirtualRegisters); + VirtualRegisterManager::iterator r; + + for (r = vRegManager.begin(); !vRegManager.done(r); r = vRegManager.advance(r)) + { + VirtualRegister& vReg = vRegManager.getVirtualRegister(r); + switch (vReg.getClass()) + { + case vrcInteger: + gReg.set(r); + break; + case vrcFloatingPoint: + case vrcFixedPoint: + fpReg.set(r); + break; + case vrcStackSlot: + ssReg.set(r); + break; + default: + PR_ASSERT(false); + } + } + for (r = vRegManager.begin(); !vRegManager.done(r); r = vRegManager.advance(r)) + { + VirtualRegister& vReg = vRegManager.getVirtualRegister(r); + switch (vReg.getClass()) + { + case vrcInteger: + interferenceMatrix.andRow(r, gReg); + break; + case vrcFloatingPoint: + case vrcFixedPoint: + interferenceMatrix.andRow(r, fpReg); + break; + case vrcStackSlot: + interferenceMatrix.andRow(r, ssReg); + break; + default: + PR_ASSERT(false); + } + } + + FastBitMatrix trans(regAllocPool, nVirtualRegisters, nVirtualRegisters); + for (r = vRegManager.begin(); !vRegManager.done(r); r = vRegManager.advance(r)) + { + interferenceMatrix.clear(r, r); + FastBitSet row(interferenceMatrix.getRow(r), nVirtualRegisters); + for (PRInt32 i = row.firstOne(); i != -1; i = row.nextOne(i)) + trans.set(i, r); + } + for (r = vRegManager.begin(); !vRegManager.done(r); r = vRegManager.advance(r)) + { + FastBitSet row(trans.getRow(r), nVirtualRegisters); + interferenceMatrix.orRow(r, row); + } + +} + + +/* + *-------------------------RegisterAllocator.cpp------------------------- + * + * RegisterAllocator::canCoalesceRegisters -- + * + * Return true if it is possible to coalesce inVr & outVr. If it is + * from & to will contain the register indexes to coalesce. + * + *----------------------------------------------------------------------- + */ +bool RegisterAllocator:: +canCoalesceRegisters(VirtualRegister& inVR, VirtualRegister& outVR, PRUint32& from, PRUint32& to) +{ + // We dont have to check the register class because if a Copy instruction + // is emitted then in & out have the same register class. + + from = inVR.getRegisterIndex(); + to = outVR.getRegisterIndex(); + bool inIsPreColored = inVR.isPreColored(); + bool outIsPreColored = outVR.isPreColored(); + + if (inIsPreColored && outIsPreColored) + { + // The only case where we can remove this copy is if this two registers + // have the same color. + if ((inVR.getPreColor() == outVR.getPreColor()) && !interferenceMatrix.test(from, to)) + { + if (from != to) + interferenceMatrix.clear(inVR.colorInfo.preColoredRegisterIndex, from); + return true; + } + } + else if (inIsPreColored) // && (!outIsPreColored) + { + // outVR is not precolored but cannot have an interference with any registers preColored to inPreColor. + if (outVR.hasSpecialInterference) + if (outVR.specialInterference.test(inVR.getPreColor())) + return false; + + if (!interferenceMatrix.test(to, interferenceMatrix.getRow(inVR.colorInfo.preColoredRegisterIndex))) + { + // We must swap in & out, because inVR must stay preColored. + PRUint32 tmp = to; to = from; from = tmp; + return true; + } + } + else if (outIsPreColored) // && (!inIsPreColored) + { + if (inVR.hasSpecialInterference) + if (inVR.specialInterference.test(outVR.getPreColor())) + return false; + + // inVR is not precolored but cannot have an interference with any registers preColored to outPreColor. + if (!interferenceMatrix.test(from, interferenceMatrix.getRow(outVR.colorInfo.preColoredRegisterIndex))) + return true; + } + else // (!inIsPreColored && !outIsPreColored) + { + if ((from == to) || !interferenceMatrix.test(from, to)) + return true; + } + return false; +} + + +/* + *-------------------------RegisterAllocator.cpp------------------------- + * + * RegisterAllocator::coalesceRegisters -- + * + * Coalesce registers at indexes in & out. Update the interference + * matrix. + * + *----------------------------------------------------------------------- + */ +inline void RegisterAllocator:: +coalesceRegisters(PRUint32 from, PRUint32 to) +{ + PRUint32 nVirtualRegisters = vRegManager.count(); + FastBitSet row(interferenceMatrix.getRow(from), nVirtualRegisters); + for (PRInt32 r = row.firstOne(); r != -1; r = row.nextOne(r)) + { + interferenceMatrix.clear(r, from); + interferenceMatrix.set(r, to); + } + interferenceMatrix.orRow(to, row); + DEBUG_ONLY(interferenceMatrix.clearRow(from)); + + // update the liveness info. + VirtualRegister& fromVR = vRegManager.getVirtualRegister(from); + VirtualRegister& toVR = vRegManager.getVirtualRegister(to); + + FastBitSet& liveness = fromVR.liveness; + for (PRInt32 i = liveness.firstOne(); i != -1; i = liveness.nextOne(i)) + { + dfsList[i]->liveAtEnd.clear(from); + dfsList[i]->liveAtEnd.set(to); + } + toVR.liveness |= liveness; + + if (fromVR.hasSpecialInterference) { + if (toVR.hasSpecialInterference) + toVR.specialInterference |= fromVR.specialInterference; + else { + toVR.specialInterference.sizeTo(NUMBER_OF_REGISTERS); + toVR.specialInterference = fromVR.specialInterference; + } + toVR.hasSpecialInterference = true; + } + + vRegManager.moveVirtualRegister(from, to); +} + + +/* + *-------------------------RegisterAllocator.cpp------------------------- + * + * RegisterAllocator::coalesce -- + * + * Check all Copy instructions & phiNodes for possible register + * coalescing. If two registers are coalesced there's no need to + * keep the instruction (or the phiNode). The ControlFlow graph + * is analysed from the most executed node to the least. + * + * TODO: loop nesting depth is not good enough (should analyse + * the program regions instead). + * + *----------------------------------------------------------------------- + */ +void +RegisterAllocator::coalesce() +{ + for (PRInt32 n = nNodes - 1; n >= 0; n--) + { + ControlNode& node = *lndList[n]; + + InstructionList& instructions = node.getInstructions(); + InstructionList::iterator i = instructions.begin(); + + // Check the instructions in this node. + while(!instructions.done(i)) + { + Instruction& insn = instructions.get(i); + // We might remove this instruction. It is necessary to advance the iterator + // before the remove. + i = instructions.advance(i); + + if (insn.getFlags() & ifCopy) + { + PR_ASSERT(insn.getInstructionUseBegin()[0].isVirtualRegister() && insn.getInstructionDefineBegin()[0].isVirtualRegister()); + + VirtualRegister& inVR = insn.getInstructionUseBegin()[0].getVirtualRegister(); + VirtualRegister& outVR = insn.getInstructionDefineBegin()[0].getVirtualRegister(); + PRUint32 from, to; + + if (canCoalesceRegisters(inVR, outVR, from, to)) + { + if (from != to) + coalesceRegisters(from, to); + + // Before removing the instruction, we unitialize the VirtualRegisterPtrs in its annotations. + insn.unlinkRegisters(); + insn.remove(); + } + } + } + + // Check the phiNodes in this node. + DoublyLinkedList& phiNodes = node.getPhiNodes(); + for (DoublyLinkedList::iterator p = phiNodes.end(); !phiNodes.done(p);) + { + PhiNode& phiNode = phiNodes.get(p); + ValueKind kind = phiNode.getKind(); + p = phiNodes.retreat(p); + + if (isStorableKind(kind)) + { + bool removePhiNode = true; + DataConsumer* limit = phiNode.getInputsEnd(); + + for (DataConsumer *consumer = phiNode.getInputsBegin(); consumer < limit; consumer++) + { + VirtualRegister* inVR = consumer->getVariable().getVirtualRegisterAnnotation(); + VirtualRegister* outVR = phiNode.getVirtualRegisterAnnotation(); + PRUint32 from, to; + + if (inVR->getClass() == outVR->getClass()) { + if (inVR != outVR) { + if (canCoalesceRegisters(*inVR, *outVR, from, to)) + coalesceRegisters(from, to); + else + removePhiNode = false; + } + } else + removePhiNode = false; + + if (isDoublewordKind(kind)) { + inVR = consumer->getVariable().getHighVirtualRegisterAnnotation(); + outVR = phiNode.getHighVirtualRegisterAnnotation(); + + if (inVR->getClass() == outVR->getClass()) { + if (inVR != outVR) { + if (canCoalesceRegisters(*inVR, *outVR, from, to)) + coalesceRegisters(from, to); + else + removePhiNode = false; + } + } else + removePhiNode = false; + } + } + if (removePhiNode) + phiNode.remove(); + } + } + } +} + + +/* + *-------------------------RegisterAllocator.cpp------------------------- + * + * RegisterAllocator::spillPhiNodes -- + * + * Replace the phiNodes spilled VirtualRegisters by their StackSlot + * equivalent. + * + *----------------------------------------------------------------------- + */ +void RegisterAllocator:: +spillPhiNodes() +{ + for (PRUint32 n = 0; n < nNodes; n++) + { + ControlNode& node = *dfsList[n]; + DoublyLinkedList& phiNodes = node.getPhiNodes(); + + for (DoublyLinkedList::iterator i = phiNodes.begin(); !phiNodes.done(i); i = phiNodes.advance(i)) + { + PhiNode& phiNode = phiNodes.get(i); + ValueKind kind = phiNode.getKind(); + if (isStorableKind(kind)) + { + DataNode& producer = phiNode; + + if (isDoublewordKind(kind)) { + VirtualRegister& lowOutVR = *producer.getLowVirtualRegisterAnnotation(); + VirtualRegister& highOutVR = *producer.getHighVirtualRegisterAnnotation(); + + // Check the outgoing edge. + if (lowOutVR.spillInfo.willSpill) + producer.getLowVirtualRegisterPtrAnnotation().initialize(*lowOutVR.equivalentRegister[vrcStackSlot]); + if (highOutVR.spillInfo.willSpill) + producer.getHighVirtualRegisterPtrAnnotation().initialize(*highOutVR.equivalentRegister[vrcStackSlot]); + + // Check the incoming edges. + DataConsumer* limit = phiNode.getInputsEnd(); + for (DataConsumer *consumer = phiNode.getInputsBegin(); consumer < limit; consumer++) + { + VirtualRegister& lowInVR = *consumer->getVariable().getLowVirtualRegisterAnnotation(); + VirtualRegister& highInVR = *consumer->getVariable().getHighVirtualRegisterAnnotation(); + if (lowInVR.spillInfo.willSpill) + consumer->getVariable().getLowVirtualRegisterPtrAnnotation().initialize(*lowInVR.equivalentRegister[vrcStackSlot]); + if (highInVR.spillInfo.willSpill) + consumer->getVariable().getHighVirtualRegisterPtrAnnotation().initialize(*highInVR.equivalentRegister[vrcStackSlot]); + } + } else { + VirtualRegister& outVR = *producer.getVirtualRegisterAnnotation(); + + // Check the outgoing edge. + if (outVR.spillInfo.willSpill) + producer.getVirtualRegisterPtrAnnotation().initialize(*outVR.equivalentRegister[vrcStackSlot]); + + // Check the incoming edges. + DataConsumer* limit = phiNode.getInputsEnd(); + for (DataConsumer *consumer = phiNode.getInputsBegin(); consumer < limit; consumer++) + { + VirtualRegister& inVR = *consumer->getVariable().getVirtualRegisterAnnotation(); + if (inVR.spillInfo.willSpill) + consumer->getVariable().getVirtualRegisterPtrAnnotation().initialize(*inVR.equivalentRegister[vrcStackSlot]); + } + } + } + } + } +} + + +/* + *-------------------------RegisterAllocator.cpp------------------------- + * + * RegisterAllocator::removePhiNodes -- + * + * Replace the phiNodes by copy instructions. + * + *----------------------------------------------------------------------- + */ +bool RegisterAllocator:: +removePhiNodes() +{ + bool addedNode = false; + bool needsRebuild = false; + + for (PRUint32 n = 0; n < nNodes; n++) + { + ControlNode& node = *dfsList[n]; + DoublyLinkedList& phiNodes = node.getPhiNodes(); + + if (phiNodes.empty()) + continue; + + const DoublyLinkedList& predecessors = node.getPredecessors(); + bool hasOneInput = predecessors.lengthIs(1); + + DoublyLinkedList::iterator i; + // If this node has only one predecessor, it is possible to insert the copy instruction + // at the begininig of this node. To respect the interference order, we have to append + // each phiNode in the same order they are in the linked list. + for (i = hasOneInput ? phiNodes.end() : phiNodes.begin(); !phiNodes.done(i);) + { + PhiNode& phiNode = phiNodes.get(i); + ValueKind kind = phiNode.getKind(); + i = hasOneInput ? phiNodes.retreat(i) : phiNodes.advance(i); + + if (isStorableKind(kind)) + { + VirtualRegister* lowOutVR = phiNode.getVirtualRegisterAnnotation(); + VirtualRegister* highOutVR = isDoublewordKind(kind) ? phiNode.getHighVirtualRegisterAnnotation() : (VirtualRegister *) 0; + DoublyLinkedList::iterator e = predecessors.begin(); + + DataConsumer* limit = phiNode.getInputsEnd(); + for (DataConsumer *consumer = phiNode.getInputsBegin(); consumer < limit; consumer++) + { + // For each consumer. + ControlEdge& edge = predecessors.get(e); + e = predecessors.advance(e); + + for (int w = 1; w <= 2; w++) { + if (w == 2 && highOutVR == NULL) + break; + + VirtualRegister* inVR = (w == 1) ? consumer->getVariable().getLowVirtualRegisterAnnotation() : + consumer->getVariable().getHighVirtualRegisterAnnotation(); + VirtualRegister* outVR = (w == 1) ? lowOutVR : highOutVR; + + if (inVR != outVR) + { + // We have to emit a Copy from inVR to outVR. + + InstructionList::iterator place; // where to append the copyInstruction. + + if (hasOneInput) + { + // append at the begining of this node. + place = node.getInstructions().begin()->prev; + } + else + { + ControlNode& source = edge.getSource(); + if (source.nSuccessors() != 1) + { + // This predecessor has more than one outgoing edge. We need to add + // a new control Block to insert the copy instruction. + ControlNode& cn = edge.getSource().controlGraph.newControlNode(); + cn.setControlBlock(); + ControlEdge& newEdge = cn.getNormalSuccessor(); + + newEdge.substituteTarget(edge); + cn.addPredecessor(edge); + + // append at the begin of this new node. + place = cn.getInstructions().begin(); + addedNode = true; + } + else + { + // append at the end of the corresponding predecessor node. + place = edge.getSource().getInstructions().end(); + } + } + + VRClass inClass = inVR->getClass(); + VRClass outClass = outVR->getClass(); + + if ((inClass == vrcStackSlot) && ((outClass == vrcStackSlot))) + { + // Both register are spilled. We have to load the value in memory and then + // store it at its destination. To do this we need to create a new temporary + // VirtualRegister. It might create some new interferences, so we have to + // do one more register allocation loop. + VirtualRegister& vReg = vRegManager.newVirtualRegister(); + instructionEmitter.emitStoreAfter(phiNode, place, vReg, *outVR); + instructionEmitter.emitLoadAfter(phiNode, place, vReg, *inVR); + needsRebuild = true; + } + else if (inClass == vrcStackSlot) + // outVR needs to be loaded. + instructionEmitter.emitLoadAfter(phiNode, place, *outVR, *inVR); + else if (outClass == vrcStackSlot) + // inVR needs to be stored. + instructionEmitter.emitStoreAfter(phiNode, place, *inVR, *outVR); + else + // None of them are spilled, it's a regular copy + // (!!! inVR & outVR might not have the same register class) + needsRebuild |= instructionEmitter.emitCopyAfter(phiNode, place, *inVR, *outVR); + } + } + } + phiNode.remove(); + } + } + } + + if (addedNode) + { + ControlGraph& cg = dfsList[0]->controlGraph; + cg.dfsSearch(); + + if (needsRebuild) { + nNodes = cg.nNodes; + dfsList = cg.dfsList; + cg.lndSearch(); + lndList = cg.lndList; + } + } + + return needsRebuild; +} + + +/* + *-------------------------RegisterAllocator.cpp------------------------- + * + * RegisterAllocator::calculateSpillCost -- + * + * In order to do a graph coloring, we need to get the spill cost of + * each VirtualRegister used in this program. + * + *----------------------------------------------------------------------- + */ +void +RegisterAllocator::calculateSpillCosts() +{ + PRUint32 nVirtualRegisters = vRegManager.count(); + FastBitSet needLoad(nVirtualRegisters); + FastBitSet currentLive(nVirtualRegisters); + FastBitSet mustSpill(nVirtualRegisters); + + for (PRInt32 n = nNodes - 1; n >=0; n--) + { + ControlNode& node = *dfsList[n]; + + needLoad.clear(); + currentLive = node.liveAtEnd; + mustSpill = currentLive; + + // Get the copy information about the phiNodes in this node. + DoublyLinkedList& phiNodes = node.getPhiNodes(); + for (DoublyLinkedList::iterator i = phiNodes.begin(); !phiNodes.done(i); i = phiNodes.advance(i)) + { + PhiNode& phiNode = phiNodes.get(i); + ValueKind kind = phiNode.getKind(); + + if (isStorableKind(kind)) + { + // FIXME: This should be more accurate by taking into account the register class of each register. + // vrcStackSlot -> vrcInteger, vrcFloatingPoint, vrcFixedPoint is a load. + // vrcInteger, vrcFloatingPoint, vrcFixedPoint -> vrcStackSlot is a store. + // vrcInteger -> vrcFloatingPoint, vrcFixedPoint (is md) + + VirtualRegister* outVR = phiNode.getVirtualRegisterAnnotation(); + if (outVR->getClass() != vrcStackSlot) + { + DataConsumer* limit = phiNode.getInputsEnd(); + for (DataConsumer *consumer = phiNode.getInputsBegin(); consumer < limit; consumer++) + { + VirtualRegister* inVR = consumer->getVariable().getVirtualRegisterAnnotation(); + if (inVR != outVR) + if (inVR->getClass() != vrcStackSlot) + inVR->spillInfo.nCopies += node.nVisited; + } + } + if (isDoublewordKind(kind)) { + outVR = phiNode.getHighVirtualRegisterAnnotation(); + if (outVR->getClass() != vrcStackSlot) + { + DataConsumer* limit = phiNode.getInputsEnd(); + for (DataConsumer *consumer = phiNode.getInputsBegin(); consumer < limit; consumer++) + { + VirtualRegister* inVR = consumer->getVariable().getHighVirtualRegisterAnnotation(); + if (inVR != outVR) + if (inVR->getClass() != vrcStackSlot) + inVR->spillInfo.nCopies += node.nVisited; + } + } + } + } + } + + // The instructions in this node. + InstructionList& instructions = node.getInstructions(); + for (InstructionList::iterator j = instructions.end(); !instructions.done(j); j = instructions.retreat(j)) + { + Instruction& instruction = instructions.get(j); + + InstructionUse* useBegin = instruction.getInstructionUseBegin(); + InstructionUse* useEnd = instruction.getInstructionUseEnd(); + InstructionUse* usePtr; + InstructionDefine* defBegin = instruction.getInstructionDefineBegin(); + InstructionDefine* defEnd = instruction.getInstructionDefineEnd(); + InstructionDefine* defPtr; + + // Check copy insn + if (instruction.getFlags() & ifCopy) + { + PR_ASSERT(useBegin[0].isVirtualRegister()); + useBegin[0].getVirtualRegister().spillInfo.nCopies += node.nVisited; + } + + // Handle definitions + for (defPtr = defBegin; defPtr < defEnd; defPtr++) + if (defPtr->isVirtualRegister()) + { + VirtualRegister& vReg = defPtr->getVirtualRegister(); + if (vReg.getClass() != vrcStackSlot) + { + PRUint32 registerIndex = vReg.getRegisterIndex(); + if (needLoad.test(registerIndex)) + { + needLoad.clear(registerIndex); + if (!mustSpill.test(registerIndex)) + vReg.spillInfo.infiniteSpillCost = true; + } + vReg.spillInfo.nStores += node.nVisited; + currentLive.clear(registerIndex); + } + } + + // Check for deaths + for (usePtr = useBegin; usePtr < useEnd; usePtr++) + if (usePtr->isVirtualRegister()) + { + VirtualRegister& vReg = usePtr->getVirtualRegister(); + if (vReg.getClass() != vrcStackSlot) + { + if (!currentLive.test(vReg.getRegisterIndex())) + { + for (PRInt32 nl = needLoad.firstOne(); nl != -1; nl = needLoad.nextOne(nl)) + { + vRegManager.getVirtualRegister(nl).spillInfo.nLoads += node.nVisited; + mustSpill.set(nl); + } + needLoad.clear(); + } + } + } + + // Handle uses + for (usePtr = useBegin; usePtr < useEnd; usePtr++) + if (usePtr->isVirtualRegister()) + { + VirtualRegister& vReg = usePtr->getVirtualRegister(); + if (vReg.getClass() != vrcStackSlot) + { + PRUint32 registerIndex = vReg.getRegisterIndex(); + currentLive.set(registerIndex); + needLoad.set(registerIndex); + } + } + + // All the registers in currentLive just lived one more cycle. + for (PRInt32 registerIndex = currentLive.firstOne(); registerIndex != -1; registerIndex = currentLive.nextOne(registerIndex)) + { + VirtualRegister& vReg = vRegManager.getVirtualRegister(registerIndex); + if (vReg.getClass() != vrcStackSlot) + vReg.spillInfo.liveLength++; + } + } + + // All the registers left in needLoad will be loaded. + for (PRInt32 nl = needLoad.firstOne(); nl != -1; nl = needLoad.nextOne(nl)) + vRegManager.getVirtualRegister(nl).spillInfo.nLoads += node.nVisited; + } + + // Summarize + for (VirtualRegisterManager::iterator j = vRegManager.begin(); !vRegManager.done(j); j = vRegManager.advance(j)) + { + VirtualRegister& vReg = vRegManager.getVirtualRegister(j); + if (vReg.getClass() != vrcStackSlot) + { + if (!vReg.spillInfo.infiniteSpillCost) + { + // It may be good to take into account the size of the live range and to + // weight differently a load/store and a copy. + vReg.spillInfo.spillCost = (2 * (vReg.spillInfo.nLoads + vReg.spillInfo.nStores) - vReg.spillInfo.nCopies) / + (((Flt32)vReg.spillInfo.liveLength)); + } + } + } +} + + + +// asharma +void +RegisterAllocator::updateLocalVariableTable() +{ + for (Uint32 m = 0; m < nNodes; m++) { + ControlNode& node = *dfsList[m]; + DoublyLinkedList &primitives = node.getPrimitives(); + for (DoublyLinkedList::iterator i = primitives.begin(); + !primitives.done(i); + i = primitives.advance(i)) { + Primitive &p = primitives.get(i); + // We're not interested in primitives that are not the values of + // certain local variables + if (!p.mapping) + continue; + switch(p.getKind()) { + case vkCond: + case vkMemory: + break; + default: + VirtualRegister *vr = p.getVirtualRegisterAnnotation(); + if (vr) { + VariableLocation loc(true, vr->getColor()); + p.mapping->setVariableLocation(loc); + } + break; + } + } + } +} + + +/* + *-------------------------RegisterAllocator.cpp------------------------- + * + * RegisterAllocator::printRegisterDebug -- + * + * Print informations about valid registers. + * + *----------------------------------------------------------------------- + */ +#ifdef DEBUG_LOG +void RegisterAllocator:: +printRegisterDebug(LogModuleObject &f, bool verbose) +{ + for (VirtualRegisterManager::iterator i = vRegManager.begin(); !vRegManager.done(i); i = vRegManager.advance(i)) + { + VirtualRegister& vReg = vRegManager.getVirtualRegister(i); + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("%d: ", i)); + + // print the class info. + PRUint8 classChar; + switch (vReg.getClass()) + { + case vrcInteger: + classChar = 'I'; + break; + case vrcFixedPoint: + classChar = 'f'; + break; + case vrcFloatingPoint: + classChar = 'F'; + break; + case vrcStackSlot: + classChar = 'S'; + break; + default: + classChar = '?'; + break; + } + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("%c ", classChar)); + + // print the register. + if (vReg.isPreColored()) + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("r%d ", vReg.getPreColor())); + else + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("vr%d ", i)); + + // print his interference. + if (verbose) + { + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("interferes w/ ( ")); + FastBitSet inter(interferenceMatrix.getRow(i), vRegManager.count()); + for (PRInt32 j = inter.firstOne(); j != -1; j = inter.nextOne(j)) + { + VirtualRegister& vr = vRegManager.getVirtualRegister(j); + if (vr.isPreColored()) + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("r%d ", vr.getPreColor())); + else + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("vr%d ", j)); + } + UT_OBJECTLOG(f, PR_LOG_ALWAYS, (" - ")); + FastBitSet& special = vReg.specialInterference; + for (PRInt32 k = special.firstOne(); k != -1; k = special.nextOne(k)) + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("r%d ", k)); + UT_OBJECTLOG(f, PR_LOG_ALWAYS, (") ")); + } + + // print the liveness info + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("alive in nodes ( ")); + for (PRInt32 k = vReg.liveness.firstOne(); k != -1; k = vReg.liveness.nextOne(k)) + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("%d ", k)); + UT_OBJECTLOG(f, PR_LOG_ALWAYS, (") ")); + + // print the interference degree + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("nInter=%d ", vReg.colorInfo.interferenceDegree)); + + // print the spill cost + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("spillcost=")); + if (vReg.spillInfo.infiniteSpillCost) + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("infinite ")); + else + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("%.2f ", vReg.spillInfo.spillCost)); + + // done. + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("\n")); + } +} +#endif diff --git a/ef/Compiler/RegisterAllocator/RegisterAllocator.h b/ef/Compiler/RegisterAllocator/RegisterAllocator.h new file mode 100644 index 000000000000..be73f37874eb --- /dev/null +++ b/ef/Compiler/RegisterAllocator/RegisterAllocator.h @@ -0,0 +1,95 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#ifndef _REGISTER_ALLOCATOR_H_ +#define _REGISTER_ALLOCATOR_H_ + +#include "RegisterAssigner.h" +#include "Coloring.h" +#include "FastBitMatrix.h" +#include "Spilling.h" +#include "LogModule.h" + +class ControlGraph; +class InstructionEmitter; +class VirtualRegisterManager; +class FastBitMatrix; +class Pool; + +extern void printGraph(Uint32 nNodes, ControlNode** dfsList); + + +/* + *--------------------------RegisterAllocator.h---------------------------- + * + * class RegisterAllocator -- + * + *----------------------------------------------------------------------- + */ +class RegisterAllocator +{ + +private: + + Pool& regAllocPool; // Register Allocation Pool. + /* + * ControlGraph data. + */ + ControlNode** dfsList; // List of the nodes in Depth First Search order. + ControlNode** lndList; // List of the nodes in Loop Nesting Depth order. + PRUint32 nNodes; // Number of nodes in this graph. + + VirtualRegisterManager& vRegManager; // Virtual Register Manager for this graph. + MdEmitter& instructionEmitter; // Instruction emitter for this platform. + Coloring registerAssigner; // Register assigner (right now only graph coloring is supported) + Spilling spilling; // Register spilling + FastBitMatrix interferenceMatrix; // Register interference matrix. + + /* + * Register Allocation core private methods. + */ + void checkRegisterClassConflicts(); + void checkPhiNodesAnnotation(); + void buildInterferenceGraph(); + bool canCoalesceRegisters(VirtualRegister& inVR, VirtualRegister& outVR, PRUint32& from, PRUint32& to); + void coalesceRegisters(PRUint32 from, PRUint32 to); + void coalesce(); + void calculateSpillCosts(); + void spillPhiNodes(); + bool removePhiNodes(); + void updateLocalVariableTable(); + +#ifdef DEBUG_LOG + void printRegisterDebug(LogModuleObject &f, bool verbose = false); +#endif + +public: + /* + * Constructor. + */ + RegisterAllocator(Pool& pool, ControlNode** dfs, ControlNode **lnd, PRUint32 n, VirtualRegisterManager& vrMan, MdEmitter& emitter) : + regAllocPool(pool), dfsList(dfs), lndList(lnd), nNodes(n), vRegManager(vrMan), instructionEmitter(emitter), + registerAssigner(pool, vRegManager), spilling(vrMan, emitter), interferenceMatrix(pool) {} + + /* + * Public call for register allocation. + */ + void allocateRegisters(); +}; + +#endif /* _REGISTER_ALLOCATOR_H_ */ diff --git a/ef/Compiler/RegisterAllocator/RegisterAssigner.h b/ef/Compiler/RegisterAllocator/RegisterAssigner.h new file mode 100644 index 000000000000..c2051b72272b --- /dev/null +++ b/ef/Compiler/RegisterAllocator/RegisterAssigner.h @@ -0,0 +1,38 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#ifndef _REGISTER_ASSIGNER_H_ +#define _REGISTER_ASSIGNER_H_ + +#include "Fundamentals.h" +#include "VirtualRegister.h" + +class FastBitMatrix; + +class RegisterAssigner +{ +protected: + VirtualRegisterManager& vRegManager; + +public: + RegisterAssigner(VirtualRegisterManager& vrMan) : vRegManager(vrMan) {} + + virtual bool assignRegisters(FastBitMatrix& interferenceMatrix) = 0; +}; + +#endif /* _REGISTER_ASSIGNER_H_ */ diff --git a/ef/Compiler/RegisterAllocator/SSATools.cpp b/ef/Compiler/RegisterAllocator/SSATools.cpp new file mode 100644 index 000000000000..7a7252697a56 --- /dev/null +++ b/ef/Compiler/RegisterAllocator/SSATools.cpp @@ -0,0 +1,32 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#include "Fundamentals.h" +#include "SSATools.h" +#include "ControlGraph.h" +#include "VirtualRegister.h" +#include "Liveness.h" + +void replacePhiNodes(ControlGraph& controlGraph, VirtualRegisterManager& vrManager) +{ + if (!controlGraph.hasBackEdges) + return; + + Liveness liveness(controlGraph.pool); + liveness.buildLivenessAnalysis(controlGraph, vrManager); +} diff --git a/ef/Compiler/RegisterAllocator/SSATools.h b/ef/Compiler/RegisterAllocator/SSATools.h new file mode 100644 index 000000000000..bc5717e08b4c --- /dev/null +++ b/ef/Compiler/RegisterAllocator/SSATools.h @@ -0,0 +1,29 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#ifndef _SSA_TOOLS_H_ +#define _SSA_TOOLS_H_ + +#include "Fundamentals.h" + +class ControlGraph; +class VirtualRegisterManager; + +extern void replacePhiNodes(ControlGraph& controlGraph, VirtualRegisterManager& vrManager); + +#endif // _SSA_TOOLS_H_ diff --git a/ef/Compiler/RegisterAllocator/Spilling.cpp b/ef/Compiler/RegisterAllocator/Spilling.cpp new file mode 100644 index 000000000000..015e33d170f8 --- /dev/null +++ b/ef/Compiler/RegisterAllocator/Spilling.cpp @@ -0,0 +1,268 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#define INCLUDE_EMITTER +#include "CpuInfo.h" +#include "Fundamentals.h" +#include "ControlNodes.h" +#include "Instruction.h" +#include "InstructionEmitter.h" +#include "Spilling.h" + + +void Spilling:: +insertSpillCode(ControlNode** dfsList, Uint32 nNodes) +{ + PRUint32 nVirtualRegisters = vRegManager.count(); + FastBitSet currentLive(vRegManager.pool, nVirtualRegisters); + FastBitSet usedInThisInstruction(vRegManager.pool, nVirtualRegisters); + RegisterFifo grNeedLoad(nVirtualRegisters); + RegisterFifo fpNeedLoad(nVirtualRegisters); + + for (PRInt32 n = nNodes - 1; n >= 0; n--) + { + PR_ASSERT(grNeedLoad.empty() & fpNeedLoad.empty()); + ControlNode& node = *dfsList[n]; + + currentLive = node.liveAtEnd; + + PRUint32 nGeneralAlive = 0; + PRUint32 nFloatingPointAlive = 0; + + // Get the number of registers alive at the end of this node. + for (PRInt32 j = currentLive.firstOne(); j != -1; j = currentLive.nextOne(j)) + { + VirtualRegister& vReg = vRegManager.getVirtualRegister(j); + if (vReg.spillInfo.willSpill) + { + currentLive.clear(j); + } + else + { + switch (vReg.getClass()) + { + case vrcInteger: + nGeneralAlive++; + break; + case vrcFloatingPoint: + case vrcFixedPoint: + nFloatingPointAlive++; + break; + default: + break; + } + } + } + +// if(node.dfsNum == 8) printf("\n________Begin Node %d________\n", node.dfsNum); + + InstructionList& instructions = node.getInstructions(); + for (InstructionList::iterator i = instructions.end(); !instructions.done(i); i = instructions.retreat(i)) + { + Instruction& instruction = instructions.get(i); + InstructionUse* useBegin = instruction.getInstructionUseBegin(); + InstructionUse* useEnd = instruction.getInstructionUseEnd(); + InstructionUse* usePtr; + InstructionDefine* defBegin = instruction.getInstructionDefineBegin(); + InstructionDefine* defEnd = instruction.getInstructionDefineEnd(); + InstructionDefine* defPtr; + +// if(node.dfsNum == 8) { printf("\n"); +// instruction.printPretty(stdout); +// printf("\n"); } + + // Handle definitions + for (defPtr = defBegin; defPtr < defEnd; defPtr++) + if (defPtr->isVirtualRegister()) + { + VirtualRegister& vReg = defPtr->getVirtualRegister(); + currentLive.clear(vReg.getRegisterIndex()); + switch (vReg.getClass()) + { + case vrcInteger: + nGeneralAlive--; + break; + case vrcFloatingPoint: + case vrcFixedPoint: + nFloatingPointAlive--; + break; + default: + break; + } + } + + // Check for deaths + for (usePtr = useBegin; usePtr < useEnd; usePtr++) + if (usePtr->isVirtualRegister()) + { + VirtualRegister& vReg = usePtr->getVirtualRegister(); + if (!currentLive.test(vReg.getRegisterIndex())) + // This is the last use of this register. + { + currentLive.set(vReg.getRegisterIndex()); + switch (vReg.getClass()) + { + case vrcInteger: + nGeneralAlive++; + while (/*(nGeneralAlive > NUMBER_OF_GREGISTERS) &&*/ !grNeedLoad.empty()) + { + PRUint32 toLoad = grNeedLoad.get(); + currentLive.clear(toLoad); + nGeneralAlive--; + + VirtualRegister& nReg = vRegManager.getVirtualRegister(toLoad); + Instruction& lastUsingInstruction = *nReg.spillInfo.lastUsingInstruction; + emitter.emitLoadAfter(*lastUsingInstruction.getPrimitive(), lastUsingInstruction.getLinks().prev, + nReg.getAlias(), *nReg.equivalentRegister[vrcStackSlot]); + nReg.releaseSelf(); + } + break; + case vrcFloatingPoint: + case vrcFixedPoint: + nFloatingPointAlive++; + while (/*(nFloatingPointAlive > NUMBER_OF_FPREGISTERS) &&*/ !fpNeedLoad.empty()) + { + PRUint32 toLoad = fpNeedLoad.get(); + currentLive.clear(toLoad); + nFloatingPointAlive--; + + VirtualRegister& nReg = vRegManager.getVirtualRegister(toLoad); + Instruction& lastUsingInstruction = *nReg.spillInfo.lastUsingInstruction; + emitter.emitLoadAfter(*lastUsingInstruction.getPrimitive(), lastUsingInstruction.getLinks().prev, + nReg.getAlias(), *nReg.equivalentRegister[vrcStackSlot]); + nReg.releaseSelf(); + } + break; + default: + break; + } + } + } + + // Handle uses + for (usePtr = useBegin; usePtr < useEnd; usePtr++) + if (usePtr->isVirtualRegister()) + { + VirtualRegister& vReg = usePtr->getVirtualRegister(); + PRUint32 registerIndex = vReg.getRegisterIndex(); + + if (vReg.spillInfo.willSpill) { +#if defined(GENERATE_FOR_X86) + if (!instruction.switchUseToSpill((usePtr - useBegin), *vReg.equivalentRegister[vrcStackSlot])) +#endif + { + switch (vReg.getClass()) + { + case vrcInteger: + if (!grNeedLoad.test(registerIndex)) + { + grNeedLoad.put(registerIndex); + VirtualRegister& alias = vRegManager.newVirtualRegister(vrcInteger); + if (vReg.isPreColored()) + alias.preColorRegister(vReg.getPreColor()); + /* if (vReg.hasSpecialInterference) { + alias.specialInterference.sizeTo(NUMBER_OF_REGISTERS); + alias.specialInterference = vReg.specialInterference; + alias.hasSpecialInterference = true; + } */ + vReg.setAlias(alias); + vReg.retainSelf(); + } + break; + case vrcFloatingPoint: + case vrcFixedPoint: + if (!fpNeedLoad.test(registerIndex)) + { + fpNeedLoad.put(registerIndex); + VirtualRegister& alias = vRegManager.newVirtualRegister(vReg.getClass()); + if (vReg.isPreColored()) + alias.preColorRegister(vReg.getPreColor()); + /*if (vReg.hasSpecialInterference) { + alias.specialInterference.sizeTo(NUMBER_OF_REGISTERS); + alias.specialInterference = vReg.specialInterference; + alias.hasSpecialInterference = true; + } */ + vReg.setAlias(alias); + vReg.retainSelf(); + } + break; + default: + break; + } + usePtr->getVirtualRegisterPtr().initialize(vReg.getAlias()); + usedInThisInstruction.set(registerIndex); + vReg.spillInfo.lastUsingInstruction = &instruction; + } + currentLive.clear(registerIndex); + } else { // will not spill + currentLive.set(registerIndex); + } + } + + // Handle definitions + for (defPtr = defBegin; defPtr < defEnd; defPtr++) + if (defPtr->isVirtualRegister()) + { + VirtualRegister& vReg = defPtr->getVirtualRegister(); + + if (vReg.spillInfo.willSpill) +#if defined(GENERATE_FOR_X86) + if (!instruction.switchDefineToSpill((defPtr - defBegin), *vReg.equivalentRegister[vrcStackSlot])) +#endif + { + if (usedInThisInstruction.test(vReg.getRegisterIndex())) + // this virtualRegister was used in this instruction and is also defined. We need to move + // this virtual register to its alias first and then save it to memory. + { + emitter.emitStoreAfter(*instruction.getPrimitive(), &instruction.getLinks(), + vReg.getAlias(), *vReg.equivalentRegister[vrcStackSlot]); + defPtr->getVirtualRegisterPtr().initialize(vReg.getAlias()); + } + else + { + emitter.emitStoreAfter(*instruction.getPrimitive(), &instruction.getLinks(), + vReg, *vReg.equivalentRegister[vrcStackSlot]); + } + } + } + } + while (!grNeedLoad.empty()) + { + PRUint32 nl = grNeedLoad.get(); + VirtualRegister& nlReg = vRegManager.getVirtualRegister(nl); + Instruction& lastUse = *nlReg.spillInfo.lastUsingInstruction; + + emitter.emitLoadAfter(*lastUse.getPrimitive(), lastUse.getLinks().prev, + nlReg.getAlias(), *nlReg.equivalentRegister[vrcStackSlot]); + nlReg.releaseSelf(); + } + while (!fpNeedLoad.empty()) + { + PRUint32 nl = fpNeedLoad.get(); + VirtualRegister& nlReg = vRegManager.getVirtualRegister(nl); + Instruction& lastUse = *nlReg.spillInfo.lastUsingInstruction; + + emitter.emitLoadAfter(*lastUse.getPrimitive(), lastUse.getLinks().prev, + nlReg.getAlias(), *nlReg.equivalentRegister[vrcStackSlot]); + nlReg.releaseSelf(); + } + +// if(node.dfsNum == 8) printf("\n________End Node %d________\n", node.dfsNum); + + } +} diff --git a/ef/Compiler/RegisterAllocator/Spilling.h b/ef/Compiler/RegisterAllocator/Spilling.h new file mode 100644 index 000000000000..bde09a0fd412 --- /dev/null +++ b/ef/Compiler/RegisterAllocator/Spilling.h @@ -0,0 +1,70 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#ifndef _SPILLING_H_ +#define _SPILLING_H_ + +#include "Fundamentals.h" +#include "VirtualRegister.h" +#include "Instruction.h" +#include "Fifo.h" +#include "CpuInfo.h" + +class ControlNode; + +class Spilling +{ +protected: + + VirtualRegisterManager& vRegManager; + MdEmitter& emitter; + +public: + + Spilling(VirtualRegisterManager& vrMan, MdEmitter& emit) : vRegManager(vrMan), emitter(emit) {} + + void insertSpillCode(ControlNode** dfsList, Uint32 nNodes); +}; + +class RegisterFifo : public Fifo +{ +private: + FastBitSet bitset; +public: + RegisterFifo(Uint32 size) : Fifo(size), bitset(size) {} + Uint32 get(); + void put(Uint32 r); + bool test(Uint32 r) {return bitset.test(r);} +}; + +inline Uint32 +RegisterFifo::get() +{ + Uint32 r = Fifo::get(); + bitset.clear(r); + return r; +} + +inline void +RegisterFifo::put(Uint32 r) +{ + Fifo::put(r); + bitset.set(r); +} + +#endif /* _SPILLING_H_ */ diff --git a/ef/Compiler/RegisterAllocator/Timer.cpp b/ef/Compiler/RegisterAllocator/Timer.cpp new file mode 100644 index 000000000000..35e210c59825 --- /dev/null +++ b/ef/Compiler/RegisterAllocator/Timer.cpp @@ -0,0 +1,186 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#include "Fundamentals.h" +#include "HashTable.h" +#include "Timer.h" +#include "Pool.h" + +static Pool pool; // Pool for the Timer class. +static HashTable timerEntries(pool); // Timers hashtable. + +const nTimersInABlock = 128; // Number of timers in a block. +static PRTime *timers = new(pool) PRTime[nTimersInABlock]; // A block of timers. +static Uint8 nextTimer = 0; // nextAvailableTimer. + +// +// Calibrate the call to PR_Now(). +// +static PRTime calibrate() +{ + PRTime t = PR_Now(); + PRTime& a = *new(pool) PRTime(); + + // Call 10 times the PR_Now() function. + a = PR_Now(); a = PR_Now(); a = PR_Now(); a = PR_Now(); a = PR_Now(); a = PR_Now(); + a = PR_Now(); a = PR_Now(); a = PR_Now(); a = PR_Now(); a = PR_Now(); a = PR_Now(); + t = (PR_Now() - t + 9) / 10; + + return t; +} + +static PRTime adjust = calibrate(); + +// +// Return the named timer.. +// +TimerEntry& Timer::getTimerEntry(const char* name) +{ + if (!timerEntries.exists(name)) { + TimerEntry* newEntry = new(pool) TimerEntry(); + newEntry->accumulator = 0; + newEntry->running = false; + timerEntries.add(name, newEntry); + } + + return *timerEntries[name]; +} + +// +// Return a reference to a new timer. +// +PRTime& Timer::getNewTimer() +{ + if (nextTimer >= nTimersInABlock) { + timers = new(pool) PRTime[nTimersInABlock]; + nextTimer = 0; + } + return timers[nextTimer++]; +} + +static Uint32 timersAreFrozen = 0; + +// +// Start the named timer. +// +void Timer::start(const char* name) +{ + if (timersAreFrozen) + return; + + freezeTimers(); + + TimerEntry& timer = getTimerEntry(name); + PR_ASSERT(!timer.running); + + timer.accumulator = 0; + timer.running = true; + timer.done = false; + + unfreezeTimers(); +} + +// +// Stop the named timer. +// +void Timer::stop(const char* name) +{ + if (timersAreFrozen) + return; + + freezeTimers(); + + TimerEntry& timer = getTimerEntry(name); + PR_ASSERT(timer.running); + timer.running = false; + timer.done = true; + + unfreezeTimers(); +} + +// +// Freeze all the running timers. +// +void Timer::freezeTimers() +{ + PRTime when = PR_Now() - adjust; + + if (timersAreFrozen == 0) { + Vector entries = timerEntries; + Uint32 count = entries.size(); + + for (Uint32 i = 0; i < count; i++) { + TimerEntry& entry = *entries[i]; + if (entry.running) { + entry.accumulator += (when - *entry.startTime); + } + } + } + timersAreFrozen++; +} + +// +// Unfreeze all the running timers. +// +void Timer::unfreezeTimers() +{ + PR_ASSERT(timersAreFrozen != 0); + timersAreFrozen--; + + if (timersAreFrozen == 0) { + Vector entries = timerEntries; + Uint32 count = entries.size(); + + PRTime& newStart = getNewTimer(); + + for (Uint32 i = 0; i < count; i++) { + TimerEntry& entry = *entries[i]; + if (entry.running) { + entry.startTime = &newStart; + } + } + + newStart = PR_Now(); + } +} + +// +// Print the named timer in the file f. +// +void Timer::print(FILE* f, const char *name) +{ + if (timersAreFrozen) + return; + + freezeTimers(); + + TimerEntry& timer = getTimerEntry(name); + + PR_ASSERT(timer.done); + PRTime elapsed = timer.accumulator; + + if (elapsed >> 32) { + fprintf(f, "[timer %s out of range]\n", name); + } else { + fprintf(f, "[%dus in %s]\n", Uint32(elapsed), name); + } + fflush(f); + + unfreezeTimers(); +} + diff --git a/ef/Compiler/RegisterAllocator/Timer.h b/ef/Compiler/RegisterAllocator/Timer.h new file mode 100644 index 000000000000..30fbdae66d44 --- /dev/null +++ b/ef/Compiler/RegisterAllocator/Timer.h @@ -0,0 +1,80 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#ifndef _TIMER_H_ +#define _TIMER_H_ + +#include "Fundamentals.h" +#include "HashTable.h" +#include "prtime.h" + +// +// Naming convention: +// As the class Timer contains only static methods, the timer's name should start with the +// module name. Otherwise starting 2 timers with the same name will assert. +// + +#ifndef NO_TIMER + +struct TimerEntry +{ + PRTime *startTime; // Current time when we start the timer. + PRTime accumulator; // Time spent in this timer. + bool running; // True if the timer is running. + bool done; // True if the timer was running and was stopped. +}; + +class Timer +{ +private: + + // Return the named timer. + static TimerEntry& getTimerEntry(const char* name); + // Return a reference to a new Timer. + static PRTime& getNewTimer(); + +public: + + // Start the timer. + static void start(const char* name); + // Stop the timer. + static void stop(const char* name); + // Freeze all the running timers. + static void freezeTimers(); + // Unfreeze all the running timers. + static void unfreezeTimers(); + // Print the timer. + static void print(FILE* f, const char *name); +}; + +inline void startTimer(const char* name) {Timer::start(name);} +inline void stopTimer(const char* name) {Timer::stop(name); Timer::print(stdout, name);} +#define START_TIMER_SAFE Timer::freezeTimers(); +#define END_TIMER_SAFE Timer::unfreezeTimers(); +#define TIMER_SAFE(x) START_TIMER_SAFE x; END_TIMER_SAFE + +#else /* NO_TIMER */ + +inline void startTimer(const char* /*name*/) {} +inline void stopTimer(const char* /*name*/) {} +#define START_TIMER_SAFE +#define END_TIMER_SAFE +#define TIMER_SAFE(x) x; + +#endif /* NO_TIMER */ +#endif /* _TIMER_H_ */ diff --git a/ef/Compiler/RegisterAllocator/VirtualRegister.cpp b/ef/Compiler/RegisterAllocator/VirtualRegister.cpp new file mode 100644 index 000000000000..a39fab8338c4 --- /dev/null +++ b/ef/Compiler/RegisterAllocator/VirtualRegister.cpp @@ -0,0 +1,272 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#include "Fundamentals.h" +#include "VirtualRegister.h" +#include "CpuInfo.h" + + + +/* + *--------------------------VirtualRegister.cpp-------------------------- + * + * VirtualRegister::resetColoringInfo -- + * + * Reset all coloring information for this VirtualRegister. + * + *----------------------------------------------------------------------- + */ + +void VirtualRegister:: +resetColoringInfo() +{ + spillInfo.nLoads = 0.0; + spillInfo.nStores = 0.0; + spillInfo.nCopies = 0.0; + spillInfo.infiniteSpillCost = false; + spillInfo.lastUsingInstruction = 0; + spillInfo.liveLength = 0; +#if DEBUG + colorInfo.color = 0; + colorInfo.interferenceDegree = 0; +#endif +} + +#define INITIAL_VR_ARRAY_SIZE 128 + + +/* + *--------------------------VirtualRegister.cpp-------------------------- + * + * VirtualRegisterManager::VirtualRegisterManager -- + * + * VirtualRegisterManager Constructor. + * + *----------------------------------------------------------------------- + */ +VirtualRegisterManager:: +VirtualRegisterManager(Pool& p) : pool(p) +{ + virtualRegisters = new(pool) VirtualRegister*[INITIAL_VR_ARRAY_SIZE]; + machineRegisters = new(pool) VirtualRegister*[NUMBER_OF_REGISTERS]; + nAllocatedRegisters = INITIAL_VR_ARRAY_SIZE; + firstFreeRegisterIndex = 0; + size = 0; + + fill(virtualRegisters, &virtualRegisters[nAllocatedRegisters], (VirtualRegister *)0); + fill(machineRegisters, &machineRegisters[NUMBER_OF_REGISTERS], (VirtualRegister *)0); + + nUsedCalleeSavedRegisters = 0; + nUsedStackSlots = 0; +} + + +/* + *--------------------------VirtualRegister.cpp-------------------------- + * + * VirtualRegisterManager::resize -- + * + * Resize the VirtualRegister array to newSize. + * + *----------------------------------------------------------------------- + */ +void VirtualRegisterManager:: +resize(PRUint32 newSize) +{ + VirtualRegister** newVirtualRegisters = new(pool) VirtualRegister*[newSize]; + + copy(virtualRegisters, &virtualRegisters[size], newVirtualRegisters); + fill(&newVirtualRegisters[size], &newVirtualRegisters[newSize], (VirtualRegister *)0); + + virtualRegisters = newVirtualRegisters; + nAllocatedRegisters = newSize; + + // Update the VirtualRegisterAddress in all the VirtualRegisterPtrs referencing valid VirtualRegisters. + for (iterator i = begin(); !done(i); i = advance(i)) + { + VirtualRegister& vReg = *virtualRegisters[i]; + DoublyLinkedList& owners = vReg.getVirtualRegisterPtrs(); + + for (DoublyLinkedList::iterator j = owners.begin(); !owners.done(j); j = owners.advance(j)) + owners.get(j).virtualRegisterAddress = &vReg; + } +} + + +/* + *--------------------------VirtualRegister.cpp-------------------------- + * + * VirtualRegisterManager::newVirtualRegister -- + * + * Return a new VirtualRegister. + * + *----------------------------------------------------------------------- + */ +VirtualRegister& VirtualRegisterManager:: +newVirtualRegister(VRClass registerClass) +{ + VirtualRegister& newVR = *new(pool) VirtualRegister(*this, firstFreeRegisterIndex, registerClass); + virtualRegisters[firstFreeRegisterIndex++] = &newVR; + + for (; firstFreeRegisterIndex < size; firstFreeRegisterIndex++) + if (virtualRegisters[firstFreeRegisterIndex] == NULL) + // This slot is free. + break; + + if (firstFreeRegisterIndex > size) + { + size = firstFreeRegisterIndex; + if (size >= nAllocatedRegisters) + resize(2 * nAllocatedRegisters); + } + + return newVR; +} + + +/* + *--------------------------VirtualRegister.cpp-------------------------- + * + * VirtualRegisterManager::getMachineRegister -- + * + * Return the Machine register r(color). + * + *----------------------------------------------------------------------- + */ +VirtualRegister& VirtualRegisterManager:: +getMachineRegister(PRUint8 color) +{ + if (machineRegisters[color] == NULL) + { + VRClass registerClass = vrcUnspecified; + + if (color <= LAST_GREGISTER) + registerClass = vrcInteger; +#if NUMBER_OF_FPREGISTERS != 0 + else if (color < LAST_FPREGISTER) + registerClass = vrcFloatingPoint; +#endif + + VirtualRegister& machineRegister = newVirtualRegister(registerClass); + machineRegister.isMachineRegister = true; + machineRegisters[color] = &machineRegister; + } + + return *machineRegisters[color]; +} + + +/* + *--------------------------VirtualRegister.cpp-------------------------- + * + * VirtualRegisterManager::freeVirtualRegister -- + * + * Free this VirtualRegister and update the firstFreeRegisterIndex + * field for the next VirtualRegister to be allocated. + * + *----------------------------------------------------------------------- + */ +void VirtualRegisterManager:: +freeVirtualRegister(PRUint32 index) +{ + PR_ASSERT((index < size) && (virtualRegisters[index] != NULL) && !virtualRegisters[index]->isReferenced()); + + if (index < firstFreeRegisterIndex) + firstFreeRegisterIndex = index; + + virtualRegisters[index] = NULL; +} + + +/* + *--------------------------VirtualRegister.cpp-------------------------- + * + * VirtualRegisterManager::compactMemory -- + * + * Try to remove any gaps in the VirtualRegister array. + * + *----------------------------------------------------------------------- + */ +void VirtualRegisterManager:: +compactMemory() +{ + PRInt32 index = count(); + + while ((--index >= 0) && (index > PRInt32(firstFreeRegisterIndex))) + if (virtualRegisters[index] != NULL) { + VirtualRegister& vReg = newVirtualRegister(virtualRegisters[index]->getClass()); + + if (virtualRegisters[index]->isPreColored()) + vReg.preColorRegister(virtualRegisters[index]->getPreColor()); + + moveVirtualRegister(index, vReg.getRegisterIndex()); + } +} + + +/* + *--------------------------VirtualRegister.cpp-------------------------- + * + * VirtualRegisterManager::checkForVirtualRegisterDeath -- + * + * If the VirtualRegister at index is not referenced any more, free it. + * + *----------------------------------------------------------------------- + */ +void VirtualRegisterManager:: +checkForVirtualRegisterDeath(PRUint32 index) +{ + PR_ASSERT((index < size) && (virtualRegisters[index] != NULL)); + + if (!virtualRegisters[index]->isReferenced()) + freeVirtualRegister(index); +} + + +/* + *--------------------------VirtualRegister.cpp-------------------------- + * + * VirtualRegisterManager::moveVirtualRegister -- + * + * Update all the VirtualRegisterPtrs pointing to source to point to dest. + * Free source when done. + * + *----------------------------------------------------------------------- + */ +void VirtualRegisterManager:: +moveVirtualRegister(PRUint32 source, PRUint32 dest) +{ + PR_ASSERT(source != dest); + PR_ASSERT((source < size) && (virtualRegisters[source] != NULL)); + PR_ASSERT((dest < size) && (virtualRegisters[dest] != NULL)); + + DoublyLinkedList& sourceOwners = virtualRegisters[source]->getVirtualRegisterPtrs(); + DoublyLinkedList& destOwners = virtualRegisters[dest]->getVirtualRegisterPtrs(); + + for (DoublyLinkedList::iterator i = sourceOwners.begin(); !sourceOwners.done(i);) + { + VirtualRegisterPtr& vRegPtr = sourceOwners.get(i); + i = sourceOwners.advance(i); + vRegPtr.remove(); + vRegPtr.virtualRegisterAddress = virtualRegisters[dest]; + destOwners.addLast(vRegPtr); + } + + freeVirtualRegister(source); +} + diff --git a/ef/Compiler/RegisterAllocator/VirtualRegister.h b/ef/Compiler/RegisterAllocator/VirtualRegister.h new file mode 100644 index 000000000000..6c2b0caa372a --- /dev/null +++ b/ef/Compiler/RegisterAllocator/VirtualRegister.h @@ -0,0 +1,382 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#ifndef _VIRTUAL_REGISTER_H_ +#define _VIRTUAL_REGISTER_H_ + +#include "Fundamentals.h" +#include "DoublyLinkedList.h" +#include "FastBitSet.h" +#include "FastBitMatrix.h" + +class VirtualRegisterManager; +class VirtualRegister; +class Instruction; + + +/* + *--------------------------VirtualRegister.h---------------------------- + * + * enum VRClass -- + * + *----------------------------------------------------------------------- + */ +enum VRClass +{ + InvalidRegisterKind, + IntegerRegister, + FloatingPointRegister, + FixedPointRegister, + MemoryRegister, + StackSlotRegister, + MemoryArgumentRegister, + + nVRClass +}; + +const VRClass vrcUnspecified = InvalidRegisterKind; +const VRClass vrcInteger = IntegerRegister; +const VRClass vrcFloatingPoint = FloatingPointRegister; +const VRClass vrcFixedPoint = FixedPointRegister; +const VRClass vrcStackSlot = StackSlotRegister; + +typedef VRClass VirtualRegisterKind; + + +/* + *--------------------------VirtualRegister.h---------------------------- + * + * class VirtualRegisterPtr -- + * + *----------------------------------------------------------------------- + */ +class VirtualRegisterPtr : public DoublyLinkedEntry +{ + friend class VirtualRegisterManager; + friend class VirtualRegister; + +private: + + VirtualRegister* virtualRegisterAddress; + VRClass registerClassConstraint; + + inline VirtualRegister* link(VirtualRegister* vReg); + inline VirtualRegister* unlink(); + +#if DEBUG + /* + * Copying a VirtualRegisterPtr is forbidden. + */ + VirtuaRegisterPtr(const VirtualRegisterPtr& vRegPtr); + void operator = (const VirtualRegisterPtr& vRegPtr); +#endif + +public: + + /* + * Constructors & destructors. + */ + inline VirtualRegisterPtr() : virtualRegisterAddress(NULL), registerClassConstraint(vrcInteger) {} + ~VirtualRegisterPtr() {unlink();} + + /* + * Initialization. + */ + inline bool isInitialized() {return (virtualRegisterAddress != NULL) ? true : false;} + inline void initialize(VirtualRegister& vReg, VRClass constraint = vrcInteger); + inline void uninitialize() {unlink(); DEBUG_ONLY(registerClassConstraint = vrcUnspecified;)} + + /* + * Getting the virtual registers or the register class constraint. + */ + inline VirtualRegister& getVirtualRegister() {return *virtualRegisterAddress;} + inline VRClass getClassConstraint() {return registerClassConstraint;} + inline void setClassConstraint(VRClass constraint) {registerClassConstraint = constraint;} +}; + + +/* + *--------------------------VirtualRegister.h---------------------------- + * + * class VirtualRegister -- + * + *----------------------------------------------------------------------- + */ +class VirtualRegister +{ + friend class VirtualRegisterManager; + +private: + + DoublyLinkedList virtualRegisterPtrs; + Instruction* definingInstruction; + + VirtualRegisterManager& registerManager; + PRUint32 registerIndex; + VRClass registerClass; + + bool isMachineRegister; + + /* + * Copying a VirtualRegister is forbidden. + */ + VirtualRegister(const VirtualRegister& vReg); + void operator = (const VirtualRegister& vReg); + + VirtualRegisterPtr lock; +#if DEBUG + bool isLocked; +#endif + + /* + * Constructors. + */ + VirtualRegister(VirtualRegisterManager& myManager, PRUint32 myIndex, VRClass myClass = vrcInteger); + +public: + + VirtualRegister* equivalentRegister[nVRClass]; + FastBitSet specialInterference; + FastBitSet liveness; + bool hasSpecialInterference; +#ifdef DEBUG + bool isAnnotated; +#endif + + /* + * Spilling & Coloring informations. + */ + struct + { + Flt32 nLoads; + Flt32 nStores; + Flt32 nCopies; + Uint32 liveLength; + + Flt32 spillCost; + bool infiniteSpillCost; + bool willSpill; + + Instruction* lastUsingInstruction; + } spillInfo; + + struct + { + PRUint32 interferenceDegree; + PRUint8 color; + PRUint8 preColor; + PRUint32 preColoredRegisterIndex; + bool isPreColored; + } colorInfo; + + /* + * For Code Generation + */ + inline void setDefiningInstruction(Instruction& insn) {definingInstruction = &insn;} + inline Instruction* getDefiningInstruction() {return definingInstruction;} + + /* + * Setting the color. + */ + inline void preColorRegister(PRUint8 preColor); + inline bool isPreColored() {return colorInfo.isPreColored;} + inline PRUint8 getPreColor() {PR_ASSERT(isPreColored()); return colorInfo.preColor;} + + inline void colorRegister(PRUint8 color) {colorInfo.color = color;} + inline PRUint8 getColor() {return colorInfo.color;} + + void resetColoringInfo(); + + inline void setClass(VRClass myClass) {registerClass = myClass;} + inline VRClass getClass() {return registerClass;} + + /* + * Getting the register's variables. + */ + inline bool isReferenced() {return !virtualRegisterPtrs.empty();} + inline DoublyLinkedList& getVirtualRegisterPtrs() {return virtualRegisterPtrs;} + inline PRUint32 getRegisterIndex() {return registerIndex;} + inline VirtualRegisterManager& getManager() {return registerManager;} + + // check for real use of these methods !. + inline VirtualRegister& getAlias() {return *equivalentRegister[registerClass];} + inline void setAlias(VirtualRegister& alias) {equivalentRegister[registerClass] = &alias;} + + // lock + inline void retainSelf() {PR_ASSERT(!isLocked); lock.initialize(*this); DEBUG_ONLY(isLocked = true);} + inline void releaseSelf() {PR_ASSERT(isLocked); lock.uninitialize(); DEBUG_ONLY(isLocked = false);} +}; + + +/* + *--------------------------VirtualRegister.h---------------------------- + * + * class VirtualRegisterManager -- + * + *----------------------------------------------------------------------- + */ +class VirtualRegisterManager +{ +private: + + VirtualRegister** virtualRegisters; + VirtualRegister** machineRegisters; + + PRUint32 nAllocatedRegisters; + PRUint32 firstFreeRegisterIndex; + PRUint32 size; + + void resize(PRUint32 amount); + void freeVirtualRegister(PRUint32 index); + +public: + + Pool& pool; + + typedef PRUint32 iterator; + +#if 0 + struct + { +#endif + PRUint8 nUsedStackSlots; + PRUint8 nUsedCalleeSavedRegisters; +#if 0 + } RegisterUsageInfo; +#endif + + VirtualRegisterManager(Pool& p); + + VirtualRegister& newVirtualRegister(VRClass cl = vrcInteger); + inline VirtualRegister& getVirtualRegister(PRUint32 index); + VirtualRegister& getMachineRegister(PRUint8 color); + + void checkForVirtualRegisterDeath(PRUint32 index); + + void compactMemory(); + void moveVirtualRegister(PRUint32 source, PRUint32 dest); + + inline iterator begin() {return advance(~0);} + inline bool done(iterator i) {return (i >= size) ? true : false;} + inline iterator advance(iterator i); + + inline PRUint32 count() {return size;} +}; + + +/* + *--------------------------VirtualRegister.h---------------------------- + * + * Inlines + * + *----------------------------------------------------------------------- + */ + +inline void VirtualRegister:: +preColorRegister(PRUint8 preColor) +{ +#ifdef DEBUG + if (isAnnotated) + trespass("This is not a temporary register. It cannot be preColored. !!!"); +#endif + + colorInfo.isPreColored = true; + colorInfo.preColor = preColor; + colorInfo.preColoredRegisterIndex = registerManager.getMachineRegister(preColor).getRegisterIndex(); +} + +inline VirtualRegister& VirtualRegisterManager:: +getVirtualRegister(PRUint32 index) +{ + PR_ASSERT((index < size) && virtualRegisters[index]); + return *virtualRegisters[index]; +} + +/* + * Return the next valid VirtualRegister index. + */ +inline VirtualRegisterManager::iterator VirtualRegisterManager:: +advance(VirtualRegisterManager::iterator i) +{ + i++; + while (i < size) + { + if ((virtualRegisters[i] != NULL) && !virtualRegisters[i]->isMachineRegister) + break; + i++; + } + return i; +} + +/* + * VirtualRegister constructor + */ +inline VirtualRegister:: +VirtualRegister(VirtualRegisterManager& myManager, PRUint32 myIndex, VRClass myClass) : + registerManager(myManager), registerIndex(myIndex), registerClass(myClass), isMachineRegister(false), + specialInterference(myManager.pool), liveness(myManager.pool) +{ + colorInfo.isPreColored = false; + colorInfo.color = 0; + spillInfo.willSpill = false; + spillInfo.spillCost = 0; + hasSpecialInterference = false; +#if DEBUG + colorInfo.color = 0; + definingInstruction = NULL; + isLocked = false; + isAnnotated = false; +#endif +} + +/* + * Add this VirtualRegisterPtr to the VirtualRegister's owners list. + */ +inline VirtualRegister* VirtualRegisterPtr:: +link(VirtualRegister* vReg) +{ + PR_ASSERT(vReg != NULL); + vReg->getVirtualRegisterPtrs().addLast(*this); + return vReg; +} + +/* + * Remove this VirtualRegisterPtr from the VirtualRegister's owners list + */ +inline VirtualRegister* VirtualRegisterPtr:: +unlink() +{ + if (virtualRegisterAddress != NULL) + { + remove(); + virtualRegisterAddress->getManager().checkForVirtualRegisterDeath(virtualRegisterAddress->getRegisterIndex()); + virtualRegisterAddress = NULL; + } + return virtualRegisterAddress; +} + + +inline void VirtualRegisterPtr:: +initialize(VirtualRegister& vReg, VRClass constraint) +{ + unlink(); + virtualRegisterAddress = link(&vReg); + registerClassConstraint = constraint; +} + +#endif /* _VIRTUAL_REGISTER_H_ */ diff --git a/ef/Debugger/Communication/DebuggerChannel.cpp b/ef/Debugger/Communication/DebuggerChannel.cpp new file mode 100644 index 000000000000..eb536e905d74 --- /dev/null +++ b/ef/Debugger/Communication/DebuggerChannel.cpp @@ -0,0 +1,493 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +// DebuggerChannel.cpp +// +// Scott M. Silver + +#include "DebuggerChannel.h" +#include "prio.h" +#include "prthread.h" +#include "prlock.h" +#ifdef assert +#undef assert +#endif +#include +#include +#include + +void DebuggerStream:: +writeRequest(Int32 inRequest) +{ + DebuggerMessageRequest msgRequest = { inRequest }; + + writeDataRaw(&msgRequest, sizeof(msgRequest)); +} + + +Int32 DebuggerStream:: +readRequest() +{ + DebuggerMessageRequest msgRequest; + + readDataRaw(&msgRequest, sizeof(msgRequest)); + + return (msgRequest.request); +} + + +void DebuggerStream:: +writeResponse(Int32 inStatus) +{ + DebuggerMessageResponse msgResponse = { inStatus }; + + writeDataRaw(&msgResponse, sizeof(msgResponse)); +} + + +Int32 DebuggerStream:: +readResponse() +{ + DebuggerMessageResponse msgResponse; + + readDataRaw(&msgResponse, sizeof(msgResponse)); + + return (msgResponse.status); +} + + +void DebuggerStream:: +writeString(const char* inString) +{ + writeData(inString, strlen(inString)); +} + + +void DebuggerStream:: +writeDataRaw(const void* inData, Int32 inLength) +{ + if (PR_Write(mFileDesc, inData, inLength) != inLength) + trespass("comm channel dead"); +} + + +void DebuggerStream:: +writeData(const void* inData, Int32 inLength) +{ + if (PR_Write(mFileDesc, &inLength, 4) != 4) + trespass("comm channel dead"); + + if (PR_Write(mFileDesc, inData, inLength) != inLength) + trespass("comm channel dead"); +} + + +Int32 DebuggerStream:: +readLength() +{ + Int32 length; + + readDataRaw(&length, 4); + return length; +} + + +void DebuggerStream:: +readDataRaw(void* outData, Int32 inLength) +{ + if (PR_Read(mFileDesc, outData, inLength) != inLength) + trespass("comm channel dead"); +} + + +void* DebuggerStream:: +readData() +{ + Int32 len = readLength(); + void* data = (void*) new char[len]; + + readDataRaw(data, len); + + return (data); +} + + +void DebuggerStream:: +writePtr(const void* inPtr) +{ + char* buffer = PR_smprintf("%p", inPtr); + writeString(buffer); + PR_smprintf_free(buffer); +} + + +static PRPtrdiff +convertAsciiToHex(const char* inString) +{ + const char* lc = inString+strlen(inString); // point to '\0' + PRPtrdiff value = 0; + PRIntn multiplier = 0; + + while (--lc >= inString) + { + if (isdigit(*lc)) + value += ((*lc - 48) << multiplier); + else if ((*lc >= 97) && (*lc <= 102)) + value += ((*lc - 87) << multiplier); + else + return (value); // bail + + multiplier += 4; + } + + return (value); +} + + +char* DebuggerStream:: +readString() +{ + Int32 len = readLength(); + char* data = new char[len+1]; + + readDataRaw(data, len); + data[len+1-1] = '\0'; // null terminate string + + return (data); +} + + +void* DebuggerStream:: +readPtr() +{ + char* data = readString(); + void* rv; + + rv = (void*) convertAsciiToHex(data); + + delete[] data; + + return (rv); +} + +bool DebuggerClientChannel:: +waitForAsyncRequest() +{ + for (;;) + { + Int32 request = mAsync.readRequest(); + + + handleAsyncRequest(request); + } + + return (true); +} + +void DebuggerClientChannel:: +asyncRequestThread(void* inThisPtr) +{ + DebuggerClientChannel* thisChannel = (DebuggerClientChannel*) inThisPtr; + + thisChannel->waitForAsyncRequest(); +} + +DebuggerClientChannel* DebuggerClientChannel:: +createClient() +{ + PRFileDesc* async; + PRFileDesc* sync; + + // specify loopback + PRNetAddr netaddr; + + netaddr.inet.family = AF_INET; + netaddr.inet.port = htons(kDebuggerPort); + netaddr.inet.ip = htonl(0x7f000001); // 127.0.0.1 + + if ((sync = PR_NewTCPSocket()) == NULL) + return (0); + + if (PR_Connect(sync, &netaddr, PR_INTERVAL_NO_TIMEOUT) < 0) + return (0); + + if ((async = PR_NewTCPSocket()) == NULL) + return (0); + + if (PR_Connect(async, &netaddr, PR_INTERVAL_NO_TIMEOUT) < 0) + return (0); + + DebuggerClientChannel* channel = new DebuggerClientChannel(sync, async); + PRThread* thread; + + thread = PR_CreateThread(PR_USER_THREAD, + &asyncRequestThread, + channel, + PR_PRIORITY_NORMAL, + PR_GLOBAL_THREAD, + PR_JOINABLE_THREAD, + 0); + + // if we can't create the async thread, this is failure + if (!thread) + { + delete channel; + return (0); + } + + return (channel); +} + +// Constructor locks the passed in lock +// Destructor unlocks the lock. +// Useful for a one line critical section +class StLocker +{ + PRLock* mLock; + +public: + StLocker(PRLock* inLock) : + mLock(inLock) { PR_Lock(mLock); } + + ~StLocker() + { + PRStatus status = PR_Unlock(mLock); + assert(status == PR_SUCCESS); + } +}; + + +char* DebuggerClientChannel:: +requestAddressToMethod(const void* inAddress, Int32& outOffset) +{ + StLocker locker(mLock); + mSync.writeRequest(kAddressToMethod); + + // now send the arguments (one hex address) + mSync.writePtr(inAddress); + + Int32 response = mSync.readResponse(); + + if (!response) + { + char *methodName = mSync.readString(); + outOffset = (Int32) mSync.readPtr(); + return (methodName); + } + + return (NULL); +} + +DebuggerClientChannel:: +DebuggerClientChannel(PRFileDesc* inSync, PRFileDesc* inAsync) : + mAsync(inAsync), + mSync(inSync), + mCompLoadHandler(0) +{ + mLock = PR_NewLock(); + assert(mLock); +} + +void* DebuggerClientChannel:: +requestMethodToAddress(const char* inMethodName) +{ + StLocker locker(mLock); + mSync.writeRequest(kMethodToAddress); + + // now send the arguments (one hex address) + mSync.writeString(inMethodName); + + Int32 response = mSync.readResponse(); + + void* address = (response == 0) ? mSync.readPtr() : 0; + + return (address); +} + +void DebuggerClientChannel:: +sendOneCharacterRequest(char inCharRequest) +{ + StLocker locker(mLock); + mSync.writeRequest((Int32) inCharRequest); +} + +void DebuggerClientChannel:: +handleAsyncRequest(Int32 inRequest) +{ + // method does not get run until + if (inRequest == kNotifyMethodCompiledLoaded) + { + char* methodName = mAsync.readString(); + void* address = mAsync.readPtr(); + + handleCompileOrLoadedMethod(methodName, address); + delete [] methodName; + mAsync.writeResponse(0); + } + else + mAsync.writeResponse(-1); +} + + +Int32 DebuggerClientChannel:: +requestNotifyOnMethodCompileLoad(const char* inMethodName) +{ + StLocker locker(mLock); + mSync.writeRequest(kRequestNotifyMethodCompiledLoaded); + + // now send the arguments (one string) + mSync.writeString(inMethodName); + + return(mSync.readResponse()); +} + +Int32 DebuggerClientChannel:: +requestRunClass(const char* inClassName) +{ + StLocker locker(mLock); + mSync.writeRequest(kRunClass); + + // now send the arguments (one string) + mSync.writeString(inClassName); + + return (mSync.readResponse()); +} + +Int32 DebuggerClientChannel:: +requestNotifyOnClassLoad(const char* inClassName) +{ + StLocker locker(mLock); + mSync.writeRequest(kNotifyOnClassLoad); + + // now send the arguments (one string) + mSync.writeString(inClassName); + + return(mSync.readResponse()); +} + +Int32 DebuggerClientChannel:: +requestNotifyOnException(const char* inClassName) +{ + StLocker locker(mLock); + mSync.writeRequest(kNotifyOnException); + + // now send the arguments (one string) + mSync.writeString(inClassName); + + return(mSync.readResponse()); +} + +void* DebuggerClientChannel:: +requestDebuggerThread() +{ + StLocker locker(mLock); + mSync.writeRequest(kRequestDebuggerThread); + + if (!mSync.readResponse()) + return (mSync.readPtr()); + else + return (0); +} + +#ifdef WIN32 +// The DLL entry-point function sets up shared memory using +// a named file-mapping object. + +#include +#include + +static DWORD* sThreadID = NULL; // pointer to shared memory + +BOOL WINAPI DllEntryPoint(HINSTANCE hinstDLL, // DLL module handle + DWORD fdwReason, // reason called + LPVOID lpvReserved) // reserved +{ + HANDLE hMapObject = NULL; // handle to file mapping + BOOL fInit, fIgnore; + + switch (fdwReason) + { + // The DLL is loading due to process + // initialization or a call to LoadLibrary. + + case DLL_PROCESS_ATTACH: + // Create a named file mapping object. + hMapObject = CreateFileMapping( + (HANDLE) 0xFFFFFFFF, // use paging file + NULL, // no security attributes + PAGE_READWRITE, // read/write access + 0, // size: high 32-bits + sizeof(*sThreadID), // size: low 32-bits + "debuggerThreadID"); // name of map object + if (hMapObject == NULL) + return FALSE; + + // The first process to attach initializes memory. + fInit = (GetLastError() != ERROR_ALREADY_EXISTS); + + // Get a pointer to the file-mapped shared memory. + sThreadID = (DWORD*) MapViewOfFile( + hMapObject, // object to map view of + FILE_MAP_WRITE, // read/write access + 0, // high offset: map from + 0, // low offset: beginning + 0); // default: map entire file + if (sThreadID == NULL) + return FALSE; + + // Initialize memory if this is the first process. + if (fInit) + memset(sThreadID, 0, sizeof(*sThreadID)); + + break; + // The attached process creates a new thread. + case DLL_THREAD_ATTACH: + break; + // The thread of the attached process terminates. + case DLL_THREAD_DETACH: + break; + // The DLL is unloading from a process due to + // process termination or a call to FreeLibrary. + case DLL_PROCESS_DETACH: + // Unmap shared memory from the process's address space. + fIgnore = UnmapViewOfFile(sThreadID); + + // Close the process's handle to the file-mapping object. + + fIgnore = CloseHandle(hMapObject); + + break; + + default: + break; + } + + return TRUE; + UNREFERENCED_PARAMETER(hinstDLL); + UNREFERENCED_PARAMETER(lpvReserved); +} + +void setDebuggerThreadID(DWORD inThreadID) +{ + *sThreadID = inThreadID; +} + +DWORD getDebuggerThreadID() +{ + return (*sThreadID); +} +#endif diff --git a/ef/Debugger/Communication/DebuggerChannel.h b/ef/Debugger/Communication/DebuggerChannel.h new file mode 100644 index 000000000000..b243bf876522 --- /dev/null +++ b/ef/Debugger/Communication/DebuggerChannel.h @@ -0,0 +1,146 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +// DebuggerChannel.h +// +// Scott M. Silver + +// A simple minded communication stream for +// the debugger pieces client/server + +#ifndef _H_DEBUGGERCHANNEL +#define _H_DEBUGGERCHANNEL + +#include "prio.h" +#include "prprf.h" +#include "Fundamentals.h" +#include "prlock.h" +#ifdef assert +#undef assert +#include +#endif + +#ifdef XP_PC +# include +#endif + +// FIX-ME endianness??? +struct DebuggerMessageRequest +{ + Int32 request; +}; + +struct DebuggerMessageResponse +{ + Int32 status; // 0 = succesful, non-zero is an error code +}; + +const Int32 kAddressToMethod = 120; +const Int32 kMethodToAddress = 121; +const Int32 kRequestNotifyMethodCompiledLoaded = 122; +const Int32 kNotifyMethodCompiledLoaded = 123; +const Int32 kRunClass = 124; +const Int32 kNotifyOnClassLoad = 125; +const Int32 kNotifyOnException = 126; +const Int32 kRequestDebuggerThread = 127; + +class NS_EXTERN DebuggerStream +{ + PRFileDesc* mFileDesc; + +public: + DebuggerStream(PRFileDesc* inCommChannel) : + mFileDesc(inCommChannel) { } + DebuggerStream() : + mFileDesc(0) { } + + void writeRequest(Int32 inRequest); + Int32 readRequest(); + void writeResponse(Int32 inStatus); + Int32 readResponse(); + + Int32 readLength(); // actual binary int32 + + void writeString(const char* inString); + char* readString(); // string must be deleted [] by callee + + void* readPtr(); + void writePtr(const void* inPtr); + + // r/w raw buffer dumping + void writeDataRaw(const void* inData, Int32 inLength); + void readDataRaw(void* outData, Int32 inLength); + + // r/w length preceded data + void writeData(const void* inData, Int32 inLength); + void* readData(); +}; + +#ifdef WIN32 +void NS_EXTERN setDebuggerThreadID(DWORD inThreadID); +DWORD NS_EXTERN getDebuggerThreadID(); +#define SET_DEBUGGER_THREAD_ID(inID) \ + PR_BEGIN_MACRO \ + setDebuggerThreadID(inID); \ + PR_END_MACRO +#else +#define SET_DEBUGGER_THREAD_ID(inID) \ + PR_BEGIN_MACRO \ + PR_END_MACRO +#endif + +const int kDebuggerPort = 8001; + +typedef void (*NotifyCompileOrLoadedMethodHandler)(const char*, void*); + +class NS_EXTERN DebuggerClientChannel +{ + DebuggerStream mSync; + DebuggerStream mAsync; + NotifyCompileOrLoadedMethodHandler mCompLoadHandler; + PRLock* mLock; + +public: + static DebuggerClientChannel* createClient(); + + char* requestAddressToMethod(const void* inAddress, Int32& outOffset); + void* requestMethodToAddress(const char* inMethodName); + void sendOneCharacterRequest(char inCharRequest); + void* requestDebuggerThread(); + Int32 requestNotifyOnMethodCompileLoad(const char* inMethodName); + Int32 requestRunClass(const char* inClassName); + Int32 requestNotifyOnClassLoad(const char* inClassName); + Int32 requestNotifyOnException(const char* inClassName); + + void setCompileOrLoadMethodHandler(NotifyCompileOrLoadedMethodHandler inHandler) { mCompLoadHandler = inHandler; } + +protected: + DebuggerClientChannel(PRFileDesc* inSync, PRFileDesc* inAsync); + + void handleCompileOrLoadedMethod(const char* inMethodName, void *inAddress) + { + if (mCompLoadHandler) + (*mCompLoadHandler)(inMethodName, inAddress); + } + + bool waitForAsyncRequest(); + static void asyncRequestThread(void* inThisPtr); + void handleAsyncRequest(Int32 inRequest); +}; + +#endif + diff --git a/ef/Debugger/Communication/Makefile b/ef/Debugger/Communication/Makefile new file mode 100644 index 000000000000..62db34043b65 --- /dev/null +++ b/ef/Debugger/Communication/Makefile @@ -0,0 +1,59 @@ +#!gmake +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +####################################################################### +# (1) Directory specific info # +####################################################################### + +DEPTH = ../.. + +LIBRARY_NAME = DebuggerChannel + +CPPSRCS = DebuggerChannel.cpp \ + $(NULL) + +EXPORTS = DebuggerChannel.h \ + $(NULL) + +LIBRARIES = libnspr21 \ + $(NULL) + +####################################################################### +# (2) Include "component" configuration information. # +####################################################################### + +include $(DEPTH)/config/config.mk + +####################################################################### +# (3) Include "local" platform-dependent assignments (OPTIONAL). # +####################################################################### + +ifeq ($(OS_ARCH),WINNT) +LDFLAGS += /ENTRY:DllEntryPoint kernel32.lib +endif + +####################################################################### +# (4) Execute "component" rules. (OPTIONAL) # +####################################################################### + +include $(DEPTH)/config/rules.mk + +####################################################################### +# (7) Execute "local" rules. (OPTIONAL). # +####################################################################### + +libs:: $(SHARED_LIBRARY) diff --git a/ef/Debugger/Communication/winbuild/DebuggerChannel.dsp b/ef/Debugger/Communication/winbuild/DebuggerChannel.dsp new file mode 100644 index 000000000000..fdcffa950902 --- /dev/null +++ b/ef/Debugger/Communication/winbuild/DebuggerChannel.dsp @@ -0,0 +1,82 @@ +# Microsoft Developer Studio Project File - Name="DebuggerChannel" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 5.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) External Target" 0x0106 + +CFG=DebuggerChannel - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "DebuggerChannel.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "DebuggerChannel.mak" CFG="DebuggerChannel - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "DebuggerChannel - Win32 Release" (based on\ + "Win32 (x86) External Target") +!MESSAGE "DebuggerChannel - Win32 Debug" (based on\ + "Win32 (x86) External Target") +!MESSAGE + +# Begin Project +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" + +!IF "$(CFG)" == "DebuggerChannel - Win32 Release" + +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Cmd_Line "NMAKE /f DebuggerChannel.mak" +# PROP BASE Rebuild_Opt "/a" +# PROP BASE Target_File "DebuggerChannel.exe" +# PROP BASE Bsc_Name "DebuggerChannel.bsc" +# PROP BASE Target_Dir "" +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Cmd_Line "gmake" +# PROP Rebuild_Opt "clean all" +# PROP Target_File "..\WINNT4.0_DBG.OBJ\libDebuggerChannel.dll" +# PROP Bsc_Name "..\WINNT4.0_DBG.OBJ\lDebuggerChannel.bsc" +# PROP Target_Dir "" + +!ELSEIF "$(CFG)" == "DebuggerChannel - Win32 Debug" + +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Cmd_Line "NMAKE /f DebuggerChannel.mak" +# PROP BASE Rebuild_Opt "/a" +# PROP BASE Target_File "DebuggerChannel.exe" +# PROP BASE Bsc_Name "DebuggerChannel.bsc" +# PROP BASE Target_Dir "" +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Cmd_Line "gmake" +# PROP Rebuild_Opt "clean all" +# PROP Target_File "..\WINNT4.0_DBG.OBJ\libDebuggerChannel.dll" +# PROP Bsc_Name "..\WINNT4.0_DBG.OBJ\lDebuggerChannel.bsc" +# PROP Target_Dir "" + +!ENDIF + +# Begin Target + +# Name "DebuggerChannel - Win32 Release" +# Name "DebuggerChannel - Win32 Debug" + +!IF "$(CFG)" == "DebuggerChannel - Win32 Release" + +!ELSEIF "$(CFG)" == "DebuggerChannel - Win32 Debug" + +!ENDIF + +# End Target +# End Project diff --git a/ef/Debugger/Communication/winbuild/DebuggerChannel.dsw b/ef/Debugger/Communication/winbuild/DebuggerChannel.dsw new file mode 100644 index 000000000000..8cacc3f2f44d --- /dev/null +++ b/ef/Debugger/Communication/winbuild/DebuggerChannel.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 5.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "DebuggerChannel"=.\DebuggerChannel.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/ef/Debugger/Communication/winbuild/Makefile b/ef/Debugger/Communication/winbuild/Makefile new file mode 100644 index 000000000000..4e931b6600aa --- /dev/null +++ b/ef/Debugger/Communication/winbuild/Makefile @@ -0,0 +1,20 @@ +#!gmake +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +all: + cd ..; gmake + diff --git a/ef/Debugger/Debugger.cpp b/ef/Debugger/Debugger.cpp new file mode 100644 index 000000000000..2bdbdfa3e5e4 --- /dev/null +++ b/ef/Debugger/Debugger.cpp @@ -0,0 +1,335 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#include +#include "CatchAssert.h" +#include "Debugger.h" +#include "jvmdi.h" +#include "LogModule.h" +#include "NativeCodeCache.h" +#include "DebuggerChannel.h" +#include "StringUtils.h" +#include "JavaVM.h" + +UT_DEFINE_LOG_MODULE(Debugger); + +DebuggerState::DebuggerState(Pool& p) : + pool(p), + enabled(false), + breakpoints(NULL) +{ +} + +DebuggerState::DebuggerState(Pool& p, bool _enabled) : pool(p) +{ + enabled = _enabled; + + if (enabled) + enable(); +} + +void +DebuggerState::enable() +{ + enabled = true; + breakpoints = new (pool) BreakPoint[MAX_BREAKPOINTS]; + + thread = DebuggerServerChannel::spawnServer(); + +#ifdef LINUX + // Set the breakpoint handler up. + SetupBreakPointHandler(); +#endif +} + +void +DebuggerState::waitForDebugger() +{ + if (thread) + PR_JoinThread(thread); +} + +static PRNetAddr sNetaddr; + +PRThread* DebuggerServerChannel:: +spawnServer() +{ + PRFileDesc* connector; + + // Create a TCP socket + if ((connector = PR_NewTCPSocket()) == NULL) + { + UT_LOG(Debugger, PR_LOG_DEBUG, ("Debugger: PR_NewTCPSocket failed\n")); + return (NULL); + } + + sNetaddr.inet.family = AF_INET; + sNetaddr.inet.port = htons(kDebuggerPort); + sNetaddr.inet.ip = htonl(INADDR_ANY); + + if (PR_Bind(connector, &sNetaddr) < 0) + { + UT_LOG(Debugger, PR_LOG_DEBUG, ("Debugger: PR_Bind failed\n")); + return (NULL); + } + + // Allow atmost 2 debugger connections + // 1 sync 1 async + if (PR_Listen(connector, 2) < 0) + { + UT_LOG(Debugger, PR_LOG_DEBUG, ("Debugger: PR_Listen failed\n")); + return (NULL); + } + + PRThread* thread; + + // Spawn the debugger listener thread + thread = PR_CreateThread(PR_USER_THREAD, + &serverThread, + connector, + PR_PRIORITY_NORMAL, + PR_GLOBAL_THREAD, + PR_JOINABLE_THREAD, + 0); + return (thread); +} + +void DebuggerServerChannel:: +serverThread(void* inArgument) +{ +#ifdef _WIN32 + SET_DEBUGGER_THREAD_ID(::GetCurrentThreadId()); +#endif + + PRFileDesc* connector = (PRFileDesc*) inArgument; + PRFileDesc* sync; + PRFileDesc* async; + + if (!(sync = PR_Accept(connector, &sNetaddr, PR_INTERVAL_NO_TIMEOUT))) + assert(false); + + if (!(async = PR_Accept(connector, &sNetaddr, PR_INTERVAL_NO_TIMEOUT))) + assert(false); + + + DebuggerServerChannel serverChannel(sync, async); + + serverChannel.serverLoop(); +} + + +void +DebuggerState:: clearAllBreakPoints() +{ + for (int i=0; i < MAX_BREAKPOINTS; i++) + breakpoints[i].clear(); +} + + + + +void DebuggerServerChannel:: +serverLoop() +{ + #define HELL_HAS_NOT_FROZEN_OVER 1 + + while (HELL_HAS_NOT_FROZEN_OVER) + { + Int32 request; + + request = mSync.readRequest(); + UT_LOG(Debugger, PR_LOG_DEBUG, ("command received: %c\n", (char) request)); + + switch(request) + { + case 'b': + JVMDI_SetBreakpoint(NULL, 0, 0, 0); + break; + case 'g': + // Not implemented + break; + case kAddressToMethod: + // request address to method + handleAddressToMethod(); + break; + case kMethodToAddress: + // request method to address + handleMethodToAddress(); + break; + case kRequestNotifyMethodCompiledLoaded: + handleNotifyOnCompileLoadMethod(); + break; + case kRunClass: + handleRunClass(); + break; + case 'q': + // Debugger thread quits + return; + default: + mSync.writeResponse(-1); + break; + } + } +} + +void +DebuggerState::setBreakPoint(void *pc) +{ +#ifdef LINUX + SetBreakPoint(pc); +#else + pc; +#endif +} + +void +DebuggerState::clearBreakPoint(void *pc) +{ + clearBreakPoint(pc); +} + +// Access to the database of classes +#include "ClassWorld.h" +#include "StringPool.h" +extern ClassWorld world; +extern StringPool sp; + +void DebuggerServerChannel:: +handleAddressToMethod() +{ + DEBUG_TRACER(UT_LOG_MODULE(Debugger), "handleAddressToMethod"); + + void* address; + CacheEntry* ce; + + address = mSync.readPtr(); + ce = NativeCodeCache::getCache().lookupByRange((Uint8*) address); + + if (ce) { + mSync.writeResponse(0); + mSync.writeString(ce->descriptor.method->toString()); + mSync.writePtr((void*)((Uint8*) address - ce->start.getFunctionAddress())); + } + else + mSync.writeResponse(-1); +} + +void DebuggerServerChannel:: +handleMethodToAddress() +{ + DEBUG_TRACER(UT_LOG_MODULE(Debugger), "handleMethodToAddress"); + char* methodName; + const char* internedMethodName; + + // lookup method name in string pool (getMethod requires interned string) + internedMethodName = sp.get(methodName = mSync.readString()); + delete [] methodName; + + + if (internedMethodName) { + Method* method; + + // now grab the method + if (world.getMethod(internedMethodName, method)) { + // lookup method in cache + MethodDescriptor methodDescriptor(*method); + + void* address = addressFunction(NativeCodeCache::getCache().lookupByDescriptor(methodDescriptor, true, true)); + if (address) { + mSync.writeResponse(0); + mSync.writePtr(address); + return; + } + } + } + + // if we fall-through the method was not found + mSync.writeResponse(-1); +} + +Vector sNotifyList; + +void DebuggerServerChannel:: +handleNotifyOnCompileLoadMethod() +{ + DEBUG_TRACER(UT_LOG_MODULE(Debugger), "handleNotifyOnCompileLoadMethod"); + char* methodName = mSync.readString(); + + sNotifyList.append(methodName); // methodName is new'ed for us by DebuggerChannel + + mSync.writeResponse(0); +} + +void executeClass(void *inArgument); + +void executeClass(void *inArgument) +{ + char* className = (char*) inArgument; + VM::theVM.execute(className, NULL, NULL, NULL, 0); +} + + +void DebuggerServerChannel:: +handleRunClass() +{ + DEBUG_TRACER(UT_LOG_MODULE(Debugger), "handleRunClass"); + + char* className = mSync.readString(); + PRThread* thread; + + // do not tie up this thread -- because we + // we need this one for communication + thread = PR_CreateThread(PR_USER_THREAD, + &executeClass, + className, + PR_PRIORITY_NORMAL, + PR_GLOBAL_THREAD, + PR_JOINABLE_THREAD, + 0); + + mSync.writeResponse(thread ? 0 : -1); // return -1 if couldn't create thread + + // FIX-ME leak className because too lazy + // to make sure thread makes its own copy + //delete [] className; +} + +void DebuggerServerChannel:: +listenToMessage(BroadcastEventKind inKind, void* inArgument) +{ + if (inKind == kEndCompileOrLoad) { + assert(inArgument); + Method& method = *(Method*) inArgument; + + char** curPos; + for (curPos = sNotifyList.begin(); curPos < sNotifyList.end(); curPos++) + if (!PL_strcmp(*curPos, method.toString())) { + mAsync.writeRequest(kNotifyMethodCompiledLoaded); + mAsync.writeString(*curPos); + + MethodDescriptor methodDescriptor(method); + void* address = addressFunction(NativeCodeCache::getCache().lookupByDescriptor(methodDescriptor, true, true)); + assert(address); + mAsync.writePtr(address); + + // now wait for a response + assert(!mAsync.readResponse()); + break; + } + } +} diff --git a/ef/Debugger/Debugger.h b/ef/Debugger/Debugger.h new file mode 100644 index 000000000000..f1767bb22a56 --- /dev/null +++ b/ef/Debugger/Debugger.h @@ -0,0 +1,128 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#ifndef _DEBUGGER_H_ +#define _DEBUGGER_H_ + +#include "nspr.h" +#include "Pool.h" +#include "InterestingEvents.h" +#include "DebuggerChannel.h" + +#define MAX_BREAKPOINTS 10 + +// The BreakPoint class holds the +class NS_EXTERN BreakPoint { + Uint32 pc; // The address of the instruction + Uint64 old_instruction; // Saved copy of the instruction + bool enabled; // Whether it's enabled + + public: + void clear() { pc = 0; enabled = false; }; +}; + +class DebuggerChannel; + +// +// The debugger object holds the current state of the debugger +class NS_EXTERN DebuggerState { + BreakPoint *breakpoints; // Breakpoints + Int32 nbreakpoints; // number of breakpoints set so far + bool enabled; // Was -debug flag passed ? + Pool &pool; // All memory allocations + PRThread *thread; // The debugger thread + +public: + void setBreakPoint(void *pc); + getBreakPoints(); + void clearBreakPoint(void *pc); + void clearAllBreakPoints(); + + // Constructors + DebuggerState(Pool& p); + DebuggerState(Pool&p, bool _enabled); + + // Enabled ? + void enable(); + bool getEnabled() { return enabled; }; + PRThread *getThread() { return thread; }; + static void eventHandler(void *arg); + void waitForDebugger(); + + static void handleAddressToMethod(DebuggerChannel& inChannel); + static void handleMethodToAddress(DebuggerChannel& inChannel); +}; + +// Takes a pc offset from the beginning of a method and converts it to a +// bytecode offset, +class pcToByteCodeTable { + // A dumb implementation to start with. Space can be saved by storing + // this as a range + Int32 *table; + Int32 nEntries; + public: + pcToByteCodeTable() { table = NULL; nEntries = 0; }; + // XXX - memory leak. Need to use a pool. + pcToByteCodeTable(Int32 size) { table = new Int32[size]; nEntries = size; }; + void setSize(Int32 size); + Int32 operator [](Int32 pcOffset) const { return table[pcOffset]; }; +}; + +class DebuggerServerChannel : + EventListener +{ + DebuggerStream mSync; + DebuggerStream mAsync; + +public: + static PRThread* spawnServer(); + virtual void listenToMessage(BroadcastEventKind inKind, void* inArgument); + +protected: + DebuggerServerChannel(PRFileDesc* inSync, PRFileDesc* inAsync) : + EventListener(gCompileOrLoadBroadcaster), + mAsync(inAsync), + mSync(inSync) { } + + void handleRequest(Int32 inRequest); + void handleMethodToAddress(); + void handleRequestDebuggerThread(); + void handleAddressToMethod(); + void handleNotifyOnCompileLoadMethod(); + void handleRunClass(); + + static void serverThread(void*); + void serverLoop(); +}; + + +// Platform specific stuff +int SetBreakPoint(void *code); + +#ifndef WIN32 +void SetupBreakPointHandler(); +#endif + +inline void +pcToByteCodeTable::setSize(Int32 size) +{ + assert(table == NULL); + table = new Int32[size]; + nEntries = size; +} + +#endif /* _DEBUGGER_H_ */ diff --git a/ef/Debugger/LinuxBreakPoint.cpp b/ef/Debugger/LinuxBreakPoint.cpp new file mode 100644 index 000000000000..db21d6a391b6 --- /dev/null +++ b/ef/Debugger/LinuxBreakPoint.cpp @@ -0,0 +1,63 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#include +#include +#include + +int old_instruction; + +int +SetBreakPoint(void *pc) +{ + old_instruction = *((unsigned char *) pc); + *((unsigned char *) pc) = 0xcc; /* break point opcode */ +#ifdef DEBUG + fprintf(stderr, "breakpoint at: %x\n", (unsigned int) pc); +#endif + /* Need to flush icache here */ + return old_instruction; +} + +extern "C" void +sigtrap_handler(int sig, struct sigcontext_struct context) +{ +#ifdef DEBUG + fprintf(stderr, "Handler: Restoring old instruction\n"); + fprintf(stderr, "ip: %x\n", (unsigned int) context.eip); +#endif + + /* Learnt this the hard way. eip points to the next instruction */ + (*((unsigned char *) (context.eip -1))) = old_instruction; + context.eip = context.eip - 1; + + /* Send a debugger event and do all kinds of things */ + + return; +} + +void +SetupBreakPointHandler() +{ + struct sigaction sigtrap_action; + + sigemptyset(&sigtrap_action.sa_mask); + sigtrap_action.sa_flags = 0; + sigtrap_action.sa_handler = (__sighandler_t) sigtrap_handler; + + sigaction(SIGTRAP, &sigtrap_action, NULL); +} diff --git a/ef/Debugger/Makefile b/ef/Debugger/Makefile new file mode 100644 index 000000000000..ead8ceac30d0 --- /dev/null +++ b/ef/Debugger/Makefile @@ -0,0 +1,73 @@ +#!gmake +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +####################################################################### +# (1) Directory specific info # +####################################################################### + +DEPTH = .. + +MODULE_NAME = EF + +DIRS = Communication + +CPPSRCS = Debugger.cpp \ + jvmdi.cpp \ + $(NULL) + + +LOCAL_EXPORTS = Debugger.h \ + jvmdi.h \ + $(NULL) + +NO_PROGRAM_IN_SUBDIRS = 1 +NO_INSTALL_IN_SUBDIRS = 1 + +####################################################################### +# (2) Include "component" configuration information. # +####################################################################### + +include $(DEPTH)/config/config.mk + +####################################################################### +# (3) Include "local" platform-dependent assignments (OPTIONAL). # +####################################################################### + +# +# OS-specific include files +# + +ifeq ($(OS_ARCH),Linux) + CPPSRCS += LinuxBreakPoint.cpp $(NULL) +else + ifeq ($(OS_ARCH),WINNT) + CPPSRCS += Win32BreakPoint.cpp + endif +endif + +####################################################################### +# (4) Execute "component" rules. (OPTIONAL) # +####################################################################### + +include $(DEPTH)/config/rules.mk + +####################################################################### +# (7) Execute "local" rules. (OPTIONAL). # +####################################################################### + + + diff --git a/ef/Debugger/Win32BreakPoint.cpp b/ef/Debugger/Win32BreakPoint.cpp new file mode 100644 index 000000000000..f42e9a9b32e6 --- /dev/null +++ b/ef/Debugger/Win32BreakPoint.cpp @@ -0,0 +1,58 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#include +#include "Fundamentals.h" +#include + +unsigned char old_instruction; + +extern "C" int +SetBreakPoint(void *pc) +{ + old_instruction = (*((unsigned char *) pc)); + *((unsigned char *) pc) = 0xcc; /* break point opcode */ + fprintf(stderr, "breakpoint at: %x\n", pc); + fprintf(stderr, "value: %x\n", &old_instruction); + /* Need to flush icache here */ + return 0; +} + +__declspec(dllexport) EXCEPTION_DISPOSITION __cdecl +_arun_handler(struct _EXCEPTION_RECORD + *ExceptionRecord, + void * EstablisherFrame, + struct _CONTEXT *ContextRecord, + void * DispatcherContext ) + +{ + // Indicate that we made it to our exception handler + fprintf(stderr, "Faulted with: 0x%x\n",ExceptionRecord->ExceptionCode); + // Change EIP in the context record so that it points to someplace + // where we can successfully continue + switch (ExceptionRecord->ExceptionCode) { + case STATUS_BREAKPOINT: + fprintf(stderr, "Restoring the instruction at %x\n", + ContextRecord->Eip); + (*(unsigned char *) (ContextRecord->Eip)) = old_instruction; + fprintf(stderr, "Restored: %x\n", old_instruction); + // Reexecute the same instruction + return ExceptionContinueExecution; + default: + return ExceptionContinueSearch; + } +} diff --git a/ef/Debugger/debug_test/Makefile b/ef/Debugger/debug_test/Makefile new file mode 100644 index 000000000000..f660ca6046b7 --- /dev/null +++ b/ef/Debugger/debug_test/Makefile @@ -0,0 +1,46 @@ +#!gmake +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +# Makefile for the debugger + +DIRS = ../Communication +DEPTH = ../.. + +CXXSRCS = \ + debug_test.cpp \ + $(NULL) + +PROGRAM_NAME = debug_test + +include $(DEPTH)/config/rules.mk + +INCLUDES += \ + -I .. \ + -I $(DEPTH)/Exports \ + -I $(DEPTH)/Exports/md \ + -I $(DEPTH)/Utilities/General \ + -I $(DEPTH)/Debugger/Communication + +ifeq ($(OS_ARCH),Linux) +LDFLAGS += -L $(DIST)/lib -L$(DEPTH)/Utilities/zlib/$(OBJDIR) +EXTRA_LIBS = -lg++ -lnspr21 -lplc21 -lEF -lzlib +endif + +ifeq ($(OS_ARCH),WINNT) +CXXFLAGS += /Fr +EXTRA_LIBS += $(DIST)/lib/libDebuggerChannel.lib $(DIST)/lib/libnspr21.lib $(DIST)/lib/libplc21.lib wsock32.lib +endif diff --git a/ef/Debugger/debug_test/debug_test.cpp b/ef/Debugger/debug_test/debug_test.cpp new file mode 100644 index 000000000000..f07afc74cc77 --- /dev/null +++ b/ef/Debugger/debug_test/debug_test.cpp @@ -0,0 +1,163 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#include +#include +#include "nspr.h" +#include "debug_test.h" +#include "DebuggerChannel.h" + +class +DebuggerClientChannel* gChannel; + + +void +DebuggerEvent::sendCommand(DebuggerClientChannel& inChannel) +{ + inChannel.sendOneCharacterRequest(cmd); +} + +void +RemoteAgent::init() +{ + // Do nothing +} + +void +RemoteAgent::SendEvent(DebuggerEvent& d) +{ + // Do socket stuff here + + cout << "Writing: " << d.cmd << endl; + d.sendCommand(*gChannel); +} + +#ifdef __GNUC__ +// for gcc with -fhandle-exceptions +void terminate() {} +#endif + +void +printMenu() +{ + cout << "b for breakpoint" << endl; + cout << "g for go!" << endl; + cout << "q for quit" << endl; +} + +void +sayLoadedMethod(const char* inName, void* inAddress) +{ + printf("Loaded/Compiled %s at %p\n", inName, inAddress); +} + +void realMain(void*); + +int +main(int argc, char *argv[]) +{ + PRThread* thread; + + thread = PR_CreateThread(PR_USER_THREAD, + realMain, + NULL, + PR_PRIORITY_NORMAL, + PR_GLOBAL_THREAD, + PR_JOINABLE_THREAD, + 0); + + PR_JoinThread(thread); + return (0); +} + +void realMain(void*) +{ + char c; + + if (!(gChannel = DebuggerClientChannel::createClient())) { + fprintf(stderr, "failed to connect to local host on debugger port\n"); + exit(-1); + } + + gChannel->setCompileOrLoadMethodHandler(sayLoadedMethod); + + while(1) { + // print a menu of commands + printMenu(); + + // read a character + + cin >> c; + cout << "read: " << c << endl; + + switch(c) { + DebuggerEvent* de; + + case 'b': + // Make up a breakpoint event + de = new DebuggerEvent('b'); + RemoteAgent::SendEvent(*de); + break; + case 'g': + // Make up a continue event + de = new DebuggerEvent('g'); + RemoteAgent::SendEvent(*de); + break; + case 'q': + // Make up a continue event + de = new DebuggerEvent('q'); + RemoteAgent::SendEvent(*de); + // Flag success + exit(0); + break; + case 'a': + { + Int32 offset; + char *methodName = gChannel->requestAddressToMethod((void*) 0x1623fa8, offset); + if (methodName) + printf("got Method: %s + %d\n", methodName, offset); + else + printf("unknown address\n"); + break; + } + case 'm': + { + void* address = gChannel->requestMethodToAddress("static private void java.lang.System.initializeSystemClass()"); + if (address) + printf("got Method: %p\n", address); + else + printf("unknown method\n"); + break; + } + case 'n': + { + const char* method = "public java.lang.Object javasoft.sqe.tests.api.java.lang.System.SystemTests11.check(suntest.quicktest.runtime.QT_Reporter,java.lang.Object[])"; + gChannel->requestNotifyOnMethodCompileLoad(method); +//"static private void java.lang.System.initializeSystemClass()"); + break; + } + case 'r': + { + gChannel->requestRunClass("javasoft/sqe/tests/api/java/lang/System/SystemTests10"); + } + default: + cerr << "Unknown command" << endl; + break; + } + } +} diff --git a/ef/Debugger/debug_test/debug_test.h b/ef/Debugger/debug_test/debug_test.h new file mode 100644 index 000000000000..75edcc977d62 --- /dev/null +++ b/ef/Debugger/debug_test/debug_test.h @@ -0,0 +1,48 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#ifndef _DEBUG_TEST_H_ +#define _DEBUG_TEST_H_ + +#include "jvmdi.h" +#include "prio.h" + +class DebuggerClientChannel; + +class DebuggerEvent { + JVMDI_Event jvmdi_event; // The real event + +public: + char cmd; // Dummy command used for testing + DebuggerEvent(char inCmd) : + cmd(inCmd) { } + + // A whole bunch of methods + virtual void sendCommand(DebuggerClientChannel& inChannel); + + int getType() { + return jvmdi_event.kind; + }; +}; + +class RemoteAgent { + public: + static void init(); + static void SendEvent(DebuggerEvent& d); +}; + +#endif /* _DEBUG_TEST_H_ */ diff --git a/ef/Debugger/jvmdi.cpp b/ef/Debugger/jvmdi.cpp new file mode 100644 index 000000000000..bb5863f1a4c1 --- /dev/null +++ b/ef/Debugger/jvmdi.cpp @@ -0,0 +1,587 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#include "JavaVM.h" +#include "Debugger.h" +#include "jvmdi.h" +#include "NativeCodeCache.h" +#include "Thread.h" + +extern "C" { + +static JVMDI_EventHook eventHook; + +/* + * Return via "statusPtr" the status of the thread as one of + * JVMDI_THREAD_STATUS_*. + * Errors: JVMDI_ERROR_INVALID_THREAD, JVMDI_ERROR_NULL_POINTER + */ +JNIEXPORT JNICALL(jvmdiError) +JVMDI_GetThreadStatus(JNIEnv * /* env */, jthread thread, jint *statusPtr) +{ + if (statusPtr == NULL) { + return JVMDI_ERROR_NULL_POINTER; + } + + Thread::JavaThread *jt = (Thread::JavaThread *) thread; + Thread *t = (Thread*)static_cast(jt->eetop); + + *statusPtr = t->getStatus(); + + return JVMDI_ERROR_NONE; +} + +/* Note: jvm.h has suspend/resume (which may be deprecated - as + * Thread.suspend() has been). JVMDI version is different, as it + * takes precautions to attempt to avoid deadlock. Also it + * cannot be depreciated. + */ +/* + * Suspend the specified thread. + * Errors: JVMDI_ERROR_INVALID_THREAD, JVMDI_ERROR_THREAD_SUSPENDED, + * JVMDI_ERROR_VM_DEAD + */ +JNIEXPORT JNICALL(jvmdiError) +JVMDI_SuspendThread(JNIEnv * /*env*/, jthread thread) +{ + Thread::JavaThread *jt = (Thread::JavaThread *) thread; + Thread *t = (Thread*)static_cast(jt->eetop); + + t->suspend(); + + return JVMDI_ERROR_NONE; +} + +/* + * Resume the specified thread. + * Errors: JVMDI_ERROR_INVALID_THREAD, JVMDI_ERROR_THREAD_NOT_SUSPENDED, + * JVMDI_ERROR_VM_DEAD + */ +JNIEXPORT JNICALL(jvmdiError) +JVMDI_ResumeThread(JNIEnv * /*env*/, jthread thread) +{ + Thread::JavaThread *jt = (Thread::JavaThread *) thread; + Thread *t = (Thread*)static_cast(jt->eetop); + + t->resume(); + + return JVMDI_ERROR_NONE; +} + +/* + * If shouldStep is true cause the thread to generate a + * JVMDI_EVENT_SINGLE_STEP event with each byte-code executed. + * Errors: JVMDI_ERROR_INVALID_THREAD, + * JVMDI_ERROR_THREAD_NOT_SUSPENDED (should suspension be a requirement?), + * JVMDI_ERROR_VM_DEAD + */ +JNIEXPORT JNICALL(jvmdiError) +JVMDI_SetSingleStep(JNIEnv * /*env*/, jthread thread, jboolean shouldStep) +{ + Thread::JavaThread *jt = (Thread::JavaThread *) thread; + + jt->single_step = shouldStep; + + return JVMDI_ERROR_NONE; +} + + + +/* + * Thread Groups + */ + +/* + * Return in 'groupsPtr' an array of top-level thread groups (parentless + * thread groups). + * Note: array returned via 'groupsPtr' is allocated globally and must be + * explictly freed with DeleteGlobalRef. + * Errors: JVMDI_ERROR_NULL_POINTER, JVMDI_ERROR_OUT_OF_MEMORY + */ +JNIEXPORT JNICALL(jvmdiError) +JVMDI_GetTopThreadGroups(JNIEnv * /*env*/, jobjectArray * /*groupsPtr*/) +{ + return JVMDI_ERROR_NOT_IMPLEMENTED; +} + + +/* + * Return in 'threadsPtr' an array of the threads within the specified + * thread group. + * Note: array returned via 'threadsPtr' is allocated globally and must be + * explictly freed with DeleteGlobalRef. + * Errors: JVMDI_ERROR_INVALID_THREAD_GROUP, JVMDI_ERROR_NULL_POINTER, + * JVMDI_ERROR_OUT_OF_MEMORY + */ +JNIEXPORT JNICALL(jvmdiError) +JVMDI_GetGroupsThreads(JNIEnv * /*env*/, jthreadGroup /*group*/, + jobjectArray * /*threadsPtr*/) +{ + return JVMDI_ERROR_NOT_IMPLEMENTED; +} + +/* + * Return in 'groupsPtr' an array of the thread groups within the + * specified thread group. + * Note: array returned via 'groupsPtr' is allocated globally and must be + * explictly freed with DeleteGlobalRef. + * Errors: JVMDI_ERROR_INVALID_THREAD_GROUP, JVMDI_ERROR_NULL_POINTER, + * JVMDI_ERROR_OUT_OF_MEMORY + */ +JNIEXPORT JNICALL(jvmdiError) +JVMDI_GetGroupsThreadGroups(JNIEnv * /*env*/, jthreadGroup /*group*/, + jobjectArray * /*groupsPtr*/) +{ + return JVMDI_ERROR_NOT_IMPLEMENTED; +} + + +/* + * Suspend all threads recursively contained in the thread group, + * except the specified threads. + * If except is NULL suspend all threads in group. + * Errors: JVMDI_ERROR_INVALID_THREAD_GROUP, JVMDI_ERROR_INVALID_THREAD + */ +JNIEXPORT JNICALL(jvmdiError) +JVMDI_SuspendThreadGroup(JNIEnv * /*env*/, jthreadGroup /*group*/, + jobjectArray /*except*/) +{ + return JVMDI_ERROR_NOT_IMPLEMENTED; +} + + +/* + * Resume all threads (recursively) in the thread group, except the + * specified threads. If except is NULL resume all threads in group. + * Errors: JVMDI_ERROR_INVALID_THREAD_GROUP, JVMDI_ERROR_INVALID_THREAD + */ +JNIEXPORT JNICALL(jvmdiError) +JVMDI_ResumeThreadGroup(JNIEnv * /*env*/, jthreadGroup /*group*/, jobjectArray /*except*/) +{ + return JVMDI_ERROR_NOT_IMPLEMENTED; +} + + +/* + * Stack access + */ + +/* + * Return via "framePtr" the frame ID for the current stack frame + * of this thread. Thread must be suspended. Only Java and + * Java native frames are returned. FrameIDs become invalid if + * the frame is resumed. + * Errors: JVMDI_ERROR_NO_MORE_FRAMES, JVMDI_ERROR_INVALID_THREAD, + * JVMDI_ERROR_THREAD_NOT_SUSPENDED, JVMDI_ERROR_NULL_POINTER + */ +JNIEXPORT JNICALL(jvmdiError) +JVMDI_GetCurrentFrame(JNIEnv * /*env*/, jthread /*thread*/, jframeID* framePtr) +{ + if (framePtr == NULL) { + return JVMDI_ERROR_NULL_POINTER; + } + + return JVMDI_ERROR_NONE; +} + + +/* + * Return via "framePtr" the frame ID for the stack frame that called + * the specified frame. Only Java and Java native frames are returned. + * Errors: JVMDI_ERROR_NO_MORE_FRAMES, JVMDI_ERROR_INVALID_FRAMEID, + * JVMDI_ERROR_NULL_POINTER + */ +JNIEXPORT JNICALL(jvmdiError) +JVMDI_GetCallerFrame(JNIEnv * /* env */, jframeID /* called*/, jframeID * /*framePtr*/) +{ + // Use code from the stackwalker here + return JVMDI_ERROR_NOT_IMPLEMENTED; +} + + +/* + * Return via "classPtr" and "methodPtr" the active method in the + * specified frame. + * Note: class returned via 'classPtr' is allocated globally and must be + * explictly freed with DeleteGlobalRef. + * Errors: JVMDI_ERROR_INVALID_FRAMEID, JVMDI_ERROR_NULL_POINTER + * JVMDI_ERROR_INVALID_FRAMEID, JVMDI_ERROR_OUT_OF_MEMORY + */ +JNIEXPORT JNICALL(jvmdiError) +JVMDI_GetFrameMethod(JNIEnv * /*env*/, jframeID /*frame*/, + jclass * /*classPtr*/, jmethodID * /*methodPtr*/) +{ + // Use code from the stackwalker here + return JVMDI_ERROR_NOT_IMPLEMENTED; +} + + +/* + * Return via "bciPtr" the byte-code index within the active method of + * the specified frame. This is the index of the currently executing + * instruction. + * Errors: JVMDI_ERROR_INVALID_FRAMEID, JVMDI_ERROR_NATIVE_FRAME, + * JVMDI_ERROR_NULL_POINTER + */ +JNIEXPORT JNICALL(jvmdiError) +JVMDI_GetFrameBCI(JNIEnv * /*env*/, jframeID /*frame*/, jint * /*bciPtr*/) +{ + return JVMDI_ERROR_NOT_IMPLEMENTED; +} + + +/* + * Local variables + */ + +/* + * Return via "valuePtr" the value of the local variable at the + * specificied slot. + * Note: object returned via 'valuePtr' is allocated globally and must be + * explictly freed with DeleteGlobalRef. + * Errors: JVMDI_ERROR_INVALID_FRAMEID, JVMDI_ERROR_INVALID_SLOT, + * JVMDI_ERROR_TYPE_MISMATCH, JVMDI_ERROR_NULL_POINTER, + * JVMDI_ERROR_NATIVE_FRAME, JVMDI_ERROR_OUT_OF_MEMORY + */ +JNIEXPORT JNICALL(jvmdiError) +JVMDI_GetLocalObject(JNIEnv * /*env*/, jframeID /*frame*/, jint /*slot*/, + jobject * /*valuePtr*/) +{ + return JVMDI_ERROR_NOT_IMPLEMENTED; +} + + +/* + * Return via "valuePtr" the value of the local variable at the + * specificied slot. + * Errors: JVMDI_ERROR_INVALID_FRAMEID, JVMDI_ERROR_INVALID_SLOT, + * JVMDI_ERROR_TYPE_MISMATCH, JVMDI_ERROR_NULL_POINTER, + * JVMDI_ERROR_NATIVE_FRAME + */ +JNIEXPORT JNICALL(jvmdiError) +JVMDI_GetLocalInt(JNIEnv * /*env*/, jframeID /*frame*/, jint /*slot*/, + jint * /*valuePtr*/) +{ + return JVMDI_ERROR_NOT_IMPLEMENTED; +} + + +/* + * Return via "valuePtr" the value of the local variable at the + * specificied slot. + * Errors: JVMDI_ERROR_INVALID_FRAMEID, JVMDI_ERROR_INVALID_SLOT, + * JVMDI_ERROR_TYPE_MISMATCH, JVMDI_ERROR_NULL_POINTER, + * JVMDI_ERROR_NATIVE_FRAME + */ +JNIEXPORT JNICALL(jvmdiError) +JVMDI_GetLocalLong(JNIEnv * /*env*/, jframeID /*frame*/, jint /*slot*/, + jlong * /*valuePtr*/) +{ + return JVMDI_ERROR_NOT_IMPLEMENTED; +} + + +/* + * Return via "valuePtr" the value of the local variable at the + * specificied slot. + * Errors: JVMDI_ERROR_INVALID_FRAMEID, JVMDI_ERROR_INVALID_SLOT, + * JVMDI_ERROR_TYPE_MISMATCH, JVMDI_ERROR_NULL_POINTER, + * JVMDI_ERROR_NATIVE_FRAME + */ +JNIEXPORT JNICALL(jvmdiError) +JVMDI_GetLocalFloat(JNIEnv * /*env*/, jframeID /*frame*/, jint /*slot*/, + jfloat * /*valuePtr*/) +{ + return JVMDI_ERROR_NOT_IMPLEMENTED; +} + + +/* + * Return via "valuePtr" the value of the local variable at the + * specificied slot. + * Errors: JVMDI_ERROR_INVALID_FRAMEID, JVMDI_ERROR_INVALID_SLOT, + * JVMDI_ERROR_TYPE_MISMATCH, JVMDI_ERROR_NULL_POINTER, + * JVMDI_ERROR_NATIVE_FRAME + */ +JNIEXPORT JNICALL(jvmdiError) +JVMDI_GetLocalDouble(JNIEnv * /*env*/, jframeID /*frame*/, jint /*slot*/, + jdouble * /*valuePtr*/) +{ + return JVMDI_ERROR_NOT_IMPLEMENTED; +} + + +/* + * Set the value of the local variable at the specificied slot. + * Errors: JVMDI_ERROR_INVALID_FRAMEID, JVMDI_ERROR_INVALID_SLOT, + * JVMDI_ERROR_TYPE_MISMATCH, JVMDI_ERROR_NATIVE_FRAME + */ +JNIEXPORT JNICALL(jvmdiError) +JVMDI_SetLocalObject(JNIEnv * /*env*/, jframeID /*frame*/, jint /*slot*/, jobject /*value*/) +{ + return JVMDI_ERROR_NOT_IMPLEMENTED; +} + + +/* + * Set the value of the local variable at the specificied slot. + * Errors: JVMDI_ERROR_INVALID_FRAMEID, JVMDI_ERROR_INVALID_SLOT, + * JVMDI_ERROR_TYPE_MISMATCH, JVMDI_ERROR_NATIVE_FRAME + */ +JNIEXPORT JNICALL(jvmdiError) +JVMDI_SetLocalInt(JNIEnv * /*env*/, jframeID /*frame*/, jint /*slot*/, jint /*value*/) +{ + return JVMDI_ERROR_NOT_IMPLEMENTED; +} + + +/* + * Set the value of the local variable at the specificied slot. + * Errors: JVMDI_ERROR_INVALID_FRAMEID, JVMDI_ERROR_INVALID_SLOT, + * JVMDI_ERROR_TYPE_MISMATCH, JVMDI_ERROR_NATIVE_FRAME + */ +JNIEXPORT JNICALL(jvmdiError) +JVMDI_SetLocalLong(JNIEnv * /*env*/, jframeID /*frame*/, jint /*slot*/, jlong /*value*/) +{ + return JVMDI_ERROR_NOT_IMPLEMENTED; +} + + +/* + * Set the value of the local variable at the specificied slot. + * Errors: JVMDI_ERROR_INVALID_FRAMEID, JVMDI_ERROR_INVALID_SLOT, + * JVMDI_ERROR_TYPE_MISMATCH, JVMDI_ERROR_NATIVE_FRAME + */ +JNIEXPORT JNICALL(jvmdiError) +JVMDI_SetLocalFloat(JNIEnv * /*env*/, jframeID /*frame*/, jint /*slot*/, jfloat /*value*/) +{ + return JVMDI_ERROR_NOT_IMPLEMENTED; +} + + +/* + * Set the value of the local variable at the specificied slot. + * Errors: JVMDI_ERROR_INVALID_FRAMEID, JVMDI_ERROR_INVALID_SLOT, + * JVMDI_ERROR_TYPE_MISMATCH, JVMDI_ERROR_NATIVE_FRAME + */ +JNIEXPORT JNICALL(jvmdiError) +JVMDI_SetLocalDouble(JNIEnv * /*env*/, jframeID /*frame*/, jint /*slot*/, jdouble /*value*/) +{ + return JVMDI_ERROR_NOT_IMPLEMENTED; +} + + +/* + * Breakpoints + */ + +/* + * Set a breakpoint. Send a JVMDI_EVENT_BREAKPOINT event when the + * instruction at the specified byte-code index in the specified + * method is about to be executed. + * Errors: JVMDI_ERROR_INVALID_METHODID, JVMDI_ERROR_INVALID_CLASS, + * JVMDI_ERROR_INVALID_BCI, JVMDI_ERROR_DUPLICATE_BREAKPOINT, + * JVMDI_ERROR_VM_DEAD, JVMDI_ERROR_OUT_OF_MEMORY + */ +JNIEXPORT JNICALL(jvmdiError) +JVMDI_SetBreakpoint(JNIEnv * /*env*/, jclass /* clazz */, + jmethodID method, jint /*bci*/) +{ + CacheEntry* ce; + ce = NativeCodeCache::getCache().lookupByRange((Uint8*) method); + + if (ce == NULL) { + /* either the method is not compiled - in which case compile it */ + return JVMDI_ERROR_INVALID_METHODID; + } + + void *code = addressFunction(ce->descriptor.method->getCode()); + + if (code == NULL) { + return JVMDI_ERROR_INVALID_METHODID; + } // else if (code == stub) compile and then break; + + // Convert the bci to a pc offset and add it to code + + VM::debugger.setBreakPoint(code); + + return JVMDI_ERROR_NONE; +} + + +/* + * Clear a breakpoint. + * Errors: JVMDI_ERROR_INVALID_METHODID, JVMDI_ERROR_INVALID_CLASS, + * JVMDI_ERROR_INVALID_BCI, JVMDI_ERROR_NO_SUCH_BREAKPOINT, + * JVMDI_ERROR_VM_DEAD + */ +JNIEXPORT JNICALL(jvmdiError) +JVMDI_ClearBreakpoint(JNIEnv * /*env*/, jclass /*clazz*/, jmethodID /*method*/, jint /*bci*/) +{ + return JVMDI_ERROR_NOT_IMPLEMENTED; +} + + +/* + * Clear all breakpoints. + * Errors: JVMDI_ERROR_VM_DEAD + */ +JNIEXPORT JNICALL(jvmdiError) +JVMDI_ClearAllBreakpoints(JNIEnv * /*env*/) +{ + VM::debugger.clearAllBreakPoints(); + + return JVMDI_ERROR_NONE; +} + + +/* + * Set the routine which will handle in-coming events. + * Passing NULL as hook unsets hook. + */ +JNIEXPORT JNICALL(jvmdiError) +JVMDI_SetEventHook(JNIEnv * /*env*/, JVMDI_EventHook hook) +{ + eventHook = hook; + + return JVMDI_ERROR_NONE; +} + + + +/* + * Method access + */ + +/* + * Return via "namePtr" the method's name and via "signaturePtr" the + * method's signature. + * Note: strings returned via 'namePtr' and 'signaturePtr' are + * allocated globally and must be explictly freed with DeleteGlobalRef. + * Errors: JVMDI_ERROR_INVALID_METHODID, JVMDI_ERROR_INVALID_CLASS, + * JVMDI_ERROR_NULL_POINTER, JVMDI_ERROR_OUT_OF_MEMORY + */ +JNIEXPORT JNICALL(jvmdiError) +JVMDI_GetMethodName(JNIEnv * env, jclass /*clazz*/, jmethodID method, + jstring *namePtr, jstring *signaturePtr) +{ + CacheEntry* ce; + ce = NativeCodeCache::getCache().lookupByRange((Uint8*) method); + + if (namePtr == NULL || signaturePtr == NULL) { + return JVMDI_ERROR_NULL_POINTER; + } + if (ce == NULL) { + return JVMDI_ERROR_INVALID_METHODID; + } + + *namePtr = (jstring) env->NewGlobalRef( + env->NewStringUTF(ce->descriptor.method->toString())); + *signaturePtr = (jstring) env->NewGlobalRef( + env->NewStringUTF(ce->descriptor.method->getSignatureString())); + + return JVMDI_ERROR_NONE; +} + +/* + * Return via "definingClassPtr" the class in which this method is + * defined. + * Note: class returned via 'definingClassPtr' is allocated globally + * and must be explictly freed with DeleteGlobalRef. + * Errors: JVMDI_ERROR_INVALID_METHODID, JVMDI_ERROR_INVALID_CLASS, + * JVMDI_ERROR_NULL_POINTER, JVMDI_ERROR_OUT_OF_MEMORY + */ +JNIEXPORT JNICALL(jvmdiError) +JVMDI_GetMethodDefiningClass(JNIEnv * env, jclass /* clazz */, jmethodID method, + jclass * definingClassPtr) +{ + CacheEntry* ce; + ce = NativeCodeCache::getCache().lookupByRange((Uint8*) method); + + if (definingClassPtr == NULL) { + return JVMDI_ERROR_NULL_POINTER; + } + *definingClassPtr = (jclass) (env->NewGlobalRef((jobject) + ce->descriptor.method->getDeclaringClass())); + + return JVMDI_ERROR_NONE; +} + + +/* + * Return via "isNativePtr" a boolean indicating whether the method + * is native. + * Errors: JVMDI_ERROR_INVALID_METHODID, JVMDI_ERROR_INVALID_CLASS, + * JVMDI_ERROR_NULL_POINTER + */ +JNIEXPORT JNICALL(jvmdiError) +JVMDI_IsMethodNative(JNIEnv * /* env */, jclass /* clazz */, jmethodID method, + jboolean * isNativePtr) +{ + if (isNativePtr == NULL) { + return JVMDI_ERROR_NULL_POINTER; + } + + CacheEntry* ce; + ce = NativeCodeCache::getCache().lookupByRange((Uint8*) method); + + if (ce == NULL) { + /* either the method is not compiled - in which case compile it */ + return JVMDI_ERROR_INVALID_METHODID; + } + + *isNativePtr = ce->descriptor.method->getMethodInfo().isNative(); + + return JVMDI_ERROR_NONE; +} + + +/* + * Misc + */ + +/* + * Return via "classesPtr" all classes currently loaded in the VM. + * Note: array returned via 'classesPtr' is allocated globally + * and must be explictly freed with DeleteGlobalRef. + * Errors: JVMDI_ERROR_NULL_POINTER, JVMDI_ERROR_OUT_OF_MEMORY + */ +JNIEXPORT JNICALL(jvmdiError) +JVMDI_GetLoadedClasses(JNIEnv * /*env*/, jobjectArray * /*classesPtr*/) +{ + return JVMDI_ERROR_NOT_IMPLEMENTED; +} + + +/* + * Return via "versionPtr" the JVMDI version number. + * Higher 16 bits is major version number, lower 16 bit is minor + * version number. + * Errors: JVMDI_ERROR_NULL_POINTER + */ +JNIEXPORT JNICALL(jvmdiError) +JVMDI_GetVersionNumber(JNIEnv * /*env*/, jint *versionPtr) +{ + if (versionPtr == NULL) { + return JVMDI_ERROR_NULL_POINTER; + } + *versionPtr = 0x00000003; + return JVMDI_ERROR_NONE; +} + +} // extern C diff --git a/ef/Driver/Makefile b/ef/Driver/Makefile new file mode 100644 index 000000000000..92f6714c505c --- /dev/null +++ b/ef/Driver/Makefile @@ -0,0 +1,50 @@ +#!gmake +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +####################################################################### +# (1) Directory specific info # +####################################################################### + +DEPTH = .. + +DIRS = StandAloneJava + +SUBMODULES = $(DIRS) + +####################################################################### +# (2) Include "component" configuration information. # +####################################################################### + +include $(DEPTH)/config/config.mk + +####################################################################### +# (3) Include "local" platform-dependent assignments (OPTIONAL). # +####################################################################### + + +####################################################################### +# (4) Execute "component" rules. (OPTIONAL) # +####################################################################### + +include $(DEPTH)/config/rules.mk + +####################################################################### +# (7) Execute "local" rules. (OPTIONAL). # +####################################################################### + + + diff --git a/ef/Driver/PrimitiveBuilder/GraphBuilder.cpp b/ef/Driver/PrimitiveBuilder/GraphBuilder.cpp new file mode 100644 index 000000000000..264da869229f --- /dev/null +++ b/ef/Driver/PrimitiveBuilder/GraphBuilder.cpp @@ -0,0 +1,418 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#include "Fundamentals.h" +#include "ControlGraph.h" +#include "Primitives.h" +#include "GraphBuilder.h" +#include "Pool.h" +#include "cstubs.h" +#include "Parser.h" + +ControlGraph& GraphBuilder:: +parse(char *filename) +{ + if (freopen(filename, "r", stdin) == NULL) + { + perror(""); + exit(EXIT_FAILURE); + } + + YYSTYPE yylval; + int yychar; + uint32 argCount = 0; + while ((yychar = yylex(&yylval)) > 0) + { + if ((yychar == PRIMITIVE) && (yylval.yyPrimitiveOperation == poArg_I)) + argCount++; + } + + freopen(filename, "r", stdin); + + ValueKind* kinds = new(envPool) ValueKind[argCount]; + for (uint32 i = 0; i < argCount; i++) + kinds[i] = vkInt; + + graph = new(envPool) ControlGraph(envPool, argCount, kinds, 1); + + predecessorEdge = 0; + lastCondition = 0; + currentNode = &graph->newControlNode(); + + yyparse(this); + + // link to the end node. + finishCurrentNode("__end__"); + currentNode->remove(); + + if (!labelManager.used("__end__")) + yyerror("no end to this method"); + + // link the begin node to the start label. + labelManager.resolve("start", graph->getBeginExtra().getSuccessorEdge()); + labelManager.define("__end__", graph->getEndNode()); + + // Initialize the finalMemory in the EndNode. + graph->getEndExtra().finalMemory.getInput(). + setVar(graph->getBeginExtra().initialMemory.getOutgoingEdge()); + + // check for link errors + if (varManager.hasUndefinedSymbols()) + undefinedSymbolError(varManager.undefinedSymbols()); + if (labelManager.hasUndefinedSymbols()) + undefinedSymbolError(labelManager.undefinedSymbols()); + + return *graph; +} + +void GraphBuilder:: +aliasVariable(char *var, char* alias) +{ + assert(varManager.defined(var)); + varManager.define(alias, varManager.get(var)); +} + +char *GraphBuilder:: +getPhiVariable(Vector& vars, char *label) +{ + uint32 str_size = 0; + char *phi_variable, *ptr; + bool restore = false; + ControlNode* saved_node; + + if (label) + if (labelManager.defined(label)) + { + saved_node = currentNode; + currentNode = &labelManager.get(label); + restore = true; + } + else + { + fprintf(stderr, "error: Label %s is not yet defined.", label); + exit(EXIT_FAILURE); + } + + for (uint32 i = 0; i < vars.size(); i++) + { + checkInputArgument(vars, i, akVariable); + str_size += (strlen(vars[i]->getName()) + 1); + } + str_size += 3 /* phi */ + 1 /* '\0' */; + phi_variable = (char *) malloc(str_size); + ptr = phi_variable; + sprintf(ptr, "phi"); ptr += 3; + for (uint32 j = 0; j < vars.size(); j++) + { + sprintf(ptr, "_%s", vars[j]->getName()); ptr += strlen(ptr); + } + + if (!varManager.defined(phi_variable)) + { + buildPhiNode(vars, vkInt, phi_variable); + } + else + { + DataNode& phi_producer = varManager.get(phi_variable); + DoublyLinkedList& phiNodes = currentNode->getPhiNodes(); + bool found = false; + + for (DoublyLinkedList::iterator it = phiNodes.begin(); !phiNodes.done(it); + it = phiNodes.advance(it)) + if (&phiNodes.get(it).getOutgoingEdge() == &phi_producer) + { + found = true; + break; + } + if (!found) + { + fprintf(stderr, "error: the phi node at line %d was defined in another block.\n" + " Try phi(arg, ...)@label\n", yylineno); + exit(EXIT_FAILURE); + } + } + + if (restore) + currentNode = saved_node; + + return phi_variable; +} + +void GraphBuilder:: +undefinedSymbolError(Vector& symbols) +{ + uint32 count = symbols.size(); + fprintf(stderr, "error: undefined symbol%s: ", count > 1 ? "s" : ""); + for (uint32 i=0; i < count; i++) + fprintf(stderr, "%s ", symbols[i]); + fprintf(stderr, "\n"); + exit(EXIT_FAILURE); +} + +void GraphBuilder:: +checkInputArgument(Vector& in, uint32 pos, uint8 kind) +{ + if (pos >= in.size()) + yyerror("wrong input argument count"); + else if (!((in[pos]->isConstant() ? akConstant : akVariable) & kind)) + yyerror("wrong argument kind"); +} + +void GraphBuilder:: +checkOutputArgument(char *name) +{ + if (!name) + yyerror("need an output argument"); +} + +void GraphBuilder:: +connectConsumer(char *name, DataConsumer& consumer) +{ + varManager.resolve(name, consumer); +} + +void GraphBuilder:: +registerProducer(char *name, DataNode& producer) +{ + if (varManager.defined(name)) + { + char fmt[] = "duplicate variable definition %s"; + char* error = (char *) malloc(strlen(fmt) - 2 + strlen(name) + 1); + sprintf(error, fmt, name); + yyerror(error); + } + varManager.define(name, producer); +} + +void GraphBuilder:: +buildConstPrimitive(Value& value, ValueKind constantKind, char *producer) +{ + PrimConst& primConst = *new(envPool) PrimConst(constantKind, value); + registerProducer(producer, primConst.getOutgoingEdge()); + currentNode->addPrimitive(primConst); +} + +void GraphBuilder:: +buildArgPrimitive(ValueKind outputKind, ConsumerOrConstant& arg0, char *producer) +{ + ValueKind v = outputKind; v = vkInt; + uint32 argNum = arg0.getName()[strlen(arg0.getName())-1] - '0'; + + PrimArg& primArg = graph->getBeginExtra().arguments[argNum]; + char buffer[] = "arg0"; + buffer[3] = '0' + argNum; + registerProducer(buffer, primArg.getOutgoingEdge()); + registerProducer(producer, primArg.getOutgoingEdge()); +} + +void GraphBuilder:: +buildResultPrimitive(ValueKind kind, ConsumerOrConstant& arg0) +{ + ValueKind* kinds = new(envPool) ValueKind[1]; + kinds[0] = kind; + ControlReturn& block = *new(envPool) ControlReturn(*currentNode, 1, kinds, envPool); + connectConsumer(arg0.getName(), block.results[0].getInput()); + if (predecessorEdge) + currentNode->addPredecessor(*predecessorEdge); + predecessorEdge = &block.getSuccessorEdge(); + + currentNode = &graph->newControlNode(); +} + +void GraphBuilder:: +buildStorePrimitive(ValueKind /*outputKind*/, ConsumerOrConstant& /*arg0*/, ConsumerOrConstant& /*arg1*/) +{ +} + +void GraphBuilder:: +buildGenericBinaryPrimitive(PrimitiveOperation op, ValueKind outputKind, + ConsumerOrConstant& arg0, ConsumerOrConstant& arg1, char *producer) +{ + PrimBinaryGeneric& prim = *new(envPool) PrimBinaryGeneric(op, outputKind, true); + if (arg0.isConstant()) + prim.getInputs()[0].setConst(arg0.getValue().i); + else + connectConsumer(arg0.getName(), prim.getInputs()[0]); + + if (arg1.isConstant()) + prim.getInputs()[1].setConst(arg1.getValue().i); + else + connectConsumer(arg1.getName(), prim.getInputs()[1]); + + registerProducer(producer, prim.getOutgoingEdge()); + currentNode->addPrimitive(prim); +} + +void GraphBuilder:: +buildIfPrimitive(PrimitiveOperation op, DataNode& cond, char *branch_to_if_true) +{ + // finish the Block + ControlIf& block = *new(envPool) ControlIf(*currentNode, Condition2(condLt + op - poIfLt), cond); + if (predecessorEdge) + currentNode->addPredecessor(*predecessorEdge); + predecessorEdge = &block.getFalseIfEdge(); + labelManager.resolve(branch_to_if_true, block.getTrueIfEdge()); + + currentNode = &graph->newControlNode(); +} + +void GraphBuilder:: +finishCurrentNode(char *successor) +{ + if (!currentNode->getPrimitives().empty()) + { + ControlBlock& cb = *new(envPool) ControlBlock(*currentNode); + if (predecessorEdge) + currentNode->addPredecessor(*predecessorEdge); + predecessorEdge = 0; + labelManager.resolve(successor, cb.getSuccessorEdge()); + currentNode = &graph->newControlNode(); + } + else + { + if (predecessorEdge) + labelManager.resolve(successor, *predecessorEdge); + predecessorEdge = 0; + } +} + +char *GraphBuilder:: +getNewConditionName() +{ + static uint32 index = 0; + static char buffer[4 + 3 + 1]; + sprintf(buffer, "cond%3.3d", index++); + return buffer; +} + +void GraphBuilder:: +buildPhiNode(Vector& in, ValueKind kind, char *producer) +{ + uint32 count = in.size(); + PhiNode& phiNode = *new(envPool) PhiNode(count, kind, envPool); + DataConsumer& fakeConsumer = *new(envPool) DataConsumer(); + fakeConsumer.setNode(&phiNode); + + for (uint32 i = 0; i < count; i++) + { + checkInputArgument(in, i, akVariable); + connectConsumer(in[i]->getName(), fakeConsumer); + } + registerProducer(producer, phiNode.getOutgoingEdge()); + currentNode->addPhiNode(phiNode); +} + +void GraphBuilder:: +buildPrimitive(PrimitiveOperation op, Vector& in, char *out) +{ + switch(op) + { + case poConst_I: + checkInputArgument(in, 0, akConstant); + checkOutputArgument(out); + buildConstPrimitive(in[0]->getValue(), vkInt, out); + break; + + case poArg_I: + checkInputArgument(in, 0, akVariable); + checkOutputArgument(out); + buildArgPrimitive(vkInt, *in[0], out); + break; + + case poResult_I: + checkInputArgument(in, 0, akVariable); + buildResultPrimitive(vkInt, *in[0]); + break; + + case poSt_I: + checkInputArgument(in, 0, akVariable); + checkInputArgument(in, 1, akVariable); + buildStorePrimitive(vkInt, *in[0], *in[1]); + break; + + case poAdd_I: + case poSub_I: + case poMul_I: + case poAnd_I: + case poOr_I: + case poXor_I: + checkInputArgument(in, 0, akAny); + checkInputArgument(in, 1, akAny); + checkOutputArgument(out); + + buildGenericBinaryPrimitive(op, vkInt, *in[0], *in[1], out); + break; + + case poCmp_I: + checkInputArgument(in, 0, akAny); + checkInputArgument(in, 1, akAny); + lastCondition = (out) ? out : getNewConditionName(); + buildGenericBinaryPrimitive(poCmp_I, vkCond, *in[0], *in[1], lastCondition); + break; + + case poIfLt: + case poIfEq: + case poIfLe: + case poIfGt: + case poIfNe: + case poIfGe: + checkInputArgument(in, 0, akVariable); // label name or cond. + if (in.size() == 1) + { + if (!varManager.exists(lastCondition)) + yyerror("no condition set for this control"); + buildIfPrimitive(op, varManager.get(lastCondition), in[0]->getName()); + } + else + { + checkInputArgument(in, 1, akVariable); // label name. + lastCondition = in[0]->getName(); + buildIfPrimitive(op, varManager.get(lastCondition), in[1]->getName()); + } + break; + + case poPhi_I: + checkOutputArgument(out); + buildPhiNode(in, vkInt, out); + break; + + case nPrimitiveOperations: // bra + checkInputArgument(in, 0, akVariable); // label name. + finishCurrentNode(in[0]->getName()); + break; + + default: + yyerror("unhandled primitive operation"); + break; + } +} + +void GraphBuilder:: +defineLabel(char *name) +{ + if (!currentNode->getPrimitives().empty()) + { + // there is an incoming edge + ControlBlock& cb = *new(envPool) ControlBlock(*currentNode); + if (predecessorEdge) + currentNode->addPredecessor(*predecessorEdge); + predecessorEdge = &cb.getSuccessorEdge(); + currentNode = &graph->newControlNode(); + } + labelManager.define(name, *currentNode); +} diff --git a/ef/Driver/PrimitiveBuilder/GraphBuilder.h b/ef/Driver/PrimitiveBuilder/GraphBuilder.h new file mode 100644 index 000000000000..63395987eeec --- /dev/null +++ b/ef/Driver/PrimitiveBuilder/GraphBuilder.h @@ -0,0 +1,94 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#ifndef _GRAPH_BUILDER_H_ +#define _GRAPH_BUILDER_H_ + +#include // for strdup +#include // for free +#include "ControlGraph.h" +#include "Fundamentals.h" +#include "Value.h" +#include "VarManager.h" +#include "LabelManager.h" +#include "Pool.h" + +class ConsumerOrConstant +{ +private: + union + { + char *name; + Value value; + }; + bool is_constant; + +public: + ConsumerOrConstant(char *name) : is_constant(false), name(strdup(name)) {} + ConsumerOrConstant(const Value& value) : is_constant(true), value(value) {} + ~ConsumerOrConstant() {free(name);} + + Value& getValue() {return value;} + char *getName() {return name;} + bool isConstant() {return is_constant;} +}; + +#define akVariable 0x01 +#define akConstant 0x02 +#define akAny (akVariable | akConstant) + +class GraphBuilder +{ +private: + + Pool& envPool; + VarManager varManager; + LabelManager labelManager; + + ControlGraph* graph; + ControlNode* currentNode; + ControlEdge* predecessorEdge; + char *lastCondition; + +public: + GraphBuilder(Pool& envPool) : envPool(envPool), varManager(envPool), labelManager(envPool) {} + ControlGraph& parse(char *filename); + + + void checkInputArgument(Vector& in, uint32 pos, uint8 kind); + void checkOutputArgument(char *name); + void registerProducer(char *name, DataNode& producer); + void connectConsumer(char *name, DataConsumer& consumer); + void buildConstPrimitive(Value& value, ValueKind constantKind, char *producer); + void buildGenericBinaryPrimitive(PrimitiveOperation op, ValueKind outputKind, ConsumerOrConstant& arg0, ConsumerOrConstant& arg1, char *producer); + void buildIfPrimitive(PrimitiveOperation op, DataNode& cond, char *branch_to_if_true); + void buildPrimitive(PrimitiveOperation op, Vector& in, char *out = 0); + void buildPhiNode(Vector& in, ValueKind kind, char *producer); + void buildArgPrimitive(ValueKind outputKind, ConsumerOrConstant& arg0, char *producer); + void buildResultPrimitive(ValueKind kind, ConsumerOrConstant& arg0); + void buildStorePrimitive(ValueKind kind, ConsumerOrConstant& arg0, ConsumerOrConstant& arg1); + char *getNewConditionName(); + void defineLabel(char *name); + void finishCurrentNode(char *successor); + void undefinedSymbolError(Vector& symbols); + char *getPhiVariable(Vector& vars, char *label = 0); + void aliasVariable(char *var, char* alias); + void generateCode(); // FIXME: to remove +}; + +#endif /* _GRAPH_BUILDER_H_ */ diff --git a/ef/Driver/PrimitiveBuilder/LabelManager.h b/ef/Driver/PrimitiveBuilder/LabelManager.h new file mode 100644 index 000000000000..35a5ccdc9fe8 --- /dev/null +++ b/ef/Driver/PrimitiveBuilder/LabelManager.h @@ -0,0 +1,34 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#ifndef _LABEL_MANAGER_H_ +#define _LABEL_MANAGER_H_ + +#include "Fundamentals.h" +#include "HashTable.h" +#include "SymbolManager.h" +#include "ControlNodes.h" + +class LabelManager : public SymbolManager +{ +public: + LabelManager(Pool& pool) : SymbolManager(pool) {} + inline void link(ControlNode& owner, ControlEdge& consumer) {owner.addPredecessor(consumer);} +}; + +#endif /* _LABEL_MANAGER_H_ */ diff --git a/ef/Driver/PrimitiveBuilder/Lexer.lex b/ef/Driver/PrimitiveBuilder/Lexer.lex new file mode 100644 index 000000000000..8443e2efb48f --- /dev/null +++ b/ef/Driver/PrimitiveBuilder/Lexer.lex @@ -0,0 +1,124 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +%option yylineno + +%{ +/* + * includes and local declaration. + */ + +#include "Fundamentals.h" +#include "Primitives.h" +#include "Value.h" +#include "GraphBuilder.h" +#include "cstubs.h" +#include "Parser.h" + +#define yywrap() 1 +#define YY_DECL int yylex(void *yylval) +#define YYLVAL ((YYSTYPE *) yylval) +#define returnPrimitive(op) YYLVAL->yyPrimitiveOperation = (op); return PRIMITIVE; +#define returnKind(kind) YYLVAL->yyValueKind = (kind); return KIND; + +static char *extractLabelName(char *label); + +%} + +label [[:alnum:]]+":" +space [ \r\t]+ +number [0-9]+ +string [[:alnum:]]+ +right_assignment "->" +left_assignment ":=" +comma "," +parenthesis "("|")" +at "@" + + +%x comment ccomment nil + +%% + +{right_assignment} {return RIGHT_ASSIGNMENT;} +{left_assignment} {return LEFT_ASSIGNMENT;} +{comma} {return yytext[0];} +{parenthesis} {return yytext[0];} +{at} {return yytext[0];} + +"_I" {returnKind(vkInt);} + +"Arg" {returnPrimitive(poArg_I)} +"Result" {returnPrimitive(poResult_I)} +"Const" {returnPrimitive(poConst_I)} +"Mul" {returnPrimitive(poMul_I)} +"Add" {returnPrimitive(poAdd_I)} +"Sub" {returnPrimitive(poSub_I)} +"And" {returnPrimitive(poAnd_I)} +"Or" {returnPrimitive(poOr_I)} +"Xor" {returnPrimitive(poXor_I)} +"Cmp" {returnPrimitive(poCmp_I)} +"IfLt" {returnPrimitive(poIfLt)} +"IfEq" {returnPrimitive(poIfEq)} +"IfLe" {returnPrimitive(poIfLe)} +"IfGt" {returnPrimitive(poIfGt)} +"IfNe" {returnPrimitive(poIfNe)} +"IfGe" {returnPrimitive(poIfGe)} +"St" {returnPrimitive(poSt_I)} +"Branch" {returnPrimitive((PrimitiveOperation)nPrimitiveOperations)} +"Phi" {return PHI;} + +{string}: {YYLVAL->yyString = extractLabelName(yytext); return LABEL;} + +{number} {sscanf(yytext, "%d", &YYLVAL->yyValue.i); return NUMBER;} +#{number} {sscanf(yytext + 1, "%d", &YYLVAL->yyValue.i); return NUMBER;} +{string} {YYLVAL->yyString = strdup(yytext); return STRING;} + + +{space}+ +"/*" BEGIN(comment); +"//" BEGIN(ccomment); +\n return '\n'; +. + +[^*]* +"*"+[^*/]* +"*"+"/" BEGIN(INITIAL); + +. +\n { + BEGIN(INITIAL); return '\n'; + } + +. { /* to quiet the compiler. */ + return yytext[0]; + yyunput(0, NULL); + yy_flex_realloc(0, 0); + REJECT; + } +%% + +static char * +extractLabelName(char *label) +{ + uint32 size = strlen(label); + char *ret = (char *) malloc(size); + strncpy(ret, label, size - 1); + ret[size - 1] = '\0'; + return ret; +} diff --git a/ef/Driver/PrimitiveBuilder/Makefile b/ef/Driver/PrimitiveBuilder/Makefile new file mode 100644 index 000000000000..e329d8bb4214 --- /dev/null +++ b/ef/Driver/PrimitiveBuilder/Makefile @@ -0,0 +1,23 @@ +#!gmake +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +all:: +export:: +libs:: +programs:: +install:: +depend:: diff --git a/ef/Driver/PrimitiveBuilder/Parser.y b/ef/Driver/PrimitiveBuilder/Parser.y new file mode 100644 index 000000000000..505ca659d2db --- /dev/null +++ b/ef/Driver/PrimitiveBuilder/Parser.y @@ -0,0 +1,190 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +%{ +#include + +#include "Fundamentals.h" +#include "Primitives.h" +#include "GraphBuilder.h" +#include "Value.h" +#include "Vector.h" +#include "cstubs.h" + +#define YYPARSE_PARAM gb +#define builder (*(GraphBuilder *)gb) +%} + +%pure_parser + +%union +{ + char *yyString; + Value yyValue; + ValueKind yyValueKind; + PrimitiveOperation yyPrimitiveOperation; + Vector *yyConsumerVector; + ConsumerOrConstant *yyConsumer; + char *yyProducer; +}; + + +%token PRIMITIVE +%token LEFT_ASSIGNMENT +%token RIGHT_ASSIGNMENT +%token STRING +%token NUMBER +%token KIND +%token LABEL +%token PHI + +%type arg +%type args +%type result +%type kind +%type phi + +%% + +input: /* empty */ + | input line +; + +line: '\n' +{ +} + | label '\n' +{ +} + | instruction '\n' +{ +} + | label instruction '\n' +{ +} + | error '\n' +{ + yyerrok; +} + ; + +label: LABEL +{ + builder.defineLabel($1); +} +; + +instruction: PRIMITIVE kind args RIGHT_ASSIGNMENT result +{ + builder.buildPrimitive($1, *$3, $5); + delete $3; // delete the vector + free($5); +} + | PHI kind args RIGHT_ASSIGNMENT result +{ + char *var = builder.getPhiVariable(*$3); + builder.aliasVariable(var, $5); + delete $3; // delete the vector + free($5); + free(var); +} + | result LEFT_ASSIGNMENT PRIMITIVE kind args +{ + builder.buildPrimitive($3, *$5, $1); + delete $5; // delete the vector + free($1); +} + | result LEFT_ASSIGNMENT PHI kind args +{ + char *var = builder.getPhiVariable(*$5); + builder.aliasVariable(var, $1); + delete $5; // delete the vector + free($1); + free(var); +} + | PRIMITIVE kind args +{ + builder.buildPrimitive($1, *$3); + delete $3; // delete the vector +} + ; + +kind: /* empty */ +{ + $$ = vkInt; +} + | KIND +{ + $$ = $1 +} + ; + +args: +{ + $$ = new Vector(); +} + | arg +{ + $$ = new Vector(); + $$->append($1); +} + | args ',' arg +{ + $$ = $1; + $$->append($3); +} + ; + +arg: STRING +{ + $$ = new ConsumerOrConstant($1); + free($1); +} + | NUMBER +{ + $$ = new ConsumerOrConstant($1); +} + | phi +{ + $$ = new ConsumerOrConstant($1); + free($1); +} + +result: STRING +{ + $$ = $1; +} + +phi: PHI '(' args ')' +{ + $$ = builder.getPhiVariable(*$3); +} + | PHI '(' args ')' '@' STRING +{ + $$ = builder.getPhiVariable(*$3, $6); +} + +%% + +int +yyerror(char *string) +{ + fprintf (stderr, "%s at line %d\n", string, yylineno); + exit(EXIT_FAILURE); + return 0; +} diff --git a/ef/Driver/PrimitiveBuilder/SymbolManager.h b/ef/Driver/PrimitiveBuilder/SymbolManager.h new file mode 100644 index 000000000000..8f65adf52381 --- /dev/null +++ b/ef/Driver/PrimitiveBuilder/SymbolManager.h @@ -0,0 +1,153 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#ifndef _SYMBOL_MANAGER_H_ +#define _SYMBOL_MANAGER_H_ + +#include "Fundamentals.h" +#include "HashTable.h" +#include "Vector.h" +#include "Pool.h" + +template +struct SymbolStruct +{ + bool defined; + bool used; + char * name; + Owner * owner; + Vector pending; + + SymbolStruct() : defined(0), used(0), name(0), owner(0) {} +}; + +template +class SymbolManager +{ +protected: + typedef SymbolStruct Symbol; + HashTable symbols; + uint32 n_undefined; + Vector ret_vector; + +public: + + SymbolManager(Pool& pool) : symbols(pool), n_undefined(0) {} + + void resolve(const char *name, Consumer& consumer) + { + if (!defined(name)) + differ(name, consumer); + else + link(*symbols[name].owner, consumer); + symbols[name].used = 1; + } + + Owner& get(const char *name) + { + Symbol& symbol = symbols[name]; + assert(symbol.defined); + return *symbol.owner; + } + + virtual void link(Owner& owner, Consumer& consumer) = 0; + + void define(const char *name, Owner& owner) + { + if (symbols.exists(name)) + { + Symbol& symbol = symbols[name]; + uint32 count = symbol.pending.size(); + + assert(!symbol.defined ); + symbol.owner = &owner; + symbol.defined = 1; + for (uint32 i = 0; i < count; i++) + link(owner, *symbol.pending[i]); + + n_undefined--; + } + else + { + Symbol symbol; + symbol.owner = &owner; + symbol.defined = 1; + symbol.name = strdup(name); + symbols.add(name, symbol); + } + } + + inline bool exists(const char *name) {return symbols.exists(name);} + inline bool defined(const char *name) {return exists(name) && symbols[name].defined;} + inline bool used(const char *name) {return exists(name) && symbols[name].used;} + + void differ(const char *name, Consumer& consumer) + { + if (!exists(name)) + { + Symbol symbol; + symbol.name = strdup(name); + symbols.add(name, symbol); + n_undefined++; + } + symbols[name].pending.append(&consumer); + } + + bool hasUndefinedSymbols() {return (n_undefined != 0);} + + Vector& undefinedSymbols() + { + Vector& all_symbols = symbols; + uint32 count= all_symbols.size(); + + ret_vector.eraseAll(); + + if (n_undefined) + for (uint32 i = 0; i < count; i++) + if (!all_symbols[i].defined) + ret_vector.append(all_symbols[i].name); + + return ret_vector; + } + + bool hasUnusedSymbols() + { + Vector& all_symbols = symbols; + uint32 count= all_symbols.size(); + for (uint32 i = 0; i < count; i++) + if (!all_symbols[i].used) + return 1; + return 0; + } + + Vector& unusedSymbols() + { + Vector& all_symbols = symbols; + uint32 count= all_symbols.size(); + + ret_vector.eraseAll(); + + for (uint32 i = 0; i < count; i++) + if (!all_symbols[i].used) + ret_vector.append(all_symbols[i].name); + + return ret_vector; + } +}; + +#endif /* _SYMBOL_MANAGER_H_ */ diff --git a/ef/Driver/PrimitiveBuilder/VarManager.h b/ef/Driver/PrimitiveBuilder/VarManager.h new file mode 100644 index 000000000000..093875c503d4 --- /dev/null +++ b/ef/Driver/PrimitiveBuilder/VarManager.h @@ -0,0 +1,47 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#ifndef _VAR_MANAGER_H_ +#define _VAR_MANAGER_H_ + +#include "Fundamentals.h" +#include "SymbolManager.h" +#include "Primitives.h" +#include "Pool.h" + +class VarManager : public SymbolManager +{ +private: + Pool& ePool; + +public: + VarManager(Pool& envPool) : SymbolManager(envPool), ePool(envPool) {} + + inline void link(DataNode& producer, DataConsumer& consumer) + { + if (consumer.getNode()->hasCategory(pcPhi)) + { + PhiNode *phiNode = (PhiNode *)consumer.getNode(); + phiNode->addInput(producer, ePool); + } + else + consumer.setVar(producer); + } +}; + +#endif /* _VAR_MANAGER_H_ */ diff --git a/ef/Driver/PrimitiveBuilder/cstubs.h b/ef/Driver/PrimitiveBuilder/cstubs.h new file mode 100644 index 000000000000..fddbc65d076b --- /dev/null +++ b/ef/Driver/PrimitiveBuilder/cstubs.h @@ -0,0 +1,28 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#ifndef _CSTUBS_H_ +#define _CSTUBS_H_ + +#include "ControlGraph.h" + +extern int yylineno; +extern "C" int yyerror(char *); +extern "C" int yylex(void *); +extern "C" int yyparse(void *); + +#endif /* _CSTUBS_H_ */ diff --git a/ef/Driver/PrimitiveBuilder/example.il b/ef/Driver/PrimitiveBuilder/example.il new file mode 100644 index 000000000000..1648d65f49ab --- /dev/null +++ b/ef/Driver/PrimitiveBuilder/example.il @@ -0,0 +1,51 @@ +/* + * void function(int res) + * { + * int i, j; + * j = 0; + * for (i=0; i < 100; i++) + * j += i; + * return res; + * } + * + */ + +/* +start: + vi2 := Arg_I arg0 + wi3 := Const_I 1 +N2: + vi4 := Phi_I wi3, vi8 + vi5 := Phi_I vi2, vi5 + + vc7 := Cmp_I vi4, 100 + IfLt vc7, N4 + vi8 := Add_I vi4, 1 + Branch N2 + +N4: + vi9 := Mul_I vi4, 3 + vi10 := Add_I vi9, 2 + vi11 := Mul_I vi5, 6 + vi12 := Add_I vi10, vi11 + Result_I vi12 + +*/ + +start: + v0 := Arg_I arg0 + i0 := Const_I 0 + j0 := Const_I 0 + Branch test + +loop: + j1 := Add_I i1, j2 + i2 := Add_I i1, 1 + +test: + i1 := Phi_I i0, i2 + j2 := Phi_I j0, j1 + c := Cmp_I i1, 100 + IfLt c, loop + + Result_I v0 diff --git a/ef/Driver/PrimitiveBuilder/main.cpp b/ef/Driver/PrimitiveBuilder/main.cpp new file mode 100644 index 000000000000..de2397272ceb --- /dev/null +++ b/ef/Driver/PrimitiveBuilder/main.cpp @@ -0,0 +1,38 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#include "Fundamentals.h" +#include "ControlGraph.h" +#include "Pool.h" +#include "GraphBuilder.h" + +int +main(int argc, char **argv) +{ + if (argc < 2) + exit(EXIT_FAILURE); + + Pool pool; + GraphBuilder builder(pool); + ControlGraph& cg = builder.parse(argv[1]); + + cg.print(stdout); + cg.generateCode(stdout); + + return 0; +} diff --git a/ef/Driver/StandAloneJava/Makefile b/ef/Driver/StandAloneJava/Makefile new file mode 100644 index 000000000000..8483c7cbcb8e --- /dev/null +++ b/ef/Driver/StandAloneJava/Makefile @@ -0,0 +1,66 @@ +#!gmake +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +####################################################################### +# (1) Directory specific info # +####################################################################### + +DEPTH = ../.. + +CPPSRCS = efmain.cpp \ + $(NULL) + +PROGRAM = sajava + + +####################################################################### +# (2) Include "component" configuration information. # +####################################################################### + +include $(DEPTH)/config/config.mk + +####################################################################### +# (3) Include "local" platform-dependent assignments (OPTIONAL). # +####################################################################### + +CFLAGS += -DIMPORTING_VM_FILES + +ifneq ($(OS_ARCH),WINNT) +LDFLAGS += -lm +endif + +LDFLAGS += $(EF_LIBS) $(NSPR_LIBS) + +####################################################################### +# (4) Execute "component" rules. (OPTIONAL) # +####################################################################### + +include $(DEPTH)/config/rules.mk + +####################################################################### +# (7) Execute "local" rules. (OPTIONAL). # +####################################################################### + +program:: $(PROGRAM) + +ifdef GENERATE_BROWSE_INFO +program:: $(BROWSE_INFO_FILE) +endif + +$(PROGRAM): $(EF_LIB_FILES) + + diff --git a/ef/Driver/StandAloneJava/efmain.cpp b/ef/Driver/StandAloneJava/efmain.cpp new file mode 100644 index 000000000000..f55bee5d52a6 --- /dev/null +++ b/ef/Driver/StandAloneJava/efmain.cpp @@ -0,0 +1,575 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#include +#include +#include "JavaVM.h" +#include "prprf.h" +#include "plstr.h" +#include "Exceptions.h" +#include "StackWalker.h" +#include "NativeCodeCache.h" // for printMethodTable + +#include "LogModule.h" + +#ifdef __MWERKS__ + #include + #include +#endif + +void realMain(void* arg); + +struct StageName +{ + char *name; + CompileStage stage; +}; + +const StageName stageNames[] = +{ + {"r", csRead}, + {"R", csRead}, + {"read", csRead}, + {"READ", csRead}, + {"p", csPreprocess}, + {"P", csPreprocess}, + {"preprocess", csPreprocess}, + {"PREPROCESS", csPreprocess}, + {"g", csGenPrimitives}, + {"G", csGenPrimitives}, + {"genprimitives", csGenPrimitives}, + {"GENPRIMITIVES", csGenPrimitives}, + {"o", csOptimize}, + {"O", csOptimize}, + {"optimize", csOptimize}, + {"OPTIMIZE", csOptimize}, + {"i", csGenInstructions}, + {"I", csGenInstructions}, + {"instructions", csGenInstructions}, + {"INSTRUCTIONS", csGenInstructions} +}; +const nStageNames = sizeof(stageNames) / sizeof(StageName); + + +static bool getStage(const char *stageName, CompileStage &stage) +{ + const StageName *sn = stageNames; + for (; sn != stageNames + nStageNames; sn++) + if (!PL_strcmp(stageName, sn->name)) { + stage = sn->stage; + return true; + } + + return false; +} + + +/* Options + * -c, -classpath + * -a, -all Compile all methods. + * -m, -method : Go to method whose simple name is + * and signature is . The -s option + * specifies what to do with the method. + * -mn, -methodName : Go to method whose simple name is + * , which must not be overloaded. The -s option + * specifies what to do with the method. + * -s, -stage default is to generate instructions + * -v, -verbose : verbose messages + * -n, -noinvoke : do not invoke compiled method. This is automatically true + * if the compile stage is anything other than genInstructions. + * -l, -lib : canonical name of native library to load at init time + * -sys, -system : Initialize system class on start-up + * -ta, -traceAll: enable method tracing for all methods + * -t, -trace : Enable tracing for a method with the given fully + * qualified className, simple methodName and java signature. + * -bc, -breakCompile : Set a debug breakpoint just before compiling + * the method with the given fully qualified className, simple methodName and + * java signature. + * -be, -breakExec : Set a debug breakpoint just before executing + * the method with the given fully qualified className, simple methodName and + * java signature. + * -h, -help : Print help message + + * -log : turn on logging for at level . By default, logs are logged + * to stderr; use -logfile to direct them to a file. + * -lf, -logFile : specify the file to put logs into. "stderr" is a valid filename and indicates + * stderr. -lf can be used more than once on the command-line; it over-rides the last value of + * -lf. This can be used to log different modules to different files. For example, + * -lf foo -log FieldOrMethod 4 -log ClassCentral 3 -lf stderr -log Codegen 5 + * logs modules FieldOrMethod and ClassCentral to the file foo and the module + * Codegen to standard error. + * -ln, -logNames : print out a list of all log modules + * -debug : Enable debugging + * -ce, -catchHardwareExceptions : Catch all hardware exceptions (used in the debug builds only) + */ +struct Options { + CompileStage stage; /* Stage upto which method must be compiled */ + bool compileAll; /* If true, compile all method in class */ + bool verbose; /* Cause verbose output to be emitted when compiling */ + bool initialize; /* If true, initialize system class */ + bool invokeMethod; /* If false, do not invoke method after compiling */ + bool emitHTML; /* If true, output a HTML file for each jit'd method */ + bool traceAllMethods; /* If true, invoking any method generates a debugging trace */ + const char *methodName; /* Name of method to compile */ + const char *methodSig; /* Signature of method to compile */ + const char *className; /* Name of class to load */ + const char *classPath; + const char *logFileName;/* Name of the logFile -- if NULL, then logFile is stderr */ + JavaObject **args; /* Command-line arguments to the class */ + const char **argStrings; + int32 nArgs; /* Number of command-line arguments to the class */ + const char *libNames[10]; /* Canonical names of libraries to be pre-loaded */ + int numLibs; /* Number of libraries to be pre-loaded */ + bool debug; /* Enable debugging */ + + bool catchHardwareExceptions; /* Catch hardware exceptions and asserts */ + + DebugDesc *compileBreakPoints; /* Descriptions of compile break points */ + Uint32 nCompileBreakPoints; /* Number of compile break points */ + Uint32 nCompileBreakSlots; /* Number of elements currently allocated in compileBreakPoints */ + + DebugDesc *execBreakPoints; /* Descriptions of exec break points */ + Uint32 nExecBreakPoints; /* Number of exec break points */ + Uint32 nExecBreakSlots; /* Number of elements currently allocated in execBreakPoints */ + Options(); + + ~Options(); + + bool parse(int argc, const char **argv); + void printHelp() {} + + private: + void setBreakPoints(Uint32 &nBreakPoints, Uint32 &nBreakSlots, + DebugDesc *&breakPoints, const char *argv[]); +}; + +#ifdef PR_LOGGING +static void printAvailableModules() +{ + LogModuleObject *module; + int i; + + PR_fprintf(PR_STDERR, "Here is the current list of log modules:\n\n"); + + i = 1; + for (module = LogModuleObject::getAllLogModules(); module; module = module->getNext()) + PR_fprintf(PR_STDERR, "%2d. %s\n", i++, module->getName()); +} +#endif + +inline Options::Options(): + stage(csGenInstructions), + compileAll(false), + verbose(false), + initialize(false), + invokeMethod(true), + emitHTML(0), + traceAllMethods(false), + methodName(0), + methodSig(0), + className(0), + classPath(0), + logFileName(0), + args(0), + argStrings(0), + nArgs(0), + numLibs(0), + debug(false), + catchHardwareExceptions(false), + compileBreakPoints(0), + nCompileBreakPoints(0), + nCompileBreakSlots(0), + execBreakPoints(0), + nExecBreakPoints(0), + nExecBreakSlots(0) +{} + + +inline Options::~Options() +{ + if (args) { + delete [] args; + delete [] argStrings; + } + + if (compileBreakPoints) + delete [] compileBreakPoints; + + if (execBreakPoints) + delete [] execBreakPoints; + + if (className) + VM::freeUtfClassName((char *) className); +} + + +#ifdef DEBUG +void Options::setBreakPoints(Uint32 &nBreakPoints, Uint32 &nBreakSlots, + DebugDesc *&breakPoints, const char *argv[]) +{ + if (nBreakPoints+1 > nBreakSlots) { + DebugDesc *temp = breakPoints; + + breakPoints = new DebugDesc[nBreakSlots += 10]; + + for (Uint32 index = 0; index < nBreakSlots-10; index++) + breakPoints[index] = temp[index]; + + } + + breakPoints[nBreakPoints].className = *++argv; + breakPoints[nBreakPoints].methodName = *++argv; + breakPoints[nBreakPoints].sig = *++argv; + nBreakPoints++; +} +#endif + + +bool Options::parse(int argc, const char **argv) +{ + for (int i = 1; i < argc; i++) { + if (!PL_strcmp(argv[i], "-a") || !PL_strcmp(argv[i], "-all")) { + compileAll = true; + invokeMethod = false; + methodName = 0; + methodSig = 0; + +#ifdef DEBUG + } else if (!PL_strcmp(argv[i], "-bc") || !PL_strcmp(argv[i], "-breakCompile")) { + setBreakPoints(nCompileBreakPoints, nCompileBreakSlots, + compileBreakPoints, &argv[i]); + i += 3; + } else if (!PL_strcmp(argv[i], "-be") || !PL_strcmp(argv[i], "-breakExec")) { + setBreakPoints(nExecBreakPoints, nExecBreakSlots, + execBreakPoints, &argv[i]); + i += 3; +#endif + + } else if (!PL_strcmp(argv[i], "-c") || !PL_strcmp(argv[i], "-classpath")) { + classPath = argv[++i]; + } else if (!PL_strcmp(argv[i], "-h") || !PL_strcmp(argv[i], "-help")) { + printHelp(); + } else if (!PL_strcmp(argv[i], "-l") || !PL_strcmp(argv[i], "-lib")) { + libNames[numLibs++] = argv[++i]; + } else if (!PL_strcmp(argv[i], "-m") || !PL_strcmp(argv[i], "-method")) { + compileAll = false; + methodName = argv[++i]; + methodSig = argv[++i]; + } else if (!PL_strcmp(argv[i], "-mn") || !PL_strcmp(argv[i], "-methodName")) { + compileAll = false; + methodName = argv[++i]; + methodSig = 0; + } else if (!PL_strcmp(argv[i], "-n") || !PL_strcmp(argv[i], "-noinvoke")) { + invokeMethod = false; + } else if (!PL_strcmp(argv[i], "-html")) { + emitHTML = true; + } else if (!PL_strcmp(argv[i], "-v") || !PL_strcmp(argv[i], "-verbose")) { + verbose = true; + } else if (!PL_strcmp(argv[i], "-s") || !PL_strcmp(argv[i], "-stage")) { + const char *stageName = argv[++i]; + if (!getStage(stageName, stage)) { + PR_fprintf(PR_STDERR, "%s: Bad stage argument %s\n", argv[0], + stageName); + return false; + } + + if (stage != csGenInstructions) + invokeMethod = false; + } else if (!PL_strcmp(argv[i], "-sys") || !PL_strcmp(argv[i], "-system")) { + initialize = true; + } else if (!PL_strcmp(argv[i], "-ta") || !PL_strcmp(argv[i], "-traceAll")) { + traceAllMethods = true; + } else if (!PL_strcmp(argv[i], "-log")) { +#ifdef PR_LOGGING + /* Get the names of the log module, level and filename */ + const char *logModuleName = argv[++i]; + PRLogModuleLevel logLevel = (PRLogModuleLevel) atoi(argv[++i]); + + /* Identify this module */ + LogModuleObject *module = NULL; + for (module = LogModuleObject::getAllLogModules(); module; module = module->getNext()) { + if (!PL_strcmp(logModuleName, module->getName())) { + module->setLogLevel(logLevel); + + if (logFileName) + module->setLogFile(logFileName); + + break; + } + } + if (!module) { + fprintf(stderr, "Incorrect module name \"%s\" in -log option.\n", logModuleName); + printAvailableModules(); + return false; + } +#else + i += 2; +#endif + } else if (!PL_strcmp(argv[i], "-lf") || !PL_strcmp(argv[i], "-logFile")) { + if (!PL_strcmp(argv[++i], "stderr")) + logFileName = 0; + else + logFileName = argv[i]; + } else if (!PL_strcmp(argv[i], "-ln") || !PL_strcmp(argv[i], "-logNames")) { +#ifdef PR_LOGGING + printAvailableModules(); + return false; +#else + PR_fprintf(PR_STDERR, "This copy of sajava does not support logging\n"); + return false; +#endif + } else if (!PL_strcmp(argv[i], "-debug")) + debug = true; + else if (!PL_strcmp(argv[i], "-ce") || !PL_strcmp(argv[i], "-catchHardwareExceptions")) + catchHardwareExceptions = true; + else if (argv[i][0] == '-') { + PR_fprintf(PR_STDERR, "bad option %s\n", argv[i]); + return false; + } else { /* Must be a class name */ + className = VM::getUtfClassName(argv[i++]); +#ifdef DEBUG_laurentm + for (Uint32 l = 0; l < strlen(className); l++) + if (className[l] == '.') + className[l] = '/'; +#endif + if ((nArgs = argc-i) > 0) { + args = new JavaObject *[nArgs]; + argStrings = new const char *[nArgs]; + + for (int j = 0; i < argc; i++, j++) + argStrings[j] = argv[i]; + + } else + args = 0; + + break; + } + } + + return true; +} + +//------------------------------------------------------------------------------ + +#ifdef DEBUG_WALDEMAR + #define PREPEND_DEFAULT_OPTIONS + static const char *const defaultOptions[] = { + "-stage", "o", + "-all", + "-verbose", + "-noinvoke", + "-classpath", "/Full-Stutter/Java/java.jar:/Full-Stutter/Java/Tiny/Java Classes", + "-log", "FieldOrMethod", "3"}; +#endif + + +#ifdef PREPEND_DEFAULT_OPTIONS +// +// Prepend user-specific default options from the defaultOptions array. +// +static void prependDefaultOptions(int &argc, const char **&argv) +{ + int nDefaultOptions = sizeof(defaultOptions) / sizeof(const char *); + if (nDefaultOptions) { + int newArgC = argc + nDefaultOptions; + const char **newArgV = new const char *[newArgC]; + const char **src = argv; + const char **dst = newArgV; + *dst++ = *src++; + copy(defaultOptions, defaultOptions+nDefaultOptions, dst); + dst += nDefaultOptions; + copy(src, src+argc-1, dst); + argc = newArgC; + argv = newArgV; + } +} +#endif + +// We need to actually create a globally +// scoped thread before we use main, because on some platforms +// (NT) NSPR implicit initialization causes us to be on a fiber +// which means that if we mistakenly call any Win32 functions +// that call WaitForSingleObject, etc we end up hanging. +// +// The NSPR people say they will make this happen automagically +// (I won't hold my breath!) =) + +#define MAIN_WRAPPER_RETURN(inWrapper, inRv) \ + PR_BEGIN_MACRO \ + inWrapper->rv = inRv; \ + return; \ + PR_END_MACRO + +struct MainWrapper +{ + int argc; // count of args + const char** argv; // vector of actual strings + int rv; // return value from main +}; + +int main(int argc, const char **argv) +{ + MainWrapper mainWrapper = {argc, argv, -1}; + PRThread* thread; + + thread = PR_CreateThread(PR_USER_THREAD, + &realMain, + &mainWrapper, + PR_PRIORITY_NORMAL, + PR_GLOBAL_THREAD, + PR_JOINABLE_THREAD, + 0); + + if (thread) + PR_JoinThread(thread); + else + trespass("could not create main thread"); + PR_Cleanup(); + return mainWrapper.rv; +} + +void realMain(void* arg) +{ + MainWrapper* mainWrapper = (MainWrapper*) arg; + int argc = mainWrapper->argc; + const char** argv = mainWrapper->argv; + +#ifdef XP_MAC + argc = ccommand((char ***)&argv); +#endif +#ifdef PREPEND_DEFAULT_OPTIONS + prependDefaultOptions(argc, argv); +#endif + Options options; + + if (!options.parse(argc, argv)) + MAIN_WRAPPER_RETURN(mainWrapper, 1); + + if (options.debug) + VM::debugger.enable(); + + if (options.classPath) + VM::setClassPath(options.classPath); + + if (!options.className) { + PR_fprintf(PR_STDERR, "%s: Error: Class name expected.\n", argv[0]); + MAIN_WRAPPER_RETURN(mainWrapper, 1); + } + + if (options.compileAll && options.methodName) { + PR_fprintf(PR_STDERR, "%s: Error: Cannot combine -all with -method.\n", + argv[0]); + MAIN_WRAPPER_RETURN(mainWrapper, 1); + } + + try { +#ifdef DEBUG + VM::theVM.setCompileBreakPoints(options.compileBreakPoints, options.nCompileBreakPoints); + VM::theVM.setExecBreakPoints(options.execBreakPoints, options.nExecBreakPoints); + VM::theVM.setInhibitBackpatching(options.traceAllMethods); + VM::theVM.setEmitHTML(options.emitHTML); +#endif + VM::theVM.setNoInvoke(!options.invokeMethod); + VM::theVM.setCompileStage(options.stage); + VM::theVM.setVerbose(options.verbose); + VM::theVM.setCatchHardwareExceptions(options.catchHardwareExceptions); + + VM::staticInit(options.initialize); + +#ifdef DEBUG + // Don't bother tracing system staticInit + VM::theVM.setTraceAllMethods(options.traceAllMethods); +#endif + } catch (VerifyError err) { + printf("Error initializing VM: %d\n", err.cause); + MAIN_WRAPPER_RETURN(mainWrapper, 1); + } + + int32 i; + /* Load all native libraries specified on the command-line */ + for (i = 0; i < options.numLibs; i++) { + if (!VM::loadLibrary(options.libNames[i])) + printf("Warning: Cannot load library %s\n", options.libNames[i]); + } + + /* Intern all command-line arguments and convert into strings */ + for (i = 0; i < options.nArgs; i++) + options.args[i] = &VM::intern(options.argStrings[i]); + + if (options.compileAll) { + try { + VM::theVM.compileMethods(options.className); + } catch (VerifyError err) { + PR_fprintf(PR_STDERR, "Error loading class/compiling methods: %d\n", + err.cause); + MAIN_WRAPPER_RETURN(mainWrapper, 1); + } + + MAIN_WRAPPER_RETURN(mainWrapper, 0); + } + + /* If we're here, we wish to execute a certain method */ + + // install the platform specific hardware exception handler + if (true || VM::debugger.getEnabled()) { // true->false delegates to debugger +#ifdef _WIN32 + // Check if we want to catch the hardware exception. + if (VM::theVM.getCatchHardwareExceptions()) { + installHardwareExceptionHandler(win32HardwareThrowExit); + } else { + installHardwareExceptionHandler(win32HardwareThrow); + } +#endif + } + + // if using the debugger ignore user's command to execute a class + if (VM::debugger.getEnabled()) + { + printf("Command sequence is remote\n"); + VM::debugger.waitForDebugger(); + } + else + { + try + { + VM::theVM.execute(options.className, options.methodName, + options.methodSig, + options.args, options.nArgs); + } catch (VerifyError err) { + printf("Error loading class/executing method: %d\n", err.cause); + MAIN_WRAPPER_RETURN(mainWrapper, 1); + } + } + + // remove the platform specific hardware exception handler + if (true || VM::debugger.getEnabled()) + removeHardwareExceptionHandler(); + + MAIN_WRAPPER_RETURN(mainWrapper, 0); +} + +#ifdef __GNUC__ +// for gcc with -fhandle-exceptions +void terminate() {} +#endif + +#if defined(_WIN32) && defined(DEBUG_LOG) +void stack(void *inPc) +{ + stackWalker(inPc); +} +#endif diff --git a/ef/Driver/StandAloneJava/macbuild/Debug.Prefix.PPC b/ef/Driver/StandAloneJava/macbuild/Debug.Prefix.PPC new file mode 100644 index 000000000000..46d5f0100bfb --- /dev/null +++ b/ef/Driver/StandAloneJava/macbuild/Debug.Prefix.PPC @@ -0,0 +1,4 @@ +#define DEBUG 1 +#define GENERATE_FOR_PPC +//#define DEBUG_SMSILVER 1 +#include "ElectricalFireConfig.h" diff --git a/ef/Driver/StandAloneJava/macbuild/Debug.Prefix.x86 b/ef/Driver/StandAloneJava/macbuild/Debug.Prefix.x86 new file mode 100644 index 000000000000..6e63619911c5 --- /dev/null +++ b/ef/Driver/StandAloneJava/macbuild/Debug.Prefix.x86 @@ -0,0 +1,4 @@ +#define DEBUG 1 +#define GENERATE_FOR_X86 +//#define DEBUG_SMSILVER 1 +#include "ElectricalFireConfig.h" diff --git a/ef/Driver/StandAloneJava/macbuild/ElectricalFire.prj2 b/ef/Driver/StandAloneJava/macbuild/ElectricalFire.prj2 new file mode 100644 index 000000000000..0309311ca562 Binary files /dev/null and b/ef/Driver/StandAloneJava/macbuild/ElectricalFire.prj2 differ diff --git a/ef/Driver/StandAloneJava/macbuild/ElectricalFireConfig.h b/ef/Driver/StandAloneJava/macbuild/ElectricalFireConfig.h new file mode 100644 index 000000000000..5365ff498123 --- /dev/null +++ b/ef/Driver/StandAloneJava/macbuild/ElectricalFireConfig.h @@ -0,0 +1,46 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#define OLDROUTINELOCATIONS 0 + +#define XP_MAC 1 +#define HAVE_LONG_LONG +#define MISALIGNED_MEMORY_ACCESS_OK +#define _PR_NO_PREEMPT 1 +#define _PR_USECPU 1 +#define _NO_FAST_STRING_INLINES_ 1 +#ifndef DEBUG + #define NDEBUG 1 +#endif + +// DEBUG_LOG controls whether we compile in the routines to disassemble and dump +// internal compiler state to a file or stdout. These are useful even in nondebug +// builds but should not be present in release builds. +// DEBUG_LOG is equivalent to PR_LOGGING; perhaps we should merge these two? +#ifndef RELEASE + #define FORCE_PR_LOG 1 + #define DEBUG_LOG +#endif + +#include "IDE_Options.h" + +#ifndef DEBUG + // Faithfully obey our requests for inlining functions. Without this Metrowerks + // will not inline functions more than four levels deep, which is a serious problem + // for class hierarchies with more than four levels of simple inline constructors. + #pragma always_inline on +#endif diff --git a/ef/Driver/StandAloneJava/macbuild/Prefix.PPC b/ef/Driver/StandAloneJava/macbuild/Prefix.PPC new file mode 100644 index 000000000000..137e860a90f2 --- /dev/null +++ b/ef/Driver/StandAloneJava/macbuild/Prefix.PPC @@ -0,0 +1,3 @@ +#define GENERATE_FOR_PPC +//#define DEBUG_WALDEMAR 1 +#include "ElectricalFireConfig.h" diff --git a/ef/Driver/StandAloneJava/winbuild/.cvsignore b/ef/Driver/StandAloneJava/winbuild/.cvsignore new file mode 100644 index 000000000000..6db941dfa06f --- /dev/null +++ b/ef/Driver/StandAloneJava/winbuild/.cvsignore @@ -0,0 +1,10 @@ +*.plg +*.opt +*.ncb +*.dsw +*.html +genfiles +Debug +Release +electric + diff --git a/ef/Driver/StandAloneJava/winbuild/Burg/.cvsignore b/ef/Driver/StandAloneJava/winbuild/Burg/.cvsignore new file mode 100644 index 000000000000..444f556c6d27 --- /dev/null +++ b/ef/Driver/StandAloneJava/winbuild/Burg/.cvsignore @@ -0,0 +1,5 @@ +*.plg +y.tab.c +y.tab.h +Debug +Release diff --git a/ef/Driver/StandAloneJava/winbuild/Burg/Burg.dsp b/ef/Driver/StandAloneJava/winbuild/Burg/Burg.dsp new file mode 100644 index 000000000000..083d617c1879 --- /dev/null +++ b/ef/Driver/StandAloneJava/winbuild/Burg/Burg.dsp @@ -0,0 +1,226 @@ +# Microsoft Developer Studio Project File - Name="Burg" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 5.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=Burg - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "Burg.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "Burg.mak" CFG="Burg - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "Burg - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "Burg - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "Burg - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "." /I "..\..\..\..\Tools\burg" /I "..\..\..\Exports ..\..\..\Exports\md" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /FR /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# SUBTRACT BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "Burg - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /Gm /GX /Zi /Od /I "." /I "..\..\..\..\Tools\burg\\" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "DEBUG" /FR /YX /FD /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# SUBTRACT BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "Burg - Win32 Release" +# Name "Burg - Win32 Debug" +# Begin Source File + +SOURCE=..\..\..\..\Tools\Burg\b.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\Tools\Burg\be.c +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\Tools\Burg\burs.c +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\Tools\Burg\closure.c +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\Tools\Burg\delta.c +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\Tools\Burg\fe.c +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\Tools\Burg\fe.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\Tools\Burg\gram.y + +!IF "$(CFG)" == "Burg - Win32 Release" + +# Begin Custom Build - Performing Custom-Build Setup +InputPath=..\..\..\..\Tools\Burg\gram.y + +BuildCmds= \ + $(NSTOOLS)\bin\yacc -l -b y.tab -d $(InputPath) + +"y.tab.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + $(BuildCmds) + +"y.tab.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + $(BuildCmds) +# End Custom Build + +!ELSEIF "$(CFG)" == "Burg - Win32 Debug" + +# Begin Custom Build - Performing Custom-Build Setup +InputPath=..\..\..\..\Tools\Burg\gram.y + +BuildCmds= \ + $(MOZ_TOOLS)\bin\yacc -l -b y.tab -d $(InputPath) + +"y.tab.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + $(BuildCmds) + +"y.tab.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + $(BuildCmds) +# End Custom Build + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\Tools\Burg\item.c +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\Tools\Burg\lex.c +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\Tools\Burg\list.c +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\Tools\Burg\main.c +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\Tools\Burg\map.c +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\Tools\Burg\nonterminal.c +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\Tools\Burg\operator.c +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\Tools\Burg\pattern.c +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\Tools\Burg\plank.c +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\Tools\Burg\queue.c +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\Tools\Burg\rule.c +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\Tools\Burg\string.c +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\Tools\Burg\symtab.c +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\Tools\Burg\table.c +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\Tools\Burg\test.c +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\Tools\Burg\trim.c +# End Source File +# Begin Source File + +SOURCE=.\y.tab.c +# End Source File +# Begin Source File + +SOURCE=.\y.tab.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\Tools\Burg\zalloc.c +# End Source File +# End Target +# End Project diff --git a/ef/Driver/StandAloneJava/winbuild/Burg/Burg.mak b/ef/Driver/StandAloneJava/winbuild/Burg/Burg.mak new file mode 100644 index 000000000000..cadffeaa20e0 --- /dev/null +++ b/ef/Driver/StandAloneJava/winbuild/Burg/Burg.mak @@ -0,0 +1,800 @@ +# Microsoft Developer Studio Generated NMAKE File, Based on Burg.dsp +!IF "$(CFG)" == "" +CFG=Burg - Win32 Debug +!MESSAGE No configuration specified. Defaulting to Burg - Win32 Debug. +!ENDIF + +!IF "$(CFG)" != "Burg - Win32 Release" && "$(CFG)" != "Burg - Win32 Debug" +!MESSAGE Invalid configuration "$(CFG)" specified. +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "Burg.mak" CFG="Burg - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "Burg - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "Burg - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE +!ERROR An invalid configuration is specified. +!ENDIF + +!IF "$(OS)" == "Windows_NT" +NULL= +!ELSE +NULL=nul +!ENDIF + +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "Burg - Win32 Release" + +OUTDIR=.\Release +INTDIR=.\Release +# Begin Custom Macros +OutDir=.\Release +# End Custom Macros + +!IF "$(RECURSE)" == "0" + +ALL : "$(OUTDIR)\Burg.exe" "$(OUTDIR)\Burg.bsc" + +!ELSE + +ALL : "$(OUTDIR)\Burg.exe" "$(OUTDIR)\Burg.bsc" + +!ENDIF + +CLEAN : + -@erase "$(INTDIR)\be.obj" + -@erase "$(INTDIR)\be.sbr" + -@erase "$(INTDIR)\burs.obj" + -@erase "$(INTDIR)\burs.sbr" + -@erase "$(INTDIR)\closure.obj" + -@erase "$(INTDIR)\closure.sbr" + -@erase "$(INTDIR)\delta.obj" + -@erase "$(INTDIR)\delta.sbr" + -@erase "$(INTDIR)\fe.obj" + -@erase "$(INTDIR)\fe.sbr" + -@erase "$(INTDIR)\item.obj" + -@erase "$(INTDIR)\item.sbr" + -@erase "$(INTDIR)\lex.obj" + -@erase "$(INTDIR)\lex.sbr" + -@erase "$(INTDIR)\list.obj" + -@erase "$(INTDIR)\list.sbr" + -@erase "$(INTDIR)\main.obj" + -@erase "$(INTDIR)\main.sbr" + -@erase "$(INTDIR)\map.obj" + -@erase "$(INTDIR)\map.sbr" + -@erase "$(INTDIR)\nonterminal.obj" + -@erase "$(INTDIR)\nonterminal.sbr" + -@erase "$(INTDIR)\operator.obj" + -@erase "$(INTDIR)\operator.sbr" + -@erase "$(INTDIR)\pattern.obj" + -@erase "$(INTDIR)\pattern.sbr" + -@erase "$(INTDIR)\plank.obj" + -@erase "$(INTDIR)\plank.sbr" + -@erase "$(INTDIR)\queue.obj" + -@erase "$(INTDIR)\queue.sbr" + -@erase "$(INTDIR)\rule.obj" + -@erase "$(INTDIR)\rule.sbr" + -@erase "$(INTDIR)\string.obj" + -@erase "$(INTDIR)\string.sbr" + -@erase "$(INTDIR)\symtab.obj" + -@erase "$(INTDIR)\symtab.sbr" + -@erase "$(INTDIR)\table.obj" + -@erase "$(INTDIR)\table.sbr" + -@erase "$(INTDIR)\test.obj" + -@erase "$(INTDIR)\test.sbr" + -@erase "$(INTDIR)\trim.obj" + -@erase "$(INTDIR)\trim.sbr" + -@erase "$(INTDIR)\vc50.idb" + -@erase "$(INTDIR)\y.tab.obj" + -@erase "$(INTDIR)\y.tab.sbr" + -@erase "$(INTDIR)\zalloc.obj" + -@erase "$(INTDIR)\zalloc.sbr" + -@erase "$(OUTDIR)\Burg.bsc" + -@erase "$(OUTDIR)\Burg.exe" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +CPP_PROJ=/nologo /ML /W3 /GX /O2 /I "." /I "..\..\..\..\Tools\burg" /I\ + "..\..\..\Exports ..\..\..\Exports\md" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D\ + "_MBCS" /FR"$(INTDIR)\\" /Fp"$(INTDIR)\Burg.pch" /YX /Fo"$(INTDIR)\\"\ + /Fd"$(INTDIR)\\" /FD /c +CPP_OBJS=.\Release/ +CPP_SBRS=.\Release/ +BSC32=bscmake.exe +BSC32_FLAGS=/o"$(OUTDIR)\Burg.bsc" +BSC32_SBRS= \ + "$(INTDIR)\be.sbr" \ + "$(INTDIR)\burs.sbr" \ + "$(INTDIR)\closure.sbr" \ + "$(INTDIR)\delta.sbr" \ + "$(INTDIR)\fe.sbr" \ + "$(INTDIR)\item.sbr" \ + "$(INTDIR)\lex.sbr" \ + "$(INTDIR)\list.sbr" \ + "$(INTDIR)\main.sbr" \ + "$(INTDIR)\map.sbr" \ + "$(INTDIR)\nonterminal.sbr" \ + "$(INTDIR)\operator.sbr" \ + "$(INTDIR)\pattern.sbr" \ + "$(INTDIR)\plank.sbr" \ + "$(INTDIR)\queue.sbr" \ + "$(INTDIR)\rule.sbr" \ + "$(INTDIR)\string.sbr" \ + "$(INTDIR)\symtab.sbr" \ + "$(INTDIR)\table.sbr" \ + "$(INTDIR)\test.sbr" \ + "$(INTDIR)\trim.sbr" \ + "$(INTDIR)\y.tab.sbr" \ + "$(INTDIR)\zalloc.sbr" + +"$(OUTDIR)\Burg.bsc" : "$(OUTDIR)" $(BSC32_SBRS) + $(BSC32) @<< + $(BSC32_FLAGS) $(BSC32_SBRS) +<< + +LINK32=link.exe +LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\ + advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib\ + odbccp32.lib wsock32.lib /nologo /subsystem:console /incremental:no\ + /pdb:"$(OUTDIR)\Burg.pdb" /machine:I386 /out:"$(OUTDIR)\Burg.exe" +LINK32_OBJS= \ + "$(INTDIR)\be.obj" \ + "$(INTDIR)\burs.obj" \ + "$(INTDIR)\closure.obj" \ + "$(INTDIR)\delta.obj" \ + "$(INTDIR)\fe.obj" \ + "$(INTDIR)\item.obj" \ + "$(INTDIR)\lex.obj" \ + "$(INTDIR)\list.obj" \ + "$(INTDIR)\main.obj" \ + "$(INTDIR)\map.obj" \ + "$(INTDIR)\nonterminal.obj" \ + "$(INTDIR)\operator.obj" \ + "$(INTDIR)\pattern.obj" \ + "$(INTDIR)\plank.obj" \ + "$(INTDIR)\queue.obj" \ + "$(INTDIR)\rule.obj" \ + "$(INTDIR)\string.obj" \ + "$(INTDIR)\symtab.obj" \ + "$(INTDIR)\table.obj" \ + "$(INTDIR)\test.obj" \ + "$(INTDIR)\trim.obj" \ + "$(INTDIR)\y.tab.obj" \ + "$(INTDIR)\zalloc.obj" + +"$(OUTDIR)\Burg.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ELSEIF "$(CFG)" == "Burg - Win32 Debug" + +OUTDIR=.\Debug +INTDIR=.\Debug +# Begin Custom Macros +OutDir=.\Debug +# End Custom Macros + +!IF "$(RECURSE)" == "0" + +ALL : "y.tab.h" "y.tab.c" "$(OUTDIR)\Burg.exe" "$(OUTDIR)\Burg.bsc" + +!ELSE + +ALL : "y.tab.h" "y.tab.c" "$(OUTDIR)\Burg.exe" "$(OUTDIR)\Burg.bsc" + +!ENDIF + +CLEAN : + -@erase "$(INTDIR)\be.obj" + -@erase "$(INTDIR)\be.sbr" + -@erase "$(INTDIR)\burs.obj" + -@erase "$(INTDIR)\burs.sbr" + -@erase "$(INTDIR)\closure.obj" + -@erase "$(INTDIR)\closure.sbr" + -@erase "$(INTDIR)\delta.obj" + -@erase "$(INTDIR)\delta.sbr" + -@erase "$(INTDIR)\fe.obj" + -@erase "$(INTDIR)\fe.sbr" + -@erase "$(INTDIR)\item.obj" + -@erase "$(INTDIR)\item.sbr" + -@erase "$(INTDIR)\lex.obj" + -@erase "$(INTDIR)\lex.sbr" + -@erase "$(INTDIR)\list.obj" + -@erase "$(INTDIR)\list.sbr" + -@erase "$(INTDIR)\main.obj" + -@erase "$(INTDIR)\main.sbr" + -@erase "$(INTDIR)\map.obj" + -@erase "$(INTDIR)\map.sbr" + -@erase "$(INTDIR)\nonterminal.obj" + -@erase "$(INTDIR)\nonterminal.sbr" + -@erase "$(INTDIR)\operator.obj" + -@erase "$(INTDIR)\operator.sbr" + -@erase "$(INTDIR)\pattern.obj" + -@erase "$(INTDIR)\pattern.sbr" + -@erase "$(INTDIR)\plank.obj" + -@erase "$(INTDIR)\plank.sbr" + -@erase "$(INTDIR)\queue.obj" + -@erase "$(INTDIR)\queue.sbr" + -@erase "$(INTDIR)\rule.obj" + -@erase "$(INTDIR)\rule.sbr" + -@erase "$(INTDIR)\string.obj" + -@erase "$(INTDIR)\string.sbr" + -@erase "$(INTDIR)\symtab.obj" + -@erase "$(INTDIR)\symtab.sbr" + -@erase "$(INTDIR)\table.obj" + -@erase "$(INTDIR)\table.sbr" + -@erase "$(INTDIR)\test.obj" + -@erase "$(INTDIR)\test.sbr" + -@erase "$(INTDIR)\trim.obj" + -@erase "$(INTDIR)\trim.sbr" + -@erase "$(INTDIR)\vc50.idb" + -@erase "$(INTDIR)\vc50.pdb" + -@erase "$(INTDIR)\y.tab.obj" + -@erase "$(INTDIR)\y.tab.sbr" + -@erase "$(INTDIR)\zalloc.obj" + -@erase "$(INTDIR)\zalloc.sbr" + -@erase "$(OUTDIR)\Burg.bsc" + -@erase "$(OUTDIR)\Burg.exe" + -@erase "$(OUTDIR)\Burg.ilk" + -@erase "$(OUTDIR)\Burg.pdb" + -@erase "y.tab.c" + -@erase "y.tab.h" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +CPP_PROJ=/nologo /MLd /W3 /Gm /GX /Zi /Od /I "." /I "..\..\..\..\Tools\burg\\"\ + /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "DEBUG" /FR"$(INTDIR)\\"\ + /Fp"$(INTDIR)\Burg.pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c +CPP_OBJS=.\Debug/ +CPP_SBRS=.\Debug/ +BSC32=bscmake.exe +BSC32_FLAGS=/o"$(OUTDIR)\Burg.bsc" +BSC32_SBRS= \ + "$(INTDIR)\be.sbr" \ + "$(INTDIR)\burs.sbr" \ + "$(INTDIR)\closure.sbr" \ + "$(INTDIR)\delta.sbr" \ + "$(INTDIR)\fe.sbr" \ + "$(INTDIR)\item.sbr" \ + "$(INTDIR)\lex.sbr" \ + "$(INTDIR)\list.sbr" \ + "$(INTDIR)\main.sbr" \ + "$(INTDIR)\map.sbr" \ + "$(INTDIR)\nonterminal.sbr" \ + "$(INTDIR)\operator.sbr" \ + "$(INTDIR)\pattern.sbr" \ + "$(INTDIR)\plank.sbr" \ + "$(INTDIR)\queue.sbr" \ + "$(INTDIR)\rule.sbr" \ + "$(INTDIR)\string.sbr" \ + "$(INTDIR)\symtab.sbr" \ + "$(INTDIR)\table.sbr" \ + "$(INTDIR)\test.sbr" \ + "$(INTDIR)\trim.sbr" \ + "$(INTDIR)\y.tab.sbr" \ + "$(INTDIR)\zalloc.sbr" + +"$(OUTDIR)\Burg.bsc" : "$(OUTDIR)" $(BSC32_SBRS) + $(BSC32) @<< + $(BSC32_FLAGS) $(BSC32_SBRS) +<< + +LINK32=link.exe +LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\ + advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib\ + odbccp32.lib wsock32.lib /nologo /subsystem:console /incremental:yes\ + /pdb:"$(OUTDIR)\Burg.pdb" /debug /machine:I386 /out:"$(OUTDIR)\Burg.exe"\ + /pdbtype:sept +LINK32_OBJS= \ + "$(INTDIR)\be.obj" \ + "$(INTDIR)\burs.obj" \ + "$(INTDIR)\closure.obj" \ + "$(INTDIR)\delta.obj" \ + "$(INTDIR)\fe.obj" \ + "$(INTDIR)\item.obj" \ + "$(INTDIR)\lex.obj" \ + "$(INTDIR)\list.obj" \ + "$(INTDIR)\main.obj" \ + "$(INTDIR)\map.obj" \ + "$(INTDIR)\nonterminal.obj" \ + "$(INTDIR)\operator.obj" \ + "$(INTDIR)\pattern.obj" \ + "$(INTDIR)\plank.obj" \ + "$(INTDIR)\queue.obj" \ + "$(INTDIR)\rule.obj" \ + "$(INTDIR)\string.obj" \ + "$(INTDIR)\symtab.obj" \ + "$(INTDIR)\table.obj" \ + "$(INTDIR)\test.obj" \ + "$(INTDIR)\trim.obj" \ + "$(INTDIR)\y.tab.obj" \ + "$(INTDIR)\zalloc.obj" + +"$(OUTDIR)\Burg.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ENDIF + +.c{$(CPP_OBJS)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cpp{$(CPP_OBJS)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cxx{$(CPP_OBJS)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.c{$(CPP_SBRS)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cpp{$(CPP_SBRS)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cxx{$(CPP_SBRS)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + + +!IF "$(CFG)" == "Burg - Win32 Release" || "$(CFG)" == "Burg - Win32 Debug" +SOURCE=..\..\..\..\Tools\Burg\be.c + +!IF "$(CFG)" == "Burg - Win32 Release" + +DEP_CPP_BE_C0=\ + "..\..\..\..\Tools\Burg\b.h"\ + "..\..\..\..\Tools\Burg\fe.h"\ + + +"$(INTDIR)\be.obj" "$(INTDIR)\be.sbr" : $(SOURCE) $(DEP_CPP_BE_C0) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "Burg - Win32 Debug" + +DEP_CPP_BE_C0=\ + "..\..\..\..\Tools\Burg\b.h"\ + "..\..\..\..\Tools\Burg\fe.h"\ + + +"$(INTDIR)\be.obj" "$(INTDIR)\be.sbr" : $(SOURCE) $(DEP_CPP_BE_C0) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +SOURCE=..\..\..\..\Tools\Burg\burs.c +DEP_CPP_BURS_=\ + "..\..\..\..\Tools\Burg\b.h"\ + + +"$(INTDIR)\burs.obj" "$(INTDIR)\burs.sbr" : $(SOURCE) $(DEP_CPP_BURS_)\ + "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +SOURCE=..\..\..\..\Tools\Burg\closure.c +DEP_CPP_CLOSU=\ + "..\..\..\..\Tools\Burg\b.h"\ + + +"$(INTDIR)\closure.obj" "$(INTDIR)\closure.sbr" : $(SOURCE) $(DEP_CPP_CLOSU)\ + "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +SOURCE=..\..\..\..\Tools\Burg\delta.c + +!IF "$(CFG)" == "Burg - Win32 Release" + +DEP_CPP_DELTA=\ + "..\..\..\..\Tools\Burg\b.h"\ + "..\..\..\..\Tools\Burg\fe.h"\ + + +"$(INTDIR)\delta.obj" "$(INTDIR)\delta.sbr" : $(SOURCE) $(DEP_CPP_DELTA)\ + "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "Burg - Win32 Debug" + +DEP_CPP_DELTA=\ + "..\..\..\..\Tools\Burg\b.h"\ + "..\..\..\..\Tools\Burg\fe.h"\ + + +"$(INTDIR)\delta.obj" "$(INTDIR)\delta.sbr" : $(SOURCE) $(DEP_CPP_DELTA)\ + "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +SOURCE=..\..\..\..\Tools\Burg\fe.c + +!IF "$(CFG)" == "Burg - Win32 Release" + +DEP_CPP_FE_C8=\ + "..\..\..\..\Tools\Burg\b.h"\ + "..\..\..\..\Tools\Burg\fe.h"\ + + +"$(INTDIR)\fe.obj" "$(INTDIR)\fe.sbr" : $(SOURCE) $(DEP_CPP_FE_C8) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "Burg - Win32 Debug" + +DEP_CPP_FE_C8=\ + "..\..\..\..\Tools\Burg\b.h"\ + "..\..\..\..\Tools\Burg\fe.h"\ + + +"$(INTDIR)\fe.obj" "$(INTDIR)\fe.sbr" : $(SOURCE) $(DEP_CPP_FE_C8) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +SOURCE=..\..\..\..\Tools\Burg\gram.y + +!IF "$(CFG)" == "Burg - Win32 Release" + +InputPath=..\..\..\..\Tools\Burg\gram.y + +"y.tab.c" "y.tab.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + $(NSTOOLS)\bin\yacc -l -b y.tab -d $(InputPath) + +!ELSEIF "$(CFG)" == "Burg - Win32 Debug" + +InputPath=..\..\..\..\Tools\Burg\gram.y + +"y.tab.c" "y.tab.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + $(NSTOOLS)\bin\yacc -l -b y.tab -d $(InputPath) + +!ENDIF + +SOURCE=..\..\..\..\Tools\Burg\item.c + +!IF "$(CFG)" == "Burg - Win32 Release" + +DEP_CPP_ITEM_=\ + "..\..\..\..\Tools\Burg\b.h"\ + "..\..\..\..\Tools\Burg\fe.h"\ + + +"$(INTDIR)\item.obj" "$(INTDIR)\item.sbr" : $(SOURCE) $(DEP_CPP_ITEM_)\ + "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "Burg - Win32 Debug" + +DEP_CPP_ITEM_=\ + "..\..\..\..\Tools\Burg\b.h"\ + "..\..\..\..\Tools\Burg\fe.h"\ + + +"$(INTDIR)\item.obj" "$(INTDIR)\item.sbr" : $(SOURCE) $(DEP_CPP_ITEM_)\ + "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +SOURCE=..\..\..\..\Tools\Burg\lex.c + +!IF "$(CFG)" == "Burg - Win32 Release" + +DEP_CPP_LEX_C=\ + "..\..\..\..\Tools\Burg\b.h"\ + "..\..\..\..\Tools\Burg\fe.h"\ + ".\y.tab.h"\ + + +"$(INTDIR)\lex.obj" "$(INTDIR)\lex.sbr" : $(SOURCE) $(DEP_CPP_LEX_C)\ + "$(INTDIR)" ".\y.tab.h" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "Burg - Win32 Debug" + +DEP_CPP_LEX_C=\ + "..\..\..\..\Tools\Burg\b.h"\ + "..\..\..\..\Tools\Burg\fe.h"\ + "..\..\..\..\tools\burg\y.tab.h"\ + + +"$(INTDIR)\lex.obj" "$(INTDIR)\lex.sbr" : $(SOURCE) $(DEP_CPP_LEX_C)\ + "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +SOURCE=..\..\..\..\Tools\Burg\list.c +DEP_CPP_LIST_=\ + "..\..\..\..\Tools\Burg\b.h"\ + + +"$(INTDIR)\list.obj" "$(INTDIR)\list.sbr" : $(SOURCE) $(DEP_CPP_LIST_)\ + "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +SOURCE=..\..\..\..\Tools\Burg\main.c + +!IF "$(CFG)" == "Burg - Win32 Release" + +DEP_CPP_MAIN_=\ + "..\..\..\..\Tools\Burg\b.h"\ + "..\..\..\..\Tools\Burg\fe.h"\ + + +"$(INTDIR)\main.obj" "$(INTDIR)\main.sbr" : $(SOURCE) $(DEP_CPP_MAIN_)\ + "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "Burg - Win32 Debug" + +DEP_CPP_MAIN_=\ + "..\..\..\..\Tools\Burg\b.h"\ + "..\..\..\..\Tools\Burg\fe.h"\ + + +"$(INTDIR)\main.obj" "$(INTDIR)\main.sbr" : $(SOURCE) $(DEP_CPP_MAIN_)\ + "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +SOURCE=..\..\..\..\Tools\Burg\map.c +DEP_CPP_MAP_C=\ + "..\..\..\..\Tools\Burg\b.h"\ + + +"$(INTDIR)\map.obj" "$(INTDIR)\map.sbr" : $(SOURCE) $(DEP_CPP_MAP_C)\ + "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +SOURCE=..\..\..\..\Tools\Burg\nonterminal.c +DEP_CPP_NONTE=\ + "..\..\..\..\Tools\Burg\b.h"\ + + +"$(INTDIR)\nonterminal.obj" "$(INTDIR)\nonterminal.sbr" : $(SOURCE)\ + $(DEP_CPP_NONTE) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +SOURCE=..\..\..\..\Tools\Burg\operator.c +DEP_CPP_OPERA=\ + "..\..\..\..\Tools\Burg\b.h"\ + + +"$(INTDIR)\operator.obj" "$(INTDIR)\operator.sbr" : $(SOURCE) $(DEP_CPP_OPERA)\ + "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +SOURCE=..\..\..\..\Tools\Burg\pattern.c +DEP_CPP_PATTE=\ + "..\..\..\..\Tools\Burg\b.h"\ + + +"$(INTDIR)\pattern.obj" "$(INTDIR)\pattern.sbr" : $(SOURCE) $(DEP_CPP_PATTE)\ + "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +SOURCE=..\..\..\..\Tools\Burg\plank.c + +!IF "$(CFG)" == "Burg - Win32 Release" + +DEP_CPP_PLANK=\ + "..\..\..\..\Tools\Burg\b.h"\ + "..\..\..\..\Tools\Burg\fe.h"\ + + +"$(INTDIR)\plank.obj" "$(INTDIR)\plank.sbr" : $(SOURCE) $(DEP_CPP_PLANK)\ + "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "Burg - Win32 Debug" + +DEP_CPP_PLANK=\ + "..\..\..\..\Tools\Burg\b.h"\ + "..\..\..\..\Tools\Burg\fe.h"\ + + +"$(INTDIR)\plank.obj" "$(INTDIR)\plank.sbr" : $(SOURCE) $(DEP_CPP_PLANK)\ + "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +SOURCE=..\..\..\..\Tools\Burg\queue.c +DEP_CPP_QUEUE=\ + "..\..\..\..\Tools\Burg\b.h"\ + + +"$(INTDIR)\queue.obj" "$(INTDIR)\queue.sbr" : $(SOURCE) $(DEP_CPP_QUEUE)\ + "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +SOURCE=..\..\..\..\Tools\Burg\rule.c +DEP_CPP_RULE_=\ + "..\..\..\..\Tools\Burg\b.h"\ + + +"$(INTDIR)\rule.obj" "$(INTDIR)\rule.sbr" : $(SOURCE) $(DEP_CPP_RULE_)\ + "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +SOURCE=..\..\..\..\Tools\Burg\string.c + +!IF "$(CFG)" == "Burg - Win32 Release" + +DEP_CPP_STRIN=\ + "..\..\..\..\Tools\Burg\b.h"\ + "..\..\..\..\Tools\Burg\fe.h"\ + + +"$(INTDIR)\string.obj" "$(INTDIR)\string.sbr" : $(SOURCE) $(DEP_CPP_STRIN)\ + "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "Burg - Win32 Debug" + +DEP_CPP_STRIN=\ + "..\..\..\..\Tools\Burg\b.h"\ + "..\..\..\..\Tools\Burg\fe.h"\ + + +"$(INTDIR)\string.obj" "$(INTDIR)\string.sbr" : $(SOURCE) $(DEP_CPP_STRIN)\ + "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +SOURCE=..\..\..\..\Tools\Burg\symtab.c + +!IF "$(CFG)" == "Burg - Win32 Release" + +DEP_CPP_SYMTA=\ + "..\..\..\..\Tools\Burg\b.h"\ + "..\..\..\..\Tools\Burg\fe.h"\ + + +"$(INTDIR)\symtab.obj" "$(INTDIR)\symtab.sbr" : $(SOURCE) $(DEP_CPP_SYMTA)\ + "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "Burg - Win32 Debug" + +DEP_CPP_SYMTA=\ + "..\..\..\..\Tools\Burg\b.h"\ + "..\..\..\..\Tools\Burg\fe.h"\ + + +"$(INTDIR)\symtab.obj" "$(INTDIR)\symtab.sbr" : $(SOURCE) $(DEP_CPP_SYMTA)\ + "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +SOURCE=..\..\..\..\Tools\Burg\table.c +DEP_CPP_TABLE=\ + "..\..\..\..\Tools\Burg\b.h"\ + + +"$(INTDIR)\table.obj" "$(INTDIR)\table.sbr" : $(SOURCE) $(DEP_CPP_TABLE)\ + "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +SOURCE=..\..\..\..\Tools\Burg\test.c + +"$(INTDIR)\test.obj" "$(INTDIR)\test.sbr" : $(SOURCE) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +SOURCE=..\..\..\..\Tools\Burg\trim.c + +!IF "$(CFG)" == "Burg - Win32 Release" + +DEP_CPP_TRIM_=\ + "..\..\..\..\Tools\Burg\b.h"\ + "..\..\..\..\Tools\Burg\fe.h"\ + + +"$(INTDIR)\trim.obj" "$(INTDIR)\trim.sbr" : $(SOURCE) $(DEP_CPP_TRIM_)\ + "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "Burg - Win32 Debug" + +DEP_CPP_TRIM_=\ + "..\..\..\..\Tools\Burg\b.h"\ + "..\..\..\..\Tools\Burg\fe.h"\ + + +"$(INTDIR)\trim.obj" "$(INTDIR)\trim.sbr" : $(SOURCE) $(DEP_CPP_TRIM_)\ + "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +SOURCE=.\y.tab.c + +!IF "$(CFG)" == "Burg - Win32 Release" + +DEP_CPP_Y_TAB=\ + "..\..\..\..\Tools\Burg\b.h"\ + "..\..\..\..\Tools\Burg\fe.h"\ + + +"$(INTDIR)\y.tab.obj" "$(INTDIR)\y.tab.sbr" : $(SOURCE) $(DEP_CPP_Y_TAB)\ + "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Burg - Win32 Debug" + +DEP_CPP_Y_TAB=\ + "..\..\..\..\Tools\Burg\b.h"\ + "..\..\..\..\Tools\Burg\fe.h"\ + + +"$(INTDIR)\y.tab.obj" "$(INTDIR)\y.tab.sbr" : $(SOURCE) $(DEP_CPP_Y_TAB)\ + "$(INTDIR)" + + +!ENDIF + +SOURCE=..\..\..\..\Tools\Burg\zalloc.c +DEP_CPP_ZALLO=\ + "..\..\..\..\Tools\Burg\b.h"\ + + +"$(INTDIR)\zalloc.obj" "$(INTDIR)\zalloc.sbr" : $(SOURCE) $(DEP_CPP_ZALLO)\ + "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + + +!ENDIF + diff --git a/ef/Driver/StandAloneJava/winbuild/DebuggerChannel.dsp b/ef/Driver/StandAloneJava/winbuild/DebuggerChannel.dsp new file mode 100644 index 000000000000..5bdc2061cbf4 --- /dev/null +++ b/ef/Driver/StandAloneJava/winbuild/DebuggerChannel.dsp @@ -0,0 +1,100 @@ +# Microsoft Developer Studio Project File - Name="DebuggerChannel" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 5.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=DebuggerChannel - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "DebuggerChannel.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "DebuggerChannel.mak" CFG="DebuggerChannel - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "DebuggerChannel - Win32 Release" (based on\ + "Win32 (x86) Dynamic-Link Library") +!MESSAGE "DebuggerChannel - Win32 Debug" (based on\ + "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "DebuggerChannel - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Debugger" +# PROP BASE Intermediate_Dir "Debugger" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c +# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\..\Exports" /I "..\..\..\Exports\md" /I "..\..\..\Utilities\General" /I "..\..\..\Utilities\General\md" /I "..\..\..\Compiler\FrontEnd" /I "..\..\..\Compiler\PrimitiveGraph" /I "..\..\..\Runtime\System\md\x86" /I "..\..\..\..\dist\WINNT4.0_DBG.OBJ\include" /I "..\..\..\Utilities\zlib" /I "..\..\..\Runtime\ClassInfo" /I "..\..\..\Runtime\ClassReader" /I "..\..\..\Runtime\FileReader" /I "..\..\..\Runtime\NativeMethods" /I "..\..\..\Runtime\Systems" /I "..\..\..\Compiler\CodeGenerator" /I "..\..\..\Compiler\RegisterAllocator" /I "..\..\..\Compiler\CodeGenerator\md\x86\x86dis" /I "..\..\..\Compiler\CodeGenerator\md\x86" /I "..\..\..\Compiler\CodeGenerator\md" /I ".\\" /I ".\genfiles" /I "..\..\..\Compiler\Optimizer" /I "..\..\..\Driver\StandAloneJava" /I "..\..\..\Runtime\System" /I "..\..\..\Debugger" /I "..\..\..\Runtime\System\md" /I "..\..\..\Debugger\Communication" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386 +# ADD LINK32 ..\..\..\..\dist\WINNT4.0_DBG.OBJ\lib\libnspr21.lib ..\..\..\..\dist\WINNT4.0_DBG.OBJ\lib\libplc21_s.lib wsock32.lib kernel32.lib user32.lib /nologo /subsystem:windows /dll /machine:I386 + +!ELSEIF "$(CFG)" == "DebuggerChannel - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "electric" +# PROP Intermediate_Dir "electric" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c +# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I "..\..\..\Exports" /I "..\..\..\Exports\md" /I "..\..\..\Utilities\General" /I "..\..\..\Utilities\General\md" /I "..\..\..\Compiler\FrontEnd" /I "..\..\..\Compiler\PrimitiveGraph" /I "..\..\..\Runtime\System\md\x86" /I "..\..\..\..\dist\WINNT4.0_DBG.OBJ\include" /I "..\..\..\Utilities\zlib" /I "..\..\..\Runtime\ClassInfo" /I "..\..\..\Runtime\ClassReader" /I "..\..\..\Runtime\FileReader" /I "..\..\..\Runtime\NativeMethods" /I "..\..\..\Runtime\Systems" /I "..\..\..\Compiler\CodeGenerator" /I "..\..\..\Compiler\RegisterAllocator" /I "..\..\..\Compiler\CodeGenerator\md\x86\x86dis" /I "..\..\..\Compiler\CodeGenerator\md\x86" /I "..\..\..\Compiler\CodeGenerator\md" /I ".\\" /I ".\genfiles" /I "..\..\..\Compiler\Optimizer" /I "..\..\..\Driver\StandAloneJava" /I "..\..\..\Runtime\System" /I "..\..\..\Debugger" /I "..\..\..\Runtime\System\md" /I "..\..\..\Debugger\Communication" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 ..\..\..\..\dist\WINNT4.0_DBG.OBJ\lib\libnspr21.lib ..\..\..\..\dist\WINNT4.0_DBG.OBJ\lib\libplc21_s.lib wsock32.lib kernel32.lib user32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "DebuggerChannel - Win32 Release" +# Name "DebuggerChannel - Win32 Debug" +# Begin Source File + +SOURCE=..\..\..\Debugger\Communication\DebuggerChannel.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Debugger\Communication\DebuggerChannel.h +# End Source File +# End Target +# End Project diff --git a/ef/Driver/StandAloneJava/winbuild/ElectricalFire.dsw b/ef/Driver/StandAloneJava/winbuild/ElectricalFire.dsw new file mode 100644 index 000000000000..1897a4436fcb --- /dev/null +++ b/ef/Driver/StandAloneJava/winbuild/ElectricalFire.dsw @@ -0,0 +1,139 @@ +Microsoft Developer Studio Workspace File, Format Version 5.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "Burg"=.\Burg\Burg.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "DebuggerChannel"=.\DebuggerChannel.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "NADGrammar"=..\..\..\Tools\Nad\NADGrammar\winbuild\NADGrammar.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "Package"=.\Package\Package.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name electricalfire + End Project Dependency +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name javah + End Project Dependency +}}} + +############################################################################### + +Project: "electricalfire"=.\electricalfire.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name Burg + End Project Dependency +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name DebuggerChannel + End Project Dependency +}}} + +############################################################################### + +Project: "furmon"=..\..\..\Tools\Monitor\winbuild\furmon.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "javah"=.\javah.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name electricalfire + End Project Dependency +}}} + +############################################################################### + +Project: "sajava"=.\sajava.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name electricalfire + End Project Dependency +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/ef/Driver/StandAloneJava/winbuild/Package/.cvsignore b/ef/Driver/StandAloneJava/winbuild/Package/.cvsignore new file mode 100644 index 000000000000..3e56df41bdca --- /dev/null +++ b/ef/Driver/StandAloneJava/winbuild/Package/.cvsignore @@ -0,0 +1,6 @@ +electric +Release +Debug +*.plg +*.idb +*.pdb diff --git a/ef/Driver/StandAloneJava/winbuild/Package/Package.dsp b/ef/Driver/StandAloneJava/winbuild/Package/Package.dsp new file mode 100644 index 000000000000..47ad381d075b --- /dev/null +++ b/ef/Driver/StandAloneJava/winbuild/Package/Package.dsp @@ -0,0 +1,609 @@ +# Microsoft Developer Studio Project File - Name="Package" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 5.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=Package - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "Package.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "Package.mak" CFG="Package - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "Package - Win32 Release" (based on\ + "Win32 (x86) Dynamic-Link Library") +!MESSAGE "Package - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "Package - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "..\Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c +# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\..\..\Debugger\Communication" /I "..\..\..\..\Driver\StandAloneJava" /I "..\..\..\..\Utilities\General" /I "..\genfiles" /I "..\..\..\..\Compiler\FrontEnd" /I "..\..\..\..\Compiler\PrimitiveGraph" /I "..\..\..\..\Runtime\System" /I "..\..\..\..\..\dist\WINNT4.0_DBG.OBJ\include" /I "..\..\..\..\Utilities\zlib" /I "..\..\..\..\Runtime\ClassInfo" /I "..\..\..\..\Runtime\ClassReader" /I "..\..\..\..\Runtime\FileReader" /I "..\..\..\..\Runtime\NativeMethods" /I "..\..\..\..\Compiler\CodeGenerator" /I "..\..\..\..\Compiler\RegisterAllocator" /I "..\..\..\..\Compiler\CodeGenerator\md\x86\x86dis" /I "..\..\..\..\Compiler\CodeGenerator\md\x86" /I "..\..\..\..\Compiler\CodeGenerator\md" /I ".\\" /I ".\genfiles" /I "..\..\..\..\Compiler\Optimizer" /I "..\..\..\..\Packages\java\lang\nativesrc\geninclude" /I "..\..\..\..\Packages\java\io\nativesrc\geninclude" /I "..\..\..\..\Packages\java\security\nativesrc\geninclude" /I "..\..\..\..\Debugger" /I "..\..\..\..\Exports" /I "..\..\..\..\Exports\md" /I "..\..\..\..\Runtime\System\md\x86" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "EF_WINDOWS" /D "GENERATE_FOR_X86" /D "_CONSOLE" /D "_MBCS" /D "XP_PC" /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /dll /machine:I386 +# ADD LINK32 ..\release\electricalfire.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib ..\..\..\..\..\dist\WINNT4.0_DBG.OBJ\lib\libnspr21.lib ..\..\..\..\..\dist\WINNT4.0_DBG.OBJ\lib\libplc21_s.lib wsock32.lib /nologo /subsystem:console /dll /machine:I386 +# SUBTRACT LINK32 /debug + +!ELSEIF "$(CFG)" == "Package - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "..\electric" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c +# ADD CPP /nologo /MDd /W3 /GX /Zi /I "..\..\..\..\Debugger\Communication" /I "..\..\..\..\Driver\StandAloneJava" /I "..\..\..\..\Utilities\General" /I "..\genfiles" /I "..\..\..\..\Compiler\FrontEnd" /I "..\..\..\..\Compiler\PrimitiveGraph" /I "..\..\..\..\Runtime\System" /I "..\..\..\..\..\dist\WINNT4.0_DBG.OBJ\include" /I "..\..\..\..\Utilities\zlib" /I "..\..\..\..\Runtime\ClassInfo" /I "..\..\..\..\Runtime\ClassReader" /I "..\..\..\..\Runtime\FileReader" /I "..\..\..\..\Runtime\NativeMethods" /I "..\..\..\..\Compiler\CodeGenerator" /I "..\..\..\..\Compiler\RegisterAllocator" /I "..\..\..\..\Compiler\CodeGenerator\md\x86\x86dis" /I "..\..\..\..\Compiler\CodeGenerator\md\x86" /I "..\..\..\..\Compiler\CodeGenerator\md" /I ".\\" /I ".\genfiles" /I "..\..\..\..\Compiler\Optimizer" /I "..\..\..\..\Packages\java\lang\nativesrc\geninclude" /I "..\..\..\..\Packages\java\io\nativesrc\geninclude" /I "..\..\..\..\Packages\java\security\nativesrc\geninclude" /I "..\..\..\..\Debugger" /I "..\..\..\..\Exports" /I "..\..\..\..\Exports\md" /I "..\..\..\..\Runtime\System\md\x86" /D "DEBUG" /D "EF_WINDOWS" /D "GENERATE_FOR_X86" /D "DEBUG_DESANTIS" /D "DEBUG_kini" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "XP_PC" /D "IMPORTING_VM_FILES" /FR"electric/" /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 ..\electric\electricalfire.lib kernel32.lib user32.lib ..\..\..\..\..\dist\WINNT4.0_DBG.OBJ\lib\libnspr21.lib ..\..\..\..\..\dist\WINNT4.0_DBG.OBJ\lib\libplc21_s.lib wsock32.lib /nologo /subsystem:console /dll /debug /machine:I386 /pdbtype:sept +# SUBTRACT LINK32 /pdb:none + +!ENDIF + +# Begin Target + +# Name "Package - Win32 Release" +# Name "Package - Win32 Debug" +# Begin Group "java" + +# PROP Default_Filter "" +# Begin Group "lang" + +# PROP Default_Filter "" +# Begin Group "reflect" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\..\Packages\java\lang\nativesrc\reflect\Array.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\Packages\java\lang\nativesrc\reflect\Constructor.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\Packages\java\lang\nativesrc\reflect\Field.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\Packages\java\lang\nativesrc\reflect\Method.cpp +# End Source File +# End Group +# Begin Source File + +SOURCE=..\..\..\..\Packages\java\lang\nativesrc\Character.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\Packages\java\lang\nativesrc\Class.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\Packages\java\lang\nativesrc\ClassLoader.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\Packages\java\lang\nativesrc\Compiler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\Packages\java\lang\nativesrc\Double.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\Packages\java\lang\nativesrc\Float.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\Packages\java\lang\nativesrc\Math.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\Packages\java\lang\nativesrc\Object.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\Packages\java\lang\nativesrc\Runtime.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\Packages\java\lang\nativesrc\SecurityManager.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\Packages\java\lang\nativesrc\String.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\Packages\java\lang\nativesrc\System.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\Packages\java\lang\nativesrc\Thread.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\Packages\java\lang\nativesrc\Throwable.cpp +# End Source File +# End Group +# Begin Group "io" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\..\Packages\java\io\nativesrc\File.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\Packages\java\io\nativesrc\FileDescriptor.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\Packages\java\io\nativesrc\FileInputStream.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\Packages\java\io\nativesrc\FileOutputStream.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\Packages\java\io\nativesrc\Mapping.h +# End Source File +# End Group +# Begin Group "security" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\..\Packages\java\security\nativesrc\AccessController.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\Packages\java\security\nativesrc\ProtectionDomain.cpp +# End Source File +# End Group +# Begin Group "util" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\..\Packages\java\util\nativesrc\ResourceBundle.cpp +# ADD CPP /I "..\..\..\..\Packages\java\util\nativesrc\geninclude" +# End Source File +# End Group +# End Group +# Begin Group "GeneratedFiles" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\..\Packages\java\io\nativesrc\geninclude\java_io_File.h +# End Source File +# Begin Source File + +SOURCE=\ +..\..\..\..\Packages\java\io\nativesrc\geninclude\java_io_FileDescriptor.h +# End Source File +# Begin Source File + +SOURCE=\ +..\..\..\..\Packages\java\io\nativesrc\geninclude\java_io_FileInputStream.h +# End Source File +# Begin Source File + +SOURCE=\ +..\..\..\..\Packages\java\io\nativesrc\geninclude\java_io_FileOutputStream.h +# End Source File +# Begin Source File + +SOURCE=\ +..\..\..\..\Packages\java\io\nativesrc\geninclude\java_io_FilterOutputStream.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\Packages\java\io\nativesrc\geninclude\java_io_InputStream.h +# End Source File +# Begin Source File + +SOURCE=\ +..\..\..\..\Packages\java\io\nativesrc\geninclude\java_io_ObjectInputStream.h +# End Source File +# Begin Source File + +SOURCE=\ +..\..\..\..\Packages\java\io\nativesrc\geninclude\java_io_ObjectStreamClass.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\Packages\java\io\nativesrc\geninclude\java_io_OutputStream.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\Packages\java\io\nativesrc\geninclude\java_io_PrintStream.h +# End Source File +# Begin Source File + +SOURCE=\ +..\..\..\..\Packages\java\io\nativesrc\geninclude\java_io_RandomAccessFile.h +# End Source File +# Begin Source File + +SOURCE=\ +..\..\..\..\Packages\java\lang\nativesrc\geninclude\java_lang_ArithmeticException.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\Packages\java\lang\nativesrc\geninclude\java_lang_Class.h +# End Source File +# Begin Source File + +SOURCE=\ +..\..\..\..\Packages\java\lang\nativesrc\geninclude\java_lang_ClassLoader.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\Packages\java\lang\nativesrc\geninclude\java_lang_Compiler.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\Packages\java\lang\nativesrc\geninclude\java_lang_Double.h +# End Source File +# Begin Source File + +SOURCE=\ +..\..\..\..\Packages\java\lang\nativesrc\geninclude\java_lang_Exception.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\Packages\java\lang\nativesrc\geninclude\java_lang_Float.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\Packages\java\lang\nativesrc\geninclude\java_lang_Math.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\Packages\java\lang\nativesrc\geninclude\java_lang_Number.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\Packages\java\lang\nativesrc\geninclude\java_lang_Object.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\Packages\java\lang\nativesrc\geninclude\java_lang_Runtime.h +# End Source File +# Begin Source File + +SOURCE=\ +..\..\..\..\Packages\java\lang\nativesrc\geninclude\java_lang_RuntimeException.h +# End Source File +# Begin Source File + +SOURCE=\ +..\..\..\..\Packages\java\lang\nativesrc\geninclude\java_lang_SecurityManager.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\Packages\java\lang\nativesrc\geninclude\java_lang_String.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\Packages\java\lang\nativesrc\geninclude\java_lang_System.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\Packages\java\lang\nativesrc\geninclude\java_lang_Thread.h +# End Source File +# Begin Source File + +SOURCE=\ +..\..\..\..\Packages\java\lang\nativesrc\geninclude\java_lang_Throwable.h +# End Source File +# Begin Source File + +SOURCE=\ +..\..\..\..\Packages\java\security\nativesrc\geninclude\java_security_AccessController.h +# End Source File +# Begin Source File + +SOURCE=\ +..\..\..\..\Packages\java\security\nativesrc\geninclude\java_security_ProtectionDomain.h +# End Source File +# Begin Source File + +SOURCE=\ +..\..\..\..\Packages\java\util\nativesrc\geninclude\java_util_ResourceBundle.h +# End Source File +# End Group +# Begin Source File + +SOURCE=..\..\..\..\..\dist\classes\java\security\AccessController.class + +!IF "$(CFG)" == "Package - Win32 Release" + +# Begin Custom Build +InputPath=..\..\..\..\..\dist\classes\java\security\AccessController.class + +"..\..\..\..\Packages\java\lsecurity\nativesrc\geninclude\ProtectionDomain.h" :\ + $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + ..\release\javah -classpath ../../../../../dist/classes -d\ + ../../../../Packages/java/security/nativesrc/geninclude\ + java/security/AccessController java/security/ProtectionDomain + +# End Custom Build + +!ELSEIF "$(CFG)" == "Package - Win32 Debug" + +# Begin Custom Build +InputPath=..\..\..\..\..\dist\classes\java\security\AccessController.class + +"..\..\..\..\Packages\java\lsecurity\nativesrc\geninclude\ProtectionDomain.h" :\ + $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + ..\electric\javah -classpath ../../../../../dist/classes -d\ + ../../../../Packages/java/security/nativesrc/geninclude\ + java/security/AccessController java/security/ProtectionDomain + +# End Custom Build + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\..\dist\classes\java\lang\Class.class + +!IF "$(CFG)" == "Package - Win32 Release" + +# Begin Custom Build - Generating Header files for java/lang +InputPath=..\..\..\..\..\dist\classes\java\lang\Class.class + +BuildCmds= \ + ..\release\javah -classpath ../../../../../dist/classes -d\ + ../../../../Packages/java/lang/nativesrc/geninclude\ + java/lang/ArithmeticException java/lang/Character java/lang/Class\ + java/lang/ClassLoader java/lang/Compiler java/lang/Double java/lang/Float\ + java/lang/Math java/lang/Runtime java/lang/SecurityManager\ + java/lang/System java/lang/String java/lang/Thread\ + java/lang/reflect/Field java/lang/reflect/Method java/lang/reflect/Constructor\ + java/lang/reflect/Array java/util/Properties + +"..\..\..\..\Packages\java\lang\nativesrc\geninclude\java_lang_Class.h" : \ +$(SOURCE) "$(INTDIR)" "$(OUTDIR)" + $(BuildCmds) + +"..\..\..\..\Packages\java\lang\nativesrc\geninclude\java_lang_ClassLoader.h" :\ + $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + $(BuildCmds) + +"..\..\..\..\Packages\java\lang\nativesrc\geninclude\java_lang_Compiler.h" : \ +$(SOURCE) "$(INTDIR)" "$(OUTDIR)" + $(BuildCmds) + +"..\..\..\..\Packages\java\lang\nativesrc\geninclude\java_lang_Double.h" : \ +$(SOURCE) "$(INTDIR)" "$(OUTDIR)" + $(BuildCmds) + +"..\..\..\..\Packages\java\lang\nativesrc\geninclude\java_lang_Float.h" : \ +$(SOURCE) "$(INTDIR)" "$(OUTDIR)" + $(BuildCmds) + +"..\..\..\..\Packages\java\lang\nativesrc\geninclude\java_lang_Math.h" : \ +$(SOURCE) "$(INTDIR)" "$(OUTDIR)" + $(BuildCmds) + +"..\..\..\..\Packages\java\lang\nativesrc\geninclude\java_lang_Runtime.h" : \ +$(SOURCE) "$(INTDIR)" "$(OUTDIR)" + $(BuildCmds) + +"..\..\..\..\Packages\java\lang\nativesrc\geninclude\java_lang_System.h" : \ +$(SOURCE) "$(INTDIR)" "$(OUTDIR)" + $(BuildCmds) + +"..\..\..\..\Packages\java\lang\nativesrc\geninclude\java_lang_String.h" : \ +$(SOURCE) "$(INTDIR)" "$(OUTDIR)" + $(BuildCmds) + +"..\..\..\..\Packages\java\lang\nativesrc\geninclude\java_lang_Thread.h" : \ +$(SOURCE) "$(INTDIR)" "$(OUTDIR)" + $(BuildCmds) + +"..\..\..\..\Packages\java\lang\nativesrc\geninclude\java_lang_Number.h" : \ +$(SOURCE) "$(INTDIR)" "$(OUTDIR)" + $(BuildCmds) + +"..\..\..\..\Packages\java\lang\nativesrc\geninclude\java_lang_Ref.h" : \ +$(SOURCE) "$(INTDIR)" "$(OUTDIR)" + $(BuildCmds) + +"..\..\..\..\Packages\java\lang\nativesrc\geninclude\java_lang_Exception.h" : \ +$(SOURCE) "$(INTDIR)" "$(OUTDIR)" + $(BuildCmds) + +"..\..\..\..\Packages\java\lang\nativesrc\geninclude\java_util_properties.h" : \ +$(SOURCE) "$(INTDIR)" "$(OUTDIR)" + $(BuildCmds) +# End Custom Build + +!ELSEIF "$(CFG)" == "Package - Win32 Debug" + +# Begin Custom Build - Generating Header files for java/lang +InputPath=..\..\..\..\..\dist\classes\java\lang\Class.class + +BuildCmds= \ + ..\electric\javah -classpath ../../../../../dist/classes -d\ + ../../../../Packages/java/lang/nativesrc/geninclude\ + java/lang/ArithmeticException java/lang/Character java/lang/Class\ + java/lang/ClassLoader java/lang/Compiler java/lang/Double java/lang/Float\ + java/lang/Math java/lang/Runtime java/lang/SecurityManager\ + java/lang/System java/lang/String java/lang/Thread\ + java/lang/reflect/Field java/lang/reflect/Method java/lang/reflect/Constructor\ + java/lang/reflect/Array java/util/Properties + +"..\..\..\..\Packages\java\lang\nativesrc\geninclude\java_lang_Class.h" : \ +$(SOURCE) "$(INTDIR)" "$(OUTDIR)" + $(BuildCmds) + +"..\..\..\..\Packages\java\lang\nativesrc\geninclude\java_lang_ClassLoader.h" :\ + $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + $(BuildCmds) + +"..\..\..\..\Packages\java\lang\nativesrc\geninclude\java_lang_Compiler.h" : \ +$(SOURCE) "$(INTDIR)" "$(OUTDIR)" + $(BuildCmds) + +"..\..\..\..\Packages\java\lang\nativesrc\geninclude\java_lang_Double.h" : \ +$(SOURCE) "$(INTDIR)" "$(OUTDIR)" + $(BuildCmds) + +"..\..\..\..\Packages\java\lang\nativesrc\geninclude\java_lang_Float.h" : \ +$(SOURCE) "$(INTDIR)" "$(OUTDIR)" + $(BuildCmds) + +"..\..\..\..\Packages\java\lang\nativesrc\geninclude\java_lang_Math.h" : \ +$(SOURCE) "$(INTDIR)" "$(OUTDIR)" + $(BuildCmds) + +"..\..\..\..\Packages\java\lang\nativesrc\geninclude\java_lang_Runtime.h" : \ +$(SOURCE) "$(INTDIR)" "$(OUTDIR)" + $(BuildCmds) + +"..\..\..\..\Packages\java\lang\nativesrc\geninclude\java_lang_System.h" : \ +$(SOURCE) "$(INTDIR)" "$(OUTDIR)" + $(BuildCmds) + +"..\..\..\..\Packages\java\lang\nativesrc\geninclude\java_lang_String.h" : \ +$(SOURCE) "$(INTDIR)" "$(OUTDIR)" + $(BuildCmds) + +"..\..\..\..\Packages\java\lang\nativesrc\geninclude\java_lang_Thread.h" : \ +$(SOURCE) "$(INTDIR)" "$(OUTDIR)" + $(BuildCmds) + +"..\..\..\..\Packages\java\lang\nativesrc\geninclude\java_lang_Number.h" : \ +$(SOURCE) "$(INTDIR)" "$(OUTDIR)" + $(BuildCmds) + +"..\..\..\..\Packages\java\lang\nativesrc\geninclude\java_lang_Ref.h" : \ +$(SOURCE) "$(INTDIR)" "$(OUTDIR)" + $(BuildCmds) + +"..\..\..\..\Packages\java\lang\nativesrc\geninclude\java_lang_Exception.h" : \ +$(SOURCE) "$(INTDIR)" "$(OUTDIR)" + $(BuildCmds) + +"..\..\..\..\Packages\java\lang\nativesrc\geninclude\java_util_properties.h" : \ +$(SOURCE) "$(INTDIR)" "$(OUTDIR)" + $(BuildCmds) +# End Custom Build + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\..\dist\classes\java\io\File.class + +!IF "$(CFG)" == "Package - Win32 Release" + +# Begin Custom Build - Generating Header files for java/io +InputPath=..\..\..\..\..\dist\classes\java\io\File.class + +BuildCmds= \ + ..\release\javah -classpath ../../../../../dist/classes -d\ + ../../../../Packages/java/io/nativesrc/geninclude java/io/File\ + java/io/FileDescriptor java/io/FileInputStream java/io/FileOutputStream\ + java/io/PrintStream java/io/RandomAccessFile + +"..\..\..\..\Packages\java\io\nativesrc\geninclude\java_io_File.h" : $(SOURCE)\ + "$(INTDIR)" "$(OUTDIR)" + $(BuildCmds) + +"..\..\..\..\Packages\java\io\nativesrc\geninclude\java_io_FileDescriptor.h" : \ +$(SOURCE) "$(INTDIR)" "$(OUTDIR)" + $(BuildCmds) + +"..\..\..\..\Packages\java\io\nativesrc\geninclude\java_io_FileInputStream.h" :\ + $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + $(BuildCmds) +# End Custom Build + +!ELSEIF "$(CFG)" == "Package - Win32 Debug" + +# Begin Custom Build - Generating Header files for java/io +InputPath=..\..\..\..\..\dist\classes\java\io\File.class + +BuildCmds= \ + ..\electric\javah -classpath ../../../../../dist/classes -d\ + ../../../../Packages/java/io/nativesrc/geninclude java/io/File\ + java/io/FileDescriptor java/io/FileInputStream java/io/FileOutputStream\ + java/io/PrintStream java/io/RandomAccessFile + +"..\..\..\..\Packages\java\io\nativesrc\geninclude\java_io_File.h" : $(SOURCE)\ + "$(INTDIR)" "$(OUTDIR)" + $(BuildCmds) + +"..\..\..\..\Packages\java\io\nativesrc\geninclude\java_io_FileDescriptor.h" : \ +$(SOURCE) "$(INTDIR)" "$(OUTDIR)" + $(BuildCmds) + +"..\..\..\..\Packages\java\io\nativesrc\geninclude\java_io_FileInputStream.h" :\ + $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + $(BuildCmds) +# End Custom Build + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\..\dist\classes\java\util\ResourceBundle.class +# End Source File +# End Target +# End Project diff --git a/ef/Driver/StandAloneJava/winbuild/SportModel/SportModel.dsp b/ef/Driver/StandAloneJava/winbuild/SportModel/SportModel.dsp new file mode 100644 index 000000000000..83a8c8e6e786 --- /dev/null +++ b/ef/Driver/StandAloneJava/winbuild/SportModel/SportModel.dsp @@ -0,0 +1,369 @@ +# Microsoft Developer Studio Project File - Name="SportModel" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 5.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=SportModel - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "SportModel.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "SportModel.mak" CFG="SportModel - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "SportModel - Win32 Debug" (based on\ + "Win32 (x86) Dynamic-Link Library") +!MESSAGE "SportModel - Win32 Unicode Debug" (based on\ + "Win32 (x86) Dynamic-Link Library") +!MESSAGE "SportModel - Win32 Release MinSize" (based on\ + "Win32 (x86) Dynamic-Link Library") +!MESSAGE "SportModel - Win32 Release MinDependency" (based on\ + "Win32 (x86) Dynamic-Link Library") +!MESSAGE "SportModel - Win32 Unicode Release MinSize" (based on\ + "Win32 (x86) Dynamic-Link Library") +!MESSAGE "SportModel - Win32 Unicode Release MinDependency" (based on\ + "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "SportModel - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "..\electric" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_USRDLL" /Yu"stdafx.h" /FD /c +# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "..\..\..\..\..\dist\WINNT4.0_DBG.OBJ\include" /I "..\..\..\..\..\sm\include" /D "_WINDOWS" /D "_USRDLL" /D "DEBUG" /D "DEBUG_warren" /D "XP_PC" /D "WIN32" /D "_DEBUG" /D "SM_NO_WRITE_BARRIER" /FD /c +# SUBTRACT CPP /YX /Yc /Yu +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 ..\..\..\..\..\dist\WINNT4.0_DBG.OBJ\lib\libnspr21.lib ..\..\..\..\..\dist\WINNT4.0_DBG.OBJ\lib\libplc21_s.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /dll /debug /machine:I386 /pdbtype:sept +# SUBTRACT LINK32 /pdb:none +# Begin Custom Build - Registering ActiveX Control... +OutDir=.\..\electric +TargetPath=\ +\ns\electricalfire\Driver\StandAloneJava\winbuild\electric\SportModel.dll +InputPath=\ +\ns\electricalfire\Driver\StandAloneJava\winbuild\electric\SportModel.dll +SOURCE=$(InputPath) + +"$(OutDir)\regsvr32.trg" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + regsvr32 /s /c "$(TargetPath)" + echo regsvr32 exec. time > "$(OutDir)\regsvr32.trg" + +# End Custom Build + +!ELSEIF "$(CFG)" == "SportModel - Win32 Unicode Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "DebugU" +# PROP BASE Intermediate_Dir "DebugU" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "DebugU" +# PROP Intermediate_Dir "DebugU" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_USRDLL" /D "_UNICODE" /Yu"stdafx.h" /FD /c +# ADD CPP /nologo /MTd /W3 /Gm /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_USRDLL" /D "_UNICODE" /Yu"stdafx.h" /FD /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept +# Begin Custom Build - Registering ActiveX Control... +OutDir=.\DebugU +TargetPath=.\DebugU\SportModel.dll +InputPath=.\DebugU\SportModel.dll +SOURCE=$(InputPath) + +"$(OutDir)\regsvr32.trg" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + regsvr32 /s /c "$(TargetPath)" + echo regsvr32 exec. time > "$(OutDir)\regsvr32.trg" + +# End Custom Build + +!ELSEIF "$(CFG)" == "SportModel - Win32 Release MinSize" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "ReleaseMinSize" +# PROP BASE Intermediate_Dir "ReleaseMinSize" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "ReleaseMinSize" +# PROP Intermediate_Dir "ReleaseMinSize" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /O1 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_USRDLL" /D "_ATL_DLL" /D "_ATL_MIN_CRT" /Yu"stdafx.h" /FD /c +# ADD CPP /nologo /MT /W3 /O1 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_USRDLL" /D "_ATL_DLL" /D "_ATL_MIN_CRT" /Yu"stdafx.h" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386 +# Begin Custom Build - Registering ActiveX Control... +OutDir=.\ReleaseMinSize +TargetPath=.\ReleaseMinSize\SportModel.dll +InputPath=.\ReleaseMinSize\SportModel.dll +SOURCE=$(InputPath) + +"$(OutDir)\regsvr32.trg" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + regsvr32 /s /c "$(TargetPath)" + echo regsvr32 exec. time > "$(OutDir)\regsvr32.trg" + +# End Custom Build + +!ELSEIF "$(CFG)" == "SportModel - Win32 Release MinDependency" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "ReleaseMinDependency" +# PROP BASE Intermediate_Dir "ReleaseMinDependency" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "ReleaseMinDependency" +# PROP Intermediate_Dir "ReleaseMinDependency" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /O1 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_USRDLL" /D "_ATL_STATIC_REGISTRY" /D "_ATL_MIN_CRT" /Yu"stdafx.h" /FD /c +# ADD CPP /nologo /MT /W3 /O1 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_USRDLL" /D "_ATL_STATIC_REGISTRY" /D "_ATL_MIN_CRT" /Yu"stdafx.h" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386 +# Begin Custom Build - Registering ActiveX Control... +OutDir=.\ReleaseMinDependency +TargetPath=.\ReleaseMinDependency\SportModel.dll +InputPath=.\ReleaseMinDependency\SportModel.dll +SOURCE=$(InputPath) + +"$(OutDir)\regsvr32.trg" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + regsvr32 /s /c "$(TargetPath)" + echo regsvr32 exec. time > "$(OutDir)\regsvr32.trg" + +# End Custom Build + +!ELSEIF "$(CFG)" == "SportModel - Win32 Unicode Release MinSize" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "ReleaseUMinSize" +# PROP BASE Intermediate_Dir "ReleaseUMinSize" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "ReleaseUMinSize" +# PROP Intermediate_Dir "ReleaseUMinSize" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /O1 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_USRDLL" /D "_UNICODE" /D "_ATL_DLL" /D "_ATL_MIN_CRT" /Yu"stdafx.h" /FD /c +# ADD CPP /nologo /MT /W3 /O1 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_USRDLL" /D "_UNICODE" /D "_ATL_DLL" /D "_ATL_MIN_CRT" /Yu"stdafx.h" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386 +# Begin Custom Build - Registering ActiveX Control... +OutDir=.\ReleaseUMinSize +TargetPath=.\ReleaseUMinSize\SportModel.dll +InputPath=.\ReleaseUMinSize\SportModel.dll +SOURCE=$(InputPath) + +"$(OutDir)\regsvr32.trg" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + regsvr32 /s /c "$(TargetPath)" + echo regsvr32 exec. time > "$(OutDir)\regsvr32.trg" + +# End Custom Build + +!ELSEIF "$(CFG)" == "SportModel - Win32 Unicode Release MinDependency" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "ReleaseUMinDependency" +# PROP BASE Intermediate_Dir "ReleaseUMinDependency" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "ReleaseUMinDependency" +# PROP Intermediate_Dir "ReleaseUMinDependency" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /O1 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_USRDLL" /D "_UNICODE" /D "_ATL_STATIC_REGISTRY" /D "_ATL_MIN_CRT" /Yu"stdafx.h" /FD /c +# ADD CPP /nologo /MT /W3 /O1 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_USRDLL" /D "_UNICODE" /D "_ATL_STATIC_REGISTRY" /D "_ATL_MIN_CRT" /Yu"stdafx.h" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386 +# Begin Custom Build - Registering ActiveX Control... +OutDir=.\ReleaseUMinDependency +TargetPath=.\ReleaseUMinDependency\SportModel.dll +InputPath=.\ReleaseUMinDependency\SportModel.dll +SOURCE=$(InputPath) + +"$(OutDir)\regsvr32.trg" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + regsvr32 /s /c "$(TargetPath)" + echo regsvr32 exec. time > "$(OutDir)\regsvr32.trg" + +# End Custom Build + +!ENDIF + +# Begin Target + +# Name "SportModel - Win32 Debug" +# Name "SportModel - Win32 Unicode Debug" +# Name "SportModel - Win32 Release MinSize" +# Name "SportModel - Win32 Release MinDependency" +# Name "SportModel - Win32 Unicode Release MinSize" +# Name "SportModel - Win32 Unicode Release MinDependency" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=..\..\..\..\..\sm\src\smalloc.c +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\..\sm\src\smassert.c +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\..\sm\src\smgc.c +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\..\sm\src\smgen.c +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\..\sm\src\smheap.c +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\..\sm\src\smmalloc.c +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\..\sm\src\smobj.c +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\..\sm\src\smpage.c +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\..\sm\src\smpool.c +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\..\sm\src\smstack.c +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\..\sm\src\smtrav.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=..\..\..\..\..\sm\include\sm.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\..\sm\include\smgen.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\..\sm\include\smheap.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\..\sm\include\smmalloc.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\..\sm\include\smobj.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\..\sm\include\smpage.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\..\sm\include\smpool.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\..\sm\include\smpriv.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\..\sm\include\smstack.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\..\sm\include\smtrav.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/ef/Driver/StandAloneJava/winbuild/electricalfire.dsp b/ef/Driver/StandAloneJava/winbuild/electricalfire.dsp new file mode 100644 index 000000000000..c37eaf23c8ab --- /dev/null +++ b/ef/Driver/StandAloneJava/winbuild/electricalfire.dsp @@ -0,0 +1,1190 @@ +# Microsoft Developer Studio Project File - Name="electricalfire" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 5.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=electricalfire - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "electricalfire.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "electricalfire.mak" CFG="electricalfire - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "electricalfire - Win32 Release" (based on\ + "Win32 (x86) Dynamic-Link Library") +!MESSAGE "electricalfire - Win32 Debug" (based on\ + "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "electricalfire - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /D "WIN32" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "..\..\..\Exports" /I "..\..\..\Exports\md" /I "..\..\..\Utilities\General" /I "..\..\..\Utilities\General\md" /I "..\..\..\Compiler\FrontEnd" /I "..\..\..\Compiler\PrimitiveGraph" /I "..\..\..\Runtime\System\md\x86" /I "..\..\..\..\dist\WINNT4.0_DBG.OBJ\include" /I "..\..\..\Utilities\zlib" /I "..\..\..\Runtime\ClassInfo" /I "..\..\..\Runtime\ClassReader" /I "..\..\..\Runtime\FileReader" /I "..\..\..\Runtime\NativeMethods" /I "..\..\..\Runtime\Systems" /I "..\..\..\Compiler\CodeGenerator" /I "..\..\..\Compiler\RegisterAllocator" /I "..\..\..\Compiler\CodeGenerator\md\x86\x86dis" /I "..\..\..\Compiler\CodeGenerator\md\x86" /I "..\..\..\Compiler\CodeGenerator\md" /I ".\\" /I ".\genfiles" /I "..\..\..\Compiler\Optimizer" /I "..\..\..\Driver\StandAloneJava" /I "..\..\..\Runtime\System" /I "..\..\..\Debugger" /I "..\..\..\Runtime\System\md" /I "..\..\..\Debugger\Communication" /D "NDEBUG" /D "EF_WINDOWS" /D "GENERATE_FOR_X86" /D "XP_PC" /D "DLL_BUILD" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "GENERATE_NATIVE_STUBS" /FR /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /dll /machine:I386 +# ADD LINK32 electric\DebuggerChannel.lib ..\..\..\..\dist\WINNT4.0_OPT.OBJ\lib\libnspr20.lib ..\..\..\..\dist\WINNT4.0_OPT.OBJ\lib\libplc20_s.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib /nologo /subsystem:console /dll /machine:I386 /nodefaultlib:"MSVCRT" +# SUBTRACT LINK32 /incremental:yes /debug + +!ELSEIF "$(CFG)" == "electricalfire - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "electric" +# PROP BASE Intermediate_Dir "electric" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "electric" +# PROP Intermediate_Dir "electric" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /I "..\..\..\Exports" /I "..\..\..\Exports\md" /I "..\..\..\Utilities\General" /I "..\..\..\Utilities\DisAssemblers\x86" /I "..\..\..\Utilities\General\md" /I "..\..\..\Compiler\FrontEnd" /I "..\..\..\Compiler\PrimitiveGraph" /I "..\..\..\Runtime\System\md\x86" /I "..\..\..\..\dist\WINNT4.0_DBG.OBJ\include" /I "..\..\..\Utilities\zlib" /I "..\..\..\Runtime\ClassInfo" /I "..\..\..\Runtime\ClassReader" /I "..\..\..\Runtime\FileReader" /I "..\..\..\Runtime\NativeMethods" /I "..\..\..\Runtime\Systems" /I "..\..\..\Compiler\CodeGenerator" /I "..\..\..\Compiler\RegisterAllocator" /I "..\..\..\Compiler\CodeGenerator\md\x86\x86dis" /I "..\..\..\Compiler\CodeGenerator\md\x86" /I "..\..\..\Compiler\CodeGenerator\md" /I ".\\" /I ".\genfiles" /I "..\..\..\Compiler\Optimizer" /I "..\..\..\Driver\StandAloneJava" /I "..\..\..\Runtime\System" /I "..\..\..\Debugger" /I "..\..\..\Runtime\System\md" /I "..\..\..\Debugger\Communication" /D "DEBUG" /D "DEBUG_LOG" /D "_DEBUG" /D "DEBUG_DESANTIS" /D "DEBUG_kini" /D "EF_WINDOWS" /D "GENERATE_FOR_X86" /D "XP_PC" /D "DLL_BUILD" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "GENERATE_NATIVE_STUBS" /FR /FD /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 electric\DebuggerChannel.lib ..\..\..\..\dist\WINNT4.0_DBG.OBJ\lib\libnspr21.lib ..\..\..\..\dist\WINNT4.0_DBG.OBJ\lib\libplc21_s.lib wsock32.lib kernel32.lib user32.lib /nologo /subsystem:console /dll /debug /machine:I386 /nodefaultlib:"MSVCRT" /pdbtype:sept /libpath:"..\..\..\..\..\dist\WINNT4.0_DBG.OBJ\lib" +# SUBTRACT LINK32 /pdb:none + +!ENDIF + +# Begin Target + +# Name "electricalfire - Win32 Release" +# Name "electricalfire - Win32 Debug" +# Begin Group "GeneratedFiles" + +# PROP Default_Filter "" +# Begin Group "x86 generated files" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=".\genfiles\x86-win32.nad.burg.cpp" +# End Source File +# Begin Source File + +SOURCE=".\genfiles\x86-win32.nad.burg.h" +# End Source File +# End Group +# Begin Group "ppc generated files" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=".\genfiles\ppc601-macos.nad.burg.cpp" +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=".\genfiles\ppc601-macos.nad.burg.h" +# PROP Exclude_From_Build 1 +# End Source File +# End Group +# Begin Source File + +SOURCE=.\genfiles\PrimitiveOperations.h +# End Source File +# End Group +# Begin Group "Runtime" + +# PROP Default_Filter "" +# Begin Group "ClassInfo" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Runtime\ClassInfo\ClassCentral.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Runtime\ClassInfo\ClassCentral.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Runtime\ClassInfo\ClassFileSummary.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Runtime\ClassInfo\ClassFileSummary.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Runtime\ClassInfo\Collector.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Runtime\ClassInfo\PathComponent.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Runtime\ClassInfo\PathComponent.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Runtime\ClassInfo\StringPool.h +# End Source File +# End Group +# Begin Group "ClassReader" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Runtime\ClassReader\AttributeHandlers.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Runtime\ClassReader\AttributeHandlers.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Runtime\ClassReader\Attributes.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Runtime\ClassReader\ClassReader.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Runtime\ClassReader\ClassReader.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Runtime\ClassReader\ConstantPool.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Runtime\ClassReader\InfoItem.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Runtime\ClassReader\utils.h +# End Source File +# End Group +# Begin Group "FileReader" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Runtime\FileReader\BufferedFileReader.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Runtime\FileReader\BufferedFileReader.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Runtime\FileReader\DiskFileReader.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Runtime\FileReader\DiskFileReader.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Runtime\FileReader\FileReader.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Runtime\FileReader\FileReader.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Runtime\FileReader\ZipArchive.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Runtime\FileReader\ZipArchive.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Runtime\FileReader\ZipFileReader.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Runtime\FileReader\ZipFileReader.h +# End Source File +# End Group +# Begin Group "NativeMethods" + +# PROP Default_Filter "" +# Begin Group "md No. 2" + +# PROP Default_Filter "" +# Begin Group "x86 No. 1" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Runtime\NativeMethods\md\x86\x86NativeMethodStubs.cpp +# End Source File +# End Group +# End Group +# Begin Source File + +SOURCE=..\..\..\Runtime\NativeMethods\Jni.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Runtime\NativeMethods\JNIManglers.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Runtime\NativeMethods\JNIManglers.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Runtime\NativeMethods\JniRuntime.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Runtime\NativeMethods\NameMangler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Runtime\NativeMethods\NameMangler.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Runtime\NativeMethods\NativeMethodDispatcher.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Runtime\NativeMethods\NativeMethodDispatcher.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Runtime\NativeMethods\NativeMethodStubs.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Runtime\NativeMethods\NetscapeManglers.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Runtime\NativeMethods\NetscapeManglers.h +# End Source File +# End Group +# Begin Group "System" + +# PROP Default_Filter "" +# Begin Group "md_" + +# PROP Default_Filter "" +# Begin Group "x86_" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Runtime\System\md\x86\Win32ExceptionHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Runtime\System\md\x86\x86ExceptionHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Runtime\System\md\x86\x86SysCallsRuntime.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Runtime\System\md\x86\x86SysCallsRuntime.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Runtime\System\md\x86\x86Win32ExceptionHandler.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Runtime\System\md\x86\x86Win32InvokeNative.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Runtime\System\md\x86\x86Win32Thread.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Runtime\System\md\x86\x86Win32Thread.h +# End Source File +# End Group +# Begin Source File + +SOURCE=..\..\..\Runtime\System\md\FieldOrMethod_md.h +# End Source File +# End Group +# Begin Source File + +SOURCE=..\..\..\Runtime\System\ClassWorld.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Runtime\System\ClassWorld.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Runtime\System\Exceptions.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Runtime\System\FieldOrInterfaceSummary.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Runtime\System\FieldOrMethod.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Runtime\System\FieldOrMethod.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Runtime\System\InterfaceDispatchTable.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Runtime\System\JavaObject.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Runtime\System\JavaObject.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Runtime\System\JavaString.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Runtime\System\JavaString.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Runtime\System\JavaVM.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Runtime\System\JavaVM.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Runtime\System\Method.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Runtime\System\Method.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Runtime\System\Monitor.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Runtime\System\Monitor.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Runtime\System\StackWalker.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Runtime\System\StackWalker.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Runtime\System\SysCallsRuntime.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Runtime\System\SysCallsRuntime.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Runtime\System\Thread.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Runtime\System\Thread.h +# End Source File +# End Group +# End Group +# Begin Group "Utilities" + +# PROP Default_Filter "" +# Begin Group "General" + +# PROP Default_Filter "" +# Begin Group "md No. 1" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Utilities\General\md\CatchAssert_md.h +# End Source File +# End Group +# Begin Source File + +SOURCE=..\..\..\Utilities\General\CatchAssert.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Utilities\General\CatchAssert.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Utilities\General\CUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Utilities\General\CUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Utilities\General\DebugUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Utilities\General\DebugUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Utilities\General\DoublyLinkedList.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Utilities\General\Exports.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Utilities\General\FastBitMatrix.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Utilities\General\FastBitMatrix.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Utilities\General\FastBitSet.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Utilities\General\FastBitSet.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Utilities\General\FastHashTable.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Utilities\General\Fifo.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Utilities\General\FloatUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Utilities\General\FloatUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Utilities\General\Fundamentals.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Utilities\General\GraphUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Utilities\General\HashTable.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Utilities\General\InterestingEvents.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Utilities\General\JavaBytecodes.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Utilities\General\JavaBytecodes.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Utilities\General\LogModule.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Utilities\General\LogModule.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Utilities\General\MemoryAccess.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Utilities\General\Pool.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Utilities\General\Pool.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Utilities\General\StringUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Utilities\General\Tree.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Utilities\General\Tree.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Utilities\General\Vector.h +# End Source File +# End Group +# Begin Group "zlib" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Utilities\zlib\adler32.c +# End Source File +# Begin Source File + +SOURCE=..\..\..\Utilities\zlib\compress.c +# End Source File +# Begin Source File + +SOURCE=..\..\..\Utilities\zlib\crc32.c +# End Source File +# Begin Source File + +SOURCE=..\..\..\Utilities\zlib\deflate.c +# End Source File +# Begin Source File + +SOURCE=..\..\..\Utilities\zlib\deflate.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Utilities\zlib\gzio.c +# End Source File +# Begin Source File + +SOURCE=..\..\..\Utilities\zlib\infblock.c +# End Source File +# Begin Source File + +SOURCE=..\..\..\Utilities\zlib\infblock.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Utilities\zlib\infcodes.c +# End Source File +# Begin Source File + +SOURCE=..\..\..\Utilities\zlib\infcodes.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Utilities\zlib\inffast.c +# End Source File +# Begin Source File + +SOURCE=..\..\..\Utilities\zlib\inffast.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Utilities\zlib\inflate.c +# End Source File +# Begin Source File + +SOURCE=..\..\..\Utilities\zlib\inftrees.c +# End Source File +# Begin Source File + +SOURCE=..\..\..\Utilities\zlib\inftrees.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Utilities\zlib\infutil.c +# End Source File +# Begin Source File + +SOURCE=..\..\..\Utilities\zlib\infutil.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Utilities\zlib\trees.c +# End Source File +# Begin Source File + +SOURCE=..\..\..\Utilities\zlib\uncompr.c +# End Source File +# Begin Source File + +SOURCE=..\..\..\Utilities\zlib\zconf.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Utilities\zlib\zlib.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Utilities\zlib\zutil.c +# End Source File +# Begin Source File + +SOURCE=..\..\..\Utilities\zlib\zutil.h +# End Source File +# End Group +# End Group +# Begin Group "Compiler" + +# PROP Default_Filter "" +# Begin Group "FrontEnd" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Compiler\FrontEnd\BytecodeGraph.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Compiler\FrontEnd\BytecodeGraph.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Compiler\FrontEnd\BytecodeTranslator.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Compiler\FrontEnd\BytecodeTranslator.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Compiler\FrontEnd\BytecodeVerifier.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Compiler\FrontEnd\BytecodeVerifier.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Compiler\FrontEnd\ErrorHandling.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Compiler\FrontEnd\ErrorHandling.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Compiler\FrontEnd\LocalEnv.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Compiler\FrontEnd\TranslationEnv.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Compiler\FrontEnd\TranslationEnv.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Compiler\FrontEnd\VerificationEnv.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Compiler\FrontEnd\VerificationEnv.h +# End Source File +# End Group +# Begin Group "CodeGenerator" + +# PROP Default_Filter "" +# Begin Group "md" + +# PROP Default_Filter "" +# Begin Group "x86" + +# PROP Default_Filter "" +# Begin Group "X86Disassembler" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Utilities\Disassemblers\x86\XDisAsm.c +# End Source File +# Begin Source File + +SOURCE=..\..\..\Utilities\Disassemblers\x86\XDisAsm.h +# End Source File +# End Group +# Begin Source File + +SOURCE="..\..\..\Compiler\CodeGenerator\md\x86\x86-win32.nad" + +!IF "$(CFG)" == "electricalfire - Win32 Release" + +# Begin Custom Build - Perly Nads +InputPath=..\..\..\Compiler\CodeGenerator\md\x86\x86-win32.nad +InputName=x86-win32 + +BuildCmds= \ + $(NSTOOLS)\perl5\perl ..\..\..\tools\nad\nad.pl $(InputPath)\ + ..\..\..\Compiler\PrimitiveGraph\PrimitiveOperations\ + genfiles\PrimitiveOperations.h genfiles\PrimitiveOperations.cpp\ + genfiles\$(InputName).nad.burg.h | Burg\Release\burg -I >\ + genfiles\$(InputName).nad.burg.cpp + +"genfiles\$(InputName).nad.burg.cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + $(BuildCmds) + +"genfiles\$(InputName).nad.burg.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + $(BuildCmds) + +"genfiles\PrimitiveOperations.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + $(BuildCmds) + +"genfiles\PrimitiveOperations.cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + $(BuildCmds) +# End Custom Build + +!ELSEIF "$(CFG)" == "electricalfire - Win32 Debug" + +# Begin Custom Build - Perly Nads +InputPath=..\..\..\Compiler\CodeGenerator\md\x86\x86-win32.nad +InputName=x86-win32 + +BuildCmds= \ + $(MOZ_TOOLS)\perl5\perl ..\..\..\tools\nad\nad.pl $(InputPath)\ + ..\..\..\Compiler\PrimitiveGraph\PrimitiveOperations\ + genfiles\PrimitiveOperations.h genfiles\PrimitiveOperations.cpp\ + genfiles\$(InputName).nad.burg.h | Burg\Debug\burg -I >\ + genfiles\$(InputName).nad.burg.cpp + +"genfiles\$(InputName).nad.burg.cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + $(BuildCmds) + +"genfiles\$(InputName).nad.burg.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + $(BuildCmds) +# End Custom Build + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\Compiler\CodeGenerator\md\x86\x86ArgumentList.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Compiler\CodeGenerator\md\x86\x86ArgumentList.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Compiler\CodeGenerator\md\x86\x86Float.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Compiler\CodeGenerator\md\x86\x86Formatter.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Compiler\CodeGenerator\md\x86\x86Formatter.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Compiler\CodeGenerator\md\x86\x86Opcode.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Compiler\CodeGenerator\md\x86\x86Opcode.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Compiler\CodeGenerator\md\x86\x86StdCall.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Compiler\CodeGenerator\md\x86\x86Win32_Support.cpp +# SUBTRACT CPP /O +# End Source File +# Begin Source File + +SOURCE=..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Cpu.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Emitter.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Emitter.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Instruction.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Instruction.h +# End Source File +# End Group +# Begin Group "generic" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Compiler\CodeGenerator\md\generic\Generic_Support.cpp +# PROP Exclude_From_Build 1 +# End Source File +# End Group +# Begin Source File + +SOURCE=..\..\..\Compiler\CodeGenerator\md\CpuInfo.h +# End Source File +# End Group +# Begin Source File + +SOURCE=..\..\..\Compiler\CodeGenerator\Backend.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Compiler\CodeGenerator\Backend.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Compiler\CodeGenerator\Burg.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Compiler\CodeGenerator\CGScheduler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Compiler\CodeGenerator\CGScheduler.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Compiler\CodeGenerator\CodeGenerator.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Compiler\CodeGenerator\CodeGenerator.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Compiler\CodeGenerator\ExceptionTable.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Compiler\CodeGenerator\ExceptionTable.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Compiler\CodeGenerator\HTMLMethodDump.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Compiler\CodeGenerator\HTMLMethodDump.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Compiler\CodeGenerator\IGVisualizer.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Compiler\CodeGenerator\IGVisualizer.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Compiler\CodeGenerator\Instruction.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Compiler\CodeGenerator\Instruction.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Compiler\CodeGenerator\InstructionEmitter.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Compiler\CodeGenerator\InstructionEmitter.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Compiler\CodeGenerator\NativeCodeCache.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Compiler\CodeGenerator\NativeCodeCache.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Compiler\CodeGenerator\NativeFormatter.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Compiler\CodeGenerator\NativeFormatter.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Compiler\CodeGenerator\Scheduler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Compiler\CodeGenerator\Scheduler.h +# End Source File +# End Group +# Begin Group "RegAlloc" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Compiler\RegisterAllocator\Coloring.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Compiler\RegisterAllocator\Coloring.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Compiler\RegisterAllocator\RegisterAllocator.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Compiler\RegisterAllocator\RegisterAllocator.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Compiler\RegisterAllocator\RegisterAssigner.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Compiler\RegisterAllocator\Spilling.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Compiler\RegisterAllocator\Spilling.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Compiler\RegisterAllocator\VirtualRegister.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Compiler\RegisterAllocator\VirtualRegister.h +# End Source File +# End Group +# Begin Group "Optimizer" + +# PROP Default_Filter ".cpp .h" +# Begin Source File + +SOURCE=..\..\..\Compiler\Optimizer\PrimitiveOptimizer.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Compiler\Optimizer\PrimitiveOptimizer.h +# End Source File +# End Group +# Begin Group "PrimitiveGraph" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Compiler\PrimitiveGraph\Address.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Compiler\PrimitiveGraph\Address.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Compiler\PrimitiveGraph\ControlGraph.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Compiler\PrimitiveGraph\ControlGraph.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Compiler\PrimitiveGraph\ControlNodes.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Compiler\PrimitiveGraph\ControlNodes.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Compiler\PrimitiveGraph\PrimitiveBuilders.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Compiler\PrimitiveGraph\PrimitiveBuilders.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Compiler\PrimitiveGraph\PrimitiveGraphVerifier.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Compiler\PrimitiveGraph\PrimitiveOperations + +!IF "$(CFG)" == "electricalfire - Win32 Release" + +!ELSEIF "$(CFG)" == "electricalfire - Win32 Debug" + +# Begin Custom Build - PrimitiveOperations +InputPath=..\..\..\Compiler\PrimitiveGraph\PrimitiveOperations +InputName=PrimitiveOperations + +BuildCmds= \ + $(MOZ_TOOLS)\perl5\perl -I"..\..\..\Tools\PrimitiveOperations"\ + ..\..\..\Tools\PrimitiveOperations\MakePrimOp.pl $(InputPath)\ + genfiles\$(InputName).h genfiles\$(InputName).cpp + +"genfiles\$(InputName).h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + $(BuildCmds) + +"genfiles\$(InputName).cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + $(BuildCmds) +# End Custom Build + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\Compiler\PrimitiveGraph\Primitives.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Compiler\PrimitiveGraph\Primitives.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Compiler\PrimitiveGraph\SysCalls.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Compiler\PrimitiveGraph\SysCalls.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Compiler\PrimitiveGraph\Value.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Compiler\PrimitiveGraph\Value.h +# End Source File +# End Group +# End Group +# Begin Group "Debugger" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Debugger\Debugger.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Debugger\Debugger.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Debugger\jvmdi.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Debugger\jvmdi.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Debugger\Win32BreakPoint.cpp +# End Source File +# End Group +# Begin Group "Exports" + +# PROP Default_Filter "" +# Begin Group "md No. 3" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Exports\md\jni_md.h +# End Source File +# End Group +# Begin Source File + +SOURCE=..\..\..\Exports\jni.h +# End Source File +# End Group +# Begin Group "Includes" + +# PROP Default_Filter "" +# Begin Group "md No. 4" + +# PROP Default_Filter "" +# Begin Group "x86 No. 2" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Includes\md\x86\x86Asm.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Includes\md\x86\x86LinuxAsm.h +# End Source File +# End Group +# Begin Source File + +SOURCE=..\..\..\Includes\md\Asm.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Includes\md\MdInclude.h +# End Source File +# End Group +# End Group +# End Target +# End Project diff --git a/ef/Driver/StandAloneJava/winbuild/electricalfire.mak b/ef/Driver/StandAloneJava/winbuild/electricalfire.mak new file mode 100644 index 000000000000..cb855ae7f008 --- /dev/null +++ b/ef/Driver/StandAloneJava/winbuild/electricalfire.mak @@ -0,0 +1,12130 @@ +# Microsoft Developer Studio Generated NMAKE File, Based on electricalfire.dsp +!IF "$(CFG)" == "" +CFG=electricalfire - Win32 Debug +!MESSAGE No configuration specified. Defaulting to electricalfire - Win32\ + Debug. +!ENDIF + +!IF "$(CFG)" != "electricalfire - Win32 Release" && "$(CFG)" !=\ + "electricalfire - Win32 Debug" +!MESSAGE Invalid configuration "$(CFG)" specified. +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "electricalfire.mak" CFG="electricalfire - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "electricalfire - Win32 Release" (based on\ + "Win32 (x86) Dynamic-Link Library") +!MESSAGE "electricalfire - Win32 Debug" (based on\ + "Win32 (x86) Dynamic-Link Library") +!MESSAGE +!ERROR An invalid configuration is specified. +!ENDIF + +!IF "$(OS)" == "Windows_NT" +NULL= +!ELSE +NULL=nul +!ENDIF + +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "electricalfire - Win32 Release" + +OUTDIR=.\Release +INTDIR=.\Release +# Begin Custom Macros +OutDir=.\Release +# End Custom Macros + +!IF "$(RECURSE)" == "0" + +ALL : "genfiles\$(InputName).nad.burg.h" "genfiles\$(InputName).nad.burg.cpp"\ + "$(OUTDIR)\electricalfire.dll" "$(OUTDIR)\electricalfire.bsc" + +!ELSE + +ALL : "genfiles\PrimitiveOperations.h" "genfiles\PrimitiveOperations.cpp"\ + "genfiles\$(InputName).nad.burg.h" "genfiles\$(InputName).nad.burg.cpp"\ + "$(OUTDIR)\electricalfire.dll" "$(OUTDIR)\electricalfire.bsc" + +!ENDIF + +!IF "$(RECURSE)" == "1" +CLEAN :"Burg - Win32 ReleaseCLEAN" "DebuggerChannel - Win32 ReleaseCLEAN" +!ELSE +CLEAN : +!ENDIF + -@erase "$(INTDIR)\Address.obj" + -@erase "$(INTDIR)\Address.sbr" + -@erase "$(INTDIR)\adler32.obj" + -@erase "$(INTDIR)\adler32.sbr" + -@erase "$(INTDIR)\AttributeHandlers.obj" + -@erase "$(INTDIR)\AttributeHandlers.sbr" + -@erase "$(INTDIR)\Backend.obj" + -@erase "$(INTDIR)\Backend.sbr" + -@erase "$(INTDIR)\BufferedFileReader.obj" + -@erase "$(INTDIR)\BufferedFileReader.sbr" + -@erase "$(INTDIR)\BytecodeGraph.obj" + -@erase "$(INTDIR)\BytecodeGraph.sbr" + -@erase "$(INTDIR)\BytecodeTranslator.obj" + -@erase "$(INTDIR)\BytecodeTranslator.sbr" + -@erase "$(INTDIR)\BytecodeVerifier.obj" + -@erase "$(INTDIR)\BytecodeVerifier.sbr" + -@erase "$(INTDIR)\CatchAssert.obj" + -@erase "$(INTDIR)\CatchAssert.sbr" + -@erase "$(INTDIR)\CGScheduler.obj" + -@erase "$(INTDIR)\CGScheduler.sbr" + -@erase "$(INTDIR)\ClassCentral.obj" + -@erase "$(INTDIR)\ClassCentral.sbr" + -@erase "$(INTDIR)\ClassFileSummary.obj" + -@erase "$(INTDIR)\ClassFileSummary.sbr" + -@erase "$(INTDIR)\ClassReader.obj" + -@erase "$(INTDIR)\ClassReader.sbr" + -@erase "$(INTDIR)\ClassWorld.obj" + -@erase "$(INTDIR)\ClassWorld.sbr" + -@erase "$(INTDIR)\CodeGenerator.obj" + -@erase "$(INTDIR)\CodeGenerator.sbr" + -@erase "$(INTDIR)\Coloring.obj" + -@erase "$(INTDIR)\Coloring.sbr" + -@erase "$(INTDIR)\compress.obj" + -@erase "$(INTDIR)\compress.sbr" + -@erase "$(INTDIR)\ControlGraph.obj" + -@erase "$(INTDIR)\ControlGraph.sbr" + -@erase "$(INTDIR)\ControlNodes.obj" + -@erase "$(INTDIR)\ControlNodes.sbr" + -@erase "$(INTDIR)\crc32.obj" + -@erase "$(INTDIR)\crc32.sbr" + -@erase "$(INTDIR)\CUtils.obj" + -@erase "$(INTDIR)\CUtils.sbr" + -@erase "$(INTDIR)\Debugger.obj" + -@erase "$(INTDIR)\Debugger.sbr" + -@erase "$(INTDIR)\DebugUtils.obj" + -@erase "$(INTDIR)\DebugUtils.sbr" + -@erase "$(INTDIR)\deflate.obj" + -@erase "$(INTDIR)\deflate.sbr" + -@erase "$(INTDIR)\DiskFileReader.obj" + -@erase "$(INTDIR)\DiskFileReader.sbr" + -@erase "$(INTDIR)\ErrorHandling.obj" + -@erase "$(INTDIR)\ErrorHandling.sbr" + -@erase "$(INTDIR)\ExceptionTable.obj" + -@erase "$(INTDIR)\ExceptionTable.sbr" + -@erase "$(INTDIR)\FastBitMatrix.obj" + -@erase "$(INTDIR)\FastBitMatrix.sbr" + -@erase "$(INTDIR)\FastBitSet.obj" + -@erase "$(INTDIR)\FastBitSet.sbr" + -@erase "$(INTDIR)\FieldOrMethod.obj" + -@erase "$(INTDIR)\FieldOrMethod.sbr" + -@erase "$(INTDIR)\FileReader.obj" + -@erase "$(INTDIR)\FileReader.sbr" + -@erase "$(INTDIR)\FloatUtils.obj" + -@erase "$(INTDIR)\FloatUtils.sbr" + -@erase "$(INTDIR)\gzio.obj" + -@erase "$(INTDIR)\gzio.sbr" + -@erase "$(INTDIR)\HTMLMethodDump.obj" + -@erase "$(INTDIR)\HTMLMethodDump.sbr" + -@erase "$(INTDIR)\IGVisualizer.obj" + -@erase "$(INTDIR)\IGVisualizer.sbr" + -@erase "$(INTDIR)\infblock.obj" + -@erase "$(INTDIR)\infblock.sbr" + -@erase "$(INTDIR)\infcodes.obj" + -@erase "$(INTDIR)\infcodes.sbr" + -@erase "$(INTDIR)\inffast.obj" + -@erase "$(INTDIR)\inffast.sbr" + -@erase "$(INTDIR)\inflate.obj" + -@erase "$(INTDIR)\inflate.sbr" + -@erase "$(INTDIR)\inftrees.obj" + -@erase "$(INTDIR)\inftrees.sbr" + -@erase "$(INTDIR)\infutil.obj" + -@erase "$(INTDIR)\infutil.sbr" + -@erase "$(INTDIR)\Instruction.obj" + -@erase "$(INTDIR)\Instruction.sbr" + -@erase "$(INTDIR)\InstructionEmitter.obj" + -@erase "$(INTDIR)\InstructionEmitter.sbr" + -@erase "$(INTDIR)\InterestingEvents.obj" + -@erase "$(INTDIR)\InterestingEvents.sbr" + -@erase "$(INTDIR)\InterfaceDispatchTable.obj" + -@erase "$(INTDIR)\InterfaceDispatchTable.sbr" + -@erase "$(INTDIR)\JavaBytecodes.obj" + -@erase "$(INTDIR)\JavaBytecodes.sbr" + -@erase "$(INTDIR)\JavaObject.obj" + -@erase "$(INTDIR)\JavaObject.sbr" + -@erase "$(INTDIR)\JavaString.obj" + -@erase "$(INTDIR)\JavaString.sbr" + -@erase "$(INTDIR)\JavaVM.obj" + -@erase "$(INTDIR)\JavaVM.sbr" + -@erase "$(INTDIR)\Jni.obj" + -@erase "$(INTDIR)\Jni.sbr" + -@erase "$(INTDIR)\JNIManglers.obj" + -@erase "$(INTDIR)\JNIManglers.sbr" + -@erase "$(INTDIR)\jvmdi.obj" + -@erase "$(INTDIR)\jvmdi.sbr" + -@erase "$(INTDIR)\LogModule.obj" + -@erase "$(INTDIR)\LogModule.sbr" + -@erase "$(INTDIR)\Method.obj" + -@erase "$(INTDIR)\Method.sbr" + -@erase "$(INTDIR)\Monitor.obj" + -@erase "$(INTDIR)\Monitor.sbr" + -@erase "$(INTDIR)\NameMangler.obj" + -@erase "$(INTDIR)\NameMangler.sbr" + -@erase "$(INTDIR)\NativeCodeCache.obj" + -@erase "$(INTDIR)\NativeCodeCache.sbr" + -@erase "$(INTDIR)\NativeFormatter.obj" + -@erase "$(INTDIR)\NativeFormatter.sbr" + -@erase "$(INTDIR)\NativeMethodDispatcher.obj" + -@erase "$(INTDIR)\NativeMethodDispatcher.sbr" + -@erase "$(INTDIR)\NetscapeManglers.obj" + -@erase "$(INTDIR)\NetscapeManglers.sbr" + -@erase "$(INTDIR)\PathComponent.obj" + -@erase "$(INTDIR)\PathComponent.sbr" + -@erase "$(INTDIR)\Pool.obj" + -@erase "$(INTDIR)\Pool.sbr" + -@erase "$(INTDIR)\PrimitiveBuilders.obj" + -@erase "$(INTDIR)\PrimitiveBuilders.sbr" + -@erase "$(INTDIR)\PrimitiveGraphVerifier.obj" + -@erase "$(INTDIR)\PrimitiveGraphVerifier.sbr" + -@erase "$(INTDIR)\PrimitiveOptimizer.obj" + -@erase "$(INTDIR)\PrimitiveOptimizer.sbr" + -@erase "$(INTDIR)\Primitives.obj" + -@erase "$(INTDIR)\Primitives.sbr" + -@erase "$(INTDIR)\RegisterAllocator.obj" + -@erase "$(INTDIR)\RegisterAllocator.sbr" + -@erase "$(INTDIR)\Scheduler.obj" + -@erase "$(INTDIR)\Scheduler.sbr" + -@erase "$(INTDIR)\Spilling.obj" + -@erase "$(INTDIR)\Spilling.sbr" + -@erase "$(INTDIR)\StackWalker.obj" + -@erase "$(INTDIR)\StackWalker.sbr" + -@erase "$(INTDIR)\SysCalls.obj" + -@erase "$(INTDIR)\SysCalls.sbr" + -@erase "$(INTDIR)\SysCallsRuntime.obj" + -@erase "$(INTDIR)\SysCallsRuntime.sbr" + -@erase "$(INTDIR)\Thread.obj" + -@erase "$(INTDIR)\Thread.sbr" + -@erase "$(INTDIR)\TranslationEnv.obj" + -@erase "$(INTDIR)\TranslationEnv.sbr" + -@erase "$(INTDIR)\Tree.obj" + -@erase "$(INTDIR)\Tree.sbr" + -@erase "$(INTDIR)\trees.obj" + -@erase "$(INTDIR)\trees.sbr" + -@erase "$(INTDIR)\uncompr.obj" + -@erase "$(INTDIR)\uncompr.sbr" + -@erase "$(INTDIR)\Value.obj" + -@erase "$(INTDIR)\Value.sbr" + -@erase "$(INTDIR)\vc50.idb" + -@erase "$(INTDIR)\VerificationEnv.obj" + -@erase "$(INTDIR)\VerificationEnv.sbr" + -@erase "$(INTDIR)\VirtualRegister.obj" + -@erase "$(INTDIR)\VirtualRegister.sbr" + -@erase "$(INTDIR)\Win32BreakPoint.obj" + -@erase "$(INTDIR)\Win32BreakPoint.sbr" + -@erase "$(INTDIR)\Win32ExceptionHandler.obj" + -@erase "$(INTDIR)\Win32ExceptionHandler.sbr" + -@erase "$(INTDIR)\x86-win32.nad.burg.obj" + -@erase "$(INTDIR)\x86-win32.nad.burg.sbr" + -@erase "$(INTDIR)\x86ArgumentList.obj" + -@erase "$(INTDIR)\x86ArgumentList.sbr" + -@erase "$(INTDIR)\x86ExceptionHandler.obj" + -@erase "$(INTDIR)\x86ExceptionHandler.sbr" + -@erase "$(INTDIR)\x86Float.obj" + -@erase "$(INTDIR)\x86Float.sbr" + -@erase "$(INTDIR)\x86Formatter.obj" + -@erase "$(INTDIR)\x86Formatter.sbr" + -@erase "$(INTDIR)\x86NativeMethodStubs.obj" + -@erase "$(INTDIR)\x86NativeMethodStubs.sbr" + -@erase "$(INTDIR)\x86Opcode.obj" + -@erase "$(INTDIR)\x86Opcode.sbr" + -@erase "$(INTDIR)\x86StdCall.obj" + -@erase "$(INTDIR)\x86StdCall.sbr" + -@erase "$(INTDIR)\x86SysCallsRuntime.obj" + -@erase "$(INTDIR)\x86SysCallsRuntime.sbr" + -@erase "$(INTDIR)\x86Win32_Support.obj" + -@erase "$(INTDIR)\x86Win32_Support.sbr" + -@erase "$(INTDIR)\x86Win32Emitter.obj" + -@erase "$(INTDIR)\x86Win32Emitter.sbr" + -@erase "$(INTDIR)\x86Win32Instruction.obj" + -@erase "$(INTDIR)\x86Win32Instruction.sbr" + -@erase "$(INTDIR)\x86Win32InvokeNative.obj" + -@erase "$(INTDIR)\x86Win32InvokeNative.sbr" + -@erase "$(INTDIR)\x86Win32Thread.obj" + -@erase "$(INTDIR)\x86Win32Thread.sbr" + -@erase "$(INTDIR)\XDisAsm.obj" + -@erase "$(INTDIR)\XDisAsm.sbr" + -@erase "$(INTDIR)\XDisAsmTable.obj" + -@erase "$(INTDIR)\XDisAsmTable.sbr" + -@erase "$(INTDIR)\ZipArchive.obj" + -@erase "$(INTDIR)\ZipArchive.sbr" + -@erase "$(INTDIR)\ZipFileReader.obj" + -@erase "$(INTDIR)\ZipFileReader.sbr" + -@erase "$(INTDIR)\zutil.obj" + -@erase "$(INTDIR)\zutil.sbr" + -@erase "$(OUTDIR)\electricalfire.bsc" + -@erase "$(OUTDIR)\electricalfire.dll" + -@erase "$(OUTDIR)\electricalfire.exp" + -@erase "$(OUTDIR)\electricalfire.lib" + -@erase "genfiles\$(InputName).nad.burg.cpp" + -@erase "genfiles\$(InputName).nad.burg.h" + -@erase "genfiles\PrimitiveOperations.cpp" + -@erase "genfiles\PrimitiveOperations.h" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +CPP_PROJ=/nologo /ML /W3 /GX /O2 /I "..\..\..\Exports" /I "..\..\..\Exports\md"\ + /I "..\..\..\Utilities\General" /I "..\..\..\Utilities\General\md" /I\ + "..\..\..\Compiler\FrontEnd" /I "..\..\..\Compiler\PrimitiveGraph" /I\ + "..\..\..\Runtime\System\md\x86" /I "..\..\..\..\dist\WINNT4.0_DBG.OBJ\include"\ + /I "..\..\..\Utilities\zlib" /I "..\..\..\Runtime\ClassInfo" /I\ + "..\..\..\Runtime\ClassReader" /I "..\..\..\Runtime\FileReader" /I\ + "..\..\..\Runtime\NativeMethods" /I "..\..\..\Runtime\Systems" /I\ + "..\..\..\Compiler\CodeGenerator" /I "..\..\..\Compiler\RegisterAllocator" /I\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86dis" /I\ + "..\..\..\Compiler\CodeGenerator\md\x86" /I\ + "..\..\..\Compiler\CodeGenerator\md" /I ".\\" /I ".\genfiles" /I\ + "..\..\..\Compiler\Optimizer" /I "..\..\..\Driver\StandAloneJava" /I\ + "..\..\..\Runtime\System" /I "..\..\..\Debugger" /I\ + "..\..\..\Runtime\System\md" /I "..\..\..\Debugger\Communication" /D "NDEBUG"\ + /D "EF_WINDOWS" /D "GENERATE_FOR_X86" /D "XP_PC" /D "DLL_BUILD" /D "WIN32" /D\ + "_CONSOLE" /D "_MBCS" /D "GENERATE_NATIVE_STUBS" /FR"$(INTDIR)\\"\ + /Fp"$(INTDIR)\electricalfire.pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c +CPP_OBJS=.\Release/ +CPP_SBRS=.\Release/ +BSC32=bscmake.exe +BSC32_FLAGS=/nologo /o"$(OUTDIR)\electricalfire.bsc" +BSC32_SBRS= \ + "$(INTDIR)\Address.sbr" \ + "$(INTDIR)\adler32.sbr" \ + "$(INTDIR)\AttributeHandlers.sbr" \ + "$(INTDIR)\Backend.sbr" \ + "$(INTDIR)\BufferedFileReader.sbr" \ + "$(INTDIR)\BytecodeGraph.sbr" \ + "$(INTDIR)\BytecodeTranslator.sbr" \ + "$(INTDIR)\BytecodeVerifier.sbr" \ + "$(INTDIR)\CatchAssert.sbr" \ + "$(INTDIR)\CGScheduler.sbr" \ + "$(INTDIR)\ClassCentral.sbr" \ + "$(INTDIR)\ClassFileSummary.sbr" \ + "$(INTDIR)\ClassReader.sbr" \ + "$(INTDIR)\ClassWorld.sbr" \ + "$(INTDIR)\CodeGenerator.sbr" \ + "$(INTDIR)\Coloring.sbr" \ + "$(INTDIR)\compress.sbr" \ + "$(INTDIR)\ControlGraph.sbr" \ + "$(INTDIR)\ControlNodes.sbr" \ + "$(INTDIR)\crc32.sbr" \ + "$(INTDIR)\CUtils.sbr" \ + "$(INTDIR)\Debugger.sbr" \ + "$(INTDIR)\DebugUtils.sbr" \ + "$(INTDIR)\deflate.sbr" \ + "$(INTDIR)\DiskFileReader.sbr" \ + "$(INTDIR)\ErrorHandling.sbr" \ + "$(INTDIR)\ExceptionTable.sbr" \ + "$(INTDIR)\FastBitMatrix.sbr" \ + "$(INTDIR)\FastBitSet.sbr" \ + "$(INTDIR)\FieldOrMethod.sbr" \ + "$(INTDIR)\FileReader.sbr" \ + "$(INTDIR)\FloatUtils.sbr" \ + "$(INTDIR)\gzio.sbr" \ + "$(INTDIR)\HTMLMethodDump.sbr" \ + "$(INTDIR)\IGVisualizer.sbr" \ + "$(INTDIR)\infblock.sbr" \ + "$(INTDIR)\infcodes.sbr" \ + "$(INTDIR)\inffast.sbr" \ + "$(INTDIR)\inflate.sbr" \ + "$(INTDIR)\inftrees.sbr" \ + "$(INTDIR)\infutil.sbr" \ + "$(INTDIR)\Instruction.sbr" \ + "$(INTDIR)\InstructionEmitter.sbr" \ + "$(INTDIR)\InterestingEvents.sbr" \ + "$(INTDIR)\InterfaceDispatchTable.sbr" \ + "$(INTDIR)\JavaBytecodes.sbr" \ + "$(INTDIR)\JavaObject.sbr" \ + "$(INTDIR)\JavaString.sbr" \ + "$(INTDIR)\JavaVM.sbr" \ + "$(INTDIR)\Jni.sbr" \ + "$(INTDIR)\JNIManglers.sbr" \ + "$(INTDIR)\jvmdi.sbr" \ + "$(INTDIR)\LogModule.sbr" \ + "$(INTDIR)\Method.sbr" \ + "$(INTDIR)\Monitor.sbr" \ + "$(INTDIR)\NameMangler.sbr" \ + "$(INTDIR)\NativeCodeCache.sbr" \ + "$(INTDIR)\NativeFormatter.sbr" \ + "$(INTDIR)\NativeMethodDispatcher.sbr" \ + "$(INTDIR)\NetscapeManglers.sbr" \ + "$(INTDIR)\PathComponent.sbr" \ + "$(INTDIR)\Pool.sbr" \ + "$(INTDIR)\PrimitiveBuilders.sbr" \ + "$(INTDIR)\PrimitiveGraphVerifier.sbr" \ + "$(INTDIR)\PrimitiveOptimizer.sbr" \ + "$(INTDIR)\Primitives.sbr" \ + "$(INTDIR)\RegisterAllocator.sbr" \ + "$(INTDIR)\Scheduler.sbr" \ + "$(INTDIR)\Spilling.sbr" \ + "$(INTDIR)\StackWalker.sbr" \ + "$(INTDIR)\SysCalls.sbr" \ + "$(INTDIR)\SysCallsRuntime.sbr" \ + "$(INTDIR)\Thread.sbr" \ + "$(INTDIR)\TranslationEnv.sbr" \ + "$(INTDIR)\Tree.sbr" \ + "$(INTDIR)\trees.sbr" \ + "$(INTDIR)\uncompr.sbr" \ + "$(INTDIR)\Value.sbr" \ + "$(INTDIR)\VerificationEnv.sbr" \ + "$(INTDIR)\VirtualRegister.sbr" \ + "$(INTDIR)\Win32BreakPoint.sbr" \ + "$(INTDIR)\Win32ExceptionHandler.sbr" \ + "$(INTDIR)\x86-win32.nad.burg.sbr" \ + "$(INTDIR)\x86ArgumentList.sbr" \ + "$(INTDIR)\x86ExceptionHandler.sbr" \ + "$(INTDIR)\x86Float.sbr" \ + "$(INTDIR)\x86Formatter.sbr" \ + "$(INTDIR)\x86NativeMethodStubs.sbr" \ + "$(INTDIR)\x86Opcode.sbr" \ + "$(INTDIR)\x86StdCall.sbr" \ + "$(INTDIR)\x86SysCallsRuntime.sbr" \ + "$(INTDIR)\x86Win32_Support.sbr" \ + "$(INTDIR)\x86Win32Emitter.sbr" \ + "$(INTDIR)\x86Win32Instruction.sbr" \ + "$(INTDIR)\x86Win32InvokeNative.sbr" \ + "$(INTDIR)\x86Win32Thread.sbr" \ + "$(INTDIR)\XDisAsm.sbr" \ + "$(INTDIR)\XDisAsmTable.sbr" \ + "$(INTDIR)\ZipArchive.sbr" \ + "$(INTDIR)\ZipFileReader.sbr" \ + "$(INTDIR)\zutil.sbr" + +"$(OUTDIR)\electricalfire.bsc" : "$(OUTDIR)" $(BSC32_SBRS) + $(BSC32) @<< + $(BSC32_FLAGS) $(BSC32_SBRS) +<< + +LINK32=link.exe +LINK32_FLAGS=electric\DebuggerChannel.lib\ + ..\..\..\..\dist\WINNT4.0_OPT.OBJ\lib\libnspr20.lib\ + ..\..\..\..\dist\WINNT4.0_OPT.OBJ\lib\libplc20_s.lib kernel32.lib user32.lib\ + gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib\ + oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib /nologo\ + /subsystem:console /dll /incremental:no /pdb:"$(OUTDIR)\electricalfire.pdb"\ + /machine:I386 /nodefaultlib:"MSVCRT" /out:"$(OUTDIR)\electricalfire.dll"\ + /implib:"$(OUTDIR)\electricalfire.lib" +LINK32_OBJS= \ + "$(INTDIR)\Address.obj" \ + "$(INTDIR)\adler32.obj" \ + "$(INTDIR)\AttributeHandlers.obj" \ + "$(INTDIR)\Backend.obj" \ + "$(INTDIR)\BufferedFileReader.obj" \ + "$(INTDIR)\BytecodeGraph.obj" \ + "$(INTDIR)\BytecodeTranslator.obj" \ + "$(INTDIR)\BytecodeVerifier.obj" \ + "$(INTDIR)\CatchAssert.obj" \ + "$(INTDIR)\CGScheduler.obj" \ + "$(INTDIR)\ClassCentral.obj" \ + "$(INTDIR)\ClassFileSummary.obj" \ + "$(INTDIR)\ClassReader.obj" \ + "$(INTDIR)\ClassWorld.obj" \ + "$(INTDIR)\CodeGenerator.obj" \ + "$(INTDIR)\Coloring.obj" \ + "$(INTDIR)\compress.obj" \ + "$(INTDIR)\ControlGraph.obj" \ + "$(INTDIR)\ControlNodes.obj" \ + "$(INTDIR)\crc32.obj" \ + "$(INTDIR)\CUtils.obj" \ + "$(INTDIR)\Debugger.obj" \ + "$(INTDIR)\DebugUtils.obj" \ + "$(INTDIR)\deflate.obj" \ + "$(INTDIR)\DiskFileReader.obj" \ + "$(INTDIR)\ErrorHandling.obj" \ + "$(INTDIR)\ExceptionTable.obj" \ + "$(INTDIR)\FastBitMatrix.obj" \ + "$(INTDIR)\FastBitSet.obj" \ + "$(INTDIR)\FieldOrMethod.obj" \ + "$(INTDIR)\FileReader.obj" \ + "$(INTDIR)\FloatUtils.obj" \ + "$(INTDIR)\gzio.obj" \ + "$(INTDIR)\HTMLMethodDump.obj" \ + "$(INTDIR)\IGVisualizer.obj" \ + "$(INTDIR)\infblock.obj" \ + "$(INTDIR)\infcodes.obj" \ + "$(INTDIR)\inffast.obj" \ + "$(INTDIR)\inflate.obj" \ + "$(INTDIR)\inftrees.obj" \ + "$(INTDIR)\infutil.obj" \ + "$(INTDIR)\Instruction.obj" \ + "$(INTDIR)\InstructionEmitter.obj" \ + "$(INTDIR)\InterestingEvents.obj" \ + "$(INTDIR)\InterfaceDispatchTable.obj" \ + "$(INTDIR)\JavaBytecodes.obj" \ + "$(INTDIR)\JavaObject.obj" \ + "$(INTDIR)\JavaString.obj" \ + "$(INTDIR)\JavaVM.obj" \ + "$(INTDIR)\Jni.obj" \ + "$(INTDIR)\JNIManglers.obj" \ + "$(INTDIR)\jvmdi.obj" \ + "$(INTDIR)\LogModule.obj" \ + "$(INTDIR)\Method.obj" \ + "$(INTDIR)\Monitor.obj" \ + "$(INTDIR)\NameMangler.obj" \ + "$(INTDIR)\NativeCodeCache.obj" \ + "$(INTDIR)\NativeFormatter.obj" \ + "$(INTDIR)\NativeMethodDispatcher.obj" \ + "$(INTDIR)\NetscapeManglers.obj" \ + "$(INTDIR)\PathComponent.obj" \ + "$(INTDIR)\Pool.obj" \ + "$(INTDIR)\PrimitiveBuilders.obj" \ + "$(INTDIR)\PrimitiveGraphVerifier.obj" \ + "$(INTDIR)\PrimitiveOptimizer.obj" \ + "$(INTDIR)\Primitives.obj" \ + "$(INTDIR)\RegisterAllocator.obj" \ + "$(INTDIR)\Scheduler.obj" \ + "$(INTDIR)\Spilling.obj" \ + "$(INTDIR)\StackWalker.obj" \ + "$(INTDIR)\SysCalls.obj" \ + "$(INTDIR)\SysCallsRuntime.obj" \ + "$(INTDIR)\Thread.obj" \ + "$(INTDIR)\TranslationEnv.obj" \ + "$(INTDIR)\Tree.obj" \ + "$(INTDIR)\trees.obj" \ + "$(INTDIR)\uncompr.obj" \ + "$(INTDIR)\Value.obj" \ + "$(INTDIR)\VerificationEnv.obj" \ + "$(INTDIR)\VirtualRegister.obj" \ + "$(INTDIR)\Win32BreakPoint.obj" \ + "$(INTDIR)\Win32ExceptionHandler.obj" \ + "$(INTDIR)\x86-win32.nad.burg.obj" \ + "$(INTDIR)\x86ArgumentList.obj" \ + "$(INTDIR)\x86ExceptionHandler.obj" \ + "$(INTDIR)\x86Float.obj" \ + "$(INTDIR)\x86Formatter.obj" \ + "$(INTDIR)\x86NativeMethodStubs.obj" \ + "$(INTDIR)\x86Opcode.obj" \ + "$(INTDIR)\x86StdCall.obj" \ + "$(INTDIR)\x86SysCallsRuntime.obj" \ + "$(INTDIR)\x86Win32_Support.obj" \ + "$(INTDIR)\x86Win32Emitter.obj" \ + "$(INTDIR)\x86Win32Instruction.obj" \ + "$(INTDIR)\x86Win32InvokeNative.obj" \ + "$(INTDIR)\x86Win32Thread.obj" \ + "$(INTDIR)\XDisAsm.obj" \ + "$(INTDIR)\XDisAsmTable.obj" \ + "$(INTDIR)\ZipArchive.obj" \ + "$(INTDIR)\ZipFileReader.obj" \ + "$(INTDIR)\zutil.obj" \ + "$(OUTDIR)\DebuggerChannel.lib" + +"$(OUTDIR)\electricalfire.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ELSEIF "$(CFG)" == "electricalfire - Win32 Debug" + +OUTDIR=.\electric +INTDIR=.\electric +# Begin Custom Macros +OutDir=.\electric +# End Custom Macros + +!IF "$(RECURSE)" == "0" + +ALL : "genfiles\$(InputName).h" "genfiles\$(InputName).cpp"\ + "$(OUTDIR)\electricalfire.dll" "$(OUTDIR)\electricalfire.bsc" + +!ELSE + +ALL : "genfiles\$(InputName).h" "genfiles\$(InputName).cpp"\ + "$(OUTDIR)\electricalfire.dll" "$(OUTDIR)\electricalfire.bsc" + +!ENDIF + +!IF "$(RECURSE)" == "1" +CLEAN :"Burg - Win32 DebugCLEAN" "DebuggerChannel - Win32 DebugCLEAN" +!ELSE +CLEAN : +!ENDIF + -@erase "$(INTDIR)\Address.obj" + -@erase "$(INTDIR)\Address.sbr" + -@erase "$(INTDIR)\adler32.obj" + -@erase "$(INTDIR)\adler32.sbr" + -@erase "$(INTDIR)\AttributeHandlers.obj" + -@erase "$(INTDIR)\AttributeHandlers.sbr" + -@erase "$(INTDIR)\Backend.obj" + -@erase "$(INTDIR)\Backend.sbr" + -@erase "$(INTDIR)\BufferedFileReader.obj" + -@erase "$(INTDIR)\BufferedFileReader.sbr" + -@erase "$(INTDIR)\BytecodeGraph.obj" + -@erase "$(INTDIR)\BytecodeGraph.sbr" + -@erase "$(INTDIR)\BytecodeTranslator.obj" + -@erase "$(INTDIR)\BytecodeTranslator.sbr" + -@erase "$(INTDIR)\BytecodeVerifier.obj" + -@erase "$(INTDIR)\BytecodeVerifier.sbr" + -@erase "$(INTDIR)\CatchAssert.obj" + -@erase "$(INTDIR)\CatchAssert.sbr" + -@erase "$(INTDIR)\CGScheduler.obj" + -@erase "$(INTDIR)\CGScheduler.sbr" + -@erase "$(INTDIR)\ClassCentral.obj" + -@erase "$(INTDIR)\ClassCentral.sbr" + -@erase "$(INTDIR)\ClassFileSummary.obj" + -@erase "$(INTDIR)\ClassFileSummary.sbr" + -@erase "$(INTDIR)\ClassReader.obj" + -@erase "$(INTDIR)\ClassReader.sbr" + -@erase "$(INTDIR)\ClassWorld.obj" + -@erase "$(INTDIR)\ClassWorld.sbr" + -@erase "$(INTDIR)\CodeGenerator.obj" + -@erase "$(INTDIR)\CodeGenerator.sbr" + -@erase "$(INTDIR)\Coloring.obj" + -@erase "$(INTDIR)\Coloring.sbr" + -@erase "$(INTDIR)\compress.obj" + -@erase "$(INTDIR)\compress.sbr" + -@erase "$(INTDIR)\ControlGraph.obj" + -@erase "$(INTDIR)\ControlGraph.sbr" + -@erase "$(INTDIR)\ControlNodes.obj" + -@erase "$(INTDIR)\ControlNodes.sbr" + -@erase "$(INTDIR)\crc32.obj" + -@erase "$(INTDIR)\crc32.sbr" + -@erase "$(INTDIR)\CUtils.obj" + -@erase "$(INTDIR)\CUtils.sbr" + -@erase "$(INTDIR)\Debugger.obj" + -@erase "$(INTDIR)\Debugger.sbr" + -@erase "$(INTDIR)\DebugUtils.obj" + -@erase "$(INTDIR)\DebugUtils.sbr" + -@erase "$(INTDIR)\deflate.obj" + -@erase "$(INTDIR)\deflate.sbr" + -@erase "$(INTDIR)\DiskFileReader.obj" + -@erase "$(INTDIR)\DiskFileReader.sbr" + -@erase "$(INTDIR)\ErrorHandling.obj" + -@erase "$(INTDIR)\ErrorHandling.sbr" + -@erase "$(INTDIR)\ExceptionTable.obj" + -@erase "$(INTDIR)\ExceptionTable.sbr" + -@erase "$(INTDIR)\FastBitMatrix.obj" + -@erase "$(INTDIR)\FastBitMatrix.sbr" + -@erase "$(INTDIR)\FastBitSet.obj" + -@erase "$(INTDIR)\FastBitSet.sbr" + -@erase "$(INTDIR)\FieldOrMethod.obj" + -@erase "$(INTDIR)\FieldOrMethod.sbr" + -@erase "$(INTDIR)\FileReader.obj" + -@erase "$(INTDIR)\FileReader.sbr" + -@erase "$(INTDIR)\FloatUtils.obj" + -@erase "$(INTDIR)\FloatUtils.sbr" + -@erase "$(INTDIR)\gzio.obj" + -@erase "$(INTDIR)\gzio.sbr" + -@erase "$(INTDIR)\HTMLMethodDump.obj" + -@erase "$(INTDIR)\HTMLMethodDump.sbr" + -@erase "$(INTDIR)\IGVisualizer.obj" + -@erase "$(INTDIR)\IGVisualizer.sbr" + -@erase "$(INTDIR)\infblock.obj" + -@erase "$(INTDIR)\infblock.sbr" + -@erase "$(INTDIR)\infcodes.obj" + -@erase "$(INTDIR)\infcodes.sbr" + -@erase "$(INTDIR)\inffast.obj" + -@erase "$(INTDIR)\inffast.sbr" + -@erase "$(INTDIR)\inflate.obj" + -@erase "$(INTDIR)\inflate.sbr" + -@erase "$(INTDIR)\inftrees.obj" + -@erase "$(INTDIR)\inftrees.sbr" + -@erase "$(INTDIR)\infutil.obj" + -@erase "$(INTDIR)\infutil.sbr" + -@erase "$(INTDIR)\Instruction.obj" + -@erase "$(INTDIR)\Instruction.sbr" + -@erase "$(INTDIR)\InstructionEmitter.obj" + -@erase "$(INTDIR)\InstructionEmitter.sbr" + -@erase "$(INTDIR)\InterestingEvents.obj" + -@erase "$(INTDIR)\InterestingEvents.sbr" + -@erase "$(INTDIR)\InterfaceDispatchTable.obj" + -@erase "$(INTDIR)\InterfaceDispatchTable.sbr" + -@erase "$(INTDIR)\JavaBytecodes.obj" + -@erase "$(INTDIR)\JavaBytecodes.sbr" + -@erase "$(INTDIR)\JavaObject.obj" + -@erase "$(INTDIR)\JavaObject.sbr" + -@erase "$(INTDIR)\JavaString.obj" + -@erase "$(INTDIR)\JavaString.sbr" + -@erase "$(INTDIR)\JavaVM.obj" + -@erase "$(INTDIR)\JavaVM.sbr" + -@erase "$(INTDIR)\Jni.obj" + -@erase "$(INTDIR)\Jni.sbr" + -@erase "$(INTDIR)\JNIManglers.obj" + -@erase "$(INTDIR)\JNIManglers.sbr" + -@erase "$(INTDIR)\jvmdi.obj" + -@erase "$(INTDIR)\jvmdi.sbr" + -@erase "$(INTDIR)\LogModule.obj" + -@erase "$(INTDIR)\LogModule.sbr" + -@erase "$(INTDIR)\Method.obj" + -@erase "$(INTDIR)\Method.sbr" + -@erase "$(INTDIR)\Monitor.obj" + -@erase "$(INTDIR)\Monitor.sbr" + -@erase "$(INTDIR)\NameMangler.obj" + -@erase "$(INTDIR)\NameMangler.sbr" + -@erase "$(INTDIR)\NativeCodeCache.obj" + -@erase "$(INTDIR)\NativeCodeCache.sbr" + -@erase "$(INTDIR)\NativeFormatter.obj" + -@erase "$(INTDIR)\NativeFormatter.sbr" + -@erase "$(INTDIR)\NativeMethodDispatcher.obj" + -@erase "$(INTDIR)\NativeMethodDispatcher.sbr" + -@erase "$(INTDIR)\NetscapeManglers.obj" + -@erase "$(INTDIR)\NetscapeManglers.sbr" + -@erase "$(INTDIR)\PathComponent.obj" + -@erase "$(INTDIR)\PathComponent.sbr" + -@erase "$(INTDIR)\Pool.obj" + -@erase "$(INTDIR)\Pool.sbr" + -@erase "$(INTDIR)\PrimitiveBuilders.obj" + -@erase "$(INTDIR)\PrimitiveBuilders.sbr" + -@erase "$(INTDIR)\PrimitiveGraphVerifier.obj" + -@erase "$(INTDIR)\PrimitiveGraphVerifier.sbr" + -@erase "$(INTDIR)\PrimitiveOptimizer.obj" + -@erase "$(INTDIR)\PrimitiveOptimizer.sbr" + -@erase "$(INTDIR)\Primitives.obj" + -@erase "$(INTDIR)\Primitives.sbr" + -@erase "$(INTDIR)\RegisterAllocator.obj" + -@erase "$(INTDIR)\RegisterAllocator.sbr" + -@erase "$(INTDIR)\Scheduler.obj" + -@erase "$(INTDIR)\Scheduler.sbr" + -@erase "$(INTDIR)\Spilling.obj" + -@erase "$(INTDIR)\Spilling.sbr" + -@erase "$(INTDIR)\StackWalker.obj" + -@erase "$(INTDIR)\StackWalker.sbr" + -@erase "$(INTDIR)\SysCalls.obj" + -@erase "$(INTDIR)\SysCalls.sbr" + -@erase "$(INTDIR)\SysCallsRuntime.obj" + -@erase "$(INTDIR)\SysCallsRuntime.sbr" + -@erase "$(INTDIR)\Thread.obj" + -@erase "$(INTDIR)\Thread.sbr" + -@erase "$(INTDIR)\TranslationEnv.obj" + -@erase "$(INTDIR)\TranslationEnv.sbr" + -@erase "$(INTDIR)\Tree.obj" + -@erase "$(INTDIR)\Tree.sbr" + -@erase "$(INTDIR)\trees.obj" + -@erase "$(INTDIR)\trees.sbr" + -@erase "$(INTDIR)\uncompr.obj" + -@erase "$(INTDIR)\uncompr.sbr" + -@erase "$(INTDIR)\Value.obj" + -@erase "$(INTDIR)\Value.sbr" + -@erase "$(INTDIR)\vc50.idb" + -@erase "$(INTDIR)\vc50.pdb" + -@erase "$(INTDIR)\VerificationEnv.obj" + -@erase "$(INTDIR)\VerificationEnv.sbr" + -@erase "$(INTDIR)\VirtualRegister.obj" + -@erase "$(INTDIR)\VirtualRegister.sbr" + -@erase "$(INTDIR)\Win32BreakPoint.obj" + -@erase "$(INTDIR)\Win32BreakPoint.sbr" + -@erase "$(INTDIR)\Win32ExceptionHandler.obj" + -@erase "$(INTDIR)\Win32ExceptionHandler.sbr" + -@erase "$(INTDIR)\x86-win32.nad.burg.obj" + -@erase "$(INTDIR)\x86-win32.nad.burg.sbr" + -@erase "$(INTDIR)\x86ArgumentList.obj" + -@erase "$(INTDIR)\x86ArgumentList.sbr" + -@erase "$(INTDIR)\x86ExceptionHandler.obj" + -@erase "$(INTDIR)\x86ExceptionHandler.sbr" + -@erase "$(INTDIR)\x86Float.obj" + -@erase "$(INTDIR)\x86Float.sbr" + -@erase "$(INTDIR)\x86Formatter.obj" + -@erase "$(INTDIR)\x86Formatter.sbr" + -@erase "$(INTDIR)\x86NativeMethodStubs.obj" + -@erase "$(INTDIR)\x86NativeMethodStubs.sbr" + -@erase "$(INTDIR)\x86Opcode.obj" + -@erase "$(INTDIR)\x86Opcode.sbr" + -@erase "$(INTDIR)\x86StdCall.obj" + -@erase "$(INTDIR)\x86StdCall.sbr" + -@erase "$(INTDIR)\x86SysCallsRuntime.obj" + -@erase "$(INTDIR)\x86SysCallsRuntime.sbr" + -@erase "$(INTDIR)\x86Win32_Support.obj" + -@erase "$(INTDIR)\x86Win32_Support.sbr" + -@erase "$(INTDIR)\x86Win32Emitter.obj" + -@erase "$(INTDIR)\x86Win32Emitter.sbr" + -@erase "$(INTDIR)\x86Win32Instruction.obj" + -@erase "$(INTDIR)\x86Win32Instruction.sbr" + -@erase "$(INTDIR)\x86Win32InvokeNative.obj" + -@erase "$(INTDIR)\x86Win32InvokeNative.sbr" + -@erase "$(INTDIR)\x86Win32Thread.obj" + -@erase "$(INTDIR)\x86Win32Thread.sbr" + -@erase "$(INTDIR)\XDisAsm.obj" + -@erase "$(INTDIR)\XDisAsm.sbr" + -@erase "$(INTDIR)\XDisAsmTable.obj" + -@erase "$(INTDIR)\XDisAsmTable.sbr" + -@erase "$(INTDIR)\ZipArchive.obj" + -@erase "$(INTDIR)\ZipArchive.sbr" + -@erase "$(INTDIR)\ZipFileReader.obj" + -@erase "$(INTDIR)\ZipFileReader.sbr" + -@erase "$(INTDIR)\zutil.obj" + -@erase "$(INTDIR)\zutil.sbr" + -@erase "$(OUTDIR)\electricalfire.bsc" + -@erase "$(OUTDIR)\electricalfire.dll" + -@erase "$(OUTDIR)\electricalfire.exp" + -@erase "$(OUTDIR)\electricalfire.ilk" + -@erase "$(OUTDIR)\electricalfire.lib" + -@erase "$(OUTDIR)\electricalfire.pdb" + -@erase "genfiles\$(InputName).cpp" + -@erase "genfiles\$(InputName).h" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +CPP_PROJ=/nologo /MDd /W3 /Gm /GX /Zi /I "..\..\..\Exports" /I\ + "..\..\..\Exports\md" /I "..\..\..\Utilities\General" /I\ + "..\..\..\Utilities\DisAssemblers\x86" /I "..\..\..\Utilities\General\md" /I\ + "..\..\..\Compiler\FrontEnd" /I "..\..\..\Compiler\PrimitiveGraph" /I\ + "..\..\..\Runtime\System\md\x86" /I\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include" /I "..\..\..\Utilities\zlib" /I\ + "..\..\..\Runtime\ClassInfo" /I "..\..\..\Runtime\ClassReader" /I\ + "..\..\..\Runtime\FileReader" /I "..\..\..\Runtime\NativeMethods" /I\ + "..\..\..\Runtime\Systems" /I "..\..\..\Compiler\CodeGenerator" /I\ + "..\..\..\Compiler\RegisterAllocator" /I\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86dis" /I\ + "..\..\..\Compiler\CodeGenerator\md\x86" /I\ + "..\..\..\Compiler\CodeGenerator\md" /I ".\\" /I ".\genfiles" /I\ + "..\..\..\Compiler\Optimizer" /I "..\..\..\Driver\StandAloneJava" /I\ + "..\..\..\Runtime\System" /I "..\..\..\Debugger" /I\ + "..\..\..\Runtime\System\md" /I "..\..\..\Debugger\Communication" /D "DEBUG" /D\ + "DEBUG_LOG" /D "_DEBUG" /D "DEBUG_DESANTIS" /D "DEBUG_kini" /D "EF_WINDOWS" /D\ + "GENERATE_FOR_X86" /D "XP_PC" /D "DLL_BUILD" /D "WIN32" /D "_CONSOLE" /D\ + "_MBCS" /D "GENERATE_NATIVE_STUBS" /FR"$(INTDIR)\\" /Fo"$(INTDIR)\\"\ + /Fd"$(INTDIR)\\" /FD /c +CPP_OBJS=.\electric/ +CPP_SBRS=.\electric/ +BSC32=bscmake.exe +BSC32_FLAGS=/nologo /o"$(OUTDIR)\electricalfire.bsc" +BSC32_SBRS= \ + "$(INTDIR)\Address.sbr" \ + "$(INTDIR)\adler32.sbr" \ + "$(INTDIR)\AttributeHandlers.sbr" \ + "$(INTDIR)\Backend.sbr" \ + "$(INTDIR)\BufferedFileReader.sbr" \ + "$(INTDIR)\BytecodeGraph.sbr" \ + "$(INTDIR)\BytecodeTranslator.sbr" \ + "$(INTDIR)\BytecodeVerifier.sbr" \ + "$(INTDIR)\CatchAssert.sbr" \ + "$(INTDIR)\CGScheduler.sbr" \ + "$(INTDIR)\ClassCentral.sbr" \ + "$(INTDIR)\ClassFileSummary.sbr" \ + "$(INTDIR)\ClassReader.sbr" \ + "$(INTDIR)\ClassWorld.sbr" \ + "$(INTDIR)\CodeGenerator.sbr" \ + "$(INTDIR)\Coloring.sbr" \ + "$(INTDIR)\compress.sbr" \ + "$(INTDIR)\ControlGraph.sbr" \ + "$(INTDIR)\ControlNodes.sbr" \ + "$(INTDIR)\crc32.sbr" \ + "$(INTDIR)\CUtils.sbr" \ + "$(INTDIR)\Debugger.sbr" \ + "$(INTDIR)\DebugUtils.sbr" \ + "$(INTDIR)\deflate.sbr" \ + "$(INTDIR)\DiskFileReader.sbr" \ + "$(INTDIR)\ErrorHandling.sbr" \ + "$(INTDIR)\ExceptionTable.sbr" \ + "$(INTDIR)\FastBitMatrix.sbr" \ + "$(INTDIR)\FastBitSet.sbr" \ + "$(INTDIR)\FieldOrMethod.sbr" \ + "$(INTDIR)\FileReader.sbr" \ + "$(INTDIR)\FloatUtils.sbr" \ + "$(INTDIR)\gzio.sbr" \ + "$(INTDIR)\HTMLMethodDump.sbr" \ + "$(INTDIR)\IGVisualizer.sbr" \ + "$(INTDIR)\infblock.sbr" \ + "$(INTDIR)\infcodes.sbr" \ + "$(INTDIR)\inffast.sbr" \ + "$(INTDIR)\inflate.sbr" \ + "$(INTDIR)\inftrees.sbr" \ + "$(INTDIR)\infutil.sbr" \ + "$(INTDIR)\Instruction.sbr" \ + "$(INTDIR)\InstructionEmitter.sbr" \ + "$(INTDIR)\InterestingEvents.sbr" \ + "$(INTDIR)\InterfaceDispatchTable.sbr" \ + "$(INTDIR)\JavaBytecodes.sbr" \ + "$(INTDIR)\JavaObject.sbr" \ + "$(INTDIR)\JavaString.sbr" \ + "$(INTDIR)\JavaVM.sbr" \ + "$(INTDIR)\Jni.sbr" \ + "$(INTDIR)\JNIManglers.sbr" \ + "$(INTDIR)\jvmdi.sbr" \ + "$(INTDIR)\LogModule.sbr" \ + "$(INTDIR)\Method.sbr" \ + "$(INTDIR)\Monitor.sbr" \ + "$(INTDIR)\NameMangler.sbr" \ + "$(INTDIR)\NativeCodeCache.sbr" \ + "$(INTDIR)\NativeFormatter.sbr" \ + "$(INTDIR)\NativeMethodDispatcher.sbr" \ + "$(INTDIR)\NetscapeManglers.sbr" \ + "$(INTDIR)\PathComponent.sbr" \ + "$(INTDIR)\Pool.sbr" \ + "$(INTDIR)\PrimitiveBuilders.sbr" \ + "$(INTDIR)\PrimitiveGraphVerifier.sbr" \ + "$(INTDIR)\PrimitiveOptimizer.sbr" \ + "$(INTDIR)\Primitives.sbr" \ + "$(INTDIR)\RegisterAllocator.sbr" \ + "$(INTDIR)\Scheduler.sbr" \ + "$(INTDIR)\Spilling.sbr" \ + "$(INTDIR)\StackWalker.sbr" \ + "$(INTDIR)\SysCalls.sbr" \ + "$(INTDIR)\SysCallsRuntime.sbr" \ + "$(INTDIR)\Thread.sbr" \ + "$(INTDIR)\TranslationEnv.sbr" \ + "$(INTDIR)\Tree.sbr" \ + "$(INTDIR)\trees.sbr" \ + "$(INTDIR)\uncompr.sbr" \ + "$(INTDIR)\Value.sbr" \ + "$(INTDIR)\VerificationEnv.sbr" \ + "$(INTDIR)\VirtualRegister.sbr" \ + "$(INTDIR)\Win32BreakPoint.sbr" \ + "$(INTDIR)\Win32ExceptionHandler.sbr" \ + "$(INTDIR)\x86-win32.nad.burg.sbr" \ + "$(INTDIR)\x86ArgumentList.sbr" \ + "$(INTDIR)\x86ExceptionHandler.sbr" \ + "$(INTDIR)\x86Float.sbr" \ + "$(INTDIR)\x86Formatter.sbr" \ + "$(INTDIR)\x86NativeMethodStubs.sbr" \ + "$(INTDIR)\x86Opcode.sbr" \ + "$(INTDIR)\x86StdCall.sbr" \ + "$(INTDIR)\x86SysCallsRuntime.sbr" \ + "$(INTDIR)\x86Win32_Support.sbr" \ + "$(INTDIR)\x86Win32Emitter.sbr" \ + "$(INTDIR)\x86Win32Instruction.sbr" \ + "$(INTDIR)\x86Win32InvokeNative.sbr" \ + "$(INTDIR)\x86Win32Thread.sbr" \ + "$(INTDIR)\XDisAsm.sbr" \ + "$(INTDIR)\XDisAsmTable.sbr" \ + "$(INTDIR)\ZipArchive.sbr" \ + "$(INTDIR)\ZipFileReader.sbr" \ + "$(INTDIR)\zutil.sbr" + +"$(OUTDIR)\electricalfire.bsc" : "$(OUTDIR)" $(BSC32_SBRS) + $(BSC32) @<< + $(BSC32_FLAGS) $(BSC32_SBRS) +<< + +LINK32=link.exe +LINK32_FLAGS=electric\DebuggerChannel.lib\ + ..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\lib\libnspr21.lib\ + ..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\lib\libplc21_s.lib wsock32.lib\ + kernel32.lib user32.lib /nologo /subsystem:console /dll /incremental:yes\ + /pdb:"$(OUTDIR)\electricalfire.pdb" /debug /machine:I386 /nodefaultlib:"MSVCRT"\ + /out:"$(OUTDIR)\electricalfire.dll" /implib:"$(OUTDIR)\electricalfire.lib"\ + /pdbtype:sept /libpath:"..\..\..\..\..\dist\WINNT4.0_DBG.OBJ\lib" +LINK32_OBJS= \ + "$(INTDIR)\Address.obj" \ + "$(INTDIR)\adler32.obj" \ + "$(INTDIR)\AttributeHandlers.obj" \ + "$(INTDIR)\Backend.obj" \ + "$(INTDIR)\BufferedFileReader.obj" \ + "$(INTDIR)\BytecodeGraph.obj" \ + "$(INTDIR)\BytecodeTranslator.obj" \ + "$(INTDIR)\BytecodeVerifier.obj" \ + "$(INTDIR)\CatchAssert.obj" \ + "$(INTDIR)\CGScheduler.obj" \ + "$(INTDIR)\ClassCentral.obj" \ + "$(INTDIR)\ClassFileSummary.obj" \ + "$(INTDIR)\ClassReader.obj" \ + "$(INTDIR)\ClassWorld.obj" \ + "$(INTDIR)\CodeGenerator.obj" \ + "$(INTDIR)\Coloring.obj" \ + "$(INTDIR)\compress.obj" \ + "$(INTDIR)\ControlGraph.obj" \ + "$(INTDIR)\ControlNodes.obj" \ + "$(INTDIR)\crc32.obj" \ + "$(INTDIR)\CUtils.obj" \ + "$(INTDIR)\Debugger.obj" \ + "$(INTDIR)\DebugUtils.obj" \ + "$(INTDIR)\deflate.obj" \ + "$(INTDIR)\DiskFileReader.obj" \ + "$(INTDIR)\ErrorHandling.obj" \ + "$(INTDIR)\ExceptionTable.obj" \ + "$(INTDIR)\FastBitMatrix.obj" \ + "$(INTDIR)\FastBitSet.obj" \ + "$(INTDIR)\FieldOrMethod.obj" \ + "$(INTDIR)\FileReader.obj" \ + "$(INTDIR)\FloatUtils.obj" \ + "$(INTDIR)\gzio.obj" \ + "$(INTDIR)\HTMLMethodDump.obj" \ + "$(INTDIR)\IGVisualizer.obj" \ + "$(INTDIR)\infblock.obj" \ + "$(INTDIR)\infcodes.obj" \ + "$(INTDIR)\inffast.obj" \ + "$(INTDIR)\inflate.obj" \ + "$(INTDIR)\inftrees.obj" \ + "$(INTDIR)\infutil.obj" \ + "$(INTDIR)\Instruction.obj" \ + "$(INTDIR)\InstructionEmitter.obj" \ + "$(INTDIR)\InterestingEvents.obj" \ + "$(INTDIR)\InterfaceDispatchTable.obj" \ + "$(INTDIR)\JavaBytecodes.obj" \ + "$(INTDIR)\JavaObject.obj" \ + "$(INTDIR)\JavaString.obj" \ + "$(INTDIR)\JavaVM.obj" \ + "$(INTDIR)\Jni.obj" \ + "$(INTDIR)\JNIManglers.obj" \ + "$(INTDIR)\jvmdi.obj" \ + "$(INTDIR)\LogModule.obj" \ + "$(INTDIR)\Method.obj" \ + "$(INTDIR)\Monitor.obj" \ + "$(INTDIR)\NameMangler.obj" \ + "$(INTDIR)\NativeCodeCache.obj" \ + "$(INTDIR)\NativeFormatter.obj" \ + "$(INTDIR)\NativeMethodDispatcher.obj" \ + "$(INTDIR)\NetscapeManglers.obj" \ + "$(INTDIR)\PathComponent.obj" \ + "$(INTDIR)\Pool.obj" \ + "$(INTDIR)\PrimitiveBuilders.obj" \ + "$(INTDIR)\PrimitiveGraphVerifier.obj" \ + "$(INTDIR)\PrimitiveOptimizer.obj" \ + "$(INTDIR)\Primitives.obj" \ + "$(INTDIR)\RegisterAllocator.obj" \ + "$(INTDIR)\Scheduler.obj" \ + "$(INTDIR)\Spilling.obj" \ + "$(INTDIR)\StackWalker.obj" \ + "$(INTDIR)\SysCalls.obj" \ + "$(INTDIR)\SysCallsRuntime.obj" \ + "$(INTDIR)\Thread.obj" \ + "$(INTDIR)\TranslationEnv.obj" \ + "$(INTDIR)\Tree.obj" \ + "$(INTDIR)\trees.obj" \ + "$(INTDIR)\uncompr.obj" \ + "$(INTDIR)\Value.obj" \ + "$(INTDIR)\VerificationEnv.obj" \ + "$(INTDIR)\VirtualRegister.obj" \ + "$(INTDIR)\Win32BreakPoint.obj" \ + "$(INTDIR)\Win32ExceptionHandler.obj" \ + "$(INTDIR)\x86-win32.nad.burg.obj" \ + "$(INTDIR)\x86ArgumentList.obj" \ + "$(INTDIR)\x86ExceptionHandler.obj" \ + "$(INTDIR)\x86Float.obj" \ + "$(INTDIR)\x86Formatter.obj" \ + "$(INTDIR)\x86NativeMethodStubs.obj" \ + "$(INTDIR)\x86Opcode.obj" \ + "$(INTDIR)\x86StdCall.obj" \ + "$(INTDIR)\x86SysCallsRuntime.obj" \ + "$(INTDIR)\x86Win32_Support.obj" \ + "$(INTDIR)\x86Win32Emitter.obj" \ + "$(INTDIR)\x86Win32Instruction.obj" \ + "$(INTDIR)\x86Win32InvokeNative.obj" \ + "$(INTDIR)\x86Win32Thread.obj" \ + "$(INTDIR)\XDisAsm.obj" \ + "$(INTDIR)\XDisAsmTable.obj" \ + "$(INTDIR)\ZipArchive.obj" \ + "$(INTDIR)\ZipFileReader.obj" \ + "$(INTDIR)\zutil.obj" \ + "$(OUTDIR)\DebuggerChannel.lib" + +"$(OUTDIR)\electricalfire.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ENDIF + +.c{$(CPP_OBJS)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cpp{$(CPP_OBJS)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cxx{$(CPP_OBJS)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.c{$(CPP_SBRS)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cpp{$(CPP_SBRS)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cxx{$(CPP_SBRS)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +MTL_PROJ= + +!IF "$(CFG)" == "electricalfire - Win32 Release" || "$(CFG)" ==\ + "electricalfire - Win32 Debug" +SOURCE=".\genfiles\x86-win32.nad.burg.cpp" + +!IF "$(CFG)" == "electricalfire - Win32 Release" + +DEP_CPP_X86_W=\ + "..\..\..\Compiler\CodeGenerator\Burg.h"\ + "..\..\..\Compiler\CodeGenerator\CodeGenerator.h"\ + "..\..\..\Compiler\CodeGenerator\FormatStructures.h"\ + "..\..\..\Compiler\CodeGenerator\Instruction.h"\ + "..\..\..\Compiler\CodeGenerator\InstructionEmitter.h"\ + "..\..\..\Compiler\CodeGenerator\md\CpuInfo.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Formatter.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Opcode.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Cpu.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Emitter.h"\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlNodes.h"\ + "..\..\..\Compiler\PrimitiveGraph\PrimitiveOperations.h"\ + "..\..\..\Compiler\PrimitiveGraph\Primitives.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Compiler\RegisterAllocator\VirtualRegister.h"\ + "..\..\..\Runtime\ClassReader\Attributes.h"\ + "..\..\..\Runtime\ClassReader\ConstantPool.h"\ + "..\..\..\Runtime\ClassReader\utils.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\System\ClassWorld.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FastBitMatrix.h"\ + "..\..\..\Utilities\General\FastBitSet.h"\ + "..\..\..\Utilities\General\FastHashTable.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\Nonspr.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + +NODEP_CPP_X86_W=\ + "..\..\..\Compiler\CodeGenerator\md\HPPACpu.h"\ + "..\..\..\Compiler\CodeGenerator\md\PPC601Cpu.h"\ + "..\..\..\Compiler\CodeGenerator\prtypes.h"\ + "..\..\..\Runtime\ClassReader\prtypes.h"\ + "..\..\..\Utilities\General\plstr.h"\ + "..\..\..\Utilities\General\prbit.h"\ + "..\..\..\Utilities\General\prlog.h"\ + "..\..\..\Utilities\General\prlong.h"\ + + +"$(INTDIR)\x86-win32.nad.burg.obj" "$(INTDIR)\x86-win32.nad.burg.sbr" : \ +$(SOURCE) $(DEP_CPP_X86_W) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "electricalfire - Win32 Debug" + +DEP_CPP_X86_W=\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\obsolete\protypes.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prbit.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcpucfg.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinet.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinrval.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prio.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlog.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlong.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtime.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtypes.h"\ + "..\..\..\Compiler\CodeGenerator\Burg.h"\ + "..\..\..\Compiler\CodeGenerator\CodeGenerator.h"\ + "..\..\..\Compiler\CodeGenerator\md\CpuInfo.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Cpu.h"\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\PrimitiveOperations.h"\ + "..\..\..\Compiler\PrimitiveGraph\Primitives.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Compiler\RegisterAllocator\VirtualRegister.h"\ + "..\..\..\Runtime\ClassReader\Attributes.h"\ + "..\..\..\Runtime\ClassReader\ConstantPool.h"\ + "..\..\..\Runtime\ClassReader\utils.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FastBitMatrix.h"\ + "..\..\..\Utilities\General\FastBitSet.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + + +"$(INTDIR)\x86-win32.nad.burg.obj" "$(INTDIR)\x86-win32.nad.burg.sbr" : \ +$(SOURCE) $(DEP_CPP_X86_W) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +SOURCE=".\genfiles\ppc601-macos.nad.burg.cpp" +SOURCE=..\..\..\Runtime\ClassInfo\ClassCentral.cpp + +!IF "$(CFG)" == "electricalfire - Win32 Release" + +DEP_CPP_CLASS=\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Runtime\ClassInfo\ClassCentral.h"\ + "..\..\..\Runtime\ClassInfo\ClassFileSummary.h"\ + "..\..\..\Runtime\ClassInfo\Collector.h"\ + "..\..\..\Runtime\ClassInfo\PathComponent.h"\ + "..\..\..\Runtime\ClassInfo\StringPool.h"\ + "..\..\..\Runtime\ClassReader\Attributes.h"\ + "..\..\..\Runtime\ClassReader\ClassReader.h"\ + "..\..\..\Runtime\ClassReader\ConstantPool.h"\ + "..\..\..\Runtime\ClassReader\InfoItem.h"\ + "..\..\..\Runtime\ClassReader\utils.h"\ + "..\..\..\Runtime\FileReader\DiskFileReader.h"\ + "..\..\..\Runtime\FileReader\FileReader.h"\ + "..\..\..\Runtime\FileReader\ZipArchive.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\System\ClassWorld.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Runtime\System\JavaString.h"\ + "..\..\..\Runtime\System\Method.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\CUtils.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FastHashTable.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\Nonspr.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\StringUtils.h"\ + "..\..\..\Utilities\General\Vector.h"\ + "..\..\..\Utilities\zlib\zconf.h"\ + "..\..\..\Utilities\zlib\zlib.h"\ + +NODEP_CPP_CLASS=\ + "..\..\..\Runtime\ClassInfo\plstr.h"\ + "..\..\..\Runtime\ClassInfo\prenv.h"\ + "..\..\..\Runtime\ClassInfo\prio.h"\ + "..\..\..\Runtime\ClassInfo\prprf.h"\ + "..\..\..\Runtime\ClassReader\prtypes.h"\ + "..\..\..\Runtime\FileReader\prio.h"\ + "..\..\..\Runtime\FileReader\prtypes.h"\ + "..\..\..\Utilities\General\plstr.h"\ + "..\..\..\Utilities\General\prio.h"\ + "..\..\..\Utilities\General\prlog.h"\ + "..\..\..\Utilities\General\prlong.h"\ + "..\..\..\Utilities\General\prprf.h"\ + + +"$(INTDIR)\ClassCentral.obj" "$(INTDIR)\ClassCentral.sbr" : $(SOURCE)\ + $(DEP_CPP_CLASS) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "electricalfire - Win32 Debug" + +DEP_CPP_CLASS=\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\obsolete\protypes.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\plstr.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcpucfg.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prenv.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinet.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinrval.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prio.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlog.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlong.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prprf.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtime.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtypes.h"\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Runtime\ClassInfo\ClassCentral.h"\ + "..\..\..\Runtime\ClassInfo\ClassFileSummary.h"\ + "..\..\..\Runtime\ClassInfo\Collector.h"\ + "..\..\..\Runtime\ClassInfo\PathComponent.h"\ + "..\..\..\Runtime\ClassInfo\StringPool.h"\ + "..\..\..\Runtime\ClassReader\Attributes.h"\ + "..\..\..\Runtime\ClassReader\ClassReader.h"\ + "..\..\..\Runtime\ClassReader\ConstantPool.h"\ + "..\..\..\Runtime\ClassReader\InfoItem.h"\ + "..\..\..\Runtime\ClassReader\utils.h"\ + "..\..\..\Runtime\FileReader\DiskFileReader.h"\ + "..\..\..\Runtime\FileReader\FileReader.h"\ + "..\..\..\Runtime\FileReader\ZipArchive.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\System\ClassWorld.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Runtime\System\JavaString.h"\ + "..\..\..\Runtime\System\Method.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\CUtils.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FastHashTable.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\StringUtils.h"\ + "..\..\..\Utilities\General\Vector.h"\ + "..\..\..\Utilities\zlib\zconf.h"\ + "..\..\..\Utilities\zlib\zlib.h"\ + + +"$(INTDIR)\ClassCentral.obj" "$(INTDIR)\ClassCentral.sbr" : $(SOURCE)\ + $(DEP_CPP_CLASS) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +SOURCE=..\..\..\Runtime\ClassInfo\ClassFileSummary.cpp + +!IF "$(CFG)" == "electricalfire - Win32 Release" + +DEP_CPP_CLASSF=\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Debugger\Communication\DebuggerChannel.h"\ + "..\..\..\Debugger\Debugger.h"\ + "..\..\..\Runtime\ClassInfo\ClassCentral.h"\ + "..\..\..\Runtime\ClassInfo\ClassFileSummary.h"\ + "..\..\..\Runtime\ClassInfo\Collector.h"\ + "..\..\..\Runtime\ClassInfo\PathComponent.h"\ + "..\..\..\Runtime\ClassInfo\StringPool.h"\ + "..\..\..\Runtime\ClassReader\Attributes.h"\ + "..\..\..\Runtime\ClassReader\ClassReader.h"\ + "..\..\..\Runtime\ClassReader\ConstantPool.h"\ + "..\..\..\Runtime\ClassReader\InfoItem.h"\ + "..\..\..\Runtime\ClassReader\utils.h"\ + "..\..\..\Runtime\FileReader\FileReader.h"\ + "..\..\..\Runtime\FileReader\ZipArchive.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\System\ClassWorld.h"\ + "..\..\..\Runtime\System\FieldOrMethod.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Runtime\System\JavaString.h"\ + "..\..\..\Runtime\System\Method.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FastHashTable.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\InterestingEvents.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\Nonspr.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + "..\..\..\Utilities\zlib\zconf.h"\ + "..\..\..\Utilities\zlib\zlib.h"\ + +NODEP_CPP_CLASSF=\ + "..\..\..\Debugger\Communication\prio.h"\ + "..\..\..\Debugger\Communication\prlock.h"\ + "..\..\..\Debugger\Communication\prprf.h"\ + "..\..\..\Debugger\nspr.h"\ + "..\..\..\Runtime\ClassInfo\plstr.h"\ + "..\..\..\Runtime\ClassInfo\prprf.h"\ + "..\..\..\Runtime\ClassReader\prtypes.h"\ + "..\..\..\Runtime\FileReader\prio.h"\ + "..\..\..\Runtime\FileReader\prtypes.h"\ + "..\..\..\Runtime\System\plstr.h"\ + "..\..\..\Utilities\General\plstr.h"\ + "..\..\..\Utilities\General\prlog.h"\ + "..\..\..\Utilities\General\prlong.h"\ + + +"$(INTDIR)\ClassFileSummary.obj" "$(INTDIR)\ClassFileSummary.sbr" : $(SOURCE)\ + $(DEP_CPP_CLASSF) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "electricalfire - Win32 Debug" + +DEP_CPP_CLASSF=\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\nspr.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\obsolete\protypes.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\plstr.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\pratom.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prbit.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prclist.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcmon.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcpucfg.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcvar.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prdtoa.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prenv.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prerror.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinet.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinit.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinrval.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prio.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlink.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlock.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlog.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlong.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prmem.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prmon.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prnetdb.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prprf.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prproces.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prsystem.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prthread.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtime.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtypes.h"\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Debugger\Communication\DebuggerChannel.h"\ + "..\..\..\Debugger\Debugger.h"\ + "..\..\..\Runtime\ClassInfo\ClassCentral.h"\ + "..\..\..\Runtime\ClassInfo\ClassFileSummary.h"\ + "..\..\..\Runtime\ClassInfo\Collector.h"\ + "..\..\..\Runtime\ClassInfo\PathComponent.h"\ + "..\..\..\Runtime\ClassInfo\StringPool.h"\ + "..\..\..\Runtime\ClassReader\Attributes.h"\ + "..\..\..\Runtime\ClassReader\ClassReader.h"\ + "..\..\..\Runtime\ClassReader\ConstantPool.h"\ + "..\..\..\Runtime\ClassReader\InfoItem.h"\ + "..\..\..\Runtime\ClassReader\utils.h"\ + "..\..\..\Runtime\FileReader\FileReader.h"\ + "..\..\..\Runtime\FileReader\ZipArchive.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\System\ClassWorld.h"\ + "..\..\..\Runtime\System\FieldOrMethod.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Runtime\System\JavaString.h"\ + "..\..\..\Runtime\System\Method.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FastHashTable.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\InterestingEvents.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + "..\..\..\Utilities\zlib\zconf.h"\ + "..\..\..\Utilities\zlib\zlib.h"\ + + +"$(INTDIR)\ClassFileSummary.obj" "$(INTDIR)\ClassFileSummary.sbr" : $(SOURCE)\ + $(DEP_CPP_CLASSF) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +SOURCE=..\..\..\Runtime\ClassInfo\PathComponent.cpp + +!IF "$(CFG)" == "electricalfire - Win32 Release" + +DEP_CPP_PATHC=\ + "..\..\..\Runtime\ClassInfo\PathComponent.h"\ + "..\..\..\Runtime\FileReader\DiskFileReader.h"\ + "..\..\..\Runtime\FileReader\FileReader.h"\ + "..\..\..\Runtime\FileReader\ZipArchive.h"\ + "..\..\..\Runtime\FileReader\ZipFileReader.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\CUtils.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\Nonspr.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\StringUtils.h"\ + "..\..\..\Utilities\zlib\zconf.h"\ + "..\..\..\Utilities\zlib\zlib.h"\ + +NODEP_CPP_PATHC=\ + "..\..\..\Runtime\ClassInfo\plstr.h"\ + "..\..\..\Runtime\ClassInfo\prio.h"\ + "..\..\..\Runtime\ClassInfo\prprf.h"\ + "..\..\..\Runtime\FileReader\prio.h"\ + "..\..\..\Runtime\FileReader\prtypes.h"\ + "..\..\..\Utilities\General\plstr.h"\ + "..\..\..\Utilities\General\prio.h"\ + "..\..\..\Utilities\General\prlog.h"\ + "..\..\..\Utilities\General\prlong.h"\ + "..\..\..\Utilities\General\prprf.h"\ + + +"$(INTDIR)\PathComponent.obj" "$(INTDIR)\PathComponent.sbr" : $(SOURCE)\ + $(DEP_CPP_PATHC) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "electricalfire - Win32 Debug" + +DEP_CPP_PATHC=\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\obsolete\protypes.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\plstr.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcpucfg.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinet.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinrval.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prio.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlog.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlong.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prprf.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtime.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtypes.h"\ + "..\..\..\Runtime\ClassInfo\PathComponent.h"\ + "..\..\..\Runtime\FileReader\DiskFileReader.h"\ + "..\..\..\Runtime\FileReader\FileReader.h"\ + "..\..\..\Runtime\FileReader\ZipArchive.h"\ + "..\..\..\Runtime\FileReader\ZipFileReader.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\CUtils.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\StringUtils.h"\ + "..\..\..\Utilities\zlib\zconf.h"\ + "..\..\..\Utilities\zlib\zlib.h"\ + + +"$(INTDIR)\PathComponent.obj" "$(INTDIR)\PathComponent.sbr" : $(SOURCE)\ + $(DEP_CPP_PATHC) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +SOURCE=..\..\..\Runtime\ClassReader\AttributeHandlers.cpp + +!IF "$(CFG)" == "electricalfire - Win32 Release" + +DEP_CPP_ATTRI=\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Runtime\ClassInfo\StringPool.h"\ + "..\..\..\Runtime\ClassReader\AttributeHandlers.h"\ + "..\..\..\Runtime\ClassReader\Attributes.h"\ + "..\..\..\Runtime\ClassReader\ClassReader.h"\ + "..\..\..\Runtime\ClassReader\ConstantPool.h"\ + "..\..\..\Runtime\ClassReader\InfoItem.h"\ + "..\..\..\Runtime\ClassReader\utils.h"\ + "..\..\..\Runtime\FileReader\FileReader.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Runtime\System\JavaString.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FastHashTable.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\Nonspr.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + +NODEP_CPP_ATTRI=\ + "..\..\..\Runtime\ClassReader\plstr.h"\ + "..\..\..\Runtime\ClassReader\prtypes.h"\ + "..\..\..\Runtime\FileReader\prio.h"\ + "..\..\..\Runtime\FileReader\prtypes.h"\ + "..\..\..\Utilities\General\plstr.h"\ + "..\..\..\Utilities\General\prlog.h"\ + "..\..\..\Utilities\General\prlong.h"\ + + +"$(INTDIR)\AttributeHandlers.obj" "$(INTDIR)\AttributeHandlers.sbr" : $(SOURCE)\ + $(DEP_CPP_ATTRI) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "electricalfire - Win32 Debug" + +DEP_CPP_ATTRI=\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\obsolete\protypes.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\plstr.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcpucfg.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinet.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinrval.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prio.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlog.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlong.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtime.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtypes.h"\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Runtime\ClassInfo\StringPool.h"\ + "..\..\..\Runtime\ClassReader\AttributeHandlers.h"\ + "..\..\..\Runtime\ClassReader\Attributes.h"\ + "..\..\..\Runtime\ClassReader\ClassReader.h"\ + "..\..\..\Runtime\ClassReader\ConstantPool.h"\ + "..\..\..\Runtime\ClassReader\InfoItem.h"\ + "..\..\..\Runtime\ClassReader\utils.h"\ + "..\..\..\Runtime\FileReader\FileReader.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Runtime\System\JavaString.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FastHashTable.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + + +"$(INTDIR)\AttributeHandlers.obj" "$(INTDIR)\AttributeHandlers.sbr" : $(SOURCE)\ + $(DEP_CPP_ATTRI) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +SOURCE=..\..\..\Runtime\ClassReader\ClassReader.cpp + +!IF "$(CFG)" == "electricalfire - Win32 Release" + +DEP_CPP_CLASSR=\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Runtime\ClassInfo\StringPool.h"\ + "..\..\..\Runtime\ClassReader\AttributeHandlers.h"\ + "..\..\..\Runtime\ClassReader\Attributes.h"\ + "..\..\..\Runtime\ClassReader\ClassReader.h"\ + "..\..\..\Runtime\ClassReader\ConstantPool.h"\ + "..\..\..\Runtime\ClassReader\InfoItem.h"\ + "..\..\..\Runtime\ClassReader\utils.h"\ + "..\..\..\Runtime\FileReader\FileReader.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Runtime\System\JavaString.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\DebugUtils.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FastHashTable.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\Nonspr.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + +NODEP_CPP_CLASSR=\ + "..\..\..\Runtime\ClassReader\plstr.h"\ + "..\..\..\Runtime\ClassReader\prtypes.h"\ + "..\..\..\Runtime\FileReader\prio.h"\ + "..\..\..\Runtime\FileReader\prtypes.h"\ + "..\..\..\Utilities\General\plstr.h"\ + "..\..\..\Utilities\General\prlog.h"\ + "..\..\..\Utilities\General\prlong.h"\ + + +"$(INTDIR)\ClassReader.obj" "$(INTDIR)\ClassReader.sbr" : $(SOURCE)\ + $(DEP_CPP_CLASSR) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "electricalfire - Win32 Debug" + +DEP_CPP_CLASSR=\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\obsolete\protypes.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\plstr.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcpucfg.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinet.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinrval.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prio.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlog.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlong.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtime.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtypes.h"\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Runtime\ClassInfo\StringPool.h"\ + "..\..\..\Runtime\ClassReader\AttributeHandlers.h"\ + "..\..\..\Runtime\ClassReader\Attributes.h"\ + "..\..\..\Runtime\ClassReader\ClassReader.h"\ + "..\..\..\Runtime\ClassReader\ConstantPool.h"\ + "..\..\..\Runtime\ClassReader\InfoItem.h"\ + "..\..\..\Runtime\ClassReader\utils.h"\ + "..\..\..\Runtime\FileReader\FileReader.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Runtime\System\JavaString.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\DebugUtils.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FastHashTable.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + + +"$(INTDIR)\ClassReader.obj" "$(INTDIR)\ClassReader.sbr" : $(SOURCE)\ + $(DEP_CPP_CLASSR) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +SOURCE=..\..\..\Runtime\FileReader\BufferedFileReader.cpp + +!IF "$(CFG)" == "electricalfire - Win32 Release" + +DEP_CPP_BUFFE=\ + "..\..\..\Runtime\FileReader\BufferedFileReader.h"\ + "..\..\..\Runtime\FileReader\FileReader.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\Nonspr.h"\ + "..\..\..\Utilities\General\Pool.h"\ + +NODEP_CPP_BUFFE=\ + "..\..\..\Runtime\FileReader\prio.h"\ + "..\..\..\Runtime\FileReader\prtypes.h"\ + "..\..\..\Utilities\General\plstr.h"\ + "..\..\..\Utilities\General\prlog.h"\ + "..\..\..\Utilities\General\prlong.h"\ + + +"$(INTDIR)\BufferedFileReader.obj" "$(INTDIR)\BufferedFileReader.sbr" : \ +$(SOURCE) $(DEP_CPP_BUFFE) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "electricalfire - Win32 Debug" + +DEP_CPP_BUFFE=\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\obsolete\protypes.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcpucfg.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinet.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinrval.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prio.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlog.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlong.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtime.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtypes.h"\ + "..\..\..\Runtime\FileReader\BufferedFileReader.h"\ + "..\..\..\Runtime\FileReader\FileReader.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\Pool.h"\ + + +"$(INTDIR)\BufferedFileReader.obj" "$(INTDIR)\BufferedFileReader.sbr" : \ +$(SOURCE) $(DEP_CPP_BUFFE) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +SOURCE=..\..\..\Runtime\FileReader\DiskFileReader.cpp + +!IF "$(CFG)" == "electricalfire - Win32 Release" + +DEP_CPP_DISKF=\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Runtime\FileReader\DiskFileReader.h"\ + "..\..\..\Runtime\FileReader\FileReader.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\Nonspr.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + +NODEP_CPP_DISKF=\ + "..\..\..\Runtime\FileReader\prio.h"\ + "..\..\..\Runtime\FileReader\prtypes.h"\ + "..\..\..\Utilities\General\plstr.h"\ + "..\..\..\Utilities\General\prlog.h"\ + "..\..\..\Utilities\General\prlong.h"\ + + +"$(INTDIR)\DiskFileReader.obj" "$(INTDIR)\DiskFileReader.sbr" : $(SOURCE)\ + $(DEP_CPP_DISKF) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "electricalfire - Win32 Debug" + +DEP_CPP_DISKF=\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\obsolete\protypes.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcpucfg.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinet.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinrval.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prio.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlog.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlong.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtime.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtypes.h"\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Runtime\FileReader\DiskFileReader.h"\ + "..\..\..\Runtime\FileReader\FileReader.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + + +"$(INTDIR)\DiskFileReader.obj" "$(INTDIR)\DiskFileReader.sbr" : $(SOURCE)\ + $(DEP_CPP_DISKF) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +SOURCE=..\..\..\Runtime\FileReader\FileReader.cpp + +!IF "$(CFG)" == "electricalfire - Win32 Release" + +DEP_CPP_FILER=\ + "..\..\..\Runtime\FileReader\FileReader.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\Nonspr.h"\ + "..\..\..\Utilities\General\Pool.h"\ + +NODEP_CPP_FILER=\ + "..\..\..\Runtime\FileReader\prio.h"\ + "..\..\..\Runtime\FileReader\prtypes.h"\ + "..\..\..\Utilities\General\plstr.h"\ + "..\..\..\Utilities\General\prlog.h"\ + "..\..\..\Utilities\General\prlong.h"\ + + +"$(INTDIR)\FileReader.obj" "$(INTDIR)\FileReader.sbr" : $(SOURCE)\ + $(DEP_CPP_FILER) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "electricalfire - Win32 Debug" + +DEP_CPP_FILER=\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\obsolete\protypes.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcpucfg.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinet.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinrval.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prio.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlog.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlong.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtime.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtypes.h"\ + "..\..\..\Runtime\FileReader\FileReader.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\Pool.h"\ + + +"$(INTDIR)\FileReader.obj" "$(INTDIR)\FileReader.sbr" : $(SOURCE)\ + $(DEP_CPP_FILER) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +SOURCE=..\..\..\Runtime\FileReader\ZipArchive.cpp + +!IF "$(CFG)" == "electricalfire - Win32 Release" + +DEP_CPP_ZIPAR=\ + "..\..\..\Runtime\FileReader\ZipArchive.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\CUtils.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\Nonspr.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\StringUtils.h"\ + "..\..\..\Utilities\zlib\zconf.h"\ + "..\..\..\Utilities\zlib\zlib.h"\ + +NODEP_CPP_ZIPAR=\ + "..\..\..\Runtime\FileReader\plstr.h"\ + "..\..\..\Runtime\FileReader\prio.h"\ + "..\..\..\Runtime\FileReader\prprf.h"\ + "..\..\..\Utilities\General\plstr.h"\ + "..\..\..\Utilities\General\prio.h"\ + "..\..\..\Utilities\General\prlog.h"\ + "..\..\..\Utilities\General\prlong.h"\ + "..\..\..\Utilities\General\prprf.h"\ + + +"$(INTDIR)\ZipArchive.obj" "$(INTDIR)\ZipArchive.sbr" : $(SOURCE)\ + $(DEP_CPP_ZIPAR) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "electricalfire - Win32 Debug" + +DEP_CPP_ZIPAR=\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\obsolete\protypes.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\plstr.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcpucfg.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinet.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinrval.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prio.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlog.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlong.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prprf.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtime.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtypes.h"\ + "..\..\..\Runtime\FileReader\ZipArchive.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\CUtils.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\StringUtils.h"\ + "..\..\..\Utilities\zlib\zconf.h"\ + "..\..\..\Utilities\zlib\zlib.h"\ + + +"$(INTDIR)\ZipArchive.obj" "$(INTDIR)\ZipArchive.sbr" : $(SOURCE)\ + $(DEP_CPP_ZIPAR) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +SOURCE=..\..\..\Runtime\FileReader\ZipFileReader.cpp + +!IF "$(CFG)" == "electricalfire - Win32 Release" + +DEP_CPP_ZIPFI=\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Runtime\FileReader\FileReader.h"\ + "..\..\..\Runtime\FileReader\ZipArchive.h"\ + "..\..\..\Runtime\FileReader\ZipFileReader.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\Nonspr.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + "..\..\..\Utilities\zlib\zconf.h"\ + "..\..\..\Utilities\zlib\zlib.h"\ + +NODEP_CPP_ZIPFI=\ + "..\..\..\Runtime\FileReader\prio.h"\ + "..\..\..\Runtime\FileReader\prtypes.h"\ + "..\..\..\Utilities\General\plstr.h"\ + "..\..\..\Utilities\General\prlog.h"\ + "..\..\..\Utilities\General\prlong.h"\ + + +"$(INTDIR)\ZipFileReader.obj" "$(INTDIR)\ZipFileReader.sbr" : $(SOURCE)\ + $(DEP_CPP_ZIPFI) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "electricalfire - Win32 Debug" + +DEP_CPP_ZIPFI=\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\obsolete\protypes.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcpucfg.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinet.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinrval.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prio.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlog.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlong.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtime.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtypes.h"\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Runtime\FileReader\FileReader.h"\ + "..\..\..\Runtime\FileReader\ZipArchive.h"\ + "..\..\..\Runtime\FileReader\ZipFileReader.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + "..\..\..\Utilities\zlib\zconf.h"\ + "..\..\..\Utilities\zlib\zlib.h"\ + + +"$(INTDIR)\ZipFileReader.obj" "$(INTDIR)\ZipFileReader.sbr" : $(SOURCE)\ + $(DEP_CPP_ZIPFI) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +SOURCE=..\..\..\Runtime\NativeMethods\md\x86\x86NativeMethodStubs.cpp + +!IF "$(CFG)" == "electricalfire - Win32 Release" + +DEP_CPP_X86NA=\ + "..\..\..\Compiler\CodeGenerator\ExceptionTable.h"\ + "..\..\..\Compiler\CodeGenerator\FormatStructures.h"\ + "..\..\..\Compiler\CodeGenerator\NativeCodeCache.h"\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Debugger\Communication\DebuggerChannel.h"\ + "..\..\..\Debugger\Debugger.h"\ + "..\..\..\Exports\jni.h"\ + "..\..\..\Exports\md\jni_md.h"\ + "..\..\..\Runtime\ClassInfo\ClassCentral.h"\ + "..\..\..\Runtime\ClassInfo\ClassFileSummary.h"\ + "..\..\..\Runtime\ClassInfo\Collector.h"\ + "..\..\..\Runtime\ClassInfo\PathComponent.h"\ + "..\..\..\Runtime\ClassInfo\StringPool.h"\ + "..\..\..\Runtime\ClassReader\Attributes.h"\ + "..\..\..\Runtime\ClassReader\ClassReader.h"\ + "..\..\..\Runtime\ClassReader\ConstantPool.h"\ + "..\..\..\Runtime\ClassReader\InfoItem.h"\ + "..\..\..\Runtime\ClassReader\utils.h"\ + "..\..\..\Runtime\FileReader\FileReader.h"\ + "..\..\..\Runtime\FileReader\ZipArchive.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\NativeMethods\NativeMethodStubs.h"\ + "..\..\..\Runtime\System\ClassWorld.h"\ + "..\..\..\Runtime\System\FieldOrMethod.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Runtime\System\JavaString.h"\ + "..\..\..\Runtime\System\Method.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FastHashTable.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\InterestingEvents.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\MemoryAccess.h"\ + "..\..\..\Utilities\General\Nonspr.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + "..\..\..\Utilities\zlib\zconf.h"\ + "..\..\..\Utilities\zlib\zlib.h"\ + +NODEP_CPP_X86NA=\ + "..\..\..\Compiler\CodeGenerator\prmon.h"\ + "..\..\..\Debugger\Communication\prio.h"\ + "..\..\..\Debugger\Communication\prlock.h"\ + "..\..\..\Debugger\Communication\prprf.h"\ + "..\..\..\Debugger\nspr.h"\ + "..\..\..\Runtime\ClassReader\prtypes.h"\ + "..\..\..\Runtime\FileReader\prio.h"\ + "..\..\..\Runtime\FileReader\prtypes.h"\ + "..\..\..\Runtime\System\plstr.h"\ + "..\..\..\Utilities\General\plstr.h"\ + "..\..\..\Utilities\General\prlog.h"\ + "..\..\..\Utilities\General\prlong.h"\ + + +"$(INTDIR)\x86NativeMethodStubs.obj" "$(INTDIR)\x86NativeMethodStubs.sbr" : \ +$(SOURCE) $(DEP_CPP_X86NA) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "electricalfire - Win32 Debug" + +DEP_CPP_X86NA=\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\nspr.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\obsolete\protypes.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\plstr.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\pratom.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prbit.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prclist.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcmon.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcpucfg.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcvar.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prdtoa.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prenv.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prerror.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinet.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinit.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinrval.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prio.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlink.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlock.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlog.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlong.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prmem.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prmon.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prnetdb.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prprf.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prproces.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prsystem.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prthread.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtime.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtypes.h"\ + "..\..\..\Compiler\CodeGenerator\ExceptionTable.h"\ + "..\..\..\Compiler\CodeGenerator\FormatStructures.h"\ + "..\..\..\Compiler\CodeGenerator\NativeCodeCache.h"\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Debugger\Communication\DebuggerChannel.h"\ + "..\..\..\Debugger\Debugger.h"\ + "..\..\..\Exports\jni.h"\ + "..\..\..\Exports\md\jni_md.h"\ + "..\..\..\Runtime\ClassInfo\ClassCentral.h"\ + "..\..\..\Runtime\ClassInfo\ClassFileSummary.h"\ + "..\..\..\Runtime\ClassInfo\Collector.h"\ + "..\..\..\Runtime\ClassInfo\PathComponent.h"\ + "..\..\..\Runtime\ClassInfo\StringPool.h"\ + "..\..\..\Runtime\ClassReader\Attributes.h"\ + "..\..\..\Runtime\ClassReader\ClassReader.h"\ + "..\..\..\Runtime\ClassReader\ConstantPool.h"\ + "..\..\..\Runtime\ClassReader\InfoItem.h"\ + "..\..\..\Runtime\ClassReader\utils.h"\ + "..\..\..\Runtime\FileReader\FileReader.h"\ + "..\..\..\Runtime\FileReader\ZipArchive.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\NativeMethods\NativeMethodStubs.h"\ + "..\..\..\Runtime\System\ClassWorld.h"\ + "..\..\..\Runtime\System\FieldOrMethod.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Runtime\System\JavaString.h"\ + "..\..\..\Runtime\System\Method.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FastHashTable.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\InterestingEvents.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\MemoryAccess.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + "..\..\..\Utilities\zlib\zconf.h"\ + "..\..\..\Utilities\zlib\zlib.h"\ + + +"$(INTDIR)\x86NativeMethodStubs.obj" "$(INTDIR)\x86NativeMethodStubs.sbr" : \ +$(SOURCE) $(DEP_CPP_X86NA) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +SOURCE=..\..\..\Runtime\NativeMethods\Jni.cpp + +!IF "$(CFG)" == "electricalfire - Win32 Release" + +DEP_CPP_JNI_C=\ + "..\..\..\Compiler\CodeGenerator\ExceptionTable.h"\ + "..\..\..\Compiler\CodeGenerator\FormatStructures.h"\ + "..\..\..\Compiler\CodeGenerator\Instruction.h"\ + "..\..\..\Compiler\CodeGenerator\InstructionEmitter.h"\ + "..\..\..\Compiler\CodeGenerator\md\CpuInfo.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Formatter.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Opcode.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Cpu.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Emitter.h"\ + "..\..\..\Compiler\CodeGenerator\NativeCodeCache.h"\ + "..\..\..\Compiler\FrontEnd\BytecodeGraph.h"\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Compiler\FrontEnd\LocalEnv.h"\ + "..\..\..\Compiler\FrontEnd\TranslationEnv.h"\ + "..\..\..\Compiler\FrontEnd\VerificationEnv.h"\ + "..\..\..\Compiler\Optimizer\PrimitiveOptimizer.h"\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlGraph.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlNodes.h"\ + "..\..\..\Compiler\PrimitiveGraph\PrimitiveOperations.h"\ + "..\..\..\Compiler\PrimitiveGraph\Primitives.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Compiler\RegisterAllocator\VirtualRegister.h"\ + "..\..\..\Debugger\Communication\DebuggerChannel.h"\ + "..\..\..\Debugger\Debugger.h"\ + "..\..\..\Exports\jni.h"\ + "..\..\..\Exports\md\jni_md.h"\ + "..\..\..\Runtime\ClassInfo\ClassCentral.h"\ + "..\..\..\Runtime\ClassInfo\ClassFileSummary.h"\ + "..\..\..\Runtime\ClassInfo\Collector.h"\ + "..\..\..\Runtime\ClassInfo\PathComponent.h"\ + "..\..\..\Runtime\ClassInfo\StringPool.h"\ + "..\..\..\Runtime\ClassReader\Attributes.h"\ + "..\..\..\Runtime\ClassReader\ClassReader.h"\ + "..\..\..\Runtime\ClassReader\ConstantPool.h"\ + "..\..\..\Runtime\ClassReader\InfoItem.h"\ + "..\..\..\Runtime\ClassReader\utils.h"\ + "..\..\..\Runtime\FileReader\BufferedFileReader.h"\ + "..\..\..\Runtime\FileReader\FileReader.h"\ + "..\..\..\Runtime\FileReader\ZipArchive.h"\ + "..\..\..\Runtime\NativeMethods\NameMangler.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\NativeMethods\NativeMethodDispatcher.h"\ + "..\..\..\Runtime\System\ClassWorld.h"\ + "..\..\..\Runtime\System\FieldOrMethod.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Runtime\System\JavaString.h"\ + "..\..\..\Runtime\System\JavaVM.h"\ + "..\..\..\Runtime\System\Method.h"\ + "..\..\..\Runtime\System\SysCallsRuntime.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\CheckedUnion.h"\ + "..\..\..\Utilities\General\DebugUtils.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FastBitMatrix.h"\ + "..\..\..\Utilities\General\FastBitSet.h"\ + "..\..\..\Utilities\General\FastHashTable.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\InterestingEvents.h"\ + "..\..\..\Utilities\General\JavaBytecodes.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\Nonspr.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + "..\..\..\Utilities\zlib\zconf.h"\ + "..\..\..\Utilities\zlib\zlib.h"\ + +NODEP_CPP_JNI_C=\ + "..\..\..\Compiler\CodeGenerator\md\HPPACpu.h"\ + "..\..\..\Compiler\CodeGenerator\md\PPC601Cpu.h"\ + "..\..\..\Compiler\CodeGenerator\prmon.h"\ + "..\..\..\Compiler\CodeGenerator\prtypes.h"\ + "..\..\..\Debugger\Communication\prio.h"\ + "..\..\..\Debugger\Communication\prlock.h"\ + "..\..\..\Debugger\Communication\prprf.h"\ + "..\..\..\Debugger\nspr.h"\ + "..\..\..\Runtime\ClassReader\prtypes.h"\ + "..\..\..\Runtime\FileReader\prio.h"\ + "..\..\..\Runtime\FileReader\prtypes.h"\ + "..\..\..\Runtime\NativeMethods\prlink.h"\ + "..\..\..\Runtime\NativeMethods\prprf.h"\ + "..\..\..\Runtime\System\plstr.h"\ + "..\..\..\Runtime\System\prprf.h"\ + "..\..\..\Utilities\General\plstr.h"\ + "..\..\..\Utilities\General\prbit.h"\ + "..\..\..\Utilities\General\prlog.h"\ + "..\..\..\Utilities\General\prlong.h"\ + + +"$(INTDIR)\Jni.obj" "$(INTDIR)\Jni.sbr" : $(SOURCE) $(DEP_CPP_JNI_C)\ + "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "electricalfire - Win32 Debug" + +DEP_CPP_JNI_C=\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\nspr.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\obsolete\protypes.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\plstr.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\pratom.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prbit.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prclist.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcmon.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcpucfg.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcvar.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prdtoa.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prenv.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prerror.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinet.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinit.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinrval.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prio.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlink.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlock.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlog.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlong.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prmem.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prmon.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prnetdb.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prprf.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prproces.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prsystem.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prthread.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtime.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtypes.h"\ + "..\..\..\Compiler\CodeGenerator\ExceptionTable.h"\ + "..\..\..\Compiler\CodeGenerator\FormatStructures.h"\ + "..\..\..\Compiler\CodeGenerator\Instruction.h"\ + "..\..\..\Compiler\CodeGenerator\md\CpuInfo.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Cpu.h"\ + "..\..\..\Compiler\CodeGenerator\NativeCodeCache.h"\ + "..\..\..\Compiler\FrontEnd\BytecodeGraph.h"\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Compiler\FrontEnd\LocalEnv.h"\ + "..\..\..\Compiler\FrontEnd\TranslationEnv.h"\ + "..\..\..\Compiler\FrontEnd\VerificationEnv.h"\ + "..\..\..\Compiler\Optimizer\PrimitiveOptimizer.h"\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlGraph.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlNodes.h"\ + "..\..\..\Compiler\PrimitiveGraph\PrimitiveOperations.h"\ + "..\..\..\Compiler\PrimitiveGraph\Primitives.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Compiler\RegisterAllocator\VirtualRegister.h"\ + "..\..\..\Debugger\Communication\DebuggerChannel.h"\ + "..\..\..\Debugger\Debugger.h"\ + "..\..\..\Exports\jni.h"\ + "..\..\..\Exports\md\jni_md.h"\ + "..\..\..\Runtime\ClassInfo\ClassCentral.h"\ + "..\..\..\Runtime\ClassInfo\ClassFileSummary.h"\ + "..\..\..\Runtime\ClassInfo\Collector.h"\ + "..\..\..\Runtime\ClassInfo\PathComponent.h"\ + "..\..\..\Runtime\ClassInfo\StringPool.h"\ + "..\..\..\Runtime\ClassReader\Attributes.h"\ + "..\..\..\Runtime\ClassReader\ClassReader.h"\ + "..\..\..\Runtime\ClassReader\ConstantPool.h"\ + "..\..\..\Runtime\ClassReader\InfoItem.h"\ + "..\..\..\Runtime\ClassReader\utils.h"\ + "..\..\..\Runtime\FileReader\BufferedFileReader.h"\ + "..\..\..\Runtime\FileReader\FileReader.h"\ + "..\..\..\Runtime\FileReader\ZipArchive.h"\ + "..\..\..\Runtime\NativeMethods\NameMangler.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\NativeMethods\NativeMethodDispatcher.h"\ + "..\..\..\Runtime\System\ClassWorld.h"\ + "..\..\..\Runtime\System\FieldOrMethod.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Runtime\System\JavaString.h"\ + "..\..\..\Runtime\System\JavaVM.h"\ + "..\..\..\Runtime\System\Method.h"\ + "..\..\..\Runtime\System\SysCallsRuntime.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\CheckedUnion.h"\ + "..\..\..\Utilities\General\DebugUtils.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FastBitMatrix.h"\ + "..\..\..\Utilities\General\FastBitSet.h"\ + "..\..\..\Utilities\General\FastHashTable.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\InterestingEvents.h"\ + "..\..\..\Utilities\General\JavaBytecodes.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + "..\..\..\Utilities\zlib\zconf.h"\ + "..\..\..\Utilities\zlib\zlib.h"\ + + +"$(INTDIR)\Jni.obj" "$(INTDIR)\Jni.sbr" : $(SOURCE) $(DEP_CPP_JNI_C)\ + "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +SOURCE=..\..\..\Runtime\NativeMethods\JNIManglers.cpp + +!IF "$(CFG)" == "electricalfire - Win32 Release" + +DEP_CPP_JNIMA=\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Debugger\Communication\DebuggerChannel.h"\ + "..\..\..\Debugger\Debugger.h"\ + "..\..\..\Runtime\ClassInfo\ClassCentral.h"\ + "..\..\..\Runtime\ClassInfo\ClassFileSummary.h"\ + "..\..\..\Runtime\ClassInfo\Collector.h"\ + "..\..\..\Runtime\ClassInfo\PathComponent.h"\ + "..\..\..\Runtime\ClassInfo\StringPool.h"\ + "..\..\..\Runtime\ClassReader\Attributes.h"\ + "..\..\..\Runtime\ClassReader\ClassReader.h"\ + "..\..\..\Runtime\ClassReader\ConstantPool.h"\ + "..\..\..\Runtime\ClassReader\InfoItem.h"\ + "..\..\..\Runtime\ClassReader\utils.h"\ + "..\..\..\Runtime\FileReader\FileReader.h"\ + "..\..\..\Runtime\FileReader\ZipArchive.h"\ + "..\..\..\Runtime\NativeMethods\JNIManglers.h"\ + "..\..\..\Runtime\NativeMethods\NameMangler.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\NativeMethods\NativeMethodStubs.h"\ + "..\..\..\Runtime\System\ClassWorld.h"\ + "..\..\..\Runtime\System\FieldOrMethod.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Runtime\System\JavaString.h"\ + "..\..\..\Runtime\System\Method.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FastHashTable.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\InterestingEvents.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\Nonspr.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + "..\..\..\Utilities\zlib\zconf.h"\ + "..\..\..\Utilities\zlib\zlib.h"\ + +NODEP_CPP_JNIMA=\ + "..\..\..\Debugger\Communication\prio.h"\ + "..\..\..\Debugger\Communication\prlock.h"\ + "..\..\..\Debugger\Communication\prprf.h"\ + "..\..\..\Debugger\nspr.h"\ + "..\..\..\Runtime\ClassReader\prtypes.h"\ + "..\..\..\Runtime\FileReader\prio.h"\ + "..\..\..\Runtime\FileReader\prtypes.h"\ + "..\..\..\Runtime\NativeMethods\plstr.h"\ + "..\..\..\Runtime\NativeMethods\prprf.h"\ + "..\..\..\Runtime\System\plstr.h"\ + "..\..\..\Utilities\General\plstr.h"\ + "..\..\..\Utilities\General\prlog.h"\ + "..\..\..\Utilities\General\prlong.h"\ + + +"$(INTDIR)\JNIManglers.obj" "$(INTDIR)\JNIManglers.sbr" : $(SOURCE)\ + $(DEP_CPP_JNIMA) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "electricalfire - Win32 Debug" + +DEP_CPP_JNIMA=\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\nspr.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\obsolete\protypes.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\plstr.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\pratom.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prbit.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prclist.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcmon.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcpucfg.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcvar.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prdtoa.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prenv.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prerror.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinet.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinit.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinrval.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prio.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlink.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlock.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlog.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlong.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prmem.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prmon.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prnetdb.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prprf.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prproces.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prsystem.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prthread.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtime.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtypes.h"\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Debugger\Communication\DebuggerChannel.h"\ + "..\..\..\Debugger\Debugger.h"\ + "..\..\..\Runtime\ClassInfo\ClassCentral.h"\ + "..\..\..\Runtime\ClassInfo\ClassFileSummary.h"\ + "..\..\..\Runtime\ClassInfo\Collector.h"\ + "..\..\..\Runtime\ClassInfo\PathComponent.h"\ + "..\..\..\Runtime\ClassInfo\StringPool.h"\ + "..\..\..\Runtime\ClassReader\Attributes.h"\ + "..\..\..\Runtime\ClassReader\ClassReader.h"\ + "..\..\..\Runtime\ClassReader\ConstantPool.h"\ + "..\..\..\Runtime\ClassReader\InfoItem.h"\ + "..\..\..\Runtime\ClassReader\utils.h"\ + "..\..\..\Runtime\FileReader\FileReader.h"\ + "..\..\..\Runtime\FileReader\ZipArchive.h"\ + "..\..\..\Runtime\NativeMethods\JNIManglers.h"\ + "..\..\..\Runtime\NativeMethods\NameMangler.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\NativeMethods\NativeMethodStubs.h"\ + "..\..\..\Runtime\System\ClassWorld.h"\ + "..\..\..\Runtime\System\FieldOrMethod.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Runtime\System\JavaString.h"\ + "..\..\..\Runtime\System\Method.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FastHashTable.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\InterestingEvents.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + "..\..\..\Utilities\zlib\zconf.h"\ + "..\..\..\Utilities\zlib\zlib.h"\ + + +"$(INTDIR)\JNIManglers.obj" "$(INTDIR)\JNIManglers.sbr" : $(SOURCE)\ + $(DEP_CPP_JNIMA) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +SOURCE=..\..\..\Runtime\NativeMethods\NameMangler.cpp + +!IF "$(CFG)" == "electricalfire - Win32 Release" + +DEP_CPP_NAMEM=\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Debugger\Communication\DebuggerChannel.h"\ + "..\..\..\Debugger\Debugger.h"\ + "..\..\..\Runtime\ClassInfo\ClassCentral.h"\ + "..\..\..\Runtime\ClassInfo\ClassFileSummary.h"\ + "..\..\..\Runtime\ClassInfo\Collector.h"\ + "..\..\..\Runtime\ClassInfo\PathComponent.h"\ + "..\..\..\Runtime\ClassInfo\StringPool.h"\ + "..\..\..\Runtime\ClassReader\Attributes.h"\ + "..\..\..\Runtime\ClassReader\ClassReader.h"\ + "..\..\..\Runtime\ClassReader\ConstantPool.h"\ + "..\..\..\Runtime\ClassReader\InfoItem.h"\ + "..\..\..\Runtime\ClassReader\utils.h"\ + "..\..\..\Runtime\FileReader\FileReader.h"\ + "..\..\..\Runtime\FileReader\ZipArchive.h"\ + "..\..\..\Runtime\NativeMethods\NameMangler.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\System\ClassWorld.h"\ + "..\..\..\Runtime\System\FieldOrMethod.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Runtime\System\JavaString.h"\ + "..\..\..\Runtime\System\Method.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FastHashTable.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\InterestingEvents.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\Nonspr.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + "..\..\..\Utilities\zlib\zconf.h"\ + "..\..\..\Utilities\zlib\zlib.h"\ + +NODEP_CPP_NAMEM=\ + "..\..\..\Debugger\Communication\prio.h"\ + "..\..\..\Debugger\Communication\prlock.h"\ + "..\..\..\Debugger\Communication\prprf.h"\ + "..\..\..\Debugger\nspr.h"\ + "..\..\..\Runtime\ClassReader\prtypes.h"\ + "..\..\..\Runtime\FileReader\prio.h"\ + "..\..\..\Runtime\FileReader\prtypes.h"\ + "..\..\..\Runtime\NativeMethods\plstr.h"\ + "..\..\..\Runtime\NativeMethods\prprf.h"\ + "..\..\..\Runtime\System\plstr.h"\ + "..\..\..\Utilities\General\plstr.h"\ + "..\..\..\Utilities\General\prlog.h"\ + "..\..\..\Utilities\General\prlong.h"\ + + +"$(INTDIR)\NameMangler.obj" "$(INTDIR)\NameMangler.sbr" : $(SOURCE)\ + $(DEP_CPP_NAMEM) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "electricalfire - Win32 Debug" + +DEP_CPP_NAMEM=\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\nspr.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\obsolete\protypes.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\plstr.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\pratom.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prbit.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prclist.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcmon.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcpucfg.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcvar.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prdtoa.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prenv.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prerror.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinet.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinit.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinrval.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prio.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlink.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlock.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlog.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlong.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prmem.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prmon.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prnetdb.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prprf.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prproces.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prsystem.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prthread.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtime.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtypes.h"\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Debugger\Communication\DebuggerChannel.h"\ + "..\..\..\Debugger\Debugger.h"\ + "..\..\..\Runtime\ClassInfo\ClassCentral.h"\ + "..\..\..\Runtime\ClassInfo\ClassFileSummary.h"\ + "..\..\..\Runtime\ClassInfo\Collector.h"\ + "..\..\..\Runtime\ClassInfo\PathComponent.h"\ + "..\..\..\Runtime\ClassInfo\StringPool.h"\ + "..\..\..\Runtime\ClassReader\Attributes.h"\ + "..\..\..\Runtime\ClassReader\ClassReader.h"\ + "..\..\..\Runtime\ClassReader\ConstantPool.h"\ + "..\..\..\Runtime\ClassReader\InfoItem.h"\ + "..\..\..\Runtime\ClassReader\utils.h"\ + "..\..\..\Runtime\FileReader\FileReader.h"\ + "..\..\..\Runtime\FileReader\ZipArchive.h"\ + "..\..\..\Runtime\NativeMethods\NameMangler.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\System\ClassWorld.h"\ + "..\..\..\Runtime\System\FieldOrMethod.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Runtime\System\JavaString.h"\ + "..\..\..\Runtime\System\Method.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FastHashTable.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\InterestingEvents.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + "..\..\..\Utilities\zlib\zconf.h"\ + "..\..\..\Utilities\zlib\zlib.h"\ + + +"$(INTDIR)\NameMangler.obj" "$(INTDIR)\NameMangler.sbr" : $(SOURCE)\ + $(DEP_CPP_NAMEM) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +SOURCE=..\..\..\Runtime\NativeMethods\NativeMethodDispatcher.cpp + +!IF "$(CFG)" == "electricalfire - Win32 Release" + +DEP_CPP_NATIV=\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Debugger\Communication\DebuggerChannel.h"\ + "..\..\..\Debugger\Debugger.h"\ + "..\..\..\Runtime\ClassInfo\ClassCentral.h"\ + "..\..\..\Runtime\ClassInfo\ClassFileSummary.h"\ + "..\..\..\Runtime\ClassInfo\Collector.h"\ + "..\..\..\Runtime\ClassInfo\PathComponent.h"\ + "..\..\..\Runtime\ClassInfo\StringPool.h"\ + "..\..\..\Runtime\ClassReader\Attributes.h"\ + "..\..\..\Runtime\ClassReader\ClassReader.h"\ + "..\..\..\Runtime\ClassReader\ConstantPool.h"\ + "..\..\..\Runtime\ClassReader\InfoItem.h"\ + "..\..\..\Runtime\ClassReader\utils.h"\ + "..\..\..\Runtime\FileReader\FileReader.h"\ + "..\..\..\Runtime\FileReader\ZipArchive.h"\ + "..\..\..\Runtime\NativeMethods\JNIManglers.h"\ + "..\..\..\Runtime\NativeMethods\NameMangler.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\NativeMethods\NativeMethodDispatcher.h"\ + "..\..\..\Runtime\NativeMethods\NetscapeManglers.h"\ + "..\..\..\Runtime\System\ClassWorld.h"\ + "..\..\..\Runtime\System\FieldOrMethod.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Runtime\System\JavaString.h"\ + "..\..\..\Runtime\System\Method.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\CUtils.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FastHashTable.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\InterestingEvents.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\Nonspr.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\StringUtils.h"\ + "..\..\..\Utilities\General\Vector.h"\ + "..\..\..\Utilities\zlib\zconf.h"\ + "..\..\..\Utilities\zlib\zlib.h"\ + +NODEP_CPP_NATIV=\ + "..\..\..\Debugger\Communication\prio.h"\ + "..\..\..\Debugger\Communication\prlock.h"\ + "..\..\..\Debugger\Communication\prprf.h"\ + "..\..\..\Debugger\nspr.h"\ + "..\..\..\Runtime\ClassReader\prtypes.h"\ + "..\..\..\Runtime\FileReader\prio.h"\ + "..\..\..\Runtime\FileReader\prtypes.h"\ + "..\..\..\Runtime\NativeMethods\plstr.h"\ + "..\..\..\Runtime\NativeMethods\prio.h"\ + "..\..\..\Runtime\NativeMethods\prlink.h"\ + "..\..\..\Runtime\NativeMethods\prmem.h"\ + "..\..\..\Runtime\NativeMethods\prprf.h"\ + "..\..\..\Runtime\System\plstr.h"\ + "..\..\..\Utilities\General\plstr.h"\ + "..\..\..\Utilities\General\prio.h"\ + "..\..\..\Utilities\General\prlog.h"\ + "..\..\..\Utilities\General\prlong.h"\ + "..\..\..\Utilities\General\prprf.h"\ + + +"$(INTDIR)\NativeMethodDispatcher.obj" "$(INTDIR)\NativeMethodDispatcher.sbr" :\ + $(SOURCE) $(DEP_CPP_NATIV) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "electricalfire - Win32 Debug" + +DEP_CPP_NATIV=\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\nspr.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\obsolete\protypes.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\plstr.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\pratom.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prbit.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prclist.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcmon.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcpucfg.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcvar.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prdtoa.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prenv.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prerror.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinet.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinit.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinrval.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prio.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlink.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlock.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlog.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlong.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prmem.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prmon.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prnetdb.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prprf.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prproces.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prsystem.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prthread.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtime.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtypes.h"\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Debugger\Communication\DebuggerChannel.h"\ + "..\..\..\Debugger\Debugger.h"\ + "..\..\..\Runtime\ClassInfo\ClassCentral.h"\ + "..\..\..\Runtime\ClassInfo\ClassFileSummary.h"\ + "..\..\..\Runtime\ClassInfo\Collector.h"\ + "..\..\..\Runtime\ClassInfo\PathComponent.h"\ + "..\..\..\Runtime\ClassInfo\StringPool.h"\ + "..\..\..\Runtime\ClassReader\Attributes.h"\ + "..\..\..\Runtime\ClassReader\ClassReader.h"\ + "..\..\..\Runtime\ClassReader\ConstantPool.h"\ + "..\..\..\Runtime\ClassReader\InfoItem.h"\ + "..\..\..\Runtime\ClassReader\utils.h"\ + "..\..\..\Runtime\FileReader\FileReader.h"\ + "..\..\..\Runtime\FileReader\ZipArchive.h"\ + "..\..\..\Runtime\NativeMethods\JNIManglers.h"\ + "..\..\..\Runtime\NativeMethods\NameMangler.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\NativeMethods\NativeMethodDispatcher.h"\ + "..\..\..\Runtime\NativeMethods\NetscapeManglers.h"\ + "..\..\..\Runtime\System\ClassWorld.h"\ + "..\..\..\Runtime\System\FieldOrMethod.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Runtime\System\JavaString.h"\ + "..\..\..\Runtime\System\Method.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\CUtils.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FastHashTable.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\InterestingEvents.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\StringUtils.h"\ + "..\..\..\Utilities\General\Vector.h"\ + "..\..\..\Utilities\zlib\zconf.h"\ + "..\..\..\Utilities\zlib\zlib.h"\ + + +"$(INTDIR)\NativeMethodDispatcher.obj" "$(INTDIR)\NativeMethodDispatcher.sbr" :\ + $(SOURCE) $(DEP_CPP_NATIV) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +SOURCE=..\..\..\Runtime\NativeMethods\NetscapeManglers.cpp + +!IF "$(CFG)" == "electricalfire - Win32 Release" + +DEP_CPP_NETSC=\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Debugger\Communication\DebuggerChannel.h"\ + "..\..\..\Debugger\Debugger.h"\ + "..\..\..\Runtime\ClassInfo\ClassCentral.h"\ + "..\..\..\Runtime\ClassInfo\ClassFileSummary.h"\ + "..\..\..\Runtime\ClassInfo\Collector.h"\ + "..\..\..\Runtime\ClassInfo\PathComponent.h"\ + "..\..\..\Runtime\ClassInfo\StringPool.h"\ + "..\..\..\Runtime\ClassReader\Attributes.h"\ + "..\..\..\Runtime\ClassReader\ClassReader.h"\ + "..\..\..\Runtime\ClassReader\ConstantPool.h"\ + "..\..\..\Runtime\ClassReader\InfoItem.h"\ + "..\..\..\Runtime\ClassReader\utils.h"\ + "..\..\..\Runtime\FileReader\FileReader.h"\ + "..\..\..\Runtime\FileReader\ZipArchive.h"\ + "..\..\..\Runtime\NativeMethods\JNIManglers.h"\ + "..\..\..\Runtime\NativeMethods\NameMangler.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\NativeMethods\NetscapeManglers.h"\ + "..\..\..\Runtime\System\ClassWorld.h"\ + "..\..\..\Runtime\System\FieldOrMethod.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Runtime\System\JavaString.h"\ + "..\..\..\Runtime\System\Method.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FastHashTable.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\InterestingEvents.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\Nonspr.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + "..\..\..\Utilities\zlib\zconf.h"\ + "..\..\..\Utilities\zlib\zlib.h"\ + +NODEP_CPP_NETSC=\ + "..\..\..\Debugger\Communication\prio.h"\ + "..\..\..\Debugger\Communication\prlock.h"\ + "..\..\..\Debugger\Communication\prprf.h"\ + "..\..\..\Debugger\nspr.h"\ + "..\..\..\Runtime\ClassReader\prtypes.h"\ + "..\..\..\Runtime\FileReader\prio.h"\ + "..\..\..\Runtime\FileReader\prtypes.h"\ + "..\..\..\Runtime\NativeMethods\plstr.h"\ + "..\..\..\Runtime\NativeMethods\prprf.h"\ + "..\..\..\Runtime\System\plstr.h"\ + "..\..\..\Utilities\General\plstr.h"\ + "..\..\..\Utilities\General\prlog.h"\ + "..\..\..\Utilities\General\prlong.h"\ + + +"$(INTDIR)\NetscapeManglers.obj" "$(INTDIR)\NetscapeManglers.sbr" : $(SOURCE)\ + $(DEP_CPP_NETSC) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "electricalfire - Win32 Debug" + +DEP_CPP_NETSC=\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\nspr.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\obsolete\protypes.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\plstr.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\pratom.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prbit.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prclist.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcmon.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcpucfg.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcvar.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prdtoa.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prenv.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prerror.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinet.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinit.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinrval.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prio.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlink.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlock.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlog.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlong.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prmem.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prmon.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prnetdb.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prprf.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prproces.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prsystem.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prthread.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtime.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtypes.h"\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Debugger\Communication\DebuggerChannel.h"\ + "..\..\..\Debugger\Debugger.h"\ + "..\..\..\Runtime\ClassInfo\ClassCentral.h"\ + "..\..\..\Runtime\ClassInfo\ClassFileSummary.h"\ + "..\..\..\Runtime\ClassInfo\Collector.h"\ + "..\..\..\Runtime\ClassInfo\PathComponent.h"\ + "..\..\..\Runtime\ClassInfo\StringPool.h"\ + "..\..\..\Runtime\ClassReader\Attributes.h"\ + "..\..\..\Runtime\ClassReader\ClassReader.h"\ + "..\..\..\Runtime\ClassReader\ConstantPool.h"\ + "..\..\..\Runtime\ClassReader\InfoItem.h"\ + "..\..\..\Runtime\ClassReader\utils.h"\ + "..\..\..\Runtime\FileReader\FileReader.h"\ + "..\..\..\Runtime\FileReader\ZipArchive.h"\ + "..\..\..\Runtime\NativeMethods\JNIManglers.h"\ + "..\..\..\Runtime\NativeMethods\NameMangler.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\NativeMethods\NetscapeManglers.h"\ + "..\..\..\Runtime\System\ClassWorld.h"\ + "..\..\..\Runtime\System\FieldOrMethod.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Runtime\System\JavaString.h"\ + "..\..\..\Runtime\System\Method.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FastHashTable.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\InterestingEvents.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + "..\..\..\Utilities\zlib\zconf.h"\ + "..\..\..\Utilities\zlib\zlib.h"\ + + +"$(INTDIR)\NetscapeManglers.obj" "$(INTDIR)\NetscapeManglers.sbr" : $(SOURCE)\ + $(DEP_CPP_NETSC) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +SOURCE=..\..\..\Runtime\System\md\x86\Win32ExceptionHandler.cpp + +!IF "$(CFG)" == "electricalfire - Win32 Release" + +DEP_CPP_WIN32=\ + "..\..\..\Compiler\CodeGenerator\ExceptionTable.h"\ + "..\..\..\Compiler\CodeGenerator\FormatStructures.h"\ + "..\..\..\Compiler\CodeGenerator\NativeCodeCache.h"\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\PrimitiveOperations.h"\ + "..\..\..\Compiler\PrimitiveGraph\Primitives.h"\ + "..\..\..\Compiler\PrimitiveGraph\SysCalls.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Compiler\RegisterAllocator\VirtualRegister.h"\ + "..\..\..\Debugger\Communication\DebuggerChannel.h"\ + "..\..\..\Debugger\Debugger.h"\ + "..\..\..\Runtime\ClassInfo\ClassCentral.h"\ + "..\..\..\Runtime\ClassInfo\ClassFileSummary.h"\ + "..\..\..\Runtime\ClassInfo\Collector.h"\ + "..\..\..\Runtime\ClassInfo\PathComponent.h"\ + "..\..\..\Runtime\ClassInfo\StringPool.h"\ + "..\..\..\Runtime\ClassReader\Attributes.h"\ + "..\..\..\Runtime\ClassReader\ClassReader.h"\ + "..\..\..\Runtime\ClassReader\ConstantPool.h"\ + "..\..\..\Runtime\ClassReader\InfoItem.h"\ + "..\..\..\Runtime\ClassReader\utils.h"\ + "..\..\..\Runtime\FileReader\FileReader.h"\ + "..\..\..\Runtime\FileReader\ZipArchive.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\System\ClassWorld.h"\ + "..\..\..\Runtime\System\FieldOrMethod.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Runtime\System\JavaString.h"\ + "..\..\..\Runtime\System\md\x86\x86Win32ExceptionHandler.h"\ + "..\..\..\Runtime\System\Method.h"\ + "..\..\..\Runtime\System\SysCallsRuntime.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FastBitMatrix.h"\ + "..\..\..\Utilities\General\FastBitSet.h"\ + "..\..\..\Utilities\General\FastHashTable.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\InterestingEvents.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\Nonspr.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + "..\..\..\Utilities\zlib\zconf.h"\ + "..\..\..\Utilities\zlib\zlib.h"\ + +NODEP_CPP_WIN32=\ + "..\..\..\Compiler\CodeGenerator\prmon.h"\ + "..\..\..\Debugger\Communication\prio.h"\ + "..\..\..\Debugger\Communication\prlock.h"\ + "..\..\..\Debugger\Communication\prprf.h"\ + "..\..\..\Debugger\nspr.h"\ + "..\..\..\Runtime\ClassReader\prtypes.h"\ + "..\..\..\Runtime\FileReader\prio.h"\ + "..\..\..\Runtime\FileReader\prtypes.h"\ + "..\..\..\Runtime\System\md\x86\prprf.h"\ + "..\..\..\Runtime\System\plstr.h"\ + "..\..\..\Utilities\General\plstr.h"\ + "..\..\..\Utilities\General\prbit.h"\ + "..\..\..\Utilities\General\prlog.h"\ + "..\..\..\Utilities\General\prlong.h"\ + + +"$(INTDIR)\Win32ExceptionHandler.obj" "$(INTDIR)\Win32ExceptionHandler.sbr" : \ +$(SOURCE) $(DEP_CPP_WIN32) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "electricalfire - Win32 Debug" + +DEP_CPP_WIN32=\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\nspr.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\obsolete\protypes.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\plstr.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\pratom.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prbit.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prclist.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcmon.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcpucfg.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcvar.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prdtoa.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prenv.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prerror.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinet.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinit.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinrval.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prio.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlink.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlock.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlog.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlong.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prmem.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prmon.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prnetdb.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prprf.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prproces.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prsystem.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prthread.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtime.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtypes.h"\ + "..\..\..\Compiler\CodeGenerator\ExceptionTable.h"\ + "..\..\..\Compiler\CodeGenerator\FormatStructures.h"\ + "..\..\..\Compiler\CodeGenerator\NativeCodeCache.h"\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\PrimitiveOperations.h"\ + "..\..\..\Compiler\PrimitiveGraph\Primitives.h"\ + "..\..\..\Compiler\PrimitiveGraph\SysCalls.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Compiler\RegisterAllocator\VirtualRegister.h"\ + "..\..\..\Debugger\Communication\DebuggerChannel.h"\ + "..\..\..\Debugger\Debugger.h"\ + "..\..\..\Runtime\ClassInfo\ClassCentral.h"\ + "..\..\..\Runtime\ClassInfo\ClassFileSummary.h"\ + "..\..\..\Runtime\ClassInfo\Collector.h"\ + "..\..\..\Runtime\ClassInfo\PathComponent.h"\ + "..\..\..\Runtime\ClassInfo\StringPool.h"\ + "..\..\..\Runtime\ClassReader\Attributes.h"\ + "..\..\..\Runtime\ClassReader\ClassReader.h"\ + "..\..\..\Runtime\ClassReader\ConstantPool.h"\ + "..\..\..\Runtime\ClassReader\InfoItem.h"\ + "..\..\..\Runtime\ClassReader\utils.h"\ + "..\..\..\Runtime\FileReader\FileReader.h"\ + "..\..\..\Runtime\FileReader\ZipArchive.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\System\ClassWorld.h"\ + "..\..\..\Runtime\System\FieldOrMethod.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Runtime\System\JavaString.h"\ + "..\..\..\Runtime\System\md\x86\x86Win32ExceptionHandler.h"\ + "..\..\..\Runtime\System\Method.h"\ + "..\..\..\Runtime\System\SysCallsRuntime.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FastBitMatrix.h"\ + "..\..\..\Utilities\General\FastBitSet.h"\ + "..\..\..\Utilities\General\FastHashTable.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\InterestingEvents.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + "..\..\..\Utilities\zlib\zconf.h"\ + "..\..\..\Utilities\zlib\zlib.h"\ + + +"$(INTDIR)\Win32ExceptionHandler.obj" "$(INTDIR)\Win32ExceptionHandler.sbr" : \ +$(SOURCE) $(DEP_CPP_WIN32) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +SOURCE=..\..\..\Runtime\System\md\x86\x86ExceptionHandler.cpp + +!IF "$(CFG)" == "electricalfire - Win32 Release" + +DEP_CPP_X86EX=\ + "..\..\..\Compiler\CodeGenerator\ExceptionTable.h"\ + "..\..\..\Compiler\CodeGenerator\FormatStructures.h"\ + "..\..\..\Compiler\CodeGenerator\NativeCodeCache.h"\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\PrimitiveOperations.h"\ + "..\..\..\Compiler\PrimitiveGraph\Primitives.h"\ + "..\..\..\Compiler\PrimitiveGraph\SysCalls.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Compiler\RegisterAllocator\VirtualRegister.h"\ + "..\..\..\Debugger\Communication\DebuggerChannel.h"\ + "..\..\..\Debugger\Debugger.h"\ + "..\..\..\Runtime\ClassInfo\ClassCentral.h"\ + "..\..\..\Runtime\ClassInfo\ClassFileSummary.h"\ + "..\..\..\Runtime\ClassInfo\Collector.h"\ + "..\..\..\Runtime\ClassInfo\PathComponent.h"\ + "..\..\..\Runtime\ClassInfo\StringPool.h"\ + "..\..\..\Runtime\ClassReader\Attributes.h"\ + "..\..\..\Runtime\ClassReader\ClassReader.h"\ + "..\..\..\Runtime\ClassReader\ConstantPool.h"\ + "..\..\..\Runtime\ClassReader\InfoItem.h"\ + "..\..\..\Runtime\ClassReader\utils.h"\ + "..\..\..\Runtime\FileReader\FileReader.h"\ + "..\..\..\Runtime\FileReader\ZipArchive.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\System\ClassWorld.h"\ + "..\..\..\Runtime\System\FieldOrMethod.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Runtime\System\JavaString.h"\ + "..\..\..\Runtime\System\md\x86\x86Win32ExceptionHandler.h"\ + "..\..\..\Runtime\System\Method.h"\ + "..\..\..\Runtime\System\StackWalker.h"\ + "..\..\..\Runtime\System\SysCallsRuntime.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FastBitMatrix.h"\ + "..\..\..\Utilities\General\FastBitSet.h"\ + "..\..\..\Utilities\General\FastHashTable.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\InterestingEvents.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\Nonspr.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + "..\..\..\Utilities\zlib\zconf.h"\ + "..\..\..\Utilities\zlib\zlib.h"\ + +NODEP_CPP_X86EX=\ + "..\..\..\Compiler\CodeGenerator\prmon.h"\ + "..\..\..\Debugger\Communication\prio.h"\ + "..\..\..\Debugger\Communication\prlock.h"\ + "..\..\..\Debugger\Communication\prprf.h"\ + "..\..\..\Debugger\nspr.h"\ + "..\..\..\Runtime\ClassReader\prtypes.h"\ + "..\..\..\Runtime\FileReader\prio.h"\ + "..\..\..\Runtime\FileReader\prtypes.h"\ + "..\..\..\Runtime\System\md\x86\prprf.h"\ + "..\..\..\Runtime\System\plstr.h"\ + "..\..\..\Utilities\General\plstr.h"\ + "..\..\..\Utilities\General\prbit.h"\ + "..\..\..\Utilities\General\prlog.h"\ + "..\..\..\Utilities\General\prlong.h"\ + + +"$(INTDIR)\x86ExceptionHandler.obj" "$(INTDIR)\x86ExceptionHandler.sbr" : \ +$(SOURCE) $(DEP_CPP_X86EX) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "electricalfire - Win32 Debug" + +DEP_CPP_X86EX=\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\nspr.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\obsolete\protypes.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\plstr.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\pratom.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prbit.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prclist.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcmon.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcpucfg.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcvar.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prdtoa.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prenv.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prerror.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinet.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinit.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinrval.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prio.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlink.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlock.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlog.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlong.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prmem.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prmon.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prnetdb.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prprf.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prproces.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prsystem.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prthread.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtime.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtypes.h"\ + "..\..\..\Compiler\CodeGenerator\ExceptionTable.h"\ + "..\..\..\Compiler\CodeGenerator\FormatStructures.h"\ + "..\..\..\Compiler\CodeGenerator\NativeCodeCache.h"\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\PrimitiveOperations.h"\ + "..\..\..\Compiler\PrimitiveGraph\Primitives.h"\ + "..\..\..\Compiler\PrimitiveGraph\SysCalls.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Compiler\RegisterAllocator\VirtualRegister.h"\ + "..\..\..\Debugger\Communication\DebuggerChannel.h"\ + "..\..\..\Debugger\Debugger.h"\ + "..\..\..\Runtime\ClassInfo\ClassCentral.h"\ + "..\..\..\Runtime\ClassInfo\ClassFileSummary.h"\ + "..\..\..\Runtime\ClassInfo\Collector.h"\ + "..\..\..\Runtime\ClassInfo\PathComponent.h"\ + "..\..\..\Runtime\ClassInfo\StringPool.h"\ + "..\..\..\Runtime\ClassReader\Attributes.h"\ + "..\..\..\Runtime\ClassReader\ClassReader.h"\ + "..\..\..\Runtime\ClassReader\ConstantPool.h"\ + "..\..\..\Runtime\ClassReader\InfoItem.h"\ + "..\..\..\Runtime\ClassReader\utils.h"\ + "..\..\..\Runtime\FileReader\FileReader.h"\ + "..\..\..\Runtime\FileReader\ZipArchive.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\System\ClassWorld.h"\ + "..\..\..\Runtime\System\FieldOrMethod.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Runtime\System\JavaString.h"\ + "..\..\..\Runtime\System\md\x86\x86Win32ExceptionHandler.h"\ + "..\..\..\Runtime\System\Method.h"\ + "..\..\..\Runtime\System\StackWalker.h"\ + "..\..\..\Runtime\System\SysCallsRuntime.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FastBitMatrix.h"\ + "..\..\..\Utilities\General\FastBitSet.h"\ + "..\..\..\Utilities\General\FastHashTable.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\InterestingEvents.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + "..\..\..\Utilities\zlib\zconf.h"\ + "..\..\..\Utilities\zlib\zlib.h"\ + + +"$(INTDIR)\x86ExceptionHandler.obj" "$(INTDIR)\x86ExceptionHandler.sbr" : \ +$(SOURCE) $(DEP_CPP_X86EX) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +SOURCE=..\..\..\Runtime\System\md\x86\x86SysCallsRuntime.cpp + +!IF "$(CFG)" == "electricalfire - Win32 Release" + +DEP_CPP_X86SY=\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Runtime\System\SysCallsRuntime.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\Nonspr.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + +NODEP_CPP_X86SY=\ + "..\..\..\Utilities\General\plstr.h"\ + "..\..\..\Utilities\General\prlog.h"\ + "..\..\..\Utilities\General\prlong.h"\ + + +"$(INTDIR)\x86SysCallsRuntime.obj" "$(INTDIR)\x86SysCallsRuntime.sbr" : \ +$(SOURCE) $(DEP_CPP_X86SY) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "electricalfire - Win32 Debug" + +DEP_CPP_X86SY=\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\obsolete\protypes.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcpucfg.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinet.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinrval.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prio.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlog.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlong.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtime.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtypes.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Runtime\System\SysCallsRuntime.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + + +"$(INTDIR)\x86SysCallsRuntime.obj" "$(INTDIR)\x86SysCallsRuntime.sbr" : \ +$(SOURCE) $(DEP_CPP_X86SY) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +SOURCE=..\..\..\Runtime\System\md\x86\x86Win32InvokeNative.cpp + +!IF "$(CFG)" == "electricalfire - Win32 Release" + +DEP_CPP_X86WI=\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\Nonspr.h"\ + +NODEP_CPP_X86WI=\ + "..\..\..\Utilities\General\plstr.h"\ + "..\..\..\Utilities\General\prlog.h"\ + "..\..\..\Utilities\General\prlong.h"\ + + +"$(INTDIR)\x86Win32InvokeNative.obj" "$(INTDIR)\x86Win32InvokeNative.sbr" : \ +$(SOURCE) $(DEP_CPP_X86WI) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "electricalfire - Win32 Debug" + +DEP_CPP_X86WI=\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\obsolete\protypes.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcpucfg.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinet.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinrval.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prio.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlog.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlong.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtime.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtypes.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + + +"$(INTDIR)\x86Win32InvokeNative.obj" "$(INTDIR)\x86Win32InvokeNative.sbr" : \ +$(SOURCE) $(DEP_CPP_X86WI) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +SOURCE=..\..\..\Runtime\System\md\x86\x86Win32Thread.cpp + +!IF "$(CFG)" == "electricalfire - Win32 Release" + +DEP_CPP_X86WIN=\ + "..\..\..\Compiler\CodeGenerator\ExceptionTable.h"\ + "..\..\..\Compiler\CodeGenerator\FormatStructures.h"\ + "..\..\..\Compiler\CodeGenerator\NativeCodeCache.h"\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Debugger\Communication\DebuggerChannel.h"\ + "..\..\..\Debugger\Debugger.h"\ + "..\..\..\Runtime\ClassInfo\ClassCentral.h"\ + "..\..\..\Runtime\ClassInfo\ClassFileSummary.h"\ + "..\..\..\Runtime\ClassInfo\Collector.h"\ + "..\..\..\Runtime\ClassInfo\PathComponent.h"\ + "..\..\..\Runtime\ClassInfo\StringPool.h"\ + "..\..\..\Runtime\ClassReader\Attributes.h"\ + "..\..\..\Runtime\ClassReader\ClassReader.h"\ + "..\..\..\Runtime\ClassReader\ConstantPool.h"\ + "..\..\..\Runtime\ClassReader\InfoItem.h"\ + "..\..\..\Runtime\ClassReader\utils.h"\ + "..\..\..\Runtime\FileReader\FileReader.h"\ + "..\..\..\Runtime\FileReader\ZipArchive.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\System\ClassWorld.h"\ + "..\..\..\Runtime\System\Exceptions.h"\ + "..\..\..\Runtime\System\FieldOrMethod.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Runtime\System\JavaString.h"\ + "..\..\..\Runtime\System\md\x86\x86Win32ExceptionHandler.h"\ + "..\..\..\Runtime\System\Method.h"\ + "..\..\..\Runtime\System\Monitor.h"\ + "..\..\..\Runtime\System\SysCallsRuntime.h"\ + "..\..\..\Runtime\System\Thread.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FastHashTable.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\InterestingEvents.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\Nonspr.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + "..\..\..\Utilities\zlib\zconf.h"\ + "..\..\..\Utilities\zlib\zlib.h"\ + +NODEP_CPP_X86WIN=\ + "..\..\..\Compiler\CodeGenerator\prmon.h"\ + "..\..\..\Debugger\Communication\prio.h"\ + "..\..\..\Debugger\Communication\prlock.h"\ + "..\..\..\Debugger\Communication\prprf.h"\ + "..\..\..\Debugger\nspr.h"\ + "..\..\..\Runtime\ClassReader\prtypes.h"\ + "..\..\..\Runtime\FileReader\prio.h"\ + "..\..\..\Runtime\FileReader\prtypes.h"\ + "..\..\..\Runtime\System\md\x86\prprf.h"\ + "..\..\..\Runtime\System\plstr.h"\ + "..\..\..\Runtime\System\pratom.h"\ + "..\..\..\Runtime\System\prcvar.h"\ + "..\..\..\Runtime\System\prlock.h"\ + "..\..\..\Runtime\System\prthread.h"\ + "..\..\..\Runtime\System\prtypes.h"\ + "..\..\..\Utilities\General\plstr.h"\ + "..\..\..\Utilities\General\prlog.h"\ + "..\..\..\Utilities\General\prlong.h"\ + + +"$(INTDIR)\x86Win32Thread.obj" "$(INTDIR)\x86Win32Thread.sbr" : $(SOURCE)\ + $(DEP_CPP_X86WIN) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "electricalfire - Win32 Debug" + +DEP_CPP_X86WIN=\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\nspr.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\obsolete\protypes.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\plstr.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\pratom.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prbit.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prclist.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcmon.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcpucfg.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcvar.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prdtoa.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prenv.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prerror.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinet.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinit.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinrval.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prio.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlink.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlock.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlog.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlong.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prmem.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prmon.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prnetdb.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prprf.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prproces.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prsystem.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prthread.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtime.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtypes.h"\ + "..\..\..\Compiler\CodeGenerator\ExceptionTable.h"\ + "..\..\..\Compiler\CodeGenerator\FormatStructures.h"\ + "..\..\..\Compiler\CodeGenerator\NativeCodeCache.h"\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Debugger\Communication\DebuggerChannel.h"\ + "..\..\..\Debugger\Debugger.h"\ + "..\..\..\Runtime\ClassInfo\ClassCentral.h"\ + "..\..\..\Runtime\ClassInfo\ClassFileSummary.h"\ + "..\..\..\Runtime\ClassInfo\Collector.h"\ + "..\..\..\Runtime\ClassInfo\PathComponent.h"\ + "..\..\..\Runtime\ClassInfo\StringPool.h"\ + "..\..\..\Runtime\ClassReader\Attributes.h"\ + "..\..\..\Runtime\ClassReader\ClassReader.h"\ + "..\..\..\Runtime\ClassReader\ConstantPool.h"\ + "..\..\..\Runtime\ClassReader\InfoItem.h"\ + "..\..\..\Runtime\ClassReader\utils.h"\ + "..\..\..\Runtime\FileReader\FileReader.h"\ + "..\..\..\Runtime\FileReader\ZipArchive.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\System\ClassWorld.h"\ + "..\..\..\Runtime\System\Exceptions.h"\ + "..\..\..\Runtime\System\FieldOrMethod.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Runtime\System\JavaString.h"\ + "..\..\..\Runtime\System\md\x86\x86Win32ExceptionHandler.h"\ + "..\..\..\Runtime\System\Method.h"\ + "..\..\..\Runtime\System\Monitor.h"\ + "..\..\..\Runtime\System\SysCallsRuntime.h"\ + "..\..\..\Runtime\System\Thread.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FastHashTable.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\InterestingEvents.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + "..\..\..\Utilities\zlib\zconf.h"\ + "..\..\..\Utilities\zlib\zlib.h"\ + + +"$(INTDIR)\x86Win32Thread.obj" "$(INTDIR)\x86Win32Thread.sbr" : $(SOURCE)\ + $(DEP_CPP_X86WIN) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +SOURCE=..\..\..\Runtime\System\ClassWorld.cpp + +!IF "$(CFG)" == "electricalfire - Win32 Release" + +DEP_CPP_CLASSW=\ + "..\..\..\Runtime\System\ClassWorld.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FastHashTable.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\Nonspr.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + +NODEP_CPP_CLASSW=\ + "..\..\..\Utilities\General\plstr.h"\ + "..\..\..\Utilities\General\prlog.h"\ + "..\..\..\Utilities\General\prlong.h"\ + + +"$(INTDIR)\ClassWorld.obj" "$(INTDIR)\ClassWorld.sbr" : $(SOURCE)\ + $(DEP_CPP_CLASSW) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "electricalfire - Win32 Debug" + +DEP_CPP_CLASSW=\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\obsolete\protypes.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcpucfg.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinet.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinrval.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prio.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlog.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlong.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtime.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtypes.h"\ + "..\..\..\Runtime\System\ClassWorld.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FastHashTable.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + + +"$(INTDIR)\ClassWorld.obj" "$(INTDIR)\ClassWorld.sbr" : $(SOURCE)\ + $(DEP_CPP_CLASSW) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +SOURCE=..\..\..\Runtime\System\FieldOrMethod.cpp + +!IF "$(CFG)" == "electricalfire - Win32 Release" + +DEP_CPP_FIELD=\ + "..\..\..\Compiler\CodeGenerator\Backend.h"\ + "..\..\..\Compiler\CodeGenerator\ExceptionTable.h"\ + "..\..\..\Compiler\CodeGenerator\FormatStructures.h"\ + "..\..\..\Compiler\CodeGenerator\Instruction.h"\ + "..\..\..\Compiler\CodeGenerator\InstructionEmitter.h"\ + "..\..\..\Compiler\CodeGenerator\md\CpuInfo.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Formatter.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Opcode.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Cpu.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Emitter.h"\ + "..\..\..\Compiler\CodeGenerator\NativeCodeCache.h"\ + "..\..\..\Compiler\FrontEnd\BytecodeGraph.h"\ + "..\..\..\Compiler\FrontEnd\BytecodeTranslator.h"\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Compiler\FrontEnd\LocalEnv.h"\ + "..\..\..\Compiler\FrontEnd\TranslationEnv.h"\ + "..\..\..\Compiler\FrontEnd\VerificationEnv.h"\ + "..\..\..\Compiler\Optimizer\PrimitiveOptimizer.h"\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlGraph.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlNodes.h"\ + "..\..\..\Compiler\PrimitiveGraph\PrimitiveOperations.h"\ + "..\..\..\Compiler\PrimitiveGraph\Primitives.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Compiler\RegisterAllocator\VirtualRegister.h"\ + "..\..\..\Debugger\Communication\DebuggerChannel.h"\ + "..\..\..\Debugger\Debugger.h"\ + "..\..\..\Runtime\ClassInfo\ClassCentral.h"\ + "..\..\..\Runtime\ClassInfo\ClassFileSummary.h"\ + "..\..\..\Runtime\ClassInfo\Collector.h"\ + "..\..\..\Runtime\ClassInfo\PathComponent.h"\ + "..\..\..\Runtime\ClassInfo\StringPool.h"\ + "..\..\..\Runtime\ClassReader\Attributes.h"\ + "..\..\..\Runtime\ClassReader\ClassReader.h"\ + "..\..\..\Runtime\ClassReader\ConstantPool.h"\ + "..\..\..\Runtime\ClassReader\InfoItem.h"\ + "..\..\..\Runtime\ClassReader\utils.h"\ + "..\..\..\Runtime\FileReader\FileReader.h"\ + "..\..\..\Runtime\FileReader\ZipArchive.h"\ + "..\..\..\Runtime\NativeMethods\NameMangler.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\NativeMethods\NativeMethodDispatcher.h"\ + "..\..\..\Runtime\System\ClassWorld.h"\ + "..\..\..\Runtime\System\FieldOrMethod.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Runtime\System\JavaString.h"\ + "..\..\..\Runtime\System\JavaVM.h"\ + "..\..\..\Runtime\System\md\FieldOrMethod_md.h"\ + "..\..\..\Runtime\System\Method.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\CheckedUnion.h"\ + "..\..\..\Utilities\General\CUtils.h"\ + "..\..\..\Utilities\General\DebugUtils.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FastBitMatrix.h"\ + "..\..\..\Utilities\General\FastBitSet.h"\ + "..\..\..\Utilities\General\FastHashTable.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\InterestingEvents.h"\ + "..\..\..\Utilities\General\JavaBytecodes.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\Nonspr.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\StringUtils.h"\ + "..\..\..\Utilities\General\Vector.h"\ + "..\..\..\Utilities\zlib\zconf.h"\ + "..\..\..\Utilities\zlib\zlib.h"\ + +NODEP_CPP_FIELD=\ + "..\..\..\Compiler\CodeGenerator\md\HPPACpu.h"\ + "..\..\..\Compiler\CodeGenerator\md\PPC601Cpu.h"\ + "..\..\..\Compiler\CodeGenerator\prmon.h"\ + "..\..\..\Compiler\CodeGenerator\prtypes.h"\ + "..\..\..\Debugger\Communication\prio.h"\ + "..\..\..\Debugger\Communication\prlock.h"\ + "..\..\..\Debugger\Communication\prprf.h"\ + "..\..\..\Debugger\nspr.h"\ + "..\..\..\Runtime\ClassReader\prtypes.h"\ + "..\..\..\Runtime\FileReader\prio.h"\ + "..\..\..\Runtime\FileReader\prtypes.h"\ + "..\..\..\Runtime\NativeMethods\prlink.h"\ + "..\..\..\Runtime\System\plstr.h"\ + "..\..\..\Runtime\System\prprf.h"\ + "..\..\..\Utilities\General\plstr.h"\ + "..\..\..\Utilities\General\prbit.h"\ + "..\..\..\Utilities\General\prio.h"\ + "..\..\..\Utilities\General\prlog.h"\ + "..\..\..\Utilities\General\prlong.h"\ + "..\..\..\Utilities\General\prprf.h"\ + + +"$(INTDIR)\FieldOrMethod.obj" "$(INTDIR)\FieldOrMethod.sbr" : $(SOURCE)\ + $(DEP_CPP_FIELD) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "electricalfire - Win32 Debug" + +DEP_CPP_FIELD=\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\nspr.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\obsolete\protypes.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\plstr.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\pratom.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prbit.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prclist.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcmon.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcpucfg.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcvar.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prdtoa.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prenv.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prerror.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinet.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinit.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinrval.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prio.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlink.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlock.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlog.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlong.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prmem.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prmon.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prnetdb.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prprf.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prproces.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prsystem.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prthread.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtime.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtypes.h"\ + "..\..\..\Compiler\CodeGenerator\Backend.h"\ + "..\..\..\Compiler\CodeGenerator\ExceptionTable.h"\ + "..\..\..\Compiler\CodeGenerator\FormatStructures.h"\ + "..\..\..\Compiler\CodeGenerator\Instruction.h"\ + "..\..\..\Compiler\CodeGenerator\md\CpuInfo.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Cpu.h"\ + "..\..\..\Compiler\CodeGenerator\NativeCodeCache.h"\ + "..\..\..\Compiler\FrontEnd\BytecodeGraph.h"\ + "..\..\..\Compiler\FrontEnd\BytecodeTranslator.h"\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Compiler\FrontEnd\LocalEnv.h"\ + "..\..\..\Compiler\FrontEnd\TranslationEnv.h"\ + "..\..\..\Compiler\FrontEnd\VerificationEnv.h"\ + "..\..\..\Compiler\Optimizer\PrimitiveOptimizer.h"\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlGraph.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlNodes.h"\ + "..\..\..\Compiler\PrimitiveGraph\PrimitiveOperations.h"\ + "..\..\..\Compiler\PrimitiveGraph\Primitives.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Compiler\RegisterAllocator\VirtualRegister.h"\ + "..\..\..\Debugger\Communication\DebuggerChannel.h"\ + "..\..\..\Debugger\Debugger.h"\ + "..\..\..\Runtime\ClassInfo\ClassCentral.h"\ + "..\..\..\Runtime\ClassInfo\ClassFileSummary.h"\ + "..\..\..\Runtime\ClassInfo\Collector.h"\ + "..\..\..\Runtime\ClassInfo\PathComponent.h"\ + "..\..\..\Runtime\ClassInfo\StringPool.h"\ + "..\..\..\Runtime\ClassReader\Attributes.h"\ + "..\..\..\Runtime\ClassReader\ClassReader.h"\ + "..\..\..\Runtime\ClassReader\ConstantPool.h"\ + "..\..\..\Runtime\ClassReader\InfoItem.h"\ + "..\..\..\Runtime\ClassReader\utils.h"\ + "..\..\..\Runtime\FileReader\FileReader.h"\ + "..\..\..\Runtime\FileReader\ZipArchive.h"\ + "..\..\..\Runtime\NativeMethods\NameMangler.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\NativeMethods\NativeMethodDispatcher.h"\ + "..\..\..\Runtime\System\ClassWorld.h"\ + "..\..\..\Runtime\System\FieldOrMethod.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Runtime\System\JavaString.h"\ + "..\..\..\Runtime\System\JavaVM.h"\ + "..\..\..\Runtime\System\md\FieldOrMethod_md.h"\ + "..\..\..\Runtime\System\Method.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\CheckedUnion.h"\ + "..\..\..\Utilities\General\CUtils.h"\ + "..\..\..\Utilities\General\DebugUtils.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FastBitMatrix.h"\ + "..\..\..\Utilities\General\FastBitSet.h"\ + "..\..\..\Utilities\General\FastHashTable.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\InterestingEvents.h"\ + "..\..\..\Utilities\General\JavaBytecodes.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\StringUtils.h"\ + "..\..\..\Utilities\General\Vector.h"\ + "..\..\..\Utilities\zlib\zconf.h"\ + "..\..\..\Utilities\zlib\zlib.h"\ + + +"$(INTDIR)\FieldOrMethod.obj" "$(INTDIR)\FieldOrMethod.sbr" : $(SOURCE)\ + $(DEP_CPP_FIELD) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +SOURCE=..\..\..\Runtime\System\InterfaceDispatchTable.cpp + +!IF "$(CFG)" == "electricalfire - Win32 Release" + +DEP_CPP_INTER=\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\Nonspr.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + +NODEP_CPP_INTER=\ + "..\..\..\Utilities\General\plstr.h"\ + "..\..\..\Utilities\General\prlog.h"\ + "..\..\..\Utilities\General\prlong.h"\ + + +"$(INTDIR)\InterfaceDispatchTable.obj" "$(INTDIR)\InterfaceDispatchTable.sbr" :\ + $(SOURCE) $(DEP_CPP_INTER) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "electricalfire - Win32 Debug" + +DEP_CPP_INTER=\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\obsolete\protypes.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcpucfg.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinet.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinrval.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prio.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlog.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlong.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtime.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtypes.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + + +"$(INTDIR)\InterfaceDispatchTable.obj" "$(INTDIR)\InterfaceDispatchTable.sbr" :\ + $(SOURCE) $(DEP_CPP_INTER) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +SOURCE=..\..\..\Runtime\System\JavaObject.cpp + +!IF "$(CFG)" == "electricalfire - Win32 Release" + +DEP_CPP_JAVAO=\ + "..\..\..\Compiler\CodeGenerator\ExceptionTable.h"\ + "..\..\..\Compiler\CodeGenerator\FormatStructures.h"\ + "..\..\..\Compiler\CodeGenerator\Instruction.h"\ + "..\..\..\Compiler\CodeGenerator\InstructionEmitter.h"\ + "..\..\..\Compiler\CodeGenerator\md\CpuInfo.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Formatter.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Opcode.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Cpu.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Emitter.h"\ + "..\..\..\Compiler\CodeGenerator\NativeCodeCache.h"\ + "..\..\..\Compiler\FrontEnd\BytecodeGraph.h"\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Compiler\FrontEnd\LocalEnv.h"\ + "..\..\..\Compiler\FrontEnd\TranslationEnv.h"\ + "..\..\..\Compiler\FrontEnd\VerificationEnv.h"\ + "..\..\..\Compiler\Optimizer\PrimitiveOptimizer.h"\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlGraph.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlNodes.h"\ + "..\..\..\Compiler\PrimitiveGraph\PrimitiveOperations.h"\ + "..\..\..\Compiler\PrimitiveGraph\Primitives.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Compiler\RegisterAllocator\VirtualRegister.h"\ + "..\..\..\Debugger\Communication\DebuggerChannel.h"\ + "..\..\..\Debugger\Debugger.h"\ + "..\..\..\Runtime\ClassInfo\ClassCentral.h"\ + "..\..\..\Runtime\ClassInfo\ClassFileSummary.h"\ + "..\..\..\Runtime\ClassInfo\Collector.h"\ + "..\..\..\Runtime\ClassInfo\PathComponent.h"\ + "..\..\..\Runtime\ClassInfo\StringPool.h"\ + "..\..\..\Runtime\ClassReader\Attributes.h"\ + "..\..\..\Runtime\ClassReader\ClassReader.h"\ + "..\..\..\Runtime\ClassReader\ConstantPool.h"\ + "..\..\..\Runtime\ClassReader\InfoItem.h"\ + "..\..\..\Runtime\ClassReader\utils.h"\ + "..\..\..\Runtime\FileReader\FileReader.h"\ + "..\..\..\Runtime\FileReader\ZipArchive.h"\ + "..\..\..\Runtime\NativeMethods\NameMangler.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\NativeMethods\NativeMethodDispatcher.h"\ + "..\..\..\Runtime\System\ClassWorld.h"\ + "..\..\..\Runtime\System\FieldOrMethod.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Runtime\System\JavaString.h"\ + "..\..\..\Runtime\System\JavaVM.h"\ + "..\..\..\Runtime\System\Method.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\CheckedUnion.h"\ + "..\..\..\Utilities\General\DebugUtils.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FastBitMatrix.h"\ + "..\..\..\Utilities\General\FastBitSet.h"\ + "..\..\..\Utilities\General\FastHashTable.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\InterestingEvents.h"\ + "..\..\..\Utilities\General\JavaBytecodes.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\Nonspr.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + "..\..\..\Utilities\zlib\zconf.h"\ + "..\..\..\Utilities\zlib\zlib.h"\ + +NODEP_CPP_JAVAO=\ + "..\..\..\Compiler\CodeGenerator\md\HPPACpu.h"\ + "..\..\..\Compiler\CodeGenerator\md\PPC601Cpu.h"\ + "..\..\..\Compiler\CodeGenerator\prmon.h"\ + "..\..\..\Compiler\CodeGenerator\prtypes.h"\ + "..\..\..\Debugger\Communication\prio.h"\ + "..\..\..\Debugger\Communication\prlock.h"\ + "..\..\..\Debugger\Communication\prprf.h"\ + "..\..\..\Debugger\nspr.h"\ + "..\..\..\Runtime\ClassReader\prtypes.h"\ + "..\..\..\Runtime\FileReader\prio.h"\ + "..\..\..\Runtime\FileReader\prtypes.h"\ + "..\..\..\Runtime\NativeMethods\prlink.h"\ + "..\..\..\Runtime\System\plstr.h"\ + "..\..\..\Runtime\System\prprf.h"\ + "..\..\..\Utilities\General\plstr.h"\ + "..\..\..\Utilities\General\prbit.h"\ + "..\..\..\Utilities\General\prlog.h"\ + "..\..\..\Utilities\General\prlong.h"\ + + +"$(INTDIR)\JavaObject.obj" "$(INTDIR)\JavaObject.sbr" : $(SOURCE)\ + $(DEP_CPP_JAVAO) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "electricalfire - Win32 Debug" + +DEP_CPP_JAVAO=\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\nspr.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\obsolete\protypes.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\plstr.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\pratom.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prbit.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prclist.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcmon.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcpucfg.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcvar.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prdtoa.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prenv.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prerror.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinet.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinit.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinrval.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prio.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlink.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlock.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlog.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlong.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prmem.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prmon.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prnetdb.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prprf.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prproces.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prsystem.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prthread.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtime.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtypes.h"\ + "..\..\..\Compiler\CodeGenerator\ExceptionTable.h"\ + "..\..\..\Compiler\CodeGenerator\FormatStructures.h"\ + "..\..\..\Compiler\CodeGenerator\Instruction.h"\ + "..\..\..\Compiler\CodeGenerator\md\CpuInfo.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Cpu.h"\ + "..\..\..\Compiler\CodeGenerator\NativeCodeCache.h"\ + "..\..\..\Compiler\FrontEnd\BytecodeGraph.h"\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Compiler\FrontEnd\LocalEnv.h"\ + "..\..\..\Compiler\FrontEnd\TranslationEnv.h"\ + "..\..\..\Compiler\FrontEnd\VerificationEnv.h"\ + "..\..\..\Compiler\Optimizer\PrimitiveOptimizer.h"\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlGraph.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlNodes.h"\ + "..\..\..\Compiler\PrimitiveGraph\PrimitiveOperations.h"\ + "..\..\..\Compiler\PrimitiveGraph\Primitives.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Compiler\RegisterAllocator\VirtualRegister.h"\ + "..\..\..\Debugger\Communication\DebuggerChannel.h"\ + "..\..\..\Debugger\Debugger.h"\ + "..\..\..\Runtime\ClassInfo\ClassCentral.h"\ + "..\..\..\Runtime\ClassInfo\ClassFileSummary.h"\ + "..\..\..\Runtime\ClassInfo\Collector.h"\ + "..\..\..\Runtime\ClassInfo\PathComponent.h"\ + "..\..\..\Runtime\ClassInfo\StringPool.h"\ + "..\..\..\Runtime\ClassReader\Attributes.h"\ + "..\..\..\Runtime\ClassReader\ClassReader.h"\ + "..\..\..\Runtime\ClassReader\ConstantPool.h"\ + "..\..\..\Runtime\ClassReader\InfoItem.h"\ + "..\..\..\Runtime\ClassReader\utils.h"\ + "..\..\..\Runtime\FileReader\FileReader.h"\ + "..\..\..\Runtime\FileReader\ZipArchive.h"\ + "..\..\..\Runtime\NativeMethods\NameMangler.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\NativeMethods\NativeMethodDispatcher.h"\ + "..\..\..\Runtime\System\ClassWorld.h"\ + "..\..\..\Runtime\System\FieldOrMethod.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Runtime\System\JavaString.h"\ + "..\..\..\Runtime\System\JavaVM.h"\ + "..\..\..\Runtime\System\Method.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\CheckedUnion.h"\ + "..\..\..\Utilities\General\DebugUtils.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FastBitMatrix.h"\ + "..\..\..\Utilities\General\FastBitSet.h"\ + "..\..\..\Utilities\General\FastHashTable.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\InterestingEvents.h"\ + "..\..\..\Utilities\General\JavaBytecodes.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + "..\..\..\Utilities\zlib\zconf.h"\ + "..\..\..\Utilities\zlib\zlib.h"\ + + +"$(INTDIR)\JavaObject.obj" "$(INTDIR)\JavaObject.sbr" : $(SOURCE)\ + $(DEP_CPP_JAVAO) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +SOURCE=..\..\..\Runtime\System\JavaString.cpp + +!IF "$(CFG)" == "electricalfire - Win32 Release" + +DEP_CPP_JAVAS=\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Runtime\ClassInfo\ClassCentral.h"\ + "..\..\..\Runtime\ClassInfo\ClassFileSummary.h"\ + "..\..\..\Runtime\ClassInfo\Collector.h"\ + "..\..\..\Runtime\ClassInfo\PathComponent.h"\ + "..\..\..\Runtime\ClassInfo\StringPool.h"\ + "..\..\..\Runtime\ClassReader\Attributes.h"\ + "..\..\..\Runtime\ClassReader\ClassReader.h"\ + "..\..\..\Runtime\ClassReader\ConstantPool.h"\ + "..\..\..\Runtime\ClassReader\InfoItem.h"\ + "..\..\..\Runtime\ClassReader\utils.h"\ + "..\..\..\Runtime\FileReader\FileReader.h"\ + "..\..\..\Runtime\FileReader\ZipArchive.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\System\ClassWorld.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Runtime\System\JavaString.h"\ + "..\..\..\Runtime\System\Method.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FastHashTable.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\Nonspr.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + "..\..\..\Utilities\zlib\zconf.h"\ + "..\..\..\Utilities\zlib\zlib.h"\ + +NODEP_CPP_JAVAS=\ + "..\..\..\Runtime\ClassReader\prtypes.h"\ + "..\..\..\Runtime\FileReader\prio.h"\ + "..\..\..\Runtime\FileReader\prtypes.h"\ + "..\..\..\Runtime\System\plstr.h"\ + "..\..\..\Utilities\General\plstr.h"\ + "..\..\..\Utilities\General\prlog.h"\ + "..\..\..\Utilities\General\prlong.h"\ + + +"$(INTDIR)\JavaString.obj" "$(INTDIR)\JavaString.sbr" : $(SOURCE)\ + $(DEP_CPP_JAVAS) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "electricalfire - Win32 Debug" + +DEP_CPP_JAVAS=\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\obsolete\protypes.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\plstr.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcpucfg.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinet.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinrval.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prio.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlog.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlong.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtime.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtypes.h"\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Runtime\ClassInfo\ClassCentral.h"\ + "..\..\..\Runtime\ClassInfo\ClassFileSummary.h"\ + "..\..\..\Runtime\ClassInfo\Collector.h"\ + "..\..\..\Runtime\ClassInfo\PathComponent.h"\ + "..\..\..\Runtime\ClassInfo\StringPool.h"\ + "..\..\..\Runtime\ClassReader\Attributes.h"\ + "..\..\..\Runtime\ClassReader\ClassReader.h"\ + "..\..\..\Runtime\ClassReader\ConstantPool.h"\ + "..\..\..\Runtime\ClassReader\InfoItem.h"\ + "..\..\..\Runtime\ClassReader\utils.h"\ + "..\..\..\Runtime\FileReader\FileReader.h"\ + "..\..\..\Runtime\FileReader\ZipArchive.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\System\ClassWorld.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Runtime\System\JavaString.h"\ + "..\..\..\Runtime\System\Method.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FastHashTable.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + "..\..\..\Utilities\zlib\zconf.h"\ + "..\..\..\Utilities\zlib\zlib.h"\ + + +"$(INTDIR)\JavaString.obj" "$(INTDIR)\JavaString.sbr" : $(SOURCE)\ + $(DEP_CPP_JAVAS) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +SOURCE=..\..\..\Runtime\System\JavaVM.cpp + +!IF "$(CFG)" == "electricalfire - Win32 Release" + +DEP_CPP_JAVAV=\ + "..\..\..\Compiler\CodeGenerator\ExceptionTable.h"\ + "..\..\..\Compiler\CodeGenerator\FormatStructures.h"\ + "..\..\..\Compiler\CodeGenerator\Instruction.h"\ + "..\..\..\Compiler\CodeGenerator\InstructionEmitter.h"\ + "..\..\..\Compiler\CodeGenerator\md\CpuInfo.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Formatter.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Opcode.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Cpu.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Emitter.h"\ + "..\..\..\Compiler\CodeGenerator\NativeCodeCache.h"\ + "..\..\..\Compiler\FrontEnd\BytecodeGraph.h"\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Compiler\FrontEnd\LocalEnv.h"\ + "..\..\..\Compiler\FrontEnd\TranslationEnv.h"\ + "..\..\..\Compiler\FrontEnd\VerificationEnv.h"\ + "..\..\..\Compiler\Optimizer\PrimitiveOptimizer.h"\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlGraph.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlNodes.h"\ + "..\..\..\Compiler\PrimitiveGraph\PrimitiveOperations.h"\ + "..\..\..\Compiler\PrimitiveGraph\Primitives.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Compiler\RegisterAllocator\VirtualRegister.h"\ + "..\..\..\Debugger\Communication\DebuggerChannel.h"\ + "..\..\..\Debugger\Debugger.h"\ + "..\..\..\Debugger\jvmdi.h"\ + "..\..\..\Exports\jni.h"\ + "..\..\..\Exports\md\jni_md.h"\ + "..\..\..\Runtime\ClassInfo\ClassCentral.h"\ + "..\..\..\Runtime\ClassInfo\ClassFileSummary.h"\ + "..\..\..\Runtime\ClassInfo\Collector.h"\ + "..\..\..\Runtime\ClassInfo\PathComponent.h"\ + "..\..\..\Runtime\ClassInfo\StringPool.h"\ + "..\..\..\Runtime\ClassReader\Attributes.h"\ + "..\..\..\Runtime\ClassReader\ClassReader.h"\ + "..\..\..\Runtime\ClassReader\ConstantPool.h"\ + "..\..\..\Runtime\ClassReader\InfoItem.h"\ + "..\..\..\Runtime\ClassReader\utils.h"\ + "..\..\..\Runtime\FileReader\FileReader.h"\ + "..\..\..\Runtime\FileReader\ZipArchive.h"\ + "..\..\..\Runtime\NativeMethods\JniRuntime.h"\ + "..\..\..\Runtime\NativeMethods\NameMangler.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\NativeMethods\NativeMethodDispatcher.h"\ + "..\..\..\Runtime\System\ClassWorld.h"\ + "..\..\..\Runtime\System\FieldOrMethod.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Runtime\System\JavaString.h"\ + "..\..\..\Runtime\System\JavaVM.h"\ + "..\..\..\Runtime\System\Method.h"\ + "..\..\..\Runtime\System\Monitor.h"\ + "..\..\..\Runtime\System\Thread.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\CheckedUnion.h"\ + "..\..\..\Utilities\General\DebugUtils.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FastBitMatrix.h"\ + "..\..\..\Utilities\General\FastBitSet.h"\ + "..\..\..\Utilities\General\FastHashTable.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\InterestingEvents.h"\ + "..\..\..\Utilities\General\JavaBytecodes.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\Nonspr.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + "..\..\..\Utilities\zlib\zconf.h"\ + "..\..\..\Utilities\zlib\zlib.h"\ + +NODEP_CPP_JAVAV=\ + "..\..\..\Compiler\CodeGenerator\md\HPPACpu.h"\ + "..\..\..\Compiler\CodeGenerator\md\PPC601Cpu.h"\ + "..\..\..\Compiler\CodeGenerator\prmon.h"\ + "..\..\..\Compiler\CodeGenerator\prtypes.h"\ + "..\..\..\Debugger\Communication\prio.h"\ + "..\..\..\Debugger\Communication\prlock.h"\ + "..\..\..\Debugger\Communication\prprf.h"\ + "..\..\..\Debugger\nspr.h"\ + "..\..\..\Runtime\ClassReader\prtypes.h"\ + "..\..\..\Runtime\FileReader\prio.h"\ + "..\..\..\Runtime\FileReader\prtypes.h"\ + "..\..\..\Runtime\NativeMethods\prlink.h"\ + "..\..\..\Runtime\System\plstr.h"\ + "..\..\..\Runtime\System\pratom.h"\ + "..\..\..\Runtime\System\prcvar.h"\ + "..\..\..\Runtime\System\prlock.h"\ + "..\..\..\Runtime\System\prprf.h"\ + "..\..\..\Runtime\System\prthread.h"\ + "..\..\..\Runtime\System\prtypes.h"\ + "..\..\..\Utilities\General\plstr.h"\ + "..\..\..\Utilities\General\prbit.h"\ + "..\..\..\Utilities\General\prlog.h"\ + "..\..\..\Utilities\General\prlong.h"\ + + +"$(INTDIR)\JavaVM.obj" "$(INTDIR)\JavaVM.sbr" : $(SOURCE) $(DEP_CPP_JAVAV)\ + "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "electricalfire - Win32 Debug" + +DEP_CPP_JAVAV=\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\nspr.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\obsolete\protypes.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\plstr.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\pratom.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prbit.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prclist.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcmon.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcpucfg.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcvar.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prdtoa.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prenv.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prerror.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinet.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinit.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinrval.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prio.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlink.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlock.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlog.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlong.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prmem.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prmon.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prnetdb.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prprf.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prproces.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prsystem.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prthread.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtime.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtypes.h"\ + "..\..\..\Compiler\CodeGenerator\ExceptionTable.h"\ + "..\..\..\Compiler\CodeGenerator\FormatStructures.h"\ + "..\..\..\Compiler\CodeGenerator\Instruction.h"\ + "..\..\..\Compiler\CodeGenerator\md\CpuInfo.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Cpu.h"\ + "..\..\..\Compiler\CodeGenerator\NativeCodeCache.h"\ + "..\..\..\Compiler\FrontEnd\BytecodeGraph.h"\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Compiler\FrontEnd\LocalEnv.h"\ + "..\..\..\Compiler\FrontEnd\TranslationEnv.h"\ + "..\..\..\Compiler\FrontEnd\VerificationEnv.h"\ + "..\..\..\Compiler\Optimizer\PrimitiveOptimizer.h"\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlGraph.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlNodes.h"\ + "..\..\..\Compiler\PrimitiveGraph\PrimitiveOperations.h"\ + "..\..\..\Compiler\PrimitiveGraph\Primitives.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Compiler\RegisterAllocator\VirtualRegister.h"\ + "..\..\..\Debugger\Communication\DebuggerChannel.h"\ + "..\..\..\Debugger\Debugger.h"\ + "..\..\..\Debugger\jvmdi.h"\ + "..\..\..\Exports\jni.h"\ + "..\..\..\Exports\md\jni_md.h"\ + "..\..\..\Runtime\ClassInfo\ClassCentral.h"\ + "..\..\..\Runtime\ClassInfo\ClassFileSummary.h"\ + "..\..\..\Runtime\ClassInfo\Collector.h"\ + "..\..\..\Runtime\ClassInfo\PathComponent.h"\ + "..\..\..\Runtime\ClassInfo\StringPool.h"\ + "..\..\..\Runtime\ClassReader\Attributes.h"\ + "..\..\..\Runtime\ClassReader\ClassReader.h"\ + "..\..\..\Runtime\ClassReader\ConstantPool.h"\ + "..\..\..\Runtime\ClassReader\InfoItem.h"\ + "..\..\..\Runtime\ClassReader\utils.h"\ + "..\..\..\Runtime\FileReader\FileReader.h"\ + "..\..\..\Runtime\FileReader\ZipArchive.h"\ + "..\..\..\Runtime\NativeMethods\JniRuntime.h"\ + "..\..\..\Runtime\NativeMethods\NameMangler.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\NativeMethods\NativeMethodDispatcher.h"\ + "..\..\..\Runtime\System\ClassWorld.h"\ + "..\..\..\Runtime\System\FieldOrMethod.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Runtime\System\JavaString.h"\ + "..\..\..\Runtime\System\JavaVM.h"\ + "..\..\..\Runtime\System\Method.h"\ + "..\..\..\Runtime\System\Monitor.h"\ + "..\..\..\Runtime\System\Thread.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\CheckedUnion.h"\ + "..\..\..\Utilities\General\DebugUtils.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FastBitMatrix.h"\ + "..\..\..\Utilities\General\FastBitSet.h"\ + "..\..\..\Utilities\General\FastHashTable.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\InterestingEvents.h"\ + "..\..\..\Utilities\General\JavaBytecodes.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + "..\..\..\Utilities\zlib\zconf.h"\ + "..\..\..\Utilities\zlib\zlib.h"\ + + +"$(INTDIR)\JavaVM.obj" "$(INTDIR)\JavaVM.sbr" : $(SOURCE) $(DEP_CPP_JAVAV)\ + "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +SOURCE=..\..\..\Runtime\System\Method.cpp + +!IF "$(CFG)" == "electricalfire - Win32 Release" + +DEP_CPP_METHO=\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Runtime\System\Method.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\Nonspr.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + +NODEP_CPP_METHO=\ + "..\..\..\Utilities\General\plstr.h"\ + "..\..\..\Utilities\General\prlog.h"\ + "..\..\..\Utilities\General\prlong.h"\ + + +"$(INTDIR)\Method.obj" "$(INTDIR)\Method.sbr" : $(SOURCE) $(DEP_CPP_METHO)\ + "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "electricalfire - Win32 Debug" + +DEP_CPP_METHO=\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\obsolete\protypes.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcpucfg.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinet.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinrval.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prio.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlog.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlong.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtime.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtypes.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Runtime\System\Method.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + + +"$(INTDIR)\Method.obj" "$(INTDIR)\Method.sbr" : $(SOURCE) $(DEP_CPP_METHO)\ + "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +SOURCE=..\..\..\Runtime\System\Monitor.cpp + +!IF "$(CFG)" == "electricalfire - Win32 Release" + +DEP_CPP_MONIT=\ + "..\..\..\Runtime\System\Exceptions.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Runtime\System\md\x86\x86Win32ExceptionHandler.h"\ + "..\..\..\Runtime\System\Monitor.h"\ + "..\..\..\Runtime\System\SysCallsRuntime.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\Nonspr.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + +NODEP_CPP_MONIT=\ + "..\..\..\Runtime\System\pratom.h"\ + "..\..\..\Runtime\System\prcvar.h"\ + "..\..\..\Runtime\System\prlock.h"\ + "..\..\..\Runtime\System\prprf.h"\ + "..\..\..\Runtime\System\prthread.h"\ + "..\..\..\Runtime\System\prtypes.h"\ + "..\..\..\Utilities\General\plstr.h"\ + "..\..\..\Utilities\General\prlog.h"\ + "..\..\..\Utilities\General\prlong.h"\ + + +"$(INTDIR)\Monitor.obj" "$(INTDIR)\Monitor.sbr" : $(SOURCE) $(DEP_CPP_MONIT)\ + "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "electricalfire - Win32 Debug" + +DEP_CPP_MONIT=\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\obsolete\protypes.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\pratom.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcpucfg.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcvar.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinet.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinrval.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prio.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlock.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlog.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlong.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prprf.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prthread.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtime.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtypes.h"\ + "..\..\..\Runtime\System\Exceptions.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Runtime\System\md\x86\x86Win32ExceptionHandler.h"\ + "..\..\..\Runtime\System\Monitor.h"\ + "..\..\..\Runtime\System\SysCallsRuntime.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + + +"$(INTDIR)\Monitor.obj" "$(INTDIR)\Monitor.sbr" : $(SOURCE) $(DEP_CPP_MONIT)\ + "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +SOURCE=..\..\..\Runtime\System\StackWalker.cpp + +!IF "$(CFG)" == "electricalfire - Win32 Release" + +DEP_CPP_STACK=\ + "..\..\..\Compiler\CodeGenerator\ExceptionTable.h"\ + "..\..\..\Compiler\CodeGenerator\FormatStructures.h"\ + "..\..\..\Compiler\CodeGenerator\NativeCodeCache.h"\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Debugger\Communication\DebuggerChannel.h"\ + "..\..\..\Debugger\Debugger.h"\ + "..\..\..\Runtime\ClassInfo\ClassCentral.h"\ + "..\..\..\Runtime\ClassInfo\ClassFileSummary.h"\ + "..\..\..\Runtime\ClassInfo\Collector.h"\ + "..\..\..\Runtime\ClassInfo\PathComponent.h"\ + "..\..\..\Runtime\ClassInfo\StringPool.h"\ + "..\..\..\Runtime\ClassReader\Attributes.h"\ + "..\..\..\Runtime\ClassReader\ClassReader.h"\ + "..\..\..\Runtime\ClassReader\ConstantPool.h"\ + "..\..\..\Runtime\ClassReader\InfoItem.h"\ + "..\..\..\Runtime\ClassReader\utils.h"\ + "..\..\..\Runtime\FileReader\FileReader.h"\ + "..\..\..\Runtime\FileReader\ZipArchive.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\System\ClassWorld.h"\ + "..\..\..\Runtime\System\FieldOrMethod.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Runtime\System\JavaString.h"\ + "..\..\..\Runtime\System\Method.h"\ + "..\..\..\Runtime\System\StackWalker.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FastHashTable.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\InterestingEvents.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\Nonspr.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + "..\..\..\Utilities\zlib\zconf.h"\ + "..\..\..\Utilities\zlib\zlib.h"\ + +NODEP_CPP_STACK=\ + "..\..\..\Compiler\CodeGenerator\prmon.h"\ + "..\..\..\Debugger\Communication\prio.h"\ + "..\..\..\Debugger\Communication\prlock.h"\ + "..\..\..\Debugger\Communication\prprf.h"\ + "..\..\..\Debugger\nspr.h"\ + "..\..\..\Runtime\ClassReader\prtypes.h"\ + "..\..\..\Runtime\FileReader\prio.h"\ + "..\..\..\Runtime\FileReader\prtypes.h"\ + "..\..\..\Runtime\System\plstr.h"\ + "..\..\..\Runtime\System\prprf.h"\ + "..\..\..\Utilities\General\plstr.h"\ + "..\..\..\Utilities\General\prlog.h"\ + "..\..\..\Utilities\General\prlong.h"\ + + +"$(INTDIR)\StackWalker.obj" "$(INTDIR)\StackWalker.sbr" : $(SOURCE)\ + $(DEP_CPP_STACK) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "electricalfire - Win32 Debug" + +DEP_CPP_STACK=\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\nspr.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\obsolete\protypes.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\plstr.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\pratom.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prbit.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prclist.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcmon.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcpucfg.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcvar.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prdtoa.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prenv.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prerror.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinet.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinit.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinrval.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prio.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlink.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlock.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlog.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlong.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prmem.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prmon.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prnetdb.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prprf.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prproces.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prsystem.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prthread.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtime.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtypes.h"\ + "..\..\..\Compiler\CodeGenerator\ExceptionTable.h"\ + "..\..\..\Compiler\CodeGenerator\FormatStructures.h"\ + "..\..\..\Compiler\CodeGenerator\NativeCodeCache.h"\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Debugger\Communication\DebuggerChannel.h"\ + "..\..\..\Debugger\Debugger.h"\ + "..\..\..\Runtime\ClassInfo\ClassCentral.h"\ + "..\..\..\Runtime\ClassInfo\ClassFileSummary.h"\ + "..\..\..\Runtime\ClassInfo\Collector.h"\ + "..\..\..\Runtime\ClassInfo\PathComponent.h"\ + "..\..\..\Runtime\ClassInfo\StringPool.h"\ + "..\..\..\Runtime\ClassReader\Attributes.h"\ + "..\..\..\Runtime\ClassReader\ClassReader.h"\ + "..\..\..\Runtime\ClassReader\ConstantPool.h"\ + "..\..\..\Runtime\ClassReader\InfoItem.h"\ + "..\..\..\Runtime\ClassReader\utils.h"\ + "..\..\..\Runtime\FileReader\FileReader.h"\ + "..\..\..\Runtime\FileReader\ZipArchive.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\System\ClassWorld.h"\ + "..\..\..\Runtime\System\FieldOrMethod.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Runtime\System\JavaString.h"\ + "..\..\..\Runtime\System\Method.h"\ + "..\..\..\Runtime\System\StackWalker.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FastHashTable.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\InterestingEvents.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + "..\..\..\Utilities\zlib\zconf.h"\ + "..\..\..\Utilities\zlib\zlib.h"\ + + +"$(INTDIR)\StackWalker.obj" "$(INTDIR)\StackWalker.sbr" : $(SOURCE)\ + $(DEP_CPP_STACK) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +SOURCE=..\..\..\Runtime\System\SysCallsRuntime.cpp + +!IF "$(CFG)" == "electricalfire - Win32 Release" + +DEP_CPP_SYSCA=\ + "..\..\..\Compiler\CodeGenerator\ExceptionTable.h"\ + "..\..\..\Compiler\CodeGenerator\FormatStructures.h"\ + "..\..\..\Compiler\CodeGenerator\Instruction.h"\ + "..\..\..\Compiler\CodeGenerator\InstructionEmitter.h"\ + "..\..\..\Compiler\CodeGenerator\md\CpuInfo.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Formatter.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Opcode.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Cpu.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Emitter.h"\ + "..\..\..\Compiler\CodeGenerator\NativeCodeCache.h"\ + "..\..\..\Compiler\FrontEnd\BytecodeGraph.h"\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Compiler\FrontEnd\LocalEnv.h"\ + "..\..\..\Compiler\FrontEnd\TranslationEnv.h"\ + "..\..\..\Compiler\FrontEnd\VerificationEnv.h"\ + "..\..\..\Compiler\Optimizer\PrimitiveOptimizer.h"\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlGraph.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlNodes.h"\ + "..\..\..\Compiler\PrimitiveGraph\PrimitiveOperations.h"\ + "..\..\..\Compiler\PrimitiveGraph\Primitives.h"\ + "..\..\..\Compiler\PrimitiveGraph\SysCalls.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Compiler\RegisterAllocator\VirtualRegister.h"\ + "..\..\..\Debugger\Communication\DebuggerChannel.h"\ + "..\..\..\Debugger\Debugger.h"\ + "..\..\..\Runtime\ClassInfo\ClassCentral.h"\ + "..\..\..\Runtime\ClassInfo\ClassFileSummary.h"\ + "..\..\..\Runtime\ClassInfo\Collector.h"\ + "..\..\..\Runtime\ClassInfo\PathComponent.h"\ + "..\..\..\Runtime\ClassInfo\StringPool.h"\ + "..\..\..\Runtime\ClassReader\Attributes.h"\ + "..\..\..\Runtime\ClassReader\ClassReader.h"\ + "..\..\..\Runtime\ClassReader\ConstantPool.h"\ + "..\..\..\Runtime\ClassReader\InfoItem.h"\ + "..\..\..\Runtime\ClassReader\utils.h"\ + "..\..\..\Runtime\FileReader\FileReader.h"\ + "..\..\..\Runtime\FileReader\ZipArchive.h"\ + "..\..\..\Runtime\NativeMethods\NameMangler.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\NativeMethods\NativeMethodDispatcher.h"\ + "..\..\..\Runtime\System\ClassWorld.h"\ + "..\..\..\Runtime\System\Exceptions.h"\ + "..\..\..\Runtime\System\FieldOrMethod.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Runtime\System\JavaString.h"\ + "..\..\..\Runtime\System\JavaVM.h"\ + "..\..\..\Runtime\System\md\x86\x86Win32ExceptionHandler.h"\ + "..\..\..\Runtime\System\Method.h"\ + "..\..\..\Runtime\System\Monitor.h"\ + "..\..\..\Runtime\System\SysCallsRuntime.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\CheckedUnion.h"\ + "..\..\..\Utilities\General\DebugUtils.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FastBitMatrix.h"\ + "..\..\..\Utilities\General\FastBitSet.h"\ + "..\..\..\Utilities\General\FastHashTable.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\InterestingEvents.h"\ + "..\..\..\Utilities\General\JavaBytecodes.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\Nonspr.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + "..\..\..\Utilities\zlib\zconf.h"\ + "..\..\..\Utilities\zlib\zlib.h"\ + +NODEP_CPP_SYSCA=\ + "..\..\..\Compiler\CodeGenerator\md\HPPACpu.h"\ + "..\..\..\Compiler\CodeGenerator\md\PPC601Cpu.h"\ + "..\..\..\Compiler\CodeGenerator\prmon.h"\ + "..\..\..\Compiler\CodeGenerator\prtypes.h"\ + "..\..\..\Debugger\Communication\prio.h"\ + "..\..\..\Debugger\Communication\prlock.h"\ + "..\..\..\Debugger\Communication\prprf.h"\ + "..\..\..\Debugger\nspr.h"\ + "..\..\..\Runtime\ClassReader\prtypes.h"\ + "..\..\..\Runtime\FileReader\prio.h"\ + "..\..\..\Runtime\FileReader\prtypes.h"\ + "..\..\..\Runtime\NativeMethods\prlink.h"\ + "..\..\..\Runtime\System\plstr.h"\ + "..\..\..\Runtime\System\pratom.h"\ + "..\..\..\Runtime\System\prcvar.h"\ + "..\..\..\Runtime\System\prlock.h"\ + "..\..\..\Runtime\System\prprf.h"\ + "..\..\..\Runtime\System\prthread.h"\ + "..\..\..\Runtime\System\prtypes.h"\ + "..\..\..\Utilities\General\plstr.h"\ + "..\..\..\Utilities\General\prbit.h"\ + "..\..\..\Utilities\General\prlog.h"\ + "..\..\..\Utilities\General\prlong.h"\ + + +"$(INTDIR)\SysCallsRuntime.obj" "$(INTDIR)\SysCallsRuntime.sbr" : $(SOURCE)\ + $(DEP_CPP_SYSCA) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "electricalfire - Win32 Debug" + +DEP_CPP_SYSCA=\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\nspr.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\obsolete\protypes.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\plstr.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\pratom.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prbit.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prclist.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcmon.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcpucfg.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcvar.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prdtoa.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prenv.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prerror.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinet.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinit.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinrval.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prio.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlink.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlock.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlog.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlong.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prmem.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prmon.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prnetdb.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prprf.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prproces.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prsystem.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prthread.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtime.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtypes.h"\ + "..\..\..\Compiler\CodeGenerator\ExceptionTable.h"\ + "..\..\..\Compiler\CodeGenerator\FormatStructures.h"\ + "..\..\..\Compiler\CodeGenerator\Instruction.h"\ + "..\..\..\Compiler\CodeGenerator\md\CpuInfo.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Cpu.h"\ + "..\..\..\Compiler\CodeGenerator\NativeCodeCache.h"\ + "..\..\..\Compiler\FrontEnd\BytecodeGraph.h"\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Compiler\FrontEnd\LocalEnv.h"\ + "..\..\..\Compiler\FrontEnd\TranslationEnv.h"\ + "..\..\..\Compiler\FrontEnd\VerificationEnv.h"\ + "..\..\..\Compiler\Optimizer\PrimitiveOptimizer.h"\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlGraph.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlNodes.h"\ + "..\..\..\Compiler\PrimitiveGraph\PrimitiveOperations.h"\ + "..\..\..\Compiler\PrimitiveGraph\Primitives.h"\ + "..\..\..\Compiler\PrimitiveGraph\SysCalls.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Compiler\RegisterAllocator\VirtualRegister.h"\ + "..\..\..\Debugger\Communication\DebuggerChannel.h"\ + "..\..\..\Debugger\Debugger.h"\ + "..\..\..\Runtime\ClassInfo\ClassCentral.h"\ + "..\..\..\Runtime\ClassInfo\ClassFileSummary.h"\ + "..\..\..\Runtime\ClassInfo\Collector.h"\ + "..\..\..\Runtime\ClassInfo\PathComponent.h"\ + "..\..\..\Runtime\ClassInfo\StringPool.h"\ + "..\..\..\Runtime\ClassReader\Attributes.h"\ + "..\..\..\Runtime\ClassReader\ClassReader.h"\ + "..\..\..\Runtime\ClassReader\ConstantPool.h"\ + "..\..\..\Runtime\ClassReader\InfoItem.h"\ + "..\..\..\Runtime\ClassReader\utils.h"\ + "..\..\..\Runtime\FileReader\FileReader.h"\ + "..\..\..\Runtime\FileReader\ZipArchive.h"\ + "..\..\..\Runtime\NativeMethods\NameMangler.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\NativeMethods\NativeMethodDispatcher.h"\ + "..\..\..\Runtime\System\ClassWorld.h"\ + "..\..\..\Runtime\System\Exceptions.h"\ + "..\..\..\Runtime\System\FieldOrMethod.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Runtime\System\JavaString.h"\ + "..\..\..\Runtime\System\JavaVM.h"\ + "..\..\..\Runtime\System\md\x86\x86Win32ExceptionHandler.h"\ + "..\..\..\Runtime\System\Method.h"\ + "..\..\..\Runtime\System\Monitor.h"\ + "..\..\..\Runtime\System\SysCallsRuntime.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\CheckedUnion.h"\ + "..\..\..\Utilities\General\DebugUtils.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FastBitMatrix.h"\ + "..\..\..\Utilities\General\FastBitSet.h"\ + "..\..\..\Utilities\General\FastHashTable.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\InterestingEvents.h"\ + "..\..\..\Utilities\General\JavaBytecodes.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + "..\..\..\Utilities\zlib\zconf.h"\ + "..\..\..\Utilities\zlib\zlib.h"\ + + +"$(INTDIR)\SysCallsRuntime.obj" "$(INTDIR)\SysCallsRuntime.sbr" : $(SOURCE)\ + $(DEP_CPP_SYSCA) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +SOURCE=..\..\..\Runtime\System\Thread.cpp + +!IF "$(CFG)" == "electricalfire - Win32 Release" + +DEP_CPP_THREA=\ + "..\..\..\Compiler\CodeGenerator\ExceptionTable.h"\ + "..\..\..\Compiler\CodeGenerator\FormatStructures.h"\ + "..\..\..\Compiler\CodeGenerator\NativeCodeCache.h"\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Debugger\Communication\DebuggerChannel.h"\ + "..\..\..\Debugger\Debugger.h"\ + "..\..\..\Runtime\ClassInfo\ClassCentral.h"\ + "..\..\..\Runtime\ClassInfo\ClassFileSummary.h"\ + "..\..\..\Runtime\ClassInfo\Collector.h"\ + "..\..\..\Runtime\ClassInfo\PathComponent.h"\ + "..\..\..\Runtime\ClassInfo\StringPool.h"\ + "..\..\..\Runtime\ClassReader\Attributes.h"\ + "..\..\..\Runtime\ClassReader\ClassReader.h"\ + "..\..\..\Runtime\ClassReader\ConstantPool.h"\ + "..\..\..\Runtime\ClassReader\InfoItem.h"\ + "..\..\..\Runtime\ClassReader\utils.h"\ + "..\..\..\Runtime\FileReader\FileReader.h"\ + "..\..\..\Runtime\FileReader\ZipArchive.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\System\ClassWorld.h"\ + "..\..\..\Runtime\System\Exceptions.h"\ + "..\..\..\Runtime\System\FieldOrMethod.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Runtime\System\JavaString.h"\ + "..\..\..\Runtime\System\md\x86\x86LinuxThread.h"\ + "..\..\..\Runtime\System\md\x86\x86Win32ExceptionHandler.h"\ + "..\..\..\Runtime\System\md\x86\x86Win32Thread.h"\ + "..\..\..\Runtime\System\Method.h"\ + "..\..\..\Runtime\System\Monitor.h"\ + "..\..\..\Runtime\System\SysCallsRuntime.h"\ + "..\..\..\Runtime\System\Thread.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FastHashTable.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\InterestingEvents.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\Nonspr.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + "..\..\..\Utilities\zlib\zconf.h"\ + "..\..\..\Utilities\zlib\zlib.h"\ + +NODEP_CPP_THREA=\ + "..\..\..\Compiler\CodeGenerator\prmon.h"\ + "..\..\..\Debugger\Communication\prio.h"\ + "..\..\..\Debugger\Communication\prlock.h"\ + "..\..\..\Debugger\Communication\prprf.h"\ + "..\..\..\Debugger\nspr.h"\ + "..\..\..\Runtime\ClassReader\prtypes.h"\ + "..\..\..\Runtime\FileReader\prio.h"\ + "..\..\..\Runtime\FileReader\prtypes.h"\ + "..\..\..\Runtime\System\plstr.h"\ + "..\..\..\Runtime\System\pratom.h"\ + "..\..\..\Runtime\System\prcvar.h"\ + "..\..\..\Runtime\System\prlock.h"\ + "..\..\..\Runtime\System\prprf.h"\ + "..\..\..\Runtime\System\prthread.h"\ + "..\..\..\Runtime\System\prtypes.h"\ + "..\..\..\Utilities\General\plstr.h"\ + "..\..\..\Utilities\General\prlog.h"\ + "..\..\..\Utilities\General\prlong.h"\ + + +"$(INTDIR)\Thread.obj" "$(INTDIR)\Thread.sbr" : $(SOURCE) $(DEP_CPP_THREA)\ + "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "electricalfire - Win32 Debug" + +DEP_CPP_THREA=\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\nspr.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\obsolete\protypes.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\plstr.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\pratom.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prbit.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prclist.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcmon.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcpucfg.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcvar.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prdtoa.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prenv.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prerror.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinet.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinit.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinrval.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prio.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlink.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlock.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlog.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlong.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prmem.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prmon.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prnetdb.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prprf.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prproces.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prsystem.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prthread.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtime.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtypes.h"\ + "..\..\..\Compiler\CodeGenerator\ExceptionTable.h"\ + "..\..\..\Compiler\CodeGenerator\FormatStructures.h"\ + "..\..\..\Compiler\CodeGenerator\NativeCodeCache.h"\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Debugger\Communication\DebuggerChannel.h"\ + "..\..\..\Debugger\Debugger.h"\ + "..\..\..\Runtime\ClassInfo\ClassCentral.h"\ + "..\..\..\Runtime\ClassInfo\ClassFileSummary.h"\ + "..\..\..\Runtime\ClassInfo\Collector.h"\ + "..\..\..\Runtime\ClassInfo\PathComponent.h"\ + "..\..\..\Runtime\ClassInfo\StringPool.h"\ + "..\..\..\Runtime\ClassReader\Attributes.h"\ + "..\..\..\Runtime\ClassReader\ClassReader.h"\ + "..\..\..\Runtime\ClassReader\ConstantPool.h"\ + "..\..\..\Runtime\ClassReader\InfoItem.h"\ + "..\..\..\Runtime\ClassReader\utils.h"\ + "..\..\..\Runtime\FileReader\FileReader.h"\ + "..\..\..\Runtime\FileReader\ZipArchive.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\System\ClassWorld.h"\ + "..\..\..\Runtime\System\Exceptions.h"\ + "..\..\..\Runtime\System\FieldOrMethod.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Runtime\System\JavaString.h"\ + "..\..\..\Runtime\System\md\x86\x86Win32ExceptionHandler.h"\ + "..\..\..\Runtime\System\md\x86\x86Win32Thread.h"\ + "..\..\..\Runtime\System\Method.h"\ + "..\..\..\Runtime\System\Monitor.h"\ + "..\..\..\Runtime\System\SysCallsRuntime.h"\ + "..\..\..\Runtime\System\Thread.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FastHashTable.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\InterestingEvents.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + "..\..\..\Utilities\zlib\zconf.h"\ + "..\..\..\Utilities\zlib\zlib.h"\ + + +"$(INTDIR)\Thread.obj" "$(INTDIR)\Thread.sbr" : $(SOURCE) $(DEP_CPP_THREA)\ + "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +SOURCE=..\..\..\Utilities\General\CatchAssert.cpp + +!IF "$(CFG)" == "electricalfire - Win32 Release" + +DEP_CPP_CATCH=\ + "..\..\..\Compiler\CodeGenerator\ExceptionTable.h"\ + "..\..\..\Compiler\CodeGenerator\FormatStructures.h"\ + "..\..\..\Compiler\CodeGenerator\Instruction.h"\ + "..\..\..\Compiler\CodeGenerator\InstructionEmitter.h"\ + "..\..\..\Compiler\CodeGenerator\md\CpuInfo.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Formatter.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Opcode.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Cpu.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Emitter.h"\ + "..\..\..\Compiler\CodeGenerator\NativeCodeCache.h"\ + "..\..\..\Compiler\FrontEnd\BytecodeGraph.h"\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Compiler\FrontEnd\LocalEnv.h"\ + "..\..\..\Compiler\FrontEnd\TranslationEnv.h"\ + "..\..\..\Compiler\FrontEnd\VerificationEnv.h"\ + "..\..\..\Compiler\Optimizer\PrimitiveOptimizer.h"\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlGraph.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlNodes.h"\ + "..\..\..\Compiler\PrimitiveGraph\PrimitiveOperations.h"\ + "..\..\..\Compiler\PrimitiveGraph\Primitives.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Compiler\RegisterAllocator\VirtualRegister.h"\ + "..\..\..\Debugger\Communication\DebuggerChannel.h"\ + "..\..\..\Debugger\Debugger.h"\ + "..\..\..\Runtime\ClassInfo\ClassCentral.h"\ + "..\..\..\Runtime\ClassInfo\ClassFileSummary.h"\ + "..\..\..\Runtime\ClassInfo\Collector.h"\ + "..\..\..\Runtime\ClassInfo\PathComponent.h"\ + "..\..\..\Runtime\ClassInfo\StringPool.h"\ + "..\..\..\Runtime\ClassReader\Attributes.h"\ + "..\..\..\Runtime\ClassReader\ClassReader.h"\ + "..\..\..\Runtime\ClassReader\ConstantPool.h"\ + "..\..\..\Runtime\ClassReader\InfoItem.h"\ + "..\..\..\Runtime\ClassReader\utils.h"\ + "..\..\..\Runtime\FileReader\FileReader.h"\ + "..\..\..\Runtime\FileReader\ZipArchive.h"\ + "..\..\..\Runtime\NativeMethods\NameMangler.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\NativeMethods\NativeMethodDispatcher.h"\ + "..\..\..\Runtime\System\ClassWorld.h"\ + "..\..\..\Runtime\System\FieldOrMethod.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Runtime\System\JavaString.h"\ + "..\..\..\Runtime\System\JavaVM.h"\ + "..\..\..\Runtime\System\Method.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\CheckedUnion.h"\ + "..\..\..\Utilities\General\DebugUtils.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FastBitMatrix.h"\ + "..\..\..\Utilities\General\FastBitSet.h"\ + "..\..\..\Utilities\General\FastHashTable.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\InterestingEvents.h"\ + "..\..\..\Utilities\General\JavaBytecodes.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\md\CatchAssert_md.h"\ + "..\..\..\Utilities\General\Nonspr.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + "..\..\..\Utilities\zlib\zconf.h"\ + "..\..\..\Utilities\zlib\zlib.h"\ + +NODEP_CPP_CATCH=\ + "..\..\..\Compiler\CodeGenerator\md\HPPACpu.h"\ + "..\..\..\Compiler\CodeGenerator\md\PPC601Cpu.h"\ + "..\..\..\Compiler\CodeGenerator\prmon.h"\ + "..\..\..\Compiler\CodeGenerator\prtypes.h"\ + "..\..\..\Debugger\Communication\prio.h"\ + "..\..\..\Debugger\Communication\prlock.h"\ + "..\..\..\Debugger\Communication\prprf.h"\ + "..\..\..\Debugger\nspr.h"\ + "..\..\..\Runtime\ClassReader\prtypes.h"\ + "..\..\..\Runtime\FileReader\prio.h"\ + "..\..\..\Runtime\FileReader\prtypes.h"\ + "..\..\..\Runtime\NativeMethods\prlink.h"\ + "..\..\..\Runtime\System\plstr.h"\ + "..\..\..\Runtime\System\prprf.h"\ + "..\..\..\Utilities\General\plstr.h"\ + "..\..\..\Utilities\General\prbit.h"\ + "..\..\..\Utilities\General\prlog.h"\ + "..\..\..\Utilities\General\prlong.h"\ + + +"$(INTDIR)\CatchAssert.obj" "$(INTDIR)\CatchAssert.sbr" : $(SOURCE)\ + $(DEP_CPP_CATCH) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "electricalfire - Win32 Debug" + +DEP_CPP_CATCH=\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\nspr.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\obsolete\protypes.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\plstr.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\pratom.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prbit.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prclist.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcmon.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcpucfg.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcvar.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prdtoa.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prenv.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prerror.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinet.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinit.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinrval.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prio.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlink.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlock.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlog.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlong.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prmem.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prmon.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prnetdb.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prprf.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prproces.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prsystem.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prthread.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtime.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtypes.h"\ + "..\..\..\Compiler\CodeGenerator\ExceptionTable.h"\ + "..\..\..\Compiler\CodeGenerator\FormatStructures.h"\ + "..\..\..\Compiler\CodeGenerator\Instruction.h"\ + "..\..\..\Compiler\CodeGenerator\md\CpuInfo.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Cpu.h"\ + "..\..\..\Compiler\CodeGenerator\NativeCodeCache.h"\ + "..\..\..\Compiler\FrontEnd\BytecodeGraph.h"\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Compiler\FrontEnd\LocalEnv.h"\ + "..\..\..\Compiler\FrontEnd\TranslationEnv.h"\ + "..\..\..\Compiler\FrontEnd\VerificationEnv.h"\ + "..\..\..\Compiler\Optimizer\PrimitiveOptimizer.h"\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlGraph.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlNodes.h"\ + "..\..\..\Compiler\PrimitiveGraph\PrimitiveOperations.h"\ + "..\..\..\Compiler\PrimitiveGraph\Primitives.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Compiler\RegisterAllocator\VirtualRegister.h"\ + "..\..\..\Debugger\Communication\DebuggerChannel.h"\ + "..\..\..\Debugger\Debugger.h"\ + "..\..\..\Runtime\ClassInfo\ClassCentral.h"\ + "..\..\..\Runtime\ClassInfo\ClassFileSummary.h"\ + "..\..\..\Runtime\ClassInfo\Collector.h"\ + "..\..\..\Runtime\ClassInfo\PathComponent.h"\ + "..\..\..\Runtime\ClassInfo\StringPool.h"\ + "..\..\..\Runtime\ClassReader\Attributes.h"\ + "..\..\..\Runtime\ClassReader\ClassReader.h"\ + "..\..\..\Runtime\ClassReader\ConstantPool.h"\ + "..\..\..\Runtime\ClassReader\InfoItem.h"\ + "..\..\..\Runtime\ClassReader\utils.h"\ + "..\..\..\Runtime\FileReader\FileReader.h"\ + "..\..\..\Runtime\FileReader\ZipArchive.h"\ + "..\..\..\Runtime\NativeMethods\NameMangler.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\NativeMethods\NativeMethodDispatcher.h"\ + "..\..\..\Runtime\System\ClassWorld.h"\ + "..\..\..\Runtime\System\FieldOrMethod.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Runtime\System\JavaString.h"\ + "..\..\..\Runtime\System\JavaVM.h"\ + "..\..\..\Runtime\System\Method.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\CheckedUnion.h"\ + "..\..\..\Utilities\General\DebugUtils.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FastBitMatrix.h"\ + "..\..\..\Utilities\General\FastBitSet.h"\ + "..\..\..\Utilities\General\FastHashTable.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\InterestingEvents.h"\ + "..\..\..\Utilities\General\JavaBytecodes.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\md\CatchAssert_md.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + "..\..\..\Utilities\zlib\zconf.h"\ + "..\..\..\Utilities\zlib\zlib.h"\ + + +"$(INTDIR)\CatchAssert.obj" "$(INTDIR)\CatchAssert.sbr" : $(SOURCE)\ + $(DEP_CPP_CATCH) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +SOURCE=..\..\..\Utilities\General\CUtils.cpp + +!IF "$(CFG)" == "electricalfire - Win32 Release" + +DEP_CPP_CUTIL=\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\CUtils.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\Nonspr.h"\ + "..\..\..\Utilities\General\Pool.h"\ + +NODEP_CPP_CUTIL=\ + "..\..\..\Utilities\General\plstr.h"\ + "..\..\..\Utilities\General\prio.h"\ + "..\..\..\Utilities\General\prlog.h"\ + "..\..\..\Utilities\General\prlong.h"\ + + +"$(INTDIR)\CUtils.obj" "$(INTDIR)\CUtils.sbr" : $(SOURCE) $(DEP_CPP_CUTIL)\ + "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "electricalfire - Win32 Debug" + +DEP_CPP_CUTIL=\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\obsolete\protypes.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\plstr.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcpucfg.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinet.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinrval.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prio.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlog.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlong.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtime.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtypes.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\CUtils.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\Pool.h"\ + + +"$(INTDIR)\CUtils.obj" "$(INTDIR)\CUtils.sbr" : $(SOURCE) $(DEP_CPP_CUTIL)\ + "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +SOURCE=..\..\..\Utilities\General\DebugUtils.cpp + +!IF "$(CFG)" == "electricalfire - Win32 Release" + +DEP_CPP_DEBUG=\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\DebugUtils.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\Nonspr.h"\ + +NODEP_CPP_DEBUG=\ + "..\..\..\Utilities\General\plstr.h"\ + "..\..\..\Utilities\General\prlog.h"\ + "..\..\..\Utilities\General\prlong.h"\ + + +"$(INTDIR)\DebugUtils.obj" "$(INTDIR)\DebugUtils.sbr" : $(SOURCE)\ + $(DEP_CPP_DEBUG) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "electricalfire - Win32 Debug" + +DEP_CPP_DEBUG=\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\obsolete\protypes.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcpucfg.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinet.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinrval.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prio.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlog.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlong.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtime.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtypes.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\DebugUtils.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + + +"$(INTDIR)\DebugUtils.obj" "$(INTDIR)\DebugUtils.sbr" : $(SOURCE)\ + $(DEP_CPP_DEBUG) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +SOURCE=..\..\..\Utilities\General\FastBitMatrix.cpp + +!IF "$(CFG)" == "electricalfire - Win32 Release" + +DEP_CPP_FASTB=\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FastBitMatrix.h"\ + "..\..\..\Utilities\General\FastBitSet.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\Nonspr.h"\ + "..\..\..\Utilities\General\Pool.h"\ + +NODEP_CPP_FASTB=\ + "..\..\..\Utilities\General\plstr.h"\ + "..\..\..\Utilities\General\prbit.h"\ + "..\..\..\Utilities\General\prlog.h"\ + "..\..\..\Utilities\General\prlong.h"\ + + +"$(INTDIR)\FastBitMatrix.obj" "$(INTDIR)\FastBitMatrix.sbr" : $(SOURCE)\ + $(DEP_CPP_FASTB) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "electricalfire - Win32 Debug" + +DEP_CPP_FASTB=\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\obsolete\protypes.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prbit.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcpucfg.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinet.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinrval.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prio.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlog.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlong.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtime.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtypes.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FastBitMatrix.h"\ + "..\..\..\Utilities\General\FastBitSet.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\Pool.h"\ + + +"$(INTDIR)\FastBitMatrix.obj" "$(INTDIR)\FastBitMatrix.sbr" : $(SOURCE)\ + $(DEP_CPP_FASTB) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +SOURCE=..\..\..\Utilities\General\FastBitSet.cpp + +!IF "$(CFG)" == "electricalfire - Win32 Release" + +DEP_CPP_FASTBI=\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FastBitSet.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\Nonspr.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + +NODEP_CPP_FASTBI=\ + "..\..\..\Utilities\General\plstr.h"\ + "..\..\..\Utilities\General\prlog.h"\ + "..\..\..\Utilities\General\prlong.h"\ + + +"$(INTDIR)\FastBitSet.obj" "$(INTDIR)\FastBitSet.sbr" : $(SOURCE)\ + $(DEP_CPP_FASTBI) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "electricalfire - Win32 Debug" + +DEP_CPP_FASTBI=\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\obsolete\protypes.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcpucfg.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinet.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinrval.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prio.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlog.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlong.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtime.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtypes.h"\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FastBitSet.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + + +"$(INTDIR)\FastBitSet.obj" "$(INTDIR)\FastBitSet.sbr" : $(SOURCE)\ + $(DEP_CPP_FASTBI) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +SOURCE=..\..\..\Utilities\General\FloatUtils.cpp + +!IF "$(CFG)" == "electricalfire - Win32 Release" + +DEP_CPP_FLOAT=\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\Nonspr.h"\ + +NODEP_CPP_FLOAT=\ + "..\..\..\Utilities\General\plstr.h"\ + "..\..\..\Utilities\General\prlog.h"\ + "..\..\..\Utilities\General\prlong.h"\ + + +"$(INTDIR)\FloatUtils.obj" "$(INTDIR)\FloatUtils.sbr" : $(SOURCE)\ + $(DEP_CPP_FLOAT) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "electricalfire - Win32 Debug" + +DEP_CPP_FLOAT=\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\obsolete\protypes.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcpucfg.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinet.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinrval.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prio.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlog.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlong.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtime.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtypes.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + + +"$(INTDIR)\FloatUtils.obj" "$(INTDIR)\FloatUtils.sbr" : $(SOURCE)\ + $(DEP_CPP_FLOAT) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +SOURCE=..\..\..\Utilities\General\InterestingEvents.cpp + +!IF "$(CFG)" == "electricalfire - Win32 Release" + +DEP_CPP_INTERE=\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\InterestingEvents.h"\ + "..\..\..\Utilities\General\Nonspr.h"\ + "..\..\..\Utilities\General\Vector.h"\ + +NODEP_CPP_INTERE=\ + "..\..\..\Utilities\General\plstr.h"\ + "..\..\..\Utilities\General\prlog.h"\ + "..\..\..\Utilities\General\prlong.h"\ + + +"$(INTDIR)\InterestingEvents.obj" "$(INTDIR)\InterestingEvents.sbr" : $(SOURCE)\ + $(DEP_CPP_INTERE) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "electricalfire - Win32 Debug" + +DEP_CPP_INTERE=\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\obsolete\protypes.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcpucfg.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinet.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinrval.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prio.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlog.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlong.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtime.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtypes.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\InterestingEvents.h"\ + "..\..\..\Utilities\General\Vector.h"\ + + +"$(INTDIR)\InterestingEvents.obj" "$(INTDIR)\InterestingEvents.sbr" : $(SOURCE)\ + $(DEP_CPP_INTERE) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +SOURCE=..\..\..\Utilities\General\JavaBytecodes.cpp + +!IF "$(CFG)" == "electricalfire - Win32 Release" + +DEP_CPP_JAVAB=\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Runtime\ClassReader\Attributes.h"\ + "..\..\..\Runtime\ClassReader\ConstantPool.h"\ + "..\..\..\Runtime\ClassReader\utils.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\DebugUtils.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\JavaBytecodes.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\MemoryAccess.h"\ + "..\..\..\Utilities\General\Nonspr.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + +NODEP_CPP_JAVAB=\ + "..\..\..\Runtime\ClassReader\prtypes.h"\ + "..\..\..\Utilities\General\plstr.h"\ + "..\..\..\Utilities\General\prlog.h"\ + "..\..\..\Utilities\General\prlong.h"\ + + +"$(INTDIR)\JavaBytecodes.obj" "$(INTDIR)\JavaBytecodes.sbr" : $(SOURCE)\ + $(DEP_CPP_JAVAB) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "electricalfire - Win32 Debug" + +DEP_CPP_JAVAB=\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\obsolete\protypes.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcpucfg.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinet.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinrval.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prio.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlog.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlong.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtime.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtypes.h"\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Runtime\ClassReader\Attributes.h"\ + "..\..\..\Runtime\ClassReader\ConstantPool.h"\ + "..\..\..\Runtime\ClassReader\utils.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\DebugUtils.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\JavaBytecodes.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\MemoryAccess.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + + +"$(INTDIR)\JavaBytecodes.obj" "$(INTDIR)\JavaBytecodes.sbr" : $(SOURCE)\ + $(DEP_CPP_JAVAB) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +SOURCE=..\..\..\Utilities\General\LogModule.cpp + +!IF "$(CFG)" == "electricalfire - Win32 Release" + +DEP_CPP_LOGMO=\ + "..\..\..\Utilities\General\LogModule.h"\ + +NODEP_CPP_LOGMO=\ + "..\..\..\Utilities\General\prlog.h"\ + + +"$(INTDIR)\LogModule.obj" "$(INTDIR)\LogModule.sbr" : $(SOURCE)\ + $(DEP_CPP_LOGMO) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "electricalfire - Win32 Debug" + +DEP_CPP_LOGMO=\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\obsolete\protypes.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcpucfg.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinet.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinrval.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prio.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlog.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlong.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtime.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtypes.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + + +"$(INTDIR)\LogModule.obj" "$(INTDIR)\LogModule.sbr" : $(SOURCE)\ + $(DEP_CPP_LOGMO) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +SOURCE=..\..\..\Utilities\General\Pool.cpp + +!IF "$(CFG)" == "electricalfire - Win32 Release" + +DEP_CPP_POOL_=\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\Nonspr.h"\ + "..\..\..\Utilities\General\Pool.h"\ + +NODEP_CPP_POOL_=\ + "..\..\..\Utilities\General\plstr.h"\ + "..\..\..\Utilities\General\prlog.h"\ + "..\..\..\Utilities\General\prlong.h"\ + + +"$(INTDIR)\Pool.obj" "$(INTDIR)\Pool.sbr" : $(SOURCE) $(DEP_CPP_POOL_)\ + "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "electricalfire - Win32 Debug" + +DEP_CPP_POOL_=\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\obsolete\protypes.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcpucfg.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinet.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinrval.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prio.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlog.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlong.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtime.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtypes.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\Pool.h"\ + + +"$(INTDIR)\Pool.obj" "$(INTDIR)\Pool.sbr" : $(SOURCE) $(DEP_CPP_POOL_)\ + "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +SOURCE=..\..\..\Utilities\General\Tree.cpp + +!IF "$(CFG)" == "electricalfire - Win32 Release" + +DEP_CPP_TREE_=\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\Nonspr.h"\ + "..\..\..\Utilities\General\Tree.h"\ + +NODEP_CPP_TREE_=\ + "..\..\..\Utilities\General\plstr.h"\ + "..\..\..\Utilities\General\prlog.h"\ + "..\..\..\Utilities\General\prlong.h"\ + + +"$(INTDIR)\Tree.obj" "$(INTDIR)\Tree.sbr" : $(SOURCE) $(DEP_CPP_TREE_)\ + "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "electricalfire - Win32 Debug" + +DEP_CPP_TREE_=\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\obsolete\protypes.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcpucfg.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinet.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinrval.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prio.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlog.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlong.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtime.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtypes.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\Tree.h"\ + + +"$(INTDIR)\Tree.obj" "$(INTDIR)\Tree.sbr" : $(SOURCE) $(DEP_CPP_TREE_)\ + "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +SOURCE=..\..\..\Utilities\zlib\adler32.c + +!IF "$(CFG)" == "electricalfire - Win32 Release" + +DEP_CPP_ADLER=\ + "..\..\..\Utilities\zlib\zconf.h"\ + "..\..\..\Utilities\zlib\zlib.h"\ + + +"$(INTDIR)\adler32.obj" "$(INTDIR)\adler32.sbr" : $(SOURCE) $(DEP_CPP_ADLER)\ + "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "electricalfire - Win32 Debug" + +DEP_CPP_ADLER=\ + "..\..\..\Utilities\zlib\zconf.h"\ + "..\..\..\Utilities\zlib\zlib.h"\ + + +"$(INTDIR)\adler32.obj" "$(INTDIR)\adler32.sbr" : $(SOURCE) $(DEP_CPP_ADLER)\ + "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +SOURCE=..\..\..\Utilities\zlib\compress.c + +!IF "$(CFG)" == "electricalfire - Win32 Release" + +DEP_CPP_COMPR=\ + "..\..\..\Utilities\zlib\zconf.h"\ + "..\..\..\Utilities\zlib\zlib.h"\ + + +"$(INTDIR)\compress.obj" "$(INTDIR)\compress.sbr" : $(SOURCE) $(DEP_CPP_COMPR)\ + "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "electricalfire - Win32 Debug" + +DEP_CPP_COMPR=\ + "..\..\..\Utilities\zlib\zconf.h"\ + "..\..\..\Utilities\zlib\zlib.h"\ + + +"$(INTDIR)\compress.obj" "$(INTDIR)\compress.sbr" : $(SOURCE) $(DEP_CPP_COMPR)\ + "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +SOURCE=..\..\..\Utilities\zlib\crc32.c + +!IF "$(CFG)" == "electricalfire - Win32 Release" + +DEP_CPP_CRC32=\ + "..\..\..\Utilities\zlib\zconf.h"\ + "..\..\..\Utilities\zlib\zlib.h"\ + + +"$(INTDIR)\crc32.obj" "$(INTDIR)\crc32.sbr" : $(SOURCE) $(DEP_CPP_CRC32)\ + "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "electricalfire - Win32 Debug" + +DEP_CPP_CRC32=\ + "..\..\..\Utilities\zlib\zconf.h"\ + "..\..\..\Utilities\zlib\zlib.h"\ + + +"$(INTDIR)\crc32.obj" "$(INTDIR)\crc32.sbr" : $(SOURCE) $(DEP_CPP_CRC32)\ + "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +SOURCE=..\..\..\Utilities\zlib\deflate.c + +!IF "$(CFG)" == "electricalfire - Win32 Release" + +DEP_CPP_DEFLA=\ + "..\..\..\Utilities\zlib\deflate.h"\ + "..\..\..\Utilities\zlib\zconf.h"\ + "..\..\..\Utilities\zlib\zlib.h"\ + "..\..\..\Utilities\zlib\zutil.h"\ + + +"$(INTDIR)\deflate.obj" "$(INTDIR)\deflate.sbr" : $(SOURCE) $(DEP_CPP_DEFLA)\ + "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "electricalfire - Win32 Debug" + +DEP_CPP_DEFLA=\ + "..\..\..\Utilities\zlib\deflate.h"\ + "..\..\..\Utilities\zlib\zconf.h"\ + "..\..\..\Utilities\zlib\zlib.h"\ + "..\..\..\Utilities\zlib\zutil.h"\ + + +"$(INTDIR)\deflate.obj" "$(INTDIR)\deflate.sbr" : $(SOURCE) $(DEP_CPP_DEFLA)\ + "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +SOURCE=..\..\..\Utilities\zlib\gzio.c +DEP_CPP_GZIO_=\ + "..\..\..\Utilities\zlib\zconf.h"\ + "..\..\..\Utilities\zlib\zlib.h"\ + "..\..\..\Utilities\zlib\zutil.h"\ + + +"$(INTDIR)\gzio.obj" "$(INTDIR)\gzio.sbr" : $(SOURCE) $(DEP_CPP_GZIO_)\ + "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +SOURCE=..\..\..\Utilities\zlib\infblock.c + +!IF "$(CFG)" == "electricalfire - Win32 Release" + +DEP_CPP_INFBL=\ + "..\..\..\Utilities\zlib\infblock.h"\ + "..\..\..\Utilities\zlib\infcodes.h"\ + "..\..\..\Utilities\zlib\inftrees.h"\ + "..\..\..\Utilities\zlib\infutil.h"\ + "..\..\..\Utilities\zlib\zconf.h"\ + "..\..\..\Utilities\zlib\zlib.h"\ + "..\..\..\Utilities\zlib\zutil.h"\ + + +"$(INTDIR)\infblock.obj" "$(INTDIR)\infblock.sbr" : $(SOURCE) $(DEP_CPP_INFBL)\ + "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "electricalfire - Win32 Debug" + +DEP_CPP_INFBL=\ + "..\..\..\Utilities\zlib\infblock.h"\ + "..\..\..\Utilities\zlib\infcodes.h"\ + "..\..\..\Utilities\zlib\inftrees.h"\ + "..\..\..\Utilities\zlib\infutil.h"\ + "..\..\..\Utilities\zlib\zconf.h"\ + "..\..\..\Utilities\zlib\zlib.h"\ + "..\..\..\Utilities\zlib\zutil.h"\ + + +"$(INTDIR)\infblock.obj" "$(INTDIR)\infblock.sbr" : $(SOURCE) $(DEP_CPP_INFBL)\ + "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +SOURCE=..\..\..\Utilities\zlib\infcodes.c + +!IF "$(CFG)" == "electricalfire - Win32 Release" + +DEP_CPP_INFCO=\ + "..\..\..\Utilities\zlib\infblock.h"\ + "..\..\..\Utilities\zlib\infcodes.h"\ + "..\..\..\Utilities\zlib\inffast.h"\ + "..\..\..\Utilities\zlib\inftrees.h"\ + "..\..\..\Utilities\zlib\infutil.h"\ + "..\..\..\Utilities\zlib\zconf.h"\ + "..\..\..\Utilities\zlib\zlib.h"\ + "..\..\..\Utilities\zlib\zutil.h"\ + + +"$(INTDIR)\infcodes.obj" "$(INTDIR)\infcodes.sbr" : $(SOURCE) $(DEP_CPP_INFCO)\ + "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "electricalfire - Win32 Debug" + +DEP_CPP_INFCO=\ + "..\..\..\Utilities\zlib\infblock.h"\ + "..\..\..\Utilities\zlib\infcodes.h"\ + "..\..\..\Utilities\zlib\inffast.h"\ + "..\..\..\Utilities\zlib\inftrees.h"\ + "..\..\..\Utilities\zlib\infutil.h"\ + "..\..\..\Utilities\zlib\zconf.h"\ + "..\..\..\Utilities\zlib\zlib.h"\ + "..\..\..\Utilities\zlib\zutil.h"\ + + +"$(INTDIR)\infcodes.obj" "$(INTDIR)\infcodes.sbr" : $(SOURCE) $(DEP_CPP_INFCO)\ + "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +SOURCE=..\..\..\Utilities\zlib\inffast.c + +!IF "$(CFG)" == "electricalfire - Win32 Release" + +DEP_CPP_INFFA=\ + "..\..\..\Utilities\zlib\infblock.h"\ + "..\..\..\Utilities\zlib\infcodes.h"\ + "..\..\..\Utilities\zlib\inffast.h"\ + "..\..\..\Utilities\zlib\inftrees.h"\ + "..\..\..\Utilities\zlib\infutil.h"\ + "..\..\..\Utilities\zlib\zconf.h"\ + "..\..\..\Utilities\zlib\zlib.h"\ + "..\..\..\Utilities\zlib\zutil.h"\ + + +"$(INTDIR)\inffast.obj" "$(INTDIR)\inffast.sbr" : $(SOURCE) $(DEP_CPP_INFFA)\ + "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "electricalfire - Win32 Debug" + +DEP_CPP_INFFA=\ + "..\..\..\Utilities\zlib\infblock.h"\ + "..\..\..\Utilities\zlib\infcodes.h"\ + "..\..\..\Utilities\zlib\inffast.h"\ + "..\..\..\Utilities\zlib\inftrees.h"\ + "..\..\..\Utilities\zlib\infutil.h"\ + "..\..\..\Utilities\zlib\zconf.h"\ + "..\..\..\Utilities\zlib\zlib.h"\ + "..\..\..\Utilities\zlib\zutil.h"\ + + +"$(INTDIR)\inffast.obj" "$(INTDIR)\inffast.sbr" : $(SOURCE) $(DEP_CPP_INFFA)\ + "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +SOURCE=..\..\..\Utilities\zlib\inflate.c + +!IF "$(CFG)" == "electricalfire - Win32 Release" + +DEP_CPP_INFLA=\ + "..\..\..\Utilities\zlib\infblock.h"\ + "..\..\..\Utilities\zlib\zconf.h"\ + "..\..\..\Utilities\zlib\zlib.h"\ + "..\..\..\Utilities\zlib\zutil.h"\ + + +"$(INTDIR)\inflate.obj" "$(INTDIR)\inflate.sbr" : $(SOURCE) $(DEP_CPP_INFLA)\ + "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "electricalfire - Win32 Debug" + +DEP_CPP_INFLA=\ + "..\..\..\Utilities\zlib\infblock.h"\ + "..\..\..\Utilities\zlib\zconf.h"\ + "..\..\..\Utilities\zlib\zlib.h"\ + "..\..\..\Utilities\zlib\zutil.h"\ + + +"$(INTDIR)\inflate.obj" "$(INTDIR)\inflate.sbr" : $(SOURCE) $(DEP_CPP_INFLA)\ + "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +SOURCE=..\..\..\Utilities\zlib\inftrees.c + +!IF "$(CFG)" == "electricalfire - Win32 Release" + +DEP_CPP_INFTR=\ + "..\..\..\Utilities\zlib\inftrees.h"\ + "..\..\..\Utilities\zlib\zconf.h"\ + "..\..\..\Utilities\zlib\zlib.h"\ + "..\..\..\Utilities\zlib\zutil.h"\ + + +"$(INTDIR)\inftrees.obj" "$(INTDIR)\inftrees.sbr" : $(SOURCE) $(DEP_CPP_INFTR)\ + "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "electricalfire - Win32 Debug" + +DEP_CPP_INFTR=\ + "..\..\..\Utilities\zlib\inftrees.h"\ + "..\..\..\Utilities\zlib\zconf.h"\ + "..\..\..\Utilities\zlib\zlib.h"\ + "..\..\..\Utilities\zlib\zutil.h"\ + + +"$(INTDIR)\inftrees.obj" "$(INTDIR)\inftrees.sbr" : $(SOURCE) $(DEP_CPP_INFTR)\ + "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +SOURCE=..\..\..\Utilities\zlib\infutil.c + +!IF "$(CFG)" == "electricalfire - Win32 Release" + +DEP_CPP_INFUT=\ + "..\..\..\Utilities\zlib\infblock.h"\ + "..\..\..\Utilities\zlib\infcodes.h"\ + "..\..\..\Utilities\zlib\inftrees.h"\ + "..\..\..\Utilities\zlib\infutil.h"\ + "..\..\..\Utilities\zlib\zconf.h"\ + "..\..\..\Utilities\zlib\zlib.h"\ + "..\..\..\Utilities\zlib\zutil.h"\ + + +"$(INTDIR)\infutil.obj" "$(INTDIR)\infutil.sbr" : $(SOURCE) $(DEP_CPP_INFUT)\ + "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "electricalfire - Win32 Debug" + +DEP_CPP_INFUT=\ + "..\..\..\Utilities\zlib\infblock.h"\ + "..\..\..\Utilities\zlib\infcodes.h"\ + "..\..\..\Utilities\zlib\inftrees.h"\ + "..\..\..\Utilities\zlib\infutil.h"\ + "..\..\..\Utilities\zlib\zconf.h"\ + "..\..\..\Utilities\zlib\zlib.h"\ + "..\..\..\Utilities\zlib\zutil.h"\ + + +"$(INTDIR)\infutil.obj" "$(INTDIR)\infutil.sbr" : $(SOURCE) $(DEP_CPP_INFUT)\ + "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +SOURCE=..\..\..\Utilities\zlib\trees.c + +!IF "$(CFG)" == "electricalfire - Win32 Release" + +DEP_CPP_TREES=\ + "..\..\..\Utilities\zlib\deflate.h"\ + "..\..\..\Utilities\zlib\zconf.h"\ + "..\..\..\Utilities\zlib\zlib.h"\ + "..\..\..\Utilities\zlib\zutil.h"\ + + +"$(INTDIR)\trees.obj" "$(INTDIR)\trees.sbr" : $(SOURCE) $(DEP_CPP_TREES)\ + "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "electricalfire - Win32 Debug" + +DEP_CPP_TREES=\ + "..\..\..\Utilities\zlib\deflate.h"\ + "..\..\..\Utilities\zlib\zconf.h"\ + "..\..\..\Utilities\zlib\zlib.h"\ + "..\..\..\Utilities\zlib\zutil.h"\ + + +"$(INTDIR)\trees.obj" "$(INTDIR)\trees.sbr" : $(SOURCE) $(DEP_CPP_TREES)\ + "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +SOURCE=..\..\..\Utilities\zlib\uncompr.c + +!IF "$(CFG)" == "electricalfire - Win32 Release" + +DEP_CPP_UNCOM=\ + "..\..\..\Utilities\zlib\zconf.h"\ + "..\..\..\Utilities\zlib\zlib.h"\ + + +"$(INTDIR)\uncompr.obj" "$(INTDIR)\uncompr.sbr" : $(SOURCE) $(DEP_CPP_UNCOM)\ + "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "electricalfire - Win32 Debug" + +DEP_CPP_UNCOM=\ + "..\..\..\Utilities\zlib\zconf.h"\ + "..\..\..\Utilities\zlib\zlib.h"\ + + +"$(INTDIR)\uncompr.obj" "$(INTDIR)\uncompr.sbr" : $(SOURCE) $(DEP_CPP_UNCOM)\ + "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +SOURCE=..\..\..\Utilities\zlib\zutil.c +DEP_CPP_ZUTIL=\ + "..\..\..\Utilities\zlib\zconf.h"\ + "..\..\..\Utilities\zlib\zlib.h"\ + "..\..\..\Utilities\zlib\zutil.h"\ + + +"$(INTDIR)\zutil.obj" "$(INTDIR)\zutil.sbr" : $(SOURCE) $(DEP_CPP_ZUTIL)\ + "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +SOURCE=..\..\..\Compiler\FrontEnd\BytecodeGraph.cpp + +!IF "$(CFG)" == "electricalfire - Win32 Release" + +DEP_CPP_BYTEC=\ + "..\..\..\Compiler\CodeGenerator\FormatStructures.h"\ + "..\..\..\Compiler\CodeGenerator\Instruction.h"\ + "..\..\..\Compiler\CodeGenerator\InstructionEmitter.h"\ + "..\..\..\Compiler\CodeGenerator\md\CpuInfo.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Formatter.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Opcode.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Cpu.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Emitter.h"\ + "..\..\..\Compiler\FrontEnd\BytecodeGraph.h"\ + "..\..\..\Compiler\FrontEnd\BytecodeVerifier.h"\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Compiler\FrontEnd\LocalEnv.h"\ + "..\..\..\Compiler\FrontEnd\TranslationEnv.h"\ + "..\..\..\Compiler\FrontEnd\VerificationEnv.h"\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlGraph.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlNodes.h"\ + "..\..\..\Compiler\PrimitiveGraph\PrimitiveOperations.h"\ + "..\..\..\Compiler\PrimitiveGraph\Primitives.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Compiler\RegisterAllocator\VirtualRegister.h"\ + "..\..\..\Runtime\ClassInfo\ClassFileSummary.h"\ + "..\..\..\Runtime\ClassInfo\Collector.h"\ + "..\..\..\Runtime\ClassInfo\StringPool.h"\ + "..\..\..\Runtime\ClassReader\Attributes.h"\ + "..\..\..\Runtime\ClassReader\ClassReader.h"\ + "..\..\..\Runtime\ClassReader\ConstantPool.h"\ + "..\..\..\Runtime\ClassReader\InfoItem.h"\ + "..\..\..\Runtime\ClassReader\utils.h"\ + "..\..\..\Runtime\FileReader\FileReader.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\System\ClassWorld.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Runtime\System\JavaString.h"\ + "..\..\..\Runtime\System\Method.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\CheckedUnion.h"\ + "..\..\..\Utilities\General\DebugUtils.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FastBitMatrix.h"\ + "..\..\..\Utilities\General\FastBitSet.h"\ + "..\..\..\Utilities\General\FastHashTable.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\GraphUtils.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\JavaBytecodes.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\MemoryAccess.h"\ + "..\..\..\Utilities\General\Nonspr.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Tree.h"\ + "..\..\..\Utilities\General\Vector.h"\ + +NODEP_CPP_BYTEC=\ + "..\..\..\Compiler\CodeGenerator\md\HPPACpu.h"\ + "..\..\..\Compiler\CodeGenerator\md\PPC601Cpu.h"\ + "..\..\..\Compiler\CodeGenerator\prtypes.h"\ + "..\..\..\Runtime\ClassReader\prtypes.h"\ + "..\..\..\Runtime\FileReader\prio.h"\ + "..\..\..\Runtime\FileReader\prtypes.h"\ + "..\..\..\Utilities\General\plstr.h"\ + "..\..\..\Utilities\General\prbit.h"\ + "..\..\..\Utilities\General\prlog.h"\ + "..\..\..\Utilities\General\prlong.h"\ + + +"$(INTDIR)\BytecodeGraph.obj" "$(INTDIR)\BytecodeGraph.sbr" : $(SOURCE)\ + $(DEP_CPP_BYTEC) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "electricalfire - Win32 Debug" + +DEP_CPP_BYTEC=\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\obsolete\protypes.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prbit.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcpucfg.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinet.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinrval.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prio.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlog.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlong.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtime.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtypes.h"\ + "..\..\..\Compiler\CodeGenerator\Instruction.h"\ + "..\..\..\Compiler\CodeGenerator\md\CpuInfo.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Cpu.h"\ + "..\..\..\Compiler\FrontEnd\BytecodeGraph.h"\ + "..\..\..\Compiler\FrontEnd\BytecodeVerifier.h"\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Compiler\FrontEnd\LocalEnv.h"\ + "..\..\..\Compiler\FrontEnd\TranslationEnv.h"\ + "..\..\..\Compiler\FrontEnd\VerificationEnv.h"\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlGraph.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlNodes.h"\ + "..\..\..\Compiler\PrimitiveGraph\PrimitiveOperations.h"\ + "..\..\..\Compiler\PrimitiveGraph\Primitives.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Compiler\RegisterAllocator\VirtualRegister.h"\ + "..\..\..\Runtime\ClassInfo\ClassFileSummary.h"\ + "..\..\..\Runtime\ClassInfo\Collector.h"\ + "..\..\..\Runtime\ClassInfo\StringPool.h"\ + "..\..\..\Runtime\ClassReader\Attributes.h"\ + "..\..\..\Runtime\ClassReader\ClassReader.h"\ + "..\..\..\Runtime\ClassReader\ConstantPool.h"\ + "..\..\..\Runtime\ClassReader\InfoItem.h"\ + "..\..\..\Runtime\ClassReader\utils.h"\ + "..\..\..\Runtime\FileReader\FileReader.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\System\ClassWorld.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Runtime\System\JavaString.h"\ + "..\..\..\Runtime\System\Method.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\CheckedUnion.h"\ + "..\..\..\Utilities\General\DebugUtils.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FastBitMatrix.h"\ + "..\..\..\Utilities\General\FastBitSet.h"\ + "..\..\..\Utilities\General\FastHashTable.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\GraphUtils.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\JavaBytecodes.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\MemoryAccess.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Tree.h"\ + "..\..\..\Utilities\General\Vector.h"\ + + +"$(INTDIR)\BytecodeGraph.obj" "$(INTDIR)\BytecodeGraph.sbr" : $(SOURCE)\ + $(DEP_CPP_BYTEC) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +SOURCE=..\..\..\Compiler\FrontEnd\BytecodeTranslator.cpp + +!IF "$(CFG)" == "electricalfire - Win32 Release" + +DEP_CPP_BYTECO=\ + "..\..\..\Compiler\CodeGenerator\FormatStructures.h"\ + "..\..\..\Compiler\CodeGenerator\Instruction.h"\ + "..\..\..\Compiler\CodeGenerator\InstructionEmitter.h"\ + "..\..\..\Compiler\CodeGenerator\md\CpuInfo.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Formatter.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Opcode.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Cpu.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Emitter.h"\ + "..\..\..\Compiler\FrontEnd\BytecodeGraph.h"\ + "..\..\..\Compiler\FrontEnd\BytecodeTranslator.h"\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Compiler\FrontEnd\LocalEnv.h"\ + "..\..\..\Compiler\FrontEnd\TranslationEnv.h"\ + "..\..\..\Compiler\FrontEnd\VerificationEnv.h"\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlGraph.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlNodes.h"\ + "..\..\..\Compiler\PrimitiveGraph\PrimitiveBuilders.h"\ + "..\..\..\Compiler\PrimitiveGraph\PrimitiveOperations.h"\ + "..\..\..\Compiler\PrimitiveGraph\Primitives.h"\ + "..\..\..\Compiler\PrimitiveGraph\SysCalls.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Compiler\RegisterAllocator\VirtualRegister.h"\ + "..\..\..\Debugger\Communication\DebuggerChannel.h"\ + "..\..\..\Debugger\Debugger.h"\ + "..\..\..\Runtime\ClassInfo\ClassCentral.h"\ + "..\..\..\Runtime\ClassInfo\ClassFileSummary.h"\ + "..\..\..\Runtime\ClassInfo\Collector.h"\ + "..\..\..\Runtime\ClassInfo\PathComponent.h"\ + "..\..\..\Runtime\ClassInfo\StringPool.h"\ + "..\..\..\Runtime\ClassReader\Attributes.h"\ + "..\..\..\Runtime\ClassReader\ClassReader.h"\ + "..\..\..\Runtime\ClassReader\ConstantPool.h"\ + "..\..\..\Runtime\ClassReader\InfoItem.h"\ + "..\..\..\Runtime\ClassReader\utils.h"\ + "..\..\..\Runtime\FileReader\FileReader.h"\ + "..\..\..\Runtime\FileReader\ZipArchive.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\System\ClassWorld.h"\ + "..\..\..\Runtime\System\FieldOrMethod.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Runtime\System\JavaString.h"\ + "..\..\..\Runtime\System\Method.h"\ + "..\..\..\Runtime\System\SysCallsRuntime.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\CheckedUnion.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FastBitMatrix.h"\ + "..\..\..\Utilities\General\FastBitSet.h"\ + "..\..\..\Utilities\General\FastHashTable.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\InterestingEvents.h"\ + "..\..\..\Utilities\General\JavaBytecodes.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\MemoryAccess.h"\ + "..\..\..\Utilities\General\Nonspr.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + "..\..\..\Utilities\zlib\zconf.h"\ + "..\..\..\Utilities\zlib\zlib.h"\ + +NODEP_CPP_BYTECO=\ + "..\..\..\Compiler\CodeGenerator\md\HPPACpu.h"\ + "..\..\..\Compiler\CodeGenerator\md\PPC601Cpu.h"\ + "..\..\..\Compiler\CodeGenerator\prtypes.h"\ + "..\..\..\Debugger\Communication\prio.h"\ + "..\..\..\Debugger\Communication\prlock.h"\ + "..\..\..\Debugger\Communication\prprf.h"\ + "..\..\..\Debugger\nspr.h"\ + "..\..\..\Runtime\ClassReader\prtypes.h"\ + "..\..\..\Runtime\FileReader\prio.h"\ + "..\..\..\Runtime\FileReader\prtypes.h"\ + "..\..\..\Runtime\System\plstr.h"\ + "..\..\..\Utilities\General\plstr.h"\ + "..\..\..\Utilities\General\prbit.h"\ + "..\..\..\Utilities\General\prlog.h"\ + "..\..\..\Utilities\General\prlong.h"\ + + +"$(INTDIR)\BytecodeTranslator.obj" "$(INTDIR)\BytecodeTranslator.sbr" : \ +$(SOURCE) $(DEP_CPP_BYTECO) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "electricalfire - Win32 Debug" + +DEP_CPP_BYTECO=\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\nspr.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\obsolete\protypes.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\plstr.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\pratom.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prbit.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prclist.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcmon.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcpucfg.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcvar.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prdtoa.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prenv.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prerror.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinet.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinit.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinrval.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prio.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlink.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlock.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlog.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlong.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prmem.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prmon.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prnetdb.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prprf.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prproces.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prsystem.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prthread.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtime.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtypes.h"\ + "..\..\..\Compiler\CodeGenerator\Instruction.h"\ + "..\..\..\Compiler\CodeGenerator\md\CpuInfo.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Cpu.h"\ + "..\..\..\Compiler\FrontEnd\BytecodeGraph.h"\ + "..\..\..\Compiler\FrontEnd\BytecodeTranslator.h"\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Compiler\FrontEnd\LocalEnv.h"\ + "..\..\..\Compiler\FrontEnd\TranslationEnv.h"\ + "..\..\..\Compiler\FrontEnd\VerificationEnv.h"\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlGraph.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlNodes.h"\ + "..\..\..\Compiler\PrimitiveGraph\PrimitiveBuilders.h"\ + "..\..\..\Compiler\PrimitiveGraph\PrimitiveOperations.h"\ + "..\..\..\Compiler\PrimitiveGraph\Primitives.h"\ + "..\..\..\Compiler\PrimitiveGraph\SysCalls.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Compiler\RegisterAllocator\VirtualRegister.h"\ + "..\..\..\Debugger\Communication\DebuggerChannel.h"\ + "..\..\..\Debugger\Debugger.h"\ + "..\..\..\Runtime\ClassInfo\ClassCentral.h"\ + "..\..\..\Runtime\ClassInfo\ClassFileSummary.h"\ + "..\..\..\Runtime\ClassInfo\Collector.h"\ + "..\..\..\Runtime\ClassInfo\PathComponent.h"\ + "..\..\..\Runtime\ClassInfo\StringPool.h"\ + "..\..\..\Runtime\ClassReader\Attributes.h"\ + "..\..\..\Runtime\ClassReader\ClassReader.h"\ + "..\..\..\Runtime\ClassReader\ConstantPool.h"\ + "..\..\..\Runtime\ClassReader\InfoItem.h"\ + "..\..\..\Runtime\ClassReader\utils.h"\ + "..\..\..\Runtime\FileReader\FileReader.h"\ + "..\..\..\Runtime\FileReader\ZipArchive.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\System\ClassWorld.h"\ + "..\..\..\Runtime\System\FieldOrMethod.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Runtime\System\JavaString.h"\ + "..\..\..\Runtime\System\Method.h"\ + "..\..\..\Runtime\System\SysCallsRuntime.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\CheckedUnion.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FastBitMatrix.h"\ + "..\..\..\Utilities\General\FastBitSet.h"\ + "..\..\..\Utilities\General\FastHashTable.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\InterestingEvents.h"\ + "..\..\..\Utilities\General\JavaBytecodes.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\MemoryAccess.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + "..\..\..\Utilities\zlib\zconf.h"\ + "..\..\..\Utilities\zlib\zlib.h"\ + + +"$(INTDIR)\BytecodeTranslator.obj" "$(INTDIR)\BytecodeTranslator.sbr" : \ +$(SOURCE) $(DEP_CPP_BYTECO) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +SOURCE=..\..\..\Compiler\FrontEnd\BytecodeVerifier.cpp + +!IF "$(CFG)" == "electricalfire - Win32 Release" + +DEP_CPP_BYTECOD=\ + "..\..\..\Compiler\CodeGenerator\FormatStructures.h"\ + "..\..\..\Compiler\CodeGenerator\Instruction.h"\ + "..\..\..\Compiler\CodeGenerator\InstructionEmitter.h"\ + "..\..\..\Compiler\CodeGenerator\md\CpuInfo.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Formatter.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Opcode.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Cpu.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Emitter.h"\ + "..\..\..\Compiler\FrontEnd\BytecodeGraph.h"\ + "..\..\..\Compiler\FrontEnd\BytecodeVerifier.h"\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Compiler\FrontEnd\LocalEnv.h"\ + "..\..\..\Compiler\FrontEnd\TranslationEnv.h"\ + "..\..\..\Compiler\FrontEnd\VerificationEnv.h"\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlGraph.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlNodes.h"\ + "..\..\..\Compiler\PrimitiveGraph\PrimitiveOperations.h"\ + "..\..\..\Compiler\PrimitiveGraph\Primitives.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Compiler\RegisterAllocator\VirtualRegister.h"\ + "..\..\..\Debugger\Communication\DebuggerChannel.h"\ + "..\..\..\Debugger\Debugger.h"\ + "..\..\..\Runtime\ClassInfo\ClassCentral.h"\ + "..\..\..\Runtime\ClassInfo\ClassFileSummary.h"\ + "..\..\..\Runtime\ClassInfo\Collector.h"\ + "..\..\..\Runtime\ClassInfo\PathComponent.h"\ + "..\..\..\Runtime\ClassInfo\StringPool.h"\ + "..\..\..\Runtime\ClassReader\Attributes.h"\ + "..\..\..\Runtime\ClassReader\ClassReader.h"\ + "..\..\..\Runtime\ClassReader\ConstantPool.h"\ + "..\..\..\Runtime\ClassReader\InfoItem.h"\ + "..\..\..\Runtime\ClassReader\utils.h"\ + "..\..\..\Runtime\FileReader\FileReader.h"\ + "..\..\..\Runtime\FileReader\ZipArchive.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\System\ClassWorld.h"\ + "..\..\..\Runtime\System\FieldOrMethod.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Runtime\System\JavaString.h"\ + "..\..\..\Runtime\System\Method.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\CheckedUnion.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FastBitMatrix.h"\ + "..\..\..\Utilities\General\FastBitSet.h"\ + "..\..\..\Utilities\General\FastHashTable.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\GraphUtils.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\InterestingEvents.h"\ + "..\..\..\Utilities\General\JavaBytecodes.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\MemoryAccess.h"\ + "..\..\..\Utilities\General\Nonspr.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Tree.h"\ + "..\..\..\Utilities\General\Vector.h"\ + "..\..\..\Utilities\zlib\zconf.h"\ + "..\..\..\Utilities\zlib\zlib.h"\ + +NODEP_CPP_BYTECOD=\ + "..\..\..\Compiler\CodeGenerator\md\HPPACpu.h"\ + "..\..\..\Compiler\CodeGenerator\md\PPC601Cpu.h"\ + "..\..\..\Compiler\CodeGenerator\prtypes.h"\ + "..\..\..\Debugger\Communication\prio.h"\ + "..\..\..\Debugger\Communication\prlock.h"\ + "..\..\..\Debugger\Communication\prprf.h"\ + "..\..\..\Debugger\nspr.h"\ + "..\..\..\Runtime\ClassReader\prtypes.h"\ + "..\..\..\Runtime\FileReader\prio.h"\ + "..\..\..\Runtime\FileReader\prtypes.h"\ + "..\..\..\Runtime\System\plstr.h"\ + "..\..\..\Utilities\General\plstr.h"\ + "..\..\..\Utilities\General\prbit.h"\ + "..\..\..\Utilities\General\prlog.h"\ + "..\..\..\Utilities\General\prlong.h"\ + + +"$(INTDIR)\BytecodeVerifier.obj" "$(INTDIR)\BytecodeVerifier.sbr" : $(SOURCE)\ + $(DEP_CPP_BYTECOD) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "electricalfire - Win32 Debug" + +DEP_CPP_BYTECOD=\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\nspr.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\obsolete\protypes.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\plstr.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\pratom.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prbit.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prclist.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcmon.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcpucfg.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcvar.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prdtoa.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prenv.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prerror.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinet.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinit.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinrval.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prio.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlink.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlock.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlog.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlong.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prmem.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prmon.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prnetdb.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prprf.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prproces.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prsystem.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prthread.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtime.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtypes.h"\ + "..\..\..\Compiler\CodeGenerator\Instruction.h"\ + "..\..\..\Compiler\CodeGenerator\md\CpuInfo.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Cpu.h"\ + "..\..\..\Compiler\FrontEnd\BytecodeGraph.h"\ + "..\..\..\Compiler\FrontEnd\BytecodeVerifier.h"\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Compiler\FrontEnd\LocalEnv.h"\ + "..\..\..\Compiler\FrontEnd\TranslationEnv.h"\ + "..\..\..\Compiler\FrontEnd\VerificationEnv.h"\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlGraph.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlNodes.h"\ + "..\..\..\Compiler\PrimitiveGraph\PrimitiveOperations.h"\ + "..\..\..\Compiler\PrimitiveGraph\Primitives.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Compiler\RegisterAllocator\VirtualRegister.h"\ + "..\..\..\Debugger\Communication\DebuggerChannel.h"\ + "..\..\..\Debugger\Debugger.h"\ + "..\..\..\Runtime\ClassInfo\ClassCentral.h"\ + "..\..\..\Runtime\ClassInfo\ClassFileSummary.h"\ + "..\..\..\Runtime\ClassInfo\Collector.h"\ + "..\..\..\Runtime\ClassInfo\PathComponent.h"\ + "..\..\..\Runtime\ClassInfo\StringPool.h"\ + "..\..\..\Runtime\ClassReader\Attributes.h"\ + "..\..\..\Runtime\ClassReader\ClassReader.h"\ + "..\..\..\Runtime\ClassReader\ConstantPool.h"\ + "..\..\..\Runtime\ClassReader\InfoItem.h"\ + "..\..\..\Runtime\ClassReader\utils.h"\ + "..\..\..\Runtime\FileReader\FileReader.h"\ + "..\..\..\Runtime\FileReader\ZipArchive.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\System\ClassWorld.h"\ + "..\..\..\Runtime\System\FieldOrMethod.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Runtime\System\JavaString.h"\ + "..\..\..\Runtime\System\Method.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\CheckedUnion.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FastBitMatrix.h"\ + "..\..\..\Utilities\General\FastBitSet.h"\ + "..\..\..\Utilities\General\FastHashTable.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\GraphUtils.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\InterestingEvents.h"\ + "..\..\..\Utilities\General\JavaBytecodes.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\MemoryAccess.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Tree.h"\ + "..\..\..\Utilities\General\Vector.h"\ + "..\..\..\Utilities\zlib\zconf.h"\ + "..\..\..\Utilities\zlib\zlib.h"\ + + +"$(INTDIR)\BytecodeVerifier.obj" "$(INTDIR)\BytecodeVerifier.sbr" : $(SOURCE)\ + $(DEP_CPP_BYTECOD) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +SOURCE=..\..\..\Compiler\FrontEnd\ErrorHandling.cpp + +!IF "$(CFG)" == "electricalfire - Win32 Release" + +DEP_CPP_ERROR=\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\Nonspr.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + +NODEP_CPP_ERROR=\ + "..\..\..\Utilities\General\plstr.h"\ + "..\..\..\Utilities\General\prlog.h"\ + "..\..\..\Utilities\General\prlong.h"\ + + +"$(INTDIR)\ErrorHandling.obj" "$(INTDIR)\ErrorHandling.sbr" : $(SOURCE)\ + $(DEP_CPP_ERROR) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "electricalfire - Win32 Debug" + +DEP_CPP_ERROR=\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\obsolete\protypes.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcpucfg.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinet.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinrval.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prio.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlog.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlong.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtime.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtypes.h"\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + + +"$(INTDIR)\ErrorHandling.obj" "$(INTDIR)\ErrorHandling.sbr" : $(SOURCE)\ + $(DEP_CPP_ERROR) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +SOURCE=..\..\..\Compiler\FrontEnd\TranslationEnv.cpp + +!IF "$(CFG)" == "electricalfire - Win32 Release" + +DEP_CPP_TRANS=\ + "..\..\..\Compiler\CodeGenerator\FormatStructures.h"\ + "..\..\..\Compiler\CodeGenerator\Instruction.h"\ + "..\..\..\Compiler\CodeGenerator\InstructionEmitter.h"\ + "..\..\..\Compiler\CodeGenerator\md\CpuInfo.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Formatter.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Opcode.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Cpu.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Emitter.h"\ + "..\..\..\Compiler\FrontEnd\BytecodeGraph.h"\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Compiler\FrontEnd\LocalEnv.h"\ + "..\..\..\Compiler\FrontEnd\TranslationEnv.h"\ + "..\..\..\Compiler\FrontEnd\VerificationEnv.h"\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlGraph.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlNodes.h"\ + "..\..\..\Compiler\PrimitiveGraph\PrimitiveOperations.h"\ + "..\..\..\Compiler\PrimitiveGraph\Primitives.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Compiler\RegisterAllocator\VirtualRegister.h"\ + "..\..\..\Runtime\ClassInfo\ClassFileSummary.h"\ + "..\..\..\Runtime\ClassInfo\Collector.h"\ + "..\..\..\Runtime\ClassInfo\StringPool.h"\ + "..\..\..\Runtime\ClassReader\Attributes.h"\ + "..\..\..\Runtime\ClassReader\ClassReader.h"\ + "..\..\..\Runtime\ClassReader\ConstantPool.h"\ + "..\..\..\Runtime\ClassReader\InfoItem.h"\ + "..\..\..\Runtime\ClassReader\utils.h"\ + "..\..\..\Runtime\FileReader\FileReader.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\System\ClassWorld.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Runtime\System\JavaString.h"\ + "..\..\..\Runtime\System\Method.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\CheckedUnion.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FastBitMatrix.h"\ + "..\..\..\Utilities\General\FastBitSet.h"\ + "..\..\..\Utilities\General\FastHashTable.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\JavaBytecodes.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\Nonspr.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + +NODEP_CPP_TRANS=\ + "..\..\..\Compiler\CodeGenerator\md\HPPACpu.h"\ + "..\..\..\Compiler\CodeGenerator\md\PPC601Cpu.h"\ + "..\..\..\Compiler\CodeGenerator\prtypes.h"\ + "..\..\..\Runtime\ClassReader\prtypes.h"\ + "..\..\..\Runtime\FileReader\prio.h"\ + "..\..\..\Runtime\FileReader\prtypes.h"\ + "..\..\..\Utilities\General\plstr.h"\ + "..\..\..\Utilities\General\prbit.h"\ + "..\..\..\Utilities\General\prlog.h"\ + "..\..\..\Utilities\General\prlong.h"\ + + +"$(INTDIR)\TranslationEnv.obj" "$(INTDIR)\TranslationEnv.sbr" : $(SOURCE)\ + $(DEP_CPP_TRANS) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "electricalfire - Win32 Debug" + +DEP_CPP_TRANS=\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\obsolete\protypes.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prbit.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcpucfg.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinet.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinrval.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prio.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlog.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlong.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtime.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtypes.h"\ + "..\..\..\Compiler\CodeGenerator\Instruction.h"\ + "..\..\..\Compiler\CodeGenerator\md\CpuInfo.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Cpu.h"\ + "..\..\..\Compiler\FrontEnd\BytecodeGraph.h"\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Compiler\FrontEnd\LocalEnv.h"\ + "..\..\..\Compiler\FrontEnd\TranslationEnv.h"\ + "..\..\..\Compiler\FrontEnd\VerificationEnv.h"\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlGraph.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlNodes.h"\ + "..\..\..\Compiler\PrimitiveGraph\PrimitiveOperations.h"\ + "..\..\..\Compiler\PrimitiveGraph\Primitives.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Compiler\RegisterAllocator\VirtualRegister.h"\ + "..\..\..\Runtime\ClassInfo\ClassFileSummary.h"\ + "..\..\..\Runtime\ClassInfo\Collector.h"\ + "..\..\..\Runtime\ClassInfo\StringPool.h"\ + "..\..\..\Runtime\ClassReader\Attributes.h"\ + "..\..\..\Runtime\ClassReader\ClassReader.h"\ + "..\..\..\Runtime\ClassReader\ConstantPool.h"\ + "..\..\..\Runtime\ClassReader\InfoItem.h"\ + "..\..\..\Runtime\ClassReader\utils.h"\ + "..\..\..\Runtime\FileReader\FileReader.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\System\ClassWorld.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Runtime\System\JavaString.h"\ + "..\..\..\Runtime\System\Method.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\CheckedUnion.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FastBitMatrix.h"\ + "..\..\..\Utilities\General\FastBitSet.h"\ + "..\..\..\Utilities\General\FastHashTable.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\JavaBytecodes.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + + +"$(INTDIR)\TranslationEnv.obj" "$(INTDIR)\TranslationEnv.sbr" : $(SOURCE)\ + $(DEP_CPP_TRANS) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +SOURCE=..\..\..\Compiler\FrontEnd\VerificationEnv.cpp + +!IF "$(CFG)" == "electricalfire - Win32 Release" + +DEP_CPP_VERIF=\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Compiler\FrontEnd\LocalEnv.h"\ + "..\..\..\Compiler\FrontEnd\VerificationEnv.h"\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\Nonspr.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + +NODEP_CPP_VERIF=\ + "..\..\..\Utilities\General\plstr.h"\ + "..\..\..\Utilities\General\prlog.h"\ + "..\..\..\Utilities\General\prlong.h"\ + + +"$(INTDIR)\VerificationEnv.obj" "$(INTDIR)\VerificationEnv.sbr" : $(SOURCE)\ + $(DEP_CPP_VERIF) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "electricalfire - Win32 Debug" + +DEP_CPP_VERIF=\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\obsolete\protypes.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcpucfg.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinet.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinrval.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prio.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlog.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlong.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtime.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtypes.h"\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Compiler\FrontEnd\LocalEnv.h"\ + "..\..\..\Compiler\FrontEnd\VerificationEnv.h"\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + + +"$(INTDIR)\VerificationEnv.obj" "$(INTDIR)\VerificationEnv.sbr" : $(SOURCE)\ + $(DEP_CPP_VERIF) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +SOURCE=..\..\..\Utilities\Disassemblers\x86\XDisAsm.c +DEP_CPP_XDISA=\ + "..\..\..\Utilities\Disassemblers\x86\XDisAsm.h"\ + + +"$(INTDIR)\XDisAsm.obj" "$(INTDIR)\XDisAsm.sbr" : $(SOURCE) $(DEP_CPP_XDISA)\ + "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +SOURCE=..\..\..\Utilities\Disassemblers\x86\XDisAsmTable.c + +"$(INTDIR)\XDisAsmTable.obj" "$(INTDIR)\XDisAsmTable.sbr" : $(SOURCE)\ + "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +SOURCE="..\..\..\Compiler\CodeGenerator\md\x86\x86-win32.nad" + +!IF "$(CFG)" == "electricalfire - Win32 Release" + +InputPath=..\..\..\Compiler\CodeGenerator\md\x86\x86-win32.nad +InputName=x86-win32 + +"genfiles\$(InputName).nad.burg.cpp" "genfiles\$(InputName).nad.burg.h"\ + "genfiles\PrimitiveOperations.h" "genfiles\PrimitiveOperations.cpp" : \ +$(SOURCE) "$(INTDIR)" "$(OUTDIR)" + $(NSTOOLS)\perl5\perl ..\..\..\tools\nad\nad.pl $(InputPath)\ + ..\..\..\Compiler\PrimitiveGraph\PrimitiveOperations\ + genfiles\PrimitiveOperations.h genfiles\PrimitiveOperations.cpp\ + genfiles\$(InputName).nad.burg.h | Burg\Release\burg -I >\ + genfiles\$(InputName).nad.burg.cpp + +!ELSEIF "$(CFG)" == "electricalfire - Win32 Debug" + +InputPath=..\..\..\Compiler\CodeGenerator\md\x86\x86-win32.nad +InputName=x86-win32 + +"genfiles\$(InputName).nad.burg.cpp" "genfiles\$(InputName).nad.burg.h" : \ +$(SOURCE) "$(INTDIR)" "$(OUTDIR)" + $(NSTOOLS)\perl5\perl ..\..\..\tools\nad\nad.pl $(InputPath)\ + ..\..\..\Compiler\PrimitiveGraph\PrimitiveOperations\ + genfiles\PrimitiveOperations.h genfiles\PrimitiveOperations.cpp\ + genfiles\$(InputName).nad.burg.h | Burg\Debug\burg -I >\ + genfiles\$(InputName).nad.burg.cpp + +!ENDIF + +SOURCE=..\..\..\Compiler\CodeGenerator\md\x86\x86ArgumentList.cpp + +!IF "$(CFG)" == "electricalfire - Win32 Release" + +DEP_CPP_X86AR=\ + "..\..\..\Compiler\CodeGenerator\ExceptionTable.h"\ + "..\..\..\Compiler\CodeGenerator\FormatStructures.h"\ + "..\..\..\Compiler\CodeGenerator\Instruction.h"\ + "..\..\..\Compiler\CodeGenerator\InstructionEmitter.h"\ + "..\..\..\Compiler\CodeGenerator\md\CpuInfo.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86ArgumentList.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Formatter.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Opcode.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Cpu.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Emitter.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Instruction.h"\ + "..\..\..\Compiler\CodeGenerator\NativeCodeCache.h"\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlNodes.h"\ + "..\..\..\Compiler\PrimitiveGraph\PrimitiveOperations.h"\ + "..\..\..\Compiler\PrimitiveGraph\Primitives.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Compiler\RegisterAllocator\VirtualRegister.h"\ + "..\..\..\Debugger\Communication\DebuggerChannel.h"\ + "..\..\..\Debugger\Debugger.h"\ + "..\..\..\Runtime\ClassInfo\ClassCentral.h"\ + "..\..\..\Runtime\ClassInfo\ClassFileSummary.h"\ + "..\..\..\Runtime\ClassInfo\Collector.h"\ + "..\..\..\Runtime\ClassInfo\PathComponent.h"\ + "..\..\..\Runtime\ClassInfo\StringPool.h"\ + "..\..\..\Runtime\ClassReader\Attributes.h"\ + "..\..\..\Runtime\ClassReader\ClassReader.h"\ + "..\..\..\Runtime\ClassReader\ConstantPool.h"\ + "..\..\..\Runtime\ClassReader\InfoItem.h"\ + "..\..\..\Runtime\ClassReader\utils.h"\ + "..\..\..\Runtime\FileReader\FileReader.h"\ + "..\..\..\Runtime\FileReader\ZipArchive.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\System\ClassWorld.h"\ + "..\..\..\Runtime\System\FieldOrMethod.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Runtime\System\JavaString.h"\ + "..\..\..\Runtime\System\Method.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FastBitMatrix.h"\ + "..\..\..\Utilities\General\FastBitSet.h"\ + "..\..\..\Utilities\General\FastHashTable.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\InterestingEvents.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\MemoryAccess.h"\ + "..\..\..\Utilities\General\Nonspr.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + "..\..\..\Utilities\zlib\zconf.h"\ + "..\..\..\Utilities\zlib\zlib.h"\ + +NODEP_CPP_X86AR=\ + "..\..\..\Compiler\CodeGenerator\md\HPPACpu.h"\ + "..\..\..\Compiler\CodeGenerator\md\PPC601Cpu.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\prtypes.h"\ + "..\..\..\Compiler\CodeGenerator\prmon.h"\ + "..\..\..\Compiler\CodeGenerator\prtypes.h"\ + "..\..\..\Debugger\Communication\prio.h"\ + "..\..\..\Debugger\Communication\prlock.h"\ + "..\..\..\Debugger\Communication\prprf.h"\ + "..\..\..\Debugger\nspr.h"\ + "..\..\..\Runtime\ClassReader\prtypes.h"\ + "..\..\..\Runtime\FileReader\prio.h"\ + "..\..\..\Runtime\FileReader\prtypes.h"\ + "..\..\..\Runtime\System\plstr.h"\ + "..\..\..\Utilities\General\plstr.h"\ + "..\..\..\Utilities\General\prbit.h"\ + "..\..\..\Utilities\General\prlog.h"\ + "..\..\..\Utilities\General\prlong.h"\ + + +"$(INTDIR)\x86ArgumentList.obj" "$(INTDIR)\x86ArgumentList.sbr" : $(SOURCE)\ + $(DEP_CPP_X86AR) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "electricalfire - Win32 Debug" + +DEP_CPP_X86AR=\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\nspr.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\obsolete\protypes.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\plstr.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\pratom.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prbit.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prclist.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcmon.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcpucfg.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcvar.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prdtoa.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prenv.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prerror.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinet.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinit.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinrval.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prio.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlink.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlock.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlog.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlong.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prmem.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prmon.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prnetdb.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prprf.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prproces.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prsystem.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prthread.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtime.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtypes.h"\ + "..\..\..\Compiler\CodeGenerator\ExceptionTable.h"\ + "..\..\..\Compiler\CodeGenerator\FormatStructures.h"\ + "..\..\..\Compiler\CodeGenerator\Instruction.h"\ + "..\..\..\Compiler\CodeGenerator\InstructionEmitter.h"\ + "..\..\..\Compiler\CodeGenerator\md\CpuInfo.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86ArgumentList.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Formatter.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Opcode.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Cpu.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Emitter.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Instruction.h"\ + "..\..\..\Compiler\CodeGenerator\NativeCodeCache.h"\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlNodes.h"\ + "..\..\..\Compiler\PrimitiveGraph\PrimitiveOperations.h"\ + "..\..\..\Compiler\PrimitiveGraph\Primitives.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Compiler\RegisterAllocator\VirtualRegister.h"\ + "..\..\..\Debugger\Communication\DebuggerChannel.h"\ + "..\..\..\Debugger\Debugger.h"\ + "..\..\..\Runtime\ClassInfo\ClassCentral.h"\ + "..\..\..\Runtime\ClassInfo\ClassFileSummary.h"\ + "..\..\..\Runtime\ClassInfo\Collector.h"\ + "..\..\..\Runtime\ClassInfo\PathComponent.h"\ + "..\..\..\Runtime\ClassInfo\StringPool.h"\ + "..\..\..\Runtime\ClassReader\Attributes.h"\ + "..\..\..\Runtime\ClassReader\ClassReader.h"\ + "..\..\..\Runtime\ClassReader\ConstantPool.h"\ + "..\..\..\Runtime\ClassReader\InfoItem.h"\ + "..\..\..\Runtime\ClassReader\utils.h"\ + "..\..\..\Runtime\FileReader\FileReader.h"\ + "..\..\..\Runtime\FileReader\ZipArchive.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\System\ClassWorld.h"\ + "..\..\..\Runtime\System\FieldOrMethod.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Runtime\System\JavaString.h"\ + "..\..\..\Runtime\System\Method.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FastBitMatrix.h"\ + "..\..\..\Utilities\General\FastBitSet.h"\ + "..\..\..\Utilities\General\FastHashTable.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\InterestingEvents.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\MemoryAccess.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + "..\..\..\Utilities\zlib\zconf.h"\ + "..\..\..\Utilities\zlib\zlib.h"\ + + +"$(INTDIR)\x86ArgumentList.obj" "$(INTDIR)\x86ArgumentList.sbr" : $(SOURCE)\ + $(DEP_CPP_X86AR) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +SOURCE=..\..\..\Compiler\CodeGenerator\md\x86\x86Float.cpp + +!IF "$(CFG)" == "electricalfire - Win32 Release" + +DEP_CPP_X86FL=\ + "..\..\..\Compiler\CodeGenerator\ExceptionTable.h"\ + "..\..\..\Compiler\CodeGenerator\FormatStructures.h"\ + "..\..\..\Compiler\CodeGenerator\Instruction.h"\ + "..\..\..\Compiler\CodeGenerator\InstructionEmitter.h"\ + "..\..\..\Compiler\CodeGenerator\md\CpuInfo.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86ArgumentList.h"\ + "..\..\..\compiler\codegenerator\md\x86\x86float.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Formatter.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Opcode.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Cpu.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Emitter.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Instruction.h"\ + "..\..\..\Compiler\CodeGenerator\NativeCodeCache.h"\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlNodes.h"\ + "..\..\..\Compiler\PrimitiveGraph\PrimitiveOperations.h"\ + "..\..\..\Compiler\PrimitiveGraph\Primitives.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Compiler\RegisterAllocator\VirtualRegister.h"\ + "..\..\..\Debugger\Communication\DebuggerChannel.h"\ + "..\..\..\Debugger\Debugger.h"\ + "..\..\..\Runtime\ClassInfo\ClassCentral.h"\ + "..\..\..\Runtime\ClassInfo\ClassFileSummary.h"\ + "..\..\..\Runtime\ClassInfo\Collector.h"\ + "..\..\..\Runtime\ClassInfo\PathComponent.h"\ + "..\..\..\Runtime\ClassInfo\StringPool.h"\ + "..\..\..\Runtime\ClassReader\Attributes.h"\ + "..\..\..\Runtime\ClassReader\ClassReader.h"\ + "..\..\..\Runtime\ClassReader\ConstantPool.h"\ + "..\..\..\Runtime\ClassReader\InfoItem.h"\ + "..\..\..\Runtime\ClassReader\utils.h"\ + "..\..\..\Runtime\FileReader\FileReader.h"\ + "..\..\..\Runtime\FileReader\ZipArchive.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\System\ClassWorld.h"\ + "..\..\..\Runtime\System\FieldOrMethod.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Runtime\System\JavaString.h"\ + "..\..\..\Runtime\System\Method.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FastBitMatrix.h"\ + "..\..\..\Utilities\General\FastBitSet.h"\ + "..\..\..\Utilities\General\FastHashTable.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\InterestingEvents.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\MemoryAccess.h"\ + "..\..\..\Utilities\General\Nonspr.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + "..\..\..\Utilities\zlib\zconf.h"\ + "..\..\..\Utilities\zlib\zlib.h"\ + +NODEP_CPP_X86FL=\ + "..\..\..\Compiler\CodeGenerator\md\HPPACpu.h"\ + "..\..\..\Compiler\CodeGenerator\md\PPC601Cpu.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\prtypes.h"\ + "..\..\..\Compiler\CodeGenerator\prmon.h"\ + "..\..\..\Compiler\CodeGenerator\prtypes.h"\ + "..\..\..\Debugger\Communication\prio.h"\ + "..\..\..\Debugger\Communication\prlock.h"\ + "..\..\..\Debugger\Communication\prprf.h"\ + "..\..\..\Debugger\nspr.h"\ + "..\..\..\Runtime\ClassReader\prtypes.h"\ + "..\..\..\Runtime\FileReader\prio.h"\ + "..\..\..\Runtime\FileReader\prtypes.h"\ + "..\..\..\Runtime\System\plstr.h"\ + "..\..\..\Utilities\General\plstr.h"\ + "..\..\..\Utilities\General\prbit.h"\ + "..\..\..\Utilities\General\prlog.h"\ + "..\..\..\Utilities\General\prlong.h"\ + + +"$(INTDIR)\x86Float.obj" "$(INTDIR)\x86Float.sbr" : $(SOURCE) $(DEP_CPP_X86FL)\ + "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "electricalfire - Win32 Debug" + +DEP_CPP_X86FL=\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\nspr.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\obsolete\protypes.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\plstr.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\pratom.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prbit.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prclist.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcmon.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcpucfg.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcvar.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prdtoa.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prenv.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prerror.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinet.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinit.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinrval.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prio.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlink.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlock.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlog.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlong.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prmem.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prmon.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prnetdb.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prprf.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prproces.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prsystem.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prthread.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtime.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtypes.h"\ + "..\..\..\Compiler\CodeGenerator\ExceptionTable.h"\ + "..\..\..\Compiler\CodeGenerator\FormatStructures.h"\ + "..\..\..\Compiler\CodeGenerator\Instruction.h"\ + "..\..\..\Compiler\CodeGenerator\InstructionEmitter.h"\ + "..\..\..\Compiler\CodeGenerator\md\CpuInfo.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86ArgumentList.h"\ + "..\..\..\compiler\codegenerator\md\x86\x86float.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Opcode.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Cpu.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Emitter.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Instruction.h"\ + "..\..\..\Compiler\CodeGenerator\NativeCodeCache.h"\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlNodes.h"\ + "..\..\..\Compiler\PrimitiveGraph\PrimitiveOperations.h"\ + "..\..\..\Compiler\PrimitiveGraph\Primitives.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Compiler\RegisterAllocator\VirtualRegister.h"\ + "..\..\..\Debugger\Communication\DebuggerChannel.h"\ + "..\..\..\Debugger\Debugger.h"\ + "..\..\..\Runtime\ClassInfo\ClassCentral.h"\ + "..\..\..\Runtime\ClassInfo\ClassFileSummary.h"\ + "..\..\..\Runtime\ClassInfo\Collector.h"\ + "..\..\..\Runtime\ClassInfo\PathComponent.h"\ + "..\..\..\Runtime\ClassInfo\StringPool.h"\ + "..\..\..\Runtime\ClassReader\Attributes.h"\ + "..\..\..\Runtime\ClassReader\ClassReader.h"\ + "..\..\..\Runtime\ClassReader\ConstantPool.h"\ + "..\..\..\Runtime\ClassReader\InfoItem.h"\ + "..\..\..\Runtime\ClassReader\utils.h"\ + "..\..\..\Runtime\FileReader\FileReader.h"\ + "..\..\..\Runtime\FileReader\ZipArchive.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\System\ClassWorld.h"\ + "..\..\..\Runtime\System\FieldOrMethod.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Runtime\System\JavaString.h"\ + "..\..\..\Runtime\System\Method.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FastBitMatrix.h"\ + "..\..\..\Utilities\General\FastBitSet.h"\ + "..\..\..\Utilities\General\FastHashTable.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\InterestingEvents.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\MemoryAccess.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + "..\..\..\Utilities\zlib\zconf.h"\ + "..\..\..\Utilities\zlib\zlib.h"\ + + +"$(INTDIR)\x86Float.obj" "$(INTDIR)\x86Float.sbr" : $(SOURCE) $(DEP_CPP_X86FL)\ + "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +SOURCE=..\..\..\Compiler\CodeGenerator\md\x86\x86Formatter.cpp + +!IF "$(CFG)" == "electricalfire - Win32 Release" + +DEP_CPP_X86FO=\ + "..\..\..\Compiler\CodeGenerator\FormatStructures.h"\ + "..\..\..\Compiler\CodeGenerator\Instruction.h"\ + "..\..\..\Compiler\CodeGenerator\InstructionEmitter.h"\ + "..\..\..\Compiler\CodeGenerator\md\CpuInfo.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Formatter.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Opcode.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Cpu.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Emitter.h"\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlNodes.h"\ + "..\..\..\Compiler\PrimitiveGraph\PrimitiveOperations.h"\ + "..\..\..\Compiler\PrimitiveGraph\Primitives.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Compiler\RegisterAllocator\VirtualRegister.h"\ + "..\..\..\Debugger\Communication\DebuggerChannel.h"\ + "..\..\..\Debugger\Debugger.h"\ + "..\..\..\Runtime\ClassInfo\ClassCentral.h"\ + "..\..\..\Runtime\ClassInfo\ClassFileSummary.h"\ + "..\..\..\Runtime\ClassInfo\Collector.h"\ + "..\..\..\Runtime\ClassInfo\PathComponent.h"\ + "..\..\..\Runtime\ClassInfo\StringPool.h"\ + "..\..\..\Runtime\ClassReader\Attributes.h"\ + "..\..\..\Runtime\ClassReader\ClassReader.h"\ + "..\..\..\Runtime\ClassReader\ConstantPool.h"\ + "..\..\..\Runtime\ClassReader\InfoItem.h"\ + "..\..\..\Runtime\ClassReader\utils.h"\ + "..\..\..\Runtime\FileReader\FileReader.h"\ + "..\..\..\Runtime\FileReader\ZipArchive.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\System\ClassWorld.h"\ + "..\..\..\Runtime\System\FieldOrMethod.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Runtime\System\JavaString.h"\ + "..\..\..\Runtime\System\Method.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FastBitMatrix.h"\ + "..\..\..\Utilities\General\FastBitSet.h"\ + "..\..\..\Utilities\General\FastHashTable.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\InterestingEvents.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\MemoryAccess.h"\ + "..\..\..\Utilities\General\Nonspr.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + "..\..\..\Utilities\zlib\zconf.h"\ + "..\..\..\Utilities\zlib\zlib.h"\ + +NODEP_CPP_X86FO=\ + "..\..\..\Compiler\CodeGenerator\md\HPPACpu.h"\ + "..\..\..\Compiler\CodeGenerator\md\PPC601Cpu.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\XDisAsm.h"\ + "..\..\..\Compiler\CodeGenerator\prtypes.h"\ + "..\..\..\Debugger\Communication\prio.h"\ + "..\..\..\Debugger\Communication\prlock.h"\ + "..\..\..\Debugger\Communication\prprf.h"\ + "..\..\..\Debugger\nspr.h"\ + "..\..\..\Runtime\ClassReader\prtypes.h"\ + "..\..\..\Runtime\FileReader\prio.h"\ + "..\..\..\Runtime\FileReader\prtypes.h"\ + "..\..\..\Runtime\System\plstr.h"\ + "..\..\..\Utilities\General\plstr.h"\ + "..\..\..\Utilities\General\prbit.h"\ + "..\..\..\Utilities\General\prlog.h"\ + "..\..\..\Utilities\General\prlong.h"\ + + +"$(INTDIR)\x86Formatter.obj" "$(INTDIR)\x86Formatter.sbr" : $(SOURCE)\ + $(DEP_CPP_X86FO) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "electricalfire - Win32 Debug" + +DEP_CPP_X86FO=\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\nspr.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\obsolete\protypes.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\plstr.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\pratom.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prbit.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prclist.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcmon.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcpucfg.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcvar.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prdtoa.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prenv.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prerror.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinet.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinit.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinrval.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prio.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlink.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlock.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlog.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlong.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prmem.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prmon.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prnetdb.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prprf.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prproces.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prsystem.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prthread.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtime.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtypes.h"\ + "..\..\..\Compiler\CodeGenerator\FormatStructures.h"\ + "..\..\..\Compiler\CodeGenerator\Instruction.h"\ + "..\..\..\Compiler\CodeGenerator\InstructionEmitter.h"\ + "..\..\..\Compiler\CodeGenerator\md\CpuInfo.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Formatter.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Opcode.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Cpu.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Emitter.h"\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlNodes.h"\ + "..\..\..\Compiler\PrimitiveGraph\PrimitiveOperations.h"\ + "..\..\..\Compiler\PrimitiveGraph\Primitives.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Compiler\RegisterAllocator\VirtualRegister.h"\ + "..\..\..\Debugger\Communication\DebuggerChannel.h"\ + "..\..\..\Debugger\Debugger.h"\ + "..\..\..\Runtime\ClassInfo\ClassCentral.h"\ + "..\..\..\Runtime\ClassInfo\ClassFileSummary.h"\ + "..\..\..\Runtime\ClassInfo\Collector.h"\ + "..\..\..\Runtime\ClassInfo\PathComponent.h"\ + "..\..\..\Runtime\ClassInfo\StringPool.h"\ + "..\..\..\Runtime\ClassReader\Attributes.h"\ + "..\..\..\Runtime\ClassReader\ClassReader.h"\ + "..\..\..\Runtime\ClassReader\ConstantPool.h"\ + "..\..\..\Runtime\ClassReader\InfoItem.h"\ + "..\..\..\Runtime\ClassReader\utils.h"\ + "..\..\..\Runtime\FileReader\FileReader.h"\ + "..\..\..\Runtime\FileReader\ZipArchive.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\System\ClassWorld.h"\ + "..\..\..\Runtime\System\FieldOrMethod.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Runtime\System\JavaString.h"\ + "..\..\..\Runtime\System\Method.h"\ + "..\..\..\Utilities\Disassemblers\x86\XDisAsm.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FastBitMatrix.h"\ + "..\..\..\Utilities\General\FastBitSet.h"\ + "..\..\..\Utilities\General\FastHashTable.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\InterestingEvents.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\MemoryAccess.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + "..\..\..\Utilities\zlib\zconf.h"\ + "..\..\..\Utilities\zlib\zlib.h"\ + + +"$(INTDIR)\x86Formatter.obj" "$(INTDIR)\x86Formatter.sbr" : $(SOURCE)\ + $(DEP_CPP_X86FO) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +SOURCE=..\..\..\Compiler\CodeGenerator\md\x86\x86Opcode.cpp + +!IF "$(CFG)" == "electricalfire - Win32 Release" + +DEP_CPP_X86OP=\ + "..\..\..\Compiler\CodeGenerator\FormatStructures.h"\ + "..\..\..\Compiler\CodeGenerator\Instruction.h"\ + "..\..\..\Compiler\CodeGenerator\InstructionEmitter.h"\ + "..\..\..\Compiler\CodeGenerator\md\CpuInfo.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86ArgumentList.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Formatter.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Opcode.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Cpu.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Emitter.h"\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlNodes.h"\ + "..\..\..\Compiler\PrimitiveGraph\PrimitiveOperations.h"\ + "..\..\..\Compiler\PrimitiveGraph\Primitives.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Compiler\RegisterAllocator\VirtualRegister.h"\ + "..\..\..\Runtime\ClassReader\Attributes.h"\ + "..\..\..\Runtime\ClassReader\ConstantPool.h"\ + "..\..\..\Runtime\ClassReader\utils.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\System\ClassWorld.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FastBitMatrix.h"\ + "..\..\..\Utilities\General\FastBitSet.h"\ + "..\..\..\Utilities\General\FastHashTable.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\MemoryAccess.h"\ + "..\..\..\Utilities\General\Nonspr.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + +NODEP_CPP_X86OP=\ + "..\..\..\Compiler\CodeGenerator\md\HPPACpu.h"\ + "..\..\..\Compiler\CodeGenerator\md\PPC601Cpu.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\prtypes.h"\ + "..\..\..\Compiler\CodeGenerator\prtypes.h"\ + "..\..\..\Runtime\ClassReader\prtypes.h"\ + "..\..\..\Utilities\General\plstr.h"\ + "..\..\..\Utilities\General\prbit.h"\ + "..\..\..\Utilities\General\prlog.h"\ + "..\..\..\Utilities\General\prlong.h"\ + + +"$(INTDIR)\x86Opcode.obj" "$(INTDIR)\x86Opcode.sbr" : $(SOURCE)\ + $(DEP_CPP_X86OP) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "electricalfire - Win32 Debug" + +DEP_CPP_X86OP=\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\obsolete\protypes.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prbit.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcpucfg.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinet.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinrval.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prio.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlog.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlong.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtime.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtypes.h"\ + "..\..\..\Compiler\CodeGenerator\Instruction.h"\ + "..\..\..\Compiler\CodeGenerator\md\CpuInfo.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86ArgumentList.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Opcode.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Cpu.h"\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlNodes.h"\ + "..\..\..\Compiler\PrimitiveGraph\PrimitiveOperations.h"\ + "..\..\..\Compiler\PrimitiveGraph\Primitives.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Compiler\RegisterAllocator\VirtualRegister.h"\ + "..\..\..\Runtime\ClassReader\Attributes.h"\ + "..\..\..\Runtime\ClassReader\ConstantPool.h"\ + "..\..\..\Runtime\ClassReader\utils.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\System\ClassWorld.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FastBitMatrix.h"\ + "..\..\..\Utilities\General\FastBitSet.h"\ + "..\..\..\Utilities\General\FastHashTable.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\MemoryAccess.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + + +"$(INTDIR)\x86Opcode.obj" "$(INTDIR)\x86Opcode.sbr" : $(SOURCE)\ + $(DEP_CPP_X86OP) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +SOURCE=..\..\..\Compiler\CodeGenerator\md\x86\x86StdCall.cpp + +!IF "$(CFG)" == "electricalfire - Win32 Release" + +DEP_CPP_X86ST=\ + "..\..\..\Compiler\CodeGenerator\ExceptionTable.h"\ + "..\..\..\Compiler\CodeGenerator\FormatStructures.h"\ + "..\..\..\Compiler\CodeGenerator\Instruction.h"\ + "..\..\..\Compiler\CodeGenerator\InstructionEmitter.h"\ + "..\..\..\Compiler\CodeGenerator\md\CpuInfo.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86ArgumentList.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Formatter.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Opcode.h"\ + "..\..\..\compiler\codegenerator\md\x86\x86stdcall.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Cpu.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Emitter.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Instruction.h"\ + "..\..\..\Compiler\CodeGenerator\NativeCodeCache.h"\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlNodes.h"\ + "..\..\..\Compiler\PrimitiveGraph\PrimitiveOperations.h"\ + "..\..\..\Compiler\PrimitiveGraph\Primitives.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Compiler\RegisterAllocator\VirtualRegister.h"\ + "..\..\..\Debugger\Communication\DebuggerChannel.h"\ + "..\..\..\Debugger\Debugger.h"\ + "..\..\..\Runtime\ClassInfo\ClassCentral.h"\ + "..\..\..\Runtime\ClassInfo\ClassFileSummary.h"\ + "..\..\..\Runtime\ClassInfo\Collector.h"\ + "..\..\..\Runtime\ClassInfo\PathComponent.h"\ + "..\..\..\Runtime\ClassInfo\StringPool.h"\ + "..\..\..\Runtime\ClassReader\Attributes.h"\ + "..\..\..\Runtime\ClassReader\ClassReader.h"\ + "..\..\..\Runtime\ClassReader\ConstantPool.h"\ + "..\..\..\Runtime\ClassReader\InfoItem.h"\ + "..\..\..\Runtime\ClassReader\utils.h"\ + "..\..\..\Runtime\FileReader\FileReader.h"\ + "..\..\..\Runtime\FileReader\ZipArchive.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\System\ClassWorld.h"\ + "..\..\..\Runtime\System\FieldOrMethod.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Runtime\System\JavaString.h"\ + "..\..\..\Runtime\System\Method.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FastBitMatrix.h"\ + "..\..\..\Utilities\General\FastBitSet.h"\ + "..\..\..\Utilities\General\FastHashTable.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\InterestingEvents.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\MemoryAccess.h"\ + "..\..\..\Utilities\General\Nonspr.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + "..\..\..\Utilities\zlib\zconf.h"\ + "..\..\..\Utilities\zlib\zlib.h"\ + +NODEP_CPP_X86ST=\ + "..\..\..\Compiler\CodeGenerator\md\HPPACpu.h"\ + "..\..\..\Compiler\CodeGenerator\md\PPC601Cpu.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\prtypes.h"\ + "..\..\..\Compiler\CodeGenerator\prmon.h"\ + "..\..\..\Compiler\CodeGenerator\prtypes.h"\ + "..\..\..\Debugger\Communication\prio.h"\ + "..\..\..\Debugger\Communication\prlock.h"\ + "..\..\..\Debugger\Communication\prprf.h"\ + "..\..\..\Debugger\nspr.h"\ + "..\..\..\Runtime\ClassReader\prtypes.h"\ + "..\..\..\Runtime\FileReader\prio.h"\ + "..\..\..\Runtime\FileReader\prtypes.h"\ + "..\..\..\Runtime\System\plstr.h"\ + "..\..\..\Utilities\General\plstr.h"\ + "..\..\..\Utilities\General\prbit.h"\ + "..\..\..\Utilities\General\prlog.h"\ + "..\..\..\Utilities\General\prlong.h"\ + + +"$(INTDIR)\x86StdCall.obj" "$(INTDIR)\x86StdCall.sbr" : $(SOURCE)\ + $(DEP_CPP_X86ST) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "electricalfire - Win32 Debug" + +DEP_CPP_X86ST=\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\nspr.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\obsolete\protypes.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\plstr.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\pratom.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prbit.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prclist.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcmon.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcpucfg.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcvar.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prdtoa.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prenv.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prerror.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinet.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinit.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinrval.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prio.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlink.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlock.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlog.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlong.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prmem.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prmon.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prnetdb.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prprf.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prproces.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prsystem.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prthread.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtime.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtypes.h"\ + "..\..\..\Compiler\CodeGenerator\ExceptionTable.h"\ + "..\..\..\Compiler\CodeGenerator\FormatStructures.h"\ + "..\..\..\Compiler\CodeGenerator\Instruction.h"\ + "..\..\..\Compiler\CodeGenerator\InstructionEmitter.h"\ + "..\..\..\Compiler\CodeGenerator\md\CpuInfo.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86ArgumentList.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Opcode.h"\ + "..\..\..\compiler\codegenerator\md\x86\x86stdcall.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Cpu.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Emitter.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Instruction.h"\ + "..\..\..\Compiler\CodeGenerator\NativeCodeCache.h"\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlNodes.h"\ + "..\..\..\Compiler\PrimitiveGraph\PrimitiveOperations.h"\ + "..\..\..\Compiler\PrimitiveGraph\Primitives.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Compiler\RegisterAllocator\VirtualRegister.h"\ + "..\..\..\Debugger\Communication\DebuggerChannel.h"\ + "..\..\..\Debugger\Debugger.h"\ + "..\..\..\Runtime\ClassInfo\ClassCentral.h"\ + "..\..\..\Runtime\ClassInfo\ClassFileSummary.h"\ + "..\..\..\Runtime\ClassInfo\Collector.h"\ + "..\..\..\Runtime\ClassInfo\PathComponent.h"\ + "..\..\..\Runtime\ClassInfo\StringPool.h"\ + "..\..\..\Runtime\ClassReader\Attributes.h"\ + "..\..\..\Runtime\ClassReader\ClassReader.h"\ + "..\..\..\Runtime\ClassReader\ConstantPool.h"\ + "..\..\..\Runtime\ClassReader\InfoItem.h"\ + "..\..\..\Runtime\ClassReader\utils.h"\ + "..\..\..\Runtime\FileReader\FileReader.h"\ + "..\..\..\Runtime\FileReader\ZipArchive.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\System\ClassWorld.h"\ + "..\..\..\Runtime\System\FieldOrMethod.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Runtime\System\JavaString.h"\ + "..\..\..\Runtime\System\Method.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FastBitMatrix.h"\ + "..\..\..\Utilities\General\FastBitSet.h"\ + "..\..\..\Utilities\General\FastHashTable.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\InterestingEvents.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\MemoryAccess.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + "..\..\..\Utilities\zlib\zconf.h"\ + "..\..\..\Utilities\zlib\zlib.h"\ + + +"$(INTDIR)\x86StdCall.obj" "$(INTDIR)\x86StdCall.sbr" : $(SOURCE)\ + $(DEP_CPP_X86ST) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +SOURCE=..\..\..\Compiler\CodeGenerator\md\x86\x86Win32_Support.cpp + +!IF "$(CFG)" == "electricalfire - Win32 Release" + +DEP_CPP_X86WIN3=\ + "..\..\..\Compiler\CodeGenerator\ExceptionTable.h"\ + "..\..\..\Compiler\CodeGenerator\FormatStructures.h"\ + "..\..\..\Compiler\CodeGenerator\NativeCodeCache.h"\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Debugger\Communication\DebuggerChannel.h"\ + "..\..\..\Debugger\Debugger.h"\ + "..\..\..\Runtime\ClassInfo\ClassCentral.h"\ + "..\..\..\Runtime\ClassInfo\ClassFileSummary.h"\ + "..\..\..\Runtime\ClassInfo\Collector.h"\ + "..\..\..\Runtime\ClassInfo\PathComponent.h"\ + "..\..\..\Runtime\ClassInfo\StringPool.h"\ + "..\..\..\Runtime\ClassReader\Attributes.h"\ + "..\..\..\Runtime\ClassReader\ClassReader.h"\ + "..\..\..\Runtime\ClassReader\ConstantPool.h"\ + "..\..\..\Runtime\ClassReader\InfoItem.h"\ + "..\..\..\Runtime\ClassReader\utils.h"\ + "..\..\..\Runtime\FileReader\FileReader.h"\ + "..\..\..\Runtime\FileReader\ZipArchive.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\System\ClassWorld.h"\ + "..\..\..\Runtime\System\FieldOrMethod.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Runtime\System\JavaString.h"\ + "..\..\..\Runtime\System\Method.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FastHashTable.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\InterestingEvents.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\MemoryAccess.h"\ + "..\..\..\Utilities\General\Nonspr.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + "..\..\..\Utilities\zlib\zconf.h"\ + "..\..\..\Utilities\zlib\zlib.h"\ + +NODEP_CPP_X86WIN3=\ + "..\..\..\Compiler\CodeGenerator\prmon.h"\ + "..\..\..\Debugger\Communication\prio.h"\ + "..\..\..\Debugger\Communication\prlock.h"\ + "..\..\..\Debugger\Communication\prprf.h"\ + "..\..\..\Debugger\nspr.h"\ + "..\..\..\Runtime\ClassReader\prtypes.h"\ + "..\..\..\Runtime\FileReader\prio.h"\ + "..\..\..\Runtime\FileReader\prtypes.h"\ + "..\..\..\Runtime\System\plstr.h"\ + "..\..\..\Utilities\General\plstr.h"\ + "..\..\..\Utilities\General\prlog.h"\ + "..\..\..\Utilities\General\prlong.h"\ + +CPP_SWITCHES=/nologo /ML /W3 /GX /I "..\..\..\Exports" /I "..\..\..\Exports\md"\ + /I "..\..\..\Utilities\General" /I "..\..\..\Utilities\General\md" /I\ + "..\..\..\Compiler\FrontEnd" /I "..\..\..\Compiler\PrimitiveGraph" /I\ + "..\..\..\Runtime\System\md\x86" /I "..\..\..\..\dist\WINNT4.0_DBG.OBJ\include"\ + /I "..\..\..\Utilities\zlib" /I "..\..\..\Runtime\ClassInfo" /I\ + "..\..\..\Runtime\ClassReader" /I "..\..\..\Runtime\FileReader" /I\ + "..\..\..\Runtime\NativeMethods" /I "..\..\..\Runtime\Systems" /I\ + "..\..\..\Compiler\CodeGenerator" /I "..\..\..\Compiler\RegisterAllocator" /I\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86dis" /I\ + "..\..\..\Compiler\CodeGenerator\md\x86" /I\ + "..\..\..\Compiler\CodeGenerator\md" /I ".\\" /I ".\genfiles" /I\ + "..\..\..\Compiler\Optimizer" /I "..\..\..\Driver\StandAloneJava" /I\ + "..\..\..\Runtime\System" /I "..\..\..\Debugger" /I\ + "..\..\..\Runtime\System\md" /I "..\..\..\Debugger\Communication" /D "NDEBUG"\ + /D "EF_WINDOWS" /D "GENERATE_FOR_X86" /D "XP_PC" /D "DLL_BUILD" /D "WIN32" /D\ + "_CONSOLE" /D "_MBCS" /D "GENERATE_NATIVE_STUBS" /FR"$(INTDIR)\\"\ + /Fp"$(INTDIR)\electricalfire.pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c + +"$(INTDIR)\x86Win32_Support.obj" "$(INTDIR)\x86Win32_Support.sbr" : $(SOURCE)\ + $(DEP_CPP_X86WIN3) "$(INTDIR)" + $(CPP) @<< + $(CPP_SWITCHES) $(SOURCE) +<< + + +!ELSEIF "$(CFG)" == "electricalfire - Win32 Debug" + +DEP_CPP_X86WIN3=\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\nspr.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\obsolete\protypes.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\plstr.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\pratom.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prbit.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prclist.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcmon.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcpucfg.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcvar.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prdtoa.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prenv.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prerror.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinet.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinit.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinrval.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prio.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlink.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlock.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlog.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlong.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prmem.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prmon.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prnetdb.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prprf.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prproces.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prsystem.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prthread.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtime.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtypes.h"\ + "..\..\..\Compiler\CodeGenerator\ExceptionTable.h"\ + "..\..\..\Compiler\CodeGenerator\FormatStructures.h"\ + "..\..\..\Compiler\CodeGenerator\NativeCodeCache.h"\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Debugger\Communication\DebuggerChannel.h"\ + "..\..\..\Debugger\Debugger.h"\ + "..\..\..\Runtime\ClassInfo\ClassCentral.h"\ + "..\..\..\Runtime\ClassInfo\ClassFileSummary.h"\ + "..\..\..\Runtime\ClassInfo\Collector.h"\ + "..\..\..\Runtime\ClassInfo\PathComponent.h"\ + "..\..\..\Runtime\ClassInfo\StringPool.h"\ + "..\..\..\Runtime\ClassReader\Attributes.h"\ + "..\..\..\Runtime\ClassReader\ClassReader.h"\ + "..\..\..\Runtime\ClassReader\ConstantPool.h"\ + "..\..\..\Runtime\ClassReader\InfoItem.h"\ + "..\..\..\Runtime\ClassReader\utils.h"\ + "..\..\..\Runtime\FileReader\FileReader.h"\ + "..\..\..\Runtime\FileReader\ZipArchive.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\System\ClassWorld.h"\ + "..\..\..\Runtime\System\FieldOrMethod.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Runtime\System\JavaString.h"\ + "..\..\..\Runtime\System\Method.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FastHashTable.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\InterestingEvents.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\MemoryAccess.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + "..\..\..\Utilities\zlib\zconf.h"\ + "..\..\..\Utilities\zlib\zlib.h"\ + +CPP_SWITCHES=/nologo /MDd /W3 /Gm /GX /Zi /I "..\..\..\Exports" /I\ + "..\..\..\Exports\md" /I "..\..\..\Utilities\General" /I\ + "..\..\..\Utilities\DisAssemblers\x86" /I "..\..\..\Utilities\General\md" /I\ + "..\..\..\Compiler\FrontEnd" /I "..\..\..\Compiler\PrimitiveGraph" /I\ + "..\..\..\Runtime\System\md\x86" /I\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include" /I "..\..\..\Utilities\zlib" /I\ + "..\..\..\Runtime\ClassInfo" /I "..\..\..\Runtime\ClassReader" /I\ + "..\..\..\Runtime\FileReader" /I "..\..\..\Runtime\NativeMethods" /I\ + "..\..\..\Runtime\Systems" /I "..\..\..\Compiler\CodeGenerator" /I\ + "..\..\..\Compiler\RegisterAllocator" /I\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86dis" /I\ + "..\..\..\Compiler\CodeGenerator\md\x86" /I\ + "..\..\..\Compiler\CodeGenerator\md" /I ".\\" /I ".\genfiles" /I\ + "..\..\..\Compiler\Optimizer" /I "..\..\..\Driver\StandAloneJava" /I\ + "..\..\..\Runtime\System" /I "..\..\..\Debugger" /I\ + "..\..\..\Runtime\System\md" /I "..\..\..\Debugger\Communication" /D "DEBUG" /D\ + "DEBUG_LOG" /D "_DEBUG" /D "DEBUG_DESANTIS" /D "DEBUG_kini" /D "EF_WINDOWS" /D\ + "GENERATE_FOR_X86" /D "XP_PC" /D "DLL_BUILD" /D "WIN32" /D "_CONSOLE" /D\ + "_MBCS" /D "GENERATE_NATIVE_STUBS" /FR"$(INTDIR)\\" /Fo"$(INTDIR)\\"\ + /Fd"$(INTDIR)\\" /FD /c + +"$(INTDIR)\x86Win32_Support.obj" "$(INTDIR)\x86Win32_Support.sbr" : $(SOURCE)\ + $(DEP_CPP_X86WIN3) "$(INTDIR)" + $(CPP) @<< + $(CPP_SWITCHES) $(SOURCE) +<< + + +!ENDIF + +SOURCE=..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Emitter.cpp + +!IF "$(CFG)" == "electricalfire - Win32 Release" + +DEP_CPP_X86WIN32=\ + "..\..\..\Compiler\CodeGenerator\ExceptionTable.h"\ + "..\..\..\Compiler\CodeGenerator\FormatStructures.h"\ + "..\..\..\Compiler\CodeGenerator\Instruction.h"\ + "..\..\..\Compiler\CodeGenerator\InstructionEmitter.h"\ + "..\..\..\Compiler\CodeGenerator\md\CpuInfo.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86ArgumentList.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Formatter.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Opcode.h"\ + "..\..\..\compiler\codegenerator\md\x86\x86stdcall.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Cpu.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Emitter.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Instruction.h"\ + "..\..\..\Compiler\CodeGenerator\NativeCodeCache.h"\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlNodes.h"\ + "..\..\..\Compiler\PrimitiveGraph\PrimitiveOperations.h"\ + "..\..\..\Compiler\PrimitiveGraph\Primitives.h"\ + "..\..\..\Compiler\PrimitiveGraph\SysCalls.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Compiler\RegisterAllocator\VirtualRegister.h"\ + "..\..\..\Debugger\Communication\DebuggerChannel.h"\ + "..\..\..\Debugger\Debugger.h"\ + "..\..\..\Runtime\ClassInfo\ClassCentral.h"\ + "..\..\..\Runtime\ClassInfo\ClassFileSummary.h"\ + "..\..\..\Runtime\ClassInfo\Collector.h"\ + "..\..\..\Runtime\ClassInfo\PathComponent.h"\ + "..\..\..\Runtime\ClassInfo\StringPool.h"\ + "..\..\..\Runtime\ClassReader\Attributes.h"\ + "..\..\..\Runtime\ClassReader\ClassReader.h"\ + "..\..\..\Runtime\ClassReader\ConstantPool.h"\ + "..\..\..\Runtime\ClassReader\InfoItem.h"\ + "..\..\..\Runtime\ClassReader\utils.h"\ + "..\..\..\Runtime\FileReader\FileReader.h"\ + "..\..\..\Runtime\FileReader\ZipArchive.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\System\ClassWorld.h"\ + "..\..\..\Runtime\System\FieldOrMethod.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Runtime\System\JavaString.h"\ + "..\..\..\Runtime\System\md\x86\x86SysCallsRuntime.h"\ + "..\..\..\Runtime\System\md\x86\x86Win32ExceptionHandler.h"\ + "..\..\..\Runtime\System\Method.h"\ + "..\..\..\Runtime\System\SysCallsRuntime.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FastBitMatrix.h"\ + "..\..\..\Utilities\General\FastBitSet.h"\ + "..\..\..\Utilities\General\FastHashTable.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\InterestingEvents.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\MemoryAccess.h"\ + "..\..\..\Utilities\General\Nonspr.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + "..\..\..\Utilities\zlib\zconf.h"\ + "..\..\..\Utilities\zlib\zlib.h"\ + ".\genfiles\x86-win32.nad.burg.h"\ + +NODEP_CPP_X86WIN32=\ + "..\..\..\Compiler\CodeGenerator\md\HPPACpu.h"\ + "..\..\..\Compiler\CodeGenerator\md\PPC601Cpu.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\prtypes.h"\ + "..\..\..\Compiler\CodeGenerator\prmon.h"\ + "..\..\..\Compiler\CodeGenerator\prtypes.h"\ + "..\..\..\Debugger\Communication\prio.h"\ + "..\..\..\Debugger\Communication\prlock.h"\ + "..\..\..\Debugger\Communication\prprf.h"\ + "..\..\..\Debugger\nspr.h"\ + "..\..\..\Runtime\ClassReader\prtypes.h"\ + "..\..\..\Runtime\FileReader\prio.h"\ + "..\..\..\Runtime\FileReader\prtypes.h"\ + "..\..\..\Runtime\System\plstr.h"\ + "..\..\..\Utilities\General\plstr.h"\ + "..\..\..\Utilities\General\prbit.h"\ + "..\..\..\Utilities\General\prlog.h"\ + "..\..\..\Utilities\General\prlong.h"\ + + +"$(INTDIR)\x86Win32Emitter.obj" "$(INTDIR)\x86Win32Emitter.sbr" : $(SOURCE)\ + $(DEP_CPP_X86WIN32) "$(INTDIR)" ".\genfiles\x86-win32.nad.burg.h" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "electricalfire - Win32 Debug" + +DEP_CPP_X86WIN32=\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\nspr.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\obsolete\protypes.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\plstr.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\pratom.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prbit.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prclist.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcmon.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcpucfg.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcvar.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prdtoa.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prenv.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prerror.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinet.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinit.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinrval.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prio.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlink.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlock.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlog.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlong.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prmem.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prmon.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prnetdb.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prprf.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prproces.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prsystem.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prthread.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtime.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtypes.h"\ + "..\..\..\Compiler\CodeGenerator\ExceptionTable.h"\ + "..\..\..\Compiler\CodeGenerator\FormatStructures.h"\ + "..\..\..\Compiler\CodeGenerator\Instruction.h"\ + "..\..\..\Compiler\CodeGenerator\InstructionEmitter.h"\ + "..\..\..\Compiler\CodeGenerator\md\CpuInfo.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86ArgumentList.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Opcode.h"\ + "..\..\..\compiler\codegenerator\md\x86\x86stdcall.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Cpu.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Emitter.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Instruction.h"\ + "..\..\..\Compiler\CodeGenerator\NativeCodeCache.h"\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlNodes.h"\ + "..\..\..\Compiler\PrimitiveGraph\PrimitiveOperations.h"\ + "..\..\..\Compiler\PrimitiveGraph\Primitives.h"\ + "..\..\..\Compiler\PrimitiveGraph\SysCalls.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Compiler\RegisterAllocator\VirtualRegister.h"\ + "..\..\..\Debugger\Communication\DebuggerChannel.h"\ + "..\..\..\Debugger\Debugger.h"\ + "..\..\..\Runtime\ClassInfo\ClassCentral.h"\ + "..\..\..\Runtime\ClassInfo\ClassFileSummary.h"\ + "..\..\..\Runtime\ClassInfo\Collector.h"\ + "..\..\..\Runtime\ClassInfo\PathComponent.h"\ + "..\..\..\Runtime\ClassInfo\StringPool.h"\ + "..\..\..\Runtime\ClassReader\Attributes.h"\ + "..\..\..\Runtime\ClassReader\ClassReader.h"\ + "..\..\..\Runtime\ClassReader\ConstantPool.h"\ + "..\..\..\Runtime\ClassReader\InfoItem.h"\ + "..\..\..\Runtime\ClassReader\utils.h"\ + "..\..\..\Runtime\FileReader\FileReader.h"\ + "..\..\..\Runtime\FileReader\ZipArchive.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\System\ClassWorld.h"\ + "..\..\..\Runtime\System\FieldOrMethod.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Runtime\System\JavaString.h"\ + "..\..\..\Runtime\System\md\x86\x86SysCallsRuntime.h"\ + "..\..\..\Runtime\System\md\x86\x86Win32ExceptionHandler.h"\ + "..\..\..\Runtime\System\Method.h"\ + "..\..\..\Runtime\System\SysCallsRuntime.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FastBitMatrix.h"\ + "..\..\..\Utilities\General\FastBitSet.h"\ + "..\..\..\Utilities\General\FastHashTable.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\InterestingEvents.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\MemoryAccess.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + "..\..\..\Utilities\zlib\zconf.h"\ + "..\..\..\Utilities\zlib\zlib.h"\ + ".\genfiles\x86-win32.nad.burg.h"\ + + +"$(INTDIR)\x86Win32Emitter.obj" "$(INTDIR)\x86Win32Emitter.sbr" : $(SOURCE)\ + $(DEP_CPP_X86WIN32) "$(INTDIR)" ".\genfiles\x86-win32.nad.burg.h" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +SOURCE=..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Instruction.cpp + +!IF "$(CFG)" == "electricalfire - Win32 Release" + +DEP_CPP_X86WIN32I=\ + "..\..\..\Compiler\CodeGenerator\ExceptionTable.h"\ + "..\..\..\Compiler\CodeGenerator\FormatStructures.h"\ + "..\..\..\Compiler\CodeGenerator\Instruction.h"\ + "..\..\..\Compiler\CodeGenerator\InstructionEmitter.h"\ + "..\..\..\Compiler\CodeGenerator\md\CpuInfo.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86ArgumentList.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Formatter.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Opcode.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Cpu.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Emitter.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Instruction.h"\ + "..\..\..\Compiler\CodeGenerator\NativeCodeCache.h"\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlNodes.h"\ + "..\..\..\Compiler\PrimitiveGraph\PrimitiveOperations.h"\ + "..\..\..\Compiler\PrimitiveGraph\Primitives.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Compiler\RegisterAllocator\VirtualRegister.h"\ + "..\..\..\Debugger\Communication\DebuggerChannel.h"\ + "..\..\..\Debugger\Debugger.h"\ + "..\..\..\Runtime\ClassInfo\ClassCentral.h"\ + "..\..\..\Runtime\ClassInfo\ClassFileSummary.h"\ + "..\..\..\Runtime\ClassInfo\Collector.h"\ + "..\..\..\Runtime\ClassInfo\PathComponent.h"\ + "..\..\..\Runtime\ClassInfo\StringPool.h"\ + "..\..\..\Runtime\ClassReader\Attributes.h"\ + "..\..\..\Runtime\ClassReader\ClassReader.h"\ + "..\..\..\Runtime\ClassReader\ConstantPool.h"\ + "..\..\..\Runtime\ClassReader\InfoItem.h"\ + "..\..\..\Runtime\ClassReader\utils.h"\ + "..\..\..\Runtime\FileReader\FileReader.h"\ + "..\..\..\Runtime\FileReader\ZipArchive.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\System\ClassWorld.h"\ + "..\..\..\Runtime\System\FieldOrMethod.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Runtime\System\JavaString.h"\ + "..\..\..\Runtime\System\Method.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FastBitMatrix.h"\ + "..\..\..\Utilities\General\FastBitSet.h"\ + "..\..\..\Utilities\General\FastHashTable.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\InterestingEvents.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\MemoryAccess.h"\ + "..\..\..\Utilities\General\Nonspr.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + "..\..\..\Utilities\zlib\zconf.h"\ + "..\..\..\Utilities\zlib\zlib.h"\ + +NODEP_CPP_X86WIN32I=\ + "..\..\..\Compiler\CodeGenerator\md\HPPACpu.h"\ + "..\..\..\Compiler\CodeGenerator\md\PPC601Cpu.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\prtypes.h"\ + "..\..\..\Compiler\CodeGenerator\prmon.h"\ + "..\..\..\Compiler\CodeGenerator\prtypes.h"\ + "..\..\..\Debugger\Communication\prio.h"\ + "..\..\..\Debugger\Communication\prlock.h"\ + "..\..\..\Debugger\Communication\prprf.h"\ + "..\..\..\Debugger\nspr.h"\ + "..\..\..\Runtime\ClassReader\prtypes.h"\ + "..\..\..\Runtime\FileReader\prio.h"\ + "..\..\..\Runtime\FileReader\prtypes.h"\ + "..\..\..\Runtime\System\plstr.h"\ + "..\..\..\Utilities\General\plstr.h"\ + "..\..\..\Utilities\General\prbit.h"\ + "..\..\..\Utilities\General\prlog.h"\ + "..\..\..\Utilities\General\prlong.h"\ + + +"$(INTDIR)\x86Win32Instruction.obj" "$(INTDIR)\x86Win32Instruction.sbr" : \ +$(SOURCE) $(DEP_CPP_X86WIN32I) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "electricalfire - Win32 Debug" + +DEP_CPP_X86WIN32I=\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\nspr.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\obsolete\protypes.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\plstr.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\pratom.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prbit.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prclist.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcmon.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcpucfg.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcvar.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prdtoa.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prenv.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prerror.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinet.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinit.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinrval.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prio.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlink.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlock.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlog.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlong.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prmem.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prmon.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prnetdb.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prprf.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prproces.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prsystem.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prthread.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtime.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtypes.h"\ + "..\..\..\Compiler\CodeGenerator\ExceptionTable.h"\ + "..\..\..\Compiler\CodeGenerator\FormatStructures.h"\ + "..\..\..\Compiler\CodeGenerator\Instruction.h"\ + "..\..\..\Compiler\CodeGenerator\InstructionEmitter.h"\ + "..\..\..\Compiler\CodeGenerator\md\CpuInfo.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86ArgumentList.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Formatter.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Opcode.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Cpu.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Emitter.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Instruction.h"\ + "..\..\..\Compiler\CodeGenerator\NativeCodeCache.h"\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlNodes.h"\ + "..\..\..\Compiler\PrimitiveGraph\PrimitiveOperations.h"\ + "..\..\..\Compiler\PrimitiveGraph\Primitives.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Compiler\RegisterAllocator\VirtualRegister.h"\ + "..\..\..\Debugger\Communication\DebuggerChannel.h"\ + "..\..\..\Debugger\Debugger.h"\ + "..\..\..\Runtime\ClassInfo\ClassCentral.h"\ + "..\..\..\Runtime\ClassInfo\ClassFileSummary.h"\ + "..\..\..\Runtime\ClassInfo\Collector.h"\ + "..\..\..\Runtime\ClassInfo\PathComponent.h"\ + "..\..\..\Runtime\ClassInfo\StringPool.h"\ + "..\..\..\Runtime\ClassReader\Attributes.h"\ + "..\..\..\Runtime\ClassReader\ClassReader.h"\ + "..\..\..\Runtime\ClassReader\ConstantPool.h"\ + "..\..\..\Runtime\ClassReader\InfoItem.h"\ + "..\..\..\Runtime\ClassReader\utils.h"\ + "..\..\..\Runtime\FileReader\FileReader.h"\ + "..\..\..\Runtime\FileReader\ZipArchive.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\System\ClassWorld.h"\ + "..\..\..\Runtime\System\FieldOrMethod.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Runtime\System\JavaString.h"\ + "..\..\..\Runtime\System\Method.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FastBitMatrix.h"\ + "..\..\..\Utilities\General\FastBitSet.h"\ + "..\..\..\Utilities\General\FastHashTable.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\InterestingEvents.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\MemoryAccess.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + "..\..\..\Utilities\zlib\zconf.h"\ + "..\..\..\Utilities\zlib\zlib.h"\ + + +"$(INTDIR)\x86Win32Instruction.obj" "$(INTDIR)\x86Win32Instruction.sbr" : \ +$(SOURCE) $(DEP_CPP_X86WIN32I) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +SOURCE=..\..\..\Compiler\CodeGenerator\md\generic\Generic_Support.cpp +SOURCE=..\..\..\Compiler\CodeGenerator\Backend.cpp + +!IF "$(CFG)" == "electricalfire - Win32 Release" + +DEP_CPP_BACKE=\ + "..\..\..\Compiler\CodeGenerator\Backend.h"\ + "..\..\..\Compiler\CodeGenerator\CGScheduler.h"\ + "..\..\..\Compiler\CodeGenerator\CodeGenerator.h"\ + "..\..\..\Compiler\CodeGenerator\ControlNodeScheduler.h"\ + "..\..\..\Compiler\CodeGenerator\ExceptionTable.h"\ + "..\..\..\Compiler\CodeGenerator\FormatStructures.h"\ + "..\..\..\Compiler\CodeGenerator\IGVisualizer.h"\ + "..\..\..\Compiler\CodeGenerator\Instruction.h"\ + "..\..\..\Compiler\CodeGenerator\InstructionEmitter.h"\ + "..\..\..\Compiler\CodeGenerator\md\CpuInfo.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Formatter.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Opcode.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Cpu.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Emitter.h"\ + "..\..\..\Compiler\CodeGenerator\NativeCodeCache.h"\ + "..\..\..\Compiler\CodeGenerator\NativeFormatter.h"\ + "..\..\..\Compiler\FrontEnd\BytecodeGraph.h"\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Compiler\FrontEnd\LocalEnv.h"\ + "..\..\..\Compiler\FrontEnd\TranslationEnv.h"\ + "..\..\..\Compiler\FrontEnd\VerificationEnv.h"\ + "..\..\..\Compiler\Optimizer\PrimitiveOptimizer.h"\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlGraph.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlNodes.h"\ + "..\..\..\Compiler\PrimitiveGraph\PrimitiveOperations.h"\ + "..\..\..\Compiler\PrimitiveGraph\Primitives.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Compiler\RegisterAllocator\Coloring.h"\ + "..\..\..\Compiler\RegisterAllocator\RegisterAllocator.h"\ + "..\..\..\Compiler\RegisterAllocator\RegisterAssigner.h"\ + "..\..\..\Compiler\RegisterAllocator\Spilling.h"\ + "..\..\..\Compiler\RegisterAllocator\VirtualRegister.h"\ + "..\..\..\Debugger\Communication\DebuggerChannel.h"\ + "..\..\..\Debugger\Debugger.h"\ + "..\..\..\Runtime\ClassInfo\ClassCentral.h"\ + "..\..\..\Runtime\ClassInfo\ClassFileSummary.h"\ + "..\..\..\Runtime\ClassInfo\Collector.h"\ + "..\..\..\Runtime\ClassInfo\PathComponent.h"\ + "..\..\..\Runtime\ClassInfo\StringPool.h"\ + "..\..\..\Runtime\ClassReader\Attributes.h"\ + "..\..\..\Runtime\ClassReader\ClassReader.h"\ + "..\..\..\Runtime\ClassReader\ConstantPool.h"\ + "..\..\..\Runtime\ClassReader\InfoItem.h"\ + "..\..\..\Runtime\ClassReader\utils.h"\ + "..\..\..\Runtime\FileReader\FileReader.h"\ + "..\..\..\Runtime\FileReader\ZipArchive.h"\ + "..\..\..\Runtime\NativeMethods\NameMangler.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\NativeMethods\NativeMethodDispatcher.h"\ + "..\..\..\Runtime\System\ClassWorld.h"\ + "..\..\..\Runtime\System\FieldOrMethod.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Runtime\System\JavaString.h"\ + "..\..\..\Runtime\System\JavaVM.h"\ + "..\..\..\Runtime\System\Method.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\CheckedUnion.h"\ + "..\..\..\Utilities\General\DebugUtils.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FastBitMatrix.h"\ + "..\..\..\Utilities\General\FastBitSet.h"\ + "..\..\..\Utilities\General\FastHashTable.h"\ + "..\..\..\Utilities\General\Fifo.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\InterestingEvents.h"\ + "..\..\..\Utilities\General\JavaBytecodes.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\Nonspr.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + "..\..\..\Utilities\zlib\zconf.h"\ + "..\..\..\Utilities\zlib\zlib.h"\ + +NODEP_CPP_BACKE=\ + "..\..\..\Compiler\CodeGenerator\md\HPPACpu.h"\ + "..\..\..\Compiler\CodeGenerator\md\PPC601Cpu.h"\ + "..\..\..\Compiler\CodeGenerator\prmon.h"\ + "..\..\..\Compiler\CodeGenerator\prtypes.h"\ + "..\..\..\Debugger\Communication\prio.h"\ + "..\..\..\Debugger\Communication\prlock.h"\ + "..\..\..\Debugger\Communication\prprf.h"\ + "..\..\..\Debugger\nspr.h"\ + "..\..\..\Runtime\ClassReader\prtypes.h"\ + "..\..\..\Runtime\FileReader\prio.h"\ + "..\..\..\Runtime\FileReader\prtypes.h"\ + "..\..\..\Runtime\NativeMethods\prlink.h"\ + "..\..\..\Runtime\System\plstr.h"\ + "..\..\..\Runtime\System\prprf.h"\ + "..\..\..\Utilities\General\plstr.h"\ + "..\..\..\Utilities\General\prbit.h"\ + "..\..\..\Utilities\General\prlog.h"\ + "..\..\..\Utilities\General\prlong.h"\ + + +"$(INTDIR)\Backend.obj" "$(INTDIR)\Backend.sbr" : $(SOURCE) $(DEP_CPP_BACKE)\ + "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "electricalfire - Win32 Debug" + +DEP_CPP_BACKE=\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\nspr.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\obsolete\protypes.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\plstr.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\pratom.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prbit.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prclist.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcmon.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcpucfg.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcvar.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prdtoa.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prenv.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prerror.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinet.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinit.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinrval.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prio.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlink.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlock.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlog.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlong.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prmem.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prmon.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prnetdb.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prprf.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prproces.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prsystem.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prthread.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtime.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtypes.h"\ + "..\..\..\Compiler\CodeGenerator\Backend.h"\ + "..\..\..\Compiler\CodeGenerator\CGScheduler.h"\ + "..\..\..\Compiler\CodeGenerator\CodeGenerator.h"\ + "..\..\..\Compiler\CodeGenerator\ExceptionTable.h"\ + "..\..\..\Compiler\CodeGenerator\FormatStructures.h"\ + "..\..\..\Compiler\CodeGenerator\Instruction.h"\ + "..\..\..\Compiler\CodeGenerator\InstructionEmitter.h"\ + "..\..\..\Compiler\CodeGenerator\md\CpuInfo.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Formatter.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Opcode.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Cpu.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Emitter.h"\ + "..\..\..\Compiler\CodeGenerator\NativeCodeCache.h"\ + "..\..\..\Compiler\CodeGenerator\NativeFormatter.h"\ + "..\..\..\Compiler\FrontEnd\BytecodeGraph.h"\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Compiler\FrontEnd\LocalEnv.h"\ + "..\..\..\Compiler\FrontEnd\TranslationEnv.h"\ + "..\..\..\Compiler\FrontEnd\VerificationEnv.h"\ + "..\..\..\Compiler\Optimizer\PrimitiveOptimizer.h"\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlGraph.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlNodes.h"\ + "..\..\..\Compiler\PrimitiveGraph\PrimitiveOperations.h"\ + "..\..\..\Compiler\PrimitiveGraph\Primitives.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Compiler\RegisterAllocator\Coloring.h"\ + "..\..\..\Compiler\RegisterAllocator\RegisterAllocator.h"\ + "..\..\..\Compiler\RegisterAllocator\RegisterAssigner.h"\ + "..\..\..\Compiler\RegisterAllocator\Spilling.h"\ + "..\..\..\Compiler\RegisterAllocator\VirtualRegister.h"\ + "..\..\..\Debugger\Communication\DebuggerChannel.h"\ + "..\..\..\Debugger\Debugger.h"\ + "..\..\..\Runtime\ClassInfo\ClassCentral.h"\ + "..\..\..\Runtime\ClassInfo\ClassFileSummary.h"\ + "..\..\..\Runtime\ClassInfo\Collector.h"\ + "..\..\..\Runtime\ClassInfo\PathComponent.h"\ + "..\..\..\Runtime\ClassInfo\StringPool.h"\ + "..\..\..\Runtime\ClassReader\Attributes.h"\ + "..\..\..\Runtime\ClassReader\ClassReader.h"\ + "..\..\..\Runtime\ClassReader\ConstantPool.h"\ + "..\..\..\Runtime\ClassReader\InfoItem.h"\ + "..\..\..\Runtime\ClassReader\utils.h"\ + "..\..\..\Runtime\FileReader\FileReader.h"\ + "..\..\..\Runtime\FileReader\ZipArchive.h"\ + "..\..\..\Runtime\NativeMethods\NameMangler.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\NativeMethods\NativeMethodDispatcher.h"\ + "..\..\..\Runtime\System\ClassWorld.h"\ + "..\..\..\Runtime\System\FieldOrMethod.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Runtime\System\JavaString.h"\ + "..\..\..\Runtime\System\JavaVM.h"\ + "..\..\..\Runtime\System\Method.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\CheckedUnion.h"\ + "..\..\..\Utilities\General\DebugUtils.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FastBitMatrix.h"\ + "..\..\..\Utilities\General\FastBitSet.h"\ + "..\..\..\Utilities\General\FastHashTable.h"\ + "..\..\..\Utilities\General\Fifo.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\InterestingEvents.h"\ + "..\..\..\Utilities\General\JavaBytecodes.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + "..\..\..\Utilities\zlib\zconf.h"\ + "..\..\..\Utilities\zlib\zlib.h"\ + + +"$(INTDIR)\Backend.obj" "$(INTDIR)\Backend.sbr" : $(SOURCE) $(DEP_CPP_BACKE)\ + "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +SOURCE=..\..\..\Compiler\CodeGenerator\CGScheduler.cpp + +!IF "$(CFG)" == "electricalfire - Win32 Release" + +DEP_CPP_CGSCH=\ + "..\..\..\Compiler\CodeGenerator\CGScheduler.h"\ + "..\..\..\Compiler\CodeGenerator\FormatStructures.h"\ + "..\..\..\Compiler\CodeGenerator\Instruction.h"\ + "..\..\..\Compiler\CodeGenerator\InstructionEmitter.h"\ + "..\..\..\Compiler\CodeGenerator\md\CpuInfo.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Formatter.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Opcode.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Cpu.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Emitter.h"\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlGraph.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlNodes.h"\ + "..\..\..\Compiler\PrimitiveGraph\PrimitiveOperations.h"\ + "..\..\..\Compiler\PrimitiveGraph\Primitives.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Compiler\RegisterAllocator\VirtualRegister.h"\ + "..\..\..\Runtime\ClassReader\Attributes.h"\ + "..\..\..\Runtime\ClassReader\ConstantPool.h"\ + "..\..\..\Runtime\ClassReader\utils.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\System\ClassWorld.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FastBitMatrix.h"\ + "..\..\..\Utilities\General\FastBitSet.h"\ + "..\..\..\Utilities\General\FastHashTable.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\GraphUtils.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\Nonspr.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + +NODEP_CPP_CGSCH=\ + "..\..\..\Compiler\CodeGenerator\md\HPPACpu.h"\ + "..\..\..\Compiler\CodeGenerator\md\PPC601Cpu.h"\ + "..\..\..\Compiler\CodeGenerator\prtypes.h"\ + "..\..\..\Runtime\ClassReader\prtypes.h"\ + "..\..\..\Utilities\General\plstr.h"\ + "..\..\..\Utilities\General\prbit.h"\ + "..\..\..\Utilities\General\prlog.h"\ + "..\..\..\Utilities\General\prlong.h"\ + + +"$(INTDIR)\CGScheduler.obj" "$(INTDIR)\CGScheduler.sbr" : $(SOURCE)\ + $(DEP_CPP_CGSCH) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "electricalfire - Win32 Debug" + +DEP_CPP_CGSCH=\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\obsolete\protypes.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prbit.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcpucfg.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinet.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinrval.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prio.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlog.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlong.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtime.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtypes.h"\ + "..\..\..\Compiler\CodeGenerator\CGScheduler.h"\ + "..\..\..\Compiler\CodeGenerator\Instruction.h"\ + "..\..\..\Compiler\CodeGenerator\InstructionEmitter.h"\ + "..\..\..\Compiler\CodeGenerator\md\CpuInfo.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Cpu.h"\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlGraph.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlNodes.h"\ + "..\..\..\Compiler\PrimitiveGraph\PrimitiveOperations.h"\ + "..\..\..\Compiler\PrimitiveGraph\Primitives.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Compiler\RegisterAllocator\VirtualRegister.h"\ + "..\..\..\Runtime\ClassReader\Attributes.h"\ + "..\..\..\Runtime\ClassReader\ConstantPool.h"\ + "..\..\..\Runtime\ClassReader\utils.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\System\ClassWorld.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FastBitMatrix.h"\ + "..\..\..\Utilities\General\FastBitSet.h"\ + "..\..\..\Utilities\General\FastHashTable.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\GraphUtils.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + + +"$(INTDIR)\CGScheduler.obj" "$(INTDIR)\CGScheduler.sbr" : $(SOURCE)\ + $(DEP_CPP_CGSCH) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +SOURCE=..\..\..\Compiler\CodeGenerator\CodeGenerator.cpp + +!IF "$(CFG)" == "electricalfire - Win32 Release" + +DEP_CPP_CODEG=\ + "..\..\..\Compiler\CodeGenerator\Burg.h"\ + "..\..\..\Compiler\CodeGenerator\CodeGenerator.h"\ + "..\..\..\Compiler\CodeGenerator\FormatStructures.h"\ + "..\..\..\Compiler\CodeGenerator\IGVisualizer.h"\ + "..\..\..\Compiler\CodeGenerator\Instruction.h"\ + "..\..\..\Compiler\CodeGenerator\InstructionEmitter.h"\ + "..\..\..\Compiler\CodeGenerator\md\CpuInfo.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Formatter.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Opcode.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Cpu.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Emitter.h"\ + "..\..\..\Compiler\CodeGenerator\Scheduler.h"\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlNodes.h"\ + "..\..\..\Compiler\PrimitiveGraph\PrimitiveOperations.h"\ + "..\..\..\Compiler\PrimitiveGraph\Primitives.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Compiler\RegisterAllocator\VirtualRegister.h"\ + "..\..\..\Runtime\ClassReader\Attributes.h"\ + "..\..\..\Runtime\ClassReader\ConstantPool.h"\ + "..\..\..\Runtime\ClassReader\utils.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\System\ClassWorld.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FastBitMatrix.h"\ + "..\..\..\Utilities\General\FastBitSet.h"\ + "..\..\..\Utilities\General\FastHashTable.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\Nonspr.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + +NODEP_CPP_CODEG=\ + "..\..\..\Compiler\CodeGenerator\md\HPPACpu.h"\ + "..\..\..\Compiler\CodeGenerator\md\PPC601Cpu.h"\ + "..\..\..\Compiler\CodeGenerator\prtypes.h"\ + "..\..\..\Runtime\ClassReader\prtypes.h"\ + "..\..\..\Utilities\General\plstr.h"\ + "..\..\..\Utilities\General\prbit.h"\ + "..\..\..\Utilities\General\prlog.h"\ + "..\..\..\Utilities\General\prlong.h"\ + + +"$(INTDIR)\CodeGenerator.obj" "$(INTDIR)\CodeGenerator.sbr" : $(SOURCE)\ + $(DEP_CPP_CODEG) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "electricalfire - Win32 Debug" + +DEP_CPP_CODEG=\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\obsolete\protypes.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prbit.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcpucfg.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinet.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinrval.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prio.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlog.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlong.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtime.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtypes.h"\ + "..\..\..\Compiler\CodeGenerator\Burg.h"\ + "..\..\..\Compiler\CodeGenerator\CodeGenerator.h"\ + "..\..\..\Compiler\CodeGenerator\FormatStructures.h"\ + "..\..\..\Compiler\CodeGenerator\Instruction.h"\ + "..\..\..\Compiler\CodeGenerator\InstructionEmitter.h"\ + "..\..\..\Compiler\CodeGenerator\md\CpuInfo.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Formatter.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Opcode.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Cpu.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Emitter.h"\ + "..\..\..\Compiler\CodeGenerator\Scheduler.h"\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlNodes.h"\ + "..\..\..\Compiler\PrimitiveGraph\PrimitiveOperations.h"\ + "..\..\..\Compiler\PrimitiveGraph\Primitives.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Compiler\RegisterAllocator\VirtualRegister.h"\ + "..\..\..\Runtime\ClassReader\Attributes.h"\ + "..\..\..\Runtime\ClassReader\ConstantPool.h"\ + "..\..\..\Runtime\ClassReader\utils.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\System\ClassWorld.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FastBitMatrix.h"\ + "..\..\..\Utilities\General\FastBitSet.h"\ + "..\..\..\Utilities\General\FastHashTable.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + + +"$(INTDIR)\CodeGenerator.obj" "$(INTDIR)\CodeGenerator.sbr" : $(SOURCE)\ + $(DEP_CPP_CODEG) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +SOURCE=..\..\..\Compiler\CodeGenerator\ExceptionTable.cpp + +!IF "$(CFG)" == "electricalfire - Win32 Release" + +DEP_CPP_EXCEP=\ + "..\..\..\Compiler\CodeGenerator\ExceptionTable.h"\ + "..\..\..\Compiler\CodeGenerator\FormatStructures.h"\ + "..\..\..\Compiler\CodeGenerator\Instruction.h"\ + "..\..\..\Compiler\CodeGenerator\InstructionEmitter.h"\ + "..\..\..\Compiler\CodeGenerator\md\CpuInfo.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Formatter.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Opcode.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Cpu.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Emitter.h"\ + "..\..\..\Compiler\CodeGenerator\NativeCodeCache.h"\ + "..\..\..\Compiler\FrontEnd\BytecodeGraph.h"\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Compiler\FrontEnd\LocalEnv.h"\ + "..\..\..\Compiler\FrontEnd\TranslationEnv.h"\ + "..\..\..\Compiler\FrontEnd\VerificationEnv.h"\ + "..\..\..\Compiler\Optimizer\PrimitiveOptimizer.h"\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlGraph.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlNodes.h"\ + "..\..\..\Compiler\PrimitiveGraph\PrimitiveOperations.h"\ + "..\..\..\Compiler\PrimitiveGraph\Primitives.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Compiler\RegisterAllocator\VirtualRegister.h"\ + "..\..\..\Debugger\Communication\DebuggerChannel.h"\ + "..\..\..\Debugger\Debugger.h"\ + "..\..\..\Runtime\ClassInfo\ClassCentral.h"\ + "..\..\..\Runtime\ClassInfo\ClassFileSummary.h"\ + "..\..\..\Runtime\ClassInfo\Collector.h"\ + "..\..\..\Runtime\ClassInfo\PathComponent.h"\ + "..\..\..\Runtime\ClassInfo\StringPool.h"\ + "..\..\..\Runtime\ClassReader\Attributes.h"\ + "..\..\..\Runtime\ClassReader\ClassReader.h"\ + "..\..\..\Runtime\ClassReader\ConstantPool.h"\ + "..\..\..\Runtime\ClassReader\InfoItem.h"\ + "..\..\..\Runtime\ClassReader\utils.h"\ + "..\..\..\Runtime\FileReader\FileReader.h"\ + "..\..\..\Runtime\FileReader\ZipArchive.h"\ + "..\..\..\Runtime\NativeMethods\NameMangler.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\NativeMethods\NativeMethodDispatcher.h"\ + "..\..\..\Runtime\System\ClassWorld.h"\ + "..\..\..\Runtime\System\FieldOrMethod.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Runtime\System\JavaString.h"\ + "..\..\..\Runtime\System\JavaVM.h"\ + "..\..\..\Runtime\System\Method.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\CheckedUnion.h"\ + "..\..\..\Utilities\General\DebugUtils.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FastBitMatrix.h"\ + "..\..\..\Utilities\General\FastBitSet.h"\ + "..\..\..\Utilities\General\FastHashTable.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\InterestingEvents.h"\ + "..\..\..\Utilities\General\JavaBytecodes.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\Nonspr.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + "..\..\..\Utilities\zlib\zconf.h"\ + "..\..\..\Utilities\zlib\zlib.h"\ + +NODEP_CPP_EXCEP=\ + "..\..\..\Compiler\CodeGenerator\md\HPPACpu.h"\ + "..\..\..\Compiler\CodeGenerator\md\PPC601Cpu.h"\ + "..\..\..\Compiler\CodeGenerator\prmon.h"\ + "..\..\..\Compiler\CodeGenerator\prtypes.h"\ + "..\..\..\Debugger\Communication\prio.h"\ + "..\..\..\Debugger\Communication\prlock.h"\ + "..\..\..\Debugger\Communication\prprf.h"\ + "..\..\..\Debugger\nspr.h"\ + "..\..\..\Runtime\ClassReader\prtypes.h"\ + "..\..\..\Runtime\FileReader\prio.h"\ + "..\..\..\Runtime\FileReader\prtypes.h"\ + "..\..\..\Runtime\NativeMethods\prlink.h"\ + "..\..\..\Runtime\System\plstr.h"\ + "..\..\..\Runtime\System\prprf.h"\ + "..\..\..\Utilities\General\plstr.h"\ + "..\..\..\Utilities\General\prbit.h"\ + "..\..\..\Utilities\General\prlog.h"\ + "..\..\..\Utilities\General\prlong.h"\ + + +"$(INTDIR)\ExceptionTable.obj" "$(INTDIR)\ExceptionTable.sbr" : $(SOURCE)\ + $(DEP_CPP_EXCEP) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "electricalfire - Win32 Debug" + +DEP_CPP_EXCEP=\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\nspr.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\obsolete\protypes.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\plstr.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\pratom.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prbit.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prclist.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcmon.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcpucfg.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcvar.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prdtoa.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prenv.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prerror.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinet.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinit.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinrval.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prio.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlink.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlock.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlog.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlong.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prmem.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prmon.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prnetdb.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prprf.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prproces.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prsystem.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prthread.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtime.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtypes.h"\ + "..\..\..\Compiler\CodeGenerator\ExceptionTable.h"\ + "..\..\..\Compiler\CodeGenerator\FormatStructures.h"\ + "..\..\..\Compiler\CodeGenerator\Instruction.h"\ + "..\..\..\Compiler\CodeGenerator\md\CpuInfo.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Cpu.h"\ + "..\..\..\Compiler\CodeGenerator\NativeCodeCache.h"\ + "..\..\..\Compiler\FrontEnd\BytecodeGraph.h"\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Compiler\FrontEnd\LocalEnv.h"\ + "..\..\..\Compiler\FrontEnd\TranslationEnv.h"\ + "..\..\..\Compiler\FrontEnd\VerificationEnv.h"\ + "..\..\..\Compiler\Optimizer\PrimitiveOptimizer.h"\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlGraph.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlNodes.h"\ + "..\..\..\Compiler\PrimitiveGraph\PrimitiveOperations.h"\ + "..\..\..\Compiler\PrimitiveGraph\Primitives.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Compiler\RegisterAllocator\VirtualRegister.h"\ + "..\..\..\Debugger\Communication\DebuggerChannel.h"\ + "..\..\..\Debugger\Debugger.h"\ + "..\..\..\Runtime\ClassInfo\ClassCentral.h"\ + "..\..\..\Runtime\ClassInfo\ClassFileSummary.h"\ + "..\..\..\Runtime\ClassInfo\Collector.h"\ + "..\..\..\Runtime\ClassInfo\PathComponent.h"\ + "..\..\..\Runtime\ClassInfo\StringPool.h"\ + "..\..\..\Runtime\ClassReader\Attributes.h"\ + "..\..\..\Runtime\ClassReader\ClassReader.h"\ + "..\..\..\Runtime\ClassReader\ConstantPool.h"\ + "..\..\..\Runtime\ClassReader\InfoItem.h"\ + "..\..\..\Runtime\ClassReader\utils.h"\ + "..\..\..\Runtime\FileReader\FileReader.h"\ + "..\..\..\Runtime\FileReader\ZipArchive.h"\ + "..\..\..\Runtime\NativeMethods\NameMangler.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\NativeMethods\NativeMethodDispatcher.h"\ + "..\..\..\Runtime\System\ClassWorld.h"\ + "..\..\..\Runtime\System\FieldOrMethod.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Runtime\System\JavaString.h"\ + "..\..\..\Runtime\System\JavaVM.h"\ + "..\..\..\Runtime\System\Method.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\CheckedUnion.h"\ + "..\..\..\Utilities\General\DebugUtils.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FastBitMatrix.h"\ + "..\..\..\Utilities\General\FastBitSet.h"\ + "..\..\..\Utilities\General\FastHashTable.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\InterestingEvents.h"\ + "..\..\..\Utilities\General\JavaBytecodes.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + "..\..\..\Utilities\zlib\zconf.h"\ + "..\..\..\Utilities\zlib\zlib.h"\ + + +"$(INTDIR)\ExceptionTable.obj" "$(INTDIR)\ExceptionTable.sbr" : $(SOURCE)\ + $(DEP_CPP_EXCEP) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +SOURCE=..\..\..\Compiler\CodeGenerator\HTMLMethodDump.cpp + +!IF "$(CFG)" == "electricalfire - Win32 Release" + +DEP_CPP_HTMLM=\ + "..\..\..\Compiler\CodeGenerator\ExceptionTable.h"\ + "..\..\..\Compiler\CodeGenerator\FormatStructures.h"\ + "..\..\..\Compiler\CodeGenerator\HTMLMethodDump.h"\ + "..\..\..\Compiler\CodeGenerator\Instruction.h"\ + "..\..\..\Compiler\CodeGenerator\InstructionEmitter.h"\ + "..\..\..\Compiler\CodeGenerator\md\CpuInfo.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Formatter.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Opcode.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Cpu.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Emitter.h"\ + "..\..\..\Compiler\CodeGenerator\NativeFormatter.h"\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlGraph.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlNodes.h"\ + "..\..\..\Compiler\PrimitiveGraph\PrimitiveOperations.h"\ + "..\..\..\Compiler\PrimitiveGraph\Primitives.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Compiler\RegisterAllocator\VirtualRegister.h"\ + "..\..\..\Debugger\Communication\DebuggerChannel.h"\ + "..\..\..\Debugger\Debugger.h"\ + "..\..\..\Runtime\ClassInfo\ClassCentral.h"\ + "..\..\..\Runtime\ClassInfo\ClassFileSummary.h"\ + "..\..\..\Runtime\ClassInfo\Collector.h"\ + "..\..\..\Runtime\ClassInfo\PathComponent.h"\ + "..\..\..\Runtime\ClassInfo\StringPool.h"\ + "..\..\..\Runtime\ClassReader\Attributes.h"\ + "..\..\..\Runtime\ClassReader\ClassReader.h"\ + "..\..\..\Runtime\ClassReader\ConstantPool.h"\ + "..\..\..\Runtime\ClassReader\InfoItem.h"\ + "..\..\..\Runtime\ClassReader\utils.h"\ + "..\..\..\Runtime\FileReader\FileReader.h"\ + "..\..\..\Runtime\FileReader\ZipArchive.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\System\ClassWorld.h"\ + "..\..\..\Runtime\System\FieldOrMethod.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Runtime\System\JavaString.h"\ + "..\..\..\Runtime\System\Method.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FastBitMatrix.h"\ + "..\..\..\Utilities\General\FastBitSet.h"\ + "..\..\..\Utilities\General\FastHashTable.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\InterestingEvents.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\Nonspr.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + "..\..\..\Utilities\zlib\zconf.h"\ + "..\..\..\Utilities\zlib\zlib.h"\ + +NODEP_CPP_HTMLM=\ + "..\..\..\Compiler\CodeGenerator\md\HPPACpu.h"\ + "..\..\..\Compiler\CodeGenerator\md\PPC601Cpu.h"\ + "..\..\..\Compiler\CodeGenerator\prtypes.h"\ + "..\..\..\Debugger\Communication\prio.h"\ + "..\..\..\Debugger\Communication\prlock.h"\ + "..\..\..\Debugger\Communication\prprf.h"\ + "..\..\..\Debugger\nspr.h"\ + "..\..\..\Runtime\ClassReader\prtypes.h"\ + "..\..\..\Runtime\FileReader\prio.h"\ + "..\..\..\Runtime\FileReader\prtypes.h"\ + "..\..\..\Runtime\System\plstr.h"\ + "..\..\..\Utilities\General\plstr.h"\ + "..\..\..\Utilities\General\prbit.h"\ + "..\..\..\Utilities\General\prlog.h"\ + "..\..\..\Utilities\General\prlong.h"\ + + +"$(INTDIR)\HTMLMethodDump.obj" "$(INTDIR)\HTMLMethodDump.sbr" : $(SOURCE)\ + $(DEP_CPP_HTMLM) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "electricalfire - Win32 Debug" + +DEP_CPP_HTMLM=\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\nspr.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\obsolete\protypes.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\plstr.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\pratom.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prbit.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prclist.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcmon.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcpucfg.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcvar.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prdtoa.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prenv.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prerror.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinet.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinit.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinrval.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prio.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlink.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlock.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlog.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlong.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prmem.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prmon.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prnetdb.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prprf.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prproces.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prsystem.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prthread.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtime.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtypes.h"\ + "..\..\..\Compiler\CodeGenerator\ExceptionTable.h"\ + "..\..\..\Compiler\CodeGenerator\FormatStructures.h"\ + "..\..\..\Compiler\CodeGenerator\HTMLMethodDump.h"\ + "..\..\..\Compiler\CodeGenerator\Instruction.h"\ + "..\..\..\Compiler\CodeGenerator\InstructionEmitter.h"\ + "..\..\..\Compiler\CodeGenerator\md\CpuInfo.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Formatter.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Opcode.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Cpu.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Emitter.h"\ + "..\..\..\Compiler\CodeGenerator\NativeFormatter.h"\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlGraph.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlNodes.h"\ + "..\..\..\Compiler\PrimitiveGraph\PrimitiveOperations.h"\ + "..\..\..\Compiler\PrimitiveGraph\Primitives.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Compiler\RegisterAllocator\VirtualRegister.h"\ + "..\..\..\Debugger\Communication\DebuggerChannel.h"\ + "..\..\..\Debugger\Debugger.h"\ + "..\..\..\Runtime\ClassInfo\ClassCentral.h"\ + "..\..\..\Runtime\ClassInfo\ClassFileSummary.h"\ + "..\..\..\Runtime\ClassInfo\Collector.h"\ + "..\..\..\Runtime\ClassInfo\PathComponent.h"\ + "..\..\..\Runtime\ClassInfo\StringPool.h"\ + "..\..\..\Runtime\ClassReader\Attributes.h"\ + "..\..\..\Runtime\ClassReader\ClassReader.h"\ + "..\..\..\Runtime\ClassReader\ConstantPool.h"\ + "..\..\..\Runtime\ClassReader\InfoItem.h"\ + "..\..\..\Runtime\ClassReader\utils.h"\ + "..\..\..\Runtime\FileReader\FileReader.h"\ + "..\..\..\Runtime\FileReader\ZipArchive.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\System\ClassWorld.h"\ + "..\..\..\Runtime\System\FieldOrMethod.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Runtime\System\JavaString.h"\ + "..\..\..\Runtime\System\Method.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FastBitMatrix.h"\ + "..\..\..\Utilities\General\FastBitSet.h"\ + "..\..\..\Utilities\General\FastHashTable.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\InterestingEvents.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + "..\..\..\Utilities\zlib\zconf.h"\ + "..\..\..\Utilities\zlib\zlib.h"\ + + +"$(INTDIR)\HTMLMethodDump.obj" "$(INTDIR)\HTMLMethodDump.sbr" : $(SOURCE)\ + $(DEP_CPP_HTMLM) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +SOURCE=..\..\..\Compiler\CodeGenerator\IGVisualizer.cpp + +!IF "$(CFG)" == "electricalfire - Win32 Release" + +DEP_CPP_IGVIS=\ + "..\..\..\Compiler\CodeGenerator\CodeGenerator.h"\ + "..\..\..\Compiler\CodeGenerator\FormatStructures.h"\ + "..\..\..\Compiler\CodeGenerator\IGVisualizer.h"\ + "..\..\..\Compiler\CodeGenerator\Instruction.h"\ + "..\..\..\Compiler\CodeGenerator\InstructionEmitter.h"\ + "..\..\..\Compiler\CodeGenerator\md\CpuInfo.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Formatter.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Opcode.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Cpu.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Emitter.h"\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlNodes.h"\ + "..\..\..\Compiler\PrimitiveGraph\PrimitiveOperations.h"\ + "..\..\..\Compiler\PrimitiveGraph\Primitives.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Compiler\RegisterAllocator\VirtualRegister.h"\ + "..\..\..\Runtime\ClassReader\Attributes.h"\ + "..\..\..\Runtime\ClassReader\ConstantPool.h"\ + "..\..\..\Runtime\ClassReader\utils.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\System\ClassWorld.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FastBitMatrix.h"\ + "..\..\..\Utilities\General\FastBitSet.h"\ + "..\..\..\Utilities\General\FastHashTable.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\Nonspr.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + +NODEP_CPP_IGVIS=\ + "..\..\..\Compiler\CodeGenerator\md\HPPACpu.h"\ + "..\..\..\Compiler\CodeGenerator\md\PPC601Cpu.h"\ + "..\..\..\Compiler\CodeGenerator\prtypes.h"\ + "..\..\..\Runtime\ClassReader\prtypes.h"\ + "..\..\..\Utilities\General\plstr.h"\ + "..\..\..\Utilities\General\prbit.h"\ + "..\..\..\Utilities\General\prlog.h"\ + "..\..\..\Utilities\General\prlong.h"\ + + +"$(INTDIR)\IGVisualizer.obj" "$(INTDIR)\IGVisualizer.sbr" : $(SOURCE)\ + $(DEP_CPP_IGVIS) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "electricalfire - Win32 Debug" + + +"$(INTDIR)\IGVisualizer.obj" "$(INTDIR)\IGVisualizer.sbr" : $(SOURCE)\ + "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +SOURCE=..\..\..\Compiler\CodeGenerator\Instruction.cpp + +!IF "$(CFG)" == "electricalfire - Win32 Release" + +DEP_CPP_INSTR=\ + "..\..\..\Compiler\CodeGenerator\FormatStructures.h"\ + "..\..\..\Compiler\CodeGenerator\Instruction.h"\ + "..\..\..\Compiler\CodeGenerator\InstructionEmitter.h"\ + "..\..\..\Compiler\CodeGenerator\md\CpuInfo.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Formatter.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Opcode.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Cpu.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Emitter.h"\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlNodes.h"\ + "..\..\..\Compiler\PrimitiveGraph\PrimitiveOperations.h"\ + "..\..\..\Compiler\PrimitiveGraph\Primitives.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Compiler\RegisterAllocator\VirtualRegister.h"\ + "..\..\..\Runtime\ClassReader\Attributes.h"\ + "..\..\..\Runtime\ClassReader\ConstantPool.h"\ + "..\..\..\Runtime\ClassReader\utils.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\System\ClassWorld.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FastBitMatrix.h"\ + "..\..\..\Utilities\General\FastBitSet.h"\ + "..\..\..\Utilities\General\FastHashTable.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\Nonspr.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + +NODEP_CPP_INSTR=\ + "..\..\..\Compiler\CodeGenerator\md\HPPACpu.h"\ + "..\..\..\Compiler\CodeGenerator\md\PPC601Cpu.h"\ + "..\..\..\Compiler\CodeGenerator\prtypes.h"\ + "..\..\..\Runtime\ClassReader\prtypes.h"\ + "..\..\..\Utilities\General\plstr.h"\ + "..\..\..\Utilities\General\prbit.h"\ + "..\..\..\Utilities\General\prlog.h"\ + "..\..\..\Utilities\General\prlong.h"\ + + +"$(INTDIR)\Instruction.obj" "$(INTDIR)\Instruction.sbr" : $(SOURCE)\ + $(DEP_CPP_INSTR) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "electricalfire - Win32 Debug" + +DEP_CPP_INSTR=\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\obsolete\protypes.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prbit.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcpucfg.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinet.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinrval.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prio.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlog.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlong.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtime.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtypes.h"\ + "..\..\..\Compiler\CodeGenerator\Instruction.h"\ + "..\..\..\Compiler\CodeGenerator\InstructionEmitter.h"\ + "..\..\..\Compiler\CodeGenerator\md\CpuInfo.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Cpu.h"\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\PrimitiveOperations.h"\ + "..\..\..\Compiler\PrimitiveGraph\Primitives.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Compiler\RegisterAllocator\VirtualRegister.h"\ + "..\..\..\Runtime\ClassReader\Attributes.h"\ + "..\..\..\Runtime\ClassReader\ConstantPool.h"\ + "..\..\..\Runtime\ClassReader\utils.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FastBitMatrix.h"\ + "..\..\..\Utilities\General\FastBitSet.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + + +"$(INTDIR)\Instruction.obj" "$(INTDIR)\Instruction.sbr" : $(SOURCE)\ + $(DEP_CPP_INSTR) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +SOURCE=..\..\..\Compiler\CodeGenerator\InstructionEmitter.cpp + +!IF "$(CFG)" == "electricalfire - Win32 Release" + +DEP_CPP_INSTRU=\ + "..\..\..\Compiler\CodeGenerator\FormatStructures.h"\ + "..\..\..\Compiler\CodeGenerator\Instruction.h"\ + "..\..\..\Compiler\CodeGenerator\InstructionEmitter.h"\ + "..\..\..\Compiler\CodeGenerator\md\CpuInfo.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Formatter.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Opcode.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Cpu.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Emitter.h"\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlNodes.h"\ + "..\..\..\Compiler\PrimitiveGraph\PrimitiveOperations.h"\ + "..\..\..\Compiler\PrimitiveGraph\Primitives.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Compiler\RegisterAllocator\VirtualRegister.h"\ + "..\..\..\Runtime\ClassReader\Attributes.h"\ + "..\..\..\Runtime\ClassReader\ConstantPool.h"\ + "..\..\..\Runtime\ClassReader\utils.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\System\ClassWorld.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FastBitMatrix.h"\ + "..\..\..\Utilities\General\FastBitSet.h"\ + "..\..\..\Utilities\General\FastHashTable.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\Nonspr.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + +NODEP_CPP_INSTRU=\ + "..\..\..\Compiler\CodeGenerator\md\HPPACpu.h"\ + "..\..\..\Compiler\CodeGenerator\md\PPC601Cpu.h"\ + "..\..\..\Compiler\CodeGenerator\prtypes.h"\ + "..\..\..\Runtime\ClassReader\prtypes.h"\ + "..\..\..\Utilities\General\plstr.h"\ + "..\..\..\Utilities\General\prbit.h"\ + "..\..\..\Utilities\General\prlog.h"\ + "..\..\..\Utilities\General\prlong.h"\ + + +"$(INTDIR)\InstructionEmitter.obj" "$(INTDIR)\InstructionEmitter.sbr" : \ +$(SOURCE) $(DEP_CPP_INSTRU) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "electricalfire - Win32 Debug" + +DEP_CPP_INSTRU=\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\obsolete\protypes.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prbit.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcpucfg.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinet.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinrval.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prio.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlog.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlong.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtime.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtypes.h"\ + "..\..\..\Compiler\CodeGenerator\Instruction.h"\ + "..\..\..\Compiler\CodeGenerator\InstructionEmitter.h"\ + "..\..\..\Compiler\CodeGenerator\md\CpuInfo.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Cpu.h"\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlNodes.h"\ + "..\..\..\Compiler\PrimitiveGraph\PrimitiveOperations.h"\ + "..\..\..\Compiler\PrimitiveGraph\Primitives.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Compiler\RegisterAllocator\VirtualRegister.h"\ + "..\..\..\Runtime\ClassReader\Attributes.h"\ + "..\..\..\Runtime\ClassReader\ConstantPool.h"\ + "..\..\..\Runtime\ClassReader\utils.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\System\ClassWorld.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FastBitMatrix.h"\ + "..\..\..\Utilities\General\FastBitSet.h"\ + "..\..\..\Utilities\General\FastHashTable.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + + +"$(INTDIR)\InstructionEmitter.obj" "$(INTDIR)\InstructionEmitter.sbr" : \ +$(SOURCE) $(DEP_CPP_INSTRU) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +SOURCE=..\..\..\Compiler\CodeGenerator\NativeCodeCache.cpp + +!IF "$(CFG)" == "electricalfire - Win32 Release" + +DEP_CPP_NATIVE=\ + "..\..\..\Compiler\CodeGenerator\ExceptionTable.h"\ + "..\..\..\Compiler\CodeGenerator\FormatStructures.h"\ + "..\..\..\Compiler\CodeGenerator\Instruction.h"\ + "..\..\..\Compiler\CodeGenerator\InstructionEmitter.h"\ + "..\..\..\Compiler\CodeGenerator\md\CpuInfo.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Formatter.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Opcode.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Cpu.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Emitter.h"\ + "..\..\..\Compiler\CodeGenerator\NativeCodeCache.h"\ + "..\..\..\Compiler\FrontEnd\BytecodeGraph.h"\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Compiler\FrontEnd\LocalEnv.h"\ + "..\..\..\Compiler\FrontEnd\TranslationEnv.h"\ + "..\..\..\Compiler\FrontEnd\VerificationEnv.h"\ + "..\..\..\Compiler\Optimizer\PrimitiveOptimizer.h"\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlGraph.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlNodes.h"\ + "..\..\..\Compiler\PrimitiveGraph\PrimitiveOperations.h"\ + "..\..\..\Compiler\PrimitiveGraph\Primitives.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Compiler\RegisterAllocator\VirtualRegister.h"\ + "..\..\..\Debugger\Communication\DebuggerChannel.h"\ + "..\..\..\Debugger\Debugger.h"\ + "..\..\..\Runtime\ClassInfo\ClassCentral.h"\ + "..\..\..\Runtime\ClassInfo\ClassFileSummary.h"\ + "..\..\..\Runtime\ClassInfo\Collector.h"\ + "..\..\..\Runtime\ClassInfo\PathComponent.h"\ + "..\..\..\Runtime\ClassInfo\StringPool.h"\ + "..\..\..\Runtime\ClassReader\Attributes.h"\ + "..\..\..\Runtime\ClassReader\ClassReader.h"\ + "..\..\..\Runtime\ClassReader\ConstantPool.h"\ + "..\..\..\Runtime\ClassReader\InfoItem.h"\ + "..\..\..\Runtime\ClassReader\utils.h"\ + "..\..\..\Runtime\FileReader\FileReader.h"\ + "..\..\..\Runtime\FileReader\ZipArchive.h"\ + "..\..\..\Runtime\NativeMethods\NameMangler.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\NativeMethods\NativeMethodDispatcher.h"\ + "..\..\..\Runtime\System\ClassWorld.h"\ + "..\..\..\Runtime\System\FieldOrMethod.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Runtime\System\JavaString.h"\ + "..\..\..\Runtime\System\JavaVM.h"\ + "..\..\..\Runtime\System\Method.h"\ + "..\..\..\Runtime\System\StackWalker.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\CheckedUnion.h"\ + "..\..\..\Utilities\General\DebugUtils.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FastBitMatrix.h"\ + "..\..\..\Utilities\General\FastBitSet.h"\ + "..\..\..\Utilities\General\FastHashTable.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\InterestingEvents.h"\ + "..\..\..\Utilities\General\JavaBytecodes.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\Nonspr.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\StringUtils.h"\ + "..\..\..\Utilities\General\Vector.h"\ + "..\..\..\Utilities\zlib\zconf.h"\ + "..\..\..\Utilities\zlib\zlib.h"\ + +NODEP_CPP_NATIVE=\ + "..\..\..\Compiler\CodeGenerator\md\HPPACpu.h"\ + "..\..\..\Compiler\CodeGenerator\md\PPC601Cpu.h"\ + "..\..\..\Compiler\CodeGenerator\prmon.h"\ + "..\..\..\Compiler\CodeGenerator\prtypes.h"\ + "..\..\..\Debugger\Communication\prio.h"\ + "..\..\..\Debugger\Communication\prlock.h"\ + "..\..\..\Debugger\Communication\prprf.h"\ + "..\..\..\Debugger\nspr.h"\ + "..\..\..\Runtime\ClassReader\prtypes.h"\ + "..\..\..\Runtime\FileReader\prio.h"\ + "..\..\..\Runtime\FileReader\prtypes.h"\ + "..\..\..\Runtime\NativeMethods\prlink.h"\ + "..\..\..\Runtime\System\plstr.h"\ + "..\..\..\Runtime\System\prprf.h"\ + "..\..\..\Utilities\General\plstr.h"\ + "..\..\..\Utilities\General\prbit.h"\ + "..\..\..\Utilities\General\prlog.h"\ + "..\..\..\Utilities\General\prlong.h"\ + "..\..\..\Utilities\General\prprf.h"\ + + +"$(INTDIR)\NativeCodeCache.obj" "$(INTDIR)\NativeCodeCache.sbr" : $(SOURCE)\ + $(DEP_CPP_NATIVE) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "electricalfire - Win32 Debug" + +DEP_CPP_NATIVE=\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\nspr.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\obsolete\protypes.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\plstr.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\pratom.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prbit.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prclist.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcmon.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcpucfg.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcvar.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prdtoa.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prenv.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prerror.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinet.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinit.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinrval.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prio.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlink.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlock.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlog.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlong.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prmem.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prmon.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prnetdb.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prprf.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prproces.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prsystem.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prthread.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtime.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtypes.h"\ + "..\..\..\Compiler\CodeGenerator\ExceptionTable.h"\ + "..\..\..\Compiler\CodeGenerator\FormatStructures.h"\ + "..\..\..\Compiler\CodeGenerator\Instruction.h"\ + "..\..\..\Compiler\CodeGenerator\md\CpuInfo.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Cpu.h"\ + "..\..\..\Compiler\CodeGenerator\NativeCodeCache.h"\ + "..\..\..\Compiler\FrontEnd\BytecodeGraph.h"\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Compiler\FrontEnd\LocalEnv.h"\ + "..\..\..\Compiler\FrontEnd\TranslationEnv.h"\ + "..\..\..\Compiler\FrontEnd\VerificationEnv.h"\ + "..\..\..\Compiler\Optimizer\PrimitiveOptimizer.h"\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlGraph.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlNodes.h"\ + "..\..\..\Compiler\PrimitiveGraph\PrimitiveOperations.h"\ + "..\..\..\Compiler\PrimitiveGraph\Primitives.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Compiler\RegisterAllocator\VirtualRegister.h"\ + "..\..\..\Debugger\Communication\DebuggerChannel.h"\ + "..\..\..\Debugger\Debugger.h"\ + "..\..\..\Runtime\ClassInfo\ClassCentral.h"\ + "..\..\..\Runtime\ClassInfo\ClassFileSummary.h"\ + "..\..\..\Runtime\ClassInfo\Collector.h"\ + "..\..\..\Runtime\ClassInfo\PathComponent.h"\ + "..\..\..\Runtime\ClassInfo\StringPool.h"\ + "..\..\..\Runtime\ClassReader\Attributes.h"\ + "..\..\..\Runtime\ClassReader\ClassReader.h"\ + "..\..\..\Runtime\ClassReader\ConstantPool.h"\ + "..\..\..\Runtime\ClassReader\InfoItem.h"\ + "..\..\..\Runtime\ClassReader\utils.h"\ + "..\..\..\Runtime\FileReader\FileReader.h"\ + "..\..\..\Runtime\FileReader\ZipArchive.h"\ + "..\..\..\Runtime\NativeMethods\NameMangler.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\NativeMethods\NativeMethodDispatcher.h"\ + "..\..\..\Runtime\System\ClassWorld.h"\ + "..\..\..\Runtime\System\FieldOrMethod.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Runtime\System\JavaString.h"\ + "..\..\..\Runtime\System\JavaVM.h"\ + "..\..\..\Runtime\System\Method.h"\ + "..\..\..\Runtime\System\StackWalker.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\CheckedUnion.h"\ + "..\..\..\Utilities\General\DebugUtils.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FastBitMatrix.h"\ + "..\..\..\Utilities\General\FastBitSet.h"\ + "..\..\..\Utilities\General\FastHashTable.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\InterestingEvents.h"\ + "..\..\..\Utilities\General\JavaBytecodes.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\StringUtils.h"\ + "..\..\..\Utilities\General\Vector.h"\ + "..\..\..\Utilities\zlib\zconf.h"\ + "..\..\..\Utilities\zlib\zlib.h"\ + + +"$(INTDIR)\NativeCodeCache.obj" "$(INTDIR)\NativeCodeCache.sbr" : $(SOURCE)\ + $(DEP_CPP_NATIVE) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +SOURCE=..\..\..\Compiler\CodeGenerator\NativeFormatter.cpp + +!IF "$(CFG)" == "electricalfire - Win32 Release" + +DEP_CPP_NATIVEF=\ + "..\..\..\Compiler\CodeGenerator\ExceptionTable.h"\ + "..\..\..\Compiler\CodeGenerator\FormatStructures.h"\ + "..\..\..\Compiler\CodeGenerator\Instruction.h"\ + "..\..\..\Compiler\CodeGenerator\InstructionEmitter.h"\ + "..\..\..\Compiler\CodeGenerator\md\CpuInfo.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Formatter.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Opcode.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Cpu.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Emitter.h"\ + "..\..\..\Compiler\CodeGenerator\NativeCodeCache.h"\ + "..\..\..\Compiler\CodeGenerator\NativeFormatter.h"\ + "..\..\..\Compiler\FrontEnd\BytecodeGraph.h"\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Compiler\FrontEnd\LocalEnv.h"\ + "..\..\..\Compiler\FrontEnd\TranslationEnv.h"\ + "..\..\..\Compiler\FrontEnd\VerificationEnv.h"\ + "..\..\..\Compiler\Optimizer\PrimitiveOptimizer.h"\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlGraph.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlNodes.h"\ + "..\..\..\Compiler\PrimitiveGraph\PrimitiveOperations.h"\ + "..\..\..\Compiler\PrimitiveGraph\Primitives.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Compiler\RegisterAllocator\VirtualRegister.h"\ + "..\..\..\Debugger\Communication\DebuggerChannel.h"\ + "..\..\..\Debugger\Debugger.h"\ + "..\..\..\Runtime\ClassInfo\ClassCentral.h"\ + "..\..\..\Runtime\ClassInfo\ClassFileSummary.h"\ + "..\..\..\Runtime\ClassInfo\Collector.h"\ + "..\..\..\Runtime\ClassInfo\PathComponent.h"\ + "..\..\..\Runtime\ClassInfo\StringPool.h"\ + "..\..\..\Runtime\ClassReader\Attributes.h"\ + "..\..\..\Runtime\ClassReader\ClassReader.h"\ + "..\..\..\Runtime\ClassReader\ConstantPool.h"\ + "..\..\..\Runtime\ClassReader\InfoItem.h"\ + "..\..\..\Runtime\ClassReader\utils.h"\ + "..\..\..\Runtime\FileReader\FileReader.h"\ + "..\..\..\Runtime\FileReader\ZipArchive.h"\ + "..\..\..\Runtime\NativeMethods\NameMangler.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\NativeMethods\NativeMethodDispatcher.h"\ + "..\..\..\Runtime\System\ClassWorld.h"\ + "..\..\..\Runtime\System\FieldOrMethod.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Runtime\System\JavaString.h"\ + "..\..\..\Runtime\System\JavaVM.h"\ + "..\..\..\Runtime\System\Method.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\CheckedUnion.h"\ + "..\..\..\Utilities\General\DebugUtils.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FastBitMatrix.h"\ + "..\..\..\Utilities\General\FastBitSet.h"\ + "..\..\..\Utilities\General\FastHashTable.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\InterestingEvents.h"\ + "..\..\..\Utilities\General\JavaBytecodes.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\Nonspr.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + "..\..\..\Utilities\zlib\zconf.h"\ + "..\..\..\Utilities\zlib\zlib.h"\ + +NODEP_CPP_NATIVEF=\ + "..\..\..\Compiler\CodeGenerator\md\HPPACpu.h"\ + "..\..\..\Compiler\CodeGenerator\md\PPC601Cpu.h"\ + "..\..\..\Compiler\CodeGenerator\prmon.h"\ + "..\..\..\Compiler\CodeGenerator\prtypes.h"\ + "..\..\..\Debugger\Communication\prio.h"\ + "..\..\..\Debugger\Communication\prlock.h"\ + "..\..\..\Debugger\Communication\prprf.h"\ + "..\..\..\Debugger\nspr.h"\ + "..\..\..\Runtime\ClassReader\prtypes.h"\ + "..\..\..\Runtime\FileReader\prio.h"\ + "..\..\..\Runtime\FileReader\prtypes.h"\ + "..\..\..\Runtime\NativeMethods\prlink.h"\ + "..\..\..\Runtime\System\plstr.h"\ + "..\..\..\Runtime\System\prprf.h"\ + "..\..\..\Utilities\General\plstr.h"\ + "..\..\..\Utilities\General\prbit.h"\ + "..\..\..\Utilities\General\prlog.h"\ + "..\..\..\Utilities\General\prlong.h"\ + + +"$(INTDIR)\NativeFormatter.obj" "$(INTDIR)\NativeFormatter.sbr" : $(SOURCE)\ + $(DEP_CPP_NATIVEF) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "electricalfire - Win32 Debug" + +DEP_CPP_NATIVEF=\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\nspr.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\obsolete\protypes.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\plstr.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\pratom.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prbit.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prclist.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcmon.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcpucfg.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcvar.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prdtoa.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prenv.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prerror.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinet.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinit.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinrval.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prio.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlink.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlock.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlog.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlong.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prmem.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prmon.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prnetdb.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prprf.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prproces.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prsystem.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prthread.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtime.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtypes.h"\ + "..\..\..\Compiler\CodeGenerator\ExceptionTable.h"\ + "..\..\..\Compiler\CodeGenerator\FormatStructures.h"\ + "..\..\..\Compiler\CodeGenerator\Instruction.h"\ + "..\..\..\Compiler\CodeGenerator\InstructionEmitter.h"\ + "..\..\..\Compiler\CodeGenerator\md\CpuInfo.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Formatter.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Opcode.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Cpu.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Emitter.h"\ + "..\..\..\Compiler\CodeGenerator\NativeCodeCache.h"\ + "..\..\..\Compiler\CodeGenerator\NativeFormatter.h"\ + "..\..\..\Compiler\FrontEnd\BytecodeGraph.h"\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Compiler\FrontEnd\LocalEnv.h"\ + "..\..\..\Compiler\FrontEnd\TranslationEnv.h"\ + "..\..\..\Compiler\FrontEnd\VerificationEnv.h"\ + "..\..\..\Compiler\Optimizer\PrimitiveOptimizer.h"\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlGraph.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlNodes.h"\ + "..\..\..\Compiler\PrimitiveGraph\PrimitiveOperations.h"\ + "..\..\..\Compiler\PrimitiveGraph\Primitives.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Compiler\RegisterAllocator\VirtualRegister.h"\ + "..\..\..\Debugger\Communication\DebuggerChannel.h"\ + "..\..\..\Debugger\Debugger.h"\ + "..\..\..\Runtime\ClassInfo\ClassCentral.h"\ + "..\..\..\Runtime\ClassInfo\ClassFileSummary.h"\ + "..\..\..\Runtime\ClassInfo\Collector.h"\ + "..\..\..\Runtime\ClassInfo\PathComponent.h"\ + "..\..\..\Runtime\ClassInfo\StringPool.h"\ + "..\..\..\Runtime\ClassReader\Attributes.h"\ + "..\..\..\Runtime\ClassReader\ClassReader.h"\ + "..\..\..\Runtime\ClassReader\ConstantPool.h"\ + "..\..\..\Runtime\ClassReader\InfoItem.h"\ + "..\..\..\Runtime\ClassReader\utils.h"\ + "..\..\..\Runtime\FileReader\FileReader.h"\ + "..\..\..\Runtime\FileReader\ZipArchive.h"\ + "..\..\..\Runtime\NativeMethods\NameMangler.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\NativeMethods\NativeMethodDispatcher.h"\ + "..\..\..\Runtime\System\ClassWorld.h"\ + "..\..\..\Runtime\System\FieldOrMethod.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Runtime\System\JavaString.h"\ + "..\..\..\Runtime\System\JavaVM.h"\ + "..\..\..\Runtime\System\Method.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\CheckedUnion.h"\ + "..\..\..\Utilities\General\DebugUtils.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FastBitMatrix.h"\ + "..\..\..\Utilities\General\FastBitSet.h"\ + "..\..\..\Utilities\General\FastHashTable.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\InterestingEvents.h"\ + "..\..\..\Utilities\General\JavaBytecodes.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + "..\..\..\Utilities\zlib\zconf.h"\ + "..\..\..\Utilities\zlib\zlib.h"\ + + +"$(INTDIR)\NativeFormatter.obj" "$(INTDIR)\NativeFormatter.sbr" : $(SOURCE)\ + $(DEP_CPP_NATIVEF) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +SOURCE=..\..\..\Compiler\CodeGenerator\Scheduler.cpp + +!IF "$(CFG)" == "electricalfire - Win32 Release" + +DEP_CPP_SCHED=\ + "..\..\..\Compiler\CodeGenerator\CodeGenerator.h"\ + "..\..\..\Compiler\CodeGenerator\FormatStructures.h"\ + "..\..\..\Compiler\CodeGenerator\Instruction.h"\ + "..\..\..\Compiler\CodeGenerator\InstructionEmitter.h"\ + "..\..\..\Compiler\CodeGenerator\md\CpuInfo.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Formatter.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Opcode.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Cpu.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Emitter.h"\ + "..\..\..\Compiler\CodeGenerator\Scheduler.h"\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlNodes.h"\ + "..\..\..\Compiler\PrimitiveGraph\PrimitiveOperations.h"\ + "..\..\..\Compiler\PrimitiveGraph\Primitives.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Compiler\RegisterAllocator\VirtualRegister.h"\ + "..\..\..\Runtime\ClassReader\Attributes.h"\ + "..\..\..\Runtime\ClassReader\ConstantPool.h"\ + "..\..\..\Runtime\ClassReader\utils.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\System\ClassWorld.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FastBitMatrix.h"\ + "..\..\..\Utilities\General\FastBitSet.h"\ + "..\..\..\Utilities\General\FastHashTable.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\Nonspr.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + +NODEP_CPP_SCHED=\ + "..\..\..\Compiler\CodeGenerator\md\HPPACpu.h"\ + "..\..\..\Compiler\CodeGenerator\md\PPC601Cpu.h"\ + "..\..\..\Compiler\CodeGenerator\prtypes.h"\ + "..\..\..\Runtime\ClassReader\prtypes.h"\ + "..\..\..\Utilities\General\plstr.h"\ + "..\..\..\Utilities\General\prbit.h"\ + "..\..\..\Utilities\General\prlog.h"\ + "..\..\..\Utilities\General\prlong.h"\ + + +"$(INTDIR)\Scheduler.obj" "$(INTDIR)\Scheduler.sbr" : $(SOURCE)\ + $(DEP_CPP_SCHED) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "electricalfire - Win32 Debug" + +DEP_CPP_SCHED=\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\obsolete\protypes.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prbit.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcpucfg.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinet.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinrval.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prio.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlog.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlong.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtime.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtypes.h"\ + "..\..\..\Compiler\CodeGenerator\CodeGenerator.h"\ + "..\..\..\Compiler\CodeGenerator\Instruction.h"\ + "..\..\..\Compiler\CodeGenerator\md\CpuInfo.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Cpu.h"\ + "..\..\..\Compiler\CodeGenerator\Scheduler.h"\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlNodes.h"\ + "..\..\..\Compiler\PrimitiveGraph\PrimitiveOperations.h"\ + "..\..\..\Compiler\PrimitiveGraph\Primitives.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Compiler\RegisterAllocator\VirtualRegister.h"\ + "..\..\..\Runtime\ClassReader\Attributes.h"\ + "..\..\..\Runtime\ClassReader\ConstantPool.h"\ + "..\..\..\Runtime\ClassReader\utils.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\System\ClassWorld.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FastBitMatrix.h"\ + "..\..\..\Utilities\General\FastBitSet.h"\ + "..\..\..\Utilities\General\FastHashTable.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + + +"$(INTDIR)\Scheduler.obj" "$(INTDIR)\Scheduler.sbr" : $(SOURCE)\ + $(DEP_CPP_SCHED) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +SOURCE=..\..\..\Compiler\RegisterAllocator\Coloring.cpp + +!IF "$(CFG)" == "electricalfire - Win32 Release" + +DEP_CPP_COLOR=\ + "..\..\..\Compiler\CodeGenerator\FormatStructures.h"\ + "..\..\..\Compiler\CodeGenerator\Instruction.h"\ + "..\..\..\Compiler\CodeGenerator\InstructionEmitter.h"\ + "..\..\..\Compiler\CodeGenerator\md\CpuInfo.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Formatter.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Opcode.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Cpu.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Emitter.h"\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlNodes.h"\ + "..\..\..\Compiler\PrimitiveGraph\PrimitiveOperations.h"\ + "..\..\..\Compiler\PrimitiveGraph\Primitives.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Compiler\RegisterAllocator\Coloring.h"\ + "..\..\..\Compiler\RegisterAllocator\RegisterAssigner.h"\ + "..\..\..\Compiler\RegisterAllocator\VirtualRegister.h"\ + "..\..\..\Runtime\ClassReader\Attributes.h"\ + "..\..\..\Runtime\ClassReader\ConstantPool.h"\ + "..\..\..\Runtime\ClassReader\utils.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\System\ClassWorld.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FastBitMatrix.h"\ + "..\..\..\Utilities\General\FastBitSet.h"\ + "..\..\..\Utilities\General\FastHashTable.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\Nonspr.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + +NODEP_CPP_COLOR=\ + "..\..\..\Compiler\CodeGenerator\md\HPPACpu.h"\ + "..\..\..\Compiler\CodeGenerator\md\PPC601Cpu.h"\ + "..\..\..\Compiler\CodeGenerator\prtypes.h"\ + "..\..\..\Runtime\ClassReader\prtypes.h"\ + "..\..\..\Utilities\General\plstr.h"\ + "..\..\..\Utilities\General\prbit.h"\ + "..\..\..\Utilities\General\prlog.h"\ + "..\..\..\Utilities\General\prlong.h"\ + + +"$(INTDIR)\Coloring.obj" "$(INTDIR)\Coloring.sbr" : $(SOURCE) $(DEP_CPP_COLOR)\ + "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "electricalfire - Win32 Debug" + +DEP_CPP_COLOR=\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\obsolete\protypes.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prbit.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcpucfg.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinet.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinrval.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prio.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlog.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlong.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtime.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtypes.h"\ + "..\..\..\Compiler\CodeGenerator\md\CpuInfo.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Cpu.h"\ + "..\..\..\Compiler\RegisterAllocator\Coloring.h"\ + "..\..\..\Compiler\RegisterAllocator\RegisterAssigner.h"\ + "..\..\..\Compiler\RegisterAllocator\VirtualRegister.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FastBitMatrix.h"\ + "..\..\..\Utilities\General\FastBitSet.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\Pool.h"\ + + +"$(INTDIR)\Coloring.obj" "$(INTDIR)\Coloring.sbr" : $(SOURCE) $(DEP_CPP_COLOR)\ + "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +SOURCE=..\..\..\Compiler\RegisterAllocator\RegisterAllocator.cpp + +!IF "$(CFG)" == "electricalfire - Win32 Release" + +DEP_CPP_REGIS=\ + "..\..\..\Compiler\CodeGenerator\FormatStructures.h"\ + "..\..\..\Compiler\CodeGenerator\Instruction.h"\ + "..\..\..\Compiler\CodeGenerator\InstructionEmitter.h"\ + "..\..\..\Compiler\CodeGenerator\md\CpuInfo.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Formatter.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Opcode.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Cpu.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Emitter.h"\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlGraph.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlNodes.h"\ + "..\..\..\Compiler\PrimitiveGraph\PrimitiveOperations.h"\ + "..\..\..\Compiler\PrimitiveGraph\Primitives.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Compiler\RegisterAllocator\Coloring.h"\ + "..\..\..\Compiler\RegisterAllocator\RegisterAllocator.h"\ + "..\..\..\Compiler\RegisterAllocator\RegisterAssigner.h"\ + "..\..\..\Compiler\RegisterAllocator\Spilling.h"\ + "..\..\..\Compiler\RegisterAllocator\VirtualRegister.h"\ + "..\..\..\Runtime\ClassReader\Attributes.h"\ + "..\..\..\Runtime\ClassReader\ConstantPool.h"\ + "..\..\..\Runtime\ClassReader\utils.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\System\ClassWorld.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FastBitMatrix.h"\ + "..\..\..\Utilities\General\FastBitSet.h"\ + "..\..\..\Utilities\General\FastHashTable.h"\ + "..\..\..\Utilities\General\Fifo.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\Nonspr.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + +NODEP_CPP_REGIS=\ + "..\..\..\Compiler\CodeGenerator\md\HPPACpu.h"\ + "..\..\..\Compiler\CodeGenerator\md\PPC601Cpu.h"\ + "..\..\..\Compiler\CodeGenerator\prtypes.h"\ + "..\..\..\Runtime\ClassReader\prtypes.h"\ + "..\..\..\Utilities\General\plstr.h"\ + "..\..\..\Utilities\General\prbit.h"\ + "..\..\..\Utilities\General\prlog.h"\ + "..\..\..\Utilities\General\prlong.h"\ + + +"$(INTDIR)\RegisterAllocator.obj" "$(INTDIR)\RegisterAllocator.sbr" : $(SOURCE)\ + $(DEP_CPP_REGIS) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "electricalfire - Win32 Debug" + +DEP_CPP_REGIS=\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\obsolete\protypes.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prbit.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcpucfg.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinet.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinrval.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prio.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlog.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlong.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtime.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtypes.h"\ + "..\..\..\Compiler\CodeGenerator\FormatStructures.h"\ + "..\..\..\Compiler\CodeGenerator\Instruction.h"\ + "..\..\..\Compiler\CodeGenerator\InstructionEmitter.h"\ + "..\..\..\Compiler\CodeGenerator\md\CpuInfo.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Formatter.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Opcode.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Cpu.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Emitter.h"\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlGraph.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlNodes.h"\ + "..\..\..\Compiler\PrimitiveGraph\PrimitiveOperations.h"\ + "..\..\..\Compiler\PrimitiveGraph\Primitives.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Compiler\RegisterAllocator\Coloring.h"\ + "..\..\..\Compiler\RegisterAllocator\RegisterAllocator.h"\ + "..\..\..\Compiler\RegisterAllocator\RegisterAssigner.h"\ + "..\..\..\Compiler\RegisterAllocator\Spilling.h"\ + "..\..\..\Compiler\RegisterAllocator\VirtualRegister.h"\ + "..\..\..\Runtime\ClassReader\Attributes.h"\ + "..\..\..\Runtime\ClassReader\ConstantPool.h"\ + "..\..\..\Runtime\ClassReader\utils.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\System\ClassWorld.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FastBitMatrix.h"\ + "..\..\..\Utilities\General\FastBitSet.h"\ + "..\..\..\Utilities\General\FastHashTable.h"\ + "..\..\..\Utilities\General\Fifo.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + + +"$(INTDIR)\RegisterAllocator.obj" "$(INTDIR)\RegisterAllocator.sbr" : $(SOURCE)\ + $(DEP_CPP_REGIS) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +SOURCE=..\..\..\Compiler\RegisterAllocator\Spilling.cpp + +!IF "$(CFG)" == "electricalfire - Win32 Release" + +DEP_CPP_SPILL=\ + "..\..\..\Compiler\CodeGenerator\FormatStructures.h"\ + "..\..\..\Compiler\CodeGenerator\Instruction.h"\ + "..\..\..\Compiler\CodeGenerator\InstructionEmitter.h"\ + "..\..\..\Compiler\CodeGenerator\md\CpuInfo.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Formatter.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Opcode.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Cpu.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Emitter.h"\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlNodes.h"\ + "..\..\..\Compiler\PrimitiveGraph\PrimitiveOperations.h"\ + "..\..\..\Compiler\PrimitiveGraph\Primitives.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Compiler\RegisterAllocator\Spilling.h"\ + "..\..\..\Compiler\RegisterAllocator\VirtualRegister.h"\ + "..\..\..\Runtime\ClassReader\Attributes.h"\ + "..\..\..\Runtime\ClassReader\ConstantPool.h"\ + "..\..\..\Runtime\ClassReader\utils.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\System\ClassWorld.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FastBitMatrix.h"\ + "..\..\..\Utilities\General\FastBitSet.h"\ + "..\..\..\Utilities\General\FastHashTable.h"\ + "..\..\..\Utilities\General\Fifo.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\Nonspr.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + +NODEP_CPP_SPILL=\ + "..\..\..\Compiler\CodeGenerator\md\HPPACpu.h"\ + "..\..\..\Compiler\CodeGenerator\md\PPC601Cpu.h"\ + "..\..\..\Compiler\CodeGenerator\prtypes.h"\ + "..\..\..\Runtime\ClassReader\prtypes.h"\ + "..\..\..\Utilities\General\plstr.h"\ + "..\..\..\Utilities\General\prbit.h"\ + "..\..\..\Utilities\General\prlog.h"\ + "..\..\..\Utilities\General\prlong.h"\ + + +"$(INTDIR)\Spilling.obj" "$(INTDIR)\Spilling.sbr" : $(SOURCE) $(DEP_CPP_SPILL)\ + "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "electricalfire - Win32 Debug" + +DEP_CPP_SPILL=\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\obsolete\protypes.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prbit.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcpucfg.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinet.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinrval.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prio.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlog.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlong.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtime.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtypes.h"\ + "..\..\..\Compiler\CodeGenerator\FormatStructures.h"\ + "..\..\..\Compiler\CodeGenerator\Instruction.h"\ + "..\..\..\Compiler\CodeGenerator\InstructionEmitter.h"\ + "..\..\..\Compiler\CodeGenerator\md\CpuInfo.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Formatter.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Opcode.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Cpu.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Emitter.h"\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlNodes.h"\ + "..\..\..\Compiler\PrimitiveGraph\PrimitiveOperations.h"\ + "..\..\..\Compiler\PrimitiveGraph\Primitives.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Compiler\RegisterAllocator\Spilling.h"\ + "..\..\..\Compiler\RegisterAllocator\VirtualRegister.h"\ + "..\..\..\Runtime\ClassReader\Attributes.h"\ + "..\..\..\Runtime\ClassReader\ConstantPool.h"\ + "..\..\..\Runtime\ClassReader\utils.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\System\ClassWorld.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FastBitMatrix.h"\ + "..\..\..\Utilities\General\FastBitSet.h"\ + "..\..\..\Utilities\General\FastHashTable.h"\ + "..\..\..\Utilities\General\Fifo.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + + +"$(INTDIR)\Spilling.obj" "$(INTDIR)\Spilling.sbr" : $(SOURCE) $(DEP_CPP_SPILL)\ + "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +SOURCE=..\..\..\Compiler\RegisterAllocator\VirtualRegister.cpp + +!IF "$(CFG)" == "electricalfire - Win32 Release" + +DEP_CPP_VIRTU=\ + "..\..\..\Compiler\CodeGenerator\FormatStructures.h"\ + "..\..\..\Compiler\CodeGenerator\Instruction.h"\ + "..\..\..\Compiler\CodeGenerator\InstructionEmitter.h"\ + "..\..\..\Compiler\CodeGenerator\md\CpuInfo.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Formatter.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Opcode.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Cpu.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Emitter.h"\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlNodes.h"\ + "..\..\..\Compiler\PrimitiveGraph\PrimitiveOperations.h"\ + "..\..\..\Compiler\PrimitiveGraph\Primitives.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Compiler\RegisterAllocator\VirtualRegister.h"\ + "..\..\..\Runtime\ClassReader\Attributes.h"\ + "..\..\..\Runtime\ClassReader\ConstantPool.h"\ + "..\..\..\Runtime\ClassReader\utils.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\System\ClassWorld.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FastBitMatrix.h"\ + "..\..\..\Utilities\General\FastBitSet.h"\ + "..\..\..\Utilities\General\FastHashTable.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\Nonspr.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + +NODEP_CPP_VIRTU=\ + "..\..\..\Compiler\CodeGenerator\md\HPPACpu.h"\ + "..\..\..\Compiler\CodeGenerator\md\PPC601Cpu.h"\ + "..\..\..\Compiler\CodeGenerator\prtypes.h"\ + "..\..\..\Runtime\ClassReader\prtypes.h"\ + "..\..\..\Utilities\General\plstr.h"\ + "..\..\..\Utilities\General\prbit.h"\ + "..\..\..\Utilities\General\prlog.h"\ + "..\..\..\Utilities\General\prlong.h"\ + + +"$(INTDIR)\VirtualRegister.obj" "$(INTDIR)\VirtualRegister.sbr" : $(SOURCE)\ + $(DEP_CPP_VIRTU) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "electricalfire - Win32 Debug" + +DEP_CPP_VIRTU=\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\obsolete\protypes.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prbit.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcpucfg.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinet.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinrval.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prio.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlog.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlong.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtime.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtypes.h"\ + "..\..\..\Compiler\CodeGenerator\md\CpuInfo.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Cpu.h"\ + "..\..\..\Compiler\RegisterAllocator\VirtualRegister.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FastBitMatrix.h"\ + "..\..\..\Utilities\General\FastBitSet.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\Pool.h"\ + + +"$(INTDIR)\VirtualRegister.obj" "$(INTDIR)\VirtualRegister.sbr" : $(SOURCE)\ + $(DEP_CPP_VIRTU) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +SOURCE=..\..\..\Compiler\Optimizer\PrimitiveOptimizer.cpp + +!IF "$(CFG)" == "electricalfire - Win32 Release" + +DEP_CPP_PRIMI=\ + "..\..\..\Compiler\CodeGenerator\FormatStructures.h"\ + "..\..\..\Compiler\CodeGenerator\Instruction.h"\ + "..\..\..\Compiler\CodeGenerator\InstructionEmitter.h"\ + "..\..\..\Compiler\CodeGenerator\md\CpuInfo.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Formatter.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Opcode.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Cpu.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Emitter.h"\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Compiler\Optimizer\PrimitiveOptimizer.h"\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlGraph.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlNodes.h"\ + "..\..\..\Compiler\PrimitiveGraph\PrimitiveOperations.h"\ + "..\..\..\Compiler\PrimitiveGraph\Primitives.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Compiler\RegisterAllocator\VirtualRegister.h"\ + "..\..\..\Runtime\ClassReader\Attributes.h"\ + "..\..\..\Runtime\ClassReader\ConstantPool.h"\ + "..\..\..\Runtime\ClassReader\utils.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\System\ClassWorld.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FastBitMatrix.h"\ + "..\..\..\Utilities\General\FastBitSet.h"\ + "..\..\..\Utilities\General\FastHashTable.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\Nonspr.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + +NODEP_CPP_PRIMI=\ + "..\..\..\Compiler\CodeGenerator\md\HPPACpu.h"\ + "..\..\..\Compiler\CodeGenerator\md\PPC601Cpu.h"\ + "..\..\..\Compiler\CodeGenerator\prtypes.h"\ + "..\..\..\Runtime\ClassReader\prtypes.h"\ + "..\..\..\Utilities\General\plstr.h"\ + "..\..\..\Utilities\General\prbit.h"\ + "..\..\..\Utilities\General\prlog.h"\ + "..\..\..\Utilities\General\prlong.h"\ + + +"$(INTDIR)\PrimitiveOptimizer.obj" "$(INTDIR)\PrimitiveOptimizer.sbr" : \ +$(SOURCE) $(DEP_CPP_PRIMI) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "electricalfire - Win32 Debug" + +DEP_CPP_PRIMI=\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\obsolete\protypes.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prbit.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcpucfg.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinet.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinrval.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prio.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlog.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlong.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtime.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtypes.h"\ + "..\..\..\Compiler\CodeGenerator\Instruction.h"\ + "..\..\..\Compiler\CodeGenerator\md\CpuInfo.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Cpu.h"\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Compiler\Optimizer\PrimitiveOptimizer.h"\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlGraph.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlNodes.h"\ + "..\..\..\Compiler\PrimitiveGraph\PrimitiveOperations.h"\ + "..\..\..\Compiler\PrimitiveGraph\Primitives.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Compiler\RegisterAllocator\VirtualRegister.h"\ + "..\..\..\Runtime\ClassReader\Attributes.h"\ + "..\..\..\Runtime\ClassReader\ConstantPool.h"\ + "..\..\..\Runtime\ClassReader\utils.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\System\ClassWorld.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FastBitMatrix.h"\ + "..\..\..\Utilities\General\FastBitSet.h"\ + "..\..\..\Utilities\General\FastHashTable.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + + +"$(INTDIR)\PrimitiveOptimizer.obj" "$(INTDIR)\PrimitiveOptimizer.sbr" : \ +$(SOURCE) $(DEP_CPP_PRIMI) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +SOURCE=..\..\..\Compiler\PrimitiveGraph\Address.cpp + +!IF "$(CFG)" == "electricalfire - Win32 Release" + +DEP_CPP_ADDRE=\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\Nonspr.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + +NODEP_CPP_ADDRE=\ + "..\..\..\Utilities\General\plstr.h"\ + "..\..\..\Utilities\General\prlog.h"\ + "..\..\..\Utilities\General\prlong.h"\ + + +"$(INTDIR)\Address.obj" "$(INTDIR)\Address.sbr" : $(SOURCE) $(DEP_CPP_ADDRE)\ + "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "electricalfire - Win32 Debug" + +DEP_CPP_ADDRE=\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\obsolete\protypes.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcpucfg.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinet.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinrval.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prio.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlog.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlong.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtime.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtypes.h"\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + + +"$(INTDIR)\Address.obj" "$(INTDIR)\Address.sbr" : $(SOURCE) $(DEP_CPP_ADDRE)\ + "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +SOURCE=..\..\..\Compiler\PrimitiveGraph\ControlGraph.cpp + +!IF "$(CFG)" == "electricalfire - Win32 Release" + +DEP_CPP_CONTR=\ + "..\..\..\Compiler\CodeGenerator\CodeGenerator.h"\ + "..\..\..\Compiler\CodeGenerator\FormatStructures.h"\ + "..\..\..\Compiler\CodeGenerator\IGVisualizer.h"\ + "..\..\..\Compiler\CodeGenerator\Instruction.h"\ + "..\..\..\Compiler\CodeGenerator\InstructionEmitter.h"\ + "..\..\..\Compiler\CodeGenerator\md\CpuInfo.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Formatter.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Opcode.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Cpu.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Emitter.h"\ + "..\..\..\Compiler\CodeGenerator\NativeFormatter.h"\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlGraph.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlNodes.h"\ + "..\..\..\Compiler\PrimitiveGraph\PrimitiveOperations.h"\ + "..\..\..\Compiler\PrimitiveGraph\Primitives.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Compiler\RegisterAllocator\VirtualRegister.h"\ + "..\..\..\Runtime\ClassReader\Attributes.h"\ + "..\..\..\Runtime\ClassReader\ConstantPool.h"\ + "..\..\..\Runtime\ClassReader\utils.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\System\ClassWorld.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FastBitMatrix.h"\ + "..\..\..\Utilities\General\FastBitSet.h"\ + "..\..\..\Utilities\General\FastHashTable.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\GraphUtils.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\Nonspr.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + +NODEP_CPP_CONTR=\ + "..\..\..\Compiler\CodeGenerator\md\HPPACpu.h"\ + "..\..\..\Compiler\CodeGenerator\md\PPC601Cpu.h"\ + "..\..\..\Compiler\CodeGenerator\prtypes.h"\ + "..\..\..\Runtime\ClassReader\prtypes.h"\ + "..\..\..\Utilities\General\plstr.h"\ + "..\..\..\Utilities\General\prbit.h"\ + "..\..\..\Utilities\General\prlog.h"\ + "..\..\..\Utilities\General\prlong.h"\ + + +"$(INTDIR)\ControlGraph.obj" "$(INTDIR)\ControlGraph.sbr" : $(SOURCE)\ + $(DEP_CPP_CONTR) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "electricalfire - Win32 Debug" + +DEP_CPP_CONTR=\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\obsolete\protypes.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prbit.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcpucfg.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinet.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinrval.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prio.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlog.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlong.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtime.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtypes.h"\ + "..\..\..\Compiler\CodeGenerator\CodeGenerator.h"\ + "..\..\..\Compiler\CodeGenerator\FormatStructures.h"\ + "..\..\..\Compiler\CodeGenerator\Instruction.h"\ + "..\..\..\Compiler\CodeGenerator\InstructionEmitter.h"\ + "..\..\..\Compiler\CodeGenerator\md\CpuInfo.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Formatter.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Opcode.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Cpu.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Emitter.h"\ + "..\..\..\Compiler\CodeGenerator\NativeFormatter.h"\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlGraph.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlNodes.h"\ + "..\..\..\Compiler\PrimitiveGraph\PrimitiveOperations.h"\ + "..\..\..\Compiler\PrimitiveGraph\Primitives.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Compiler\RegisterAllocator\VirtualRegister.h"\ + "..\..\..\Runtime\ClassReader\Attributes.h"\ + "..\..\..\Runtime\ClassReader\ConstantPool.h"\ + "..\..\..\Runtime\ClassReader\utils.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\System\ClassWorld.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FastBitMatrix.h"\ + "..\..\..\Utilities\General\FastBitSet.h"\ + "..\..\..\Utilities\General\FastHashTable.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\GraphUtils.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + + +"$(INTDIR)\ControlGraph.obj" "$(INTDIR)\ControlGraph.sbr" : $(SOURCE)\ + $(DEP_CPP_CONTR) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +SOURCE=..\..\..\Compiler\PrimitiveGraph\ControlNodes.cpp + +!IF "$(CFG)" == "electricalfire - Win32 Release" + +DEP_CPP_CONTRO=\ + "..\..\..\Compiler\CodeGenerator\FormatStructures.h"\ + "..\..\..\Compiler\CodeGenerator\Instruction.h"\ + "..\..\..\Compiler\CodeGenerator\InstructionEmitter.h"\ + "..\..\..\Compiler\CodeGenerator\md\CpuInfo.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Formatter.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Opcode.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Cpu.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Emitter.h"\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlGraph.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlNodes.h"\ + "..\..\..\Compiler\PrimitiveGraph\PrimitiveOperations.h"\ + "..\..\..\Compiler\PrimitiveGraph\Primitives.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Compiler\RegisterAllocator\VirtualRegister.h"\ + "..\..\..\Runtime\ClassReader\Attributes.h"\ + "..\..\..\Runtime\ClassReader\ConstantPool.h"\ + "..\..\..\Runtime\ClassReader\utils.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\System\ClassWorld.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\DebugUtils.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FastBitMatrix.h"\ + "..\..\..\Utilities\General\FastBitSet.h"\ + "..\..\..\Utilities\General\FastHashTable.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\Nonspr.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + +NODEP_CPP_CONTRO=\ + "..\..\..\Compiler\CodeGenerator\md\HPPACpu.h"\ + "..\..\..\Compiler\CodeGenerator\md\PPC601Cpu.h"\ + "..\..\..\Compiler\CodeGenerator\prtypes.h"\ + "..\..\..\Runtime\ClassReader\prtypes.h"\ + "..\..\..\Utilities\General\plstr.h"\ + "..\..\..\Utilities\General\prbit.h"\ + "..\..\..\Utilities\General\prlog.h"\ + "..\..\..\Utilities\General\prlong.h"\ + + +"$(INTDIR)\ControlNodes.obj" "$(INTDIR)\ControlNodes.sbr" : $(SOURCE)\ + $(DEP_CPP_CONTRO) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "electricalfire - Win32 Debug" + +DEP_CPP_CONTRO=\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\obsolete\protypes.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prbit.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcpucfg.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinet.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinrval.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prio.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlog.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlong.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtime.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtypes.h"\ + "..\..\..\Compiler\CodeGenerator\Instruction.h"\ + "..\..\..\Compiler\CodeGenerator\md\CpuInfo.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Cpu.h"\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlGraph.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlNodes.h"\ + "..\..\..\Compiler\PrimitiveGraph\PrimitiveOperations.h"\ + "..\..\..\Compiler\PrimitiveGraph\Primitives.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Compiler\RegisterAllocator\VirtualRegister.h"\ + "..\..\..\Runtime\ClassReader\Attributes.h"\ + "..\..\..\Runtime\ClassReader\ConstantPool.h"\ + "..\..\..\Runtime\ClassReader\utils.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\System\ClassWorld.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\DebugUtils.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FastBitMatrix.h"\ + "..\..\..\Utilities\General\FastBitSet.h"\ + "..\..\..\Utilities\General\FastHashTable.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + + +"$(INTDIR)\ControlNodes.obj" "$(INTDIR)\ControlNodes.sbr" : $(SOURCE)\ + $(DEP_CPP_CONTRO) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +SOURCE=..\..\..\Compiler\PrimitiveGraph\PrimitiveBuilders.cpp + +!IF "$(CFG)" == "electricalfire - Win32 Release" + +DEP_CPP_PRIMIT=\ + "..\..\..\Compiler\CodeGenerator\FormatStructures.h"\ + "..\..\..\Compiler\CodeGenerator\Instruction.h"\ + "..\..\..\Compiler\CodeGenerator\InstructionEmitter.h"\ + "..\..\..\Compiler\CodeGenerator\md\CpuInfo.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Formatter.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Opcode.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Cpu.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Emitter.h"\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlGraph.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlNodes.h"\ + "..\..\..\Compiler\PrimitiveGraph\PrimitiveBuilders.h"\ + "..\..\..\Compiler\PrimitiveGraph\PrimitiveOperations.h"\ + "..\..\..\Compiler\PrimitiveGraph\Primitives.h"\ + "..\..\..\Compiler\PrimitiveGraph\SysCalls.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Compiler\RegisterAllocator\VirtualRegister.h"\ + "..\..\..\Runtime\ClassReader\Attributes.h"\ + "..\..\..\Runtime\ClassReader\ConstantPool.h"\ + "..\..\..\Runtime\ClassReader\utils.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\System\ClassWorld.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Runtime\System\Method.h"\ + "..\..\..\Runtime\System\SysCallsRuntime.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FastBitMatrix.h"\ + "..\..\..\Utilities\General\FastBitSet.h"\ + "..\..\..\Utilities\General\FastHashTable.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\Nonspr.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + +NODEP_CPP_PRIMIT=\ + "..\..\..\Compiler\CodeGenerator\md\HPPACpu.h"\ + "..\..\..\Compiler\CodeGenerator\md\PPC601Cpu.h"\ + "..\..\..\Compiler\CodeGenerator\prtypes.h"\ + "..\..\..\Runtime\ClassReader\prtypes.h"\ + "..\..\..\Utilities\General\plstr.h"\ + "..\..\..\Utilities\General\prbit.h"\ + "..\..\..\Utilities\General\prlog.h"\ + "..\..\..\Utilities\General\prlong.h"\ + + +"$(INTDIR)\PrimitiveBuilders.obj" "$(INTDIR)\PrimitiveBuilders.sbr" : $(SOURCE)\ + $(DEP_CPP_PRIMIT) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "electricalfire - Win32 Debug" + +DEP_CPP_PRIMIT=\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\obsolete\protypes.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prbit.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcpucfg.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinet.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinrval.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prio.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlog.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlong.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtime.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtypes.h"\ + "..\..\..\Compiler\CodeGenerator\Instruction.h"\ + "..\..\..\Compiler\CodeGenerator\md\CpuInfo.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Cpu.h"\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlGraph.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlNodes.h"\ + "..\..\..\Compiler\PrimitiveGraph\PrimitiveBuilders.h"\ + "..\..\..\Compiler\PrimitiveGraph\PrimitiveOperations.h"\ + "..\..\..\Compiler\PrimitiveGraph\Primitives.h"\ + "..\..\..\Compiler\PrimitiveGraph\SysCalls.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Compiler\RegisterAllocator\VirtualRegister.h"\ + "..\..\..\Runtime\ClassReader\Attributes.h"\ + "..\..\..\Runtime\ClassReader\ConstantPool.h"\ + "..\..\..\Runtime\ClassReader\utils.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\System\ClassWorld.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Runtime\System\Method.h"\ + "..\..\..\Runtime\System\SysCallsRuntime.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FastBitMatrix.h"\ + "..\..\..\Utilities\General\FastBitSet.h"\ + "..\..\..\Utilities\General\FastHashTable.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + + +"$(INTDIR)\PrimitiveBuilders.obj" "$(INTDIR)\PrimitiveBuilders.sbr" : $(SOURCE)\ + $(DEP_CPP_PRIMIT) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +SOURCE=..\..\..\Compiler\PrimitiveGraph\PrimitiveGraphVerifier.cpp + +!IF "$(CFG)" == "electricalfire - Win32 Release" + +DEP_CPP_PRIMITI=\ + "..\..\..\Compiler\CodeGenerator\FormatStructures.h"\ + "..\..\..\Compiler\CodeGenerator\Instruction.h"\ + "..\..\..\Compiler\CodeGenerator\InstructionEmitter.h"\ + "..\..\..\Compiler\CodeGenerator\md\CpuInfo.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Formatter.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Opcode.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Cpu.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Emitter.h"\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlGraph.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlNodes.h"\ + "..\..\..\Compiler\PrimitiveGraph\PrimitiveOperations.h"\ + "..\..\..\Compiler\PrimitiveGraph\Primitives.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Compiler\RegisterAllocator\VirtualRegister.h"\ + "..\..\..\Runtime\ClassReader\Attributes.h"\ + "..\..\..\Runtime\ClassReader\ConstantPool.h"\ + "..\..\..\Runtime\ClassReader\utils.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\System\ClassWorld.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FastBitMatrix.h"\ + "..\..\..\Utilities\General\FastBitSet.h"\ + "..\..\..\Utilities\General\FastHashTable.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\GraphUtils.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\Nonspr.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + +NODEP_CPP_PRIMITI=\ + "..\..\..\Compiler\CodeGenerator\md\HPPACpu.h"\ + "..\..\..\Compiler\CodeGenerator\md\PPC601Cpu.h"\ + "..\..\..\Compiler\CodeGenerator\prtypes.h"\ + "..\..\..\Runtime\ClassReader\prtypes.h"\ + "..\..\..\Utilities\General\plstr.h"\ + "..\..\..\Utilities\General\prbit.h"\ + "..\..\..\Utilities\General\prlog.h"\ + "..\..\..\Utilities\General\prlong.h"\ + + +"$(INTDIR)\PrimitiveGraphVerifier.obj" "$(INTDIR)\PrimitiveGraphVerifier.sbr" :\ + $(SOURCE) $(DEP_CPP_PRIMITI) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "electricalfire - Win32 Debug" + +DEP_CPP_PRIMITI=\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\obsolete\protypes.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prbit.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcpucfg.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinet.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinrval.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prio.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlog.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlong.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtime.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtypes.h"\ + "..\..\..\Compiler\CodeGenerator\Instruction.h"\ + "..\..\..\Compiler\CodeGenerator\md\CpuInfo.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Cpu.h"\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlGraph.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlNodes.h"\ + "..\..\..\Compiler\PrimitiveGraph\PrimitiveOperations.h"\ + "..\..\..\Compiler\PrimitiveGraph\Primitives.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Compiler\RegisterAllocator\VirtualRegister.h"\ + "..\..\..\Runtime\ClassReader\Attributes.h"\ + "..\..\..\Runtime\ClassReader\ConstantPool.h"\ + "..\..\..\Runtime\ClassReader\utils.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\System\ClassWorld.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FastBitMatrix.h"\ + "..\..\..\Utilities\General\FastBitSet.h"\ + "..\..\..\Utilities\General\FastHashTable.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\GraphUtils.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + + +"$(INTDIR)\PrimitiveGraphVerifier.obj" "$(INTDIR)\PrimitiveGraphVerifier.sbr" :\ + $(SOURCE) $(DEP_CPP_PRIMITI) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +SOURCE=..\..\..\Compiler\PrimitiveGraph\PrimitiveOperations + +!IF "$(CFG)" == "electricalfire - Win32 Release" + +!ELSEIF "$(CFG)" == "electricalfire - Win32 Debug" + +InputPath=..\..\..\Compiler\PrimitiveGraph\PrimitiveOperations +InputName=PrimitiveOperations + +"genfiles\$(InputName).h" "genfiles\$(InputName).cpp" : $(SOURCE) "$(INTDIR)"\ + "$(OUTDIR)" + $(NSTOOLS)\perl5\perl -I"..\..\..\Tools\PrimitiveOperations"\ + ..\..\..\Tools\PrimitiveOperations\MakePrimOp.pl $(InputPath)\ + genfiles\$(InputName).h genfiles\$(InputName).cpp + +!ENDIF + +SOURCE=..\..\..\Compiler\PrimitiveGraph\Primitives.cpp + +!IF "$(CFG)" == "electricalfire - Win32 Release" + +DEP_CPP_PRIMITIV=\ + "..\..\..\Compiler\CodeGenerator\FormatStructures.h"\ + "..\..\..\Compiler\CodeGenerator\Instruction.h"\ + "..\..\..\Compiler\CodeGenerator\InstructionEmitter.h"\ + "..\..\..\Compiler\CodeGenerator\md\CpuInfo.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Formatter.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Opcode.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Cpu.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Emitter.h"\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlNodes.h"\ + "..\..\..\compiler\primitivegraph\primitiveoperations.cpp"\ + "..\..\..\Compiler\PrimitiveGraph\PrimitiveOperations.h"\ + "..\..\..\Compiler\PrimitiveGraph\Primitives.h"\ + "..\..\..\Compiler\PrimitiveGraph\SysCalls.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Compiler\RegisterAllocator\VirtualRegister.h"\ + "..\..\..\Debugger\Communication\DebuggerChannel.h"\ + "..\..\..\Debugger\Debugger.h"\ + "..\..\..\Runtime\ClassInfo\ClassCentral.h"\ + "..\..\..\Runtime\ClassInfo\ClassFileSummary.h"\ + "..\..\..\Runtime\ClassInfo\Collector.h"\ + "..\..\..\Runtime\ClassInfo\PathComponent.h"\ + "..\..\..\Runtime\ClassInfo\StringPool.h"\ + "..\..\..\Runtime\ClassReader\Attributes.h"\ + "..\..\..\Runtime\ClassReader\ClassReader.h"\ + "..\..\..\Runtime\ClassReader\ConstantPool.h"\ + "..\..\..\Runtime\ClassReader\InfoItem.h"\ + "..\..\..\Runtime\ClassReader\utils.h"\ + "..\..\..\Runtime\FileReader\FileReader.h"\ + "..\..\..\Runtime\FileReader\ZipArchive.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\System\ClassWorld.h"\ + "..\..\..\Runtime\System\FieldOrMethod.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Runtime\System\JavaString.h"\ + "..\..\..\Runtime\System\Method.h"\ + "..\..\..\Runtime\System\SysCallsRuntime.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\DebugUtils.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FastBitMatrix.h"\ + "..\..\..\Utilities\General\FastBitSet.h"\ + "..\..\..\Utilities\General\FastHashTable.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\InterestingEvents.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\Nonspr.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + "..\..\..\Utilities\zlib\zconf.h"\ + "..\..\..\Utilities\zlib\zlib.h"\ + +NODEP_CPP_PRIMITIV=\ + "..\..\..\Compiler\CodeGenerator\md\HPPACpu.h"\ + "..\..\..\Compiler\CodeGenerator\md\PPC601Cpu.h"\ + "..\..\..\Compiler\CodeGenerator\prtypes.h"\ + "..\..\..\Debugger\Communication\prio.h"\ + "..\..\..\Debugger\Communication\prlock.h"\ + "..\..\..\Debugger\Communication\prprf.h"\ + "..\..\..\Debugger\nspr.h"\ + "..\..\..\Runtime\ClassReader\prtypes.h"\ + "..\..\..\Runtime\FileReader\prio.h"\ + "..\..\..\Runtime\FileReader\prtypes.h"\ + "..\..\..\Runtime\System\plstr.h"\ + "..\..\..\Utilities\General\plstr.h"\ + "..\..\..\Utilities\General\prbit.h"\ + "..\..\..\Utilities\General\prlog.h"\ + "..\..\..\Utilities\General\prlong.h"\ + + +"$(INTDIR)\Primitives.obj" "$(INTDIR)\Primitives.sbr" : $(SOURCE)\ + $(DEP_CPP_PRIMITIV) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "electricalfire - Win32 Debug" + +DEP_CPP_PRIMITIV=\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\nspr.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\obsolete\protypes.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\plstr.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\pratom.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prbit.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prclist.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcmon.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcpucfg.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcvar.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prdtoa.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prenv.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prerror.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinet.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinit.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinrval.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prio.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlink.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlock.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlog.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlong.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prmem.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prmon.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prnetdb.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prprf.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prproces.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prsystem.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prthread.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtime.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtypes.h"\ + "..\..\..\Compiler\CodeGenerator\Instruction.h"\ + "..\..\..\Compiler\CodeGenerator\md\CpuInfo.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Cpu.h"\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlNodes.h"\ + "..\..\..\compiler\primitivegraph\primitiveoperations.cpp"\ + "..\..\..\Compiler\PrimitiveGraph\PrimitiveOperations.h"\ + "..\..\..\Compiler\PrimitiveGraph\Primitives.h"\ + "..\..\..\Compiler\PrimitiveGraph\SysCalls.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Compiler\RegisterAllocator\VirtualRegister.h"\ + "..\..\..\Debugger\Communication\DebuggerChannel.h"\ + "..\..\..\Debugger\Debugger.h"\ + "..\..\..\Runtime\ClassInfo\ClassCentral.h"\ + "..\..\..\Runtime\ClassInfo\ClassFileSummary.h"\ + "..\..\..\Runtime\ClassInfo\Collector.h"\ + "..\..\..\Runtime\ClassInfo\PathComponent.h"\ + "..\..\..\Runtime\ClassInfo\StringPool.h"\ + "..\..\..\Runtime\ClassReader\Attributes.h"\ + "..\..\..\Runtime\ClassReader\ClassReader.h"\ + "..\..\..\Runtime\ClassReader\ConstantPool.h"\ + "..\..\..\Runtime\ClassReader\InfoItem.h"\ + "..\..\..\Runtime\ClassReader\utils.h"\ + "..\..\..\Runtime\FileReader\FileReader.h"\ + "..\..\..\Runtime\FileReader\ZipArchive.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\System\ClassWorld.h"\ + "..\..\..\Runtime\System\FieldOrMethod.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Runtime\System\JavaString.h"\ + "..\..\..\Runtime\System\Method.h"\ + "..\..\..\Runtime\System\SysCallsRuntime.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\DebugUtils.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FastBitMatrix.h"\ + "..\..\..\Utilities\General\FastBitSet.h"\ + "..\..\..\Utilities\General\FastHashTable.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\InterestingEvents.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + "..\..\..\Utilities\zlib\zconf.h"\ + "..\..\..\Utilities\zlib\zlib.h"\ + + +"$(INTDIR)\Primitives.obj" "$(INTDIR)\Primitives.sbr" : $(SOURCE)\ + $(DEP_CPP_PRIMITIV) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +SOURCE=..\..\..\Compiler\PrimitiveGraph\SysCalls.cpp + +!IF "$(CFG)" == "electricalfire - Win32 Release" + +DEP_CPP_SYSCAL=\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\PrimitiveOperations.h"\ + "..\..\..\Compiler\PrimitiveGraph\Primitives.h"\ + "..\..\..\Compiler\PrimitiveGraph\SysCalls.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Compiler\RegisterAllocator\VirtualRegister.h"\ + "..\..\..\Runtime\ClassReader\Attributes.h"\ + "..\..\..\Runtime\ClassReader\ConstantPool.h"\ + "..\..\..\Runtime\ClassReader\utils.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Runtime\System\md\x86\x86SysCallsRuntime.h"\ + "..\..\..\Runtime\System\SysCallsRuntime.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FastBitMatrix.h"\ + "..\..\..\Utilities\General\FastBitSet.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\Nonspr.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + +NODEP_CPP_SYSCAL=\ + "..\..\..\Runtime\ClassReader\prtypes.h"\ + "..\..\..\Utilities\General\plstr.h"\ + "..\..\..\Utilities\General\prbit.h"\ + "..\..\..\Utilities\General\prlog.h"\ + "..\..\..\Utilities\General\prlong.h"\ + + +"$(INTDIR)\SysCalls.obj" "$(INTDIR)\SysCalls.sbr" : $(SOURCE) $(DEP_CPP_SYSCAL)\ + "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "electricalfire - Win32 Debug" + +DEP_CPP_SYSCAL=\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\obsolete\protypes.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prbit.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcpucfg.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinet.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinrval.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prio.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlog.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlong.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtime.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtypes.h"\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\PrimitiveOperations.h"\ + "..\..\..\Compiler\PrimitiveGraph\Primitives.h"\ + "..\..\..\Compiler\PrimitiveGraph\SysCalls.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Compiler\RegisterAllocator\VirtualRegister.h"\ + "..\..\..\Runtime\ClassReader\Attributes.h"\ + "..\..\..\Runtime\ClassReader\ConstantPool.h"\ + "..\..\..\Runtime\ClassReader\utils.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Runtime\System\md\x86\x86SysCallsRuntime.h"\ + "..\..\..\Runtime\System\SysCallsRuntime.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FastBitMatrix.h"\ + "..\..\..\Utilities\General\FastBitSet.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + + +"$(INTDIR)\SysCalls.obj" "$(INTDIR)\SysCalls.sbr" : $(SOURCE) $(DEP_CPP_SYSCAL)\ + "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +SOURCE=..\..\..\Compiler\PrimitiveGraph\Value.cpp + +!IF "$(CFG)" == "electricalfire - Win32 Release" + +DEP_CPP_VALUE=\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\DebugUtils.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\Nonspr.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + +NODEP_CPP_VALUE=\ + "..\..\..\Utilities\General\plstr.h"\ + "..\..\..\Utilities\General\prlog.h"\ + "..\..\..\Utilities\General\prlong.h"\ + + +"$(INTDIR)\Value.obj" "$(INTDIR)\Value.sbr" : $(SOURCE) $(DEP_CPP_VALUE)\ + "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "electricalfire - Win32 Debug" + +DEP_CPP_VALUE=\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\obsolete\protypes.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcpucfg.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinet.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinrval.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prio.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlog.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlong.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtime.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtypes.h"\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\DebugUtils.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + + +"$(INTDIR)\Value.obj" "$(INTDIR)\Value.sbr" : $(SOURCE) $(DEP_CPP_VALUE)\ + "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +SOURCE=..\..\..\Debugger\Debugger.cpp + +!IF "$(CFG)" == "electricalfire - Win32 Release" + +DEP_CPP_DEBUGG=\ + "..\..\..\Compiler\CodeGenerator\ExceptionTable.h"\ + "..\..\..\Compiler\CodeGenerator\FormatStructures.h"\ + "..\..\..\Compiler\CodeGenerator\Instruction.h"\ + "..\..\..\Compiler\CodeGenerator\InstructionEmitter.h"\ + "..\..\..\Compiler\CodeGenerator\md\CpuInfo.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Formatter.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Opcode.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Cpu.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Emitter.h"\ + "..\..\..\Compiler\CodeGenerator\NativeCodeCache.h"\ + "..\..\..\Compiler\FrontEnd\BytecodeGraph.h"\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Compiler\FrontEnd\LocalEnv.h"\ + "..\..\..\Compiler\FrontEnd\TranslationEnv.h"\ + "..\..\..\Compiler\FrontEnd\VerificationEnv.h"\ + "..\..\..\Compiler\Optimizer\PrimitiveOptimizer.h"\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlGraph.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlNodes.h"\ + "..\..\..\Compiler\PrimitiveGraph\PrimitiveOperations.h"\ + "..\..\..\Compiler\PrimitiveGraph\Primitives.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Compiler\RegisterAllocator\VirtualRegister.h"\ + "..\..\..\Debugger\Communication\DebuggerChannel.h"\ + "..\..\..\Debugger\Debugger.h"\ + "..\..\..\Debugger\jvmdi.h"\ + "..\..\..\Exports\jni.h"\ + "..\..\..\Exports\md\jni_md.h"\ + "..\..\..\Runtime\ClassInfo\ClassCentral.h"\ + "..\..\..\Runtime\ClassInfo\ClassFileSummary.h"\ + "..\..\..\Runtime\ClassInfo\Collector.h"\ + "..\..\..\Runtime\ClassInfo\PathComponent.h"\ + "..\..\..\Runtime\ClassInfo\StringPool.h"\ + "..\..\..\Runtime\ClassReader\Attributes.h"\ + "..\..\..\Runtime\ClassReader\ClassReader.h"\ + "..\..\..\Runtime\ClassReader\ConstantPool.h"\ + "..\..\..\Runtime\ClassReader\InfoItem.h"\ + "..\..\..\Runtime\ClassReader\utils.h"\ + "..\..\..\Runtime\FileReader\FileReader.h"\ + "..\..\..\Runtime\FileReader\ZipArchive.h"\ + "..\..\..\Runtime\NativeMethods\NameMangler.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\NativeMethods\NativeMethodDispatcher.h"\ + "..\..\..\Runtime\System\ClassWorld.h"\ + "..\..\..\Runtime\System\FieldOrMethod.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Runtime\System\JavaString.h"\ + "..\..\..\Runtime\System\JavaVM.h"\ + "..\..\..\Runtime\System\Method.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\CheckedUnion.h"\ + "..\..\..\Utilities\General\DebugUtils.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FastBitMatrix.h"\ + "..\..\..\Utilities\General\FastBitSet.h"\ + "..\..\..\Utilities\General\FastHashTable.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\InterestingEvents.h"\ + "..\..\..\Utilities\General\JavaBytecodes.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\Nonspr.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\StringUtils.h"\ + "..\..\..\Utilities\General\Vector.h"\ + "..\..\..\Utilities\zlib\zconf.h"\ + "..\..\..\Utilities\zlib\zlib.h"\ + +NODEP_CPP_DEBUGG=\ + "..\..\..\Compiler\CodeGenerator\md\HPPACpu.h"\ + "..\..\..\Compiler\CodeGenerator\md\PPC601Cpu.h"\ + "..\..\..\Compiler\CodeGenerator\prmon.h"\ + "..\..\..\Compiler\CodeGenerator\prtypes.h"\ + "..\..\..\Debugger\Communication\prio.h"\ + "..\..\..\Debugger\Communication\prlock.h"\ + "..\..\..\Debugger\Communication\prprf.h"\ + "..\..\..\Debugger\nspr.h"\ + "..\..\..\Runtime\ClassReader\prtypes.h"\ + "..\..\..\Runtime\FileReader\prio.h"\ + "..\..\..\Runtime\FileReader\prtypes.h"\ + "..\..\..\Runtime\NativeMethods\prlink.h"\ + "..\..\..\Runtime\System\plstr.h"\ + "..\..\..\Runtime\System\prprf.h"\ + "..\..\..\Utilities\General\plstr.h"\ + "..\..\..\Utilities\General\prbit.h"\ + "..\..\..\Utilities\General\prlog.h"\ + "..\..\..\Utilities\General\prlong.h"\ + "..\..\..\Utilities\General\prprf.h"\ + + +"$(INTDIR)\Debugger.obj" "$(INTDIR)\Debugger.sbr" : $(SOURCE) $(DEP_CPP_DEBUGG)\ + "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "electricalfire - Win32 Debug" + +DEP_CPP_DEBUGG=\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\nspr.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\obsolete\protypes.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\plstr.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\pratom.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prbit.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prclist.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcmon.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcpucfg.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcvar.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prdtoa.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prenv.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prerror.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinet.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinit.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinrval.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prio.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlink.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlock.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlog.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlong.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prmem.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prmon.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prnetdb.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prprf.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prproces.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prsystem.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prthread.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtime.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtypes.h"\ + "..\..\..\Compiler\CodeGenerator\ExceptionTable.h"\ + "..\..\..\Compiler\CodeGenerator\FormatStructures.h"\ + "..\..\..\Compiler\CodeGenerator\Instruction.h"\ + "..\..\..\Compiler\CodeGenerator\md\CpuInfo.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Cpu.h"\ + "..\..\..\Compiler\CodeGenerator\NativeCodeCache.h"\ + "..\..\..\Compiler\FrontEnd\BytecodeGraph.h"\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Compiler\FrontEnd\LocalEnv.h"\ + "..\..\..\Compiler\FrontEnd\TranslationEnv.h"\ + "..\..\..\Compiler\FrontEnd\VerificationEnv.h"\ + "..\..\..\Compiler\Optimizer\PrimitiveOptimizer.h"\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlGraph.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlNodes.h"\ + "..\..\..\Compiler\PrimitiveGraph\PrimitiveOperations.h"\ + "..\..\..\Compiler\PrimitiveGraph\Primitives.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Compiler\RegisterAllocator\VirtualRegister.h"\ + "..\..\..\Debugger\Communication\DebuggerChannel.h"\ + "..\..\..\Debugger\Debugger.h"\ + "..\..\..\Debugger\jvmdi.h"\ + "..\..\..\Exports\jni.h"\ + "..\..\..\Exports\md\jni_md.h"\ + "..\..\..\Runtime\ClassInfo\ClassCentral.h"\ + "..\..\..\Runtime\ClassInfo\ClassFileSummary.h"\ + "..\..\..\Runtime\ClassInfo\Collector.h"\ + "..\..\..\Runtime\ClassInfo\PathComponent.h"\ + "..\..\..\Runtime\ClassInfo\StringPool.h"\ + "..\..\..\Runtime\ClassReader\Attributes.h"\ + "..\..\..\Runtime\ClassReader\ClassReader.h"\ + "..\..\..\Runtime\ClassReader\ConstantPool.h"\ + "..\..\..\Runtime\ClassReader\InfoItem.h"\ + "..\..\..\Runtime\ClassReader\utils.h"\ + "..\..\..\Runtime\FileReader\FileReader.h"\ + "..\..\..\Runtime\FileReader\ZipArchive.h"\ + "..\..\..\Runtime\NativeMethods\NameMangler.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\NativeMethods\NativeMethodDispatcher.h"\ + "..\..\..\Runtime\System\ClassWorld.h"\ + "..\..\..\Runtime\System\FieldOrMethod.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Runtime\System\JavaString.h"\ + "..\..\..\Runtime\System\JavaVM.h"\ + "..\..\..\Runtime\System\Method.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\CheckedUnion.h"\ + "..\..\..\Utilities\General\DebugUtils.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FastBitMatrix.h"\ + "..\..\..\Utilities\General\FastBitSet.h"\ + "..\..\..\Utilities\General\FastHashTable.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\InterestingEvents.h"\ + "..\..\..\Utilities\General\JavaBytecodes.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\StringUtils.h"\ + "..\..\..\Utilities\General\Vector.h"\ + "..\..\..\Utilities\zlib\zconf.h"\ + "..\..\..\Utilities\zlib\zlib.h"\ + + +"$(INTDIR)\Debugger.obj" "$(INTDIR)\Debugger.sbr" : $(SOURCE) $(DEP_CPP_DEBUGG)\ + "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +SOURCE=..\..\..\Debugger\jvmdi.cpp + +!IF "$(CFG)" == "electricalfire - Win32 Release" + +DEP_CPP_JVMDI=\ + "..\..\..\Compiler\CodeGenerator\ExceptionTable.h"\ + "..\..\..\Compiler\CodeGenerator\FormatStructures.h"\ + "..\..\..\Compiler\CodeGenerator\Instruction.h"\ + "..\..\..\Compiler\CodeGenerator\InstructionEmitter.h"\ + "..\..\..\Compiler\CodeGenerator\md\CpuInfo.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Formatter.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Opcode.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Cpu.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Emitter.h"\ + "..\..\..\Compiler\CodeGenerator\NativeCodeCache.h"\ + "..\..\..\Compiler\FrontEnd\BytecodeGraph.h"\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Compiler\FrontEnd\LocalEnv.h"\ + "..\..\..\Compiler\FrontEnd\TranslationEnv.h"\ + "..\..\..\Compiler\FrontEnd\VerificationEnv.h"\ + "..\..\..\Compiler\Optimizer\PrimitiveOptimizer.h"\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlGraph.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlNodes.h"\ + "..\..\..\Compiler\PrimitiveGraph\PrimitiveOperations.h"\ + "..\..\..\Compiler\PrimitiveGraph\Primitives.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Compiler\RegisterAllocator\VirtualRegister.h"\ + "..\..\..\Debugger\Communication\DebuggerChannel.h"\ + "..\..\..\Debugger\Debugger.h"\ + "..\..\..\Debugger\jvmdi.h"\ + "..\..\..\Exports\jni.h"\ + "..\..\..\Exports\md\jni_md.h"\ + "..\..\..\Runtime\ClassInfo\ClassCentral.h"\ + "..\..\..\Runtime\ClassInfo\ClassFileSummary.h"\ + "..\..\..\Runtime\ClassInfo\Collector.h"\ + "..\..\..\Runtime\ClassInfo\PathComponent.h"\ + "..\..\..\Runtime\ClassInfo\StringPool.h"\ + "..\..\..\Runtime\ClassReader\Attributes.h"\ + "..\..\..\Runtime\ClassReader\ClassReader.h"\ + "..\..\..\Runtime\ClassReader\ConstantPool.h"\ + "..\..\..\Runtime\ClassReader\InfoItem.h"\ + "..\..\..\Runtime\ClassReader\utils.h"\ + "..\..\..\Runtime\FileReader\FileReader.h"\ + "..\..\..\Runtime\FileReader\ZipArchive.h"\ + "..\..\..\Runtime\NativeMethods\NameMangler.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\NativeMethods\NativeMethodDispatcher.h"\ + "..\..\..\Runtime\System\ClassWorld.h"\ + "..\..\..\Runtime\System\FieldOrMethod.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Runtime\System\JavaString.h"\ + "..\..\..\Runtime\System\JavaVM.h"\ + "..\..\..\Runtime\System\Method.h"\ + "..\..\..\Runtime\System\Monitor.h"\ + "..\..\..\Runtime\System\Thread.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\CheckedUnion.h"\ + "..\..\..\Utilities\General\DebugUtils.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FastBitMatrix.h"\ + "..\..\..\Utilities\General\FastBitSet.h"\ + "..\..\..\Utilities\General\FastHashTable.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\InterestingEvents.h"\ + "..\..\..\Utilities\General\JavaBytecodes.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\Nonspr.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + "..\..\..\Utilities\zlib\zconf.h"\ + "..\..\..\Utilities\zlib\zlib.h"\ + +NODEP_CPP_JVMDI=\ + "..\..\..\Compiler\CodeGenerator\md\HPPACpu.h"\ + "..\..\..\Compiler\CodeGenerator\md\PPC601Cpu.h"\ + "..\..\..\Compiler\CodeGenerator\prmon.h"\ + "..\..\..\Compiler\CodeGenerator\prtypes.h"\ + "..\..\..\Debugger\Communication\prio.h"\ + "..\..\..\Debugger\Communication\prlock.h"\ + "..\..\..\Debugger\Communication\prprf.h"\ + "..\..\..\Debugger\nspr.h"\ + "..\..\..\Runtime\ClassReader\prtypes.h"\ + "..\..\..\Runtime\FileReader\prio.h"\ + "..\..\..\Runtime\FileReader\prtypes.h"\ + "..\..\..\Runtime\NativeMethods\prlink.h"\ + "..\..\..\Runtime\System\plstr.h"\ + "..\..\..\Runtime\System\pratom.h"\ + "..\..\..\Runtime\System\prcvar.h"\ + "..\..\..\Runtime\System\prlock.h"\ + "..\..\..\Runtime\System\prprf.h"\ + "..\..\..\Runtime\System\prthread.h"\ + "..\..\..\Runtime\System\prtypes.h"\ + "..\..\..\Utilities\General\plstr.h"\ + "..\..\..\Utilities\General\prbit.h"\ + "..\..\..\Utilities\General\prlog.h"\ + "..\..\..\Utilities\General\prlong.h"\ + + +"$(INTDIR)\jvmdi.obj" "$(INTDIR)\jvmdi.sbr" : $(SOURCE) $(DEP_CPP_JVMDI)\ + "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "electricalfire - Win32 Debug" + +DEP_CPP_JVMDI=\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\nspr.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\obsolete\protypes.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\plstr.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\pratom.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prbit.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prclist.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcmon.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcpucfg.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcvar.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prdtoa.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prenv.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prerror.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinet.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinit.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinrval.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prio.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlink.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlock.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlog.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlong.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prmem.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prmon.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prnetdb.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prprf.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prproces.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prsystem.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prthread.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtime.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtypes.h"\ + "..\..\..\Compiler\CodeGenerator\ExceptionTable.h"\ + "..\..\..\Compiler\CodeGenerator\FormatStructures.h"\ + "..\..\..\Compiler\CodeGenerator\Instruction.h"\ + "..\..\..\Compiler\CodeGenerator\md\CpuInfo.h"\ + "..\..\..\Compiler\CodeGenerator\md\x86\x86Win32Cpu.h"\ + "..\..\..\Compiler\CodeGenerator\NativeCodeCache.h"\ + "..\..\..\Compiler\FrontEnd\BytecodeGraph.h"\ + "..\..\..\Compiler\FrontEnd\ErrorHandling.h"\ + "..\..\..\Compiler\FrontEnd\LocalEnv.h"\ + "..\..\..\Compiler\FrontEnd\TranslationEnv.h"\ + "..\..\..\Compiler\FrontEnd\VerificationEnv.h"\ + "..\..\..\Compiler\Optimizer\PrimitiveOptimizer.h"\ + "..\..\..\Compiler\PrimitiveGraph\Address.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlGraph.h"\ + "..\..\..\Compiler\PrimitiveGraph\ControlNodes.h"\ + "..\..\..\Compiler\PrimitiveGraph\PrimitiveOperations.h"\ + "..\..\..\Compiler\PrimitiveGraph\Primitives.h"\ + "..\..\..\Compiler\PrimitiveGraph\Value.h"\ + "..\..\..\Compiler\RegisterAllocator\VirtualRegister.h"\ + "..\..\..\Debugger\Communication\DebuggerChannel.h"\ + "..\..\..\Debugger\Debugger.h"\ + "..\..\..\Debugger\jvmdi.h"\ + "..\..\..\Exports\jni.h"\ + "..\..\..\Exports\md\jni_md.h"\ + "..\..\..\Runtime\ClassInfo\ClassCentral.h"\ + "..\..\..\Runtime\ClassInfo\ClassFileSummary.h"\ + "..\..\..\Runtime\ClassInfo\Collector.h"\ + "..\..\..\Runtime\ClassInfo\PathComponent.h"\ + "..\..\..\Runtime\ClassInfo\StringPool.h"\ + "..\..\..\Runtime\ClassReader\Attributes.h"\ + "..\..\..\Runtime\ClassReader\ClassReader.h"\ + "..\..\..\Runtime\ClassReader\ConstantPool.h"\ + "..\..\..\Runtime\ClassReader\InfoItem.h"\ + "..\..\..\Runtime\ClassReader\utils.h"\ + "..\..\..\Runtime\FileReader\FileReader.h"\ + "..\..\..\Runtime\FileReader\ZipArchive.h"\ + "..\..\..\Runtime\NativeMethods\NameMangler.h"\ + "..\..\..\Runtime\NativeMethods\NativeDefs.h"\ + "..\..\..\Runtime\NativeMethods\NativeMethodDispatcher.h"\ + "..\..\..\Runtime\System\ClassWorld.h"\ + "..\..\..\Runtime\System\FieldOrMethod.h"\ + "..\..\..\Runtime\System\InterfaceDispatchTable.h"\ + "..\..\..\Runtime\System\JavaObject.h"\ + "..\..\..\Runtime\System\JavaString.h"\ + "..\..\..\Runtime\System\JavaVM.h"\ + "..\..\..\Runtime\System\Method.h"\ + "..\..\..\Runtime\System\Monitor.h"\ + "..\..\..\Runtime\System\Thread.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\CheckedUnion.h"\ + "..\..\..\Utilities\General\DebugUtils.h"\ + "..\..\..\Utilities\General\DoublyLinkedList.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\FastBitMatrix.h"\ + "..\..\..\Utilities\General\FastBitSet.h"\ + "..\..\..\Utilities\General\FastHashTable.h"\ + "..\..\..\Utilities\General\FloatUtils.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\HashTable.h"\ + "..\..\..\Utilities\General\InterestingEvents.h"\ + "..\..\..\Utilities\General\JavaBytecodes.h"\ + "..\..\..\Utilities\General\LogModule.h"\ + "..\..\..\Utilities\General\Pool.h"\ + "..\..\..\Utilities\General\Vector.h"\ + "..\..\..\Utilities\zlib\zconf.h"\ + "..\..\..\Utilities\zlib\zlib.h"\ + + +"$(INTDIR)\jvmdi.obj" "$(INTDIR)\jvmdi.sbr" : $(SOURCE) $(DEP_CPP_JVMDI)\ + "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +SOURCE=..\..\..\Debugger\Win32BreakPoint.cpp + +!IF "$(CFG)" == "electricalfire - Win32 Release" + +DEP_CPP_WIN32B=\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + "..\..\..\Utilities\General\Nonspr.h"\ + +NODEP_CPP_WIN32B=\ + "..\..\..\Utilities\General\plstr.h"\ + "..\..\..\Utilities\General\prlog.h"\ + "..\..\..\Utilities\General\prlong.h"\ + + +"$(INTDIR)\Win32BreakPoint.obj" "$(INTDIR)\Win32BreakPoint.sbr" : $(SOURCE)\ + $(DEP_CPP_WIN32B) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "electricalfire - Win32 Debug" + +DEP_CPP_WIN32B=\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\obsolete\protypes.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prcpucfg.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinet.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prinrval.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prio.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlog.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prlong.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtime.h"\ + "..\..\..\..\dist\WINNT4.0_x86_DBG.OBJ\include\prtypes.h"\ + "..\..\..\Utilities\General\CatchAssert.h"\ + "..\..\..\Utilities\General\Exports.h"\ + "..\..\..\Utilities\General\Fundamentals.h"\ + + +"$(INTDIR)\Win32BreakPoint.obj" "$(INTDIR)\Win32BreakPoint.sbr" : $(SOURCE)\ + $(DEP_CPP_WIN32B) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +!IF "$(CFG)" == "electricalfire - Win32 Release" + +"Burg - Win32 Release" : + cd ".\Burg" + $(MAKE) /$(MAKEFLAGS) /F .\Burg.mak CFG="Burg - Win32 Release" + cd ".." + +"Burg - Win32 ReleaseCLEAN" : + cd ".\Burg" + $(MAKE) /$(MAKEFLAGS) CLEAN /F .\Burg.mak CFG="Burg - Win32 Release"\ + RECURSE=1 + cd ".." + +!ELSEIF "$(CFG)" == "electricalfire - Win32 Debug" + +"Burg - Win32 Debug" : + cd ".\Burg" + $(MAKE) /$(MAKEFLAGS) /F .\Burg.mak CFG="Burg - Win32 Debug" + cd ".." + +"Burg - Win32 DebugCLEAN" : + cd ".\Burg" + $(MAKE) /$(MAKEFLAGS) CLEAN /F .\Burg.mak CFG="Burg - Win32 Debug" RECURSE=1\ + + cd ".." + +!ENDIF + +!IF "$(CFG)" == "electricalfire - Win32 Release" + +"DebuggerChannel - Win32 Release" : + cd "." + $(MAKE) /$(MAKEFLAGS) /F .\DebuggerChannel.mak\ + CFG="DebuggerChannel - Win32 Release" + cd "." + +"DebuggerChannel - Win32 ReleaseCLEAN" : + cd "." + $(MAKE) /$(MAKEFLAGS) CLEAN /F .\DebuggerChannel.mak\ + CFG="DebuggerChannel - Win32 Release" RECURSE=1 + cd "." + +!ELSEIF "$(CFG)" == "electricalfire - Win32 Debug" + +"DebuggerChannel - Win32 Debug" : + cd "." + $(MAKE) /$(MAKEFLAGS) /F .\DebuggerChannel.mak\ + CFG="DebuggerChannel - Win32 Debug" + cd "." + +"DebuggerChannel - Win32 DebugCLEAN" : + cd "." + $(MAKE) /$(MAKEFLAGS) CLEAN /F .\DebuggerChannel.mak\ + CFG="DebuggerChannel - Win32 Debug" RECURSE=1 + cd "." + +!ENDIF + + +!ENDIF + diff --git a/ef/Driver/StandAloneJava/winbuild/gmakedep/gmakedep.dsp b/ef/Driver/StandAloneJava/winbuild/gmakedep/gmakedep.dsp new file mode 100644 index 000000000000..260eb5343a19 --- /dev/null +++ b/ef/Driver/StandAloneJava/winbuild/gmakedep/gmakedep.dsp @@ -0,0 +1,92 @@ +# Microsoft Developer Studio Project File - Name="gmakedep" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 5.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=gmakedep - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "gmakedep.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "gmakedep.mak" CFG="gmakedep - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "gmakedep - Win32 Release" (based on\ + "Win32 (x86) Console Application") +!MESSAGE "gmakedep - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "gmakedep - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "gmakedep - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "gmakedep - Win32 Release" +# Name "gmakedep - Win32 Debug" +# Begin Source File + +SOURCE=..\makedep.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\VC\mfc\src\THRDCORE.CPP +# End Source File +# End Target +# End Project diff --git a/ef/Driver/StandAloneJava/winbuild/gmakedep/gmakedep.dsw b/ef/Driver/StandAloneJava/winbuild/gmakedep/gmakedep.dsw new file mode 100644 index 000000000000..f5114bc45a9e --- /dev/null +++ b/ef/Driver/StandAloneJava/winbuild/gmakedep/gmakedep.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 5.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "gmakedep"=.\gmakedep.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/ef/Driver/StandAloneJava/winbuild/gmakedep/makedep.cpp b/ef/Driver/StandAloneJava/winbuild/gmakedep/makedep.cpp new file mode 100644 index 000000000000..7389c7273dee --- /dev/null +++ b/ef/Driver/StandAloneJava/winbuild/gmakedep/makedep.cpp @@ -0,0 +1,859 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +// +// Dependancy building hack. Lloyd W. Tabb 04/05/96 +// + +#include +#include +#include +#include +#include +#include + +int mainReturn = 0; +BOOL b16 = FALSE; +BOOL bSimple = FALSE; + +// freopen won't work on stdout in win16 +FILE *pAltFile = stdout; + +CStringArray includeDirectories; + +// turn a file, relative path or other into an absolute path +// This function copied from MFC 1.52 +BOOL PASCAL _AfxFullPath(LPSTR lpszPathOut, LPCSTR lpszFileIn) + // lpszPathOut = buffer of _MAX_PATH + // lpszFileIn = file, relative path or absolute path + // (both in ANSI character set) +{ + OFSTRUCT of; + if (OpenFile(lpszFileIn, &of, OF_PARSE) != HFILE_ERROR) + { + // of.szPathName is in the OEM character set + OemToAnsi(of.szPathName, lpszPathOut); + // Maintain the capitialization + //AnsiUpper(lpszPathOut); // paths in upper case just to be sure + return TRUE; + } + else + { + TRACE1("Warning: could not parse the path %Fs\n", lpszFileIn); + lstrcpy(lpszPathOut, lpszFileIn); // take it literally + // Maintain the capitialization + //AnsiUpper(lpszPathOut); // paths in upper case just to be sure + return FALSE; + } +} + +void AddIncludeDirectory( char *pString ){ + CString s = pString; + int len = s.GetLength(); + if(len > 0 && s[len - 1] != '\\' ){ + s += "\\"; + } + includeDirectories.Add(s); +} + +BOOL FileExists( const char *pString ){ + struct _stat buf; + int result; + + result = _stat( pString, &buf ); + return (result == 0); +} + +void FixPathName(CString& str) { + //str.MakeUpper(); // all upper case + + // now switch all forward slashes to back slashes + int index; + while ((index = str.Find('\\')) != -1) { + str.SetAt(index, '/'); + } +} + +void FATName(CString& csLONGName) +{ + // Only relevant for 16 bits. + if(b16) { + // Convert filename to FAT (8.3) equivalent. + char aBuffer[2048]; + + if(GetShortPathName(csLONGName, aBuffer, 2048)) { + csLONGName = aBuffer; + } + } +} + + +class CFileRecord { +public: + CString m_shortName; + CString m_pathName; + CPtrArray m_includes; + BOOL m_bVisited; + BOOL m_bSystem; + BOOL m_bSource; + static CMapStringToPtr fileMap; + static CStringArray orderedFileNames; + static CMapStringToPtr includeMap; + static CMapStringToPtr noDependMap; + + CFileRecord( const char *shortName, const char* pFullName, BOOL bSystem, BOOL bSource): + m_shortName( shortName ), + m_pathName(), + m_includes(), + m_bVisited(FALSE), + m_bSource( bSource ), + m_bSystem(bSystem){ + + m_pathName = pFullName; + FixPathName(m_pathName); // all upper case for consistency + ASSERT(FindFileRecord(m_pathName) == NULL); // make sure it's not already in the map + fileMap[m_pathName] = this; // add this to the filemap, using the appropriate name as the key + if (bSource) { + orderedFileNames.Add(m_pathName); // remember the order we saw source files in + } + } + + // + // open the file and grab all the includes. + // + void ProcessFile(){ + FILE *f; + CString fullName; + BOOL bSystem; + DWORD lineCntr = 0; + char *a = new char[2048]; + memset(a, 0, 2048); + char srcPath[_MAX_PATH]; + + // construct the full path + if (!_AfxFullPath(srcPath, m_pathName)) { + strcpy(srcPath, m_pathName); + } + + // strip off the source filename to end up with just the path + LPSTR pTemp = strrchr(srcPath, '\\'); + if (pTemp) { + *(pTemp + 1) = 0; + } + + f = fopen(m_pathName, "r"); + if(f != NULL && f != (FILE *)-1) { + setvbuf(f, NULL, _IOFBF, 32768); // use a large file buffer + while(fgets(a, 2047, f)) { + // if the string "//{{NO_DEPENDENCIES}}" is at the start of one of the + // first 10 lines of a file, don't build dependencies on it or any + // of the files it includes + if (lineCntr < 10) { + static char* pDependStr = "//{{NO_DEPENDENCIES}}"; + if (strncmp(a, pDependStr, strlen(pDependStr)) == 0) { + noDependMap[m_pathName] = 0; // add it to the noDependMap + break; // no need for further processing of this file + } + } + ++lineCntr; + // have to handle a variety of legal syntaxes that we find in our source files: + // #include + // # include + // #include + // if the first non-whitespace char is a '#', consider this line + pTemp = a; + pTemp += strspn(pTemp, " \t"); // skip whitespace + if (*pTemp == '#') { + ++pTemp; // skip the '#' + pTemp += strspn(pTemp, " \t"); // skip more whitespace + if( !strncmp(pTemp, "include", 7) ){ + pTemp += 7; // skip the "include" + pTemp += strspn(pTemp, " \t"); // skip more whitespace + bSystem = (*pTemp == '<'); // mark if it's a system include or not + if (bSystem || (*pTemp == '"')) { + LPSTR pStart = pTemp + 1; // mark the start of the string + pTemp = pStart + strcspn(pStart, ">\" "); // find the end of the string + *pTemp = 0; // terminate the string + + // construct the full pathname from the path part of the + // source file and the name listed here + fullName = srcPath; + fullName += pStart; + CFileRecord *pAddMe = AddFile( pStart, fullName, bSystem ); + if (pAddMe) { + m_includes.Add(pAddMe); + } + } + } + } + } + fclose(f); + } + delete [] a; + } + + void PrintIncludes(){ + int i = 0; + while( i < m_includes.GetSize() ){ + CFileRecord *pRec = (CFileRecord*) m_includes[i]; + + // Don't write out files that don't exist or are not in the namespace + // of the programs using it (netscape_AppletMozillaContext.h doesn't + // mix well with 16 bits). + // Also don't write out files that are in the noDependMap + void* lookupJunk; + if( !pRec->m_bVisited && pRec->m_pathName.GetLength() != 0 && !noDependMap.Lookup(pRec->m_pathName, lookupJunk)) { + + // not supposed to have a file in the list that doesn't exist + ASSERT(FileExists(pRec->m_pathName)); + + CString csOutput; + csOutput = pRec->m_pathName; + FATName(csOutput); + + fprintf(pAltFile, "\\\n %s ", (const char *) csOutput ); + + // mark this one as done so we don't do it more than once + pRec->m_bVisited = TRUE; + + pRec->PrintIncludes(); + } + i++; + } + } + + void PrintDepend(){ + CFileRecord *pRec; + BOOL bFound; + POSITION next; + CString name; + + // clear all the m_bVisisted flags so we can use it to keep track + // of whether we've already output this file as a dependency + next = fileMap.GetStartPosition(); + while( next ){ + fileMap.GetNextAssoc( next, name, *(void**)&pRec ); + pRec->m_bVisited = FALSE; + } + + char fname[_MAX_FNAME]; + + if (pRec->m_pathName.GetLength() != 0) { + if( bSimple ){ + fprintf(pAltFile, "\n\n\n%s:\t", m_pathName ); + } + else { + CString csOutput; + csOutput = m_pathName; + FATName(csOutput); + + _splitpath( csOutput, NULL, NULL, fname, NULL ); + + fprintf(pAltFile, "\n\n\n$(OUTDIR)\\%s.obj: %s ", fname, (const char*) csOutput ); + } + m_bVisited = TRUE; // mark it as done so we won't do it again + PrintIncludes(); + } + } + + + static CString NormalizeFileName( const char* pName ){ + return CString(pName); + } + + static CFileRecord* FindFileRecord( const char *pName ){ + CFileRecord* pRec = NULL; + CString name(pName); + FixPathName(name); + fileMap.Lookup(name, (void*&)pRec); + return(pRec); + } +public: + static CFileRecord* AddFile( const char* pShortName, const char* pFullName, BOOL bSystem = FALSE, + BOOL bSource = FALSE ){ + + char fullName[_MAX_PATH]; + BOOL bFound = FALSE; + BOOL bFoundInInclude = FALSE; + CString foundName; + CString fixedShortName; + CString s; + + + // if it is source, we might be getting an obj file. If we do, + // convert it to a c or c++ file. + if( bSource && (strcmp(GetExt(pShortName),".obj") == 0) ){ + char path_buffer[_MAX_PATH]; + char fname[_MAX_FNAME] = ""; + CString s; + + _splitpath( pShortName, NULL, NULL, fname, NULL ); + if( FileExists( s = CString(fname) + ".cpp") ){ + pShortName = s; + pFullName = s; + } + else if( FileExists( s = CString(fname) + ".c" ) ){ + pShortName = s; + pFullName = s; + } + else { + return 0; + } + } + + // if pFullName was not constructed, construct it here based on the current directory + if (!pFullName) { + _AfxFullPath(fullName, pShortName); + pFullName = fullName; + } + + // first check to see if we already have this exact file + CFileRecord *pRec = FindFileRecord(pFullName); + + if (pRec) { + bFound = TRUE; + } + + // check the fullname first + if (!bFound && FileExists(pFullName)) { + foundName = pFullName; + bFound = TRUE; + } + + // if still not found, search the include paths + if (!bFound) { + // all files we've found in include directories are in the includeMap + // we can see if we've already found it in the include path before and + // save time by getting it from there + fixedShortName = pShortName; + FixPathName(fixedShortName); // normalize the name + includeMap.Lookup(fixedShortName, (void*&)pRec); + pShortName = fixedShortName; // set this to point to the normalized name for when we add it to the include map + if (!pRec) { + int i = 0; + while( i < includeDirectories.GetSize() ){ + if( FileExists( includeDirectories[i] + pShortName ) ){ + foundName = includeDirectories[i] + pShortName; + bFound = TRUE; + bFoundInInclude = TRUE; + break; + } + i++; + } + } + } + + // if we found it and don't already have a fileRecord for it + // see if this name is already in there + if (bFound && !pRec) { + pRec = FindFileRecord(foundName); + } + + // source files are not allowed to be missing + if (!pRec && !bFound && bSource) { + fprintf(stderr, "Source file: %s doesn't exist\n", pFullName); + mainReturn = -1; // exit with an error, don't write out the results + } + +#ifdef _DEBUG + if (!pRec && !bFound && !bSystem) { + fprintf(stderr, "Header not found: %s (%s)\n", pShortName, pFullName); + } +#endif + + // if none of the above logic found it already in the list, must be a new file, add it to the list + if (bFound && (pRec == NULL)) { + pRec = new CFileRecord( pShortName, foundName, bSystem, bSource); + + // if we found this one in the include path, add it to the includeMap + // for performance reasons (so we can find it there next time rather + // than having to search the file system again) + if (bFoundInInclude) { + includeMap[pShortName] = pRec; + } + } + return pRec; + } + + + static void PrintDependancies(){ + CFileRecord *pRec; + BOOL bFound; + POSITION next; + CString name; + + // use orderedFileNames to preserve order + for (int pos = 0; pos < orderedFileNames.GetSize(); pos++) { + pRec = FindFileRecord(orderedFileNames[pos]); + if(pRec && pRec->m_bSource ){ + pRec->PrintDepend(); + } + } + } + + + void PrintDepend2(){ + CFileRecord *pRec; + int i; + + if( m_includes.GetSize() != 0 ){ + fprintf(pAltFile, "\n\n\n%s: \\\n",m_pathName ); + i = 0; + while( i < m_includes.GetSize() ){ + pRec = (CFileRecord*) m_includes[i]; + fprintf(pAltFile, "\t\t\t%s\t\\\n",pRec->m_pathName ); + i++; + } + } + } + + static void PrintDependancies2(){ + CFileRecord *pRec; + BOOL bFound; + POSITION next; + CString name; + + next = fileMap.GetStartPosition(); + while( next ){ + fileMap.GetNextAssoc( next, name, *(void**)&pRec ); + pRec->PrintDepend2(); + } + } + + + static void PrintTargets(const char *pMacroName, const char *pDelimeter){ + CFileRecord *pRec; + BOOL bFound; + POSITION next; + CString name; + + BOOL bNeedDelimeter = FALSE; + fprintf(pAltFile, "%s = ", pMacroName); + + // use orderedFileNames to preserve target order + for (int pos = 0; pos < orderedFileNames.GetSize(); pos++) { + pRec = FindFileRecord(orderedFileNames[pos]); + ASSERT(pRec); + + if( pRec && pRec->m_bSource && pRec->m_pathName.GetLength() != 0){ + char fname[_MAX_FNAME]; + + CString csOutput; + csOutput = pRec->m_pathName; + FATName(csOutput); + + _splitpath( csOutput, NULL, NULL, fname, NULL ); + + if(bNeedDelimeter) { + fprintf(pAltFile, "%s\n", pDelimeter); + bNeedDelimeter = FALSE; + } + + fprintf(pAltFile, " $(OUTDIR)\\%s.obj ", fname ); + bNeedDelimeter = TRUE; + } + } + fprintf(pAltFile, "\n\n\n"); + } + + static CString DirDefine( const char *pPath ){ + char path_buffer[_MAX_PATH]; + char dir[_MAX_DIR] = ""; + char dir2[_MAX_DIR] = ""; + char fname[_MAX_FNAME] = ""; + char ext[_MAX_EXT] = ""; + CString s; + + _splitpath( pPath, 0, dir, 0, ext ); + + BOOL bDone = FALSE; + + while( dir && !bDone){ + // remove the trailing slash + dir[ strlen(dir)-1] = 0; + _splitpath( dir, 0, dir2, fname, 0 ); + if( strcmp( fname, "SRC" ) == 0 ){ + strcpy( dir, dir2 ); + } + else { + bDone = TRUE; + } + } + s = CString(fname) + "_" + (ext+1); + return s; + } + + + static void PrintSources(){ + int i; + CString dirName, newDirName; + + for( i=0; i< orderedFileNames.GetSize(); i++ ){ + newDirName= DirDefine( orderedFileNames[i] ); + if( newDirName != dirName ){ + fprintf( pAltFile, "\n\n\nFILES_%s= $(FILES_%s) \\", + (const char*)newDirName, (const char*)newDirName ); + dirName = newDirName; + } + fprintf( pAltFile, "\n\t%s^", (const char*)orderedFileNames[i] ); + } + } + + static CString SourceDirName( const char *pPath, BOOL bFileName){ + char path_buffer[_MAX_PATH]; + char drive[_MAX_DRIVE] = ""; + char dir[_MAX_DIR] = ""; + char fname[_MAX_FNAME] = ""; + char ext[_MAX_EXT] = ""; + CString s; + + _splitpath( pPath, drive, dir, fname, ext ); + + s = CString(drive) + dir; + if( bFileName ){ + s += CString("FNAME") + ext; + } + else { + // remove the trailing slash + s = s.Left( s.GetLength() - 1 ); + } + return s; + } + + + static CString GetExt( const char *pPath){ + char ext[_MAX_EXT] = ""; + + _splitpath( pPath, 0,0,0, ext ); + + CString s = CString(ext); + s.MakeLower(); + return s; + } + + static void PrintBuildRules(){ + int i; + CString dirName; + + CMapStringToPtr dirList; + + for( i=0; i< orderedFileNames.GetSize(); i++ ){ + dirList[ SourceDirName(orderedFileNames[i], TRUE) ]= 0; + } + + POSITION next; + CString name; + void *pVal; + + next = dirList.GetStartPosition(); + while( next ){ + dirList.GetNextAssoc( next, name, pVal); + CString dirDefine = DirDefine( name ); + CString ext = GetExt( name ); + name = SourceDirName( name, FALSE ); + CString response = dirDefine.Left(8); + + fprintf( pAltFile, + "\n\n\n{%s}%s{$(OUTDIR)}.obj:\n" + "\t@rem <<$(OUTDIR)\\%s.cl\n" + "\t$(CFILEFLAGS)\n" + "\t$(CFLAGS_%s)\n" + "<m_bVisited == FALSE && pRec->m_bSystem == FALSE ){ + // mark this file as already done so we don't read it again + // to find it's headers + pRec->m_bVisited = TRUE; + pRec->ProcessFile(); + // Start searching from the beginning again + // because ProcessFile may have added new files + // and changed the GetNextAssoc order + next = fileMap.GetStartPosition(); + + } + } + } + + +}; + +CMapStringToPtr CFileRecord::fileMap; +CStringArray CFileRecord::orderedFileNames; +CMapStringToPtr CFileRecord::includeMap; +CMapStringToPtr CFileRecord::noDependMap; + +int main( int argc, char** argv ){ + int i = 1; + char *pStr; + static int iRecursion = 0; // Track levels of recursion. + static CString outputFileName; + + // Entering. + iRecursion++; + + while( i < argc ){ + if( argv[i][0] == '-' || argv[i][0] == '/' ){ + switch( argv[i][1] ){ + + case 'i': + case 'I': + if( argv[i][2] != 0 ){ + pStr = &(argv[i][2]); + } + else { + i++; + pStr = argv[i]; + } + if( pStr == 0 || *pStr == '-' || *pStr == '/' ){ + goto usage; + } + else { + AddIncludeDirectory( pStr ); + } + break; + + case 'f': + case 'F': + if( argv[i][2] != 0 ){ + pStr = &(argv[i][2]); + } + else { + i++; + pStr = argv[i]; + } + if( pStr == 0 || *pStr == '-' || *pStr == '/'){ + goto usage; + } + else { + CStdioFile f; + CString s; + if( f.Open( pStr, CFile::modeRead ) ){ + while(f.ReadString(s)){ + s.TrimLeft(); + s.TrimRight(); + if( s.GetLength() ){ + CFileRecord::AddFile( s, NULL, FALSE, TRUE ); + } + } + f.Close(); + } + else { + fprintf(stderr,"makedep: file not found: %s", pStr ); + exit(-1); + } + } + break; + + case 'o': + case 'O': + if( argv[i][2] != 0 ){ + pStr = &(argv[i][2]); + } + else { + i++; + pStr = argv[i]; + } + if( pStr == 0 || *pStr == '-' || *pStr == '/'){ + goto usage; + } + else { + CStdioFile f; + CString s; + outputFileName = pStr; + if(!(pAltFile = fopen(pStr, "w+"))) { + fprintf(stderr, "makedep: file not found: %s", pStr ); + exit(-1); + } + } + break; + + case '1': + if( argv[i][2] == '6') { + b16 = TRUE; + } + break; + + case 's': + case 'S': + bSimple = TRUE; + break; + + + + case 'h': + case 'H': + case '?': + usage: + fprintf(stderr, "usage: makedep -I -F \n" + " -I Directory name, can be repeated\n" + " -F List of files to scan, one per line\n" + " -O File to write output, default stdout\n"); + exit(-1); + } + } + else if( argv[i][0] == '@' ){ + // file contains our commands. + CStdioFile f; + CString s; + int iNewArgc = 0; + char **apNewArgv = new char*[5000]; + memset(apNewArgv, 0, sizeof(apNewArgv)); + + // First one is always the name of the exe. + apNewArgv[0] = argv[0]; + iNewArgc++; + + const char *pTraverse; + const char *pBeginArg; + if( f.Open( &argv[i][1], CFile::modeRead ) ){ + while( iNewArgc < 5000 && f.ReadString(s) ) { + // Scan the string for args, and do the right thing. + pTraverse = (const char *)s; + while(iNewArgc < 5000 && *pTraverse) { + if(isspace(*pTraverse)) { + pTraverse++; + continue; + } + + // Extract to next space. + pBeginArg = pTraverse; + do { + pTraverse++; + } + while(*pTraverse && !isspace(*pTraverse)); + apNewArgv[iNewArgc] = new char[pTraverse - pBeginArg + 1]; + memset(apNewArgv[iNewArgc], 0, pTraverse - pBeginArg + 1); + strncpy(apNewArgv[iNewArgc], pBeginArg, pTraverse - pBeginArg); + iNewArgc++; + } + } + f.Close(); + } + + // Recurse if needed. + if(iNewArgc > 1) { + main(iNewArgc, apNewArgv); + } + + // Free off the argvs (but not the very first one which we didn't allocate). + while(iNewArgc > 1) { + iNewArgc--; + delete [] apNewArgv[iNewArgc]; + } + delete [] apNewArgv; + } + else { + CFileRecord::AddFile( argv[i], NULL, FALSE, TRUE ); + } + i++; + } + + // Only of the very bottom level of recursion do we do this. + if(iRecursion == 1) { + + // only write the results out if no errors encountered + if (mainReturn == 0) { + CFileRecord::ProcessFiles(); + + ////////////////////////////////////////// + // JUST PRINT THE DEPENDANCIES + ////////////////////////////////////////// + /*if( !bSimple ){ + CFileRecord::PrintTargets("OBJ_FILES", "\\"); + if(b16) { + CFileRecord::PrintTargets("LINK_OBJS", "+\\"); + } + else { + CFileRecord::PrintTargets("LINK_OBJS", "^"); + } + CFileRecord::PrintSources(); + CFileRecord::PrintBuildRules(); + }*/ + ////////////////////////////////////////// + + CFileRecord::PrintDependancies(); + } + + if(pAltFile != stdout) { + fclose(pAltFile); + if (mainReturn != 0) { + remove(outputFileName); // kill output file if returning an error + } + } + } + iRecursion--; + return mainReturn; +} diff --git a/ef/Driver/StandAloneJava/winbuild/javah.dsp b/ef/Driver/StandAloneJava/winbuild/javah.dsp new file mode 100644 index 000000000000..6f7e729bc45d --- /dev/null +++ b/ef/Driver/StandAloneJava/winbuild/javah.dsp @@ -0,0 +1,115 @@ +# Microsoft Developer Studio Project File - Name="javah" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 5.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=javah - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "javah.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "javah.mak" CFG="javah - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "javah - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "javah - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "javah - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\..\Debugger ..\..\..\Exports ..\..\..\Exports\md" /I "..\..\..\Exports ..\..\..\Exports\md" /I "..\..\..\Debugger" /I "..\..\..\Compiler\FrontEnd" /I "..\..\..\Compiler\PrimitiveGraph" /I "..\..\..\Driver\StandAloneJava" /I "..\..\..\Runtime\System" /I "..\..\..\..\dist\WINNT4.0_DBG.OBJ\include" /I "..\..\..\Utilities\zlib" /I "..\..\..\Runtime\ClassInfo" /I "..\..\..\Runtime\ClassReader" /I "..\..\..\Runtime\FileReader" /I "..\..\..\Runtime\NativeMethods" /I "..\..\..\Runtime\Systems" /I "..\..\..\Compiler\CodeGenerator" /I "..\..\..\Compiler\RegisterAllocator" /I "..\..\..\Compiler\CodeGenerator\md\x86\x86dis" /I "..\..\..\Compiler\CodeGenerator\md\x86" /I "..\..\..\Compiler\CodeGenerator\md" /I ".\\" /I ".\genfiles" /I "..\..\..\Compiler\Optimizer" /I "..\..\..\Utilities\General" /I "..\..\..\Exports" /I "..\..\..\Exports\md" /I "..\..\..\Runtime\System\md" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /D "EF_WINDOWS" /D "GENERATE_FOR_X86" /D "XP_PC" /D "USE_PR_IO" /D "IMPORTING_VM_FILES" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 release\electricalfire.lib ..\..\..\..\dist\WINNT4.0_OPT.OBJ\lib\libnspr21.lib ..\..\..\..\dist\WINNT4.0_OPT.OBJ\lib\libplc20_s.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib /nologo /subsystem:console /incremental:yes /machine:I386 +# SUBTRACT LINK32 /debug + +!ELSEIF "$(CFG)" == "javah - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "electric" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MD /W3 /Gm /GX /Zi /I "..\..\..\Debugger\Communication" /I "..\..\..\Debugger" /I "..\..\..\Compiler\FrontEnd" /I "..\..\..\Compiler\PrimitiveGraph" /I "..\..\..\Driver\StandAloneJava" /I "..\..\..\Runtime\System" /I "..\..\..\..\dist\WINNT4.0_DBG.OBJ\include" /I "..\..\..\Utilities\zlib" /I "..\..\..\Runtime\ClassInfo" /I "..\..\..\Runtime\ClassReader" /I "..\..\..\Runtime\FileReader" /I "..\..\..\Runtime\NativeMethods" /I "..\..\..\Runtime\Systems" /I "..\..\..\Compiler\CodeGenerator" /I "..\..\..\Compiler\RegisterAllocator" /I "..\..\..\Compiler\CodeGenerator\md\x86\x86dis" /I "..\..\..\Compiler\CodeGenerator\md\x86" /I "..\..\..\Compiler\CodeGenerator\md" /I ".\\" /I ".\genfiles" /I "..\..\..\Compiler\Optimizer" /I "..\..\..\Utilities\General" /I "..\..\..\Exports" /I "..\..\..\Exports\md" /I "..\..\..\Runtime\System\md" /D "DEBUG" /D "EF_WINDOWS" /D "GENERATE_FOR_X86" /D "DEBUG_DESANTIS" /D "DEBUG_LOG" /D "DEBUG_kini" /D "XP_PC" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "USE_PR_IO" /D "IMPORTING_VM_FILES" /FR"electric/" /Fo"electric/" /Fd"electric/" /FD /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 electric\electricalfire.lib ..\..\..\..\dist\WINNT4.0_DBG.OBJ\lib\libnspr21.lib ..\..\..\..\dist\WINNT4.0_DBG.OBJ\lib\libplc21_s.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# SUBTRACT LINK32 /pdb:none + +!ENDIF + +# Begin Target + +# Name "javah - Win32 Release" +# Name "javah - Win32 Debug" +# Begin Source File + +SOURCE=..\..\..\Tools\JavaH\HeaderGenerator.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Tools\JavaH\HeaderGenerator.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Tools\JavaH\JNIHeaderGenerator.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Tools\JavaH\JNIHeaderGenerator.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Tools\JavaH\main.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Tools\JavaH\NetscapeHeaderGenerator.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Tools\JavaH\NetscapeHeaderGenerator.h +# End Source File +# End Target +# End Project diff --git a/ef/Driver/StandAloneJava/winbuild/sajava.dsp b/ef/Driver/StandAloneJava/winbuild/sajava.dsp new file mode 100644 index 000000000000..ea114cd42284 --- /dev/null +++ b/ef/Driver/StandAloneJava/winbuild/sajava.dsp @@ -0,0 +1,92 @@ +# Microsoft Developer Studio Project File - Name="sajava" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 5.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=sajava - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "sajava.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "sajava.mak" CFG="sajava - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "sajava - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "sajava - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "sajava - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /Zi /D "WIN32" /D "_DEBUG" /D "DEBUG" /D "_MBCS" /D "DEBUG_LOG /D" /YX /FD _CONSOLE" /c +# ADD CPP /nologo /W3 /GX /O2 /I "..\..\..\Debugger ..\..\..\Exports ..\..\..\Exports\md" /I "..\..\..\Exports ..\..\..\Exports\md" /I "..\..\..\Debugger" /I "..\..\..\Driver\StandAloneJava" /I "..\..\..\Utilities\General" /I "..\..\..\Utilities\General\md" /I "..\..\..\Compiler\FrontEnd" /I "..\..\..\Compiler\PrimitiveGraph" /I "..\..\..\Runtime\System" /I "..\..\..\..\dist\WINNT4.0_DBG.OBJ\include" /I "..\..\..\Utilities\zlib" /I "..\..\..\Runtime\ClassInfo" /I "..\..\..\Runtime\ClassReader" /I "..\..\..\Runtime\FileReader" /I "..\..\..\Runtime\NativeMethods" /I "..\..\..\Runtime\Systems" /I "..\..\..\Compiler\CodeGenerator" /I "..\..\..\Compiler\RegisterAllocator" /I "..\..\..\Compiler\CodeGenerator\md\x86\x86dis" /I "..\..\..\Compiler\CodeGenerator\md\x86" /I "..\..\..\Compiler\CodeGenerator\md" /I ".\\" /I ".\genfiles" /I "..\..\..\Compiler\Optimizer" /I "..\..\..\Exports" /I "..\..\..\Exports\md" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "EF_WINDOWS" /D "GENERATE_FOR_X86" /D "XP_PC" /D "GENERATE_NATIVE_STUBS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 Release\electricalfire.lib ..\..\..\..\dist\WINNT4.0_OPT.OBJ\lib\libnspr20.lib ..\..\..\..\dist\WINNT4.0_OPT.OBJ\lib\libplc20_s.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib /nologo /subsystem:console /machine:I386 +# SUBTRACT LINK32 /debug + +!ELSEIF "$(CFG)" == "sajava - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "electric" +# PROP Intermediate_Dir "electric" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /I "..\..\..\Debugger\Communication" /I "..\..\..\Debugger" /I "..\..\..\Driver\StandAloneJava" /I "..\..\..\Utilities\General" /I "..\..\..\Utilities\General\md" /I "..\..\..\Compiler\FrontEnd" /I "..\..\..\Compiler\PrimitiveGraph" /I "..\..\..\Runtime\System" /I "..\..\..\..\dist\WINNT4.0_DBG.OBJ\include" /I "..\..\..\Utilities\zlib" /I "..\..\..\Runtime\ClassInfo" /I "..\..\..\Runtime\ClassReader" /I "..\..\..\Runtime\FileReader" /I "..\..\..\Runtime\NativeMethods" /I "..\..\..\Runtime\Systems" /I "..\..\..\Compiler\CodeGenerator" /I "..\..\..\Compiler\RegisterAllocator" /I "..\..\..\Compiler\CodeGenerator\md\x86\x86dis" /I "..\..\..\Compiler\CodeGenerator\md\x86" /I "..\..\..\Compiler\CodeGenerator\md" /I ".\\" /I ".\genfiles" /I "..\..\..\Compiler\Optimizer" /I "..\..\..\Exports" /I "..\..\..\Exports\md" /D "DEBUG" /D "DEBUG_LOG" /D "_DEBUG" /D "DEBUG_DESANTIS" /D "DEBUG_kini" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "EF_WINDOWS" /D "GENERATE_FOR_X86" /D "XP_PC" /D "GENERATE_NATIVE_STUBS" /D "IMPORTING_VM_FILES" /FD /c +# SUBTRACT CPP /YX +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /i "C:\WINNT35\Profiles\kini\ns\dist\WINNT4.0_DBG.OBJ\lib" /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 electric\electricalfire.lib ..\..\..\..\dist\WINNT4.0_DBG.OBJ\lib\libnspr21.lib ..\..\..\..\dist\WINNT4.0_DBG.OBJ\lib\libplc21_s.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib /nologo /subsystem:console /debug /machine:I386 /nodefaultlib:"MSVCRT" /pdbtype:sept /libpath:"..\..\..\..\..\dist\WINNT4.0_DBG.OBJ\lib" +# SUBTRACT LINK32 /pdb:none + +!ENDIF + +# Begin Target + +# Name "sajava - Win32 Release" +# Name "sajava - Win32 Debug" +# Begin Source File + +SOURCE=..\efmain.cpp +# End Source File +# End Target +# End Project diff --git a/ef/Exports/Makefile b/ef/Exports/Makefile new file mode 100644 index 000000000000..aa34279b6622 --- /dev/null +++ b/ef/Exports/Makefile @@ -0,0 +1,40 @@ +#! gmake +# +# CONFIDENTIAL AND PROPRIETARY SOURCE CODE OF +# NETSCAPE COMMUNICATIONS CORPORATION +# Copyright © 1996, 1997 Netscape Communications Corporation. All Rights +# Reserved. Use of this Source Code is subject to the terms of the +# applicable license agreement from Netscape Communications Corporation. +# The copyright notice(s) in this Source Code does not indicate actual or +# intended publication of this Source Code. +# + +####################################################################### +# (1) Include manifest file # +####################################################################### + +include manifest.mn + +####################################################################### +# (2) Include "component" configuration information. # +####################################################################### + +include $(DEPTH)/config/config.mk + +####################################################################### +# (3) Include "local" platform-dependent assignments (OPTIONAL). # +####################################################################### + + + +####################################################################### +# (4) Execute "component" rules. (OPTIONAL) # +####################################################################### + +include $(DEPTH)/config/rules.mk + +####################################################################### +# (7) Execute "local" rules. (OPTIONAL). # +####################################################################### + + diff --git a/ef/Exports/jni.h b/ef/Exports/jni.h new file mode 100644 index 000000000000..ed3143e2a94b --- /dev/null +++ b/ef/Exports/jni.h @@ -0,0 +1,1857 @@ +/* + * @(#)jni.h 1.28 97/05/19 + * + * Copyright (c) 1993-1996 Sun Microsystems, Inc. All Rights Reserved. + * + * Permission to use, copy, modify, and distribute this software + * and its documentation for NON-COMMERCIAL purposes and without + * fee is hereby granted provided that this copyright notice + * appears in all copies. + * + * The Java source code is the confidential and proprietary information + * of Sun Microsystems, Inc. ("Confidential Information"). You shall + * not disclose such Confidential Information and shall use it only in + * accordance with the terms of the license agreement you entered into + * with Sun. + * + * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF + * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED + * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. + */ + +/* + * We used part of Netscape's Java Runtime Interface (JRI) as the starting + * point of our design and implementation. + */ + +/****************************************************************************** + * Java Runtime Interface + * Copyright (c) 1996 Netscape Communications Corporation. All rights reserved. + *****************************************************************************/ + +#ifndef JNI_H +#define JNI_H + +#include +#include + +/* jni_md.h contains the machine-dependent typedefs for jbyte, jint + and jlong */ + +#include "jni_md.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * JNI Types + */ + +typedef unsigned char jboolean; +typedef unsigned short jchar; +typedef short jshort; +typedef float jfloat; +typedef double jdouble; + +typedef jint jsize; + +#ifdef __cplusplus + +class _jobject {}; +class _jclass : public _jobject {}; +class _jthrowable : public _jobject {}; +class _jstring : public _jobject {}; +class _jarray : public _jobject {}; +class _jbooleanArray : public _jarray {}; +class _jbyteArray : public _jarray {}; +class _jcharArray : public _jarray {}; +class _jshortArray : public _jarray {}; +class _jintArray : public _jarray {}; +class _jlongArray : public _jarray {}; +class _jfloatArray : public _jarray {}; +class _jdoubleArray : public _jarray {}; +class _jobjectArray : public _jarray {}; + +typedef _jobject *jobject; +typedef _jclass *jclass; +typedef _jthrowable *jthrowable; +typedef _jstring *jstring; +typedef _jarray *jarray; +typedef _jbooleanArray *jbooleanArray; +typedef _jbyteArray *jbyteArray; +typedef _jcharArray *jcharArray; +typedef _jshortArray *jshortArray; +typedef _jintArray *jintArray; +typedef _jlongArray *jlongArray; +typedef _jfloatArray *jfloatArray; +typedef _jdoubleArray *jdoubleArray; +typedef _jobjectArray *jobjectArray; + +#else + +struct _jobject; + +typedef struct _jobject *jobject; +typedef jobject jclass; +typedef jobject jthrowable; +typedef jobject jstring; +typedef jobject jarray; +typedef jarray jbooleanArray; +typedef jarray jbyteArray; +typedef jarray jcharArray; +typedef jarray jshortArray; +typedef jarray jintArray; +typedef jarray jlongArray; +typedef jarray jfloatArray; +typedef jarray jdoubleArray; +typedef jarray jobjectArray; + +#endif + +typedef jobject jref; /* For transition---not meant to be part of public + API anymore.*/ +typedef jobject jweak; + +typedef union jvalue { + jboolean z; + jbyte b; + jchar c; + jshort s; + jint i; + jlong j; + jfloat f; + jdouble d; + jobject l; +} jvalue; + +struct _jfieldID; +typedef struct _jfieldID *jfieldID; + +struct _jmethodID; +typedef struct _jmethodID *jmethodID; + +/* + * jboolean constants + */ + +#define JNI_FALSE 0 +#define JNI_TRUE 1 + +/* + * possible return values for JNI functions. + */ + +#define JNI_OK 0 +#define JNI_ERR (-1) + +/* + * used in ReleaseScalarArrayElements + */ + +#define JNI_COMMIT 1 +#define JNI_ABORT 2 + +/* + * used in RegisterNatives to describe native method name, signature, + * and function pointer. + */ + +typedef struct { + char *name; + char *signature; + void *fnPtr; +} JNINativeMethod; + +/* + * JNI Native Method Interface. + */ + +struct JNINativeInterface_; + +struct JNIEnv_; + +#ifdef __cplusplus +typedef JNIEnv_ JNIEnv; +#else +typedef const struct JNINativeInterface_ *JNIEnv; +#endif + +/* + * JNI Invocation Interface. + */ + +struct JNIInvokeInterface_; + +struct JavaVM_; + +#ifdef __cplusplus +typedef JavaVM_ JavaVM; +#else +typedef const struct JNIInvokeInterface_ *JavaVM; +#endif + +struct JNINativeInterface_ { + void *reserved0; + void *reserved1; + void *reserved2; + + void *reserved3; + JNIFUNCPTR(jint, GetVersion)(JNIEnv *env); + + JNIFUNCPTR(jclass, DefineClass) + (JNIEnv *env, const char *name, jobject loader, const jbyte *buf, + jsize len); + JNIFUNCPTR(jclass, FindClass) + (JNIEnv *env, const char *name); + + JNIFUNCPTR(jmethodID, FromReflectedMethod) + (JNIEnv *env, jobject method); + JNIFUNCPTR(jfieldID, FromReflectedField) + (JNIEnv *env, jobject field); + + JNIFUNCPTR(jobject, ToReflectedMethod) + (JNIEnv *env, jclass cls, jmethodID methodID); + + /*void *reserved4; + void *reserved5; + void *reserved6; + */ + + JNIFUNCPTR(jclass, GetSuperclass) + (JNIEnv *env, jclass sub); + JNIFUNCPTR(jboolean, IsAssignableFrom) + (JNIEnv *env, jclass sub, jclass sup); + + JNIFUNCPTR(jobject, ToReflectedField) + (JNIEnv *env, jclass cls, jfieldID fieldID); + + /* void *reserved7;*/ + + JNIFUNCPTR(jint, Throw) + (JNIEnv *env, jthrowable obj); + JNIFUNCPTR(jint, ThrowNew) + (JNIEnv *env, jclass clazz, const char *msg); + JNIFUNCPTR(jthrowable, ExceptionOccurred) + (JNIEnv *env); + JNIFUNCPTR(void, ExceptionDescribe) + (JNIEnv *env); + JNIFUNCPTR(void, ExceptionClear) + (JNIEnv *env); + JNIFUNCPTR(void, FatalError) + (JNIEnv *env, const char *msg); + + JNIFUNCPTR(jint, PushLocalFrame) + (JNIEnv *env, jint capacity); + JNIFUNCPTR (jobject, PopLocalFrame) + (JNIEnv *env, jobject result); + + /* void *reserved8; + void *reserved9; + */ + + JNIFUNCPTR(jobject, NewGlobalRef) + (JNIEnv *env, jobject lobj); + JNIFUNCPTR(void, DeleteGlobalRef) + (JNIEnv *env, jobject gref); + JNIFUNCPTR(void, DeleteLocalRef) + (JNIEnv *env, jobject obj); + JNIFUNCPTR(jboolean, IsSameObject) + (JNIEnv *env, jobject obj1, jobject obj2); + + JNIFUNCPTR(jobject, NewLocalRef) + (JNIEnv *env, jobject ref); + JNIFUNCPTR(jint, EnsureLocalCapacity) + (JNIEnv *env, jint capacity); + + /* + void *reserved10; + void *reserved11; + */ + + JNIFUNCPTR(jobject, AllocObject) + (JNIEnv *env, jclass clazz); + JNIFUNCPTR(jobject, NewObject) + (JNIEnv *env, jclass clazz, jmethodID methodID, ...); + JNIFUNCPTR(jobject, NewObjectV) + (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); + JNIFUNCPTR(jobject, NewObjectA) + (JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args); + + JNIFUNCPTR(jclass, GetObjectClass) + (JNIEnv *env, jobject obj); + JNIFUNCPTR(jboolean, IsInstanceOf) + (JNIEnv *env, jobject obj, jclass clazz); + + JNIFUNCPTR(jmethodID, GetMethodID) + (JNIEnv *env, jclass clazz, const char *name, const char *sig); + + JNIFUNCPTR(jobject, CallObjectMethod) + (JNIEnv *env, jobject obj, jmethodID methodID, ...); + JNIFUNCPTR(jobject, CallObjectMethodV) + (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); + JNIFUNCPTR(jobject, CallObjectMethodA) + (JNIEnv *env, jobject obj, jmethodID methodID, jvalue * args); + + JNIFUNCPTR(jboolean, CallBooleanMethod) + (JNIEnv *env, jobject obj, jmethodID methodID, ...); + JNIFUNCPTR(jboolean, CallBooleanMethodV) + (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); + JNIFUNCPTR(jboolean, CallBooleanMethodA) + (JNIEnv *env, jobject obj, jmethodID methodID, jvalue * args); + + JNIFUNCPTR(jbyte, CallByteMethod) + (JNIEnv *env, jobject obj, jmethodID methodID, ...); + JNIFUNCPTR(jbyte, CallByteMethodV) + (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); + JNIFUNCPTR(jbyte, CallByteMethodA) + (JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args); + + JNIFUNCPTR(jchar, CallCharMethod) + (JNIEnv *env, jobject obj, jmethodID methodID, ...); + JNIFUNCPTR(jchar, CallCharMethodV) + (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); + JNIFUNCPTR(jchar, CallCharMethodA) + (JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args); + + JNIFUNCPTR(jshort, CallShortMethod) + (JNIEnv *env, jobject obj, jmethodID methodID, ...); + JNIFUNCPTR(jshort, CallShortMethodV) + (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); + JNIFUNCPTR(jshort, CallShortMethodA) + (JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args); + + JNIFUNCPTR(jint, CallIntMethod) + (JNIEnv *env, jobject obj, jmethodID methodID, ...); + JNIFUNCPTR(jint, CallIntMethodV) + (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); + JNIFUNCPTR(jint, CallIntMethodA) + (JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args); + + JNIFUNCPTR(jlong, CallLongMethod) + (JNIEnv *env, jobject obj, jmethodID methodID, ...); + JNIFUNCPTR(jlong, CallLongMethodV) + (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); + JNIFUNCPTR(jlong, CallLongMethodA) + (JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args); + + JNIFUNCPTR(jfloat, CallFloatMethod) + (JNIEnv *env, jobject obj, jmethodID methodID, ...); + JNIFUNCPTR(jfloat, CallFloatMethodV) + (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); + JNIFUNCPTR(jfloat, CallFloatMethodA) + (JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args); + + JNIFUNCPTR(jdouble, CallDoubleMethod) + (JNIEnv *env, jobject obj, jmethodID methodID, ...); + JNIFUNCPTR(jdouble, CallDoubleMethodV) + (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); + JNIFUNCPTR(jdouble, CallDoubleMethodA) + (JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args); + + JNIFUNCPTR(void, CallVoidMethod) + (JNIEnv *env, jobject obj, jmethodID methodID, ...); + JNIFUNCPTR(void, CallVoidMethodV) + (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); + JNIFUNCPTR(void, CallVoidMethodA) + (JNIEnv *env, jobject obj, jmethodID methodID, jvalue * args); + + JNIFUNCPTR(jobject, CallNonvirtualObjectMethod) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); + JNIFUNCPTR(jobject, CallNonvirtualObjectMethodV) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + va_list args); + JNIFUNCPTR(jobject, CallNonvirtualObjectMethodA) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + jvalue * args); + + JNIFUNCPTR(jboolean, CallNonvirtualBooleanMethod) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); + JNIFUNCPTR(jboolean, CallNonvirtualBooleanMethodV) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + va_list args); + JNIFUNCPTR(jboolean, CallNonvirtualBooleanMethodA) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + jvalue * args); + + JNIFUNCPTR(jbyte, CallNonvirtualByteMethod) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); + JNIFUNCPTR(jbyte, CallNonvirtualByteMethodV) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + va_list args); + JNIFUNCPTR(jbyte, CallNonvirtualByteMethodA) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + jvalue *args); + + JNIFUNCPTR(jchar, CallNonvirtualCharMethod) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); + JNIFUNCPTR(jchar, CallNonvirtualCharMethodV) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + va_list args); + JNIFUNCPTR(jchar, CallNonvirtualCharMethodA) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + jvalue *args); + + JNIFUNCPTR(jshort, CallNonvirtualShortMethod) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); + JNIFUNCPTR(jshort, CallNonvirtualShortMethodV) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + va_list args); + JNIFUNCPTR(jshort, CallNonvirtualShortMethodA) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + jvalue *args); + + JNIFUNCPTR(jint, CallNonvirtualIntMethod) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); + JNIFUNCPTR(jint, CallNonvirtualIntMethodV) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + va_list args); + JNIFUNCPTR(jint, CallNonvirtualIntMethodA) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + jvalue *args); + + JNIFUNCPTR(jlong, CallNonvirtualLongMethod) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); + JNIFUNCPTR(jlong, CallNonvirtualLongMethodV) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + va_list args); + JNIFUNCPTR(jlong, CallNonvirtualLongMethodA) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + jvalue *args); + + JNIFUNCPTR(jfloat, CallNonvirtualFloatMethod) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); + JNIFUNCPTR(jfloat, CallNonvirtualFloatMethodV) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + va_list args); + JNIFUNCPTR(jfloat, CallNonvirtualFloatMethodA) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + jvalue *args); + + JNIFUNCPTR(jdouble, CallNonvirtualDoubleMethod) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); + JNIFUNCPTR(jdouble, CallNonvirtualDoubleMethodV) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + va_list args); + JNIFUNCPTR(jdouble, CallNonvirtualDoubleMethodA) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + jvalue *args); + + JNIFUNCPTR(void, CallNonvirtualVoidMethod) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); + JNIFUNCPTR(void, CallNonvirtualVoidMethodV) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + va_list args); + JNIFUNCPTR(void, CallNonvirtualVoidMethodA) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + jvalue * args); + + JNIFUNCPTR(jfieldID, GetFieldID) + (JNIEnv *env, jclass clazz, const char *name, const char *sig); + + JNIFUNCPTR(jobject, GetObjectField) + (JNIEnv *env, jobject obj, jfieldID fieldID); + JNIFUNCPTR(jboolean, GetBooleanField) + (JNIEnv *env, jobject obj, jfieldID fieldID); + JNIFUNCPTR(jbyte, GetByteField) + (JNIEnv *env, jobject obj, jfieldID fieldID); + JNIFUNCPTR(jchar, GetCharField) + (JNIEnv *env, jobject obj, jfieldID fieldID); + JNIFUNCPTR(jshort, GetShortField) + (JNIEnv *env, jobject obj, jfieldID fieldID); + JNIFUNCPTR(jint, GetIntField) + (JNIEnv *env, jobject obj, jfieldID fieldID); + JNIFUNCPTR(jlong, GetLongField) + (JNIEnv *env, jobject obj, jfieldID fieldID); + JNIFUNCPTR(jfloat, GetFloatField) + (JNIEnv *env, jobject obj, jfieldID fieldID); + JNIFUNCPTR(jdouble, GetDoubleField) + (JNIEnv *env, jobject obj, jfieldID fieldID); + + JNIFUNCPTR(void, SetObjectField) + (JNIEnv *env, jobject obj, jfieldID fieldID, jobject val); + JNIFUNCPTR(void, SetBooleanField) + (JNIEnv *env, jobject obj, jfieldID fieldID, jboolean val); + JNIFUNCPTR(void, SetByteField) + (JNIEnv *env, jobject obj, jfieldID fieldID, jbyte val); + JNIFUNCPTR(void, SetCharField) + (JNIEnv *env, jobject obj, jfieldID fieldID, jchar val); + JNIFUNCPTR(void, SetShortField) + (JNIEnv *env, jobject obj, jfieldID fieldID, jshort val); + JNIFUNCPTR(void, SetIntField) + (JNIEnv *env, jobject obj, jfieldID fieldID, jint val); + JNIFUNCPTR(void, SetLongField) + (JNIEnv *env, jobject obj, jfieldID fieldID, jlong val); + JNIFUNCPTR(void, SetFloatField) + (JNIEnv *env, jobject obj, jfieldID fieldID, jfloat val); + JNIFUNCPTR(void, SetDoubleField) + (JNIEnv *env, jobject obj, jfieldID fieldID, jdouble val); + + JNIFUNCPTR(jmethodID, GetStaticMethodID) + (JNIEnv *env, jclass clazz, const char *name, const char *sig); + + JNIFUNCPTR(jobject, CallStaticObjectMethod) + (JNIEnv *env, jclass clazz, jmethodID methodID, ...); + JNIFUNCPTR(jobject, CallStaticObjectMethodV) + (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); + JNIFUNCPTR(jobject, CallStaticObjectMethodA) + (JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args); + + JNIFUNCPTR(jboolean, CallStaticBooleanMethod) + (JNIEnv *env, jclass clazz, jmethodID methodID, ...); + JNIFUNCPTR(jboolean, CallStaticBooleanMethodV) + (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); + JNIFUNCPTR(jboolean, CallStaticBooleanMethodA) + (JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args); + + JNIFUNCPTR(jbyte, CallStaticByteMethod) + (JNIEnv *env, jclass clazz, jmethodID methodID, ...); + JNIFUNCPTR(jbyte, CallStaticByteMethodV) + (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); + JNIFUNCPTR(jbyte, CallStaticByteMethodA) + (JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args); + + JNIFUNCPTR(jchar, CallStaticCharMethod) + (JNIEnv *env, jclass clazz, jmethodID methodID, ...); + JNIFUNCPTR(jchar, CallStaticCharMethodV) + (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); + JNIFUNCPTR(jchar, CallStaticCharMethodA) + (JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args); + + JNIFUNCPTR(jshort, CallStaticShortMethod) + (JNIEnv *env, jclass clazz, jmethodID methodID, ...); + JNIFUNCPTR(jshort, CallStaticShortMethodV) + (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); + JNIFUNCPTR(jshort, CallStaticShortMethodA) + (JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args); + + JNIFUNCPTR(jint, CallStaticIntMethod) + (JNIEnv *env, jclass clazz, jmethodID methodID, ...); + JNIFUNCPTR(jint, CallStaticIntMethodV) + (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); + JNIFUNCPTR(jint, CallStaticIntMethodA) + (JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args); + + JNIFUNCPTR(jlong, CallStaticLongMethod) + (JNIEnv *env, jclass clazz, jmethodID methodID, ...); + JNIFUNCPTR(jlong, CallStaticLongMethodV) + (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); + JNIFUNCPTR(jlong, CallStaticLongMethodA) + (JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args); + + JNIFUNCPTR(jfloat, CallStaticFloatMethod) + (JNIEnv *env, jclass clazz, jmethodID methodID, ...); + JNIFUNCPTR(jfloat, CallStaticFloatMethodV) + (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); + JNIFUNCPTR(jfloat, CallStaticFloatMethodA) + (JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args); + + JNIFUNCPTR(jdouble, CallStaticDoubleMethod) + (JNIEnv *env, jclass clazz, jmethodID methodID, ...); + JNIFUNCPTR(jdouble, CallStaticDoubleMethodV) + (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); + JNIFUNCPTR(jdouble, CallStaticDoubleMethodA) + (JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args); + + JNIFUNCPTR(void, CallStaticVoidMethod) + (JNIEnv *env, jclass cls, jmethodID methodID, ...); + JNIFUNCPTR(void, CallStaticVoidMethodV) + (JNIEnv *env, jclass cls, jmethodID methodID, va_list args); + JNIFUNCPTR(void, CallStaticVoidMethodA) + (JNIEnv *env, jclass cls, jmethodID methodID, jvalue * args); + + JNIFUNCPTR(jfieldID, GetStaticFieldID) + (JNIEnv *env, jclass clazz, const char *name, const char *sig); + JNIFUNCPTR(jobject, GetStaticObjectField) + (JNIEnv *env, jclass clazz, jfieldID fieldID); + JNIFUNCPTR(jboolean, GetStaticBooleanField) + (JNIEnv *env, jclass clazz, jfieldID fieldID); + JNIFUNCPTR(jbyte, GetStaticByteField) + (JNIEnv *env, jclass clazz, jfieldID fieldID); + JNIFUNCPTR(jchar, GetStaticCharField) + (JNIEnv *env, jclass clazz, jfieldID fieldID); + JNIFUNCPTR(jshort, GetStaticShortField) + (JNIEnv *env, jclass clazz, jfieldID fieldID); + JNIFUNCPTR(jint, GetStaticIntField) + (JNIEnv *env, jclass clazz, jfieldID fieldID); + JNIFUNCPTR(jlong, GetStaticLongField) + (JNIEnv *env, jclass clazz, jfieldID fieldID); + JNIFUNCPTR(jfloat, GetStaticFloatField) + (JNIEnv *env, jclass clazz, jfieldID fieldID); + JNIFUNCPTR(jdouble, GetStaticDoubleField) + (JNIEnv *env, jclass clazz, jfieldID fieldID); + + JNIFUNCPTR(void, SetStaticObjectField) + (JNIEnv *env, jclass clazz, jfieldID fieldID, jobject value); + JNIFUNCPTR(void, SetStaticBooleanField) + (JNIEnv *env, jclass clazz, jfieldID fieldID, jboolean value); + JNIFUNCPTR(void, SetStaticByteField) + (JNIEnv *env, jclass clazz, jfieldID fieldID, jbyte value); + JNIFUNCPTR(void, SetStaticCharField) + (JNIEnv *env, jclass clazz, jfieldID fieldID, jchar value); + JNIFUNCPTR(void, SetStaticShortField) + (JNIEnv *env, jclass clazz, jfieldID fieldID, jshort value); + JNIFUNCPTR(void, SetStaticIntField) + (JNIEnv *env, jclass clazz, jfieldID fieldID, jint value); + JNIFUNCPTR(void, SetStaticLongField) + (JNIEnv *env, jclass clazz, jfieldID fieldID, jlong value); + JNIFUNCPTR(void, SetStaticFloatField) + (JNIEnv *env, jclass clazz, jfieldID fieldID, jfloat value); + JNIFUNCPTR(void, SetStaticDoubleField) + (JNIEnv *env, jclass clazz, jfieldID fieldID, jdouble value); + + JNIFUNCPTR(jstring, NewString) + (JNIEnv *env, const jchar *unicode, jsize len); + JNIFUNCPTR(jsize, GetStringLength) + (JNIEnv *env, jstring str); + JNIFUNCPTR(const jchar*, GetStringChars) + (JNIEnv *env, jstring str, jboolean *isCopy); + JNIFUNCPTR(void, ReleaseStringChars) + (JNIEnv *env, jstring str, const jchar *chars); + + JNIFUNCPTR(jstring, NewStringUTF) + (JNIEnv *env, const char *utf); + JNIFUNCPTR(jsize, GetStringUTFLength) + (JNIEnv *env, jstring str); + JNIFUNCPTR(const char*, GetStringUTFChars) + (JNIEnv *env, jstring str, jboolean *isCopy); + JNIFUNCPTR(void, ReleaseStringUTFChars) + (JNIEnv *env, jstring str, const char* chars); + + + JNIFUNCPTR(jsize, GetArrayLength) + (JNIEnv *env, jarray array); + + JNIFUNCPTR(jobjectArray, NewObjectArray) + (JNIEnv *env, jsize len, jclass clazz, jobject init); + JNIFUNCPTR(jobject, GetObjectArrayElement) + (JNIEnv *env, jobjectArray array, jsize index); + JNIFUNCPTR(void, SetObjectArrayElement) + (JNIEnv *env, jobjectArray array, jsize index, jobject val); + + JNIFUNCPTR(jbooleanArray, NewBooleanArray) + (JNIEnv *env, jsize len); + JNIFUNCPTR(jbyteArray, NewByteArray) + (JNIEnv *env, jsize len); + JNIFUNCPTR(jcharArray, NewCharArray) + (JNIEnv *env, jsize len); + JNIFUNCPTR(jshortArray, NewShortArray) + (JNIEnv *env, jsize len); + JNIFUNCPTR(jintArray, NewIntArray) + (JNIEnv *env, jsize len); + JNIFUNCPTR(jlongArray, NewLongArray) + (JNIEnv *env, jsize len); + JNIFUNCPTR(jfloatArray, NewFloatArray) + (JNIEnv *env, jsize len); + JNIFUNCPTR(jdoubleArray, NewDoubleArray) + (JNIEnv *env, jsize len); + + JNIFUNCPTR(jboolean *, GetBooleanArrayElements) + (JNIEnv *env, jbooleanArray array, jboolean *isCopy); + JNIFUNCPTR(jbyte *, GetByteArrayElements) + (JNIEnv *env, jbyteArray array, jboolean *isCopy); + JNIFUNCPTR(jchar *, GetCharArrayElements) + (JNIEnv *env, jcharArray array, jboolean *isCopy); + JNIFUNCPTR(jshort *, GetShortArrayElements) + (JNIEnv *env, jshortArray array, jboolean *isCopy); + JNIFUNCPTR(jint *, GetIntArrayElements) + (JNIEnv *env, jintArray array, jboolean *isCopy); + JNIFUNCPTR(jlong *, GetLongArrayElements) + (JNIEnv *env, jlongArray array, jboolean *isCopy); + JNIFUNCPTR(jfloat *, GetFloatArrayElements) + (JNIEnv *env, jfloatArray array, jboolean *isCopy); + JNIFUNCPTR(jdouble *, GetDoubleArrayElements) + (JNIEnv *env, jdoubleArray array, jboolean *isCopy); + + JNIFUNCPTR(void, ReleaseBooleanArrayElements) + (JNIEnv *env, jbooleanArray array, jboolean *elems, jint mode); + JNIFUNCPTR(void, ReleaseByteArrayElements) + (JNIEnv *env, jbyteArray array, jbyte *elems, jint mode); + JNIFUNCPTR(void, ReleaseCharArrayElements) + (JNIEnv *env, jcharArray array, jchar *elems, jint mode); + JNIFUNCPTR(void, ReleaseShortArrayElements) + (JNIEnv *env, jshortArray array, jshort *elems, jint mode); + JNIFUNCPTR(void, ReleaseIntArrayElements) + (JNIEnv *env, jintArray array, jint *elems, jint mode); + JNIFUNCPTR(void, ReleaseLongArrayElements) + (JNIEnv *env, jlongArray array, jlong *elems, jint mode); + JNIFUNCPTR(void, ReleaseFloatArrayElements) + (JNIEnv *env, jfloatArray array, jfloat *elems, jint mode); + JNIFUNCPTR(void, ReleaseDoubleArrayElements) + (JNIEnv *env, jdoubleArray array, jdouble *elems, jint mode); + + JNIFUNCPTR(void, GetBooleanArrayRegion) + (JNIEnv *env, jbooleanArray array, jsize start, jsize l, jboolean *buf); + JNIFUNCPTR(void, GetByteArrayRegion) + (JNIEnv *env, jbyteArray array, jsize start, jsize len, jbyte *buf); + JNIFUNCPTR(void, GetCharArrayRegion) + (JNIEnv *env, jcharArray array, jsize start, jsize len, jchar *buf); + JNIFUNCPTR(void, GetShortArrayRegion) + (JNIEnv *env, jshortArray array, jsize start, jsize len, jshort *buf); + JNIFUNCPTR(void, GetIntArrayRegion) + (JNIEnv *env, jintArray array, jsize start, jsize len, jint *buf); + JNIFUNCPTR(void, GetLongArrayRegion) + (JNIEnv *env, jlongArray array, jsize start, jsize len, jlong *buf); + JNIFUNCPTR(void, GetFloatArrayRegion) + (JNIEnv *env, jfloatArray array, jsize start, jsize len, jfloat *buf); + JNIFUNCPTR(void, GetDoubleArrayRegion) + (JNIEnv *env, jdoubleArray array, jsize start, jsize len, jdouble *buf); + + JNIFUNCPTR(void, SetBooleanArrayRegion) + (JNIEnv *env, jbooleanArray array, jsize start, jsize l, jboolean *buf); + JNIFUNCPTR(void, SetByteArrayRegion) + (JNIEnv *env, jbyteArray array, jsize start, jsize len, jbyte *buf); + JNIFUNCPTR(void, SetCharArrayRegion) + (JNIEnv *env, jcharArray array, jsize start, jsize len, jchar *buf); + JNIFUNCPTR(void, SetShortArrayRegion) + (JNIEnv *env, jshortArray array, jsize start, jsize len, jshort *buf); + JNIFUNCPTR(void, SetIntArrayRegion) + (JNIEnv *env, jintArray array, jsize start, jsize len, jint *buf); + JNIFUNCPTR(void, SetLongArrayRegion) + (JNIEnv *env, jlongArray array, jsize start, jsize len, jlong *buf); + JNIFUNCPTR(void, SetFloatArrayRegion) + (JNIEnv *env, jfloatArray array, jsize start, jsize len, jfloat *buf); + JNIFUNCPTR(void, SetDoubleArrayRegion) + (JNIEnv *env, jdoubleArray array, jsize start, jsize len, jdouble *buf); + + JNIFUNCPTR(jint, RegisterNatives) + (JNIEnv *env, jclass clazz, const JNINativeMethod *methods, + jint nMethods); + JNIFUNCPTR(jint, UnregisterNatives) + (JNIEnv *env, jclass clazz); + + JNIFUNCPTR(jint, MonitorEnter) + (JNIEnv *env, jobject obj); + JNIFUNCPTR(jint, MonitorExit) + (JNIEnv *env, jobject obj); + + JNIFUNCPTR(jint, GetJavaVM) + (JNIEnv *env, JavaVM **vm); + + JNIFUNCPTR(void, GetStringRegion) + (JNIEnv *env, jstring str, jsize start, jsize len, jchar *buf); + JNIFUNCPTR(void, GetStringUTFRegion) + (JNIEnv *env, jstring str, jsize start, jsize len, char *buf); + + JNIFUNCPTR(void *, GetPrimitiveArrayCritical) + (JNIEnv *env, jarray array, jboolean *isCopy); + JNIFUNCPTR(void, ReleasePrimitiveArrayCritical) + (JNIEnv *env, jarray array, void *carray, jint mode); + + JNIFUNCPTR(const jchar *, GetStringCritical) + (JNIEnv *env, jstring string, jboolean *isCopy); + JNIFUNCPTR(void, ReleaseStringCritical) + (JNIEnv *env, jstring string, const jchar *cstring); + + JNIFUNCPTR(jweak, NewWeakGlobalRef) + (JNIEnv *env, jobject obj); + JNIFUNCPTR(void, DeleteWeakGlobalRef) + (JNIEnv *env, jweak ref); + + JNIFUNCPTR(jboolean, ExceptionCheck) + (JNIEnv *env); + +}; + +/* + * We use inlined functions for C++ so that programmers can write: + * + * env->FindClass("java/lang/String") + * + * in C++ rather than: + * + * (*env)->FindClass(env, "java/lang/String") + * + * in C. + */ + +struct JNIEnv_ { + const struct JNINativeInterface_ *functions; + void *reserved0; + void *reserved1[6]; +#ifdef __cplusplus + + jint GetVersion() { + return functions->GetVersion(this); + } + jclass DefineClass(const char *name, jobject loader, const jbyte *buf, + jsize len) { + return functions->DefineClass(this, name, loader, buf, len); + } + jclass FindClass(const char *name) { + return functions->FindClass(this, name); + } + jclass GetSuperclass(jclass sub) { + return functions->GetSuperclass(this, sub); + } + jboolean IsAssignableFrom(jclass sub, jclass sup) { + return functions->IsAssignableFrom(this, sub, sup); + } + + jint Throw(jthrowable obj) { + return functions->Throw(this, obj); + } + jint ThrowNew(jclass clazz, const char *msg) { + return functions->ThrowNew(this, clazz, msg); + } + jthrowable ExceptionOccurred() { + return functions->ExceptionOccurred(this); + } + void ExceptionDescribe() { + functions->ExceptionDescribe(this); + } + void ExceptionClear() { + functions->ExceptionClear(this); + } + void FatalError(const char *msg) { + functions->FatalError(this, msg); + } + + jobject NewGlobalRef(jobject lobj) { + return functions->NewGlobalRef(this,lobj); + } + void DeleteGlobalRef(jobject gref) { + functions->DeleteGlobalRef(this,gref); + } + void DeleteLocalRef(jobject obj) { + functions->DeleteLocalRef(this, obj); + } + + jboolean IsSameObject(jobject obj1, jobject obj2) { + return functions->IsSameObject(this,obj1,obj2); + } + + jobject AllocObject(jclass clazz) { + return functions->AllocObject(this,clazz); + } + jobject NewObject(jclass clazz, jmethodID methodID, ...) { + va_list args; + jobject result; + va_start(args, methodID); + result = functions->NewObjectV(this,clazz,methodID,args); + va_end(args); + return result; + } + jobject NewObjectV(jclass clazz, jmethodID methodID, + va_list args) { + return functions->NewObjectV(this,clazz,methodID,args); + } + jobject NewObjectA(jclass clazz, jmethodID methodID, + jvalue *args) { + return functions->NewObjectA(this,clazz,methodID,args); + } + + jclass GetObjectClass(jobject obj) { + return functions->GetObjectClass(this,obj); + } + jboolean IsInstanceOf(jobject obj, jclass clazz) { + return functions->IsInstanceOf(this,obj,clazz); + } + + jmethodID GetMethodID(jclass clazz, const char *name, + const char *sig) { + return functions->GetMethodID(this,clazz,name,sig); + } + + jobject CallObjectMethod(jobject obj, jmethodID methodID, ...) { + va_list args; + jobject result; + va_start(args,methodID); + result = functions->CallObjectMethodV(this,obj,methodID,args); + va_end(args); + return result; + } + jobject CallObjectMethodV(jobject obj, jmethodID methodID, + va_list args) { + return functions->CallObjectMethodV(this,obj,methodID,args); + } + jobject CallObjectMethodA(jobject obj, jmethodID methodID, + jvalue * args) { + return functions->CallObjectMethodA(this,obj,methodID,args); + } + + jboolean CallBooleanMethod(jobject obj, + jmethodID methodID, ...) { + va_list args; + jboolean result; + va_start(args,methodID); + result = functions->CallBooleanMethodV(this,obj,methodID,args); + va_end(args); + return result; + } + jboolean CallBooleanMethodV(jobject obj, jmethodID methodID, + va_list args) { + return functions->CallBooleanMethodV(this,obj,methodID,args); + } + jboolean CallBooleanMethodA(jobject obj, jmethodID methodID, + jvalue * args) { + return functions->CallBooleanMethodA(this,obj,methodID, args); + } + + jbyte CallByteMethod(jobject obj, jmethodID methodID, ...) { + va_list args; + jbyte result; + va_start(args,methodID); + result = functions->CallByteMethodV(this,obj,methodID,args); + va_end(args); + return result; + } + jbyte CallByteMethodV(jobject obj, jmethodID methodID, + va_list args) { + return functions->CallByteMethodV(this,obj,methodID,args); + } + jbyte CallByteMethodA(jobject obj, jmethodID methodID, + jvalue * args) { + return functions->CallByteMethodA(this,obj,methodID,args); + } + + jchar CallCharMethod(jobject obj, jmethodID methodID, ...) { + va_list args; + jchar result; + va_start(args,methodID); + result = functions->CallCharMethodV(this,obj,methodID,args); + va_end(args); + return result; + } + jchar CallCharMethodV(jobject obj, jmethodID methodID, + va_list args) { + return functions->CallCharMethodV(this,obj,methodID,args); + } + jchar CallCharMethodA(jobject obj, jmethodID methodID, + jvalue * args) { + return functions->CallCharMethodA(this,obj,methodID,args); + } + + jshort CallShortMethod(jobject obj, jmethodID methodID, ...) { + va_list args; + jshort result; + va_start(args,methodID); + result = functions->CallShortMethodV(this,obj,methodID,args); + va_end(args); + return result; + } + jshort CallShortMethodV(jobject obj, jmethodID methodID, + va_list args) { + return functions->CallShortMethodV(this,obj,methodID,args); + } + jshort CallShortMethodA(jobject obj, jmethodID methodID, + jvalue * args) { + return functions->CallShortMethodA(this,obj,methodID,args); + } + + jint CallIntMethod(jobject obj, jmethodID methodID, ...) { + va_list args; + jint result; + va_start(args,methodID); + result = functions->CallIntMethodV(this,obj,methodID,args); + va_end(args); + return result; + } + jint CallIntMethodV(jobject obj, jmethodID methodID, + va_list args) { + return functions->CallIntMethodV(this,obj,methodID,args); + } + jint CallIntMethodA(jobject obj, jmethodID methodID, + jvalue * args) { + return functions->CallIntMethodA(this,obj,methodID,args); + } + + jlong CallLongMethod(jobject obj, jmethodID methodID, ...) { + va_list args; + jlong result; + va_start(args,methodID); + result = functions->CallLongMethodV(this,obj,methodID,args); + va_end(args); + return result; + } + jlong CallLongMethodV(jobject obj, jmethodID methodID, + va_list args) { + return functions->CallLongMethodV(this,obj,methodID,args); + } + jlong CallLongMethodA(jobject obj, jmethodID methodID, + jvalue * args) { + return functions->CallLongMethodA(this,obj,methodID,args); + } + + jfloat CallFloatMethod(jobject obj, jmethodID methodID, ...) { + va_list args; + jfloat result; + va_start(args,methodID); + result = functions->CallFloatMethodV(this,obj,methodID,args); + va_end(args); + return result; + } + jfloat CallFloatMethodV(jobject obj, jmethodID methodID, + va_list args) { + return functions->CallFloatMethodV(this,obj,methodID,args); + } + jfloat CallFloatMethodA(jobject obj, jmethodID methodID, + jvalue * args) { + return functions->CallFloatMethodA(this,obj,methodID,args); + } + + jdouble CallDoubleMethod(jobject obj, jmethodID methodID, ...) { + va_list args; + jdouble result; + va_start(args,methodID); + result = functions->CallDoubleMethodV(this,obj,methodID,args); + va_end(args); + return result; + } + jdouble CallDoubleMethodV(jobject obj, jmethodID methodID, + va_list args) { + return functions->CallDoubleMethodV(this,obj,methodID,args); + } + jdouble CallDoubleMethodA(jobject obj, jmethodID methodID, + jvalue * args) { + return functions->CallDoubleMethodA(this,obj,methodID,args); + } + + void CallVoidMethod(jobject obj, jmethodID methodID, ...) { + va_list args; + va_start(args,methodID); + functions->CallVoidMethodV(this,obj,methodID,args); + va_end(args); + } + void CallVoidMethodV(jobject obj, jmethodID methodID, + va_list args) { + functions->CallVoidMethodV(this,obj,methodID,args); + } + void CallVoidMethodA(jobject obj, jmethodID methodID, + jvalue * args) { + functions->CallVoidMethodA(this,obj,methodID,args); + } + + jobject CallNonvirtualObjectMethod(jobject obj, jclass clazz, + jmethodID methodID, ...) { + va_list args; + jobject result; + va_start(args,methodID); + result = functions->CallNonvirtualObjectMethodV(this,obj,clazz, + methodID,args); + va_end(args); + return result; + } + jobject CallNonvirtualObjectMethodV(jobject obj, jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallNonvirtualObjectMethodV(this,obj,clazz, + methodID,args); + } + jobject CallNonvirtualObjectMethodA(jobject obj, jclass clazz, + jmethodID methodID, jvalue * args) { + return functions->CallNonvirtualObjectMethodA(this,obj,clazz, + methodID,args); + } + + jboolean CallNonvirtualBooleanMethod(jobject obj, jclass clazz, + jmethodID methodID, ...) { + va_list args; + jboolean result; + va_start(args,methodID); + result = functions->CallNonvirtualBooleanMethodV(this,obj,clazz, + methodID,args); + va_end(args); + return result; + } + jboolean CallNonvirtualBooleanMethodV(jobject obj, jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallNonvirtualBooleanMethodV(this,obj,clazz, + methodID,args); + } + jboolean CallNonvirtualBooleanMethodA(jobject obj, jclass clazz, + jmethodID methodID, jvalue * args) { + return functions->CallNonvirtualBooleanMethodA(this,obj,clazz, + methodID, args); + } + + jbyte CallNonvirtualByteMethod(jobject obj, jclass clazz, + jmethodID methodID, ...) { + va_list args; + jbyte result; + va_start(args,methodID); + result = functions->CallNonvirtualByteMethodV(this,obj,clazz, + methodID,args); + va_end(args); + return result; + } + jbyte CallNonvirtualByteMethodV(jobject obj, jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallNonvirtualByteMethodV(this,obj,clazz, + methodID,args); + } + jbyte CallNonvirtualByteMethodA(jobject obj, jclass clazz, + jmethodID methodID, jvalue * args) { + return functions->CallNonvirtualByteMethodA(this,obj,clazz, + methodID,args); + } + + jchar CallNonvirtualCharMethod(jobject obj, jclass clazz, + jmethodID methodID, ...) { + va_list args; + jchar result; + va_start(args,methodID); + result = functions->CallNonvirtualCharMethodV(this,obj,clazz, + methodID,args); + va_end(args); + return result; + } + jchar CallNonvirtualCharMethodV(jobject obj, jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallNonvirtualCharMethodV(this,obj,clazz, + methodID,args); + } + jchar CallNonvirtualCharMethodA(jobject obj, jclass clazz, + jmethodID methodID, jvalue * args) { + return functions->CallNonvirtualCharMethodA(this,obj,clazz, + methodID,args); + } + + jshort CallNonvirtualShortMethod(jobject obj, jclass clazz, + jmethodID methodID, ...) { + va_list args; + jshort result; + va_start(args,methodID); + result = functions->CallNonvirtualShortMethodV(this,obj,clazz, + methodID,args); + va_end(args); + return result; + } + jshort CallNonvirtualShortMethodV(jobject obj, jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallNonvirtualShortMethodV(this,obj,clazz, + methodID,args); + } + jshort CallNonvirtualShortMethodA(jobject obj, jclass clazz, + jmethodID methodID, jvalue * args) { + return functions->CallNonvirtualShortMethodA(this,obj,clazz, + methodID,args); + } + + jint CallNonvirtualIntMethod(jobject obj, jclass clazz, + jmethodID methodID, ...) { + va_list args; + jint result; + va_start(args,methodID); + result = functions->CallNonvirtualIntMethodV(this,obj,clazz, + methodID,args); + va_end(args); + return result; + } + jint CallNonvirtualIntMethodV(jobject obj, jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallNonvirtualIntMethodV(this,obj,clazz, + methodID,args); + } + jint CallNonvirtualIntMethodA(jobject obj, jclass clazz, + jmethodID methodID, jvalue * args) { + return functions->CallNonvirtualIntMethodA(this,obj,clazz, + methodID,args); + } + + jlong CallNonvirtualLongMethod(jobject obj, jclass clazz, + jmethodID methodID, ...) { + va_list args; + jlong result; + va_start(args,methodID); + result = functions->CallNonvirtualLongMethodV(this,obj,clazz, + methodID,args); + va_end(args); + return result; + } + jlong CallNonvirtualLongMethodV(jobject obj, jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallNonvirtualLongMethodV(this,obj,clazz, + methodID,args); + } + jlong CallNonvirtualLongMethodA(jobject obj, jclass clazz, + jmethodID methodID, jvalue * args) { + return functions->CallNonvirtualLongMethodA(this,obj,clazz, + methodID,args); + } + + jfloat CallNonvirtualFloatMethod(jobject obj, jclass clazz, + jmethodID methodID, ...) { + va_list args; + jfloat result; + va_start(args,methodID); + result = functions->CallNonvirtualFloatMethodV(this,obj,clazz, + methodID,args); + va_end(args); + return result; + } + jfloat CallNonvirtualFloatMethodV(jobject obj, jclass clazz, + jmethodID methodID, + va_list args) { + return functions->CallNonvirtualFloatMethodV(this,obj,clazz, + methodID,args); + } + jfloat CallNonvirtualFloatMethodA(jobject obj, jclass clazz, + jmethodID methodID, + jvalue * args) { + return functions->CallNonvirtualFloatMethodA(this,obj,clazz, + methodID,args); + } + + jdouble CallNonvirtualDoubleMethod(jobject obj, jclass clazz, + jmethodID methodID, ...) { + va_list args; + jdouble result; + va_start(args,methodID); + result = functions->CallNonvirtualDoubleMethodV(this,obj,clazz, + methodID,args); + va_end(args); + return result; + } + jdouble CallNonvirtualDoubleMethodV(jobject obj, jclass clazz, + jmethodID methodID, + va_list args) { + return functions->CallNonvirtualDoubleMethodV(this,obj,clazz, + methodID,args); + } + jdouble CallNonvirtualDoubleMethodA(jobject obj, jclass clazz, + jmethodID methodID, + jvalue * args) { + return functions->CallNonvirtualDoubleMethodA(this,obj,clazz, + methodID,args); + } + + void CallNonvirtualVoidMethod(jobject obj, jclass clazz, + jmethodID methodID, ...) { + va_list args; + va_start(args,methodID); + functions->CallNonvirtualVoidMethodV(this,obj,clazz,methodID,args); + va_end(args); + } + void CallNonvirtualVoidMethodV(jobject obj, jclass clazz, + jmethodID methodID, + va_list args) { + functions->CallNonvirtualVoidMethodV(this,obj,clazz,methodID,args); + } + void CallNonvirtualVoidMethodA(jobject obj, jclass clazz, + jmethodID methodID, + jvalue * args) { + functions->CallNonvirtualVoidMethodA(this,obj,clazz,methodID,args); + } + + jfieldID GetFieldID(jclass clazz, const char *name, + const char *sig) { + return functions->GetFieldID(this,clazz,name,sig); + } + + jobject GetObjectField(jobject obj, jfieldID fieldID) { + return functions->GetObjectField(this,obj,fieldID); + } + jboolean GetBooleanField(jobject obj, jfieldID fieldID) { + return functions->GetBooleanField(this,obj,fieldID); + } + jbyte GetByteField(jobject obj, jfieldID fieldID) { + return functions->GetByteField(this,obj,fieldID); + } + jchar GetCharField(jobject obj, jfieldID fieldID) { + return functions->GetCharField(this,obj,fieldID); + } + jshort GetShortField(jobject obj, jfieldID fieldID) { + return functions->GetShortField(this,obj,fieldID); + } + jint GetIntField(jobject obj, jfieldID fieldID) { + return functions->GetIntField(this,obj,fieldID); + } + jlong GetLongField(jobject obj, jfieldID fieldID) { + return functions->GetLongField(this,obj,fieldID); + } + jfloat GetFloatField(jobject obj, jfieldID fieldID) { + return functions->GetFloatField(this,obj,fieldID); + } + jdouble GetDoubleField(jobject obj, jfieldID fieldID) { + return functions->GetDoubleField(this,obj,fieldID); + } + + void SetObjectField(jobject obj, jfieldID fieldID, jobject val) { + functions->SetObjectField(this,obj,fieldID,val); + } + void SetBooleanField(jobject obj, jfieldID fieldID, + jboolean val) { + functions->SetBooleanField(this,obj,fieldID,val); + } + void SetByteField(jobject obj, jfieldID fieldID, + jbyte val) { + functions->SetByteField(this,obj,fieldID,val); + } + void SetCharField(jobject obj, jfieldID fieldID, + jchar val) { + functions->SetCharField(this,obj,fieldID,val); + } + void SetShortField(jobject obj, jfieldID fieldID, + jshort val) { + functions->SetShortField(this,obj,fieldID,val); + } + void SetIntField(jobject obj, jfieldID fieldID, + jint val) { + functions->SetIntField(this,obj,fieldID,val); + } + void SetLongField(jobject obj, jfieldID fieldID, + jlong val) { + functions->SetLongField(this,obj,fieldID,val); + } + void SetFloatField(jobject obj, jfieldID fieldID, + jfloat val) { + functions->SetFloatField(this,obj,fieldID,val); + } + void SetDoubleField(jobject obj, jfieldID fieldID, + jdouble val) { + functions->SetDoubleField(this,obj,fieldID,val); + } + + jmethodID GetStaticMethodID(jclass clazz, const char *name, + const char *sig) { + return functions->GetStaticMethodID(this,clazz,name,sig); + } + + jobject CallStaticObjectMethod(jclass clazz, jmethodID methodID, + ...) { + va_list args; + jobject result; + va_start(args,methodID); + result = functions->CallStaticObjectMethodV(this,clazz,methodID,args); + va_end(args); + return result; + } + jobject CallStaticObjectMethodV(jclass clazz, jmethodID methodID, + va_list args) { + return functions->CallStaticObjectMethodV(this,clazz,methodID,args); + } + jobject CallStaticObjectMethodA(jclass clazz, jmethodID methodID, + jvalue *args) { + return functions->CallStaticObjectMethodA(this,clazz,methodID,args); + } + + jboolean CallStaticBooleanMethod(jclass clazz, + jmethodID methodID, ...) { + va_list args; + jboolean result; + va_start(args,methodID); + result = functions->CallStaticBooleanMethodV(this,clazz,methodID,args); + va_end(args); + return result; + } + jboolean CallStaticBooleanMethodV(jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallStaticBooleanMethodV(this,clazz,methodID,args); + } + jboolean CallStaticBooleanMethodA(jclass clazz, + jmethodID methodID, jvalue *args) { + return functions->CallStaticBooleanMethodA(this,clazz,methodID,args); + } + + jbyte CallStaticByteMethod(jclass clazz, + jmethodID methodID, ...) { + va_list args; + jbyte result; + va_start(args,methodID); + result = functions->CallStaticByteMethodV(this,clazz,methodID,args); + va_end(args); + return result; + } + jbyte CallStaticByteMethodV(jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallStaticByteMethodV(this,clazz,methodID,args); + } + jbyte CallStaticByteMethodA(jclass clazz, + jmethodID methodID, jvalue *args) { + return functions->CallStaticByteMethodA(this,clazz,methodID,args); + } + + jchar CallStaticCharMethod(jclass clazz, + jmethodID methodID, ...) { + va_list args; + jchar result; + va_start(args,methodID); + result = functions->CallStaticCharMethodV(this,clazz,methodID,args); + va_end(args); + return result; + } + jchar CallStaticCharMethodV(jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallStaticCharMethodV(this,clazz,methodID,args); + } + jchar CallStaticCharMethodA(jclass clazz, + jmethodID methodID, jvalue *args) { + return functions->CallStaticCharMethodA(this,clazz,methodID,args); + } + + jshort CallStaticShortMethod(jclass clazz, + jmethodID methodID, ...) { + va_list args; + jshort result; + va_start(args,methodID); + result = functions->CallStaticShortMethodV(this,clazz,methodID,args); + va_end(args); + return result; + } + jshort CallStaticShortMethodV(jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallStaticShortMethodV(this,clazz,methodID,args); + } + jshort CallStaticShortMethodA(jclass clazz, + jmethodID methodID, jvalue *args) { + return functions->CallStaticShortMethodA(this,clazz,methodID,args); + } + + jint CallStaticIntMethod(jclass clazz, + jmethodID methodID, ...) { + va_list args; + jint result; + va_start(args,methodID); + result = functions->CallStaticIntMethodV(this,clazz,methodID,args); + va_end(args); + return result; + } + jint CallStaticIntMethodV(jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallStaticIntMethodV(this,clazz,methodID,args); + } + jint CallStaticIntMethodA(jclass clazz, + jmethodID methodID, jvalue *args) { + return functions->CallStaticIntMethodA(this,clazz,methodID,args); + } + + jlong CallStaticLongMethod(jclass clazz, + jmethodID methodID, ...) { + va_list args; + jlong result; + va_start(args,methodID); + result = functions->CallStaticLongMethodV(this,clazz,methodID,args); + va_end(args); + return result; + } + jlong CallStaticLongMethodV(jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallStaticLongMethodV(this,clazz,methodID,args); + } + jlong CallStaticLongMethodA(jclass clazz, + jmethodID methodID, jvalue *args) { + return functions->CallStaticLongMethodA(this,clazz,methodID,args); + } + + jfloat CallStaticFloatMethod(jclass clazz, + jmethodID methodID, ...) { + va_list args; + jfloat result; + va_start(args,methodID); + result = functions->CallStaticFloatMethodV(this,clazz,methodID,args); + va_end(args); + return result; + } + jfloat CallStaticFloatMethodV(jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallStaticFloatMethodV(this,clazz,methodID,args); + } + jfloat CallStaticFloatMethodA(jclass clazz, + jmethodID methodID, jvalue *args) { + return functions->CallStaticFloatMethodA(this,clazz,methodID,args); + } + + jdouble CallStaticDoubleMethod(jclass clazz, + jmethodID methodID, ...) { + va_list args; + jdouble result; + va_start(args,methodID); + result = functions->CallStaticDoubleMethodV(this,clazz,methodID,args); + va_end(args); + return result; + } + jdouble CallStaticDoubleMethodV(jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallStaticDoubleMethodV(this,clazz,methodID,args); + } + jdouble CallStaticDoubleMethodA(jclass clazz, + jmethodID methodID, jvalue *args) { + return functions->CallStaticDoubleMethodA(this,clazz,methodID,args); + } + + void CallStaticVoidMethod(jclass cls, jmethodID methodID, ...) { + va_list args; + va_start(args,methodID); + functions->CallStaticVoidMethodV(this,cls,methodID,args); + va_end(args); + } + void CallStaticVoidMethodV(jclass cls, jmethodID methodID, + va_list args) { + functions->CallStaticVoidMethodV(this,cls,methodID,args); + } + void CallStaticVoidMethodA(jclass cls, jmethodID methodID, + jvalue * args) { + functions->CallStaticVoidMethodA(this,cls,methodID,args); + } + + jfieldID GetStaticFieldID(jclass clazz, const char *name, + const char *sig) { + return functions->GetStaticFieldID(this,clazz,name,sig); + } + jobject GetStaticObjectField(jclass clazz, jfieldID fieldID) { + return functions->GetStaticObjectField(this,clazz,fieldID); + } + jboolean GetStaticBooleanField(jclass clazz, jfieldID fieldID) { + return functions->GetStaticBooleanField(this,clazz,fieldID); + } + jbyte GetStaticByteField(jclass clazz, jfieldID fieldID) { + return functions->GetStaticByteField(this,clazz,fieldID); + } + jchar GetStaticCharField(jclass clazz, jfieldID fieldID) { + return functions->GetStaticCharField(this,clazz,fieldID); + } + jshort GetStaticShortField(jclass clazz, jfieldID fieldID) { + return functions->GetStaticShortField(this,clazz,fieldID); + } + jint GetStaticIntField(jclass clazz, jfieldID fieldID) { + return functions->GetStaticIntField(this,clazz,fieldID); + } + jlong GetStaticLongField(jclass clazz, jfieldID fieldID) { + return functions->GetStaticLongField(this,clazz,fieldID); + } + jfloat GetStaticFloatField(jclass clazz, jfieldID fieldID) { + return functions->GetStaticFloatField(this,clazz,fieldID); + } + jdouble GetStaticDoubleField(jclass clazz, jfieldID fieldID) { + return functions->GetStaticDoubleField(this,clazz,fieldID); + } + + void SetStaticObjectField(jclass clazz, jfieldID fieldID, + jobject value) { + functions->SetStaticObjectField(this,clazz,fieldID,value); + } + void SetStaticBooleanField(jclass clazz, jfieldID fieldID, + jboolean value) { + functions->SetStaticBooleanField(this,clazz,fieldID,value); + } + void SetStaticByteField(jclass clazz, jfieldID fieldID, + jbyte value) { + functions->SetStaticByteField(this,clazz,fieldID,value); + } + void SetStaticCharField(jclass clazz, jfieldID fieldID, + jchar value) { + functions->SetStaticCharField(this,clazz,fieldID,value); + } + void SetStaticShortField(jclass clazz, jfieldID fieldID, + jshort value) { + functions->SetStaticShortField(this,clazz,fieldID,value); + } + void SetStaticIntField(jclass clazz, jfieldID fieldID, + jint value) { + functions->SetStaticIntField(this,clazz,fieldID,value); + } + void SetStaticLongField(jclass clazz, jfieldID fieldID, + jlong value) { + functions->SetStaticLongField(this,clazz,fieldID,value); + } + void SetStaticFloatField(jclass clazz, jfieldID fieldID, + jfloat value) { + functions->SetStaticFloatField(this,clazz,fieldID,value); + } + void SetStaticDoubleField(jclass clazz, jfieldID fieldID, + jdouble value) { + functions->SetStaticDoubleField(this,clazz,fieldID,value); + } + + jstring NewString(const jchar *unicode, jsize len) { + return functions->NewString(this,unicode,len); + } + jsize GetStringLength(jstring str) { + return functions->GetStringLength(this,str); + } + const jchar *GetStringChars(jstring str, jboolean *isCopy) { + return functions->GetStringChars(this,str,isCopy); + } + void ReleaseStringChars(jstring str, const jchar *chars) { + functions->ReleaseStringChars(this,str,chars); + } + + jstring NewStringUTF(const char *utf) { + return functions->NewStringUTF(this,utf); + } + jsize GetStringUTFLength(jstring str) { + return functions->GetStringUTFLength(this,str); + } + const char* GetStringUTFChars(jstring str, jboolean *isCopy) { + return functions->GetStringUTFChars(this,str,isCopy); + } + void ReleaseStringUTFChars(jstring str, const char* chars) { + functions->ReleaseStringUTFChars(this,str,chars); + } + + jsize GetArrayLength(jarray array) { + return functions->GetArrayLength(this,array); + } + + jobjectArray NewObjectArray(jsize len, jclass clazz, + jobject init) { + return functions->NewObjectArray(this,len,clazz,init); + } + jobject GetObjectArrayElement(jobjectArray array, jsize index) { + return functions->GetObjectArrayElement(this,array,index); + } + void SetObjectArrayElement(jobjectArray array, jsize index, + jobject val) { + functions->SetObjectArrayElement(this,array,index,val); + } + + jbooleanArray NewBooleanArray(jsize len) { + return functions->NewBooleanArray(this,len); + } + jbyteArray NewByteArray(jsize len) { + return functions->NewByteArray(this,len); + } + jcharArray NewCharArray(jsize len) { + return functions->NewCharArray(this,len); + } + jshortArray NewShortArray(jsize len) { + return functions->NewShortArray(this,len); + } + jintArray NewIntArray(jsize len) { + return functions->NewIntArray(this,len); + } + jlongArray NewLongArray(jsize len) { + return functions->NewLongArray(this,len); + } + jfloatArray NewFloatArray(jsize len) { + return functions->NewFloatArray(this,len); + } + jdoubleArray NewDoubleArray(jsize len) { + return functions->NewDoubleArray(this,len); + } + + jboolean * GetBooleanArrayElements(jbooleanArray array, jboolean *isCopy) { + return functions->GetBooleanArrayElements(this,array,isCopy); + } + jbyte * GetByteArrayElements(jbyteArray array, jboolean *isCopy) { + return functions->GetByteArrayElements(this,array,isCopy); + } + jchar * GetCharArrayElements(jcharArray array, jboolean *isCopy) { + return functions->GetCharArrayElements(this,array,isCopy); + } + jshort * GetShortArrayElements(jshortArray array, jboolean *isCopy) { + return functions->GetShortArrayElements(this,array,isCopy); + } + jint * GetIntArrayElements(jintArray array, jboolean *isCopy) { + return functions->GetIntArrayElements(this,array,isCopy); + } + jlong * GetLongArrayElements(jlongArray array, jboolean *isCopy) { + return functions->GetLongArrayElements(this,array,isCopy); + } + jfloat * GetFloatArrayElements(jfloatArray array, jboolean *isCopy) { + return functions->GetFloatArrayElements(this,array,isCopy); + } + jdouble * GetDoubleArrayElements(jdoubleArray array, jboolean *isCopy) { + return functions->GetDoubleArrayElements(this,array,isCopy); + } + + void ReleaseBooleanArrayElements(jbooleanArray array, + jboolean *elems, + jint mode) { + functions->ReleaseBooleanArrayElements(this,array,elems,mode); + } + void ReleaseByteArrayElements(jbyteArray array, + jbyte *elems, + jint mode) { + functions->ReleaseByteArrayElements(this,array,elems,mode); + } + void ReleaseCharArrayElements(jcharArray array, + jchar *elems, + jint mode) { + functions->ReleaseCharArrayElements(this,array,elems,mode); + } + void ReleaseShortArrayElements(jshortArray array, + jshort *elems, + jint mode) { + functions->ReleaseShortArrayElements(this,array,elems,mode); + } + void ReleaseIntArrayElements(jintArray array, + jint *elems, + jint mode) { + functions->ReleaseIntArrayElements(this,array,elems,mode); + } + void ReleaseLongArrayElements(jlongArray array, + jlong *elems, + jint mode) { + functions->ReleaseLongArrayElements(this,array,elems,mode); + } + void ReleaseFloatArrayElements(jfloatArray array, + jfloat *elems, + jint mode) { + functions->ReleaseFloatArrayElements(this,array,elems,mode); + } + void ReleaseDoubleArrayElements(jdoubleArray array, + jdouble *elems, + jint mode) { + functions->ReleaseDoubleArrayElements(this,array,elems,mode); + } + + void GetBooleanArrayRegion(jbooleanArray array, + jsize start, jsize len, jboolean *buf) { + functions->GetBooleanArrayRegion(this,array,start,len,buf); + } + void GetByteArrayRegion(jbyteArray array, + jsize start, jsize len, jbyte *buf) { + functions->GetByteArrayRegion(this,array,start,len,buf); + } + void GetCharArrayRegion(jcharArray array, + jsize start, jsize len, jchar *buf) { + functions->GetCharArrayRegion(this,array,start,len,buf); + } + void GetShortArrayRegion(jshortArray array, + jsize start, jsize len, jshort *buf) { + functions->GetShortArrayRegion(this,array,start,len,buf); + } + void GetIntArrayRegion(jintArray array, + jsize start, jsize len, jint *buf) { + functions->GetIntArrayRegion(this,array,start,len,buf); + } + void GetLongArrayRegion(jlongArray array, + jsize start, jsize len, jlong *buf) { + functions->GetLongArrayRegion(this,array,start,len,buf); + } + void GetFloatArrayRegion(jfloatArray array, + jsize start, jsize len, jfloat *buf) { + functions->GetFloatArrayRegion(this,array,start,len,buf); + } + void GetDoubleArrayRegion(jdoubleArray array, + jsize start, jsize len, jdouble *buf) { + functions->GetDoubleArrayRegion(this,array,start,len,buf); + } + + void SetBooleanArrayRegion(jbooleanArray array, jsize start, jsize len, + jboolean *buf) { + functions->SetBooleanArrayRegion(this,array,start,len,buf); + } + void SetByteArrayRegion(jbyteArray array, jsize start, jsize len, + jbyte *buf) { + functions->SetByteArrayRegion(this,array,start,len,buf); + } + void SetCharArrayRegion(jcharArray array, jsize start, jsize len, + jchar *buf) { + functions->SetCharArrayRegion(this,array,start,len,buf); + } + void SetShortArrayRegion(jshortArray array, jsize start, jsize len, + jshort *buf) { + functions->SetShortArrayRegion(this,array,start,len,buf); + } + void SetIntArrayRegion(jintArray array, jsize start, jsize len, + jint *buf) { + functions->SetIntArrayRegion(this,array,start,len,buf); + } + void SetLongArrayRegion(jlongArray array, jsize start, jsize len, + jlong *buf) { + functions->SetLongArrayRegion(this,array,start,len,buf); + } + void SetFloatArrayRegion(jfloatArray array, jsize start, jsize len, + jfloat *buf) { + functions->SetFloatArrayRegion(this,array,start,len,buf); + } + void SetDoubleArrayRegion(jdoubleArray array, jsize start, jsize len, + jdouble *buf) { + functions->SetDoubleArrayRegion(this,array,start,len,buf); + } + + jint RegisterNatives(jclass clazz, const JNINativeMethod *methods, + jint nMethods) { + return functions->RegisterNatives(this,clazz,methods,nMethods); + } + jint UnregisterNatives(jclass clazz) { + return functions->UnregisterNatives(this,clazz); + } + + jint MonitorEnter(jobject obj) { + return functions->MonitorEnter(this,obj); + } + jint MonitorExit(jobject obj) { + return functions->MonitorExit(this,obj); + } + + jint GetJavaVM(JavaVM **vm) { + return functions->GetJavaVM(this,vm); + } + +#endif /* __cplusplus */ +}; + +/* These structures will be VM-specific. */ + +typedef struct JDK1_1InitArgs { + jint version; + + char **properties; + jint checkSource; + jint nativeStackSize; + jint javaStackSize; + jint minHeapSize; + jint maxHeapSize; + jint verifyMode; + char *classpath; + + JNIFUNCPTR(jint, vfprintf)(FILE *fp, const char *format, va_list args); + JNIFUNCPTR(void, exit)(jint code); + JNIFUNCPTR(void, abort)(); + + jint enableClassGC; + jint enableVerboseGC; + jint disableAsyncGC; + jint verbose; + jboolean debugging; + jint debugPort; +} JDK1_1InitArgs; + +typedef struct JDK1_1AttachArgs { + void * __padding; /* C compilers don't allow empty structures. */ +} JDK1_1AttachArgs; + +/* End VM-specific. */ + +struct JNIInvokeInterface_ { + void *reserved0; + void *reserved1; + void *reserved2; + + JNIFUNCPTR(jint, DestroyJavaVM)(JavaVM *vm); + + JNIFUNCPTR(jint, AttachCurrentThread) + (JavaVM *vm, JNIEnv **penv, void *args); + + JNIFUNCPTR(jint, DetachCurrentThread)(JavaVM *vm); +}; + +struct JavaVM_ { + const struct JNIInvokeInterface_ *functions; + void *reserved0; + void *reserved1; + void *reserved2; +#ifdef __cplusplus + + jint DestroyJavaVM() { + return functions->DestroyJavaVM(this); + } + jint AttachCurrentThread(JNIEnv **penv, void *args) { + return functions->AttachCurrentThread(this, penv, args); + } + jint DetachCurrentThread() { + return functions->DetachCurrentThread(this); + } + +#endif +}; + +JNICALL(jint) JNI_GetDefaultJavaVMInitArgs(void *); + +JNICALL(jint) JNI_CreateJavaVM(JavaVM **, JNIEnv **, void *); + +JNICALL(jint) JNI_GetCreatedJavaVMs(JavaVM **, jsize, jsize *); + +#ifdef __cplusplus +} /* extern "C" */ +#endif /* __cplusplus */ + +#endif /* JNI_H */ + + diff --git a/ef/Exports/manifest.mn b/ef/Exports/manifest.mn new file mode 100644 index 000000000000..bd49be80bf72 --- /dev/null +++ b/ef/Exports/manifest.mn @@ -0,0 +1,18 @@ +# +# CONFIDENTIAL AND PROPRIETARY SOURCE CODE OF +# NETSCAPE COMMUNICATIONS CORPORATION +# Copyright (C) 1996 Netscape Communications Corporation. All Rights +# Reserved. Use of this Source Code is subject to the terms of the +# applicable license agreement from Netscape Communications Corporation. +# The copyright notice(s) in this Source Code does not indicate actual or +# intended publication of this Source Code. +# +DEPTH = .. + +MODULE_NAME = EF + +DIRS = md + +LOCAL_EXPORTS = jni.h \ + $(NULL) + diff --git a/ef/Exports/md/Makefile b/ef/Exports/md/Makefile new file mode 100644 index 000000000000..aa34279b6622 --- /dev/null +++ b/ef/Exports/md/Makefile @@ -0,0 +1,40 @@ +#! gmake +# +# CONFIDENTIAL AND PROPRIETARY SOURCE CODE OF +# NETSCAPE COMMUNICATIONS CORPORATION +# Copyright © 1996, 1997 Netscape Communications Corporation. All Rights +# Reserved. Use of this Source Code is subject to the terms of the +# applicable license agreement from Netscape Communications Corporation. +# The copyright notice(s) in this Source Code does not indicate actual or +# intended publication of this Source Code. +# + +####################################################################### +# (1) Include manifest file # +####################################################################### + +include manifest.mn + +####################################################################### +# (2) Include "component" configuration information. # +####################################################################### + +include $(DEPTH)/config/config.mk + +####################################################################### +# (3) Include "local" platform-dependent assignments (OPTIONAL). # +####################################################################### + + + +####################################################################### +# (4) Execute "component" rules. (OPTIONAL) # +####################################################################### + +include $(DEPTH)/config/rules.mk + +####################################################################### +# (7) Execute "local" rules. (OPTIONAL). # +####################################################################### + + diff --git a/ef/Exports/md/jni_md.h b/ef/Exports/md/jni_md.h new file mode 100644 index 000000000000..bd4a5a0c38ef --- /dev/null +++ b/ef/Exports/md/jni_md.h @@ -0,0 +1,50 @@ +/* + * @(#)jni_md.h 1.6 97/08/07 + * + * Copyright 1993-1997 Sun Microsystems, Inc. 901 San Antonio Road, + * Palo Alto, California, 94303, U.S.A. All Rights Reserved. + * + * This software is the confidential and proprietary information of Sun + * Microsystems, Inc. ("Confidential Information"). You shall not + * disclose such Confidential Information and shall use it only in + * accordance with the terms of the license agreement you entered into + * with Sun. + * + * CopyrightVersion 1.2 + * + */ + +#ifndef JNI_MD_H +#define JNI_MD_H + +#if defined(_WIN32) +#define JNIEXPORT __declspec(dllexport) +#define JNIIMPORT __declspec(dllimport) +#define JNICALL(returnType) returnType __stdcall +#define JNIFUNCPTR(returnType, name) returnType (__stdcall *name) + +typedef long jint; +typedef __int64 jlong; +typedef signed char jbyte; + +#elif defined(LINUX) +#define JNIEXPORT +#define JNIIMPORT +#define JNICALL(returnType) __attribute__((stdcall)) returnType +#define JNIFUNCPTR(returnType, name) __attribute__((stdcall)) returnType (*name) + +typedef long jint; +typedef long long jlong; +typedef signed char jbyte; +#else +#define JNIEXPORT +#define JNIIMPORT +#define JNICALL(X) X +#define JNIFUNCPTR(returnType, name) returnType (*name) + +typedef long jint; +typedef long long jlong; +typedef signed char jbyte; +#endif + +#endif /* JNI_MD_H */ diff --git a/ef/Exports/md/manifest.mn b/ef/Exports/md/manifest.mn new file mode 100644 index 000000000000..21d5efa7d02c --- /dev/null +++ b/ef/Exports/md/manifest.mn @@ -0,0 +1,15 @@ +# +# CONFIDENTIAL AND PROPRIETARY SOURCE CODE OF +# NETSCAPE COMMUNICATIONS CORPORATION +# Copyright (C) 1996 Netscape Communications Corporation. All Rights +# Reserved. Use of this Source Code is subject to the terms of the +# applicable license agreement from Netscape Communications Corporation. +# The copyright notice(s) in this Source Code does not indicate actual or +# intended publication of this Source Code. +# +DEPTH = ../.. + + +LOCAL_EXPORTS = jni_md.h \ + $(NULL) + diff --git a/ef/Includes/md/Asm.h b/ef/Includes/md/Asm.h new file mode 100644 index 000000000000..3f7c273c9e5a --- /dev/null +++ b/ef/Includes/md/Asm.h @@ -0,0 +1,30 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#ifndef _MD_ASM_H_ +#define _MD_ASM_H_ + +#include +#include MD_INCLUDE_FILE(Asm.h) + +#if defined(__cplusplus) +#define NS_ASM_EXTERN extern "C" +#else /* ! __cplusplus */ +#define NS_ASM_EXTERN +#endif /* __cplusplus */ + +#endif /* _MD_ASM_H_ */ diff --git a/ef/Includes/md/MdInclude.h b/ef/Includes/md/MdInclude.h new file mode 100644 index 000000000000..940b0348191e --- /dev/null +++ b/ef/Includes/md/MdInclude.h @@ -0,0 +1,62 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#ifndef _MD_INCLUDE_H_ +#define _MD_INCLUDE_H_ + +/* This file contains the definition of platform specific macros. The variable + * TARGET_CPU must be set before processing this file. + * + * The macros are: + * + * - MD_INCLUDE_FILE(filename): + * #include MD_INCLUDE_FILE(Asm.h) with TARGET_CPU set to x86 + * will produce #include + * + */ + +/* String concatenation for the preprocessor. The XCAT* macros will cause the + * inner CAT* macros to be evaluated first, producing still-valid pp-tokens. + * Then the final concatenation can be done. + */ + +#if defined(__STDC__) + #define CAT(a,b) a##b + #define CAT3(a,b,c) a##b##c +#else /* ! __STDC__ */ + #define CAT(a,b) a/**/b + #define CAT3(a,b,c) a/**/b/**/c +#endif /* __STDC__ */ + +#define XCAT(a,b) CAT(a,b) +#define XCAT3(a,b,c) CAT3(a,b,c) + +/* _MD_DIRNAME is the include directory name string for target architecture. + * _MD_FILE_NAME is the complete path to the m.dep. file. + */ + +#define _MD_DIR_NAME() XCAT3(md/,TARGET_CPU,/) +#define _MD_FILE_NAME(name) XCAT3(_MD_DIR_NAME(),TARGET_CPU,name) + + +/* Public: + */ + +#define MD_INCLUDE_FILE(name) XCAT3(<,_MD_FILE_NAME(name),>) + +#endif /* _MD_INCLUDE_H_ */ diff --git a/ef/Includes/md/x86/x86Asm.h b/ef/Includes/md/x86/x86Asm.h new file mode 100644 index 000000000000..40c7dc424f39 --- /dev/null +++ b/ef/Includes/md/x86/x86Asm.h @@ -0,0 +1,26 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#ifndef _MD_X86_ASM_H_ +#define _MD_X86_ASM_H_ + +#if defined(LINUX) +#include "x86LinuxAsm.h" +#endif /* LINUX */ + +#endif /* _MD_X86_ASM_H_ */ diff --git a/ef/Includes/md/x86/x86LinuxAsm.h b/ef/Includes/md/x86/x86LinuxAsm.h new file mode 100644 index 000000000000..ee4daf357b32 --- /dev/null +++ b/ef/Includes/md/x86/x86LinuxAsm.h @@ -0,0 +1,48 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#ifndef _MD_X86_LINUX_ASM_H_ +#define _MD_X86_LINUX_ASM_H_ + +#define SYMBOL_NAME_STR(name) #name +#define SYMBOL_NAME(name) name +#define SYMBOL_NAME_LABEL(name) CAT(name,:) + +#if !defined(__i486__) && !defined(__i586__) +#define ALIGN .align 4,0x90 +#define ALIGN_STR ".align 4,0x90" +#else /* __i486__/__i586__ */ +#define ALIGN .align 16,0x90 +#define ALIGN_STR ".align 16,0x90" +#endif /* __i486__/__i586__ */ + +#define STATIC_ENTRY(name) \ + ALIGN; \ + SYMBOL_NAME_LABEL(name) + +#define GLOBAL_ENTRY(name) \ + .globl SYMBOL_NAME(name); \ + STATIC_ENTRY(name) + +#define END_ENTRY(name) \ + SYMBOL_NAME_LABEL(CAT(.L,name)); \ + .size SYMBOL_NAME(name),SYMBOL_NAME(CAT(.L,name))-SYMBOL_NAME(name) + +#define TEXT_SEGMENT .text +#define DATA_SEGMENT .data +#endif /* _MD_X86_LINUX_ASM_H_ */ diff --git a/ef/Makefile b/ef/Makefile new file mode 100644 index 000000000000..30e89f1985f4 --- /dev/null +++ b/ef/Makefile @@ -0,0 +1,47 @@ +#!gmake +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +####################################################################### +# (1) Include manifest file # +####################################################################### + +include manifest.mn + +####################################################################### +# (2) Include "component" configuration information. # +####################################################################### + +include $(DEPTH)/config/config.mk + +####################################################################### +# (3) Include "local" platform-dependent assignments (OPTIONAL). # +####################################################################### + + + +####################################################################### +# (4) Execute "component" rules. (OPTIONAL) # +####################################################################### + +include $(DEPTH)/config/rules.mk + +####################################################################### +# (7) Execute "local" rules. (OPTIONAL). # +####################################################################### + +include rules.mk + diff --git a/ef/Packages/Makefile b/ef/Packages/Makefile new file mode 100644 index 000000000000..8b4063f83c11 --- /dev/null +++ b/ef/Packages/Makefile @@ -0,0 +1,47 @@ +#!gmake +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +####################################################################### +# (1) Include manifest file # +####################################################################### + +include manifest.mn + +####################################################################### +# (2) Include "component" configuration information. # +####################################################################### + +include $(DEPTH)/config/config.mk + +####################################################################### +# (3) Include "local" platform-dependent assignments (OPTIONAL). # +####################################################################### + +include config.mk + +####################################################################### +# (4) Execute "component" rules. (OPTIONAL) # +####################################################################### + +include $(DEPTH)/config/rules.mk + +####################################################################### +# (7) Execute "local" rules. (OPTIONAL). # +####################################################################### + +include rules.mk + diff --git a/ef/Packages/config.mk b/ef/Packages/config.mk new file mode 100644 index 000000000000..5cd18dc8b6b6 --- /dev/null +++ b/ef/Packages/config.mk @@ -0,0 +1,19 @@ +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +OBJS = $(wildcard $(DEPTH)/$(OBJDIR)/Package/*$(OBJ_SUFFIX)) +LDFLAGS += $(EF_LIBS) $(NSPR_LIBS) + diff --git a/ef/Packages/java/Makefile b/ef/Packages/java/Makefile new file mode 100644 index 000000000000..1f9342b20734 --- /dev/null +++ b/ef/Packages/java/Makefile @@ -0,0 +1,45 @@ +#!gmake +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +####################################################################### +# (1) Include manifest file # +####################################################################### + +include manifest.mn + +####################################################################### +# (2) Include "component" configuration information. # +####################################################################### + +include $(DEPTH)/config/config.mk + +####################################################################### +# (3) Include "local" platform-dependent assignments (OPTIONAL). # +####################################################################### + + +####################################################################### +# (4) Execute "component" rules. (OPTIONAL) # +####################################################################### + +include $(DEPTH)/config/rules.mk + +####################################################################### +# (7) Execute "local" rules. (OPTIONAL). # +####################################################################### + + diff --git a/ef/Packages/java/io/Makefile b/ef/Packages/java/io/Makefile new file mode 100644 index 000000000000..1f9342b20734 --- /dev/null +++ b/ef/Packages/java/io/Makefile @@ -0,0 +1,45 @@ +#!gmake +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +####################################################################### +# (1) Include manifest file # +####################################################################### + +include manifest.mn + +####################################################################### +# (2) Include "component" configuration information. # +####################################################################### + +include $(DEPTH)/config/config.mk + +####################################################################### +# (3) Include "local" platform-dependent assignments (OPTIONAL). # +####################################################################### + + +####################################################################### +# (4) Execute "component" rules. (OPTIONAL) # +####################################################################### + +include $(DEPTH)/config/rules.mk + +####################################################################### +# (7) Execute "local" rules. (OPTIONAL). # +####################################################################### + + diff --git a/ef/Packages/java/io/manifest.mn b/ef/Packages/java/io/manifest.mn new file mode 100644 index 000000000000..39f93c46fe03 --- /dev/null +++ b/ef/Packages/java/io/manifest.mn @@ -0,0 +1,23 @@ +#!gmake +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +DEPTH = ../../.. + +DIRS = nativesrc + + + diff --git a/ef/Packages/java/io/nativesrc/File.cpp b/ef/Packages/java/io/nativesrc/File.cpp new file mode 100644 index 000000000000..4a3ef7a20264 --- /dev/null +++ b/ef/Packages/java/io/nativesrc/File.cpp @@ -0,0 +1,366 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#include "java_io_File.h" +#include "java_lang_String.h" + +#include "prio.h" +#include "prprf.h" + +#include "JavaString.h" +#include "JavaVM.h" +#include "SysCallsRuntime.h" + +extern "C" { + +/* Implementation of the native code in java/io/File */ + +static bool getFileInfo(Java_java_io_File *file, PRFileInfo &info) +{ + JavaString *str = (JavaString *) file->path; + if (str == NULL) + sysThrowNullPointerException(); + + char *filePath = str->convertUtf(); + + bool ret = (PR_GetFileInfo(filePath, &info) == PR_SUCCESS); + JavaString::freeUtf(filePath); + + return ret; +} + +/* Given a File object, return its file name. The null-terminated + * string returned by this function must be freed using JavaString::freeUtf() + */ +static char *getFilePath(Java_java_io_File *file) +{ + JavaString *str = (JavaString *) file->path; + + if (str == NULL) + sysThrowNullPointerException(); + + char *filePath = str->convertUtf(); + return filePath; +} + + +/* + * Class : java/io/File + * Method : exists0 + * Signature : ()Z + */ +NS_EXPORT NS_NATIVECALL(uint32 /* bool */) +Netscape_Java_java_io_File_exists0(Java_java_io_File *file) +{ + PRFileInfo info; + + return getFileInfo(file, info); +} + + +/* + * Class : java/io/File + * Method : canWrite0 + * Signature : ()Z + */ +NS_EXPORT NS_NATIVECALL(uint32 /* bool */) +Netscape_Java_java_io_File_canWrite0(Java_java_io_File *file) +{ + /* Open the file for writing; if it succeeds, we can write to the file. */ + char *filePath = getFilePath(file); + + PRFileDesc *fd = PR_Open(filePath, PR_WRONLY, 00644); + + JavaString::freeUtf(filePath); + + if (!fd) + return false; + + PR_Close(fd); + return true; +} + + + +/* + * Class : java/io/File + * Method : canRead0 + * Signature : ()Z + */ +NS_EXPORT NS_NATIVECALL(uint32 /* bool */) +Netscape_Java_java_io_File_canRead0(Java_java_io_File *file) +{ + /* Open the file for reading; if it succeeds, we can write to the file. */ + char *filePath = getFilePath(file); + + PRFileDesc *fd = PR_Open(filePath, PR_RDONLY, 00644); + + JavaString::freeUtf(filePath); + + if (!fd) + return false; + + PR_Close(fd); + return true; +} + + + +/* + * Class : java/io/File + * Method : isFile0 + * Signature : ()Z + */ +NS_EXPORT NS_NATIVECALL(uint32 /* bool */) +Netscape_Java_java_io_File_isFile0(Java_java_io_File *file) +{ + PRFileInfo fileInfo; + + if (!getFileInfo(file, fileInfo)) + return false; + + return (fileInfo.type == PR_FILE_FILE); +} + + + +/* + * Class : java/io/File + * Method : isDirectory0 + * Signature : ()Z + */ +NS_EXPORT NS_NATIVECALL(uint32 /* bool */) +Netscape_Java_java_io_File_isDirectory0(Java_java_io_File *file) +{ + PRFileInfo fileInfo; + + if (!getFileInfo(file, fileInfo)) + return false; + + return (fileInfo.type == PR_FILE_DIRECTORY); +} + + + +/* + * Class : java/io/File + * Method : lastModified0 + * Signature : ()J + */ +NS_EXPORT NS_NATIVECALL(int64) +Netscape_Java_java_io_File_lastModified0(Java_java_io_File *) +{ + PR_fprintf(PR_STDERR, "Warning: File::lastModified0() not implemented\n"); + return 0; +} + + + +/* + * Class : java/io/File + * Method : length0 + * Signature : ()J + */ +NS_EXPORT NS_NATIVECALL(int64) +Netscape_Java_java_io_File_length0(Java_java_io_File *file) +{ + PRFileInfo fileInfo; + + if (!getFileInfo(file, fileInfo)) + return 0; + + return ((Int64) fileInfo.size); +} + + + +/* + * Class : java/io/File + * Method : mkdir0 + * Signature : ()Z + */ +NS_EXPORT NS_NATIVECALL(uint32 /* bool */) +Netscape_Java_java_io_File_mkdir0(Java_java_io_File *file) +{ + char *dirName = getFilePath(file); + bool ret = true; + + if (PR_MkDir(dirName, 00755) == PR_FAILURE) + ret = false; + + JavaString::freeUtf(dirName); + + return ret; +} + + + +/* + * Class : java/io/File + * Method : renameTo0 + * Signature : (Ljava/io/File;)Z + */ +NS_EXPORT NS_NATIVECALL(uint32 /* bool */) +Netscape_Java_java_io_File_renameTo0(Java_java_io_File *from, + Java_java_io_File *to) +{ + char *fromName = getFilePath(from); + char *toName = getFilePath(to); + + bool ret = (PR_Rename(fromName, toName) == PR_SUCCESS); + + JavaString::freeUtf(fromName); + JavaString::freeUtf(toName); + + return ret; +} + + + +/* + * Class : java/io/File + * Method : delete0 + * Signature : ()Z + */ +NS_EXPORT NS_NATIVECALL(uint32 /* bool */) +Netscape_Java_java_io_File_delete0(Java_java_io_File *file) +{ + char *name = getFilePath(file); + + bool ret = (PR_Delete(name) == PR_SUCCESS); + + JavaString::freeUtf(name); + return ret; +} + + + +/* + * Class : java/io/File + * Method : rmdir0 + * Signature : ()Z + */ +NS_EXPORT NS_NATIVECALL(uint32 /* bool */) +Netscape_Java_java_io_File_rmdir0(Java_java_io_File *file) +{ + char *name = getFilePath(file); + + bool ret = (PR_RmDir(name) == PR_SUCCESS); + + JavaString::freeUtf(name); + return ret; +} + + + +/* + * Class : java/io/File + * Method : list0 + * Signature : ()[Ljava/lang/String; + */ +NS_EXPORT NS_NATIVECALL(ArrayOf_Java_java_lang_String *) +Netscape_Java_java_io_File_list0(Java_java_io_File *dir) +{ + char *name = getFilePath(dir); + + PRFileInfo info; + if (!getFileInfo(dir, info)) + return 0; + + PRDir* d = PR_OpenDir(name); + PRDirEntry* e; + Uint32 count = 0; + while ((e = PR_ReadDir(d, PR_SKIP_BOTH)) != NULL) + count++; + PR_CloseDir(d); + d = PR_OpenDir(name); + + JavaArray *arr = (JavaArray *) sysNewObjectArray(&VM::getStandardClass(cString), count); + ArrayOf_Java_java_lang_String *stringArray = (ArrayOf_Java_java_lang_String *) arr; + for (Uint32 i = 0; i < count; i++) + stringArray->elements[i] = (Java_java_lang_String*) JavaString::make(PR_ReadDir(d, PR_SKIP_BOTH)->name); + + PR_CloseDir(d); + return stringArray; +} + + + +/* + * Class : java/io/File + * Method : canonPath + * Signature : (Ljava/lang/String;)Ljava/lang/String; + */ +NS_EXPORT NS_NATIVECALL(Java_java_lang_String *) +Netscape_Java_java_io_File_canonPath(Java_java_io_File *, Java_java_lang_String *) +{ + printf("File::canonPath() not yet implemented\n"); + return 0; +} + + + +/* + * Class : java/io/File + * Method : isAbsolute + * Signature : ()Z + */ +NS_EXPORT NS_NATIVECALL(uint32 /* bool */) +Netscape_Java_java_io_File_isAbsolute(Java_java_io_File *file) +{ + JavaString* jspath = (JavaString*)file->path; + const int16* path = jspath->getStr(); + char first = (char) path[0]; + + // Shouldn't this be done in NSPR ? + +#if defined(XP_UNIX) + Class &clazz = const_cast(file->getClass()); + Field &fld = clazz.getField("pathSeparatorChar"); + int16 pathSeparatorChar = fld.getChar(NULL); // pathSeparatorChar is a static field + if (first == pathSeparatorChar) + return 1; + else return 0; +#elif defined(XP_PC) + if (first == '/' || first == '\\') + return 1; + char second = (char) path[1]; + if (((first >= 'A' && first <= 'Z') || (first >= 'a' && first <= 'z')) + && (second == ':')) + return 1; + return 0; +#else + printf("File::isAbsolute() not yet implemented on this platform\n"); +#endif + return 0; +} + +/* + * Class : java/io/File + * Method : initIDs + * Signature : ()V + */ +NS_EXPORT NS_NATIVECALL(void) +Netscape_Java_java_io_File_initIDs() +{ + /* Currently empty, since all our initialization is done statically (see Mapping.h) */ +} + + +} /* extern "C" */ + diff --git a/ef/Packages/java/io/nativesrc/FileDescriptor.cpp b/ef/Packages/java/io/nativesrc/FileDescriptor.cpp new file mode 100644 index 000000000000..aec76ccf6ea1 --- /dev/null +++ b/ef/Packages/java/io/nativesrc/FileDescriptor.cpp @@ -0,0 +1,76 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#include + + +#include "java_io_FileDescriptor.h" +#include "prio.h" +#include "prprf.h" + +#include "Mapping.h" + +/* This is used as a global file-descriptor mapper */ + +Mapping fdMapping; + +extern "C" { + +#ifdef LINUX + +// +// This is temporary. I have to find a way to get the static +// initializers to work !!!! +// +// Sorry, Laurent. +// +void _init() +{ + fdMapping.init(); +#if 0 + fdMapping.descs[1] = PR_Open("/tmp/stdout", PR_WRONLY | PR_CREATE_FILE | PR_APPEND, 0644); + fdMapping.descs[2] = fdMapping.descs[1]; +#endif +} +#endif + +/* + * Class : java/io/FileDescriptor + * Method : sync + * Signature : ()V + */ +NS_EXPORT NS_NATIVECALL(void) +Netscape_Java_java_io_FileDescriptor_sync(Java_java_io_FileDescriptor *fileD) +{ + PRFileDesc *desc = fdMapping.get(fileD->fd); + + if (desc) PR_Sync(desc); +} + +/* + * Class : java/io/FileDescriptor + * Method : initIDs + * Signature : ()V + */ +NS_EXPORT NS_NATIVECALL(void) +Netscape_Java_java_io_FileDescriptor_initIDs() +{ + +} + +} /* extern "C" */ + diff --git a/ef/Packages/java/io/nativesrc/FileInputStream.cpp b/ef/Packages/java/io/nativesrc/FileInputStream.cpp new file mode 100644 index 000000000000..ee71b9cb17df --- /dev/null +++ b/ef/Packages/java/io/nativesrc/FileInputStream.cpp @@ -0,0 +1,180 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#include "java_io_FileInputStream.h" +#include "java_io_FileDescriptor.h" + +#include "prio.h" +#include "prprf.h" +#include "Mapping.h" + +#include "ErrorHandling.h" + +#include "JavaString.h" +#include "SysCallsRuntime.h" + +extern Mapping fdMapping; + +extern "C" { + +inline PRFileDesc *java_io_FileInputStream_GetDesc(Java_java_io_FileInputStream *str) +{ + PRFileDesc *desc = fdMapping.get(str->fd->fd); + + if (!desc) + sysThrowNamedException("java/io/IOException"); + + return desc; +} + +inline int64 java_io_FileInputStream_Read(Java_java_io_FileInputStream *str, + char *buf, int32 len) +{ + PRFileDesc *desc = java_io_FileInputStream_GetDesc(str); + + int nRead = PR_Read(desc, buf, len); + + if (nRead == 0) + return -1; /* EOF */ + else if (nRead < 0) + sysThrowNamedException("java/io/IOException"); + return nRead; +} + +/* + * Class : java/io/FileInputStream + * Method : open + * Signature : (Ljava/lang/String;)V + */ +NS_EXPORT NS_NATIVECALL(void) +Netscape_Java_java_io_FileInputStream_open(Java_java_io_FileInputStream *stream, + Java_java_lang_String *str) +{ + char *name = ((JavaString *) str)->convertUtf(); + + PRFileDesc *desc = PR_Open(name, PR_RDONLY, 0); + + JavaString::freeUtf(name); + + if (!desc) + sysThrowNamedException("java/io/IOException"); + + Int32 fd = fdMapping.add(desc); + stream->fd->fd = fd; +} + + +/* + * Class : java/io/FileInputStream + * Method : read + * Signature : ()I + */ +NS_EXPORT NS_NATIVECALL(int32) +Netscape_Java_java_io_FileInputStream_read(Java_java_io_FileInputStream *str) +{ + char c; + Int32 nRead = (int32) java_io_FileInputStream_Read(str, &c, 1); + assert(nRead == 1); + return (Int32) c; +} + + +/* + * Class : java/io/FileInputStream + * Method : readBytes + * Signature : ([BII)I + */ +NS_EXPORT NS_NATIVECALL(int32) +Netscape_Java_java_io_FileInputStream_readBytes(Java_java_io_FileInputStream *str, + ArrayOf_uint8 *arr, + int32 offset, + int32 len) +{ + if (offset < 0 || offset >= len || (Uint32)len > (arr->length - offset)) + runtimeError(RuntimeError::illegalAccess); + + char *startp = (char *) arr->elements + offset; + int32 nRead = (int32) java_io_FileInputStream_Read(str, startp, len); + + return nRead; +} + + +/* + * Class : java/io/FileInputStream + * Method : skip + * Signature : (J)J + */ +NS_EXPORT NS_NATIVECALL(int64) +Netscape_Java_java_io_FileInputStream_skip(Java_java_io_FileInputStream *str, + int64 nBytesToSkip) +{ + if (nBytesToSkip < 0) + sysThrowNamedException("java/io/IOException"); + else if (nBytesToSkip == 0) + return 0; + + char *buf = new char[(int32) nBytesToSkip]; + + if (!buf) + return 0; + + int32 nRead = (int32) java_io_FileInputStream_Read(str, buf, (int32) nBytesToSkip); + + return nRead; +} + + +/* + * Class : java/io/FileInputStream + * Method : available + * Signature : ()I + */ +NS_EXPORT NS_NATIVECALL(int32) +Netscape_Java_java_io_FileInputStream_available(Java_java_io_FileInputStream *str) +{ + PRFileDesc *desc = java_io_FileInputStream_GetDesc(str); + + return PR_Available(desc); +} + + +/* + * Class : java/io/FileInputStream + * Method : close + * Signature : ()V + */ +NS_EXPORT NS_NATIVECALL(void) +Netscape_Java_java_io_FileInputStream_close(Java_java_io_FileInputStream *str) +{ + fdMapping.close(str->fd->fd); +} + +/* + * Class : java/io/FileInputStream + * Method : initIDs + * Signature : ()V + */ +NS_EXPORT NS_NATIVECALL(void) +Netscape_Java_java_io_FileInputStream_initIDs() +{ + /* Currently empty, since all our initialization is done statically (see Mapping.h) */ +} + + +} /* extern "C" */ + diff --git a/ef/Packages/java/io/nativesrc/FileOutputStream.cpp b/ef/Packages/java/io/nativesrc/FileOutputStream.cpp new file mode 100644 index 000000000000..99b55e326b73 --- /dev/null +++ b/ef/Packages/java/io/nativesrc/FileOutputStream.cpp @@ -0,0 +1,157 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#include "java_io_FileOutputStream.h" + +#include "java_io_FileDescriptor.h" +#include "java_lang_String.h" + +#include "prio.h" +#include "prprf.h" + +#include "ErrorHandling.h" +#include "Mapping.h" +#include "JavaString.h" +#include "SysCallsRuntime.h" + +extern Mapping fdMapping; + +extern "C" { +inline PRFileDesc *java_io_FileOutputStream_GetDesc(Java_java_io_FileOutputStream *str) +{ + PRFileDesc *desc = fdMapping.get(str->fd->fd); + + if (!desc) + runtimeError(RuntimeError::IOError); + + return desc; +} + +inline int64 java_io_FileOutputStream_Write(Java_java_io_FileOutputStream *str, + char *buf, int32 len) +{ + PRFileDesc *desc = java_io_FileOutputStream_GetDesc(str); + + int nWritten = PR_Write(desc, buf, len); + + if (nWritten < 0) + runtimeError(RuntimeError::IOError); + + return nWritten; +} + +/* + * Class : java/io/FileOutputStream + * Method : open + * Signature : (Ljava/lang/String;)V + */ +NS_EXPORT NS_NATIVECALL(void) +Netscape_Java_java_io_FileOutputStream_open(Java_java_io_FileOutputStream *stream, + Java_java_lang_String *string) +{ + char *name = ((JavaString *) string)->convertUtf(); + + PRFileDesc *desc = PR_Open(name, PR_WRONLY | PR_CREATE_FILE, 0); + + JavaString::freeUtf(name); + + if (!desc) + sysThrowNamedException("java/io/IOException"); + + int32 fd = fdMapping.add(desc); + stream->fd->fd = fd; + +} + +/* + * Class : java/io/FileOutputStream + * Method : openAppend + * Signature : (Ljava/lang/String;)V + */ +NS_EXPORT NS_NATIVECALL(void) +Netscape_Java_java_io_FileOutputStream_openAppend(Java_java_io_FileOutputStream *stream, Java_java_lang_String *string) +{ + char *name = ((JavaString *) string)->convertUtf(); + + PRFileDesc *desc = PR_Open(name, PR_APPEND, 0); + + JavaString::freeUtf(name); + + if (!desc) + sysThrowNamedException("java/io/IOException"); + + int32 fd = fdMapping.add(desc); + stream->fd->fd = fd; +} + + +/* + * Class : java/io/FileOutputStream + * Method : write + * Signature : (I)V + */ +NS_EXPORT NS_NATIVECALL(void) +Netscape_Java_java_io_FileOutputStream_write(Java_java_io_FileOutputStream *str, + int32 byte) +{ + java_io_FileOutputStream_Write(str, (char *) &byte, 1); +} + + +/* + * Class : java/io/FileOutputStream + * Method : writeBytes + * Signature : ([BII)V + */ +NS_EXPORT NS_NATIVECALL(void) +Netscape_Java_java_io_FileOutputStream_writeBytes(Java_java_io_FileOutputStream *str, + ArrayOf_uint8 *arr, + int32 offset, int32 len) +{ + if (offset < 0 || offset >= len || (Uint32)len > (arr->length - offset)) + runtimeError(RuntimeError::illegalAccess); + + char *startp = (char *) arr->elements + offset; + java_io_FileOutputStream_Write(str, startp, len); + +} + + +/* + * Class : java/io/FileOutputStream + * Method : close + * Signature : ()V + */ +NS_EXPORT NS_NATIVECALL(void) +Netscape_Java_java_io_FileOutputStream_close(Java_java_io_FileOutputStream *str) +{ + fdMapping.close(str->fd->fd); +} + +/* + * Class : java/io/FileOutputStream + * Method : initIDs + * Signature : ()V + */ +NS_EXPORT NS_NATIVECALL(void) +Netscape_Java_java_io_FileOutputStream_initIDs() +{ + /* Currently empty, since all our initialization is done statically (see Mapping.h) */ +} + +} /* extern "C" */ + diff --git a/ef/Packages/java/io/nativesrc/Makefile b/ef/Packages/java/io/nativesrc/Makefile new file mode 100644 index 000000000000..1f9342b20734 --- /dev/null +++ b/ef/Packages/java/io/nativesrc/Makefile @@ -0,0 +1,45 @@ +#!gmake +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +####################################################################### +# (1) Include manifest file # +####################################################################### + +include manifest.mn + +####################################################################### +# (2) Include "component" configuration information. # +####################################################################### + +include $(DEPTH)/config/config.mk + +####################################################################### +# (3) Include "local" platform-dependent assignments (OPTIONAL). # +####################################################################### + + +####################################################################### +# (4) Execute "component" rules. (OPTIONAL) # +####################################################################### + +include $(DEPTH)/config/rules.mk + +####################################################################### +# (7) Execute "local" rules. (OPTIONAL). # +####################################################################### + + diff --git a/ef/Packages/java/io/nativesrc/Mapping.h b/ef/Packages/java/io/nativesrc/Mapping.h new file mode 100644 index 000000000000..383d909ca681 --- /dev/null +++ b/ef/Packages/java/io/nativesrc/Mapping.h @@ -0,0 +1,87 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#ifndef _FD_MAPPING_H_ +#define _FD_MAPPING_H_ + +#include + +/* The current JDK Java source uses an int32 to represent a file-descriptor. + * NSPR uses pointers to PRFileDesc's. So we need a mapping from one to the + * other. + */ +struct Mapping { + PRFileDesc **descs; + int32 numDescs; + + /* Initialize the mapping mechanism and the values of STDIN, STDOUT + * and STDERR. + */ + Mapping() {init(); } + + void init() { + numDescs = 10; + descs = new PRFileDesc * [numDescs]; + memset(descs, 0, numDescs * sizeof(PRFileDesc *)); + descs[0] = PR_STDIN; + descs[1] = PR_STDOUT; + descs[2] = PR_STDERR; + } + + /* Return true if the given fd is valid. */ + bool valid(int fd) { return (fd < numDescs && descs[fd] != 0); } + + /* Add a new file descriptor and return the corresponding fd */ + int add(PRFileDesc *desc) { + int32 i; + for (i = 0; i < numDescs; i++) + if (!descs[i]) { + descs[i] = desc; + return i; + } else if (descs[i] == desc) /* Already added by someone else */ + return i; + + PRFileDesc **temp = descs; + descs = new PRFileDesc * [numDescs = numDescs+10]; + memset(descs, 0, sizeof(PRFileDesc *)*numDescs); + for (int32 j = 0; j < numDescs; j++) + descs[j] = temp[j]; + + delete [] temp; + + descs[i] = desc; + return i; + } + + PRFileDesc *get(int32 fd) { assert(fd < numDescs); return descs[fd]; } + + void close(int32 fd) { + assert(fd < numDescs); + + if (valid(fd)) + PR_Close(descs[fd]); + + descs[fd] = 0; + } + + ~Mapping() { + delete [] descs; + } +}; + + +#endif /* _FD_MAPPING_H_ */ diff --git a/ef/Packages/java/io/nativesrc/RandomAccessFile.cpp b/ef/Packages/java/io/nativesrc/RandomAccessFile.cpp new file mode 100644 index 000000000000..14e45f53869a --- /dev/null +++ b/ef/Packages/java/io/nativesrc/RandomAccessFile.cpp @@ -0,0 +1,66 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#include "java_io_RandomAccessFile.h" +#include "java_io_FileDescriptor.h" +#include "java_lang_String.h" + +#include "prio.h" +#include "prprf.h" +#include "Mapping.h" + +#include "JavaString.h" +#include "JavaVM.h" + +extern Mapping fdMapping; + +extern "C" { + +/* + * Class : java/io/RandomAccessFile + * Method : initIDs + * Signature : ()V + */ +NS_EXPORT NS_NATIVECALL(void) +Netscape_Java_java_io_RandomAccessFile_initIDs() +{ +// PR_fprintf(PR_STDERR, "Warning: RandomAccessFile::initIDs() not implemented\n"); +} + +/* + * Class : java/io/RandomAccessFile + * Method : open + * Signature : (Ljava/lang/String;Z)V + */ +NS_EXPORT NS_NATIVECALL(void) +Netscape_Java_java_io_RandomAccessFile_open(Java_java_io_RandomAccessFile *raFile, Java_java_lang_String *str, uint32 /* bool */ w) +{ + char *name = ((JavaString *) str)->convertUtf(); + + PRFileDesc *desc = PR_Open(name, (w) ? PR_RDWR|PR_CREATE_FILE : PR_RDONLY, 0); + + JavaString::freeUtf(name); + + if (!desc) + sysThrowNamedException("java/io/IOException"); + + Int32 fd = fdMapping.add(desc); + raFile->fd->fd = fd; +} + +} diff --git a/ef/Packages/java/io/nativesrc/geninclude/.cvsignore b/ef/Packages/java/io/nativesrc/geninclude/.cvsignore new file mode 100644 index 000000000000..f6847e0eb6cf --- /dev/null +++ b/ef/Packages/java/io/nativesrc/geninclude/.cvsignore @@ -0,0 +1,3 @@ +java_io_* +java_lang_* + diff --git a/ef/Packages/java/io/nativesrc/manifest.mn b/ef/Packages/java/io/nativesrc/manifest.mn new file mode 100644 index 000000000000..37df03d5c4e0 --- /dev/null +++ b/ef/Packages/java/io/nativesrc/manifest.mn @@ -0,0 +1,36 @@ +#!gmake +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +DEPTH = ../../../.. + +MODULE_NAME = Package + + +CPPSRCS = File.cpp \ + FileDescriptor.cpp \ + FileInputStream.cpp \ + FileOutputStream.cpp \ + $(NULL) + + +HEADER_GEN = java.io.File \ + java.io.FileDescriptor \ + java.io.FileInputStream \ + java.io.FileOutputStream \ + $(NULL) + + diff --git a/ef/Packages/java/lang/Makefile b/ef/Packages/java/lang/Makefile new file mode 100644 index 000000000000..1f9342b20734 --- /dev/null +++ b/ef/Packages/java/lang/Makefile @@ -0,0 +1,45 @@ +#!gmake +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +####################################################################### +# (1) Include manifest file # +####################################################################### + +include manifest.mn + +####################################################################### +# (2) Include "component" configuration information. # +####################################################################### + +include $(DEPTH)/config/config.mk + +####################################################################### +# (3) Include "local" platform-dependent assignments (OPTIONAL). # +####################################################################### + + +####################################################################### +# (4) Execute "component" rules. (OPTIONAL) # +####################################################################### + +include $(DEPTH)/config/rules.mk + +####################################################################### +# (7) Execute "local" rules. (OPTIONAL). # +####################################################################### + + diff --git a/ef/Packages/java/lang/manifest.mn b/ef/Packages/java/lang/manifest.mn new file mode 100644 index 000000000000..64057b85d616 --- /dev/null +++ b/ef/Packages/java/lang/manifest.mn @@ -0,0 +1,25 @@ +#!gmake +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +DEPTH = ../../.. + +DIRS = nativesrc + + + + + diff --git a/ef/Packages/java/lang/nativesrc/Character.cpp b/ef/Packages/java/lang/nativesrc/Character.cpp new file mode 100644 index 000000000000..fc4c9ca875cc --- /dev/null +++ b/ef/Packages/java/lang/nativesrc/Character.cpp @@ -0,0 +1,1313 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#include "java_lang_Character.h" + +#include "JavaVM.h" +#include "FieldOrMethod.h" +#include "SysCallsRuntime.h" + + +static signed char X[] = { + 0, 1, 2, 3, 4, 5, 6, 7, // 0x0000 + 8, 9, 10, 11, 12, 13, 14, 15, // 0x0200 + 16, 17, 18, 19, 20, 21, 22, 23, // 0x0400 + 24, 25, 26, 27, 28, 28, 28, 28, // 0x0600 + 28, 28, 28, 28, 29, 30, 31, 32, // 0x0800 + 33, 34, 35, 36, 37, 38, 39, 40, // 0x0A00 + 41, 42, 43, 44, 45, 46, 28, 28, // 0x0C00 + 47, 48, 49, 50, 51, 52, 53, 28, // 0x0E00 + 28, 28, 54, 55, 56, 57, 58, 59, // 0x1000 + 28, 28, 28, 28, 28, 28, 28, 28, // 0x1200 + 28, 28, 28, 28, 28, 28, 28, 28, // 0x1400 + 28, 28, 28, 28, 28, 28, 28, 28, // 0x1600 + 28, 28, 28, 28, 28, 28, 28, 28, // 0x1800 + 28, 28, 28, 28, 28, 28, 28, 28, // 0x1A00 + 28, 28, 28, 28, 28, 28, 28, 28, // 0x1C00 + 60, 60, 61, 62, 63, 64, 65, 66, // 0x1E00 + 67, 68, 69, 70, 71, 72, 73, 74, // 0x2000 + 75, 75, 75, 76, 77, 78, 28, 28, // 0x2200 + 79, 80, 81, 82, 83, 83, 84, 85, // 0x2400 + 86, 85, 28, 28, 87, 88, 89, 28, // 0x2600 + 28, 28, 28, 28, 28, 28, 28, 28, // 0x2800 + 28, 28, 28, 28, 28, 28, 28, 28, // 0x2A00 + 28, 28, 28, 28, 28, 28, 28, 28, // 0x2C00 + 28, 28, 28, 28, 28, 28, 28, 28, // 0x2E00 + 90, 91, 92, 93, 94, 56, 95, 28, // 0x3000 + 96, 97, 98, 99, 83, 100, 83, 101, // 0x3200 + 28, 28, 28, 28, 28, 28, 28, 28, // 0x3400 + 28, 28, 28, 28, 28, 28, 28, 28, // 0x3600 + 28, 28, 28, 28, 28, 28, 28, 28, // 0x3800 + 28, 28, 28, 28, 28, 28, 28, 28, // 0x3A00 + 28, 28, 28, 28, 28, 28, 28, 28, // 0x3C00 + 28, 28, 28, 28, 28, 28, 28, 28, // 0x3E00 + 28, 28, 28, 28, 28, 28, 28, 28, // 0x4000 + 28, 28, 28, 28, 28, 28, 28, 28, // 0x4200 + 28, 28, 28, 28, 28, 28, 28, 28, // 0x4400 + 28, 28, 28, 28, 28, 28, 28, 28, // 0x4600 + 28, 28, 28, 28, 28, 28, 28, 28, // 0x4800 + 28, 28, 28, 28, 28, 28, 28, 28, // 0x4A00 + 28, 28, 28, 28, 28, 28, 28, 28, // 0x4C00 + 56, 56, 56, 56, 56, 56, 56, 56, // 0x4E00 + 56, 56, 56, 56, 56, 56, 56, 56, // 0x5000 + 56, 56, 56, 56, 56, 56, 56, 56, // 0x5200 + 56, 56, 56, 56, 56, 56, 56, 56, // 0x5400 + 56, 56, 56, 56, 56, 56, 56, 56, // 0x5600 + 56, 56, 56, 56, 56, 56, 56, 56, // 0x5800 + 56, 56, 56, 56, 56, 56, 56, 56, // 0x5A00 + 56, 56, 56, 56, 56, 56, 56, 56, // 0x5C00 + 56, 56, 56, 56, 56, 56, 56, 56, // 0x5E00 + 56, 56, 56, 56, 56, 56, 56, 56, // 0x6000 + 56, 56, 56, 56, 56, 56, 56, 56, // 0x6200 + 56, 56, 56, 56, 56, 56, 56, 56, // 0x6400 + 56, 56, 56, 56, 56, 56, 56, 56, // 0x6600 + 56, 56, 56, 56, 56, 56, 56, 56, // 0x6800 + 56, 56, 56, 56, 56, 56, 56, 56, // 0x6A00 + 56, 56, 56, 56, 56, 56, 56, 56, // 0x6C00 + 56, 56, 56, 56, 56, 56, 56, 56, // 0x6E00 + 56, 56, 56, 56, 56, 56, 56, 56, // 0x7000 + 56, 56, 56, 56, 56, 56, 56, 56, // 0x7200 + 56, 56, 56, 56, 56, 56, 56, 56, // 0x7400 + 56, 56, 56, 56, 56, 56, 56, 56, // 0x7600 + 56, 56, 56, 56, 56, 56, 56, 56, // 0x7800 + 56, 56, 56, 56, 56, 56, 56, 56, // 0x7A00 + 56, 56, 56, 56, 56, 56, 56, 56, // 0x7C00 + 56, 56, 56, 56, 56, 56, 56, 56, // 0x7E00 + 56, 56, 56, 56, 56, 56, 56, 56, // 0x8000 + 56, 56, 56, 56, 56, 56, 56, 56, // 0x8200 + 56, 56, 56, 56, 56, 56, 56, 56, // 0x8400 + 56, 56, 56, 56, 56, 56, 56, 56, // 0x8600 + 56, 56, 56, 56, 56, 56, 56, 56, // 0x8800 + 56, 56, 56, 56, 56, 56, 56, 56, // 0x8A00 + 56, 56, 56, 56, 56, 56, 56, 56, // 0x8C00 + 56, 56, 56, 56, 56, 56, 56, 56, // 0x8E00 + 56, 56, 56, 56, 56, 56, 56, 56, // 0x9000 + 56, 56, 56, 56, 56, 56, 56, 56, // 0x9200 + 56, 56, 56, 56, 56, 56, 56, 56, // 0x9400 + 56, 56, 56, 56, 56, 56, 56, 56, // 0x9600 + 56, 56, 56, 56, 56, 56, 56, 56, // 0x9800 + 56, 56, 56, 56, 56, 56, 56, 56, // 0x9A00 + 56, 56, 56, 56, 56, 56, 56, 56, // 0x9C00 + 56, 56, 56, 56, 56, 56, 102, 28, // 0x9E00 + 28, 28, 28, 28, 28, 28, 28, 28, // 0xA000 + 28, 28, 28, 28, 28, 28, 28, 28, // 0xA200 + 28, 28, 28, 28, 28, 28, 28, 28, // 0xA400 + 28, 28, 28, 28, 28, 28, 28, 28, // 0xA600 + 28, 28, 28, 28, 28, 28, 28, 28, // 0xA800 + 28, 28, 28, 28, 28, 28, 28, 28, // 0xAA00 + 56, 56, 56, 56, 56, 56, 56, 56, // 0xAC00 + 56, 56, 56, 56, 56, 56, 56, 56, // 0xAE00 + 56, 56, 56, 56, 56, 56, 56, 56, // 0xB000 + 56, 56, 56, 56, 56, 56, 56, 56, // 0xB200 + 56, 56, 56, 56, 56, 56, 56, 56, // 0xB400 + 56, 56, 56, 56, 56, 56, 56, 56, // 0xB600 + 56, 56, 56, 56, 56, 56, 56, 56, // 0xB800 + 56, 56, 56, 56, 56, 56, 56, 56, // 0xBA00 + 56, 56, 56, 56, 56, 56, 56, 56, // 0xBC00 + 56, 56, 56, 56, 56, 56, 56, 56, // 0xBE00 + 56, 56, 56, 56, 56, 56, 56, 56, // 0xC000 + 56, 56, 56, 56, 56, 56, 56, 56, // 0xC200 + 56, 56, 56, 56, 56, 56, 56, 56, // 0xC400 + 56, 56, 56, 56, 56, 56, 56, 56, // 0xC600 + 56, 56, 56, 56, 56, 56, 56, 56, // 0xC800 + 56, 56, 56, 56, 56, 56, 56, 56, // 0xCA00 + 56, 56, 56, 56, 56, 56, 56, 56, // 0xCC00 + 56, 56, 56, 56, 56, 56, 56, 56, // 0xCE00 + 56, 56, 56, 56, 56, 56, 56, 56, // 0xD000 + 56, 56, 56, 56, 56, 56, 56, 56, // 0xD200 + 56, 56, 56, 56, 56, 56, 56, 56, // 0xD400 + 56, 56, 56, 56, 56, 56, 103, 28, // 0xD600 + 104, 104, 104, 104, 104, 104, 104, 104, // 0xD800 + 104, 104, 104, 104, 104, 104, 104, 104, // 0xDA00 + 104, 104, 104, 104, 104, 104, 104, 104, // 0xDC00 + 104, 104, 104, 104, 104, 104, 104, 104, // 0xDE00 + 105, 105, 105, 105, 105, 105, 105, 105, // 0xE000 + 105, 105, 105, 105, 105, 105, 105, 105, // 0xE200 + 105, 105, 105, 105, 105, 105, 105, 105, // 0xE400 + 105, 105, 105, 105, 105, 105, 105, 105, // 0xE600 + 105, 105, 105, 105, 105, 105, 105, 105, // 0xE800 + 105, 105, 105, 105, 105, 105, 105, 105, // 0xEA00 + 105, 105, 105, 105, 105, 105, 105, 105, // 0xEC00 + 105, 105, 105, 105, 105, 105, 105, 105, // 0xEE00 + 105, 105, 105, 105, 105, 105, 105, 105, // 0xF000 + 105, 105, 105, 105, 105, 105, 105, 105, // 0xF200 + 105, 105, 105, 105, 105, 105, 105, 105, // 0xF400 + 105, 105, 105, 105, 105, 105, 105, 105, // 0xF600 + 105, 105, 105, 105, 56, 56, 56, 56, // 0xF800 + 106, 28, 28, 28, 107, 108, 109, 110, // 0xFA00 + 56, 56, 56, 56, 111, 112, 113, 114, // 0xFC00 + 115, 116, 56, 117, 118, 119, 120, 121 // 0xFE00 + }; + +static signed char Y[] = { + 0, 0, 0, 0, 0, 0, 0, 0, // 0 + 0, 1, 1, 1, 1, 1, 0, 0, // 0 + 0, 0, 0, 0, 0, 0, 0, 0, // 0 + 0, 0, 0, 0, 1, 1, 1, 1, // 0 + 2, 3, 3, 3, 4, 3, 3, 3, // 0 + 5, 6, 3, 7, 3, 8, 3, 3, // 0 + 9, 9, 9, 9, 9, 9, 9, 9, // 0 + 9, 9, 3, 3, 7, 7, 7, 3, // 0 + 3, 10, 10, 10, 10, 10, 10, 10, // 1 + 10, 10, 10, 10, 10, 10, 10, 10, // 1 + 10, 10, 10, 10, 10, 10, 10, 10, // 1 + 10, 10, 10, 5, 3, 6, 11, 12, // 1 + 11, 13, 13, 13, 13, 13, 13, 13, // 1 + 13, 13, 13, 13, 13, 13, 13, 13, // 1 + 13, 13, 13, 13, 13, 13, 13, 13, // 1 + 13, 13, 13, 5, 7, 6, 7, 0, // 1 + 0, 0, 0, 0, 0, 0, 0, 0, // 2 + 0, 0, 0, 0, 0, 0, 0, 0, // 2 + 0, 0, 0, 0, 0, 0, 0, 0, // 2 + 0, 0, 0, 0, 0, 0, 0, 0, // 2 + 14, 3, 4, 4, 4, 4, 15, 15, // 2 + 11, 15, 16, 5, 7, 8, 15, 11, // 2 + 15, 7, 17, 17, 11, 16, 15, 3, // 2 + 11, 18, 16, 6, 19, 19, 19, 3, // 2 + 20, 20, 20, 20, 20, 20, 20, 20, // 3 + 20, 20, 20, 20, 20, 20, 20, 20, // 3 + 20, 20, 20, 20, 20, 20, 20, 7, // 3 + 20, 20, 20, 20, 20, 20, 20, 16, // 3 + 21, 21, 21, 21, 21, 21, 21, 21, // 3 + 21, 21, 21, 21, 21, 21, 21, 21, // 3 + 21, 21, 21, 21, 21, 21, 21, 7, // 3 + 21, 21, 21, 21, 21, 21, 21, 22, // 3 + 23, 24, 23, 24, 23, 24, 23, 24, // 4 + 23, 24, 23, 24, 23, 24, 23, 24, // 4 + 23, 24, 23, 24, 23, 24, 23, 24, // 4 + 23, 24, 23, 24, 23, 24, 23, 24, // 4 + 23, 24, 23, 24, 23, 24, 23, 24, // 4 + 23, 24, 23, 24, 23, 24, 23, 24, // 4 + 25, 26, 23, 24, 23, 24, 23, 24, // 4 + 16, 23, 24, 23, 24, 23, 24, 23, // 4 + 24, 23, 24, 23, 24, 23, 24, 23, // 5 + 24, 16, 23, 24, 23, 24, 23, 24, // 5 + 23, 24, 23, 24, 23, 24, 23, 24, // 5 + 23, 24, 23, 24, 23, 24, 23, 24, // 5 + 23, 24, 23, 24, 23, 24, 23, 24, // 5 + 23, 24, 23, 24, 23, 24, 23, 24, // 5 + 23, 24, 23, 24, 23, 24, 23, 24, // 5 + 27, 23, 24, 23, 24, 23, 24, 28, // 5 + 16, 29, 23, 24, 23, 24, 30, 23, // 6 + 24, 31, 31, 23, 24, 16, 32, 32, // 6 + 33, 23, 24, 31, 34, 16, 35, 36, // 6 + 23, 24, 16, 16, 35, 37, 16, 38, // 6 + 23, 24, 23, 24, 23, 24, 38, 23, // 6 + 24, 39, 40, 16, 23, 24, 39, 23, // 6 + 24, 41, 41, 23, 24, 23, 24, 42, // 6 + 23, 24, 16, 40, 23, 24, 40, 40, // 6 + 40, 40, 40, 40, 43, 44, 45, 43, // 7 + 44, 45, 43, 44, 45, 23, 24, 23, // 7 + 24, 23, 24, 23, 24, 23, 24, 23, // 7 + 24, 23, 24, 23, 24, 16, 23, 24, // 7 + 23, 24, 23, 24, 23, 24, 23, 24, // 7 + 23, 24, 23, 24, 23, 24, 23, 24, // 7 + 16, 43, 44, 45, 23, 24, 46, 46, // 7 + 46, 46, 23, 24, 23, 24, 23, 24, // 7 + 23, 24, 23, 24, 23, 24, 23, 24, // 8 + 23, 24, 23, 24, 23, 24, 23, 24, // 8 + 23, 24, 23, 24, 23, 24, 23, 24, // 8 + 46, 46, 46, 46, 46, 46, 46, 46, // 8 + 46, 46, 46, 46, 46, 46, 46, 46, // 8 + 46, 46, 46, 46, 46, 46, 46, 46, // 8 + 46, 46, 46, 46, 46, 46, 46, 46, // 8 + 46, 46, 46, 46, 46, 46, 46, 46, // 8 + 46, 46, 46, 46, 46, 46, 46, 46, // 9 + 46, 46, 46, 46, 46, 46, 46, 46, // 9 + 16, 16, 16, 47, 48, 16, 49, 49, // 9 + 50, 50, 16, 51, 16, 16, 16, 16, // 9 + 49, 16, 16, 52, 16, 16, 16, 16, // 9 + 53, 54, 16, 16, 16, 16, 16, 54, // 9 + 16, 16, 55, 16, 16, 16, 16, 16, // 9 + 16, 16, 16, 16, 16, 16, 16, 16, // 9 + 16, 16, 16, 56, 16, 16, 16, 16, // 10 + 56, 16, 57, 57, 16, 16, 16, 16, // 10 + 16, 16, 58, 16, 16, 16, 16, 16, // 10 + 16, 16, 16, 16, 16, 16, 16, 16, // 10 + 16, 16, 16, 16, 16, 16, 16, 16, // 10 + 16, 46, 46, 46, 46, 46, 46, 46, // 10 + 59, 59, 59, 59, 59, 59, 59, 59, // 10 + 59, 11, 11, 59, 59, 59, 59, 59, // 10 + 59, 59, 11, 11, 11, 11, 11, 11, // 11 + 11, 11, 11, 11, 11, 11, 11, 11, // 11 + 59, 59, 11, 11, 11, 11, 11, 11, // 11 + 11, 11, 11, 11, 11, 11, 11, 46, // 11 + 59, 59, 59, 59, 59, 11, 11, 11, // 11 + 11, 11, 46, 46, 46, 46, 46, 46, // 11 + 46, 46, 46, 46, 46, 46, 46, 46, // 11 + 46, 46, 46, 46, 46, 46, 46, 46, // 11 + 60, 60, 60, 60, 60, 60, 60, 60, // 12 + 60, 60, 60, 60, 60, 60, 60, 60, // 12 + 60, 60, 60, 60, 60, 60, 60, 60, // 12 + 60, 60, 60, 60, 60, 60, 60, 60, // 12 + 60, 60, 60, 60, 60, 60, 60, 60, // 12 + 60, 60, 60, 60, 60, 60, 60, 60, // 12 + 60, 60, 60, 60, 60, 60, 60, 60, // 12 + 60, 60, 60, 60, 60, 60, 60, 60, // 12 + 60, 60, 60, 60, 60, 60, 46, 46, // 13 + 46, 46, 46, 46, 46, 46, 46, 46, // 13 + 46, 46, 46, 46, 46, 46, 46, 46, // 13 + 46, 46, 46, 46, 46, 46, 46, 46, // 13 + 60, 60, 46, 46, 46, 46, 46, 46, // 13 + 46, 46, 46, 46, 46, 46, 46, 46, // 13 + 46, 46, 46, 46, 3, 3, 46, 46, // 13 + 46, 46, 59, 46, 46, 46, 3, 46, // 13 + 46, 46, 46, 46, 11, 11, 61, 3, // 14 + 62, 62, 62, 46, 63, 46, 64, 64, // 14 + 16, 20, 20, 20, 20, 20, 20, 20, // 14 + 20, 20, 20, 20, 20, 20, 20, 20, // 14 + 20, 20, 46, 20, 20, 20, 20, 20, // 14 + 20, 20, 20, 20, 65, 66, 66, 66, // 14 + 16, 21, 21, 21, 21, 21, 21, 21, // 14 + 21, 21, 21, 21, 21, 21, 21, 21, // 14 + 21, 21, 16, 21, 21, 21, 21, 21, // 15 + 21, 21, 21, 21, 67, 68, 68, 46, // 15 + 69, 70, 38, 38, 38, 71, 72, 46, // 15 + 46, 46, 38, 46, 38, 46, 38, 46, // 15 + 38, 46, 23, 24, 23, 24, 23, 24, // 15 + 23, 24, 23, 24, 23, 24, 23, 24, // 15 + 73, 74, 16, 40, 46, 46, 46, 46, // 15 + 46, 46, 46, 46, 46, 46, 46, 46, // 15 + 46, 75, 75, 75, 75, 75, 75, 75, // 16 + 75, 75, 75, 75, 75, 46, 75, 75, // 16 + 20, 20, 20, 20, 20, 20, 20, 20, // 16 + 20, 20, 20, 20, 20, 20, 20, 20, // 16 + 20, 20, 20, 20, 20, 20, 20, 20, // 16 + 20, 20, 20, 20, 20, 20, 20, 20, // 16 + 21, 21, 21, 21, 21, 21, 21, 21, // 16 + 21, 21, 21, 21, 21, 21, 21, 21, // 16 + 21, 21, 21, 21, 21, 21, 21, 21, // 17 + 21, 21, 21, 21, 21, 21, 21, 21, // 17 + 46, 74, 74, 74, 74, 74, 74, 74, // 17 + 74, 74, 74, 74, 74, 46, 74, 74, // 17 + 23, 24, 23, 24, 23, 24, 23, 24, // 17 + 23, 24, 23, 24, 23, 24, 23, 24, // 17 + 23, 24, 23, 24, 23, 24, 23, 24, // 17 + 23, 24, 23, 24, 23, 24, 23, 24, // 17 + 23, 24, 15, 60, 60, 60, 60, 46, // 18 + 46, 46, 46, 46, 46, 46, 46, 46, // 18 + 23, 24, 23, 24, 23, 24, 23, 24, // 18 + 23, 24, 23, 24, 23, 24, 23, 24, // 18 + 23, 24, 23, 24, 23, 24, 23, 24, // 18 + 23, 24, 23, 24, 23, 24, 23, 24, // 18 + 23, 24, 23, 24, 23, 24, 23, 24, // 18 + 23, 24, 23, 24, 23, 24, 23, 24, // 18 + 40, 23, 24, 23, 24, 46, 46, 23, // 19 + 24, 46, 46, 23, 24, 46, 46, 46, // 19 + 23, 24, 23, 24, 23, 24, 23, 24, // 19 + 23, 24, 23, 24, 23, 24, 23, 24, // 19 + 23, 24, 23, 24, 23, 24, 23, 24, // 19 + 23, 24, 23, 24, 46, 46, 23, 24, // 19 + 23, 24, 23, 24, 23, 24, 46, 46, // 19 + 23, 24, 46, 46, 46, 46, 46, 46, // 19 + 46, 46, 46, 46, 46, 46, 46, 46, // 20 + 46, 46, 46, 46, 46, 46, 46, 46, // 20 + 46, 46, 46, 46, 46, 46, 46, 46, // 20 + 46, 46, 46, 46, 46, 46, 46, 46, // 20 + 46, 46, 46, 46, 46, 46, 46, 46, // 20 + 46, 46, 46, 46, 46, 46, 46, 46, // 20 + 46, 76, 76, 76, 76, 76, 76, 76, // 20 + 76, 76, 76, 76, 76, 76, 76, 76, // 20 + 76, 76, 76, 76, 76, 76, 76, 76, // 21 + 76, 76, 76, 76, 76, 76, 76, 76, // 21 + 76, 76, 76, 76, 76, 76, 76, 46, // 21 + 46, 59, 3, 3, 3, 3, 3, 3, // 21 + 46, 77, 77, 77, 77, 77, 77, 77, // 21 + 77, 77, 77, 77, 77, 77, 77, 77, // 21 + 77, 77, 77, 77, 77, 77, 77, 77, // 21 + 77, 77, 77, 77, 77, 77, 77, 77, // 21 + 77, 77, 77, 77, 77, 77, 77, 16, // 22 + 46, 3, 46, 46, 46, 46, 46, 46, // 22 + 46, 60, 60, 60, 60, 60, 60, 60, // 22 + 60, 60, 60, 60, 60, 60, 60, 60, // 22 + 60, 60, 46, 60, 60, 60, 60, 60, // 22 + 60, 60, 60, 60, 60, 60, 60, 60, // 22 + 60, 60, 60, 60, 60, 60, 60, 60, // 22 + 60, 60, 46, 60, 60, 60, 3, 60, // 22 + 3, 60, 60, 3, 60, 46, 46, 46, // 23 + 46, 46, 46, 46, 46, 46, 46, 46, // 23 + 40, 40, 40, 40, 40, 40, 40, 40, // 23 + 40, 40, 40, 40, 40, 40, 40, 40, // 23 + 40, 40, 40, 40, 40, 40, 40, 40, // 23 + 40, 40, 40, 46, 46, 46, 46, 46, // 23 + 40, 40, 40, 3, 3, 46, 46, 46, // 23 + 46, 46, 46, 46, 46, 46, 46, 46, // 23 + 46, 46, 46, 46, 46, 46, 46, 46, // 24 + 46, 46, 46, 46, 3, 46, 46, 46, // 24 + 46, 46, 46, 46, 46, 46, 46, 46, // 24 + 46, 46, 46, 3, 46, 46, 46, 3, // 24 + 46, 40, 40, 40, 40, 40, 40, 40, // 24 + 40, 40, 40, 40, 40, 40, 40, 40, // 24 + 40, 40, 40, 40, 40, 40, 40, 40, // 24 + 40, 40, 40, 46, 46, 46, 46, 46, // 24 + 59, 40, 40, 40, 40, 40, 40, 40, // 25 + 40, 40, 40, 60, 60, 60, 60, 60, // 25 + 60, 60, 60, 46, 46, 46, 46, 46, // 25 + 46, 46, 46, 46, 46, 46, 46, 46, // 25 + 78, 78, 78, 78, 78, 78, 78, 78, // 25 + 78, 78, 3, 3, 3, 3, 46, 46, // 25 + 60, 40, 40, 40, 40, 40, 40, 40, // 25 + 40, 40, 40, 40, 40, 40, 40, 40, // 25 + 40, 40, 40, 40, 40, 40, 40, 40, // 26 + 40, 40, 40, 40, 40, 40, 40, 40, // 26 + 40, 40, 40, 40, 40, 40, 40, 40, // 26 + 40, 40, 40, 40, 40, 40, 40, 40, // 26 + 40, 40, 40, 40, 40, 40, 40, 40, // 26 + 40, 40, 40, 40, 40, 40, 40, 40, // 26 + 40, 40, 40, 40, 40, 40, 40, 40, // 26 + 46, 46, 40, 40, 40, 40, 40, 46, // 26 + 40, 40, 40, 40, 40, 40, 40, 40, // 27 + 40, 40, 40, 40, 40, 40, 40, 46, // 27 + 40, 40, 40, 40, 3, 40, 60, 60, // 27 + 60, 60, 60, 60, 60, 79, 79, 60, // 27 + 60, 60, 60, 60, 60, 59, 59, 60, // 27 + 60, 15, 60, 60, 60, 60, 46, 46, // 27 + 9, 9, 9, 9, 9, 9, 9, 9, // 27 + 9, 9, 46, 46, 46, 46, 46, 46, // 27 + 46, 46, 46, 46, 46, 46, 46, 46, // 28 + 46, 46, 46, 46, 46, 46, 46, 46, // 28 + 46, 46, 46, 46, 46, 46, 46, 46, // 28 + 46, 46, 46, 46, 46, 46, 46, 46, // 28 + 46, 46, 46, 46, 46, 46, 46, 46, // 28 + 46, 46, 46, 46, 46, 46, 46, 46, // 28 + 46, 46, 46, 46, 46, 46, 46, 46, // 28 + 46, 46, 46, 46, 46, 46, 46, 46, // 28 + 46, 60, 60, 80, 46, 40, 40, 40, // 29 + 40, 40, 40, 40, 40, 40, 40, 40, // 29 + 40, 40, 40, 40, 40, 40, 40, 40, // 29 + 40, 40, 40, 40, 40, 40, 40, 40, // 29 + 40, 40, 40, 40, 40, 40, 40, 40, // 29 + 40, 40, 40, 40, 40, 40, 40, 40, // 29 + 40, 40, 40, 40, 40, 40, 40, 40, // 29 + 40, 40, 46, 46, 60, 40, 80, 80, // 29 + 80, 60, 60, 60, 60, 60, 60, 60, // 30 + 60, 80, 80, 80, 80, 60, 46, 46, // 30 + 15, 60, 60, 60, 60, 46, 46, 46, // 30 + 40, 40, 40, 40, 40, 40, 40, 40, // 30 + 40, 40, 60, 60, 3, 3, 81, 81, // 30 + 81, 81, 81, 81, 81, 81, 81, 81, // 30 + 3, 46, 46, 46, 46, 46, 46, 46, // 30 + 46, 46, 46, 46, 46, 46, 46, 46, // 30 + 46, 60, 80, 80, 46, 40, 40, 40, // 31 + 40, 40, 40, 40, 40, 46, 46, 40, // 31 + 40, 46, 46, 40, 40, 40, 40, 40, // 31 + 40, 40, 40, 40, 40, 40, 40, 40, // 31 + 40, 40, 40, 40, 40, 40, 40, 40, // 31 + 40, 46, 40, 40, 40, 40, 40, 40, // 31 + 40, 46, 40, 46, 46, 46, 40, 40, // 31 + 40, 40, 46, 46, 60, 46, 80, 80, // 31 + 80, 60, 60, 60, 60, 46, 46, 80, // 32 + 80, 46, 46, 80, 80, 60, 46, 46, // 32 + 46, 46, 46, 46, 46, 46, 46, 80, // 32 + 46, 46, 46, 46, 40, 40, 46, 40, // 32 + 40, 40, 60, 60, 46, 46, 81, 81, // 32 + 81, 81, 81, 81, 81, 81, 81, 81, // 32 + 40, 40, 4, 4, 82, 82, 82, 82, // 32 + 19, 83, 15, 46, 46, 46, 46, 46, // 32 + 46, 46, 60, 46, 46, 40, 40, 40, // 33 + 40, 40, 40, 46, 46, 46, 46, 40, // 33 + 40, 46, 46, 40, 40, 40, 40, 40, // 33 + 40, 40, 40, 40, 40, 40, 40, 40, // 33 + 40, 40, 40, 40, 40, 40, 40, 40, // 33 + 40, 46, 40, 40, 40, 40, 40, 40, // 33 + 40, 46, 40, 40, 46, 40, 40, 46, // 33 + 40, 40, 46, 46, 60, 46, 80, 80, // 33 + 80, 60, 60, 46, 46, 46, 46, 60, // 34 + 60, 46, 46, 60, 60, 60, 46, 46, // 34 + 46, 46, 46, 46, 46, 46, 46, 46, // 34 + 46, 40, 40, 40, 40, 46, 40, 46, // 34 + 46, 46, 46, 46, 46, 46, 81, 81, // 34 + 81, 81, 81, 81, 81, 81, 81, 81, // 34 + 60, 60, 40, 40, 40, 46, 46, 46, // 34 + 46, 46, 46, 46, 46, 46, 46, 46, // 34 + 46, 60, 60, 80, 46, 40, 40, 40, // 35 + 40, 40, 40, 40, 46, 40, 46, 40, // 35 + 40, 40, 46, 40, 40, 40, 40, 40, // 35 + 40, 40, 40, 40, 40, 40, 40, 40, // 35 + 40, 40, 40, 40, 40, 40, 40, 40, // 35 + 40, 46, 40, 40, 40, 40, 40, 40, // 35 + 40, 46, 40, 40, 46, 40, 40, 40, // 35 + 40, 40, 46, 46, 60, 40, 80, 80, // 35 + 80, 60, 60, 60, 60, 60, 46, 60, // 36 + 60, 80, 46, 80, 80, 60, 46, 46, // 36 + 15, 46, 46, 46, 46, 46, 46, 46, // 36 + 46, 46, 46, 46, 46, 46, 46, 46, // 36 + 40, 46, 46, 46, 46, 46, 81, 81, // 36 + 81, 81, 81, 81, 81, 81, 81, 81, // 36 + 46, 46, 46, 46, 46, 46, 46, 46, // 36 + 46, 46, 46, 46, 46, 46, 46, 46, // 36 + 46, 60, 80, 80, 46, 40, 40, 40, // 37 + 40, 40, 40, 40, 40, 46, 46, 40, // 37 + 40, 46, 46, 40, 40, 40, 40, 40, // 37 + 40, 40, 40, 40, 40, 40, 40, 40, // 37 + 40, 40, 40, 40, 40, 40, 40, 40, // 37 + 40, 46, 40, 40, 40, 40, 40, 40, // 37 + 40, 46, 40, 40, 46, 46, 40, 40, // 37 + 40, 40, 46, 46, 60, 40, 80, 60, // 37 + 80, 60, 60, 60, 46, 46, 46, 80, // 38 + 80, 46, 46, 80, 80, 60, 46, 46, // 38 + 46, 46, 46, 46, 46, 46, 60, 80, // 38 + 46, 46, 46, 46, 40, 40, 46, 40, // 38 + 40, 40, 46, 46, 46, 46, 81, 81, // 38 + 81, 81, 81, 81, 81, 81, 81, 81, // 38 + 15, 46, 46, 46, 46, 46, 46, 46, // 38 + 46, 46, 46, 46, 46, 46, 46, 46, // 38 + 46, 46, 60, 80, 46, 40, 40, 40, // 39 + 40, 40, 40, 46, 46, 46, 40, 40, // 39 + 40, 46, 40, 40, 40, 40, 46, 46, // 39 + 46, 40, 40, 46, 40, 46, 40, 40, // 39 + 46, 46, 46, 40, 40, 46, 46, 46, // 39 + 40, 40, 40, 46, 46, 46, 40, 40, // 39 + 40, 40, 40, 40, 40, 40, 46, 40, // 39 + 40, 40, 46, 46, 46, 46, 80, 80, // 39 + 60, 80, 80, 46, 46, 46, 80, 80, // 40 + 80, 46, 80, 80, 80, 60, 46, 46, // 40 + 46, 46, 46, 46, 46, 46, 46, 80, // 40 + 46, 46, 46, 46, 46, 46, 46, 46, // 40 + 46, 46, 46, 46, 46, 46, 46, 81, // 40 + 81, 81, 81, 81, 81, 81, 81, 81, // 40 + 84, 19, 19, 46, 46, 46, 46, 46, // 40 + 46, 46, 46, 46, 46, 46, 46, 46, // 40 + 46, 80, 80, 80, 46, 40, 40, 40, // 41 + 40, 40, 40, 40, 40, 46, 40, 40, // 41 + 40, 46, 40, 40, 40, 40, 40, 40, // 41 + 40, 40, 40, 40, 40, 40, 40, 40, // 41 + 40, 40, 40, 40, 40, 40, 40, 40, // 41 + 40, 46, 40, 40, 40, 40, 40, 40, // 41 + 40, 40, 40, 40, 46, 40, 40, 40, // 41 + 40, 40, 46, 46, 46, 46, 60, 60, // 41 + 60, 80, 80, 80, 80, 46, 60, 60, // 42 + 60, 46, 60, 60, 60, 60, 46, 46, // 42 + 46, 46, 46, 46, 46, 60, 60, 46, // 42 + 46, 46, 46, 46, 46, 46, 46, 46, // 42 + 40, 40, 46, 46, 46, 46, 81, 81, // 42 + 81, 81, 81, 81, 81, 81, 81, 81, // 42 + 46, 46, 46, 46, 46, 46, 46, 46, // 42 + 46, 46, 46, 46, 46, 46, 46, 46, // 42 + 46, 46, 80, 80, 46, 40, 40, 40, // 43 + 40, 40, 40, 40, 40, 46, 40, 40, // 43 + 40, 46, 40, 40, 40, 40, 40, 40, // 43 + 40, 40, 40, 40, 40, 40, 40, 40, // 43 + 40, 40, 40, 40, 40, 40, 40, 40, // 43 + 40, 46, 40, 40, 40, 40, 40, 40, // 43 + 40, 40, 40, 40, 46, 40, 40, 40, // 43 + 40, 40, 46, 46, 46, 46, 80, 60, // 43 + 80, 80, 80, 80, 80, 46, 60, 80, // 44 + 80, 46, 80, 80, 60, 60, 46, 46, // 44 + 46, 46, 46, 46, 46, 80, 80, 46, // 44 + 46, 46, 46, 46, 46, 46, 40, 46, // 44 + 40, 40, 46, 46, 46, 46, 81, 81, // 44 + 81, 81, 81, 81, 81, 81, 81, 81, // 44 + 46, 46, 46, 46, 46, 46, 46, 46, // 44 + 46, 46, 46, 46, 46, 46, 46, 46, // 44 + 46, 46, 80, 80, 46, 40, 40, 40, // 45 + 40, 40, 40, 40, 40, 46, 40, 40, // 45 + 40, 46, 40, 40, 40, 40, 40, 40, // 45 + 40, 40, 40, 40, 40, 40, 40, 40, // 45 + 40, 40, 40, 40, 40, 40, 40, 40, // 45 + 40, 46, 40, 40, 40, 40, 40, 40, // 45 + 40, 40, 40, 40, 40, 40, 40, 40, // 45 + 40, 40, 46, 46, 46, 46, 80, 80, // 45 + 80, 60, 60, 60, 46, 46, 80, 80, // 46 + 80, 46, 80, 80, 80, 60, 46, 46, // 46 + 46, 46, 46, 46, 46, 46, 46, 80, // 46 + 46, 46, 46, 46, 46, 46, 46, 46, // 46 + 40, 40, 46, 46, 46, 46, 81, 81, // 46 + 81, 81, 81, 81, 81, 81, 81, 81, // 46 + 46, 46, 46, 46, 46, 46, 46, 46, // 46 + 46, 46, 46, 46, 46, 46, 46, 46, // 46 + 46, 40, 40, 40, 40, 40, 40, 40, // 47 + 40, 40, 40, 40, 40, 40, 40, 40, // 47 + 40, 40, 40, 40, 40, 40, 40, 40, // 47 + 40, 40, 40, 40, 40, 40, 40, 40, // 47 + 40, 40, 40, 40, 40, 40, 40, 40, // 47 + 40, 40, 40, 40, 40, 40, 40, 3, // 47 + 40, 60, 40, 40, 60, 60, 60, 60, // 47 + 60, 60, 60, 46, 46, 46, 46, 4, // 47 + 40, 40, 40, 40, 40, 40, 59, 60, // 48 + 60, 60, 60, 60, 60, 60, 60, 15, // 48 + 9, 9, 9, 9, 9, 9, 9, 9, // 48 + 9, 9, 3, 3, 46, 46, 46, 46, // 48 + 46, 46, 46, 46, 46, 46, 46, 46, // 48 + 46, 46, 46, 46, 46, 46, 46, 46, // 48 + 46, 46, 46, 46, 46, 46, 46, 46, // 48 + 46, 46, 46, 46, 46, 46, 46, 46, // 48 + 46, 40, 40, 46, 40, 46, 46, 40, // 49 + 40, 46, 40, 46, 46, 40, 46, 46, // 49 + 46, 46, 46, 46, 40, 40, 40, 40, // 49 + 46, 40, 40, 40, 40, 40, 40, 40, // 49 + 46, 40, 40, 40, 46, 40, 46, 40, // 49 + 46, 46, 40, 40, 46, 40, 40, 3, // 49 + 40, 60, 40, 40, 60, 60, 60, 60, // 49 + 60, 60, 46, 60, 60, 40, 46, 46, // 49 + 40, 40, 40, 40, 40, 46, 59, 46, // 50 + 60, 60, 60, 60, 60, 60, 46, 46, // 50 + 9, 9, 9, 9, 9, 9, 9, 9, // 50 + 9, 9, 46, 46, 40, 40, 46, 46, // 50 + 46, 46, 46, 46, 46, 46, 46, 46, // 50 + 46, 46, 46, 46, 46, 46, 46, 46, // 50 + 46, 46, 46, 46, 46, 46, 46, 46, // 50 + 46, 46, 46, 46, 46, 46, 46, 46, // 50 + 15, 15, 15, 15, 3, 3, 3, 3, // 51 + 3, 3, 3, 3, 3, 3, 3, 3, // 51 + 3, 3, 3, 15, 15, 15, 15, 15, // 51 + 60, 60, 15, 15, 15, 15, 15, 15, // 51 + 78, 78, 78, 78, 78, 78, 78, 78, // 51 + 78, 78, 85, 85, 85, 85, 85, 85, // 51 + 85, 85, 85, 85, 15, 60, 15, 60, // 51 + 15, 60, 5, 6, 5, 6, 80, 80, // 51 + 40, 40, 40, 40, 40, 40, 40, 40, // 52 + 46, 40, 40, 40, 40, 40, 40, 40, // 52 + 40, 40, 40, 40, 40, 40, 40, 40, // 52 + 40, 40, 40, 40, 40, 40, 40, 40, // 52 + 40, 40, 40, 40, 40, 40, 40, 40, // 52 + 40, 40, 46, 46, 46, 46, 46, 46, // 52 + 46, 60, 60, 60, 60, 60, 60, 60, // 52 + 60, 60, 60, 60, 60, 60, 60, 80, // 52 + 60, 60, 60, 60, 60, 3, 60, 60, // 53 + 60, 60, 60, 60, 46, 46, 46, 46, // 53 + 60, 60, 60, 60, 60, 60, 46, 60, // 53 + 46, 60, 60, 60, 60, 60, 60, 60, // 53 + 60, 60, 60, 60, 60, 60, 60, 60, // 53 + 60, 60, 60, 60, 60, 60, 46, 46, // 53 + 46, 60, 60, 60, 60, 60, 60, 60, // 53 + 46, 60, 46, 46, 46, 46, 46, 46, // 53 + 46, 46, 46, 46, 46, 46, 46, 46, // 54 + 46, 46, 46, 46, 46, 46, 46, 46, // 54 + 46, 46, 46, 46, 46, 46, 46, 46, // 54 + 46, 46, 46, 46, 46, 46, 46, 46, // 54 + 76, 76, 76, 76, 76, 76, 76, 76, // 54 + 76, 76, 76, 76, 76, 76, 76, 76, // 54 + 76, 76, 76, 76, 76, 76, 76, 76, // 54 + 76, 76, 76, 76, 76, 76, 76, 76, // 54 + 76, 76, 76, 76, 76, 76, 46, 46, // 55 + 46, 46, 46, 46, 46, 46, 46, 46, // 55 + 16, 16, 16, 16, 16, 16, 16, 16, // 55 + 16, 16, 16, 16, 16, 16, 16, 16, // 55 + 16, 16, 16, 16, 16, 16, 16, 16, // 55 + 16, 16, 16, 16, 16, 16, 16, 16, // 55 + 16, 16, 16, 16, 16, 16, 16, 46, // 55 + 46, 46, 46, 3, 46, 46, 46, 46, // 55 + 40, 40, 40, 40, 40, 40, 40, 40, // 56 + 40, 40, 40, 40, 40, 40, 40, 40, // 56 + 40, 40, 40, 40, 40, 40, 40, 40, // 56 + 40, 40, 40, 40, 40, 40, 40, 40, // 56 + 40, 40, 40, 40, 40, 40, 40, 40, // 56 + 40, 40, 40, 40, 40, 40, 40, 40, // 56 + 40, 40, 40, 40, 40, 40, 40, 40, // 56 + 40, 40, 40, 40, 40, 40, 40, 40, // 56 + 40, 40, 40, 40, 40, 40, 40, 40, // 57 + 40, 40, 40, 40, 40, 40, 40, 40, // 57 + 40, 40, 40, 40, 40, 40, 40, 40, // 57 + 40, 40, 46, 46, 46, 46, 46, 40, // 57 + 40, 40, 40, 40, 40, 40, 40, 40, // 57 + 40, 40, 40, 40, 40, 40, 40, 40, // 57 + 40, 40, 40, 40, 40, 40, 40, 40, // 57 + 40, 40, 40, 40, 40, 40, 40, 40, // 57 + 40, 40, 40, 40, 40, 40, 40, 40, // 58 + 40, 40, 40, 40, 40, 40, 40, 40, // 58 + 40, 40, 40, 40, 40, 40, 40, 40, // 58 + 40, 40, 40, 40, 40, 40, 40, 40, // 58 + 40, 40, 40, 46, 46, 46, 46, 46, // 58 + 40, 40, 40, 40, 40, 40, 40, 40, // 58 + 40, 40, 40, 40, 40, 40, 40, 40, // 58 + 40, 40, 40, 40, 40, 40, 40, 40, // 58 + 40, 40, 40, 40, 40, 40, 40, 40, // 59 + 40, 40, 40, 40, 40, 40, 40, 40, // 59 + 40, 40, 40, 40, 40, 40, 40, 40, // 59 + 40, 40, 40, 40, 40, 40, 40, 40, // 59 + 40, 40, 40, 40, 40, 40, 40, 40, // 59 + 40, 40, 40, 40, 40, 40, 40, 40, // 59 + 40, 40, 40, 40, 40, 40, 40, 40, // 59 + 40, 40, 46, 46, 46, 46, 46, 46, // 59 + 23, 24, 23, 24, 23, 24, 23, 24, // 60 + 23, 24, 23, 24, 23, 24, 23, 24, // 60 + 23, 24, 23, 24, 23, 24, 23, 24, // 60 + 23, 24, 23, 24, 23, 24, 23, 24, // 60 + 23, 24, 23, 24, 23, 24, 23, 24, // 60 + 23, 24, 23, 24, 23, 24, 23, 24, // 60 + 23, 24, 23, 24, 23, 24, 23, 24, // 60 + 23, 24, 23, 24, 23, 24, 23, 24, // 60 + 23, 24, 23, 24, 23, 24, 23, 24, // 61 + 23, 24, 23, 24, 23, 24, 23, 24, // 61 + 23, 24, 23, 24, 23, 24, 16, 16, // 61 + 16, 16, 16, 16, 46, 46, 46, 46, // 61 + 23, 24, 23, 24, 23, 24, 23, 24, // 61 + 23, 24, 23, 24, 23, 24, 23, 24, // 61 + 23, 24, 23, 24, 23, 24, 23, 24, // 61 + 23, 24, 23, 24, 23, 24, 23, 24, // 61 + 23, 24, 23, 24, 23, 24, 23, 24, // 62 + 23, 24, 23, 24, 23, 24, 23, 24, // 62 + 23, 24, 23, 24, 23, 24, 23, 24, // 62 + 23, 24, 23, 24, 23, 24, 23, 24, // 62 + 23, 24, 23, 24, 23, 24, 23, 24, // 62 + 23, 24, 23, 24, 23, 24, 23, 24, // 62 + 23, 24, 23, 24, 23, 24, 23, 24, // 62 + 23, 24, 46, 46, 46, 46, 46, 46, // 62 + 86, 86, 86, 86, 86, 86, 86, 86, // 63 + 87, 87, 87, 87, 87, 87, 87, 87, // 63 + 86, 86, 86, 86, 86, 86, 46, 46, // 63 + 87, 87, 87, 87, 87, 87, 46, 46, // 63 + 86, 86, 86, 86, 86, 86, 86, 86, // 63 + 87, 87, 87, 87, 87, 87, 87, 87, // 63 + 86, 86, 86, 86, 86, 86, 86, 86, // 63 + 87, 87, 87, 87, 87, 87, 87, 87, // 63 + 86, 86, 86, 86, 86, 86, 46, 46, // 64 + 87, 87, 87, 87, 87, 87, 46, 46, // 64 + 16, 86, 16, 86, 16, 86, 16, 86, // 64 + 46, 87, 46, 87, 46, 87, 46, 87, // 64 + 86, 86, 86, 86, 86, 86, 86, 86, // 64 + 87, 87, 87, 87, 87, 87, 87, 87, // 64 + 88, 88, 89, 89, 89, 89, 90, 90, // 64 + 91, 91, 92, 92, 93, 93, 46, 46, // 64 + 86, 86, 86, 86, 86, 86, 86, 86, // 65 + 87, 87, 87, 87, 87, 87, 87, 87, // 65 + 86, 86, 86, 86, 86, 86, 86, 86, // 65 + 87, 87, 87, 87, 87, 87, 87, 87, // 65 + 86, 86, 86, 86, 86, 86, 86, 86, // 65 + 87, 87, 87, 87, 87, 87, 87, 87, // 65 + 86, 86, 16, 94, 16, 46, 16, 16, // 65 + 87, 87, 95, 95, 96, 11, 38, 11, // 65 + 11, 11, 16, 94, 16, 46, 16, 16, // 66 + 97, 97, 97, 97, 96, 11, 11, 11, // 66 + 86, 86, 16, 16, 46, 46, 16, 16, // 66 + 87, 87, 98, 98, 46, 11, 11, 11, // 66 + 86, 86, 16, 16, 16, 99, 16, 16, // 66 + 87, 87, 100, 100, 101, 11, 11, 11, // 66 + 46, 46, 16, 94, 16, 46, 16, 16, // 66 + 102, 102, 103, 103, 96, 11, 11, 46, // 66 + 2, 2, 2, 2, 2, 2, 2, 2, // 67 + 2, 2, 2, 2, 104, 104, 104, 104, // 67 + 8, 8, 8, 8, 8, 8, 3, 3, // 67 + 5, 6, 5, 5, 5, 6, 5, 5, // 67 + 3, 3, 3, 3, 3, 3, 3, 3, // 67 + 105, 106, 104, 104, 104, 104, 104, 46, // 67 + 3, 3, 3, 3, 3, 3, 3, 3, // 67 + 3, 5, 6, 3, 3, 3, 3, 12, // 67 + 12, 3, 3, 3, 7, 5, 6, 46, // 68 + 46, 46, 46, 46, 46, 46, 46, 46, // 68 + 46, 46, 46, 46, 46, 46, 46, 46, // 68 + 46, 46, 46, 46, 46, 46, 46, 46, // 68 + 46, 46, 46, 46, 46, 46, 46, 46, // 68 + 46, 46, 104, 104, 104, 104, 104, 104, // 68 + 17, 46, 46, 46, 17, 17, 17, 17, // 68 + 17, 17, 7, 7, 7, 5, 6, 16, // 68 + 107, 107, 107, 107, 107, 107, 107, 107, // 69 + 107, 107, 7, 7, 7, 5, 6, 46, // 69 + 46, 46, 46, 46, 46, 46, 46, 46, // 69 + 46, 46, 46, 46, 46, 46, 46, 46, // 69 + 4, 4, 4, 4, 4, 4, 4, 4, // 69 + 4, 4, 4, 4, 46, 46, 46, 46, // 69 + 46, 46, 46, 46, 46, 46, 46, 46, // 69 + 46, 46, 46, 46, 46, 46, 46, 46, // 69 + 46, 46, 46, 46, 46, 46, 46, 46, // 70 + 46, 46, 46, 46, 46, 46, 46, 46, // 70 + 60, 60, 60, 60, 60, 60, 60, 60, // 70 + 60, 60, 60, 60, 60, 79, 79, 79, // 70 + 79, 60, 46, 46, 46, 46, 46, 46, // 70 + 46, 46, 46, 46, 46, 46, 46, 46, // 70 + 46, 46, 46, 46, 46, 46, 46, 46, // 70 + 46, 46, 46, 46, 46, 46, 46, 46, // 70 + 15, 15, 38, 15, 15, 15, 15, 38, // 71 + 15, 15, 16, 38, 38, 38, 16, 16, // 71 + 38, 38, 38, 16, 15, 38, 15, 15, // 71 + 38, 38, 38, 38, 38, 38, 15, 15, // 71 + 15, 15, 15, 15, 38, 15, 38, 15, // 71 + 38, 15, 38, 38, 38, 38, 16, 16, // 71 + 38, 38, 15, 38, 16, 40, 40, 40, // 71 + 40, 46, 46, 46, 46, 46, 46, 46, // 71 + 46, 46, 46, 46, 46, 46, 46, 46, // 72 + 46, 46, 46, 46, 46, 46, 46, 46, // 72 + 46, 46, 46, 19, 19, 19, 19, 19, // 72 + 19, 19, 19, 19, 19, 19, 19, 108, // 72 + 109, 109, 109, 109, 109, 109, 109, 109, // 72 + 109, 109, 109, 109, 110, 110, 110, 110, // 72 + 111, 111, 111, 111, 111, 111, 111, 111, // 72 + 111, 111, 111, 111, 112, 112, 112, 112, // 72 + 113, 113, 113, 46, 46, 46, 46, 46, // 73 + 46, 46, 46, 46, 46, 46, 46, 46, // 73 + 7, 7, 7, 7, 7, 15, 15, 15, // 73 + 15, 15, 15, 15, 15, 15, 15, 15, // 73 + 15, 15, 15, 15, 15, 15, 15, 15, // 73 + 15, 15, 15, 15, 15, 15, 15, 15, // 73 + 15, 15, 15, 15, 15, 15, 15, 15, // 73 + 15, 15, 15, 15, 15, 15, 15, 15, // 73 + 15, 15, 15, 15, 15, 15, 15, 15, // 74 + 15, 15, 15, 15, 15, 15, 15, 15, // 74 + 15, 15, 7, 15, 7, 15, 15, 15, // 74 + 15, 15, 15, 15, 15, 15, 15, 15, // 74 + 15, 15, 15, 15, 15, 15, 15, 15, // 74 + 15, 15, 15, 46, 46, 46, 46, 46, // 74 + 46, 46, 46, 46, 46, 46, 46, 46, // 74 + 46, 46, 46, 46, 46, 46, 46, 46, // 74 + 7, 7, 7, 7, 7, 7, 7, 7, // 75 + 7, 7, 7, 7, 7, 7, 7, 7, // 75 + 7, 7, 7, 7, 7, 7, 7, 7, // 75 + 7, 7, 7, 7, 7, 7, 7, 7, // 75 + 7, 7, 7, 7, 7, 7, 7, 7, // 75 + 7, 7, 7, 7, 7, 7, 7, 7, // 75 + 7, 7, 7, 7, 7, 7, 7, 7, // 75 + 7, 7, 7, 7, 7, 7, 7, 7, // 75 + 7, 7, 7, 7, 7, 7, 7, 7, // 76 + 7, 7, 7, 7, 7, 7, 7, 7, // 76 + 7, 7, 7, 7, 7, 7, 7, 7, // 76 + 7, 7, 7, 7, 7, 7, 7, 7, // 76 + 7, 7, 7, 7, 7, 7, 7, 7, // 76 + 7, 7, 7, 7, 7, 7, 7, 7, // 76 + 7, 7, 46, 46, 46, 46, 46, 46, // 76 + 46, 46, 46, 46, 46, 46, 46, 46, // 76 + 15, 46, 15, 15, 15, 15, 15, 15, // 77 + 7, 7, 7, 7, 15, 15, 15, 15, // 77 + 15, 15, 15, 15, 15, 15, 15, 15, // 77 + 15, 15, 15, 15, 15, 15, 15, 15, // 77 + 7, 7, 15, 15, 15, 15, 15, 15, // 77 + 15, 5, 6, 15, 15, 15, 15, 15, // 77 + 15, 15, 15, 15, 15, 15, 15, 15, // 77 + 15, 15, 15, 15, 15, 15, 15, 15, // 77 + 15, 15, 15, 15, 15, 15, 15, 15, // 78 + 15, 15, 15, 15, 15, 15, 15, 15, // 78 + 15, 15, 15, 15, 15, 15, 15, 15, // 78 + 15, 15, 15, 15, 15, 15, 15, 15, // 78 + 15, 15, 15, 15, 15, 15, 15, 15, // 78 + 15, 15, 15, 15, 15, 15, 15, 15, // 78 + 15, 15, 15, 15, 15, 15, 15, 15, // 78 + 15, 15, 15, 46, 46, 46, 46, 46, // 78 + 15, 15, 15, 15, 15, 15, 15, 15, // 79 + 15, 15, 15, 15, 15, 15, 15, 15, // 79 + 15, 15, 15, 15, 15, 15, 15, 15, // 79 + 15, 15, 15, 15, 15, 15, 15, 15, // 79 + 15, 15, 15, 15, 15, 46, 46, 46, // 79 + 46, 46, 46, 46, 46, 46, 46, 46, // 79 + 46, 46, 46, 46, 46, 46, 46, 46, // 79 + 46, 46, 46, 46, 46, 46, 46, 46, // 79 + 15, 15, 15, 15, 15, 15, 15, 15, // 80 + 15, 15, 15, 46, 46, 46, 46, 46, // 80 + 46, 46, 46, 46, 46, 46, 46, 46, // 80 + 46, 46, 46, 46, 46, 46, 46, 46, // 80 + 114, 114, 114, 114, 114, 114, 114, 114, // 80 + 114, 114, 114, 114, 114, 114, 114, 114, // 80 + 114, 114, 114, 114, 82, 82, 82, 82, // 80 + 82, 82, 82, 82, 82, 82, 82, 82, // 80 + 82, 82, 82, 82, 82, 82, 82, 82, // 81 + 115, 115, 115, 115, 115, 115, 115, 115, // 81 + 115, 115, 115, 115, 115, 115, 115, 115, // 81 + 115, 115, 115, 115, 15, 15, 15, 15, // 81 + 15, 15, 15, 15, 15, 15, 15, 15, // 81 + 15, 15, 15, 15, 15, 15, 15, 15, // 81 + 15, 15, 15, 15, 15, 15, 116, 116, // 81 + 116, 116, 116, 116, 116, 116, 116, 116, // 81 + 116, 116, 116, 116, 116, 116, 116, 116, // 82 + 116, 116, 116, 116, 116, 116, 116, 116, // 82 + 117, 117, 117, 117, 117, 117, 117, 117, // 82 + 117, 117, 117, 117, 117, 117, 117, 117, // 82 + 117, 117, 117, 117, 117, 117, 117, 117, // 82 + 117, 117, 118, 46, 46, 46, 46, 46, // 82 + 46, 46, 46, 46, 46, 46, 46, 46, // 82 + 46, 46, 46, 46, 46, 46, 46, 46, // 82 + 15, 15, 15, 15, 15, 15, 15, 15, // 83 + 15, 15, 15, 15, 15, 15, 15, 15, // 83 + 15, 15, 15, 15, 15, 15, 15, 15, // 83 + 15, 15, 15, 15, 15, 15, 15, 15, // 83 + 15, 15, 15, 15, 15, 15, 15, 15, // 83 + 15, 15, 15, 15, 15, 15, 15, 15, // 83 + 15, 15, 15, 15, 15, 15, 15, 15, // 83 + 15, 15, 15, 15, 15, 15, 15, 15, // 83 + 15, 15, 15, 15, 15, 15, 15, 15, // 84 + 15, 15, 15, 15, 15, 15, 15, 15, // 84 + 15, 15, 15, 15, 15, 15, 46, 46, // 84 + 46, 46, 46, 46, 46, 46, 46, 46, // 84 + 15, 15, 15, 15, 15, 15, 15, 15, // 84 + 15, 15, 15, 15, 15, 15, 15, 15, // 84 + 15, 15, 15, 15, 15, 15, 15, 15, // 84 + 15, 15, 15, 15, 15, 15, 15, 15, // 84 + 15, 15, 15, 15, 15, 15, 15, 15, // 85 + 15, 15, 15, 15, 15, 15, 15, 15, // 85 + 15, 15, 15, 15, 15, 15, 15, 15, // 85 + 15, 15, 15, 15, 15, 15, 15, 15, // 85 + 15, 15, 15, 15, 15, 15, 15, 15, // 85 + 15, 15, 15, 15, 15, 15, 15, 15, // 85 + 46, 46, 46, 46, 46, 46, 46, 46, // 85 + 46, 46, 46, 46, 46, 46, 46, 46, // 85 + 15, 15, 15, 15, 15, 15, 15, 15, // 86 + 15, 15, 15, 15, 15, 15, 15, 15, // 86 + 15, 15, 15, 15, 46, 46, 46, 46, // 86 + 46, 46, 15, 15, 15, 15, 15, 15, // 86 + 15, 15, 15, 15, 15, 15, 15, 15, // 86 + 15, 15, 15, 15, 15, 15, 15, 15, // 86 + 15, 15, 15, 15, 15, 15, 15, 15, // 86 + 15, 15, 15, 15, 15, 15, 15, 15, // 86 + 46, 15, 15, 15, 15, 46, 15, 15, // 87 + 15, 15, 46, 46, 15, 15, 15, 15, // 87 + 15, 15, 15, 15, 15, 15, 15, 15, // 87 + 15, 15, 15, 15, 15, 15, 15, 15, // 87 + 15, 15, 15, 15, 15, 15, 15, 15, // 87 + 46, 15, 15, 15, 15, 15, 15, 15, // 87 + 15, 15, 15, 15, 15, 15, 15, 15, // 87 + 15, 15, 15, 15, 15, 15, 15, 15, // 87 + 15, 15, 15, 15, 15, 15, 15, 15, // 88 + 15, 15, 15, 15, 46, 15, 46, 15, // 88 + 15, 15, 15, 46, 46, 46, 15, 46, // 88 + 15, 15, 15, 15, 15, 15, 15, 46, // 88 + 46, 15, 15, 15, 15, 15, 15, 15, // 88 + 46, 46, 46, 46, 46, 46, 46, 46, // 88 + 46, 46, 46, 46, 46, 46, 119, 119, // 88 + 119, 119, 119, 119, 119, 119, 119, 119, // 88 + 114, 114, 114, 114, 114, 114, 114, 114, // 89 + 114, 114, 83, 83, 83, 83, 83, 83, // 89 + 83, 83, 83, 83, 15, 46, 46, 46, // 89 + 15, 15, 15, 15, 15, 15, 15, 15, // 89 + 15, 15, 15, 15, 15, 15, 15, 15, // 89 + 15, 15, 15, 15, 15, 15, 15, 15, // 89 + 46, 15, 15, 15, 15, 15, 15, 15, // 89 + 15, 15, 15, 15, 15, 15, 15, 46, // 89 + 2, 3, 3, 3, 15, 59, 3, 120, // 90 + 5, 6, 5, 6, 5, 6, 5, 6, // 90 + 5, 6, 15, 15, 5, 6, 5, 6, // 90 + 5, 6, 5, 6, 8, 5, 6, 5, // 90 + 15, 121, 121, 121, 121, 121, 121, 121, // 90 + 121, 121, 60, 60, 60, 60, 60, 60, // 90 + 8, 59, 59, 59, 59, 59, 15, 15, // 90 + 46, 46, 46, 46, 46, 46, 46, 15, // 90 + 46, 40, 40, 40, 40, 40, 40, 40, // 91 + 40, 40, 40, 40, 40, 40, 40, 40, // 91 + 40, 40, 40, 40, 40, 40, 40, 40, // 91 + 40, 40, 40, 40, 40, 40, 40, 40, // 91 + 40, 40, 40, 40, 40, 40, 40, 40, // 91 + 40, 40, 40, 40, 40, 40, 40, 40, // 91 + 40, 40, 40, 40, 40, 40, 40, 40, // 91 + 40, 40, 40, 40, 40, 40, 40, 40, // 91 + 40, 40, 40, 40, 40, 40, 40, 40, // 92 + 40, 40, 40, 40, 40, 40, 40, 40, // 92 + 40, 40, 40, 40, 40, 46, 46, 46, // 92 + 46, 60, 60, 59, 59, 59, 59, 46, // 92 + 46, 40, 40, 40, 40, 40, 40, 40, // 92 + 40, 40, 40, 40, 40, 40, 40, 40, // 92 + 40, 40, 40, 40, 40, 40, 40, 40, // 92 + 40, 40, 40, 40, 40, 40, 40, 40, // 92 + 40, 40, 40, 40, 40, 40, 40, 40, // 93 + 40, 40, 40, 40, 40, 40, 40, 40, // 93 + 40, 40, 40, 40, 40, 40, 40, 40, // 93 + 40, 40, 40, 40, 40, 40, 40, 40, // 93 + 40, 40, 40, 40, 40, 40, 40, 40, // 93 + 40, 40, 40, 40, 40, 40, 40, 40, // 93 + 40, 40, 40, 40, 40, 40, 40, 40, // 93 + 40, 40, 40, 3, 59, 59, 59, 46, // 93 + 46, 46, 46, 46, 46, 40, 40, 40, // 94 + 40, 40, 40, 40, 40, 40, 40, 40, // 94 + 40, 40, 40, 40, 40, 40, 40, 40, // 94 + 40, 40, 40, 40, 40, 40, 40, 40, // 94 + 40, 40, 40, 40, 40, 40, 40, 40, // 94 + 40, 40, 40, 40, 40, 46, 46, 46, // 94 + 46, 40, 40, 40, 40, 40, 40, 40, // 94 + 40, 40, 40, 40, 40, 40, 40, 40, // 94 + 40, 40, 40, 40, 40, 40, 40, 40, // 95 + 40, 40, 40, 40, 40, 40, 40, 46, // 95 + 15, 15, 85, 85, 85, 85, 15, 15, // 95 + 15, 15, 15, 15, 15, 15, 15, 15, // 95 + 46, 46, 46, 46, 46, 46, 46, 46, // 95 + 46, 46, 46, 46, 46, 46, 46, 46, // 95 + 46, 46, 46, 46, 46, 46, 46, 46, // 95 + 46, 46, 46, 46, 46, 46, 46, 46, // 95 + 15, 15, 15, 15, 15, 15, 15, 15, // 96 + 15, 15, 15, 15, 15, 15, 15, 15, // 96 + 15, 15, 15, 15, 15, 15, 15, 15, // 96 + 15, 15, 15, 15, 15, 46, 46, 46, // 96 + 85, 85, 85, 85, 85, 85, 85, 85, // 96 + 85, 85, 15, 15, 15, 15, 15, 15, // 96 + 15, 15, 15, 15, 15, 15, 15, 15, // 96 + 15, 15, 15, 15, 15, 15, 15, 15, // 96 + 15, 15, 15, 15, 46, 46, 46, 46, // 97 + 46, 46, 46, 46, 46, 46, 46, 46, // 97 + 46, 46, 46, 46, 46, 46, 46, 46, // 97 + 46, 46, 46, 46, 46, 46, 46, 46, // 97 + 15, 15, 15, 15, 15, 15, 15, 15, // 97 + 15, 15, 15, 15, 15, 15, 15, 15, // 97 + 15, 15, 15, 15, 15, 15, 15, 15, // 97 + 15, 15, 15, 15, 46, 46, 46, 15, // 97 + 114, 114, 114, 114, 114, 114, 114, 114, // 98 + 114, 114, 15, 15, 15, 15, 15, 15, // 98 + 15, 15, 15, 15, 15, 15, 15, 15, // 98 + 15, 15, 15, 15, 15, 15, 15, 15, // 98 + 15, 15, 15, 15, 15, 15, 15, 15, // 98 + 15, 15, 15, 15, 15, 15, 15, 15, // 98 + 15, 46, 46, 46, 46, 46, 46, 46, // 98 + 46, 46, 46, 46, 46, 46, 46, 46, // 98 + 15, 15, 15, 15, 15, 15, 15, 15, // 99 + 15, 15, 15, 15, 46, 46, 46, 46, // 99 + 15, 15, 15, 15, 15, 15, 15, 15, // 99 + 15, 15, 15, 15, 15, 15, 15, 15, // 99 + 15, 15, 15, 15, 15, 15, 15, 15, // 99 + 15, 15, 15, 15, 15, 15, 15, 15, // 99 + 15, 15, 15, 15, 15, 15, 15, 15, // 99 + 15, 15, 15, 15, 15, 15, 15, 46, // 99 + 15, 15, 15, 15, 15, 15, 15, 15, // 100 + 15, 15, 15, 15, 15, 15, 15, 15, // 100 + 15, 15, 15, 15, 15, 15, 15, 15, // 100 + 15, 15, 15, 15, 15, 15, 15, 15, // 100 + 15, 15, 15, 15, 15, 15, 15, 15, // 100 + 15, 15, 15, 15, 15, 15, 15, 15, // 100 + 15, 15, 15, 15, 15, 15, 15, 46, // 100 + 46, 46, 46, 15, 15, 15, 15, 15, // 100 + 15, 15, 15, 15, 15, 15, 15, 15, // 101 + 15, 15, 15, 15, 15, 15, 15, 15, // 101 + 15, 15, 15, 15, 15, 15, 15, 15, // 101 + 15, 15, 15, 15, 15, 15, 46, 46, // 101 + 15, 15, 15, 15, 15, 15, 15, 15, // 101 + 15, 15, 15, 15, 15, 15, 15, 15, // 101 + 15, 15, 15, 15, 15, 15, 15, 15, // 101 + 15, 15, 15, 15, 15, 15, 15, 46, // 101 + 40, 40, 40, 40, 40, 40, 40, 40, // 102 + 40, 40, 40, 40, 40, 40, 40, 40, // 102 + 40, 40, 40, 40, 40, 40, 40, 40, // 102 + 40, 40, 40, 40, 40, 40, 40, 40, // 102 + 40, 40, 40, 40, 40, 40, 46, 46, // 102 + 46, 46, 46, 46, 46, 46, 46, 46, // 102 + 46, 46, 46, 46, 46, 46, 46, 46, // 102 + 46, 46, 46, 46, 46, 46, 46, 46, // 102 + 40, 40, 40, 40, 40, 40, 40, 40, // 103 + 40, 40, 40, 40, 40, 40, 40, 40, // 103 + 40, 40, 40, 40, 40, 40, 40, 40, // 103 + 40, 40, 40, 40, 40, 40, 40, 40, // 103 + 40, 40, 40, 40, 46, 46, 46, 46, // 103 + 46, 46, 46, 46, 46, 46, 46, 46, // 103 + 46, 46, 46, 46, 46, 46, 46, 46, // 103 + 46, 46, 46, 46, 46, 46, 46, 46, // 103 + 122, 122, 122, 122, 122, 122, 122, 122, // 104 + 122, 122, 122, 122, 122, 122, 122, 122, // 104 + 122, 122, 122, 122, 122, 122, 122, 122, // 104 + 122, 122, 122, 122, 122, 122, 122, 122, // 104 + 122, 122, 122, 122, 122, 122, 122, 122, // 104 + 122, 122, 122, 122, 122, 122, 122, 122, // 104 + 122, 122, 122, 122, 122, 122, 122, 122, // 104 + 122, 122, 122, 122, 122, 122, 122, 122, // 104 + 123, 123, 123, 123, 123, 123, 123, 123, // 105 + 123, 123, 123, 123, 123, 123, 123, 123, // 105 + 123, 123, 123, 123, 123, 123, 123, 123, // 105 + 123, 123, 123, 123, 123, 123, 123, 123, // 105 + 123, 123, 123, 123, 123, 123, 123, 123, // 105 + 123, 123, 123, 123, 123, 123, 123, 123, // 105 + 123, 123, 123, 123, 123, 123, 123, 123, // 105 + 123, 123, 123, 123, 123, 123, 123, 123, // 105 + 40, 40, 40, 40, 40, 40, 40, 40, // 106 + 40, 40, 40, 40, 40, 40, 40, 40, // 106 + 40, 40, 40, 40, 40, 40, 40, 40, // 106 + 40, 40, 40, 40, 40, 40, 40, 40, // 106 + 40, 40, 40, 40, 40, 40, 40, 40, // 106 + 40, 40, 40, 40, 40, 40, 46, 46, // 106 + 46, 46, 46, 46, 46, 46, 46, 46, // 106 + 46, 46, 46, 46, 46, 46, 46, 46, // 106 + 16, 16, 16, 16, 16, 16, 16, 46, // 107 + 46, 46, 46, 46, 46, 46, 46, 46, // 107 + 46, 46, 46, 16, 16, 16, 16, 16, // 107 + 46, 46, 46, 46, 46, 46, 60, 40, // 107 + 40, 40, 40, 40, 40, 40, 40, 40, // 107 + 40, 7, 40, 40, 40, 40, 40, 40, // 107 + 40, 40, 40, 40, 40, 40, 40, 46, // 107 + 40, 40, 40, 40, 40, 46, 40, 46, // 107 + 40, 40, 46, 40, 40, 46, 40, 40, // 108 + 40, 40, 40, 40, 40, 40, 40, 40, // 108 + 40, 40, 40, 40, 40, 40, 40, 40, // 108 + 40, 40, 40, 40, 40, 40, 40, 40, // 108 + 40, 40, 40, 40, 40, 40, 40, 40, // 108 + 40, 40, 40, 40, 40, 40, 40, 40, // 108 + 40, 40, 40, 40, 40, 40, 40, 40, // 108 + 40, 40, 40, 40, 40, 40, 40, 40, // 108 + 40, 40, 40, 40, 40, 40, 40, 40, // 109 + 40, 40, 40, 40, 40, 40, 40, 40, // 109 + 40, 40, 40, 40, 40, 40, 40, 40, // 109 + 40, 40, 40, 40, 40, 40, 40, 40, // 109 + 40, 40, 40, 40, 40, 40, 40, 40, // 109 + 40, 40, 40, 40, 40, 40, 40, 40, // 109 + 40, 40, 46, 46, 46, 46, 46, 46, // 109 + 46, 46, 46, 46, 46, 46, 46, 46, // 109 + 46, 46, 46, 46, 46, 46, 46, 46, // 110 + 46, 46, 46, 46, 46, 46, 46, 46, // 110 + 46, 46, 46, 40, 40, 40, 40, 40, // 110 + 40, 40, 40, 40, 40, 40, 40, 40, // 110 + 40, 40, 40, 40, 40, 40, 40, 40, // 110 + 40, 40, 40, 40, 40, 40, 40, 40, // 110 + 40, 40, 40, 40, 40, 40, 40, 40, // 110 + 40, 40, 40, 40, 40, 40, 40, 40, // 110 + 40, 40, 40, 40, 40, 40, 40, 40, // 111 + 40, 40, 40, 40, 40, 40, 40, 40, // 111 + 40, 40, 40, 40, 40, 40, 40, 40, // 111 + 40, 40, 40, 40, 40, 40, 40, 40, // 111 + 40, 40, 40, 40, 40, 40, 40, 40, // 111 + 40, 40, 40, 40, 40, 40, 40, 40, // 111 + 40, 40, 40, 40, 40, 40, 40, 40, // 111 + 40, 40, 40, 40, 40, 40, 5, 6, // 111 + 46, 46, 46, 46, 46, 46, 46, 46, // 112 + 46, 46, 46, 46, 46, 46, 46, 46, // 112 + 40, 40, 40, 40, 40, 40, 40, 40, // 112 + 40, 40, 40, 40, 40, 40, 40, 40, // 112 + 40, 40, 40, 40, 40, 40, 40, 40, // 112 + 40, 40, 40, 40, 40, 40, 40, 40, // 112 + 40, 40, 40, 40, 40, 40, 40, 40, // 112 + 40, 40, 40, 40, 40, 40, 40, 40, // 112 + 40, 40, 40, 40, 40, 40, 40, 40, // 113 + 40, 40, 40, 40, 40, 40, 40, 40, // 113 + 46, 46, 40, 40, 40, 40, 40, 40, // 113 + 40, 40, 40, 40, 40, 40, 40, 40, // 113 + 40, 40, 40, 40, 40, 40, 40, 40, // 113 + 40, 40, 40, 40, 40, 40, 40, 40, // 113 + 40, 40, 40, 40, 40, 40, 40, 40, // 113 + 40, 40, 40, 40, 40, 40, 40, 40, // 113 + 40, 40, 40, 40, 40, 40, 40, 40, // 114 + 46, 46, 46, 46, 46, 46, 46, 46, // 114 + 46, 46, 46, 46, 46, 46, 46, 46, // 114 + 46, 46, 46, 46, 46, 46, 46, 46, // 114 + 46, 46, 46, 46, 46, 46, 46, 46, // 114 + 46, 46, 46, 46, 46, 46, 46, 46, // 114 + 40, 40, 40, 40, 40, 40, 40, 40, // 114 + 40, 40, 40, 40, 46, 46, 46, 46, // 114 + 46, 46, 46, 46, 46, 46, 46, 46, // 115 + 46, 46, 46, 46, 46, 46, 46, 46, // 115 + 46, 46, 46, 46, 46, 46, 46, 46, // 115 + 46, 46, 46, 46, 46, 46, 46, 46, // 115 + 60, 60, 60, 60, 46, 46, 46, 46, // 115 + 46, 46, 46, 46, 46, 46, 46, 46, // 115 + 3, 8, 8, 12, 12, 5, 6, 5, // 115 + 6, 5, 6, 5, 6, 5, 6, 5, // 115 + 6, 5, 6, 5, 6, 46, 46, 46, // 116 + 46, 3, 3, 3, 3, 12, 12, 12, // 116 + 3, 3, 3, 46, 3, 3, 3, 3, // 116 + 8, 5, 6, 5, 6, 5, 6, 3, // 116 + 3, 3, 7, 8, 7, 7, 7, 46, // 116 + 3, 4, 3, 3, 46, 46, 46, 46, // 116 + 40, 40, 40, 46, 40, 46, 40, 40, // 116 + 40, 40, 40, 40, 40, 40, 40, 40, // 116 + 40, 40, 40, 40, 40, 40, 40, 40, // 117 + 40, 40, 40, 40, 40, 40, 40, 40, // 117 + 40, 40, 40, 40, 40, 40, 40, 40, // 117 + 40, 40, 40, 40, 40, 40, 40, 40, // 117 + 40, 40, 40, 40, 40, 40, 40, 40, // 117 + 40, 40, 40, 40, 40, 40, 40, 40, // 117 + 40, 40, 40, 40, 40, 40, 40, 40, // 117 + 40, 40, 40, 40, 40, 46, 46, 104, // 117 + 46, 3, 3, 3, 4, 3, 3, 3, // 118 + 5, 6, 3, 7, 3, 8, 3, 3, // 118 + 9, 9, 9, 9, 9, 9, 9, 9, // 118 + 9, 9, 3, 3, 7, 7, 7, 3, // 118 + 3, 10, 10, 10, 10, 10, 10, 10, // 118 + 10, 10, 10, 10, 10, 10, 10, 10, // 118 + 10, 10, 10, 10, 10, 10, 10, 10, // 118 + 10, 10, 10, 5, 3, 6, 11, 12, // 118 + 11, 13, 13, 13, 13, 13, 13, 13, // 119 + 13, 13, 13, 13, 13, 13, 13, 13, // 119 + 13, 13, 13, 13, 13, 13, 13, 13, // 119 + 13, 13, 13, 5, 7, 6, 7, 46, // 119 + 46, 3, 5, 6, 3, 3, 40, 40, // 119 + 40, 40, 40, 40, 40, 40, 40, 40, // 119 + 59, 40, 40, 40, 40, 40, 40, 40, // 119 + 40, 40, 40, 40, 40, 40, 40, 40, // 119 + 40, 40, 40, 40, 40, 40, 40, 40, // 120 + 40, 40, 40, 40, 40, 40, 40, 40, // 120 + 40, 40, 40, 40, 40, 40, 40, 40, // 120 + 40, 40, 40, 40, 40, 40, 59, 59, // 120 + 40, 40, 40, 40, 40, 40, 40, 40, // 120 + 40, 40, 40, 40, 40, 40, 40, 40, // 120 + 40, 40, 40, 40, 40, 40, 40, 40, // 120 + 40, 40, 40, 40, 40, 40, 40, 46, // 120 + 46, 46, 40, 40, 40, 40, 40, 40, // 121 + 46, 46, 40, 40, 40, 40, 40, 40, // 121 + 46, 46, 40, 40, 40, 40, 40, 40, // 121 + 46, 46, 40, 40, 40, 46, 46, 46, // 121 + 4, 4, 7, 11, 15, 4, 4, 46, // 121 + 7, 7, 7, 7, 7, 15, 15, 46, // 121 + 46, 46, 46, 46, 46, 46, 46, 46, // 121 + 46, 46, 46, 46, 46, 15, 46, 46 // 121 + }; + + static Int32 A[] = { + 0x0001000F, // 0 Cc, ignorable + 0x0004000F, // 1 Cc, whitespace + 0x0004000C, // 2 Zs, whitespace + 0x00000018, // 3 Po + 0x0006001A, // 4 Sc, currency + 0x00000015, // 5 Ps + 0x00000016, // 6 Pe + 0x00000019, // 7 Sm + 0x00000014, // 8 Pd + 0x00036009, // 9 Nd, identifier part, decimal 16 + 0x0827FE01, // 10 Lu, hasLower (add 32), identifier start, supradecimal 31 + 0x0000001B, // 11 Sk + 0x00050017, // 12 Pc, underscore + 0x0817FE02, // 13 Ll, hasUpper (subtract 32), identifier start, supradecimal 31 + 0x0000000C, // 14 Zs + 0x0000001C, // 15 So + 0x00070002, // 16 Ll, identifier start + 0x0000600B, // 17 No, decimal 16 + 0x0000500B, // 18 No, decimal 8 + 0x0000800B, // 19 No, strange + 0x08270001, // 20 Lu, hasLower (add 32), identifier start + 0x08170002, // 21 Ll, hasUpper (subtract 32), identifier start + 0xE1D70002, // 22 Ll, hasUpper (subtract -121), identifier start + 0x00670001, // 23 Lu, hasLower (add 1), identifier start + 0x00570002, // 24 Ll, hasUpper (subtract 1), identifier start + 0xCE670001, // 25 Lu, hasLower (add -199), identifier start + 0x3A170002, // 26 Ll, hasUpper (subtract 232), identifier start + 0xE1E70001, // 27 Lu, hasLower (add -121), identifier start + 0x4B170002, // 28 Ll, hasUpper (subtract 300), identifier start + 0x34A70001, // 29 Lu, hasLower (add 210), identifier start + 0x33A70001, // 30 Lu, hasLower (add 206), identifier start + 0x33670001, // 31 Lu, hasLower (add 205), identifier start + 0x32A70001, // 32 Lu, hasLower (add 202), identifier start + 0x32E70001, // 33 Lu, hasLower (add 203), identifier start + 0x33E70001, // 34 Lu, hasLower (add 207), identifier start + 0x34E70001, // 35 Lu, hasLower (add 211), identifier start + 0x34670001, // 36 Lu, hasLower (add 209), identifier start + 0x35670001, // 37 Lu, hasLower (add 213), identifier start + 0x00070001, // 38 Lu, identifier start + 0x36A70001, // 39 Lu, hasLower (add 218), identifier start + 0x00070005, // 40 Lo, identifier start + 0x36670001, // 41 Lu, hasLower (add 217), identifier start + 0x36E70001, // 42 Lu, hasLower (add 219), identifier start + 0x00AF0001, // 43 Lu, hasLower (add 2), hasTitle, identifier start + 0x007F0003, // 44 Lt, hasUpper (subtract 1), hasLower (add 1), hasTitle, identifier start + 0x009F0002, // 45 Ll, hasUpper (subtract 2), hasTitle, identifier start + 0x00000000, // 46 unassigned + 0x34970002, // 47 Ll, hasUpper (subtract 210), identifier start + 0x33970002, // 48 Ll, hasUpper (subtract 206), identifier start + 0x33570002, // 49 Ll, hasUpper (subtract 205), identifier start + 0x32970002, // 50 Ll, hasUpper (subtract 202), identifier start + 0x32D70002, // 51 Ll, hasUpper (subtract 203), identifier start + 0x33D70002, // 52 Ll, hasUpper (subtract 207), identifier start + 0x34570002, // 53 Ll, hasUpper (subtract 209), identifier start + 0x34D70002, // 54 Ll, hasUpper (subtract 211), identifier start + 0x35570002, // 55 Ll, hasUpper (subtract 213), identifier start + 0x36970002, // 56 Ll, hasUpper (subtract 218), identifier start + 0x36570002, // 57 Ll, hasUpper (subtract 217), identifier start + 0x36D70002, // 58 Ll, hasUpper (subtract 219), identifier start + 0x00070004, // 59 Lm, identifier start + 0x00030006, // 60 Mn, identifier part + 0x09A70001, // 61 Lu, hasLower (add 38), identifier start + 0x09670001, // 62 Lu, hasLower (add 37), identifier start + 0x10270001, // 63 Lu, hasLower (add 64), identifier start + 0x0FE70001, // 64 Lu, hasLower (add 63), identifier start + 0x09970002, // 65 Ll, hasUpper (subtract 38), identifier start + 0x09570002, // 66 Ll, hasUpper (subtract 37), identifier start + 0x10170002, // 67 Ll, hasUpper (subtract 64), identifier start + 0x0FD70002, // 68 Ll, hasUpper (subtract 63), identifier start + 0x0F970002, // 69 Ll, hasUpper (subtract 62), identifier start + 0x0E570002, // 70 Ll, hasUpper (subtract 57), identifier start + 0x0BD70002, // 71 Ll, hasUpper (subtract 47), identifier start + 0x0D970002, // 72 Ll, hasUpper (subtract 54), identifier start + 0x15970002, // 73 Ll, hasUpper (subtract 86), identifier start + 0x14170002, // 74 Ll, hasUpper (subtract 80), identifier start + 0x14270001, // 75 Lu, hasLower (add 80), identifier start + 0x0C270001, // 76 Lu, hasLower (add 48), identifier start + 0x0C170002, // 77 Ll, hasUpper (subtract 48), identifier start + 0x00034009, // 78 Nd, identifier part, decimal 0 + 0x00000007, // 79 Me + 0x00030008, // 80 Mc, identifier part + 0x00037409, // 81 Nd, identifier part, decimal 26 + 0x00005A0B, // 82 No, decimal 13 + 0x00006E0B, // 83 No, decimal 23 + 0x0000740B, // 84 No, decimal 26 + 0x0000000B, // 85 No + 0xFE170002, // 86 Ll, hasUpper (subtract -8), identifier start + 0xFE270001, // 87 Lu, hasLower (add -8), identifier start + 0xED970002, // 88 Ll, hasUpper (subtract -74), identifier start + 0xEA970002, // 89 Ll, hasUpper (subtract -86), identifier start + 0xE7170002, // 90 Ll, hasUpper (subtract -100), identifier start + 0xE0170002, // 91 Ll, hasUpper (subtract -128), identifier start + 0xE4170002, // 92 Ll, hasUpper (subtract -112), identifier start + 0xE0970002, // 93 Ll, hasUpper (subtract -126), identifier start + 0xFDD70002, // 94 Ll, hasUpper (subtract -9), identifier start + 0xEDA70001, // 95 Lu, hasLower (add -74), identifier start + 0xFDE70001, // 96 Lu, hasLower (add -9), identifier start + 0xEAA70001, // 97 Lu, hasLower (add -86), identifier start + 0xE7270001, // 98 Lu, hasLower (add -100), identifier start + 0xFE570002, // 99 Ll, hasUpper (subtract -7), identifier start + 0xE4270001, // 100 Lu, hasLower (add -112), identifier start + 0xFE670001, // 101 Lu, hasLower (add -7), identifier start + 0xE0270001, // 102 Lu, hasLower (add -128), identifier start + 0xE0A70001, // 103 Lu, hasLower (add -126), identifier start + 0x00010010, // 104 Cf, ignorable + 0x0004000D, // 105 Zl, whitespace + 0x0004000E, // 106 Zp, whitespace + 0x0000400B, // 107 No, decimal 0 + 0x0000440B, // 108 No, decimal 2 + 0x0427420A, // 109 Nl, hasLower (add 16), identifier start, decimal 1 + 0x0427800A, // 110 Nl, hasLower (add 16), identifier start, strange + 0x0417620A, // 111 Nl, hasUpper (subtract 16), identifier start, decimal 17 + 0x0417800A, // 112 Nl, hasUpper (subtract 16), identifier start, strange + 0x0007800A, // 113 Nl, identifier start, strange + 0x0000420B, // 114 No, decimal 1 + 0x0000720B, // 115 No, decimal 25 + 0x06A0001C, // 116 So, hasLower (add 26) + 0x0690001C, // 117 So, hasUpper (subtract 26) + 0x00006C0B, // 118 No, decimal 22 + 0x0000560B, // 119 No, decimal 11 + 0x0007720A, // 120 Nl, identifier start, decimal 25 + 0x0007400A, // 121 Nl, identifier start, decimal 0 + 0x00000013, // 122 Cs + 0x00000012 // 123 Co + }; + +inline Field *getField(const char *className, const char *name) +{ + ClassCentral ¢ral = VM::getCentral(); + + ClassFileSummary &summ = central.addClass(className); + + Class *clazz = const_cast(static_cast(summ.getThisClass())); + + Field *field = &clazz->getDeclaredField(name); + + return field; +} + +inline void setStaticField(const char *name, const char *className, JavaObject &val) +{ + Field *field = getField(className, name); + + field->set(0, val); +} + + +extern "C" { +/* + * Class : java/lang/Character + * Method : initializeCharacterClass + * Signature : ()V + */ +NS_EXPORT NS_NATIVECALL(void) +Netscape_Java_java_lang_Character_initializeCharacterClass() +{ + /* We could avoid the copies by creating dummying up JavaArray's, but I + * want this to be as less a kludge as possible. We can do that + * if we really want better performance -- kini + */ + JavaArray *XArray = (JavaArray *) sysNewByteArray(sizeof(X)); + memcpy((char *) XArray+arrayEltsOffset(tkChar), X, sizeof(X)); + setStaticField("X", "java/lang/Character", *XArray); + + JavaArray *YArray = (JavaArray *) sysNewByteArray(sizeof(Y)); + memcpy((char *) YArray+arrayEltsOffset(tkChar), Y, sizeof(Y)); + setStaticField("Y", "java/lang/Character", *YArray); + + JavaArray *AArray = (JavaArray *) sysNewIntArray(sizeof(A)); + memcpy((char *) AArray+arrayEltsOffset(tkChar), A, sizeof(A)); + setStaticField("A", "java/lang/Character", *AArray); +} + + +} /* extern "C" */ + + diff --git a/ef/Packages/java/lang/nativesrc/Class.cpp b/ef/Packages/java/lang/nativesrc/Class.cpp new file mode 100644 index 000000000000..f7a542059c1d --- /dev/null +++ b/ef/Packages/java/lang/nativesrc/Class.cpp @@ -0,0 +1,721 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#include "java_lang_Class.h" +#include "java_lang_reflect_Field.h" +#include "java_lang_reflect_Method.h" +#include "java_lang_reflect_Constructor.h" + +#include "JavaVM.h" +#include "JavaString.h" + +#include "prprf.h" +#include "SysCallsRuntime.h" +#include "StackWalker.h" + +enum FieldOrMethodCategory { + fieldOrMethodCategoryPublic=0, + fieldOrMethodCategoryDeclared=1 +}; + +static inline void throwClassVerifyException(VerifyError err) +{ + // FIXME Need to be more specific in the exceptions we throw here + switch (err.cause) { + case VerifyError::noClassDefFound: + case VerifyError::badClassFormat: + default: + sysThrowNamedException("java/lang/ClassNotFoundException"); + break; + + case VerifyError::illegalAccess: + sysThrowNamedException("java/lang/IllegalAccessException"); + break; + } + +} + +static inline void throwClassRuntimeException(RuntimeError err) +{ + // FIXME Need to be more specific in the exceptions we throw here + switch (err.cause) { + case RuntimeError::illegalAccess: + sysThrowNamedException("java/lang/IllegalAccessException"); + break; + + case RuntimeError::nullPointer: + sysThrowNullPointerException(); + break; + + default: + sysThrowNamedException("java/lang/IllegalArgumentException"); + break; + } +} + +extern "C" { + +/* Some interesting things to remember: + * (1) What is passed to all native methods of java/lang/Class is an instance + * of the VM class Class. + * (2) All native routines here do not check for security restrictions; it is + * assumed that security is dealt with at a higher level. + */ + +static inline Type &toType(Java_java_lang_Class &inClass) +{ + Type &type = *(Type *) (&inClass); + return type; +} + +static inline JavaObject &toObject(Java_java_lang_Object &inObject) +{ + return *(Class *)(&inObject); +} + + +/* + * Class : java/lang/Class + * Method : forName + * Signature : (Ljava/lang/String;)Ljava/lang/Class; + */ +NS_EXPORT NS_NATIVECALL(Java_java_lang_Class *) +Netscape_Java_java_lang_Class_forName(Java_java_lang_String *nameString) +{ + if (!nameString) + sysThrowNamedException("java/lang/ClassNotFoundException"); + + ClassCentral ¢ral = VM::getCentral(); + char *name = ((JavaString *) nameString)->convertUtf(); + + // Replace dots with slashes to obtain the fully qualified name of the class. + // central.addClass() expects a fully qualified class name. + for (char *p = name; *p; p++) + if (*p == '.') *p = '/'; + + Class *clz; + try { + clz = static_cast(central.addClass(name).getThisClass()); + } catch(VerifyError err) { + throwClassVerifyException(err); + } catch(RuntimeError err) { + throwClassRuntimeException(err); + } + + /* Free the memory we just allocated */ + JavaString::freeUtf(name); + + return (Java_java_lang_Class *) clz; +} + + +/* + * Class : java/lang/Class + * Method : newInstance + * Signature : ()Ljava/lang/Object; + */ +NS_EXPORT NS_NATIVECALL(Java_java_lang_Object *) +Netscape_Java_java_lang_Class_newInstance(Java_java_lang_Class *inClass) +{ + Type &type = toType(*inClass); + + // We can't instantiate primitive types, arrays or interfaces + if (type.typeKind != tkObject) + sysThrowNamedException("java/lang/InstantiationException"); + + const Class &clazz = asClass(type); + + // Check to see if the caller of the class has package access to this class + Frame thisFrame; + + Method &callerMethod = thisFrame.getCallingJavaMethod(); + ClassOrInterface *callingClass; + + callingClass = callerMethod.getDeclaringClass(); + + bool hasPackageAccess = false; + if (callingClass->package.name == clazz.package.name) + hasPackageAccess = true; + + // Check argument type. Make sure that the class that called this + // method is a class that can access the class clazz. + if (!(clazz.getModifiers() & CR_ACC_PUBLIC) && !hasPackageAccess) + sysThrowNamedException("java/lang/IllegalAccessException"); + + // Make sure that the class is instantiable. The class is + // instantiable if it is not abstract, and has at least one constructor + // that the calling class can access. + if ((clazz.getModifiers() & CR_ACC_ABSTRACT) || clazz.isInterface()) + sysThrowNamedException("java/lang/InstantiationException"); + + const Constructor **constructors; + const Constructor **declaredConstructors; + Int32 nDeclaredConstructors; + + // Check that there is at least one constructor that the calling class can call + if (const_cast(&clazz)->getConstructors(constructors) == 0 && + (nDeclaredConstructors = + const_cast(&clazz)->getDeclaredConstructors(declaredConstructors)) > 0) { + + /* Now go through each of these declared constructors and see if we have + * package access to any of them + * FIXME This is horrendous, too much work. Think about not doing this much + * work everytime + */ + for (Int32 i = 0; i < nDeclaredConstructors; i++) + if (!(declaredConstructors[i]->getModifiers() & CR_METHOD_PRIVATE)) + if (hasPackageAccess) + break; + + if (i == nDeclaredConstructors) + sysThrowNamedException("java/lang/IllegalAccessException"); + } + + try { + return (Java_java_lang_Object *) (&const_cast(&clazz)->newInstance()); + } catch (RuntimeError err) { + throwClassRuntimeException(err); + } +} + + +/* + * Class : java/lang/Class + * Method : isInstance + * Signature : (Ljava/lang/Object;)Z + */ +NS_EXPORT NS_NATIVECALL(uint32 /* bool */) +Netscape_Java_java_lang_Class_isInstance(Java_java_lang_Class *inClass, + Java_java_lang_Object *inObj) +{ + Type &type = toType(*inClass); + if (type.isPrimitive()) + return (Uint32)false; + + if (!inObj) + return false; + + const Class &clazz = asClass(type); + return (Uint32) clazz.isInstance(toObject(*inObj)); +} + + +/* + * Class : java/lang/Class + * Method : isAssignableFrom + * Signature : (Ljava/lang/Class;)Z + */ +NS_EXPORT NS_NATIVECALL(uint32) /* bool */ +Netscape_Java_java_lang_Class_isAssignableFrom(Java_java_lang_Class * inClass, + Java_java_lang_Class * inToClass) +{ + if (!inToClass) + sysThrowNullPointerException(); + + return toType(*inClass).isAssignableFrom(toType(*inToClass)); +} + + +/* + * Class : java/lang/Class + * Method : isInterface + * Signature : ()Z + */ +NS_EXPORT NS_NATIVECALL(uint32 /* bool */) +Netscape_Java_java_lang_Class_isInterface(Java_java_lang_Class *inClass) +{ + Type &type = toType(*inClass); + return type.isInterface(); +} + + +/* + * Class : java/lang/Class + * Method : isArray + * Signature : ()Z + */ +NS_EXPORT NS_NATIVECALL(uint32 /* bool */) +Netscape_Java_java_lang_Class_isArray(Java_java_lang_Class *inClass) +{ + Type &type = toType(*inClass); + return type.isArray(); +} + + +/* + * Class : java/lang/Class + * Method : isPrimitive + * Signature : ()Z + */ +NS_EXPORT NS_NATIVECALL(uint32 /* bool */) +Netscape_Java_java_lang_Class_isPrimitive(Java_java_lang_Class *inClass) +{ + Type &type = toType(*inClass); + return type.isPrimitive(); +} + + +/* + * Class : java/lang/Class + * Method : getName + * Signature : ()Ljava/lang/String; + */ +NS_EXPORT NS_NATIVECALL(Java_java_lang_String *) +Netscape_Java_java_lang_Class_getName(Java_java_lang_Class *inClass) +{ + Type &type = toType(*inClass); + const char *fullName = type.getName(); + + JavaString &fullNameStr = VM::intern(fullName); + return (Java_java_lang_String *) &fullNameStr; +} + + +/* + * Class : java/lang/Class + * Method : getClassLoader + * Signature : ()Ljava/lang/ClassLoader; + */ +NS_EXPORT NS_NATIVECALL(Java_java_lang_ClassLoader *) +Netscape_Java_java_lang_Class_getClassLoader(Java_java_lang_Class *) +{ +#ifdef DEBUG_LOG + PR_fprintf(PR_STDERR, "Netscape_Java_java_lang_Class_getClassLoader() not implemented"); +#endif + + return 0; +} + + +/* + * Class : java/lang/Class + * Method : getSuperclass + * Signature : ()Ljava/lang/Class; + */ +NS_EXPORT NS_NATIVECALL(Java_java_lang_Class *) +Netscape_Java_java_lang_Class_getSuperclass(Java_java_lang_Class *inClass) +{ + Type &type = toType(*inClass); + const Type *superClass = type.getSuperClass(); + return (Java_java_lang_Class *) superClass; +} + + +/* + * Class : java/lang/Class + * Method : getInterfaces + * Signature : ()[Ljava/lang/Class; + */ +NS_EXPORT NS_NATIVECALL(ArrayOf_Java_java_lang_Class *) +Netscape_Java_java_lang_Class_getInterfaces(Java_java_lang_Class *inClass) +{ + Type &type = toType(*inClass); + + if (isPrimitiveKind(type.typeKind)) + sysThrowNamedException("java/lang/IllegalAccessException"); + + ClassOrInterface &clazz = *static_cast(&type); + Interface **interfaces; + Int32 numInterfaces = clazz.getInterfaces(interfaces); + + JavaArray *arr = (JavaArray *) sysNewObjectArray(&VM::getStandardClass(cClass), numInterfaces); + + ArrayOf_Java_java_lang_Class *clazzArray = (ArrayOf_Java_java_lang_Class *) arr; + for (Int32 i = 0; i < numInterfaces; i++) + clazzArray->elements[i] = (Java_java_lang_Class *) interfaces[i]; + + return clazzArray; +} + + +/* + * Class : java/lang/Class + * Method : getComponentType + * Signature : ()Ljava/lang/Class; + */ +NS_EXPORT NS_NATIVECALL(Java_java_lang_Class *) +Netscape_Java_java_lang_Class_getComponentType(Java_java_lang_Class *inClass) +{ + Type &type = toType(*inClass); + if (!type.isArray()) + return NULL; + + const Type &componentType = asArray(type).getComponentType(); + return (Java_java_lang_Class *) &componentType; +} + + +/* + * Class : java/lang/Class + * Method : getModifiers + * Signature : ()I + */ +NS_EXPORT NS_NATIVECALL(int32) +Netscape_Java_java_lang_Class_getModifiers(Java_java_lang_Class *inClass) +{ + Type &type = toType(*inClass); + return type.getModifiers(); +} + + +/* + * Class : java/lang/Class + * Method : getSigners + * Signature : ()[Ljava/lang/Object; + */ +NS_EXPORT NS_NATIVECALL(ArrayOf_Java_java_lang_Object *) +Netscape_Java_java_lang_Class_getSigners(Java_java_lang_Class *) +{ + printf("Netscape_Java_java_lang_Class_getSigners() not implemented"); + return 0; +} + + +/* + * Class : java/lang/Class + * Method : setSigners + * Signature : ([Ljava/lang/Object;)V + */ +NS_EXPORT NS_NATIVECALL(void) +Netscape_Java_java_lang_Class_setSigners(Java_java_lang_Class *, ArrayOf_Java_java_lang_Object *) +{ + printf("Netscape_Java_java_lang_Class_setSigners() not implemented"); +} + + +/* + * Class : java/lang/Class + * Method : getPrimitiveClass + * Signature : (Ljava/lang/String;)Ljava/lang/Class; + */ +NS_EXPORT NS_NATIVECALL(Java_java_lang_Class *) +Netscape_Java_java_lang_Class_getPrimitiveClass(Java_java_lang_String *nameString) +{ + if (!nameString) + return NULL; + + char *className = ((JavaString *) nameString)->convertUtf(); + const PrimitiveType *clazz = PrimitiveType::getClass(className); + + /* Free the memory we just allocated */ + JavaString::freeUtf(className); + + return (Java_java_lang_Class *)clazz; +} + + +/* + * Class : java/lang/Class + * Method : getFields0 + * Signature : (I)[Ljava/lang/reflect/Field; + * + * fieldCategory tells us what class of fields to return. + * fieldCategory can have the values defined in enum FieldCategory, + * defined above. + */ +NS_EXPORT NS_NATIVECALL(ArrayOf_Java_java_lang_reflect_Field *) +Netscape_Java_java_lang_Class_getFields0(Java_java_lang_Class *inClass, + int32 category) +{ +#if 0 + ClassOrInterface &clazz = *(ClassOrInterface *) &toType(*inClass); + const Field **fields; + Int32 numFields; + + if (category == fieldOrMethodCategoryPublic) + numFields = clazz.getFields(fields); + else + numFields = clazz.getDeclaredFields(fields); + + const Type *classField = &VM::getStandardClass(cField); + JavaArray *arr = (JavaArray *) sysNewObjectArray(classField, numFields); + + ArrayOf_Java_java_lang_reflect_Field *fieldArray = + (ArrayOf_Java_java_lang_reflect_Field *) arr; + + for (Int32 i = 0; i < numFields; i++) + fieldArray->elements[i] = (Java_java_lang_reflect_Field *) fields[i]; + + return fieldArray; +#else + bool publik = (category == fieldOrMethodCategoryPublic); + + ClassOrInterface &clazz = *(ClassOrInterface *) &toType(*inClass); + Int32 numFields = 0; + + if (publik) { + Int32 i; + + /* Walk all interfaces that we implement */ + Int32 interfaceCount; + Interface **interfaces; + + interfaceCount = clazz.getInterfaces(interfaces); + + for (i = 0; i < interfaceCount; i++) { + const Field **dummy; + numFields += interfaces[i]->getFields(dummy); + } + + /* Walk our instance fields from child to parent */ + ClassOrInterface *tmp; + for (tmp = &clazz; tmp; tmp = (ClassOrInterface *) tmp->getSuperClass()) { + const Field **fieldsInThisClass; + Int32 numFieldsInThisClass = tmp->getDeclaredFields(fieldsInThisClass); + + for (i = 0; i < numFieldsInThisClass; i++) + if (fieldsInThisClass[i]->getModifiers() & CR_FIELD_PUBLIC) + numFields++; + } + + /* Allocate a JavaArray of the correct size */ + const Type *classField = &VM::getStandardClass(cField); + JavaArray *arr = (JavaArray *) sysNewObjectArray(classField, numFields); + + ArrayOf_Java_java_lang_reflect_Field *fieldArray = + (ArrayOf_Java_java_lang_reflect_Field *) arr; + + Int32 index = 0; + + /* Walk the fields again, this time copying them into our array */ + for (i = 0; i < interfaceCount; i++) { + const Field **interfaceFields; + Int32 numInterfaceFields = interfaces[i]->getFields(interfaceFields); + + for (Int32 j = 0; j < numInterfaceFields; j++) + fieldArray->elements[index++] = (Java_java_lang_reflect_Field *) interfaceFields[j]; + } + + /* Add instance fields, starting with the topmost superclass */ + Vector vec; + for (tmp = &clazz; tmp; tmp = (ClassOrInterface *)(tmp->getSuperClass())) + vec.append(tmp); + + for (Int32 vectorIndex = vec.size(); vectorIndex > 0; vectorIndex--) { + tmp = vec[vectorIndex-1]; + const Field **fieldsInThisClass; + Int32 numFieldsInThisClass = tmp->getDeclaredFields(fieldsInThisClass); + + for (i = 0; i < numFieldsInThisClass; i++) + if (fieldsInThisClass[i]->getModifiers() & CR_FIELD_PUBLIC) + fieldArray->elements[index++] = (Java_java_lang_reflect_Field *) fieldsInThisClass[i]; + + } + + assert(index == numFields); + + return fieldArray; + } else { + const Field **fields; + numFields = clazz.getDeclaredFields(fields); + + const Type *classField = &VM::getStandardClass(cField); + JavaArray *arr = (JavaArray *) sysNewObjectArray(classField, numFields); + + ArrayOf_Java_java_lang_reflect_Field *fieldArray = + (ArrayOf_Java_java_lang_reflect_Field *) arr; + + for (Int32 i = 0; i < numFields; i++) + fieldArray->elements[i] = (Java_java_lang_reflect_Field *) fields[i]; + + return fieldArray; + } +#endif +} + + +/* + * Class : java/lang/Class + * Method : getMethods0 + * Signature : (I)[Ljava/lang/reflect/Method; + */ +NS_EXPORT NS_NATIVECALL(ArrayOf_Java_java_lang_reflect_Method *) +Netscape_Java_java_lang_Class_getMethods0(Java_java_lang_Class *inClass, + int32 category) +{ + ClassOrInterface &clazz = *(ClassOrInterface *) &toType(*inClass); + const Method **methods; + Int32 numMethods; + + if (category == fieldOrMethodCategoryPublic) + numMethods = clazz.getMethods(methods); + else + numMethods = clazz.getDeclaredMethods(methods); + + const Type *classMethod = &VM::getStandardClass(cMethod); + JavaArray *arr = (JavaArray *) sysNewObjectArray(classMethod, numMethods); + + ArrayOf_Java_java_lang_reflect_Method *methodArray = + (ArrayOf_Java_java_lang_reflect_Method *) arr; + + for (Int32 i = 0; i < numMethods; i++) + methodArray->elements[i] = (Java_java_lang_reflect_Method *) methods[i]; + + return methodArray; + +} + + +/* + * Class : java/lang/Class + * Method : getConstructors0 + * Signature : (I)[Ljava/lang/reflect/Constructor; + */ +NS_EXPORT NS_NATIVECALL(ArrayOf_Java_java_lang_reflect_Constructor *) +Netscape_Java_java_lang_Class_getConstructors0(Java_java_lang_Class *inClass, + int32 category) +{ + ClassOrInterface &clazz = *(ClassOrInterface *) &toType(*inClass); + const Constructor **constructors; + Int32 numConstructors; + + if (category == fieldOrMethodCategoryPublic) + numConstructors = clazz.getConstructors(constructors); + else + numConstructors = clazz.getDeclaredConstructors(constructors); + + const Type *classConstructor = &VM::getStandardClass(cConstructor); + JavaArray *arr = (JavaArray *) sysNewObjectArray(classConstructor, numConstructors); + + ArrayOf_Java_java_lang_reflect_Constructor *constructorArray = + (ArrayOf_Java_java_lang_reflect_Constructor *) arr; + + for (Int32 i = 0; i < numConstructors; i++) + constructorArray->elements[i] = (Java_java_lang_reflect_Constructor *) constructors[i]; + + return constructorArray; +} + + +/* + * Class : java/lang/Class + * Method : getField0 + * Signature : (Ljava/lang/String;I)Ljava/lang/reflect/Field; + */ +NS_EXPORT NS_NATIVECALL(Java_java_lang_reflect_Field *) +Netscape_Java_java_lang_Class_getField0(Java_java_lang_Class *inClass, + Java_java_lang_String *inName, + int32 category) +{ + if (!inName || !inClass) + sysThrowNullPointerException(); + + char *name = ((JavaString *) inName)->convertUtf(); + ClassOrInterface &clazz = *(ClassOrInterface *) &toType(*inClass); + + const Field *field; + try { + if (category == fieldOrMethodCategoryPublic) + field = &clazz.getField(name); + else + field = &clazz.getDeclaredField(name); + } catch (RuntimeError) { + sysThrowNamedException("java/lang/NoSuchFieldException"); + } + + JavaString::freeUtf(name); + return (Java_java_lang_reflect_Field *)field; +} + + +/* + * Class : java/lang/Class + * Method : getMethod0 + * Signature : (Ljava/lang/String;[Ljava/lang/Class;I)Ljava/lang/reflect/Method; + */ +NS_EXPORT NS_NATIVECALL(Java_java_lang_reflect_Method *) +Netscape_Java_java_lang_Class_getMethod0(Java_java_lang_Class *inClass, + Java_java_lang_String *inName, + ArrayOf_Java_java_lang_Class *paramTypes, + int32 category) +{ + if (!inName) + sysThrowNullPointerException(); + + Int32 numParams; + const Type **params; + + if (!paramTypes) { + Type *dummy[1]; + + params = (const Type **) dummy; + numParams = 0; + } else { + params = (const Type **) paramTypes->elements; + numParams = paramTypes->length; + } + + ClassOrInterface &clazz = *(ClassOrInterface *) &toType(*inClass); + + char *name = ((JavaString *) inName)->convertUtf(); + + const Method *method; + + try { + if (category == fieldOrMethodCategoryPublic) + method = &clazz.getMethod(name, params, numParams); + else + method = &clazz.getDeclaredMethod(name, params, numParams); + } catch (RuntimeError) { + sysThrowNamedException("java/lang/NoSuchMethodException"); + } + + JavaString::freeUtf(name); + return (Java_java_lang_reflect_Method *) method; +} + + +/* + * Class : java/lang/Class + * Method : getConstructor0 + * Signature : ([Ljava/lang/Class;I)Ljava/lang/reflect/Constructor; + */ +NS_EXPORT NS_NATIVECALL(Java_java_lang_reflect_Constructor *) +Netscape_Java_java_lang_Class_getConstructor0(Java_java_lang_Class *inClass, + ArrayOf_Java_java_lang_Class *paramTypes, + int32 category) +{ + ClassOrInterface &clazz = *(ClassOrInterface *) &toType(*inClass); + + const Type **params; + Uint32 nParams; + + if (paramTypes == 0) { + params = (const Type **) 0; + nParams = 0; + } else { + params = (const Type **) paramTypes->elements; + nParams = paramTypes->length; + } + + Constructor *constructor; + + try { + if (category == fieldOrMethodCategoryPublic) + constructor = &clazz.getConstructor(params, nParams); + else + constructor = &clazz.getDeclaredConstructor(params, nParams); + } catch (RuntimeError) { + sysThrowNamedException("java/lang/NoSuchMethodException"); + } + + return (Java_java_lang_reflect_Constructor *) constructor; +} + + +} /* extern "C" */ + diff --git a/ef/Packages/java/lang/nativesrc/ClassLoader.cpp b/ef/Packages/java/lang/nativesrc/ClassLoader.cpp new file mode 100644 index 000000000000..d97b1dd0a36b --- /dev/null +++ b/ef/Packages/java/lang/nativesrc/ClassLoader.cpp @@ -0,0 +1,150 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#include "java_lang_ClassLoader.h" +#include "FieldOrMethod.h" +#include "JavaVM.h" +#include "JavaString.h" +#include "SysCallsRuntime.h" +#include "prio.h" +#include + +extern "C" { +/* + * Class : java/lang/ClassLoader + * Method : init + * Signature : ()V + */ +NS_EXPORT NS_NATIVECALL(void ) +Netscape_Java_java_lang_ClassLoader_init(Java_java_lang_ClassLoader *) +{ + //printf("Netscape_Java_java_lang_ClassLoader_init() not implemented"); +} + +NS_EXPORT NS_NATIVECALL(void ) +Netscape_Java_java_lang_ClassLoader_initIDs() +{ +// printf("Netscape_Java_java_lang_ClassLoader_init() not implemented"); +} + + +/* + * Class : java/lang/ClassLoader + * Method : defineClass0 + * Signature : (Ljava/lang/String;[BII)Ljava/lang/Class; + */ +NS_EXPORT NS_NATIVECALL(Java_java_lang_Class *) +Netscape_Java_java_lang_ClassLoader_defineClass0(Java_java_lang_ClassLoader *, Java_java_lang_String *, ArrayOf_uint8 *, int32, int32) +{ + printf("Netscape_Java_java_lang_ClassLoader_defineClass0() not implemented"); + return 0; +} + + +/* + * Class : java/lang/ClassLoader + * Method : resolveClass0 + * Signature : (Ljava/lang/Class;)V + */ +NS_EXPORT NS_NATIVECALL(void) +Netscape_Java_java_lang_ClassLoader_resolveClass0(Java_java_lang_ClassLoader *, Java_java_lang_Class *) +{ + printf("Netscape_Java_java_lang_ClassLoader_resolveClass0() not implemented"); + +} + + +/* + * Class : java/lang/ClassLoader + * Method : findSystemClass0 + * Signature : (Ljava/lang/String;)Ljava/lang/Class; + */ +NS_EXPORT NS_NATIVECALL(Java_java_lang_Class *) +Netscape_Java_java_lang_ClassLoader_findSystemClass0(Java_java_lang_ClassLoader *, Java_java_lang_String *str) +{ +#if 0 + Java_java_lang_Class* ret; + try { + char *className = ((JavaString *) str)->convertUtf(); + ClassCentral ¢ral = VM::getCentral(); + + ClassFileSummary &summ = central.addClass(className); + Class *clazz = const_cast(static_cast(summ.getThisClass())); + + JavaString::freeUtf(className); + + assert(clazz); + ret = ((Java_java_lang_Class*)&asClass(*clazz)); + } catch (VerifyError e) { + ret = NULL; + } + return ret; +#endif +// fprintf(stdout, "looking for class %s\n", ((JavaString *) str)->convertUtf()); + return NULL; +} + + +/* + * Class : java/lang/ClassLoader + * Method : getSystemResourceAsStream0 + * Signature : (Ljava/lang/String;)Ljava/io/InputStream; + */ +NS_EXPORT NS_NATIVECALL(Java_java_io_InputStream *) +Netscape_Java_java_lang_ClassLoader_getSystemResourceAsStream0(Java_java_lang_String *str) +{ + if (str == NULL) + sysThrowNullPointerException(); + + char* fileName = ((JavaString *) str)->convertUtf(); + PRFileInfo info; + if (PR_GetFileInfo(fileName, &info) != PR_SUCCESS) { + JavaString::freeUtf(fileName); + return NULL; + } + JavaString::freeUtf(fileName); + + ClassCentral ¢ral = VM::getCentral(); + + ClassFileSummary &summ = central.addClass("java/io/FileInputStream"); + Class *clazz = const_cast(static_cast(summ.getThisClass())); + const Type* paramType[1]; + paramType[0] = (Type *) &VM::getStandardClass(cString); + JavaObject* param[1]; + param[0] = (JavaObject *) str; + + Constructor& c = clazz->getDeclaredConstructor(paramType, 1); + JavaObject& ret = c.newInstance(param, 1); + + return (Java_java_io_InputStream *) &ret; +} + + +/* + * Class : java/lang/ClassLoader + * Method : getSystemResourceAsName0 + * Signature : (Ljava/lang/String;)Ljava/lang/String; + */ +NS_EXPORT NS_NATIVECALL(Java_java_lang_String *) +Netscape_Java_java_lang_ClassLoader_getSystemResourceAsName0(Java_java_lang_String *) +{ + printf("Netscape_Java_java_lang_ClassLoader_getSystemResourceAsName0() not implemented"); + return 0; +} + +} /* extern "C" */ + diff --git a/ef/Packages/java/lang/nativesrc/Compiler.cpp b/ef/Packages/java/lang/nativesrc/Compiler.cpp new file mode 100644 index 000000000000..69d83b4416eb --- /dev/null +++ b/ef/Packages/java/lang/nativesrc/Compiler.cpp @@ -0,0 +1,97 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#include "java_lang_Compiler.h" +#include + +extern "C" { +/* + * Class : java/lang/Compiler + * Method : initialize + * Signature : ()V + */ +NS_EXPORT NS_NATIVECALL(void) +Netscape_Java_java_lang_Compiler_initialize() +{ + printf("Netscape_Java_java_lang_Compiler_initialize() not implemented"); +} + + +/* + * Class : java/lang/Compiler + * Method : compileClass + * Signature : (Ljava/lang/Class;)Z + */ +NS_EXPORT NS_NATIVECALL(uint32 /* bool */) +Netscape_Java_java_lang_Compiler_compileClass(Java_java_lang_Class *) +{ + printf("Netscape_Java_java_lang_Compiler_compileClass() not implemented"); + return 0; +} + + +/* + * Class : java/lang/Compiler + * Method : compileClasses + * Signature : (Ljava/lang/String;)Z + */ +NS_EXPORT NS_NATIVECALL(uint32 /* bool */) +Netscape_Java_java_lang_Compiler_compileClasses(Java_java_lang_String *) +{ + printf("Netscape_Java_java_lang_Compiler_compileClasses() not implemented"); + return 0; +} + + +/* + * Class : java/lang/Compiler + * Method : command + * Signature : (Ljava/lang/Object;)Ljava/lang/Object; + */ +NS_EXPORT NS_NATIVECALL(Java_java_lang_Object *) +Netscape_Java_java_lang_Compiler_command(Java_java_lang_Object *) +{ + printf("Netscape_Java_java_lang_Compiler_command() not implemented"); + return 0; +} + + +/* + * Class : java/lang/Compiler + * Method : enable + * Signature : ()V + */ +NS_EXPORT NS_NATIVECALL(void) +Netscape_Java_java_lang_Compiler_enable() +{ + printf("Netscape_Java_java_lang_Compiler_enable() not implemented"); +} + + +/* + * Class : java/lang/Compiler + * Method : disable + * Signature : ()V + */ +NS_EXPORT NS_NATIVECALL(void) +Netscape_Java_java_lang_Compiler_disable() +{ + printf("Netscape_Java_java_lang_Compiler_disable() not implemented"); +} + +} /* extern "C" */ + diff --git a/ef/Packages/java/lang/nativesrc/Double.cpp b/ef/Packages/java/lang/nativesrc/Double.cpp new file mode 100644 index 000000000000..06dd84f30abd --- /dev/null +++ b/ef/Packages/java/lang/nativesrc/Double.cpp @@ -0,0 +1,60 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#include "java_lang_Double.h" +#include + +extern "C" { + +/* + * Class : java/lang/Double + * Method : doubleToLongBits + * Signature : (D)J + */ +NS_EXPORT NS_NATIVECALL(int64) +Netscape_Java_java_lang_Double_doubleToLongBits(float64 d) +{ + return *reinterpret_cast(&d); +} + + +/* + * Class : java/lang/Double + * Method : longBitsToDouble + * Signature : (J)D + */ +NS_EXPORT NS_NATIVECALL(float64) +Netscape_Java_java_lang_Double_longBitsToDouble(int64 i) +{ + return *reinterpret_cast(&i); +} + + +/* + * Class : java/lang/Double + * Method : valueOf0 + * Signature : (Ljava/lang/String;)D + */ +NS_EXPORT NS_NATIVECALL(float64) +Netscape_Java_java_lang_Double_valueOf0(Java_java_lang_String *) +{ + printf("Netscape_Java_java_lang_Double_valueOf0() not implemented"); + return 0; +} + +} /* extern "C" */ + diff --git a/ef/Packages/java/lang/nativesrc/Float.cpp b/ef/Packages/java/lang/nativesrc/Float.cpp new file mode 100644 index 000000000000..83d0bde58dab --- /dev/null +++ b/ef/Packages/java/lang/nativesrc/Float.cpp @@ -0,0 +1,46 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#include "java_lang_Float.h" +#include + +extern "C" { +/* + * Class : java/lang/Float + * Method : floatToIntBits + * Signature : (F)I + */ +NS_EXPORT NS_NATIVECALL(int32) +Netscape_Java_java_lang_Float_floatToIntBits(float f) +{ + return *reinterpret_cast(&f); +} + + +/* + * Class : java/lang/Float + * Method : intBitsToFloat + * Signature : (I)F + */ +NS_EXPORT NS_NATIVECALL(float) +Netscape_Java_java_lang_Float_intBitsToFloat(int32 i) +{ + return *reinterpret_cast(&i); +} + +} /* extern "C" */ + diff --git a/ef/Packages/java/lang/nativesrc/Makefile b/ef/Packages/java/lang/nativesrc/Makefile new file mode 100644 index 000000000000..1f9342b20734 --- /dev/null +++ b/ef/Packages/java/lang/nativesrc/Makefile @@ -0,0 +1,45 @@ +#!gmake +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +####################################################################### +# (1) Include manifest file # +####################################################################### + +include manifest.mn + +####################################################################### +# (2) Include "component" configuration information. # +####################################################################### + +include $(DEPTH)/config/config.mk + +####################################################################### +# (3) Include "local" platform-dependent assignments (OPTIONAL). # +####################################################################### + + +####################################################################### +# (4) Execute "component" rules. (OPTIONAL) # +####################################################################### + +include $(DEPTH)/config/rules.mk + +####################################################################### +# (7) Execute "local" rules. (OPTIONAL). # +####################################################################### + + diff --git a/ef/Packages/java/lang/nativesrc/Math.cpp b/ef/Packages/java/lang/nativesrc/Math.cpp new file mode 100644 index 000000000000..ce25e6034eb7 --- /dev/null +++ b/ef/Packages/java/lang/nativesrc/Math.cpp @@ -0,0 +1,214 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#include "java_lang_Math.h" +#include + +extern "C" { +/* + * Class : java/lang/Math + * Method : sin + * Signature : (D)D + */ +NS_EXPORT NS_NATIVECALL(float64) +Netscape_Java_java_lang_Math_sin(float64) +{ + printf("Netscape_Java_java_lang_Math_sin() not implemented"); + return 0; +} + + +/* + * Class : java/lang/Math + * Method : cos + * Signature : (D)D + */ +NS_EXPORT NS_NATIVECALL(float64) +Netscape_Java_java_lang_Math_cos(float64) +{ + printf("Netscape_Java_java_lang_Math_cos() not implemented"); + return 0; +} + + +/* + * Class : java/lang/Math + * Method : tan + * Signature : (D)D + */ +NS_EXPORT NS_NATIVECALL(float64) +Netscape_Java_java_lang_Math_tan(float64) +{ + printf("Netscape_Java_java_lang_Math_tan() not implemented"); + return 0; +} + + +/* + * Class : java/lang/Math + * Method : asin + * Signature : (D)D + */ +NS_EXPORT NS_NATIVECALL(float64) +Netscape_Java_java_lang_Math_asin(float64) +{ + printf("Netscape_Java_java_lang_Math_asin() not implemented"); + return 0; +} + + +/* + * Class : java/lang/Math + * Method : acos + * Signature : (D)D + */ +NS_EXPORT NS_NATIVECALL(float64) +Netscape_Java_java_lang_Math_acos(float64); + + +/* + * Class : java/lang/Math + * Method : atan + * Signature : (D)D + */ +NS_EXPORT NS_NATIVECALL(float64) +Netscape_Java_java_lang_Math_atan(float64) +{ + printf("Netscape_Java_java_lang_Math_atan() not implemented"); + return 0; +} + + +/* + * Class : java/lang/Math + * Method : exp + * Signature : (D)D + */ +NS_EXPORT NS_NATIVECALL(float64) +Netscape_Java_java_lang_Math_exp(float64) +{ + printf("Netscape_Java_java_lang_Math_exp() not implemented"); + return 0; +} + + +/* + * Class : java/lang/Math + * Method : log + * Signature : (D)D + */ +NS_EXPORT NS_NATIVECALL(float64) +Netscape_Java_java_lang_Math_log(float64) +{ + printf("Netscape_Java_java_lang_Math_log() not implemented"); + return 0; +} + + +/* + * Class : java/lang/Math + * Method : sqrt + * Signature : (D)D + */ +NS_EXPORT NS_NATIVECALL(float64) +Netscape_Java_java_lang_Math_sqrt(float64) +{ + printf("Netscape_Java_java_lang_Math_sqrt() not implemented"); + return 0; +} + + +/* + * Class : java/lang/Math + * Method : IEEEremainder + * Signature : (DD)D + */ +NS_EXPORT NS_NATIVECALL(float64) +Netscape_Java_java_lang_Math_IEEEremainder(float64, float64) +{ + printf("Netscape_Java_java_lang_Math_IEEEremainder() not implemented"); + return 0; +} + + +/* + * Class : java/lang/Math + * Method : ceil + * Signature : (D)D + */ +NS_EXPORT NS_NATIVECALL(float64) +Netscape_Java_java_lang_Math_ceil(float64) +{ + printf("Netscape_Java_java_lang_Math_ceil() not implemented"); + return 0; +} + + +/* + * Class : java/lang/Math + * Method : floor + * Signature : (D)D + */ +NS_EXPORT NS_NATIVECALL(float64) +Netscape_Java_java_lang_Math_floor(float64) +{ + printf("Netscape_Java_java_lang_Math_floor() not implemented"); + return 0; +} + + +/* + * Class : java/lang/Math + * Method : rint + * Signature : (D)D + */ +NS_EXPORT NS_NATIVECALL(float64) +Netscape_Java_java_lang_Math_rint(float64) +{ + printf("Netscape_Java_java_lang_Math_rint() not implemented"); + return 0; +} + + +/* + * Class : java/lang/Math + * Method : atan2 + * Signature : (DD)D + */ +NS_EXPORT NS_NATIVECALL(float64) +Netscape_Java_java_lang_Math_atan2(float64, float64) +{ + printf("Netscape_Java_java_lang_Math_atan2() not implemented"); + return 0; +} + + +/* + * Class : java/lang/Math + * Method : pow + * Signature : (DD)D + */ +NS_EXPORT NS_NATIVECALL(float64) +Netscape_Java_java_lang_Math_pow(float64, float64) +{ + printf("Netscape_Java_java_lang_Math_pow() not implemented"); + return 0; +} + + +} /* extern "C" */ + diff --git a/ef/Packages/java/lang/nativesrc/Object.cpp b/ef/Packages/java/lang/nativesrc/Object.cpp new file mode 100644 index 000000000000..2dded10a6334 --- /dev/null +++ b/ef/Packages/java/lang/nativesrc/Object.cpp @@ -0,0 +1,118 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#include "java_lang_Object.h" +#include +#include "Monitor.h" +#include "Exceptions.h" + +extern "C" { + +static inline JavaObject &toObject(Java_java_lang_Object &inObject) +{ + return *(Class *)(&inObject); +} + +/* + * Class : java/lang/Object + * Method : getClass + * Signature : ()Ljava/lang/Class; + */ +NS_EXPORT NS_NATIVECALL(Java_java_lang_Class *) +Netscape_Java_java_lang_Object_getClass(Java_java_lang_Object *obj) +{ + return (Java_java_lang_Class *) (&toObject(*obj).getType()); +} + + +/* + * Class : java/lang/Object + * Method : hashCode + * Signature : ()I + */ +NS_EXPORT NS_NATIVECALL(int32) +Netscape_Java_java_lang_Object_hashCode(Java_java_lang_Object *obj) +{ + // XXX - This won't work once a relocating GC is implemented + return reinterpret_cast(obj); +} + + +/* + * Class : java/lang/Object + * Method : clone + * Signature : ()Ljava/lang/Object; + */ +NS_EXPORT NS_NATIVECALL(Java_java_lang_Object *) +Netscape_Java_java_lang_Object_clone(Java_java_lang_Object *inObj) +{ + JavaObject *newObj = ((Class *) toObject(*inObj).getClass().clone(*inObj)); + + return (Java_java_lang_Object *) (newObj); +} + + +/* + * Class : java/lang/Object + * Method : notify + * Signature : ()V + */ +NS_EXPORT NS_NATIVECALL(void) +Netscape_Java_java_lang_Object_notify(Java_java_lang_Object *o) +{ + if (o == NULL) { + sysThrowNamedException("java/lang/NullPointerException"); + return; + } + Monitor::notify(*o); +} + + +/* + * Class : java/lang/Object + * Method : notifyAll + * Signature : ()V + */ +NS_EXPORT NS_NATIVECALL(void) +Netscape_Java_java_lang_Object_notifyAll(Java_java_lang_Object *o) +{ + if (o == NULL) { + sysThrowNamedException("java/lang/NullPointerException"); + return; + } + Monitor::notifyAll(*o); +} + + +/* + * Class : java/lang/Object + * Method : wait + * Signature : (J)V + */ +NS_EXPORT NS_NATIVECALL(void) +Netscape_Java_java_lang_Object_wait(Java_java_lang_Object *o, int64 l) +{ + if (o == NULL) { + sysThrowNamedException("java/lang/NullPointerException"); + return; + } + Monitor::wait(*o,l); +} + + +} /* extern "C" */ + diff --git a/ef/Packages/java/lang/nativesrc/Runtime.cpp b/ef/Packages/java/lang/nativesrc/Runtime.cpp new file mode 100644 index 000000000000..cd6f4fde26ee --- /dev/null +++ b/ef/Packages/java/lang/nativesrc/Runtime.cpp @@ -0,0 +1,175 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#include "java_lang_Runtime.h" +#include +#include "Thread.h" + +extern "C" { +/* + * Class : java/lang/Runtime + * Method : exitInternal + * Signature : (I)V + */ +NS_EXPORT NS_NATIVECALL(void) +Netscape_Java_java_lang_Runtime_exitInternal(Java_java_lang_Runtime *, int32 code) +{ + Thread::exit(); +} + + +/* + * Class : java/lang/Runtime + * Method : runFinalizersOnExit0 + * Signature : (Z)V + */ +NS_EXPORT NS_NATIVECALL(void) +Netscape_Java_java_lang_Runtime_runFinalizersOnExit0(uint32 /* bool */) +{ + printf("Netscape_Java_java_lang_Runtime_runFinalizersOnExit0() not implemented"); + +} + + +/* + * Class : java/lang/Runtime + * Method : execInternal + * Signature : ([Ljava/lang/String;[Ljava/lang/String;)Ljava/lang/Process; + */ +NS_EXPORT NS_NATIVECALL(Java_java_lang_Process *) +Netscape_Java_java_lang_Runtime_execInternal(Java_java_lang_Runtime *, ArrayOf_Java_java_lang_String *, ArrayOf_Java_java_lang_String *) +{ + printf("Netscape_Java_java_lang_Runtime_execInternal() not implemented"); + return 0; +} + + +/* + * Class : java/lang/Runtime + * Method : freeMemory + * Signature : ()J + */ +NS_EXPORT NS_NATIVECALL(int64) +Netscape_Java_java_lang_Runtime_freeMemory(Java_java_lang_Runtime *) +{ + printf("Netscape_Java_java_lang_Runtime_freeMemory() not implemented"); + return 0; +} + + +/* + * Class : java/lang/Runtime + * Method : totalMemory + * Signature : ()J + */ +NS_EXPORT NS_NATIVECALL(int64) +Netscape_Java_java_lang_Runtime_totalMemory(Java_java_lang_Runtime *) +{ + printf("Netscape_Java_java_lang_Runtime_totalMemory() not implemented"); + return 0; +} + + +/* + * Class : java/lang/Runtime + * Method : gc + * Signature : ()V + */ +NS_EXPORT NS_NATIVECALL(void) +Netscape_Java_java_lang_Runtime_gc(Java_java_lang_Runtime *) +{ + printf("Netscape_Java_java_lang_Runtime_gc() not implemented"); +} + + +/* + * Class : java/lang/Runtime + * Method : runFinalization + * Signature : ()V + */ +NS_EXPORT NS_NATIVECALL(void) +Netscape_Java_java_lang_Runtime_runFinalization(Java_java_lang_Runtime *) +{ + printf("Netscape_Java_java_lang_Runtime_runFinalization() not implemented"); +} + + +/* + * Class : java/lang/Runtime + * Method : traceInstructions + * Signature : (Z)V + */ +NS_EXPORT NS_NATIVECALL(void) +Netscape_Java_java_lang_Runtime_traceInstructions(Java_java_lang_Runtime *, uint32 /* bool */) +{ + printf("Netscape_Java_java_lang_Runtime_traceInstructions() not implemented"); +} + + +/* + * Class : java/lang/Runtime + * Method : traceMethodCalls + * Signature : (Z)V + */ +NS_EXPORT NS_NATIVECALL(void) +Netscape_Java_java_lang_Runtime_traceMethodCalls(Java_java_lang_Runtime *, uint32 /* bool */) +{ + printf("Netscape_Java_java_lang_Runtime_traceMethodCalls() not implemented"); +} + + +/* + * Class : java/lang/Runtime + * Method : initializeLinkerInternal + * Signature : ()Ljava/lang/String; + */ +NS_EXPORT NS_NATIVECALL(Java_java_lang_String *) +Netscape_Java_java_lang_Runtime_initializeLinkerInternal(Java_java_lang_Runtime *) +{ + printf("Netscape_Java_java_lang_Runtime_initializeLinkerInternal() not implemented"); + return 0; +} + + +/* + * Class : java/lang/Runtime + * Method : buildLibName + * Signature : (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String; + */ +NS_EXPORT NS_NATIVECALL(Java_java_lang_String *) +Netscape_Java_java_lang_Runtime_buildLibName(Java_java_lang_Runtime *, Java_java_lang_String *, Java_java_lang_String *) +{ + printf("Netscape_Java_java_lang_Runtime_buildLibName() not implemented"); + return 0; +} + + +/* + * Class : java/lang/Runtime + * Method : loadFileInternal + * Signature : (Ljava/lang/String;)I + */ +NS_EXPORT NS_NATIVECALL(int32) +Netscape_Java_java_lang_Runtime_loadFileInternal(Java_java_lang_Runtime *, Java_java_lang_String *) +{ + printf("Netscape_Java_java_lang_Runtime_loadFileInternal() not implemented"); + return 0; +} + + +} /* extern "C" */ + diff --git a/ef/Packages/java/lang/nativesrc/SecurityManager.cpp b/ef/Packages/java/lang/nativesrc/SecurityManager.cpp new file mode 100644 index 000000000000..e838360c0788 --- /dev/null +++ b/ef/Packages/java/lang/nativesrc/SecurityManager.cpp @@ -0,0 +1,88 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#include "java_lang_SecurityManager.h" +#include + +extern "C" { +/* + * Class : java/lang/SecurityManager + * Method : getClassContext + * Signature : ()[Ljava/lang/Class; + */ +NS_EXPORT NS_NATIVECALL(ArrayOf_Java_java_lang_Class *) +Netscape_Java_java_lang_SecurityManager_getClassContext(Java_java_lang_SecurityManager *) +{ + printf("Netscape_Java_java_lang_SecurityManager_getClassContext() not implemented"); + return 0; +} + + +/* + * Class : java/lang/SecurityManager + * Method : currentClassLoader + * Signature : ()Ljava/lang/ClassLoader; + */ +NS_EXPORT NS_NATIVECALL(Java_java_lang_ClassLoader *) +Netscape_Java_java_lang_SecurityManager_currentClassLoader(Java_java_lang_SecurityManager *) +{ + printf("Netscape_Java_java_lang_SecurityManager_currentClassLoader() not implemented"); + return 0; +} + + +/* + * Class : java/lang/SecurityManager + * Method : classDepth + * Signature : (Ljava/lang/String;)I + */ +NS_EXPORT NS_NATIVECALL(int32) +Netscape_Java_java_lang_SecurityManager_classDepth(Java_java_lang_SecurityManager *, Java_java_lang_String *) +{ + printf("Netscape_Java_java_lang_SecurityManager_classDepth() not implemented"); + return 0; +} + + +/* + * Class : java/lang/SecurityManager + * Method : classLoaderDepth + * Signature : ()I + */ +NS_EXPORT NS_NATIVECALL(int32) +Netscape_Java_java_lang_SecurityManager_classLoaderDepth(Java_java_lang_SecurityManager *) +{ + printf("Netscape_Java_java_lang_SecurityManager_classLoaderDepth() not implemented"); + return 0; +} + + +/* + * Class : java/lang/SecurityManager + * Method : currentLoadedClass0 + * Signature : ()Ljava/lang/Class; + */ +NS_EXPORT NS_NATIVECALL(Java_java_lang_Class *) +Netscape_Java_java_lang_SecurityManager_currentLoadedClass0(Java_java_lang_SecurityManager *) +{ + printf("Netscape_Java_java_lang_SecurityManager_currentLoadedClass0() not implemented"); + return 0; +} + + +} /* extern "C" */ + diff --git a/ef/Packages/java/lang/nativesrc/String.cpp b/ef/Packages/java/lang/nativesrc/String.cpp new file mode 100644 index 000000000000..cadfc47c558b --- /dev/null +++ b/ef/Packages/java/lang/nativesrc/String.cpp @@ -0,0 +1,40 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#include "java_lang_String.h" +#include "JavaVM.h" + +extern "C" { +/* + * Class : java/lang/String + * Method : intern + * Signature : ()Ljava/lang/String; + */ +NS_EXPORT NS_NATIVECALL(Java_java_lang_String *) +Netscape_Java_java_lang_String_intern(Java_java_lang_String *jThis) +{ + JavaString& jString = asJavaString(*jThis); + char* CString = jString.convertUtf(); + + JavaString& internString = VM::intern(CString); + JavaString::freeUtf(CString); + + return (Java_java_lang_String *)(&internString); +} + +} diff --git a/ef/Packages/java/lang/nativesrc/System.cpp b/ef/Packages/java/lang/nativesrc/System.cpp new file mode 100644 index 000000000000..1fc692c1dff4 --- /dev/null +++ b/ef/Packages/java/lang/nativesrc/System.cpp @@ -0,0 +1,282 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#include "java_lang_System.h" + +#include "java_io_InputStream.h" +#include "java_io_PrintStream.h" +#include "java_util_Properties.h" + +#include "FieldOrMethod.h" +#include "JavaVM.h" +#include "prprf.h" +#include "prtime.h" +#include "StackWalker.h" +#include "SysCallsRuntime.h" + +extern "C" { +inline Field *getField(const char *className, const char *name) +{ + ClassCentral ¢ral = VM::getCentral(); + + ClassFileSummary &summ = central.addClass(className); + + Class *clazz = const_cast(static_cast(summ.getThisClass())); + + Field *field = &clazz->getDeclaredField(name); + + return field; +} + +inline void setStaticField(const char *name, const char *className, JavaObject &val) +{ + Field *field = getField(className, name); + + field->set(0, val); +} + +/* + * Class : java/lang/System + * Method : setIn0 + * Signature : (Ljava/io/InputStream;)V + */ +NS_EXPORT NS_NATIVECALL(void) +Netscape_Java_java_lang_System_setIn0(Java_java_io_InputStream *str) +{ + setStaticField("in", "java/lang/System", *str); +} + + +/* + * Class : java/lang/System + * Method : setOut0 + * Signature : (Ljava/io/PrintStream;)V + */ +NS_EXPORT NS_NATIVECALL(void) +Netscape_Java_java_lang_System_setOut0(Java_java_io_PrintStream *str) +{ + setStaticField("out", "java/lang/System", *str); +} + + +/* + * Class : java/lang/System + * Method : setErr0 + * Signature : (Ljava/io/PrintStream;)V + */ +NS_EXPORT NS_NATIVECALL(void) +Netscape_Java_java_lang_System_setErr0(Java_java_io_PrintStream *str) +{ + setStaticField("err", "java/lang/System", *str); +} + + +/* + * Class : java/lang/System + * Method : currentTimeMillis + * Signature : ()J + */ +NS_EXPORT NS_NATIVECALL(int64) +Netscape_Java_java_lang_System_currentTimeMillis() +{ + PRInt64 thousand, milliseconds; + PRTime now = PR_Now(); + LL_I2L(thousand, 1000); + LL_DIV(milliseconds, now, thousand); + return milliseconds; +} + + +/* + * Class : java/lang/System + * Method : arraycopy + * Signature : (Ljava/lang/Object;ILjava/lang/Object;II)V + */ +NS_EXPORT NS_NATIVECALL(void) +Netscape_Java_java_lang_System_arraycopy(Java_java_lang_Object *srcObj, + int32 srcPos, + Java_java_lang_Object *destObj, + int32 destPos, int32 len) +{ + // ChkNull. + if ((srcObj == 0) || (destObj == 0)) { + sysThrowNullPointerException(); + assert("never come back"); // FIX-ME assert(true) + } + + // ChkArrayStore. + if ((srcObj->getType().typeKind != tkArray) || (destObj->getType().typeKind != tkArray)) { + sysThrowArrayStoreException(); + assert("never come back"); // FIX-ME assert(1) + } + TypeKind tkSource = asArray(srcObj->getType()).componentType.typeKind; + TypeKind tkDest = asArray(destObj->getType()).componentType.typeKind; + if (tkSource != tkDest) + sysThrowArrayStoreException(); + + JavaArray& srcArray = *reinterpret_cast(srcObj); + JavaArray& dstArray = *reinterpret_cast(destObj); + + // ChkLimit. + if ((len < 0) || (srcPos < 0) || (destPos < 0) || (uint32(len + srcPos) > srcArray.length) || + (uint32(len + destPos) > dstArray.length)) { + + sysThrowArrayIndexOutOfBoundsException(); + assert("never come back"); + } + + // Do the copy. + int offset = arrayEltsOffset(tkSource); + char* srcPtr = ((char *) &srcArray) + offset; + char* destPtr = ((char *) &dstArray) + offset; + int8 shift = getLgTypeKindSize(tkSource); + + memmove(&destPtr[destPos << shift], &srcPtr[srcPos << shift], len << shift); +} + +/* + * Class : java/lang/System + * Method : getCallerClass + * Signature : ()Ljava/lang/Class; + */ +NS_EXPORT NS_NATIVECALL(Java_java_lang_Class *) +Netscape_Java_java_lang_System_getCallerClass() +{ + Frame thisFrame; + Method* callerMethod; + + thisFrame.moveToPrevFrame(); // system guard frame + thisFrame.moveToPrevFrame(); // java frame + callerMethod = thisFrame.getMethod(); + + // FIX-ME should call some RuntimeException here + if (!callerMethod) + { + trespass("Caller was not a Java function!!"); + return 0; + } + else + { + ClassOrInterface* potentialClass = callerMethod->getDeclaringClass(); + assert(potentialClass); // FIX-ME this might be guaranteed to me non-NULL + return ((Java_java_lang_Class*)&asClass(*potentialClass)); + } +} + + +/* + * Class : java/lang/System + * Method : identityHashCode + * Signature : (Ljava/lang/Object;)I + */ +NS_EXPORT NS_NATIVECALL(int32) +Netscape_Java_java_lang_System_identityHashCode(Java_java_lang_Object *) +{ +#ifdef DEBUG_LOG + PR_fprintf(PR_STDERR, "Warning: System::hashCode() not implemented\n"); +#endif + return 0; +} + + +/* + * Class : java/lang/System + * Method : initProperties + * Signature : (Ljava/util/Properties;)Ljava/util/Properties; + */ +NS_EXPORT NS_NATIVECALL(Java_java_util_Properties *) +Netscape_Java_java_lang_System_initProperties(Java_java_util_Properties *props) +{ + // FIXME: should we check the security manager for checkPropertiesAccess ? + + const Type* parameterTypesForPropertyPut[2]; + + parameterTypesForPropertyPut[0] = (Type *) &VM::getStandardClass(cObject); + parameterTypesForPropertyPut[1] = (Type *) &VM::getStandardClass(cObject); + + Method& Property_put = const_cast(&props->getClass())->getMethod("put", parameterTypesForPropertyPut, 2); + JavaObject* arguments[2]; + +#define PUTPROP(key,value) { \ + arguments[0] = JavaString::make(key); \ + arguments[1] = JavaString::make(value); \ + Property_put.invoke(props, arguments, 2); \ + } + + + /* java properties */ + PUTPROP("java-vm.specification.version", "?.?"); + PUTPROP("java-vm.specification.name", "???"); + PUTPROP("java-vm.specification.vendor", "???"); + PUTPROP("java-vm.version", "?.?"); + PUTPROP("java-vm.name", "Electrical Fire"); + PUTPROP("java-vm.vendor", "???"); + + PUTPROP("java.specification.version", "?.?"); + PUTPROP("java.specification.name", "???"); + PUTPROP("java.specification.vendor", "???"); + + PUTPROP("java.version", "?"); + PUTPROP("java.vendor", "???"); + PUTPROP("java.vendor.url", "home.netscape.com"); + PUTPROP("java.vendor.url.bug", "home.netscape.com/bugreport.cgi"); + PUTPROP("java.class.version", "?.?"); + + /* Java2D properties */ + PUTPROP("java.awt.graphicsenv", "sun.awt.GraphicsEnvironment"); + PUTPROP("java.awt.fonts", "you wanna fonts?"); + + /* os properties */ + PUTPROP("os.name", "???"); + PUTPROP("os.version", "???"); + PUTPROP("os.arch", "???"); + + /* file system properties */ + PUTPROP("file.separator", "/ or \\"); + PUTPROP("path.separator", ": or ;"); + PUTPROP("line.separator", "\n"); + + /* + * user.language + * user.region (if user's environmant specify this) + * file.encoding + * file.encoding.pkg + */ + + PUTPROP("user.language", "???"); + PUTPROP("file.encoding", "???"); + PUTPROP("user.region", "???"); + PUTPROP("file.encoding.pkg", "sun.io"); + + /* system */ + PUTPROP("java.library.path", "???"); + PUTPROP("java.home", "???"); + PUTPROP("java.class.path", "\ns\dist\classes"); + PUTPROP("user.name", "???"); + PUTPROP("user.home", "???"); + PUTPROP("user.timezone", "???"); + PUTPROP("user.dir", "???"); + PUTPROP("java.compiler", "???"); + + return props; +} + + + + +} /* extern "C" */ + diff --git a/ef/Packages/java/lang/nativesrc/Thread.cpp b/ef/Packages/java/lang/nativesrc/Thread.cpp new file mode 100644 index 000000000000..a378f974c7df --- /dev/null +++ b/ef/Packages/java/lang/nativesrc/Thread.cpp @@ -0,0 +1,221 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#include "java_lang_Thread.h" +#include "Thread.h" + +extern "C" { +/* + * Class : java/lang/Thread + * Method : currentThread + * Signature : ()Ljava/lang/Thread; + */ +NS_EXPORT NS_NATIVECALL(Java_java_lang_Thread *) +Netscape_Java_java_lang_Thread_currentThread() +{ + return (Java_java_lang_Thread *)Thread::currentThread(); +} + + +/* + * Class : java/lang/Thread + * Method : yield + * Signature : ()V + */ +NS_EXPORT NS_NATIVECALL(void) +Netscape_Java_java_lang_Thread_yield() +{ + Thread::yield(); +} + + +/* + * Class : java/lang/Thread + * Method : sleep + * Signature : (J)V + */ +NS_EXPORT NS_NATIVECALL(void) +Netscape_Java_java_lang_Thread_sleep(int64 l) +{ + Thread::sleep(l); +} + + +/* + * Class : java/lang/Thread + * Method : start + * Signature : ()V + */ +NS_EXPORT NS_NATIVECALL(void) +Netscape_Java_java_lang_Thread_start(Java_java_lang_Thread *t) +{ + Thread* thr = (Thread*)static_cast(t->eetop); + if (thr == NULL) { + //thr = new(*Thread::pool) Thread((JavaObject*)t); + thr = new Thread((JavaObject*)t); + t->eetop = (int64)thr; + } + thr->start(); +} + + +/* + * Class : java/lang/Thread + * Method : isInterrupted + * Signature : (Z)Z + */ +NS_EXPORT NS_NATIVECALL(uint32) /* bool */ +Netscape_Java_java_lang_Thread_isInterrupted(Java_java_lang_Thread *t, uint32 f) +{ + Thread* thr = (Thread*)static_cast(t->eetop); + if (thr == NULL) { + //thr = new(*Thread::pool) Thread((JavaObject*)t); + thr = new Thread((JavaObject*)t); + t->eetop = (int64)thr; + } + return thr->isInterrupted(f); +} + + +/* + * Class : java/lang/Thread + * Method : isAlive + * Signature : ()Z + */ +NS_EXPORT NS_NATIVECALL(uint32) /* bool */ +Netscape_Java_java_lang_Thread_isAlive(Java_java_lang_Thread *t) +{ + Thread* thr = (Thread*)static_cast(t->eetop); + if (thr == NULL) { + //thr = new(*Thread::pool) Thread((JavaObject*)t); + thr = new Thread((JavaObject*)t); + t->eetop = (int64)thr; + } + return thr->isAlive(); +} + + +/* + * Class : java/lang/Thread + * Method : countStackFrames + * Signature : ()I + */ +NS_EXPORT NS_NATIVECALL(int32) +Netscape_Java_java_lang_Thread_countStackFrames(Java_java_lang_Thread *t) +{ + Thread* thr = (Thread*)static_cast(t->eetop); + if (thr == NULL) { + //thr = new(*Thread::pool) Thread((JavaObject*)t); + thr = new Thread((JavaObject*)t); + t->eetop = (int64)thr; + } + return thr->countStackFrames(); +} + + +/* + * Class : java/lang/Thread + * Method : setPriority0 + * Signature : (I)V + */ +NS_EXPORT NS_NATIVECALL(void) +Netscape_Java_java_lang_Thread_setPriority0(Java_java_lang_Thread *t, int32 p) +{ + Thread* thr = (Thread*)static_cast(t->eetop); + if (thr == NULL) { + //thr = new(*Thread::pool) Thread((JavaObject*)t); + thr = new Thread((JavaObject*)t); + t->eetop = (int64)thr; + } + thr->setPriority(p); +} + + +/* + * Class : java/lang/Thread + * Method : stop0 + * Signature : (Ljava/lang/Object;)V + */ +NS_EXPORT NS_NATIVECALL(void) +Netscape_Java_java_lang_Thread_stop0(Java_java_lang_Thread *t, Java_java_lang_Object *exc) +{ + Thread* thr = (Thread*)static_cast(t->eetop); + if (thr == NULL) { + //thr = new(*Thread::pool) Thread((JavaObject*)t); + thr = new Thread((JavaObject*)t); + t->eetop = (int64)thr; + } + thr->stop((JavaObject*)exc); +} + + +/* + * Class : java/lang/Thread + * Method : suspend0 + * Signature : ()V + */ +NS_EXPORT NS_NATIVECALL(void) +Netscape_Java_java_lang_Thread_suspend0(Java_java_lang_Thread *t) +{ + Thread* thr = (Thread*)static_cast(t->eetop); + if (thr == NULL) { + //thr = new(*Thread::pool) Thread((JavaObject*)t); + thr = new Thread((JavaObject*)t); + t->eetop = (int64)thr; + } + thr->suspend(); +} + + +/* + * Class : java/lang/Thread + * Method : resume0 + * Signature : ()V + */ +NS_EXPORT NS_NATIVECALL(void) +Netscape_Java_java_lang_Thread_resume0(Java_java_lang_Thread *t) +{ + Thread* thr = (Thread*)static_cast(t->eetop); + if (thr == NULL) { + //thr = new(*Thread::pool) Thread((JavaObject*)t); + thr = new Thread((JavaObject*)t); + t->eetop = (int64)thr; + } + thr->resume(); +} + + +/* + * Class : java/lang/Thread + * Method : interrupt0 + * Signature : ()V + */ +NS_EXPORT NS_NATIVECALL(void) +Netscape_Java_java_lang_Thread_interrupt0(Java_java_lang_Thread *t) +{ + Thread* thr = (Thread*)static_cast(t->eetop); + if (thr == NULL) { + //thr = new(*Thread::pool) Thread((JavaObject*)t); + thr = new Thread((JavaObject*)t); + t->eetop = (int64)thr; + } + thr->interrupt(); +} + + +} /* extern "C" */ + diff --git a/ef/Packages/java/lang/nativesrc/Throwable.cpp b/ef/Packages/java/lang/nativesrc/Throwable.cpp new file mode 100644 index 000000000000..2b45f835d2ea --- /dev/null +++ b/ef/Packages/java/lang/nativesrc/Throwable.cpp @@ -0,0 +1,48 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#include "java_lang_Throwable.h" +#include + +extern "C" { +/* + * Class : java/lang/Throwable + * Method : printStackTrace0 + * Signature : (Ljava/lang/Object;)V + */ +NS_EXPORT NS_NATIVECALL(void) +Netscape_Java_java_lang_Throwable_printStackTrace0(Java_java_lang_Throwable *, Java_java_lang_Object *) +{ + printf("Netscape_Java_java_lang_Throwable_printStackTrace0() not implemented"); +} + + +/* + * Class : java/lang/Throwable + * Method : fillInStackTrace + * Signature : ()Ljava/lang/Throwable; + */ +NS_EXPORT NS_NATIVECALL(Java_java_lang_Throwable *) +Netscape_Java_java_lang_Throwable_fillInStackTrace(Java_java_lang_Throwable *) +{ + //printf("Netscape_Java_java_lang_Throwable_fillInStackTrace() not implemented"); + return 0; +} + + +} /* extern "C" */ + diff --git a/ef/Packages/java/lang/nativesrc/geninclude/.cvsignore b/ef/Packages/java/lang/nativesrc/geninclude/.cvsignore new file mode 100644 index 000000000000..25e200774236 --- /dev/null +++ b/ef/Packages/java/lang/nativesrc/geninclude/.cvsignore @@ -0,0 +1 @@ +java_* diff --git a/ef/Packages/java/lang/nativesrc/manifest.mn b/ef/Packages/java/lang/nativesrc/manifest.mn new file mode 100644 index 000000000000..5e0ccbde5578 --- /dev/null +++ b/ef/Packages/java/lang/nativesrc/manifest.mn @@ -0,0 +1,43 @@ +#!gmake +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +DEPTH = ../../../.. + +MODULE_NAME = Package + +DIRS = reflect + +CPPSRCS = Character.cpp \ + Class.cpp \ + ClassLoader.cpp \ + Compiler.cpp \ + Double.cpp \ + Float.cpp \ + Math.cpp \ + Object.cpp \ + Runtime.cpp \ + SecurityManager.cpp \ + String.cpp \ + System.cpp \ + Thread.cpp \ + Throwable.cpp \ + $(NULL) + +HEADER_GEN = java.lang.Object \ + $(NULL) + + diff --git a/ef/Packages/java/lang/nativesrc/reflect/Array.cpp b/ef/Packages/java/lang/nativesrc/reflect/Array.cpp new file mode 100644 index 000000000000..1649ac2367a0 --- /dev/null +++ b/ef/Packages/java/lang/nativesrc/reflect/Array.cpp @@ -0,0 +1,509 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#include "java_lang_reflect_Array.h" +#include +#include "SysCallsRuntime.h" +#include "ErrorHandling.h" + +static inline JavaArray &toArray(Java_java_lang_Object *obj) +{ + if (!obj) + sysThrowNullPointerException(); + + if (obj->type->typeKind != tkArray) + sysThrowNamedException("java/lang/IllegalArgumentException"); + + return *(JavaArray *) obj; +} + +static inline void checkIndex(JavaArray &array, Int32 index) +{ + if (index < 0 || index >= (Int32) array.length) + sysThrowArrayIndexOutOfBoundsException(); +} + + +extern "C" { + + +/* + * Class : java/lang/reflect/Array + * Method : get + * Signature : (Ljava/lang/Object;I)Ljava/lang/Object; + */ +NS_EXPORT NS_NATIVECALL(Java_java_lang_Object *) +Netscape_Java_java_lang_reflect_Array_get(Java_java_lang_Object *obj, int32 index) +{ + JavaArray &array = toArray(obj); + + checkIndex(array, index); + + try { + return (Java_java_lang_Object *) array.get(index); + } catch (RuntimeError) { + sysThrowNamedException("java/lang/IllegalArgumentException"); + } +} + + +/* + * Class : java/lang/reflect/Array + * Method : getBoolean + * Signature : (Ljava/lang/Object;I)Z + */ +NS_EXPORT NS_NATIVECALL(uint32 /* bool */) +Netscape_Java_java_lang_reflect_Array_getBoolean(Java_java_lang_Object *obj, + int32 index) +{ + JavaArray &array = toArray(obj); + + checkIndex(array, index); + + try { + return array.getBoolean(index); + } catch (RuntimeError) { + sysThrowNamedException("java/lang/IllegalArgumentException"); + } +} + + +/* + * Class : java/lang/reflect/Array + * Method : getByte + * Signature : (Ljava/lang/Object;I)B + */ +NS_EXPORT NS_NATIVECALL(uint32 /* byte */) +Netscape_Java_java_lang_reflect_Array_getByte(Java_java_lang_Object *obj, + int32 index) +{ + JavaArray &array = toArray(obj); + + checkIndex(array, index); + + try { + return array.getByte(index); + } catch (RuntimeError) { + sysThrowNamedException("java/lang/IllegalArgumentException"); + } +} + + +/* + * Class : java/lang/reflect/Array + * Method : getChar + * Signature : (Ljava/lang/Object;I)C + */ +NS_EXPORT NS_NATIVECALL(int32 /* char */) +Netscape_Java_java_lang_reflect_Array_getChar(Java_java_lang_Object *obj, + int32 index) +{ + JavaArray &array = toArray(obj); + + checkIndex(array, index); + + try { + return array.getChar(index); + } catch (RuntimeError) { + sysThrowNamedException("java/lang/IllegalArgumentException"); + } +} + + +/* + * Class : java/lang/reflect/Array + * Method : getDouble + * Signature : (Ljava/lang/Object;I)D + */ +NS_EXPORT NS_NATIVECALL(Flt64) +Netscape_Java_java_lang_reflect_Array_getDouble(Java_java_lang_Object *obj, + int32 index) +{ + JavaArray &array = toArray(obj); + + checkIndex(array, index); + + try { + return array.getDouble(index); + } catch (RuntimeError) { + sysThrowNamedException("java/lang/IllegalArgumentException"); + } +} + + +/* + * Class : java/lang/reflect/Array + * Method : getFloat + * Signature : (Ljava/lang/Object;I)F + */ +NS_EXPORT NS_NATIVECALL(Flt32) +Netscape_Java_java_lang_reflect_Array_getFloat(Java_java_lang_Object *obj, + int32 index) +{ + JavaArray &array = toArray(obj); + + checkIndex(array, index); + + try { + return array.getFloat(index); + } catch (RuntimeError) { + sysThrowNamedException("java/lang/IllegalArgumentException"); + } +} + + +/* + * Class : java/lang/reflect/Array + * Method : getInt + * Signature : (Ljava/lang/Object;I)I + */ +NS_EXPORT NS_NATIVECALL(int32) +Netscape_Java_java_lang_reflect_Array_getInt(Java_java_lang_Object *obj, + int32 index) +{ + JavaArray &array = toArray(obj); + + checkIndex(array, index); + + try { + return array.getInt(index); + } catch (RuntimeError) { + sysThrowNamedException("java/lang/IllegalArgumentException"); + } +} + + +/* + * Class : java/lang/reflect/Array + * Method : getLength + * Signature : (Ljava/lang/Object;)I + */ +NS_EXPORT NS_NATIVECALL(int32) +Netscape_Java_java_lang_reflect_Array_getLength(Java_java_lang_Object *obj) +{ + JavaArray &array = toArray(obj); + + return array.length; +} + + +/* + * Class : java/lang/reflect/Array + * Method : getLong + * Signature : (Ljava/lang/Object;I)J + */ +NS_EXPORT NS_NATIVECALL(int64) +Netscape_Java_java_lang_reflect_Array_getLong(Java_java_lang_Object *obj, int32 index) +{ + JavaArray &array = toArray(obj); + + checkIndex(array, index); + + try { + return array.getLong(index); + } catch (RuntimeError) { + sysThrowNamedException("java/lang/IllegalArgumentException"); + } +} + + +/* + * Class : java/lang/reflect/Array + * Method : getShort + * Signature : (Ljava/lang/Object;I)S + */ +NS_EXPORT NS_NATIVECALL(int32 /* short */) +Netscape_Java_java_lang_reflect_Array_getShort(Java_java_lang_Object *obj, int32 index) +{ + JavaArray &array = toArray(obj); + + checkIndex(array, index); + + try { + return array.getShort(index); + } catch (RuntimeError) { + sysThrowNamedException("java/lang/IllegalArgumentException"); + } +} + + +/* + * Class : java/lang/reflect/Array + * Method : multiNewArray + * Signature : (Ljava/lang/Class;[I)Ljava/lang/Object; + */ +NS_EXPORT NS_NATIVECALL(Java_java_lang_Object *) +Netscape_Java_java_lang_reflect_Array_multiNewArray(Java_java_lang_Class *inClass, + ArrayOf_int32 *dimensions) +{ + if (!inClass || !dimensions) + sysThrowNullPointerException(); + + if (dimensions->length < 0) + sysThrowNamedException("java/lang/NegativeArraySizeException"); + else if (dimensions->length >= 255 || dimensions->length == 0) + sysThrowNamedException("java/lang/IllegalArgumentException"); + + /* We special-case 2D and 3D arrays since we have sysCalls defined for them */ + Int32 numDimensions = dimensions->length; + + switch (numDimensions) { + case 2: + return (Java_java_lang_Object *) sysNew2DArray(&((Type *) inClass)->getArrayType().getArrayType(), + dimensions->elements[0], + dimensions->elements[1]); + + case 3: + return (Java_java_lang_Object *) sysNew3DArray(&((Type *) inClass)->getArrayType().getArrayType().getArrayType(), + dimensions->elements[0], + dimensions->elements[1], + dimensions->elements[2]); + default: + return (Java_java_lang_Object *) sysNewNDArray((const Type *) inClass, dimensions); + } + +} + + +/* + * Class : java/lang/reflect/Array + * Method : newArray + * Signature : (Ljava/lang/Class;I)Ljava/lang/Object; + */ +NS_EXPORT NS_NATIVECALL(Java_java_lang_Object *) +Netscape_Java_java_lang_reflect_Array_newArray(Java_java_lang_Class *inClass, + int32 size) +{ + if (!inClass) + sysThrowNullPointerException(); + + if (size < 0) + sysThrowNamedException("java/lang/NegativeArraySizeException"); + + const Type *typeOfArray = (const Type *) inClass; + + if (typeOfArray->isPrimitive()) { + JavaArray *primitiveArray = (JavaArray *) sysNewPrimitiveArray(typeOfArray->typeKind, + size); + + return (Java_java_lang_Object *) primitiveArray; + } else { + JavaArray *objectArray = (JavaArray *) sysNewObjectArray(typeOfArray, size); + + return (Java_java_lang_Object *) objectArray; + } +} + + +/* + * Class : java/lang/reflect/Array + * Method : set + * Signature : (Ljava/lang/Object;ILjava/lang/Object;)V + */ +NS_EXPORT NS_NATIVECALL(void) +Netscape_Java_java_lang_reflect_Array_set(Java_java_lang_Object *obj, int32 index, + Java_java_lang_Object *value) +{ + JavaArray &array = toArray(obj); + + checkIndex(array, index); + + try { + array.set(index, value); + } catch (RuntimeError) { + sysThrowNamedException("java/lang/IllegalArgumentException"); + } +} + + +/* + * Class : java/lang/reflect/Array + * Method : setBoolean + * Signature : (Ljava/lang/Object;IZ)V + */ +NS_EXPORT NS_NATIVECALL(void) +Netscape_Java_java_lang_reflect_Array_setBoolean(Java_java_lang_Object *obj, + int32 index, + uint32 /* bool */ value) +{ + JavaArray &array = toArray(obj); + + checkIndex(array, index); + + try { + array.setBoolean(index, (Int8) value); + } catch (RuntimeError) { + sysThrowNamedException("java/lang/IllegalArgumentException"); + } +} + + +/* + * Class : java/lang/reflect/Array + * Method : setByte + * Signature : (Ljava/lang/Object;IB)V + */ +NS_EXPORT NS_NATIVECALL(void) +Netscape_Java_java_lang_reflect_Array_setByte(Java_java_lang_Object *obj, + int32 index, + uint32 /* byte */ value) +{ + JavaArray &array = toArray(obj); + + checkIndex(array, index); + + try { + array.setByte(index, (Int8) value); + } catch (RuntimeError) { + sysThrowNamedException("java/lang/IllegalArgumentException"); + } +} + + +/* + * Class : java/lang/reflect/Array + * Method : setChar + * Signature : (Ljava/lang/Object;IC)V + */ +NS_EXPORT NS_NATIVECALL(void) +Netscape_Java_java_lang_reflect_Array_setChar(Java_java_lang_Object *obj, + int32 index, + int32 /* char */ value) +{ + JavaArray &array = toArray(obj); + + checkIndex(array, index); + + try { + array.setChar(index, (Int16) value); + } catch (RuntimeError) { + sysThrowNamedException("java/lang/IllegalArgumentException"); + } +} + + +/* + * Class : java/lang/reflect/Array + * Method : setDouble + * Signature : (Ljava/lang/Object;ID)V + */ +NS_EXPORT NS_NATIVECALL(void) +Netscape_Java_java_lang_reflect_Array_setDouble(Java_java_lang_Object *obj, + int32 index, + Flt64 value) +{ + JavaArray &array = toArray(obj); + + checkIndex(array, index); + + try { + array.setDouble(index, value); + } catch (RuntimeError) { + sysThrowNamedException("java/lang/IllegalArgumentException"); + } +} + + +/* + * Class : java/lang/reflect/Array + * Method : setFloat + * Signature : (Ljava/lang/Object;IF)V + */ +NS_EXPORT NS_NATIVECALL(void) +Netscape_Java_java_lang_reflect_Array_setFloat(Java_java_lang_Object *obj, + int32 index, Flt32 value) +{ + JavaArray &array = toArray(obj); + + checkIndex(array, index); + + try { + array.setFloat(index, value); + } catch (RuntimeError) { + sysThrowNamedException("java/lang/IllegalArgumentException"); + } +} + + +/* + * Class : java/lang/reflect/Array + * Method : setInt + * Signature : (Ljava/lang/Object;II)V + */ +NS_EXPORT NS_NATIVECALL(void) +Netscape_Java_java_lang_reflect_Array_setInt(Java_java_lang_Object *obj, + int32 index, + int32 value) +{ + JavaArray &array = toArray(obj); + + checkIndex(array, index); + + try { + array.setInt(index, value); + } catch (RuntimeError) { + sysThrowNamedException("java/lang/IllegalArgumentException"); + } +} + + +/* + * Class : java/lang/reflect/Array + * Method : setLong + * Signature : (Ljava/lang/Object;IJ)V + */ +NS_EXPORT NS_NATIVECALL(void) +Netscape_Java_java_lang_reflect_Array_setLong(Java_java_lang_Object *obj, + int32 index, + int64 value) +{ + JavaArray &array = toArray(obj); + + checkIndex(array, index); + + try { + array.setLong(index, value); + } catch (RuntimeError) { + sysThrowNamedException("java/lang/IllegalArgumentException"); + } +} + + +/* + * Class : java/lang/reflect/Array + * Method : setShort + * Signature : (Ljava/lang/Object;IS)V + */ +NS_EXPORT NS_NATIVECALL(void) +Netscape_Java_java_lang_reflect_Array_setShort(Java_java_lang_Object *obj, int32 index, + int32 /* short */value) +{ + JavaArray &array = toArray(obj); + + checkIndex(array, index); + + try { + array.setShort(index, (Int16) value); + } catch (RuntimeError) { + sysThrowNamedException("java/lang/IllegalArgumentException"); + } +} + +} + + + diff --git a/ef/Packages/java/lang/nativesrc/reflect/Constructor.cpp b/ef/Packages/java/lang/nativesrc/reflect/Constructor.cpp new file mode 100644 index 000000000000..affee0a3fc10 --- /dev/null +++ b/ef/Packages/java/lang/nativesrc/reflect/Constructor.cpp @@ -0,0 +1,209 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#include "java_lang_reflect_Constructor.h" +#include "java_lang_Class.h" + +#include "JavaVM.h" +#include "FieldOrMethod.h" +#include "SysCallsRuntime.h" +#include "StackWalker.h" + +#include + +// Make sure that the class that called this method can access this field. +// Throw an IllegalAccessException if it can't. +static inline void checkCallingClass(const Method &method) +{ + Frame thisFrame; + Method &callerMethod = thisFrame.getCallingJavaMethod(); + + if (callerMethod.getDeclaringClass() != method.getDeclaringClass()) { + if ((method.getModifiers() & CR_METHOD_PRIVATE)) + sysThrowNamedException("java/lang/IllegalAccessException"); + else if ((method.getModifiers() & CR_METHOD_PROTECTED)) { + if (!method.getDeclaringClass()->isAssignableFrom(*(const Type *) callerMethod.getDeclaringClass())) + sysThrowNamedException("java/lang/IllegalAccessException"); + } + } +} + +static void throwConstructorException(RuntimeError err) +{ + // FIXME Need to check for illegalAccess, which we currently do not enforce + // Also need to throw an InvocationTargetException + switch (err.cause) { + case RuntimeError::nullPointer: + sysThrowNullPointerException(); + break; + + case RuntimeError::illegalArgument: + sysThrowNamedException("java/lang/IllegalArgumentException"); + break; + + case RuntimeError::notInstantiable: + sysThrowNamedException("java/lang/InstantiationException"); + break; + + default: + trespass("Unknown Runtime Error in throwConstructorException()"); + } +} + +extern "C" { + +/* XXX Routines returning strings will have to be redone once the VM supports + * unicode strings directly + */ + +static inline Constructor &toConstructor(Java_java_lang_reflect_Constructor *inConstr) +{ + if (!inConstr) + sysThrowNullPointerException(); + + return *(Constructor *) inConstr; +} + +/* + * Class : java/lang/reflect/Constructor + * Method : equals + * Signature : (Ljava/lang/Object;)Z + */ +NS_EXPORT NS_NATIVECALL(uint32 /* bool */) +Netscape_Java_java_lang_reflect_Constructor_equals(Java_java_lang_reflect_Constructor *inConstr, + Java_java_lang_Object *inObj) +{ + Constructor &constructor = toConstructor(inConstr); + JavaObject *obj = (JavaObject *) inObj; + + return obj && constructor.equals(*obj); +} + + +/* + * Class : java/lang/reflect/Constructor + * Method : getDeclaringClass + * Signature : ()Ljava/lang/Class; + */ +NS_EXPORT NS_NATIVECALL(Java_java_lang_Class *) +Netscape_Java_java_lang_reflect_Constructor_getDeclaringClass(Java_java_lang_reflect_Constructor *inConstr) +{ + Constructor &constructor = toConstructor(inConstr); + + return ((Java_java_lang_Class *) constructor.getDeclaringClass()); +} + + +/* + * Class : java/lang/reflect/Constructor + * Method : getExceptionTypes + * Signature : ()[Ljava/lang/Class; + */ +NS_EXPORT NS_NATIVECALL(ArrayOf_Java_java_lang_Class *) +Netscape_Java_java_lang_reflect_Constructor_getExceptionTypes(Java_java_lang_reflect_Constructor *) +{ + printf("Netscape_Java_java_lang_reflect_Constructor_getExceptionTypes() not implemented\n"); + return 0; +} + + +/* + * Class : java/lang/reflect/Constructor + * Method : getModifiers + * Signature : ()I + */ +NS_EXPORT NS_NATIVECALL(int32) +Netscape_Java_java_lang_reflect_Constructor_getModifiers(Java_java_lang_reflect_Constructor *inConstr) +{ + Constructor &constructor = toConstructor(inConstr); + + return constructor.getModifiers(); +} + + +/* + * Class : java/lang/reflect/Constructor + * Method : getParameterTypes + * Signature : ()[Ljava/lang/Class; + */ +NS_EXPORT NS_NATIVECALL(ArrayOf_Java_java_lang_Class *) +Netscape_Java_java_lang_reflect_Constructor_getParameterTypes(Java_java_lang_reflect_Constructor *inConstr) +{ + Constructor &constructor = toConstructor(inConstr); + + const Type **params; + Int32 numParams; + + numParams = constructor.getParameterTypes(params); + + void *arr = sysNewObjectArray(&VM::getStandardClass(cClass), numParams-1); + + ArrayOf_Java_java_lang_Class *clazzArray = (ArrayOf_Java_java_lang_Class *) arr; + + // The first parameter is always ourselves + for (Int32 i = 1; i < numParams; i++) + clazzArray->elements[i-1] = (Java_java_lang_Class *)params[i]; + + return clazzArray; +} + + +/* + * Class : java/lang/reflect/Constructor + * Method : newInstance + * Signature : ([Ljava/lang/Object;)Ljava/lang/Object; + */ +NS_EXPORT NS_NATIVECALL(Java_java_lang_Object *) +Netscape_Java_java_lang_reflect_Constructor_newInstance(Java_java_lang_reflect_Constructor *inConstr, + ArrayOf_Java_java_lang_Object *inParams) +{ + Constructor &constructor = toConstructor(inConstr); + + checkCallingClass(constructor); + + JavaObject **params = (JavaObject **) inParams->elements; + Int32 numParams = (inParams) ? inParams->length : 0; + + try { + return (Java_java_lang_Object *) &constructor.newInstance(params, numParams); + } catch (RuntimeError err) { + throwConstructorException(err); + } +} + + +/* + * Class : java/lang/reflect/Constructor + * Method : toString + * Signature : ()Ljava/lang/String; + */ +NS_EXPORT NS_NATIVECALL(Java_java_lang_String *) +Netscape_Java_java_lang_reflect_Constructor_toString(Java_java_lang_reflect_Constructor *inConstr) +{ + Constructor &constructor = toConstructor(inConstr); + + const char *str = constructor.toString(); + + return ((Java_java_lang_String *) &VM::intern(str)); +} + +} + + + + + diff --git a/ef/Packages/java/lang/nativesrc/reflect/Field.cpp b/ef/Packages/java/lang/nativesrc/reflect/Field.cpp new file mode 100644 index 000000000000..1674a9fa07f6 --- /dev/null +++ b/ef/Packages/java/lang/nativesrc/reflect/Field.cpp @@ -0,0 +1,564 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#include +#include "java_lang_reflect_Field.h" +#include "java_lang_Class.h" + +#include "JavaVM.h" +#include "SysCallsRuntime.h" +#include "StackWalker.h" + +static inline void throwFieldException(RuntimeError err) +{ + // FIXME Need to check for illegalAccess, which we currently do not enforce + if (err.cause == RuntimeError::nullPointer) + sysThrowNullPointerException(); + else if (err.cause == RuntimeError::illegalArgument) + sysThrowNamedException("java/lang/IllegalArgumentException"); + else + trespass("Unknown Runtime Error in throwFieldException()"); +} + +extern "C" { + +/* XXX Routines returning strings will have to be redone once the VM supports + * unicode strings directly + */ + +static inline Field &toField(Java_java_lang_reflect_Field *inField) +{ + if (!inField) + sysThrowNullPointerException(); + + return *(Field *) inField; +} + + +/* + * Class : java/lang/reflect/Field + * Method : equals + * Signature : (Ljava/lang/Object;)Z + */ +NS_EXPORT NS_NATIVECALL(uint32 /* bool */) +Netscape_Java_java_lang_reflect_Field_equals(Java_java_lang_reflect_Field *inField, + Java_java_lang_Object *inObj) +{ + Field &field = toField(inField); + + JavaObject *obj = (JavaObject *) inObj; + + return obj && field.equals(*obj); +} + +// Make sure that the class that called this method can access this field. +// Throw an IllegalAccessException if it can't. +static inline void checkCallingClass(const Field &field) +{ + Frame thisFrame; + Method &callerMethod = thisFrame.getCallingJavaMethod(); + + if (callerMethod.getDeclaringClass() != field.getDeclaringClass()) { + if ((field.getModifiers() & CR_FIELD_PRIVATE)) + sysThrowNamedException("java/lang/IllegalAccessException"); + else if ((field.getModifiers() & CR_FIELD_PROTECTED)) { + if (!field.getDeclaringClass()->isAssignableFrom(*(const Type *) callerMethod.getDeclaringClass())) + sysThrowNamedException("java/lang/IllegalAccessException"); + } + } +} + + +#if 0 + /* Warning this code assumes that the caller was a Java Method */\ + thisFrame.moveToPrevFrame(); /* system guard frame */\ + thisFrame.moveToPrevFrame(); /* java frame */\ + Method *callerMethod = thisFrame.getMethod();\ + if (callerMethod->getDeclaringClass() != field.getDeclaringClass()) {\ + if ((field.getModifiers() & CR_FIELD_PRIVATE)) \ + sysThrowNamedException("java/lang/IllegalAccessException");\ + else if ((field.getModifiers() & CR_FIELD_PROTECTED)) {\ + if (!field.getDeclaringClass()->isAssignableFrom(*(const Type *) callerMethod->getDeclaringClass()))\ + sysThrowNamedException("java/lang/IllegalAccessException");\ + }\ + } +#endif + +/* + * Class : java/lang/reflect/Field + * Method : get + * Signature : (Ljava/lang/Object;)Ljava/lang/Object; + */ +NS_EXPORT NS_NATIVECALL(Java_java_lang_Object *) +Netscape_Java_java_lang_reflect_Field_get(Java_java_lang_reflect_Field *inField, + Java_java_lang_Object *obj) +{ + Field &field = toField(inField); + + checkCallingClass(field); + + try { + return (Java_java_lang_Object *)&field.get((JavaObject *) obj); + } catch (RuntimeError err) { + throwFieldException(err); + } + +} + + +/* + * Class : java/lang/reflect/Field + * Method : getBoolean + * Signature : (Ljava/lang/Object;)Z + */ +NS_EXPORT NS_NATIVECALL(uint32 /* bool */) +Netscape_Java_java_lang_reflect_Field_getBoolean(Java_java_lang_reflect_Field *inField, + Java_java_lang_Object *obj) +{ + Field &field = toField(inField); + + checkCallingClass(field); + + try { + return field.getBoolean((JavaObject *) obj); + } catch (RuntimeError err) { + throwFieldException(err); + } + +} + + +/* + * Class : java/lang/reflect/Field + * Method : getByte + * Signature : (Ljava/lang/Object;)B + */ +NS_EXPORT NS_NATIVECALL(uint32 /* byte */) +Netscape_Java_java_lang_reflect_Field_getByte(Java_java_lang_reflect_Field *inField, + Java_java_lang_Object *obj) +{ + Field &field = toField(inField); + + checkCallingClass(field); + + try { + return field.getByte((JavaObject *) obj); + } catch (RuntimeError err) { + throwFieldException(err); + } +} + + + +/* + * Class : java/lang/reflect/Field + * Method : getChar + * Signature : (Ljava/lang/Object;)C + */ +NS_EXPORT NS_NATIVECALL(int32 /* char */) +Netscape_Java_java_lang_reflect_Field_getChar(Java_java_lang_reflect_Field *inField, + Java_java_lang_Object *obj) +{ + Field &field = toField(inField); + + checkCallingClass(field); + + try { + return field.getChar((JavaObject *) obj); + } catch (RuntimeError err) { + throwFieldException(err); + } +} + + +/* + * Class : java/lang/reflect/Field + * Method : getDouble + * Signature : (Ljava/lang/Object;)D + */ +NS_EXPORT NS_NATIVECALL(Flt64) + Netscape_Java_java_lang_reflect_Field_getDouble(Java_java_lang_reflect_Field *inField, + Java_java_lang_Object *obj) +{ + Field &field = toField(inField); + + checkCallingClass(field); + + try { + return field.getDouble((JavaObject *) obj); + } catch (RuntimeError err) { + throwFieldException(err); + } +} + + +/* + * Class : java/lang/reflect/Field + * Method : getFloat + * Signature : (Ljava/lang/Object;)F + */ +NS_EXPORT NS_NATIVECALL(Flt32) +Netscape_Java_java_lang_reflect_Field_getFloat(Java_java_lang_reflect_Field *inField, + Java_java_lang_Object *obj) +{ + Field &field = toField(inField); + + checkCallingClass(field); + + try { + return field.getFloat((JavaObject *) obj); + } catch (RuntimeError err) { + throwFieldException(err); + } +} + + +/* + * Class : java/lang/reflect/Field + * Method : getInt + * Signature : (Ljava/lang/Object;)I + */ +NS_EXPORT NS_NATIVECALL(int32) +Netscape_Java_java_lang_reflect_Field_getInt(Java_java_lang_reflect_Field *inField, + Java_java_lang_Object *obj) +{ + Field &field = toField(inField); + + checkCallingClass(field); + + try { + return field.getInt((JavaObject *) obj); + } catch (RuntimeError err) { + throwFieldException(err); + } +} + + +/* + * Class : java/lang/reflect/Field + * Method : getLong + * Signature : (Ljava/lang/Object;)J + */ +NS_EXPORT NS_NATIVECALL(int64) +Netscape_Java_java_lang_reflect_Field_getLong(Java_java_lang_reflect_Field *inField, + Java_java_lang_Object *obj) +{ + Field &field = toField(inField); + + checkCallingClass(field); + + try { + return field.getLong((JavaObject *) obj); + } catch (RuntimeError err) { + throwFieldException(err); + } +} + + +/* + * Class : java/lang/reflect/Field + * Method : getShort + * Signature : (Ljava/lang/Object;)S + */ +NS_EXPORT NS_NATIVECALL(int32 /* short */) +Netscape_Java_java_lang_reflect_Field_getShort(Java_java_lang_reflect_Field *inField, + Java_java_lang_Object *obj) +{ + Field &field = toField(inField); + + checkCallingClass(field); + + try { + return field.getShort((JavaObject *) obj); + } catch (RuntimeError err) { + throwFieldException(err); + } +} + +/* + * Class : java/lang/reflect/Field + * Method : getDeclaringClass + * Signature : ()Ljava/lang/Class; + */ +NS_EXPORT NS_NATIVECALL(Java_java_lang_Class *) +Netscape_Java_java_lang_reflect_Field_getDeclaringClass(Java_java_lang_reflect_Field *inField) +{ + Field &field = toField(inField); + + return ((Java_java_lang_Class *) field.getDeclaringClass()); +} + + +/* + * Class : java/lang/reflect/Field + * Method : getModifiers + * Signature : ()I + */ +NS_EXPORT NS_NATIVECALL(int32) +Netscape_Java_java_lang_reflect_Field_getModifiers(Java_java_lang_reflect_Field *inField) +{ + Field &field = toField(inField); + + return field.getModifiers(); +} + + +/* + * Class : java/lang/reflect/Field + * Method : getName + * Signature : ()Ljava/lang/String; + */ +NS_EXPORT NS_NATIVECALL(Java_java_lang_String *) +Netscape_Java_java_lang_reflect_Field_getName(Java_java_lang_reflect_Field *inField) +{ + Field &field = toField(inField); + + const char *str = field.getName(); + + return ((Java_java_lang_String *) &VM::intern(str)); +} + + +/* + * Class : java/lang/reflect/Field + * Method : set + * Signature : (Ljava/lang/Object;Ljava/lang/Object;)V + */ +NS_EXPORT NS_NATIVECALL(void) +Netscape_Java_java_lang_reflect_Field_set(Java_java_lang_reflect_Field *inField, + Java_java_lang_Object *obj, + Java_java_lang_Object *value) +{ + Field &field = toField(inField); + + checkCallingClass(field); + + if (value == 0) + sysThrowNullPointerException(); + + try { + field.set((JavaObject *) obj, *(JavaObject *) value); + } catch (RuntimeError err) { + throwFieldException(err); + } +} + +/* + * Class : java/lang/reflect/Field + * Method : getType + * Signature : ()Ljava/lang/Class; + */ +NS_EXPORT NS_NATIVECALL(Java_java_lang_Class *) +Netscape_Java_java_lang_reflect_Field_getType(Java_java_lang_reflect_Field *inField) +{ + Field &field = toField(inField); + + return (Java_java_lang_Class *) &field.getType(); +} + +/* + * Class : java/lang/reflect/Field + * Method : setBoolean + * Signature : (Ljava/lang/Object;Z)V + */ +NS_EXPORT NS_NATIVECALL(void) +Netscape_Java_java_lang_reflect_Field_setBoolean(Java_java_lang_reflect_Field *inField, + Java_java_lang_Object *obj, + uint32 /* bool */value) +{ + Field &field = toField(inField); + + checkCallingClass(field); + + try { + field.setBoolean((JavaObject *) obj, (Int8) value); + } catch (RuntimeError err) { + throwFieldException(err); + } +} + + +/* + * Class : java/lang/reflect/Field + * Method : setByte + * Signature : (Ljava/lang/Object;B)V + */ +NS_EXPORT NS_NATIVECALL(void) +Netscape_Java_java_lang_reflect_Field_setByte(Java_java_lang_reflect_Field *inField, + Java_java_lang_Object *obj, + uint32 /* byte */value) +{ + Field &field = toField(inField); + + checkCallingClass(field); + + try { + field.setByte((JavaObject *) obj, (Uint8) value); + } catch (RuntimeError err) { + throwFieldException(err); + } +} + + +/* + * Class : java/lang/reflect/Field + * Method : setChar + * Signature : (Ljava/lang/Object;C)V + */ +NS_EXPORT NS_NATIVECALL(void) +Netscape_Java_java_lang_reflect_Field_setChar(Java_java_lang_reflect_Field *inField, + Java_java_lang_Object *obj, + int32 /* char */value) +{ + Field &field = toField(inField); + + checkCallingClass(field); + + try { + field.setChar((JavaObject *) obj, (Int16) value); + } catch (RuntimeError err) { + throwFieldException(err); + } +} + + +/* + * Class : java/lang/reflect/Field + * Method : setDouble + * Signature : (Ljava/lang/Object;D)V + */ +NS_EXPORT NS_NATIVECALL(void) +Netscape_Java_java_lang_reflect_Field_setDouble(Java_java_lang_reflect_Field *inField, + Java_java_lang_Object *obj, + Flt64 value) +{ + Field &field = toField(inField); + + checkCallingClass(field); + + try { + field.setDouble((JavaObject *) obj, value); + } catch (RuntimeError err) { + throwFieldException(err); + } +} + + +/* + * Class : java/lang/reflect/Field + * Method : setFloat + * Signature : (Ljava/lang/Object;F)V + */ +NS_EXPORT NS_NATIVECALL(void) +Netscape_Java_java_lang_reflect_Field_setFloat(Java_java_lang_reflect_Field *inField, + Java_java_lang_Object *obj, + Flt32 value) +{ + Field &field = toField(inField); + + checkCallingClass(field); + + try { + field.setFloat((JavaObject *) obj, value); + } catch (RuntimeError err) { + throwFieldException(err); + } +} + + +/* + * Class : java/lang/reflect/Field + * Method : setInt + * Signature : (Ljava/lang/Object;I)V + */ +NS_EXPORT NS_NATIVECALL(void) +Netscape_Java_java_lang_reflect_Field_setInt(Java_java_lang_reflect_Field *inField, + Java_java_lang_Object *obj, + int32 value) +{ + Field &field = toField(inField); + + checkCallingClass(field); + + try { + field.setInt((JavaObject *) obj, (Int32) value); + } catch (RuntimeError err) { + throwFieldException(err); + } +} + + +/* + * Class : java/lang/reflect/Field + * Method : setLong + * Signature : (Ljava/lang/Object;J)V + */ +NS_EXPORT NS_NATIVECALL(void) +Netscape_Java_java_lang_reflect_Field_setLong(Java_java_lang_reflect_Field *inField, + Java_java_lang_Object *obj, + int64 value) +{ + Field &field = toField(inField); + + checkCallingClass(field); + + try { + field.setLong((JavaObject *) obj, value); + } catch (RuntimeError err) { + throwFieldException(err); + } +} + + +/* + * Class : java/lang/reflect/Field + * Method : setShort + * Signature : (Ljava/lang/Object;S)V + */ +NS_EXPORT NS_NATIVECALL(void) +Netscape_Java_java_lang_reflect_Field_setShort(Java_java_lang_reflect_Field *inField, + Java_java_lang_Object *obj, + int32 /* short */value) +{ + Field &field = toField(inField); + + checkCallingClass(field); + + try { + field.setShort((JavaObject *) obj, (Int16) value); + } catch (RuntimeError err) { + throwFieldException(err); + } +} + +/* + * Class : java/lang/reflect/Field + * Method : toString + * Signature : ()Ljava/lang/String; + */ +NS_EXPORT NS_NATIVECALL(Java_java_lang_String *) +Netscape_Java_java_lang_reflect_Field_toString(Java_java_lang_reflect_Field *inField) +{ + Field &field = toField(inField); + + const char *str = field.toString(); + + return ((Java_java_lang_String *) &VM::intern(str)); +} + +} + diff --git a/ef/Packages/java/lang/nativesrc/reflect/Makefile b/ef/Packages/java/lang/nativesrc/reflect/Makefile new file mode 100644 index 000000000000..1f9342b20734 --- /dev/null +++ b/ef/Packages/java/lang/nativesrc/reflect/Makefile @@ -0,0 +1,45 @@ +#!gmake +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +####################################################################### +# (1) Include manifest file # +####################################################################### + +include manifest.mn + +####################################################################### +# (2) Include "component" configuration information. # +####################################################################### + +include $(DEPTH)/config/config.mk + +####################################################################### +# (3) Include "local" platform-dependent assignments (OPTIONAL). # +####################################################################### + + +####################################################################### +# (4) Execute "component" rules. (OPTIONAL) # +####################################################################### + +include $(DEPTH)/config/rules.mk + +####################################################################### +# (7) Execute "local" rules. (OPTIONAL). # +####################################################################### + + diff --git a/ef/Packages/java/lang/nativesrc/reflect/Method.cpp b/ef/Packages/java/lang/nativesrc/reflect/Method.cpp new file mode 100644 index 000000000000..32e4ce49d41b --- /dev/null +++ b/ef/Packages/java/lang/nativesrc/reflect/Method.cpp @@ -0,0 +1,246 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#include +#include "java_lang_reflect_Method.h" +#include "java_lang_Class.h" + +#include "JavaVM.h" +#include "SysCallsRuntime.h" +#include "StackWalker.h" + +static inline void throwMethodException(RuntimeError err) +{ + // FIXME Need to check for illegalAccess, which we currently do not enforce + // Also need to throw an InvocationTargetException + if (err.cause == RuntimeError::nullPointer) + sysThrowNullPointerException(); + else if (err.cause == RuntimeError::illegalArgument) + sysThrowNamedException("java/lang/IllegalArgumentException"); + else + trespass("Unknown Runtime Error in throwMethodException()"); + +} + +// Make sure that the class that called this method can access this field. +// Throw an IllegalAccessException if it can't. +static inline void checkCallingClass(const Method &method) +{ + Frame thisFrame; + Method &callerMethod = thisFrame.getCallingJavaMethod(); + + if (callerMethod.getDeclaringClass() != method.getDeclaringClass()) { + if ((method.getModifiers() & CR_METHOD_PRIVATE)) + sysThrowNamedException("java/lang/IllegalAccessException"); + else if ((method.getModifiers() & CR_METHOD_PROTECTED)) { + if (!method.getDeclaringClass()->isAssignableFrom(*(const Type *) callerMethod.getDeclaringClass())) + sysThrowNamedException("java/lang/IllegalAccessException"); + } + } +} + +extern "C" { + +/* XXX Routines returning strings will have to be redone once the VM supports + * unicode strings directly + */ + +static inline Method &toMethod(Java_java_lang_reflect_Method *inMethod) +{ + if (!inMethod) + sysThrowNullPointerException(); + + return *(Method *) inMethod; +} + + + +/* + * Class : java/lang/reflect/Method + * Method : equals + * Signature : (Ljava/lang/Object;)Z + */ +NS_EXPORT NS_NATIVECALL(uint32 /* bool */) +Netscape_Java_java_lang_reflect_Method_equals(Java_java_lang_reflect_Method *inMethod, + Java_java_lang_Object *inObj) +{ + Method &method = toMethod(inMethod); + JavaObject *obj = (JavaObject *) inObj; + + return obj && method.equals(*obj); +} + + +/* + * Class : java/lang/reflect/Method + * Method : getDeclaringClass + * Signature : ()Ljava/lang/Class; + */ +NS_EXPORT NS_NATIVECALL(Java_java_lang_Class *) +Netscape_Java_java_lang_reflect_Method_getDeclaringClass(Java_java_lang_reflect_Method *inMethod) +{ + Method &method = toMethod(inMethod); + + return ((Java_java_lang_Class *) method.getDeclaringClass()); +} + + +/* + * Class : java/lang/reflect/Method + * Method : getExceptionTypes + * Signature : ()[Ljava/lang/Class; + */ +NS_EXPORT NS_NATIVECALL(ArrayOf_Java_java_lang_Class *) +Netscape_Java_java_lang_reflect_Method_getExceptionTypes(Java_java_lang_reflect_Method *) +{ + printf("Netscape_Java_java_lang_reflect_Method_getExceptionTypes() not implemented\n"); + return 0; +} + + +/* + * Class : java/lang/reflect/Method + * Method : getModifiers + * Signature : ()I + */ +NS_EXPORT NS_NATIVECALL(int32) +Netscape_Java_java_lang_reflect_Method_getModifiers(Java_java_lang_reflect_Method *inMethod) +{ + Method &method = toMethod(inMethod); + + return method.getModifiers(); +} + + + +/* + * Class : java/lang/reflect/Method + * Method : getName + * Signature : ()Ljava/lang/String; + */ +NS_EXPORT NS_NATIVECALL(Java_java_lang_String *) +Netscape_Java_java_lang_reflect_Method_getName(Java_java_lang_reflect_Method *inMethod) +{ + Method &method = toMethod(inMethod); + + const char *name = method.getName(); + + return ((Java_java_lang_String *) &VM::intern(name)); +} + + +/* + * Class : java/lang/reflect/Method + * Method : getParameterTypes + * Signature : ()[Ljava/lang/Class; + */ +NS_EXPORT NS_NATIVECALL(ArrayOf_Java_java_lang_Class *) +Netscape_Java_java_lang_reflect_Method_getParameterTypes(Java_java_lang_reflect_Method *inMethod) +{ + Method &method = toMethod(inMethod); + const Type **params; + Int32 numParams; + + numParams = method.getParameterTypes(params); + + void *arr = sysNewObjectArray(&VM::getStandardClass(cClass), numParams); + + ArrayOf_Java_java_lang_Class *clazzArray = (ArrayOf_Java_java_lang_Class *) arr; + for (Int32 i = 0; i < numParams; i++) + clazzArray->elements[i] = (Java_java_lang_Class *) params[i]; + + return clazzArray; +} + + + +/* + * Class : java/lang/reflect/Method + * Method : getReturnType + * Signature : ()Ljava/lang/Class; + */ +NS_EXPORT NS_NATIVECALL(Java_java_lang_Class *) +Netscape_Java_java_lang_reflect_Method_getReturnType(Java_java_lang_reflect_Method *inMethod) +{ + Method &method = toMethod(inMethod); + + return ((Java_java_lang_Class *) &method.getReturnType()); +} + + +/* + * Class : java/lang/reflect/Method + * Method : invoke + * Signature : (Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object; + */ +NS_EXPORT NS_NATIVECALL(Java_java_lang_Object *) +Netscape_Java_java_lang_reflect_Method_invoke(Java_java_lang_reflect_Method *inMethod, + Java_java_lang_Object *inObj, + ArrayOf_Java_java_lang_Object *inParams) +{ + Method &method = toMethod(inMethod); + + checkCallingClass(method); + + if (!(method.getModifiers() & CR_METHOD_STATIC) && !inObj) + sysThrowNullPointerException(); + + JavaObject *obj = (JavaObject *) inObj; + JavaObject **params; + Int32 numParams; + + if (inParams) { + params = (JavaObject **) inParams->elements; + numParams = inParams->length; + } else { + JavaObject *dummy[1]; + + // It is permissible for params to be non-null only if + // the method takes no arguments + params = (JavaObject **) dummy; + numParams = 0; + } + + try { + return ((Java_java_lang_Object *) method.invoke(obj, params, numParams)); + } catch (RuntimeError err) { + throwMethodException(err); + } +} + + +/* + * Class : java/lang/reflect/Method + * Method : toString + * Signature : ()Ljava/lang/String; + */ +NS_EXPORT NS_NATIVECALL(Java_java_lang_String *) +Netscape_Java_java_lang_reflect_Method_toString(Java_java_lang_reflect_Method *inMethod) +{ + Method &method = toMethod(inMethod); + + const char *str = method.toString(); + + return ((Java_java_lang_String *) &VM::intern(str)); +} + + + +} + + + diff --git a/ef/Packages/java/lang/nativesrc/reflect/manifest.mn b/ef/Packages/java/lang/nativesrc/reflect/manifest.mn new file mode 100644 index 000000000000..0957cf5e6c15 --- /dev/null +++ b/ef/Packages/java/lang/nativesrc/reflect/manifest.mn @@ -0,0 +1,51 @@ +#!gmake +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +DEPTH = ../../../../.. + +MODULE_NAME = Package + +CPPSRCS = Array.cpp \ + Constructor.cpp \ + Field.cpp \ + Method.cpp \ + $(NULL) + + +HEADER_GEN = java.lang.String \ + java.lang.Class \ + java.lang.ClassLoader \ + java.lang.Compiler \ + java.lang.Character \ + java.lang.Double \ + java.lang.Float \ + java.lang.Math \ + java.lang.Runtime \ + java.lang.SecurityManager \ + java.lang.System \ + java.util.Properties \ + java.io.InputStream \ + java.io.PrintStream \ + java.lang.Thread \ + java.lang.Throwable \ + java.lang.reflect.Field \ + java.lang.reflect.Method \ + java.lang.reflect.Constructor \ + java.lang.reflect.Array \ + $(NULL) + + diff --git a/ef/Packages/java/manifest.mn b/ef/Packages/java/manifest.mn new file mode 100644 index 000000000000..2a05c318aea2 --- /dev/null +++ b/ef/Packages/java/manifest.mn @@ -0,0 +1,22 @@ +#!gmake +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +DEPTH = ../.. + +DIRS = lang io security + + diff --git a/ef/Packages/java/security/Makefile b/ef/Packages/java/security/Makefile new file mode 100644 index 000000000000..1f9342b20734 --- /dev/null +++ b/ef/Packages/java/security/Makefile @@ -0,0 +1,45 @@ +#!gmake +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +####################################################################### +# (1) Include manifest file # +####################################################################### + +include manifest.mn + +####################################################################### +# (2) Include "component" configuration information. # +####################################################################### + +include $(DEPTH)/config/config.mk + +####################################################################### +# (3) Include "local" platform-dependent assignments (OPTIONAL). # +####################################################################### + + +####################################################################### +# (4) Execute "component" rules. (OPTIONAL) # +####################################################################### + +include $(DEPTH)/config/rules.mk + +####################################################################### +# (7) Execute "local" rules. (OPTIONAL). # +####################################################################### + + diff --git a/ef/Packages/java/security/manifest.mn b/ef/Packages/java/security/manifest.mn new file mode 100644 index 000000000000..39f93c46fe03 --- /dev/null +++ b/ef/Packages/java/security/manifest.mn @@ -0,0 +1,23 @@ +#!gmake +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +DEPTH = ../../.. + +DIRS = nativesrc + + + diff --git a/ef/Packages/java/security/nativesrc/AccessController.cpp b/ef/Packages/java/security/nativesrc/AccessController.cpp new file mode 100644 index 000000000000..817e6a712471 --- /dev/null +++ b/ef/Packages/java/security/nativesrc/AccessController.cpp @@ -0,0 +1,80 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#include "java_security_AccessController.h" +#include "prprf.h" + +extern "C" { + +/* + * Class : java/security/AccessController + * Method : beginPrivileged + * Signature : ()V + */ +NS_EXPORT NS_NATIVECALL(void) +Netscape_Java_java_security_AccessController_beginPrivileged() +{ + PR_fprintf(PR_STDERR, "Netscape_Java_java_security_AccessController_beginPrivilege not implemented\n"); +} + + +/* + * Class : java/security/AccessController + * Method : endPrivileged + * Signature : ()V + */ +NS_EXPORT NS_NATIVECALL(void) +Netscape_Java_java_security_AccessController_endPrivileged() +{ + PR_fprintf(PR_STDERR, "Netscape_Java_java_security_AccessController_endPrivileged not implemented\n"); +} + + + +/* + * Class : java/security/AccessController + * Method : getInheritedAccessControlContext + * Signature : ()Ljava/security/AccessControlContext; + */ +NS_EXPORT NS_NATIVECALL(Java_java_security_AccessControlContext *) +Netscape_Java_java_security_AccessController_getInheritedAccessControlContext() +{ + PR_fprintf(PR_STDERR, "Netscape_Java_java_security_AccessController_getInheritedAccessControlContext not implemented\n"); + return 0; +} + + + +/* + * Class : java/security/AccessController + * Method : getStackAccessControlContext + * Signature : ()Ljava/security/AccessControlContext; + */ +NS_EXPORT NS_NATIVECALL(Java_java_security_AccessControlContext *) +Netscape_Java_java_security_AccessController_getStackAccessControlContext() +{ + PR_fprintf(PR_STDERR, "Netscape_Java_java_security_AccessController_getStackAccessControlContext not implemented\n"); + return 0; + +} + +} + + + + + diff --git a/ef/Packages/java/security/nativesrc/Makefile b/ef/Packages/java/security/nativesrc/Makefile new file mode 100644 index 000000000000..1f9342b20734 --- /dev/null +++ b/ef/Packages/java/security/nativesrc/Makefile @@ -0,0 +1,45 @@ +#!gmake +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +####################################################################### +# (1) Include manifest file # +####################################################################### + +include manifest.mn + +####################################################################### +# (2) Include "component" configuration information. # +####################################################################### + +include $(DEPTH)/config/config.mk + +####################################################################### +# (3) Include "local" platform-dependent assignments (OPTIONAL). # +####################################################################### + + +####################################################################### +# (4) Execute "component" rules. (OPTIONAL) # +####################################################################### + +include $(DEPTH)/config/rules.mk + +####################################################################### +# (7) Execute "local" rules. (OPTIONAL). # +####################################################################### + + diff --git a/ef/Packages/java/security/nativesrc/ProtectionDomain.cpp b/ef/Packages/java/security/nativesrc/ProtectionDomain.cpp new file mode 100644 index 000000000000..ed18431fe9dd --- /dev/null +++ b/ef/Packages/java/security/nativesrc/ProtectionDomain.cpp @@ -0,0 +1,49 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#include "java_security_ProtectionDomain.h" +#include "prprf.h" + +extern "C" { + +/* + * Class : java/security/ProtectionDomain + * Method : getProtectionDomain + * Signature : (Ljava/lang/Class;)Ljava/security/ProtectionDomain; + */ +NS_EXPORT NS_NATIVECALL(Java_java_security_ProtectionDomain *) +Netscape_Java_java_security_ProtectionDomain_getProtectionDomain(Java_java_lang_Class *) +{ + PR_fprintf(PR_STDERR, "Netscape_Java_java_security_ProtectionDomain_getProtectionDomain not implemented\n"); + return 0; +} + + +/* + * Class : java/security/ProtectionDomain + * Method : setProtectionDomain + * Signature : (Ljava/lang/Class;Ljava/security/ProtectionDomain;)V + */ +NS_EXPORT NS_NATIVECALL(void) +Netscape_Java_java_security_ProtectionDomain_setProtectionDomain(Java_java_lang_Class *, Java_java_security_ProtectionDomain *) +{ + PR_fprintf(PR_STDERR, "Netscape_Java_java_security_ProtectionDomain_setProtectionDomain not implemented\n"); + +} + +} + diff --git a/ef/Packages/java/security/nativesrc/geninclude/.cvsignore b/ef/Packages/java/security/nativesrc/geninclude/.cvsignore new file mode 100644 index 000000000000..c1e2dbce11f6 --- /dev/null +++ b/ef/Packages/java/security/nativesrc/geninclude/.cvsignore @@ -0,0 +1,4 @@ +java_io_* +java_lang_* +java_security_* + diff --git a/ef/Packages/java/security/nativesrc/manifest.mn b/ef/Packages/java/security/nativesrc/manifest.mn new file mode 100644 index 000000000000..e1bf83c01439 --- /dev/null +++ b/ef/Packages/java/security/nativesrc/manifest.mn @@ -0,0 +1,32 @@ +#!gmake +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +DEPTH = ../../../.. + +MODULE_NAME = Package + + +CPPSRCS = AccessController.cpp \ + ProtectionDomain.cpp \ + $(NULL) + + +HEADER_GEN = java.security.AccessController \ + java.security.ProtectionDomain \ + $(NULL) + + diff --git a/ef/Packages/java/util/nativesrc/ResourceBundle.cpp b/ef/Packages/java/util/nativesrc/ResourceBundle.cpp new file mode 100644 index 000000000000..28737661cbfa --- /dev/null +++ b/ef/Packages/java/util/nativesrc/ResourceBundle.cpp @@ -0,0 +1,37 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#include "java_util_ResourceBundle.h" +#include "prprf.h" +#include "prio.h" +#include "JavaVM.h" +#include "SysCallsRuntime.h" + +extern "C" { + +NS_EXPORT NS_NATIVECALL(ArrayOf_Java_java_lang_Class *) +Netscape_Java_java_util_ResourceBundle_getClassContext() +{ +#ifdef DEBUG_LOG +// PR_fprintf(PR_STDERR, "Warning: ResourceBundle::getClassContext() not implemented\n"); +#endif + + ArrayOf_Java_java_lang_Class *arr = (ArrayOf_Java_java_lang_Class *) sysNewObjectArray(&VM::getStandardClass(cClass), 3); + return arr; +} + +} diff --git a/ef/Packages/manifest.mn b/ef/Packages/manifest.mn new file mode 100644 index 000000000000..91de25ffd54e --- /dev/null +++ b/ef/Packages/manifest.mn @@ -0,0 +1,24 @@ +#! gmake +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +DEPTH = .. + +LIBRARY_NAME = Package + +DIRS = java + + diff --git a/ef/Packages/rules.mk b/ef/Packages/rules.mk new file mode 100644 index 000000000000..38c834872f23 --- /dev/null +++ b/ef/Packages/rules.mk @@ -0,0 +1,23 @@ +#! gmake +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +program:: $(SHARED_LIBRARY) + +clobber:: + rm -r -f $(HEADER_GEN_DIR) + + diff --git a/ef/Quality/BuildScript/buildef.pl b/ef/Quality/BuildScript/buildef.pl new file mode 100644 index 000000000000..3ef71edbc22a --- /dev/null +++ b/ef/Quality/BuildScript/buildef.pl @@ -0,0 +1,52 @@ +#!perl +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +use Cwd; + +# Add our lib path to the Perl search path. +use lib "../PerlLib/"; +use BuildMod; +use TestsMod; +use ReportMod; + +while (1) { + + # Build the Debug build. + #@args = ("efDbg.txt"); + #$runTests = BuildMod::build(@args); + + TestsMod::runSuite("testsuite.txt"); + + # Run the conformance tests only if the build was sucessful. + if ($runTests) { + + print "Tests not being run right now.\n"; + + # Temp way to run the tests. + $save_dir = cwd; + chdir("D:/continuousbuilds/tests"); + print ("running tests.\n"); + system("tcl D:/continuousbuilds/scripts/runTestSuite.tcl"); + chdir($save_dir); + + } + + # Build the Optimize build. + #@args = ("efOpt.txt"); + #BuildMod::build(@args); + +} diff --git a/ef/Quality/BuildScript/efDbg.txt b/ef/Quality/BuildScript/efDbg.txt new file mode 100644 index 000000000000..1e6335a468fc --- /dev/null +++ b/ef/Quality/BuildScript/efDbg.txt @@ -0,0 +1,15 @@ +ElectricalFire +WIN32 +Dbg +cvs co ns/coreconf +cvs co ns/nspr20 +cd ns/nspr20 +cvs update -d -r EF_BRANCH121097 +gmake clobber +gmake +cd ../.. +cvs co ns/electricalfire +cd ns/electricalfire +gmake clobber +gmake +cd ../.. \ No newline at end of file diff --git a/ef/Quality/BuildScript/efOpt.txt b/ef/Quality/BuildScript/efOpt.txt new file mode 100644 index 000000000000..6b894a008f8e --- /dev/null +++ b/ef/Quality/BuildScript/efOpt.txt @@ -0,0 +1,15 @@ +ElectricalFire +WIN32 +Opt +cvs co ns/coreconf +cvs co ns/nspr20 +cd ns/nspr20 +cvs update -d -r EF_BRANCH121097 +gmake clobber +gmake BUILD_OPT=1 +cd ../.. +cvs co ns/electricalfire +cd ns/electricalfire +gmake clobber +gmake BUILD_OPT=1 +cd ../.. \ No newline at end of file diff --git a/ef/Quality/PerlLib/BuildMod.pm b/ef/Quality/PerlLib/BuildMod.pm new file mode 100644 index 000000000000..2363b3d1daf2 --- /dev/null +++ b/ef/Quality/PerlLib/BuildMod.pm @@ -0,0 +1,256 @@ +#!perl +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +package BuildMod; +use Exporter; +use Cwd; + +@ISA = qw(Exporter); +@EXPORT = qw(checkArgs); + +# +# build +# +# Builds all modules specified in the build file. +# +sub build { + + local @args = @_; + + # Global variables. + $buildFile = ""; + $buildTitle = ""; + $buildTarget = ""; # Dbg or Opt. + $buildPlatform = ""; # WIN32, UNIX, WIN16... + $buildName = ""; # $buildPlatform + $buildTarget + + $buildLog = ""; # $buildPlatform + $buildTarget + "Log.txt"; + $buildStatus = 0; # Build flag. + $buildStatusStr = "success"; + $startTime = ""; + + &parseArgs(@args); + + # Open the build file. + open BUILDFILE, $buildFile || die ("Cannot open build file.\n"); + + # Read in the build headers. + $buildTitle = ; + $buildPlatform = ; + $buildTarget = ; + + # Remove \n, if any, + $buildTitle =~ s/\n$//; + $buildPlatform =~ s/\n$//; + $buildTarget =~ s/\n$//; + + # Init variables. + $buildName = "${buildPlatform} ${buildTarget}"; + $buildLog = "${buildPlatform}_${buildTarget}Log.txt"; + $startTime = time - 60 * 10; + + # Inform Tinderbox that we are starting a build. + &beginTinderbox; + + # Open the build log. + open(LOG, ">${buildLog}") || die "Cannot open build log.\n"; + + # Read from the build file and do build. + while ($strBuf = ) { + + #Remove any \n. + $strBuf =~ s/\n//; + + # Check if the command is to change to a directory. + $loweredBuf = lc $strBuf; + if ($loweredBuf =~ /^cd /) { + + $dir = $strBuf; + $dir =~ s/^cd\s+//; + print "Changing to $dir\n"; + if (!chdir("$dir")) { + print LOG "Cannot change to directory $dir\n"; + $buildStatus = 1; + } + + } else { + + print "$strBuf 2>&1 |\n"; + print LOG "$strBuf 2>&1 |\n"; + open(COMMAND,"$strBuf 2>&1 |"); + + # Tee the output + while( ){ + print $_; + print LOG $_; + } + close(COMMAND); + $buildStatus |= $?; + + } + + } + + # Check if the build is busted or sucessful. + $buildStatusStr = ($buildStatus ? 'busted' : 'success'); + print("Build Status: $buildStatusStr\n"); + + # Finish the log file and send it to tinderbox. + &endTinderbox(LOG); + + # Rename the log file. + rename("${buildLog}", "${buildPlatform}${buildTarget}.last"); + + # Return 1 if build was sucessful, else return 0; + if ($buildStatusStr == 'success') { + return 1; + } else { + return 0; + } + +} + + +# +# checkArgs +# +# Checks to see if there are command line arguments. +# Returns true(1) or false(0). +# +sub checkArgs { + + local @args = @_; + + # print("Number of args: $#args\n"); + + if ($#args == -1) { + return 0; + } + + return 1; + +} + +# +# parseArgs +# +# Go through the argument list and set the matching global +# variables. +# +sub parseArgs { + + local @args = @_; + + # The first argument should the build file. + $buildFile = $args[0]; + + # Check if the file exits. + if (!(-e $buildFile)) { + die "Build file does not exist in the current directory.\n"; + } + + # Go through the rest of the arguments. + print("Args: "); + $i = 0; + while( $i < @args ){ + + print("$args[$i]", "\n"); + + $i++; + + # Ignore the rest of the arguments. + + } + print("\n"); + + return; + +} + +# +# beginTinderbox +# +# Sends mail to the Tinderbox daemon, +# that a build is about to start. +# +sub beginTinderbox { + + print "Telling Tinderbox that we are starting a build.\n"; + + open( LOG, ">>logfile" ); + print LOG "\n"; + print LOG "tinderbox: tree: $buildTitle\n"; + print LOG "tinderbox: builddate: $startTime\n"; + print LOG "tinderbox: status: building\n"; + print LOG "tinderbox: build: $buildName\n"; + + if ($buildPlatform =~ /WIN32/) { + print LOG "tinderbox: errorparser: windows\n"; + print LOG "tinderbox: buildfamily: windows\n"; + } else { + + # ***** Need to add other platform specific info. ***** + print LOG "tinderbox: errorparser: unknown\n"; + print LOG "tinderbox: buildfamily: unknown\n"; + + } + + print LOG "\n"; + close( LOG ); + + # Send the logfile to Tinderbox. + if ($buildPlatform =~ /WIN32/) { + print "Sending logfile.\n"; + system("$nstools\\bin\\blat logfile -t tinderbox-daemon\@warp" ); + } else { + + # ***** Need to add other platform specific mailing methods. ***** + die "Don't know how to send on $buildPlatform\n"; + } + + return; + +} + +# +# endTinderbox +# +# Sends mail to the Tinderbox daemon, +# that a build is done. +# +sub endTinderbox { + + my($LOG) = @_; + + print "Telling Tinderbox that the build is done.\n"; + print LOG "tinderbox: tree: $buildTitle\n"; + print LOG "tinderbox: builddate: $startTime\n"; + print LOG "tinderbox: status: $buildStatusStr\n"; + print LOG "tinderbox: build: $buildName\n"; + print LOG "tinderbox: errorparser: windows\n"; + print LOG "tinderbox: buildfamily: windows\n"; + + close LOG; + + # Inform Tinderbox that the build is done. + system("$nstools\\bin\\blat $buildLog -t tinderbox-daemon\@warp" ); + + return; + +} + + diff --git a/ef/Quality/PerlLib/ReportMod.pm b/ef/Quality/PerlLib/ReportMod.pm new file mode 100644 index 000000000000..82a40ab96b70 --- /dev/null +++ b/ef/Quality/PerlLib/ReportMod.pm @@ -0,0 +1,164 @@ +#!perl +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +package ReportMod; +use Exporter; +use Socket; + +@ISA = qw(Exporter); +@EXPORT = qw(sendReport); + +# +# sendReport +# +# Connect to the remote host and give the results of the test run. +# +# +sub sendReport { + + local ($localhost,$remotehost, $port, $resultfile) = @_; + + openConnection(F, $remotehost, $port) || die ("Error connecting to the server.\n"); + + $buffer = "b\t$localhost\n"; + syswrite(F, $buffer, length($buffer)); + + $testRunID = ; + print ("Test Run ID: $testRunID"); + + open(REPORT,$resultfile) || die "Could not open file.\n"; + while () { + + $testID = $_; + $testClass = ; + $testResult = ; + $testLog = ""; + $logBuffer = ""; + + $testBuffer = "p\t$testRunID\t$testID\t"; + + # Parse the result string. + $loweredResult = lc $testResult; + if ($loweredResult =~ /passed/) { + $testBuffer .= "p\n"; + } + + elsif ($loweredResult =~ /failed/) { + $testBuffer .= "f\n"; + } + + elsif ($loweredResult =~ /exception/) { + $testBuffer .= "u\n"; + } + + elsif ($loweredResult =~ /assertion/) { + $testBuffer .= "a\n"; + } + + else { + $testBuffer .= "c\n"; + } + + # Write the result to the socket. + syswrite(F, $testBuffer, length($testBuffer)); + + # Read the transaction ID from the server. + $transID = ; + print "Transaciton ID: $transID\n"; + + # If the test didn't pass, get the result log. + if (!($loweredResult =~ /passed/)) { + + $logBuffer = "n\t$transID\n"; + + $beginBuf = ; + # Check if the log is correct. + if (!($beginBuf =~ //)) { + die "Log is incorrect.\n"; + } + + while (1) { + $endBuf = ; + if ($endBuf =~ //) { + last; + } else { + $testLog .= $endBuf; + } + } + + # Print the log into the socket. + $logBuffer .= "$testLog\n"; + syswrite(F, $logBuffer, length($logBuffer)); + + } + + } + + $buffer = "e\t$testRunID\n"; + syswrite(F, $buffer, length($buffer)); + + # Give the server time to finish up before closing the socket. + sleep(3); + close(F); + +} + +# +# open Connection +# +# Open a socket to the remote host. +# +sub openConnection { + + my ($FS, $dest, $port) = @_; + + $AF_INET = 2; + $SOCK_STREAM = 1; + + $sockaddr = 'S n a4 x8'; + + ($name,$aliases,$proto) = getprotobyname('tcp'); + ($name,$aliases,$port) = getservbyname($port,'tcp') + unless $port =~ /^\d+$/; + ($name,$aliases,$type,$len,$thisaddr) = + gethostbyname($hostname); + ($name,$aliases,$type,$len,$thataddr) = gethostbyname($dest); + + $this = pack($sockaddr, $AF_INET, 0, $thisaddr); + $that = pack($sockaddr, $AF_INET, $port, $thataddr); + + if (socket($FS, $AF_INET, $SOCK_STREAM, $proto)) { + print "socket ok\n"; + } + else { + die $!; + } + + if (connect($FS,$that)) { + print "connect ok\n"; + } + else { + die $!; + } + + return 1; + +} + +1; + + diff --git a/ef/Quality/PerlLib/TestsMod.pm b/ef/Quality/PerlLib/TestsMod.pm new file mode 100644 index 000000000000..c743258b6068 --- /dev/null +++ b/ef/Quality/PerlLib/TestsMod.pm @@ -0,0 +1,715 @@ +#!perl +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +package TestsMod; +use Exporter; + +@ISA = qw(Exporter); +@EXPORT = qw(runTests,checkArgs); + +# +# runSuite +# +# Runs each test package it reads from the given file. +# +sub runSuite { + + my ($testsuite) = @_; + + print "Running test suite: $testsuite\n"; + + # Open the test suite and run each test package read. + open TESTSUITE, $testsuite || die ("Cannot open testsuite.\n"); + + while ($inputString = ) { + + # Parse the string for the testpackage and if there is a wrapper class. + ($testPackage, $wrapperClass) = ($inputString =~ /^(\S+)\s+(.*)/); + + if ($wrapperClass =~ /[A-Za-z]/) { + @args = ("${testPackage}.txt", "-q", "-gt", "-uw", + "$wrapperClass"); + } else { + @args = ("${testPackage}.txt", "-q", "-gt"); + } + runTests(@args); + + # Send the report to the server. + ReportMod::sendReport("ranma","ranma","8765","report.txt"); + + # Backup the current report. + rename("report.txt", "${testPackage}Report.old"); + + } + + close TESTSUITE; + +} + +# +# runTests +# +# Performs the conformance tests on a given java implementation. +# +# +sub runTests { + + my (@args) = @_; + + # Global variables. + $testfile = ""; + $useWorkDir = 0; + $workDir = ""; + $useTestRoot = 0; + $testRoot = ""; + $genReport = 0; + $genResult = 0; + $useWrapper = 0; + $wrapperClass = ""; + $useDots = 0; + $classpath = $ENV{CLASSPATH}; + + # Test info. + $testID = ""; + $executeClass = ""; + $executeArgs = ""; + $result = ""; + $resultLog = ""; + $color = ""; + + # Width count. + $widthCount = 0; + + # Result counters. + $totalTests = 0; + $totalPassed = 0; + $totalFailed = 0; + $totalException = 0; + $totalAssert = 0; + $totalCheckTest = 0; + + # Parse the argument list. + &parseArgs(@args); + + print("Test file: $testfile\n"); + print("Working dir: $workDir\n"); + print("Test root: $testDir\n"); + print("Generate results: $genResult\n"); + print("Wrapper class: $wrapperClass\n"); + print("Classpath: $classpath\n"); + print("\n"); + + # Open the test file. + open TESTLIST, $testfile || die ("Cannot open test file.\n"); + + # Open the html result files. + if ($genResult) { + + open RESULTS, "+>report.html" || die ("Cannot open report file.\n"); + open PASSED, "+>passed.html" || die ("Cannot open passed file.\n"); + open FAILED, "+>failed.html" || die ("Cannot open failed file.\n"); + open EXCEPTION, "+>exception.html" || die ("Cannot open exception file.\n"); + open ASSERT, "+>assert.html" || die ("Cannot open assert file.\n"); + open CHECKTEST, "+>checktest.html" || die ("Cannot open check test file.\n"); + + # Generate the headers for the result html. + &genResultHeader; + + } + + # Open the report file. + if ($genReport) { + open REPORT, "+>report.txt" || die ("Cannot open results file.\n"); + } + + while ($testID = ) { + + # ***** Need to take care of blanks, space, etc... ***** # + + $testString = ; + + # Parse the test string for the execute class and arguments. + ($executeClass, $executeArgs) = ($testString =~ /^(\S+)\s+(.*)/); + + &resolveArgs; + + # Excute the test. + $totalTests++; + if ($useWrapper) { + $executeString = "sajava -classpath $classpath -sys -ce $wrapperClass $executeClass $executeArgs"; + } else { + $executeString = "sajava -classpath $classpath -sys -ce $executeClass $executeArgs"; + } + + open(LOG,"$executeString 2>&1 |") || die ("Could not execute test\n"); + + while() { + $resultLog .= $_; + } + close LOG; + #print("Result: $resultLog\n"); + + # Parse the result string. Print to stdout and report. + $loweredResult = lc $resultLog; + if ($loweredResult =~ /status:passed./) { + + $totalPassed++; + $result = "PASSED"; + $color = "#99FF99"; + + if ($useDots) { + &printDot; + } else { + &printToScreen; + } + + if ($genResult) { + &genTestResult(*PASSED); + } + } + + elsif ($loweredResult =~ /status:failed./) { + + $totalFailed++; + $result = "FAILED"; + $color = "#FF6666"; + &printToScreen; + + if ($genResult) { + &genTestResult(*FAILED); + } + } + + elsif ($loweredResult =~ /status:not run./) { + + $totalFailed++; + $result = "FAILED"; + $color = "#FF6666"; + &printToScreen; + + if ($genResult) { + &genTestResult(*FAILED); + } + } + + elsif ($loweredResult =~ /status:exception./) { + + $totalException++; + $result = "EXCEPTION"; + $color = "#FF6666"; + &printToScreen; + + if ($genResult) { + &genTestResult(*EXCEPTION); + } + } + + elsif ($loweredResult =~ /status:assertion./) { + + $totalAssert++; + $result = "ASSERTION"; + $color = "#FF6666"; + &printToScreen; + + if ($genResult) { + &genTestResult(*ASSERT); + } + } + + else { + + $totalCheckTest++; + $result = "CHECK TEST"; + $color = "#8080FF"; + &printToScreen; + + if ($genResult) { + &genTestResult(*CHECKTEST); + } + } + + # Print the result to the report file. + if ($genReport) { + &printTestReport(*REPORT); + } + + #Clear the test info. + $testID = ""; + $executeClass = ""; + $executeArgs = ""; + $result = ""; + $resultLog = ""; + $color = ""; + + } + + print("\nDone with tests.\n"); + &genResultFooter; + + # Close files. + close TESTLIST; + + # Close the report files. + if ($genResult) { + + close RESULTS; + close PASSED; + close FAILED; + close EXCEPTION; + close ASSERT; + close CHECKTEST; + + } + + # Close the result file. + if ($genReport) { + close REPORT; + } + +} + +# +# checkArgs +# +# Checks to see if there are command line arguments. +# Returns true(1) or false(0). +# +sub checkArgs { + + local @args = @_; + + # print("Number of args: $#args\n"); + + if ($#args == -1) { + return 0; + } + + return 1; + +} + +# +# parseArgs +# +# Go through the argument list and set the matching global +# variables. +# +sub parseArgs { + + local @args = @_; + + # Check if the first argument is the help option. + if ( $args[$i] eq '-h' ){ + print("runTests\n"); + print("Usage: runTests [options....]\n"); + print("Options:\n"); + print("\t-q\t\t\tQuiet mode. Print non-passing tests only.\n"); + print("\t-gr\t\t\tGenerate result files in html format.\n"); + print("\t-gt\t\t\tGenerate a report file in text format.\n"); + print("\t-uw \t\tUse specfied class as a wrapper class.\n"); + print("\t-classpath \tUse specified path as the classpath.\n"); + print("\t-workdir \t\tUse specified dir as the working dir.\n"); + print("\t-testroot \tUse specified path as the test root.\n"); + print("\t-keyword \tRun tests with the specified keyword only.\n"); + print("\t-h\t\t\tHelp. You're in it.\n"); + exit; + } + + # The first argument should the test file. + $testfile = $args[0]; + + # Check if the file exits. + if (!(-e $testfile)) { + die "Test file does not exist in the current directory.\n"; + } + + # Go through the rest of the arguments. + print("Args: "); + $i = 0; + while( $i < @args ){ + + #print("$args[$i]", "\n"); + + if ( $args[$i] eq '-gr' ){ + $genResult = 1; + } + + if ( $args[$i] eq '-gt' ){ + $genReport = 1; + } + + if ( $args[$i] eq '-q' ){ + $useDots = 1; + } + + elsif ( $args[$i] eq '-uw' ) { + $useWrapper = 1; + $i++; + $wrapperClass = $args[$i]; + + # Check if a wrapper class has been given. + if ( $wrapperClass eq '' ) { + die ("No wrapper class specified.\n"); + } + } + + elsif ( $args[$i] eq '-classpath' ) { + $i++; + $classpath = $args[$i]; + + #Check if the given work dir is valid. + if ( $classpath eq '' ) { + die ("No classpath specified.\n"); + } + } + + elsif ( $args[$i] eq '-workdir' ) { + $useWorkDir = 1; + $i++; + $workDir = $args[$i]; + + #Check if the given work dir is valid. + if ( $workDir eq '' ) { + die ("No working directory specified.\n"); + } elsif (!(-e $workDir)) { + die ("Working directory does not exist.\n"); + } else { + $workDir .= "/"; + } + } + + elsif ( $args[$i] eq '-testroot' ) { + $useTestRoot = 1; + $i++; + $testRoot = $args[$i]; + + #Check if the given test root is valid. + if ( $testRoot eq '' ) { + die ("No test root specified.\n"); + } + } + + $i++; + + # Ignore the rest of the arguments. + + } + print("\n"); + + return; + +} + +# +# resolveArgs +# +# Replace any test argument with the correct value. +# +sub resolveArgs { + + if ($useWorkDir) { + $executeArgs =~ s/-WorkDir\s+(\S+)/-WorkDir $workDir/; + $executeArgs =~ s/-workDir\s+(\S+)/-WorkDir $workDir /; + $executeArgs =~ s/-TestWorkDir\s+(\S+)/-WorkDir $workDir /; + } else { + # Remove the argument name and value from the string. + $executeArgs =~ s/-WorkDir\s+(\S+)/\ /; + $executeArgs =~ s/-workDir\s+(\S+)/\ /; + $executeArgs =~ s/-TestWorkDir\s+(\S+)/\ /; + } + + if ($useTestRoot) { + $executeArgs =~ s/file:\/G:\/JCK-114a/$testRoot/; + } else { + # Remove the argument name and value from the string. + $executeArgs =~ s/-Test\s+(\S+)/\ /; + $executeArgs =~ s/-test\s+(\S+)/\ /; + $executeArgs =~ s/-TestURL\s+(\S+)/\ /; + $executeArgs =~ s/-testURL\s+(\S+)/\ /; + } + + return; + +} + +# +# printDot +# +# Prints a dot on stdout. +# +sub printDot { + + # Check if width exceeds 80 chars. + if ($widthCount >= 80) { + + print("\n"); + print("."); + + $widthCount = 0; + + } else { + + $widthCount++; + print("."); + + } + + return; + +} + +# +# printToScreen +# +# Prints the test result to stdout. +# +sub printToScreen { + + print("\nTestCaseID: $testID"); + print("Execute Class: $executeClass\n"); + print("Execute Args: $executeArgs\n"); + print("Result: $result.\n"); + + if (!($result eq 'PASSED')) { + print("Result Log:\n"); + print("$resultLog\n"); + $widthCount = 0; + } + +} + +# +# genResultHeader +# +# Prints out headers for the result files. +# +sub genResultHeader { + + print RESULTS "\n"; + print RESULTS "Test Results\n"; + print RESULTS "\n"; + + print PASSED "\n"; + print PASSED "Pass Results\n"; + print PASSED "\n"; + + print FAILED "\n"; + print FAILED "Fail Results\n"; + print FAILED "\n"; + + print EXCEPTION "\n"; + print EXCEPTION "Exceptions Results\n"; + print EXCEPTION "\n"; + + print ASSERT "\n"; + print ASSERT "Assert Results\n"; + print ASSERT "\n"; + + print CHECKTEST "\n"; + print CHECKTEST "Check Test Results\n"; + print CHECKTEST "\n"; + +} + +# +# genResultFooter +# +# Prints out footers for the result files. +# +sub genResultFooter { + + # Print out totals to the result file. + &genResults; + print RESULTS "\n"; + print RESULTS "\n"; + + print PASSED "\n"; + print PASSED "\n"; + + print FAILED "\n"; + print FAILED "\n"; + + print EXCEPTION "\n"; + print EXCEPTION "\n"; + + print ASSERT "\n"; + print ASSERT "\n"; + + print CHECKTEST "\n"; + print CHECKTEST "\n"; + +} + +# +# genResults +# +# Print out the totals for the test run. +# +sub genResults { + + #Print out the totals. + print RESULTS "\n"; + + print RESULTS "

\n"; + print RESULTS "\n"; + + print RESULTS "\n"; + print RESULTS "\n"; + + print RESULTS "\n"; + print RESULTS "\n"; + + print RESULTS "\n"; + print RESULTS "\n"; + + print RESULTS "\n"; + print RESULTS "\n"; + + print RESULTS "\n"; + print RESULTS "\n"; + + print RESULTS "\n"; + print RESULTS "\n"; + + print RESULTS "\n"; + print RESULTS "\n"; + + print RESULTS "\n"; + print RESULTS "\n"; + + print RESULTS "\n"; + print RESULTS "\n"; + + print RESULTS "\n"; + print RESULTS "\n"; + + print RESULTS "\n"; + print RESULTS "\n"; + + print RESULTS "\n"; + print RESULTS "\n"; + + print RESULTS "
Total\n"; + print RESULTS $totalTests; + print RESULTS "
Passed\n"; + print RESULTS $totalPassed; + print RESULTS "
Failed\n"; + print RESULTS $totalFailed; + print RESULTS "
Unhandled Exceptions\n"; + print RESULTS $totalException; + print RESULTS "
Assertions Thrown"; + print RESULTS $totalAssert; + print RESULTS "
Check Test\n"; + print RESULTS $totalCheckTest; + print RESULTS "

\n"; + +} + +# +# genTestResult +# +# Print out the test to the right result file. +# +sub genTestResult { + + local(*RESULTFILE) = @_; + + print RESULTFILE "\n"; + + print RESULTFILE "\n"; + print RESULTFILE "\n"; + + print RESULTFILE "\n"; + print RESULTFILE "\n"; + + print RESULTFILE "\n"; + print RESULTFILE "\n"; + + print RESULTFILE "\n"; + print RESULTFILE "\n"; + + print RESULTFILE "\n"; + print RESULTFILE "\n"; + + print RESULTFILE "\n"; + print RESULTFILE "\n"; + + print RESULTFILE "\n"; + print RESULTFILE "\n"; + + print RESULTFILE "\n"; + print RESULTFILE "\n"; + + #Only print the log if the test didn't pass. + if (!($result eq 'PASSED')) { + + print RESULTFILE "\n"; + print RESULTFILE "\n"; + + print RESULTFILE "\n"; + print RESULTFILE "\n"; + + } + + print RESULTFILE "
Test ID"; + print RESULTFILE $testID; + print RESULTFILE "
Execute Class"; + print RESULTFILE $executeClass; + print RESULTFILE "
Execute Arguments"; + print RESULTFILE "${executeArgs} "; + print RESULTFILE "
Result"; + print RESULTFILE $result; + print RESULTFILE "
Log
\n";
+	print RESULTFILE $resultLog; 
+	print RESULTFILE "

\n"; + +} + +# +# printTestReport +# +# Print out the test result to the report file. +# +sub printTestReport { + + local(*REPORTFILE) = @_; + + print REPORTFILE "$testID"; + #Check for new line. + if ($executeArgs =~ /\n/) { + print REPORTFILE "$executeClass $executeArgs"; + } else { + print REPORTFILE "$executeClass $executeArgs\n"; + } + print REPORTFILE "$result\n"; + + # If the test didn't passed, print out the result log. + if (!($result eq 'PASSED')) { + print REPORTFILE "\n"; + print REPORTFILE "$resultLog"; + print REPORTFILE "\n"; + } + +} + diff --git a/ef/Quality/TestScript/executeJCKWrapper.class b/ef/Quality/TestScript/executeJCKWrapper.class new file mode 100644 index 000000000000..b41b805fcbb4 Binary files /dev/null and b/ef/Quality/TestScript/executeJCKWrapper.class differ diff --git a/ef/Quality/TestScript/executeJCKWrapper.java b/ef/Quality/TestScript/executeJCKWrapper.java new file mode 100644 index 000000000000..c85d26435f00 --- /dev/null +++ b/ef/Quality/TestScript/executeJCKWrapper.java @@ -0,0 +1,132 @@ +/* -*- Mode: C; tab-width: 4, indent-tabs-mode: nil; -*- */ +/* + * @(#)executeJCKWrapper + * + * Copyright Notice + * This file contains proprietary information of Netscape Communications. + * Copying or reproduction without prior written approval is prohibited. + * + * Copyright (c) 1997 + * + */ + +/* Package Name */ + +/* Imports */ +import java.io.PrintStream; +import java.lang.reflect.Method; + +/** + * executeJCKWrapper runs a given simple JCK test. + * + * @param args Command line arguements. + * + * @author Patrick Dionisio <11-04-97 1:00pm> + */ +public class executeJCKWrapper { + + /** + * The method that runs the test. + * + * @param args The command line arguments. + * log Stream to report messages to. + * + * @author Patrick Dionisio <11-04-97 1:00pm> + */ + public void test(String[] args, PrintStream log) { + + String className = null; + String[] executeArgs = { }; + + int i = 0; + + /* Get the executeClass. */ + if (i < args.length) { + className = args[i]; + i++; + } + + /* Get any optional args. */ + if (i < args.length) { + executeArgs = new String[args.length - i]; + System.arraycopy(args, i, executeArgs, 0, executeArgs.length); + } + + System.out.println(className); + + try { + + Class c; + c = Class.forName(className); + + Class[] runParamTypes = {executeArgs.getClass(), log.getClass()}; + + Method runMethod = c.getMethod("run", runParamTypes); + + /* Invoke the test class. */ + Object[] runArgs = {executeArgs,log}; + Object result = runMethod.invoke(null, runArgs); + + /* Print the result. */ + switch (((Integer)result).intValue()) { + case 0: + System.out.println("STATUS:Passed."); + break; + + case 1: + System.out.println("STATUS:Check me."); + break; + + case 2: + System.out.println("STATUS:Failed."); + break; + + default: + System.out.println("STATUS:Check me"); + + } + + } + + catch(VerifyError error) { + + /* Assume that the verifier is enabled, catch any verify errors. */ + System.out.println("STATUS:Passed."); + + } + + catch(Exception e) { + + /* Print out any exceptions. */ + System.out.println("STATUS:Failed."); + System.out.println("Exception caught."); + e.printStackTrace(); + + } + + } + + /** + * Main method. Checks is args is valid before running the test. + * + * @param args The command line arguments. + * + * @author Patrick Dionisio <11-04-97 1:00pm> + */ + public static void main(String[] args) { + + /* Check if the number of args is valid. */ + if (args.length >= 1) { + + executeJCKWrapper run = new executeJCKWrapper(); + run.test(args, System.out); + + } else { + + System.out.println("usage: java executeJCKWrapper classname arguments"); + + } + + } + +} diff --git a/ef/Quality/TestScript/jckInstr.txt b/ef/Quality/TestScript/jckInstr.txt new file mode 100644 index 000000000000..ef2ab95415d1 --- /dev/null +++ b/ef/Quality/TestScript/jckInstr.txt @@ -0,0 +1,1704 @@ +JCK-114a|vm|instr|aaload|aaload001|aaload00101|aaload00101|Test1 +javasoft/sqe/tests/vm/aaload/aaload001/aaload00101/aaload00101 +JCK-114a|vm|instr|aaload|aaload003|aaload00301|aaload00301|Test1 +javasoft/sqe/tests/vm/aaload/aaload003/aaload00301/aaload00301 +JCK-114a|vm|instr|aaload|aaload006|aaload00601|aaload00601|Test1 +javasoft/sqe/tests/vm/aaload/aaload006/aaload00601/aaload00601 +JCK-114a|vm|instr|aaload|aaload007|aaload00701|aaload00701|Test1 +javasoft/sqe/tests/vm/aaload/aaload007/aaload00701/aaload00701 +JCK-114a|vm|instr|aastore|aastore001|aastore00101|aastore00101|Test1 +javasoft/sqe/tests/vm/aastore/aastore001/aastore00101/aastore00101 +JCK-114a|vm|instr|aastore|aastore002|aastore00201|aastore00201|Test1 +javasoft/sqe/tests/vm/aastore/aastore002/aastore00201/aastore00201 +JCK-114a|vm|instr|aastore|aastore004|aastore00401|aastore00401|Test1 +javasoft/sqe/tests/vm/aastore/aastore004/aastore00401/aastore00401 +JCK-114a|vm|instr|aastore|aastore007|aastore00701|aastore00701|Test1 +javasoft/sqe/tests/vm/aastore/aastore007/aastore00701/aastore00701 +JCK-114a|vm|instr|aastore|aastore010|aastore01001|aastore01001|Test1 +javasoft/sqe/tests/vm/aastore/aastore010/aastore01001/aastore01001 +JCK-114a|vm|instr|aastore|aastore010|aastore01002|aastore01002|Test1 +javasoft/sqe/tests/vm/aastore/aastore010/aastore01002/aastore01002 +JCK-114a|vm|instr|aastore|aastore010|aastore01003|aastore01003|Test1 +javasoft/sqe/tests/vm/aastore/aastore010/aastore01003/aastore01003 +JCK-114a|vm|instr|aastore|aastore011|aastore01101|aastore01101|Test1 +javasoft/sqe/tests/vm/aastore/aastore011/aastore01101/aastore01101 +JCK-114a|vm|instr|aastore|aastore011|aastore01102|aastore01102|Test1 +javasoft/sqe/tests/vm/aastore/aastore011/aastore01102/aastore01102 +JCK-114a|vm|instr|aastore|aastore012|aastore01201|aastore01201|Test1 +javasoft/sqe/tests/vm/aastore/aastore012/aastore01201/aastore01201 +JCK-114a|vm|instr|aastore|aastore013|aastore01301|aastore01301|Test1 +javasoft/sqe/tests/vm/aastore/aastore013/aastore01301/aastore01301 +JCK-114a|vm|instr|aastore|aastore014|aastore01401|aastore01401|Test1 +javasoft/sqe/tests/vm/aastore/aastore014/aastore01401/aastore01401 +JCK-114a|vm|instr|anewarray|anewarray002|anewarray00201|anewarray00201|Test1 +javasoft/sqe/tests/vm/anewarray/anewarray002/anewarray00201/anewarray00201 +JCK-114a|vm|instr|anewarray|anewarray003|anewarray00301|anewarray00301|Test1 +javasoft/sqe/tests/vm/anewarray/anewarray003/anewarray00301/anewarray00301 +JCK-114a|vm|instr|anewarray|anewarray005|anewarray00501|anewarray00501|Test1 +javasoft/sqe/tests/vm/anewarray/anewarray005/anewarray00501/anewarray00501 +JCK-114a|vm|instr|anewarray|anewarray006|anewarray00601|anewarray00601|Test1 +javasoft/sqe/tests/vm/anewarray/anewarray006/anewarray00601/anewarray00601 +JCK-114a|vm|instr|anewarray|anewarray007|anewarray00701|anewarray00701|Test1 +javasoft/sqe/tests/vm/anewarray/anewarray007/anewarray00701/anewarray00701 +JCK-114a|vm|instr|anewarray|anewarray008|anewarray00801|anewarray00801|Test1 +javasoft/sqe/tests/vm/anewarray/anewarray008/anewarray00801/anewarray00801 +JCK-114a|vm|instr|anewarray|anewarray009|anewarray00901|anewarray00901|Test1 +javasoft/sqe/tests/vm/anewarray/anewarray009/anewarray00901/anewarray00901 +JCK-114a|vm|instr|arraylength|arraylength001|arraylength00101|arraylength00101|Test1 +javasoft/sqe/tests/vm/arraylength/arraylength001/arraylength00101/arraylength00101 +JCK-114a|vm|instr|arraylength|arraylength003|arraylength00301|arraylength00301|Test1 +javasoft/sqe/tests/vm/arraylength/arraylength003/arraylength00301/arraylength00301 +JCK-114a|vm|instr|arraylength|arraylength004|arraylength00401|arraylength00401|Test1 +javasoft/sqe/tests/vm/arraylength/arraylength004/arraylength00401/arraylength00401 +JCK-114a|vm|instr|arraylength|arraylength005|arraylength00501|arraylength00501|Test1 +javasoft/sqe/tests/vm/arraylength/arraylength005/arraylength00501/arraylength00501 +JCK-114a|vm|instr|athrow|athrow001|athrow00101|athrow00101|Test1 +javasoft/sqe/tests/vm/athrow/athrow001/athrow00101/athrow00101 +JCK-114a|vm|instr|athrow|athrow002|athrow00201|athrow00201|Test1 +javasoft/sqe/tests/vm/athrow/athrow002/athrow00201/athrow00201 +JCK-114a|vm|instr|athrow|athrow002|athrow00202|athrow00202|Test1 +javasoft/sqe/tests/vm/athrow/athrow002/athrow00202/athrow00202 +JCK-114a|vm|instr|athrow|athrow004|athrow00401|athrow00401|Test1 +javasoft/sqe/tests/vm/athrow/athrow004/athrow00401/athrow00401 +JCK-114a|vm|instr|athrow|athrow005|athrow00501|athrow00501|Test1 +javasoft/sqe/tests/vm/athrow/athrow005/athrow00501/athrow00501 +JCK-114a|vm|instr|athrow|athrow006|athrow00601|athrow00601|Test1 +javasoft/sqe/tests/vm/athrow/athrow006/athrow00601/athrow00601 +JCK-114a|vm|instr|athrow|athrow008|athrow00801|athrow00801|Test1 +javasoft/sqe/tests/vm/athrow/athrow008/athrow00801/athrow00801 +JCK-114a|vm|instr|athrow|athrow009|athrow00901|athrow00901|Test1 +javasoft/sqe/tests/vm/athrow/athrow009/athrow00901/athrow00901 +JCK-114a|vm|instr|athrow|athrow009|athrow00902|athrow00902|Test1 +javasoft/sqe/tests/vm/athrow/athrow009/athrow00902/athrow00902 +JCK-114a|vm|instr|athrow|athrow009|athrow00903|athrow00903|Test1 +javasoft/sqe/tests/vm/athrow/athrow009/athrow00903/athrow00903 +JCK-114a|vm|instr|aload|aload001|aload00101|aload00101|Test1 +javasoft/sqe/tests/vm/aload/aload001/aload00101/aload00101 +JCK-114a|vm|instr|aloadN|aloadN002|aloadN00205|aloadN00205|Test1 +javasoft/sqe/tests/vm/aloadN/aloadN002/aloadN00205/aloadN00205 +JCK-114a|vm|instr|aloadN|aloadN002|aloadN00206|aloadN00206|Test1 +javasoft/sqe/tests/vm/aloadN/aloadN002/aloadN00206/aloadN00206 +JCK-114a|vm|instr|aloadN|aloadN002|aloadN00207|aloadN00207|Test1 +javasoft/sqe/tests/vm/aloadN/aloadN002/aloadN00207/aloadN00207 +JCK-114a|vm|instr|aloadN|aloadN002|aloadN00208|aloadN00208|Test1 +javasoft/sqe/tests/vm/aloadN/aloadN002/aloadN00208/aloadN00208 +JCK-114a|vm|instr|aload_w|aload_w001|aload_w00101|aload_w00101|Test1 +javasoft/sqe/tests/vm/aload_w/aload_w001/aload_w00101/aload_w00101 +JCK-114a|vm|instr|astore|astore001|astore00101|astore00101|Test1 +javasoft/sqe/tests/vm/astore/astore001/astore00101/astore00101 +JCK-114a|vm|instr|astore|astore004|astore00401|astore00401|Test1 +javasoft/sqe/tests/vm/astore/astore004/astore00401/astore00401 +JCK-114a|vm|instr|astoreN|astoreN004|astoreN00401|astoreN00401|Test1 +javasoft/sqe/tests/vm/astoreN/astoreN004/astoreN00401/astoreN00401 +JCK-114a|vm|instr|astoreN|astoreN004|astoreN00402|astoreN00402|Test1 +javasoft/sqe/tests/vm/astoreN/astoreN004/astoreN00402/astoreN00402 +JCK-114a|vm|instr|astoreN|astoreN004|astoreN00403|astoreN00403|Test1 +javasoft/sqe/tests/vm/astoreN/astoreN004/astoreN00403/astoreN00403 +JCK-114a|vm|instr|astoreN|astoreN004|astoreN00404|astoreN00404|Test1 +javasoft/sqe/tests/vm/astoreN/astoreN004/astoreN00404/astoreN00404 +JCK-114a|vm|instr|astore_w|astore_w001|astore_w00101|astore_w00101|Test1 +javasoft/sqe/tests/vm/astore_w/astore_w001/astore_w00101/astore_w00101 +JCK-114a|vm|instr|areturn|areturn001|areturn00101|areturn00101|Test1 +javasoft/sqe/tests/vm/areturn/areturn001/areturn00101/areturn00101 +JCK-114a|vm|instr|areturn|areturn002|areturn00201|areturn00201|Test1 +javasoft/sqe/tests/vm/areturn/areturn002/areturn00201/areturn00201 +JCK-114a|vm|instr|areturn|areturn003|areturn00301|areturn00301|Test1 +javasoft/sqe/tests/vm/areturn/areturn003/areturn00301/areturn00301 +JCK-114a|vm|instr|areturn|areturn005|areturn00501|areturn00501|Test1 +javasoft/sqe/tests/vm/areturn/areturn005/areturn00501/areturn00501 +JCK-114a|vm|instr|areturn|areturn005|areturn00502|areturn00502|Test1 +javasoft/sqe/tests/vm/areturn/areturn005/areturn00502/areturn00502 +JCK-114a|vm|instr|areturn|areturn006|areturn00601|areturn00601|Test1 +javasoft/sqe/tests/vm/areturn/areturn006/areturn00601/areturn00601 +JCK-114a|vm|instr|areturn|areturn007|areturn00701|areturn00701|Test1 +javasoft/sqe/tests/vm/areturn/areturn007/areturn00701/areturn00701 +JCK-114a|vm|instr|aconst_null|aconst_null001|aconst_null00101|aconst_null00101|Test1 +javasoft/sqe/tests/vm/aconst_null/aconst_null001/aconst_null00101/aconst_null00101 +JCK-114a|vm|instr|baload|baload002|baload00201|baload00201|Test1 +javasoft/sqe/tests/vm/baload/baload002/baload00201/baload00201 +JCK-114a|vm|instr|baload|baload006|baload00601|baload00601|Test1 +javasoft/sqe/tests/vm/baload/baload006/baload00601/baload00601 +JCK-114a|vm|instr|baload|baload007|baload00701|baload00701|Test1 +javasoft/sqe/tests/vm/baload/baload007/baload00701/baload00701 +JCK-114a|vm|instr|bastore|bastore001|bastore00101|bastore00101|Test1 +javasoft/sqe/tests/vm/bastore/bastore001/bastore00101/bastore00101 +JCK-114a|vm|instr|bastore|bastore003|bastore00301|bastore00301|Test1 +javasoft/sqe/tests/vm/bastore/bastore003/bastore00301/bastore00301 +JCK-114a|vm|instr|bastore|bastore007|bastore00701|bastore00701|Test1 +javasoft/sqe/tests/vm/bastore/bastore007/bastore00701/bastore00701 +JCK-114a|vm|instr|bipush|bipush001|bipush00101|bipush00101|Test1 +javasoft/sqe/tests/vm/bipush/bipush001/bipush00101/bipush00101 +JCK-114a|vm|instr|bipush|bipush002|bipush00201|bipush00201|Test1 +javasoft/sqe/tests/vm/bipush/bipush002/bipush00201/bipush00201 +JCK-114a|vm|instr|caload|caload002|caload00201|caload00201|Test1 +javasoft/sqe/tests/vm/caload/caload002/caload00201/caload00201 +JCK-114a|vm|instr|caload|caload007|caload00701|caload00701|Test1 +javasoft/sqe/tests/vm/caload/caload007/caload00701/caload00701 +JCK-114a|vm|instr|caload|caload008|caload00801|caload00801|Test1 +javasoft/sqe/tests/vm/caload/caload008/caload00801/caload00801 +JCK-114a|vm|instr|castore|castore001|castore00101|castore00101|Test1 +javasoft/sqe/tests/vm/castore/castore001/castore00101/castore00101 +JCK-114a|vm|instr|castore|castore003|castore00301|castore00301|Test1 +javasoft/sqe/tests/vm/castore/castore003/castore00301/castore00301 +JCK-114a|vm|instr|castore|castore007|castore00701|castore00701|Test1 +javasoft/sqe/tests/vm/castore/castore007/castore00701/castore00701 +JCK-114a|vm|instr|castore|castore008|castore00801|castore00801|Test1 +javasoft/sqe/tests/vm/castore/castore008/castore00801/castore00801 +JCK-114a|vm|instr|checkcast|checkcast003|checkcast_arr2|checkcast_arr2|Test1 +javasoft/sqe/tests/vm/checkcast/checkcast003/checkcast_arr2 +JCK-114a|vm|instr|checkcast|checkcast003|checkcast_arr3|checkcast_arr3|Test1 +javasoft/sqe/tests/vm/checkcast/checkcast003/checkcast_arr3 +JCK-114a|vm|instr|checkcast|checkcast003|checkcast_arr4|checkcast_arr4|Test1 +javasoft/sqe/tests/vm/checkcast/checkcast003/checkcast_arr4 +JCK-114a|vm|instr|checkcast|checkcast003|checkcast_arr5|checkcast_arr5|Test1 +javasoft/sqe/tests/vm/checkcast/checkcast003/checkcast_arr5 +JCK-114a|vm|instr|checkcast|checkcast003|checkcast_arr6|checkcast_arr6|Test1 +javasoft/sqe/tests/vm/checkcast/checkcast003/checkcast_arr6 +JCK-114a|vm|instr|checkcast|checkcast004|checkcast00402|checkcast00402|Test1 +javasoft/sqe/tests/vm/checkcast/checkcast004/checkcast00402/checkcast00402 +JCK-114a|vm|instr|checkcast|checkcast005|checkcast00501|checkcast00501|Test1 +javasoft/sqe/tests/vm/checkcast/checkcast005/checkcast00501/checkcast00501 +JCK-114a|vm|instr|checkcast|checkcast006|checkcast00601|checkcast00601|Test1 +javasoft/sqe/tests/vm/checkcast/checkcast006/checkcast00601/checkcast00601 +JCK-114a|vm|instr|checkcast|checkcast006|checkcast00602|checkcast00602|Test1 +javasoft/sqe/tests/vm/checkcast/checkcast006/checkcast00602/checkcast00602 +JCK-114a|vm|instr|checkcast|checkcast007|checkcast00701|checkcast00701|Test1 +javasoft/sqe/tests/vm/checkcast/checkcast007/checkcast00701/checkcast00701 +JCK-114a|vm|instr|checkcast|checkcast008|checkcast00801|checkcast00801|Test1 +javasoft/sqe/tests/vm/checkcast/checkcast008/checkcast00801/checkcast00801 +JCK-114a|vm|instr|checkcast|checkcast009|checkcast00901|checkcast00901|Test1 +javasoft/sqe/tests/vm/checkcast/checkcast009/checkcast00901/checkcast00901 +JCK-114a|vm|instr|checkcast|checkcast009|checkcast00902|checkcast00902|Test1 +javasoft/sqe/tests/vm/checkcast/checkcast009/checkcast00902/checkcast00902 +JCK-114a|vm|instr|checkcast|checkcast009|checkcast00903|checkcast00903|Test1 +javasoft/sqe/tests/vm/checkcast/checkcast009/checkcast00903/checkcast00903 +JCK-114a|vm|instr|checkcast|checkcast009|checkcast00904|checkcast00904|Test1 +javasoft/sqe/tests/vm/checkcast/checkcast009/checkcast00904/checkcast00904 +JCK-114a|vm|instr|checkcast|checkcast010|checkcast01001|checkcast01001|Test1 +javasoft/sqe/tests/vm/checkcast/checkcast010/checkcast01001/checkcast01001 +JCK-114a|vm|instr|checkcast|checkcast011|checkcast01101|checkcast01101|Test1 +javasoft/sqe/tests/vm/checkcast/checkcast011/checkcast01101/checkcast01101 +JCK-114a|vm|instr|dadd|dadd001|dadd00101|dadd00101|Test1 +javasoft/sqe/tests/vm/dadd/dadd001/dadd00101/dadd00101 +JCK-114a|vm|instr|dadd|dadd002|dadd00201|dadd00201|Test1 +javasoft/sqe/tests/vm/dadd/dadd002/dadd00201/dadd00201 +JCK-114a|vm|instr|dadd|dadd003|dadd00301|dadd00301|Test1 +javasoft/sqe/tests/vm/dadd/dadd003/dadd00301/dadd00301 +JCK-114a|vm|instr|dadd|dadd004|dadd00401|dadd00401|Test1 +javasoft/sqe/tests/vm/dadd/dadd004/dadd00401/dadd00401 +JCK-114a|vm|instr|dadd|dadd005|dadd00501|dadd00501|Test1 +javasoft/sqe/tests/vm/dadd/dadd005/dadd00501/dadd00501 +JCK-114a|vm|instr|dadd|dadd006|dadd00601|dadd00601|Test1 +javasoft/sqe/tests/vm/dadd/dadd006/dadd00601/dadd00601 +JCK-114a|vm|instr|dadd|dadd007|dadd00701|dadd00701|Test1 +javasoft/sqe/tests/vm/dadd/dadd007/dadd00701/dadd00701 +JCK-114a|vm|instr|dadd|dadd008|dadd00801|dadd00801|Test1 +javasoft/sqe/tests/vm/dadd/dadd008/dadd00801/dadd00801 +JCK-114a|vm|instr|dadd|dadd009|dadd00901|dadd00901|Test1 +javasoft/sqe/tests/vm/dadd/dadd009/dadd00901/dadd00901 +JCK-114a|vm|instr|dadd|dadd010|dadd01001|dadd01001|Test1 +javasoft/sqe/tests/vm/dadd/dadd010/dadd01001/dadd01001 +JCK-114a|vm|instr|dadd|dadd011|dadd01101|dadd01101|Test1 +javasoft/sqe/tests/vm/dadd/dadd011/dadd01101/dadd01101 +JCK-114a|vm|instr|ddiv|ddiv001|ddiv00101|ddiv00101|Test1 +javasoft/sqe/tests/vm/ddiv/ddiv001/ddiv00101/ddiv00101 +JCK-114a|vm|instr|ddiv|ddiv002|ddiv00201|ddiv00201|Test1 +javasoft/sqe/tests/vm/ddiv/ddiv002/ddiv00201/ddiv00201 +JCK-114a|vm|instr|ddiv|ddiv003|ddiv00301|ddiv00301|Test1 +javasoft/sqe/tests/vm/ddiv/ddiv003/ddiv00301/ddiv00301 +JCK-114a|vm|instr|ddiv|ddiv004|ddiv00401|ddiv00401|Test1 +javasoft/sqe/tests/vm/ddiv/ddiv004/ddiv00401/ddiv00401 +JCK-114a|vm|instr|ddiv|ddiv005|ddiv00501|ddiv00501|Test1 +javasoft/sqe/tests/vm/ddiv/ddiv005/ddiv00501/ddiv00501 +JCK-114a|vm|instr|ddiv|ddiv006|ddiv00601|ddiv00601|Test1 +javasoft/sqe/tests/vm/ddiv/ddiv006/ddiv00601/ddiv00601 +JCK-114a|vm|instr|ddiv|ddiv007|ddiv00701|ddiv00701|Test1 +javasoft/sqe/tests/vm/ddiv/ddiv007/ddiv00701/ddiv00701 +JCK-114a|vm|instr|ddiv|ddiv008|ddiv00801|ddiv00801|Test1 +javasoft/sqe/tests/vm/ddiv/ddiv008/ddiv00801/ddiv00801 +JCK-114a|vm|instr|ddiv|ddiv009|ddiv00901|ddiv00901|Test1 +javasoft/sqe/tests/vm/ddiv/ddiv009/ddiv00901/ddiv00901 +JCK-114a|vm|instr|ddiv|ddiv010|ddiv01001|ddiv01001|Test1 +javasoft/sqe/tests/vm/ddiv/ddiv010/ddiv01001/ddiv01001 +JCK-114a|vm|instr|ddiv|ddiv011|ddiv01101|ddiv01101|Test1 +javasoft/sqe/tests/vm/ddiv/ddiv011/ddiv01101/ddiv01101 +JCK-114a|vm|instr|dmul|dmul001|dmul00101|dmul00101|Test1 +javasoft/sqe/tests/vm/dmul/dmul001/dmul00101/dmul00101 +JCK-114a|vm|instr|dmul|dmul002|dmul00201|dmul00201|Test1 +javasoft/sqe/tests/vm/dmul/dmul002/dmul00201/dmul00201 +JCK-114a|vm|instr|dmul|dmul003|dmul00301|dmul00301|Test1 +javasoft/sqe/tests/vm/dmul/dmul003/dmul00301/dmul00301 +JCK-114a|vm|instr|dmul|dmul004|dmul00401|dmul00401|Test1 +javasoft/sqe/tests/vm/dmul/dmul004/dmul00401/dmul00401 +JCK-114a|vm|instr|dmul|dmul005|dmul00501|dmul00501|Test1 +javasoft/sqe/tests/vm/dmul/dmul005/dmul00501/dmul00501 +JCK-114a|vm|instr|dmul|dmul006|dmul00601|dmul00601|Test1 +javasoft/sqe/tests/vm/dmul/dmul006/dmul00601/dmul00601 +JCK-114a|vm|instr|dmul|dmul007|dmul00701|dmul00701|Test1 +javasoft/sqe/tests/vm/dmul/dmul007/dmul00701/dmul00701 +JCK-114a|vm|instr|dmul|dmul008|dmul00801|dmul00801|Test1 +javasoft/sqe/tests/vm/dmul/dmul008/dmul00801/dmul00801 +JCK-114a|vm|instr|dmul|dmul011|dmul01101|dmul01101|Test1 +javasoft/sqe/tests/vm/dmul/dmul011/dmul01101/dmul01101 +JCK-114a|vm|instr|dneg|dneg001|dneg00101|dneg00101|Test1 +javasoft/sqe/tests/vm/dneg/dneg001/dneg00101/dneg00101 +JCK-114a|vm|instr|dneg|dneg002|dneg00201|dneg00201|Test1 +javasoft/sqe/tests/vm/dneg/dneg002/dneg00201/dneg00201 +JCK-114a|vm|instr|dneg|dneg003|dneg00301|dneg00301|Test1 +javasoft/sqe/tests/vm/dneg/dneg003/dneg00301/dneg00301 +JCK-114a|vm|instr|dneg|dneg004|dneg00401|dneg00401|Test1 +javasoft/sqe/tests/vm/dneg/dneg004/dneg00401/dneg00401 +JCK-114a|vm|instr|dneg|dneg006|dneg00601|dneg00601|Test1 +javasoft/sqe/tests/vm/dneg/dneg006/dneg00601/dneg00601 +JCK-114a|vm|instr|drem|drem001|drem00101|drem00101|Test1 +javasoft/sqe/tests/vm/drem/drem001/drem00101/drem00101 +JCK-114a|vm|instr|drem|drem002|drem00201|drem00201|Test1 +javasoft/sqe/tests/vm/drem/drem002/drem00201/drem00201 +JCK-114a|vm|instr|drem|drem003|drem00301|drem00301|Test1 +javasoft/sqe/tests/vm/drem/drem003/drem00301/drem00301 +JCK-114a|vm|instr|drem|drem004|drem00401|drem00401|Test1 +javasoft/sqe/tests/vm/drem/drem004/drem00401/drem00401 +JCK-114a|vm|instr|drem|drem005|drem00501|drem00501|Test1 +javasoft/sqe/tests/vm/drem/drem005/drem00501/drem00501 +JCK-114a|vm|instr|drem|drem006|drem00601|drem00601|Test1 +javasoft/sqe/tests/vm/drem/drem006/drem00601/drem00601 +JCK-114a|vm|instr|drem|drem007|drem00701|drem00701|Test1 +javasoft/sqe/tests/vm/drem/drem007/drem00701/drem00701 +JCK-114a|vm|instr|drem|drem008|drem00801|drem00801|Test1 +javasoft/sqe/tests/vm/drem/drem008/drem00801/drem00801 +JCK-114a|vm|instr|drem|drem011|drem01101|drem01101|Test1 +javasoft/sqe/tests/vm/drem/drem011/drem01101/drem01101 +JCK-114a|vm|instr|dsub|dsub001|dsub00101|dsub00101|Test1 +javasoft/sqe/tests/vm/dsub/dsub001/dsub00101/dsub00101 +JCK-114a|vm|instr|dsub|dsub001|dsub00102|dsub00102|Test1 +javasoft/sqe/tests/vm/dsub/dsub001/dsub00102/dsub00102 +JCK-114a|vm|instr|dsub|dsub001|dsub00103|dsub00103|Test1 +javasoft/sqe/tests/vm/dsub/dsub001/dsub00103/dsub00103 +JCK-114a|vm|instr|dsub|dsub001|dsub00104|dsub00104|Test1 +javasoft/sqe/tests/vm/dsub/dsub001/dsub00104/dsub00104 +JCK-114a|vm|instr|dsub|dsub001|dsub00105|dsub00105|Test1 +javasoft/sqe/tests/vm/dsub/dsub001/dsub00105/dsub00105 +JCK-114a|vm|instr|dsub|dsub001|dsub00106|dsub00106|Test1 +javasoft/sqe/tests/vm/dsub/dsub001/dsub00106/dsub00106 +JCK-114a|vm|instr|dsub|dsub001|dsub00107|dsub00107|Test1 +javasoft/sqe/tests/vm/dsub/dsub001/dsub00107/dsub00107 +JCK-114a|vm|instr|dsub|dsub001|dsub00108|dsub00108|Test1 +javasoft/sqe/tests/vm/dsub/dsub001/dsub00108/dsub00108 +JCK-114a|vm|instr|dsub|dsub001|dsub00109|dsub00109|Test1 +javasoft/sqe/tests/vm/dsub/dsub001/dsub00109/dsub00109 +JCK-114a|vm|instr|dsub|dsub001|dsub00110|dsub00110|Test1 +javasoft/sqe/tests/vm/dsub/dsub001/dsub00110/dsub00110 +JCK-114a|vm|instr|dsub|dsub002|dsub00201|dsub00201|Test1 +javasoft/sqe/tests/vm/dsub/dsub002/dsub00201/dsub00201 +JCK-114a|vm|instr|dsub|dsub003|dsub00301|dsub00301|Test1 +javasoft/sqe/tests/vm/dsub/dsub003/dsub00301/dsub00301 +JCK-114a|vm|instr|dsub|dsub005|dsub00501|dsub00501|Test1 +javasoft/sqe/tests/vm/dsub/dsub005/dsub00501/dsub00501 +JCK-114a|vm|instr|daload|daload002|daload00201|daload00201|Test1 +javasoft/sqe/tests/vm/daload/daload002/daload00201/daload00201 +JCK-114a|vm|instr|daload|daload006|daload00601|daload00601|Test1 +javasoft/sqe/tests/vm/daload/daload006/daload00601/daload00601 +JCK-114a|vm|instr|daload|daload007|daload00701|daload00701|Test1 +javasoft/sqe/tests/vm/daload/daload007/daload00701/daload00701 +JCK-114a|vm|instr|dastore|dastore001|dastore00101|dastore00101|Test1 +javasoft/sqe/tests/vm/dastore/dastore001/dastore00101/dastore00101 +JCK-114a|vm|instr|dastore|dastore003|dastore00301|dastore00301|Test1 +javasoft/sqe/tests/vm/dastore/dastore003/dastore00301/dastore00301 +JCK-114a|vm|instr|dastore|dastore007|dastore00701|dastore00701|Test1 +javasoft/sqe/tests/vm/dastore/dastore007/dastore00701/dastore00701 +JCK-114a|vm|instr|dastore|dastore008|dastore00801|dastore00801|Test1 +javasoft/sqe/tests/vm/dastore/dastore008/dastore00801/dastore00801 +JCK-114a|vm|instr|dcmpop|dcmpop001|dcmpop00101|dcmpop00101|Test1 +javasoft/sqe/tests/vm/dcmpop/dcmpop001/dcmpop00101/dcmpop00101 +JCK-114a|vm|instr|dcmpop|dcmpop002|dcmpop00201|dcmpop00201|Test1 +javasoft/sqe/tests/vm/dcmpop/dcmpop002/dcmpop00201/dcmpop00201 +JCK-114a|vm|instr|dcmpop|dcmpop002|dcmpop00202|dcmpop00202|Test1 +javasoft/sqe/tests/vm/dcmpop/dcmpop002/dcmpop00202/dcmpop00202 +JCK-114a|vm|instr|dcmpop|dcmpop003|dcmpop00301|dcmpop00301|Test1 +javasoft/sqe/tests/vm/dcmpop/dcmpop003/dcmpop00301/dcmpop00301 +JCK-114a|vm|instr|dcmpop|dcmpop004|dcmpop00401|dcmpop00401|Test1 +javasoft/sqe/tests/vm/dcmpop/dcmpop004/dcmpop00401/dcmpop00401 +JCK-114a|vm|instr|dcmpop|dcmpop005|dcmpop00501|dcmpop00501|Test1 +javasoft/sqe/tests/vm/dcmpop/dcmpop005/dcmpop00501/dcmpop00501 +JCK-114a|vm|instr|dcmpop|dcmpop006|dcmpop00601|dcmpop00601|Test1 +javasoft/sqe/tests/vm/dcmpop/dcmpop006/dcmpop00601/dcmpop00601 +JCK-114a|vm|instr|d2f|d2f001|d2f00101|d2f00101|Test1 +javasoft/sqe/tests/vm/d2f/d2f001/d2f00101/d2f00101 +JCK-114a|vm|instr|d2f|d2f002|d2f00201|d2f00201|Test1 +javasoft/sqe/tests/vm/d2f/d2f002/d2f00201/d2f00201 +JCK-114a|vm|instr|d2f|d2f003|d2f00301|d2f00301|Test1 +javasoft/sqe/tests/vm/d2f/d2f003/d2f00301/d2f00301 +JCK-114a|vm|instr|d2f|d2f004|d2f00401|d2f00401|Test1 +javasoft/sqe/tests/vm/d2f/d2f004/d2f00401/d2f00401 +JCK-114a|vm|instr|d2f|d2f005|d2f00501|d2f00501|Test1 +javasoft/sqe/tests/vm/d2f/d2f005/d2f00501/d2f00501 +JCK-114a|vm|instr|d2i|d2i002|d2i00201|d2i00201|Test1 +javasoft/sqe/tests/vm/d2i/d2i002/d2i00201/d2i00201 +JCK-114a|vm|instr|d2i|d2i003|d2i00301|d2i00301|Test1 +javasoft/sqe/tests/vm/d2i/d2i003/d2i00301/d2i00301 +JCK-114a|vm|instr|d2i|d2i004|d2i00401|d2i00401|Test1 +javasoft/sqe/tests/vm/d2i/d2i004/d2i00401/d2i00401 +JCK-114a|vm|instr|d2l|d2l002|d2l00201|d2l00201|Test1 +javasoft/sqe/tests/vm/d2l/d2l002/d2l00201/d2l00201 +JCK-114a|vm|instr|d2l|d2l003|d2l00301|d2l00301|Test1 +javasoft/sqe/tests/vm/d2l/d2l003/d2l00301/d2l00301 +JCK-114a|vm|instr|d2l|d2l004|d2l00401|d2l00401|Test1 +javasoft/sqe/tests/vm/d2l/d2l004/d2l00401/d2l00401 +JCK-114a|vm|instr|dload|dload001|dload00101|dload00101|Test1 +javasoft/sqe/tests/vm/dload/dload001/dload00101/dload00101 +JCK-114a|vm|instr|dloadN|dloadN001|dloadN00105|dloadN00105|Test1 +javasoft/sqe/tests/vm/dloadN/dloadN001/dloadN00105/dloadN00105 +JCK-114a|vm|instr|dloadN|dloadN001|dloadN00106|dloadN00106|Test1 +javasoft/sqe/tests/vm/dloadN/dloadN001/dloadN00106/dloadN00106 +JCK-114a|vm|instr|dloadN|dloadN001|dloadN00107|dloadN00107|Test1 +javasoft/sqe/tests/vm/dloadN/dloadN001/dloadN00107/dloadN00107 +JCK-114a|vm|instr|dloadN|dloadN001|dloadN00108|dloadN00108|Test1 +javasoft/sqe/tests/vm/dloadN/dloadN001/dloadN00108/dloadN00108 +JCK-114a|vm|instr|dload_w|dload_w003|dload_w00301|dload_w00301|Test1 +javasoft/sqe/tests/vm/dload_w/dload_w003/dload_w00301/dload_w00301 +JCK-114a|vm|instr|dstore|dstore001|dstore00101|dstore00101|Test1 +javasoft/sqe/tests/vm/dstore/dstore001/dstore00101/dstore00101 +JCK-114a|vm|instr|dstore|dstore005|dstore00501|dstore00501|Test1 +javasoft/sqe/tests/vm/dstore/dstore005/dstore00501/dstore00501 +JCK-114a|vm|instr|dstoreN|dstoreN004|dstoreN00401|dstoreN00401|Test1 +javasoft/sqe/tests/vm/dstoreN/dstoreN004/dstoreN00401/dstoreN00401 +JCK-114a|vm|instr|dstoreN|dstoreN004|dstoreN00402|dstoreN00402|Test1 +javasoft/sqe/tests/vm/dstoreN/dstoreN004/dstoreN00402/dstoreN00402 +JCK-114a|vm|instr|dstoreN|dstoreN004|dstoreN00403|dstoreN00403|Test1 +javasoft/sqe/tests/vm/dstoreN/dstoreN004/dstoreN00403/dstoreN00403 +JCK-114a|vm|instr|dstoreN|dstoreN004|dstoreN00404|dstoreN00404|Test1 +javasoft/sqe/tests/vm/dstoreN/dstoreN004/dstoreN00404/dstoreN00404 +JCK-114a|vm|instr|dstore_w|dstore_w001|dstore_w00101|dstore_w00101|Test1 +javasoft/sqe/tests/vm/dstore_w/dstore_w001/dstore_w00101/dstore_w00101 +JCK-114a|vm|instr|dreturn|dreturn001|dreturn00101|dreturn00101|Test1 +javasoft/sqe/tests/vm/dreturn/dreturn001/dreturn00101/dreturn00101 +JCK-114a|vm|instr|dreturn|dreturn002|dreturn00201|dreturn00201|Test1 +javasoft/sqe/tests/vm/dreturn/dreturn002/dreturn00201/dreturn00201 +JCK-114a|vm|instr|dreturn|dreturn003|dreturn00301|dreturn00301|Test1 +javasoft/sqe/tests/vm/dreturn/dreturn003/dreturn00301/dreturn00301 +JCK-114a|vm|instr|dreturn|dreturn004|dreturn00401|dreturn00401|Test1 +javasoft/sqe/tests/vm/dreturn/dreturn004/dreturn00401/dreturn00401 +JCK-114a|vm|instr|dreturn|dreturn007|dreturn00701|dreturn00701|Test1 +javasoft/sqe/tests/vm/dreturn/dreturn007/dreturn00701/dreturn00701 +JCK-114a|vm|instr|dreturn|dreturn007|dreturn00702|dreturn00702|Test1 +javasoft/sqe/tests/vm/dreturn/dreturn007/dreturn00702/dreturn00702 +JCK-114a|vm|instr|dup|dup001|dup00101|dup00101|Test1 +javasoft/sqe/tests/vm/dup/dup001/dup00101/dup00101 +JCK-114a|vm|instr|dup|dup004|dup00403|dup00403|Test1 +javasoft/sqe/tests/vm/dup/dup004/dup00403/dup00403 +JCK-114a|vm|instr|dup|dup004|dup00404|dup00404|Test1 +javasoft/sqe/tests/vm/dup/dup004/dup00404/dup00404 +JCK-114a|vm|instr|dup|dup004|dup00405|dup00405|Test1 +javasoft/sqe/tests/vm/dup/dup004/dup00405/dup00405 +JCK-114a|vm|instr|dup2|dup2001|dup200101|dup200101|Test1 +javasoft/sqe/tests/vm/dup2/dup2001/dup200101/dup200101 +JCK-114a|vm|instr|dup2|dup2001|dup200102|dup200102|Test1 +javasoft/sqe/tests/vm/dup2/dup2001/dup200102/dup200102 +JCK-114a|vm|instr|dup2|dup2001|dup200103|dup200103|Test1 +javasoft/sqe/tests/vm/dup2/dup2001/dup200103/dup200103 +JCK-114a|vm|instr|dup2|dup2001|dup200104|dup200104|Test1 +javasoft/sqe/tests/vm/dup2/dup2001/dup200104/dup200104 +JCK-114a|vm|instr|dup2|dup2001|dup200105|dup200105|Test1 +javasoft/sqe/tests/vm/dup2/dup2001/dup200105/dup200105 +JCK-114a|vm|instr|dup2_x1|dup2_x1001|dup2_x100101|dup2_x100101|Test1 +javasoft/sqe/tests/vm/dup2_x1/dup2_x1001/dup2_x100101/dup2_x100101 +JCK-114a|vm|instr|dup2_x1|dup2_x1001|dup2_x100102|dup2_x100102|Test1 +javasoft/sqe/tests/vm/dup2_x1/dup2_x1001/dup2_x100102/dup2_x100102 +JCK-114a|vm|instr|dup2_x1|dup2_x1001|dup2_x100103|dup2_x100103|Test1 +javasoft/sqe/tests/vm/dup2_x1/dup2_x1001/dup2_x100103/dup2_x100103 +JCK-114a|vm|instr|dup2_x1|dup2_x1001|dup2_x100104|dup2_x100104|Test1 +javasoft/sqe/tests/vm/dup2_x1/dup2_x1001/dup2_x100104/dup2_x100104 +JCK-114a|vm|instr|dup2_x1|dup2_x1001|dup2_x100105|dup2_x100105|Test1 +javasoft/sqe/tests/vm/dup2_x1/dup2_x1001/dup2_x100105/dup2_x100105 +JCK-114a|vm|instr|dup2_x2|dup2_x2001|dup2_x200101|dup2_x200101|Test1 +javasoft/sqe/tests/vm/dup2_x2/dup2_x2001/dup2_x200101/dup2_x200101 +JCK-114a|vm|instr|dup2_x2|dup2_x2001|dup2_x200102|dup2_x200102|Test1 +javasoft/sqe/tests/vm/dup2_x2/dup2_x2001/dup2_x200102/dup2_x200102 +JCK-114a|vm|instr|dup2_x2|dup2_x2001|dup2_x200103|dup2_x200103|Test1 +javasoft/sqe/tests/vm/dup2_x2/dup2_x2001/dup2_x200103/dup2_x200103 +JCK-114a|vm|instr|dup2_x2|dup2_x2001|dup2_x200104|dup2_x200104|Test1 +javasoft/sqe/tests/vm/dup2_x2/dup2_x2001/dup2_x200104/dup2_x200104 +JCK-114a|vm|instr|dup2_x2|dup2_x2001|dup2_x200105|dup2_x200105|Test1 +javasoft/sqe/tests/vm/dup2_x2/dup2_x2001/dup2_x200105/dup2_x200105 +JCK-114a|vm|instr|dup_x1|dup_x1001|dup_x100101|dup_x100101|Test1 +javasoft/sqe/tests/vm/dup_x1/dup_x1001/dup_x100101/dup_x100101 +JCK-114a|vm|instr|dup_x1|dup_x1004|dup_x100403|dup_x100403|Test1 +javasoft/sqe/tests/vm/dup_x1/dup_x1004/dup_x100403/dup_x100403 +JCK-114a|vm|instr|dup_x1|dup_x1004|dup_x100404|dup_x100404|Test1 +javasoft/sqe/tests/vm/dup_x1/dup_x1004/dup_x100404/dup_x100404 +JCK-114a|vm|instr|dup_x1|dup_x1004|dup_x100405|dup_x100405|Test1 +javasoft/sqe/tests/vm/dup_x1/dup_x1004/dup_x100405/dup_x100405 +JCK-114a|vm|instr|dup_x2|dup_x2001|dup_x200101|dup_x200101|Test1 +javasoft/sqe/tests/vm/dup_x2/dup_x2001/dup_x200101/dup_x200101 +JCK-114a|vm|instr|dup_x2|dup_x2004|dup_x200401|dup_x200401|Test1 +javasoft/sqe/tests/vm/dup_x2/dup_x2004/dup_x200401/dup_x200401 +JCK-114a|vm|instr|dup_x2|dup_x2004|dup_x200402|dup_x200402|Test1 +javasoft/sqe/tests/vm/dup_x2/dup_x2004/dup_x200402/dup_x200402 +JCK-114a|vm|instr|dup_x2|dup_x2004|dup_x200403|dup_x200403|Test1 +javasoft/sqe/tests/vm/dup_x2/dup_x2004/dup_x200403/dup_x200403 +JCK-114a|vm|instr|dconstD|dconstD001|dconstD00102|dconstD00102|Test1 +javasoft/sqe/tests/vm/dconstD/dconstD001/dconstD00102/dconstD00102 +JCK-114a|vm|instr|dconstD|dconstD001|dconstD00103|dconstD00103|Test1 +javasoft/sqe/tests/vm/dconstD/dconstD001/dconstD00103/dconstD00103 +JCK-114a|vm|instr|fadd|fadd001|fadd00101|fadd00101|Test1 +javasoft/sqe/tests/vm/fadd/fadd001/fadd00101/fadd00101 +JCK-114a|vm|instr|fadd|fadd002|fadd00201|fadd00201|Test1 +javasoft/sqe/tests/vm/fadd/fadd002/fadd00201/fadd00201 +JCK-114a|vm|instr|fadd|fadd003|fadd00301|fadd00301|Test1 +javasoft/sqe/tests/vm/fadd/fadd003/fadd00301/fadd00301 +JCK-114a|vm|instr|fadd|fadd004|fadd00401|fadd00401|Test1 +javasoft/sqe/tests/vm/fadd/fadd004/fadd00401/fadd00401 +JCK-114a|vm|instr|fadd|fadd005|fadd00501|fadd00501|Test1 +javasoft/sqe/tests/vm/fadd/fadd005/fadd00501/fadd00501 +JCK-114a|vm|instr|fadd|fadd006|fadd00601|fadd00601|Test1 +javasoft/sqe/tests/vm/fadd/fadd006/fadd00601/fadd00601 +JCK-114a|vm|instr|fadd|fadd007|fadd00701|fadd00701|Test1 +javasoft/sqe/tests/vm/fadd/fadd007/fadd00701/fadd00701 +JCK-114a|vm|instr|fadd|fadd008|fadd00801|fadd00801|Test1 +javasoft/sqe/tests/vm/fadd/fadd008/fadd00801/fadd00801 +JCK-114a|vm|instr|fadd|fadd009|fadd00901|fadd00901|Test1 +javasoft/sqe/tests/vm/fadd/fadd009/fadd00901/fadd00901 +JCK-114a|vm|instr|fadd|fadd010|fadd01001|fadd01001|Test1 +javasoft/sqe/tests/vm/fadd/fadd010/fadd01001/fadd01001 +JCK-114a|vm|instr|fadd|fadd011|fadd01101|fadd01101|Test1 +javasoft/sqe/tests/vm/fadd/fadd011/fadd01101/fadd01101 +JCK-114a|vm|instr|fadd|fadd014|fadd01401|fadd01401|Test1 +javasoft/sqe/tests/vm/fadd/fadd014/fadd01401/fadd01401 +JCK-114a|vm|instr|fdiv|fdiv001|fdiv00101|fdiv00101|Test1 +javasoft/sqe/tests/vm/fdiv/fdiv001/fdiv00101/fdiv00101 +JCK-114a|vm|instr|fdiv|fdiv002|fdiv00201|fdiv00201|Test1 +javasoft/sqe/tests/vm/fdiv/fdiv002/fdiv00201/fdiv00201 +JCK-114a|vm|instr|fdiv|fdiv003|fdiv00301|fdiv00301|Test1 +javasoft/sqe/tests/vm/fdiv/fdiv003/fdiv00301/fdiv00301 +JCK-114a|vm|instr|fdiv|fdiv004|fdiv00401|fdiv00401|Test1 +javasoft/sqe/tests/vm/fdiv/fdiv004/fdiv00401/fdiv00401 +JCK-114a|vm|instr|fdiv|fdiv005|fdiv00501|fdiv00501|Test1 +javasoft/sqe/tests/vm/fdiv/fdiv005/fdiv00501/fdiv00501 +JCK-114a|vm|instr|fdiv|fdiv006|fdiv00601|fdiv00601|Test1 +javasoft/sqe/tests/vm/fdiv/fdiv006/fdiv00601/fdiv00601 +JCK-114a|vm|instr|fdiv|fdiv007|fdiv00701|fdiv00701|Test1 +javasoft/sqe/tests/vm/fdiv/fdiv007/fdiv00701/fdiv00701 +JCK-114a|vm|instr|fdiv|fdiv008|fdiv00801|fdiv00801|Test1 +javasoft/sqe/tests/vm/fdiv/fdiv008/fdiv00801/fdiv00801 +JCK-114a|vm|instr|fdiv|fdiv009|fdiv00901|fdiv00901|Test1 +javasoft/sqe/tests/vm/fdiv/fdiv009/fdiv00901/fdiv00901 +JCK-114a|vm|instr|fdiv|fdiv010|fdiv01001|fdiv01001|Test1 +javasoft/sqe/tests/vm/fdiv/fdiv010/fdiv01001/fdiv01001 +JCK-114a|vm|instr|fdiv|fdiv011|fdiv01101|fdiv01101|Test1 +javasoft/sqe/tests/vm/fdiv/fdiv011/fdiv01101/fdiv01101 +JCK-114a|vm|instr|fdiv|fdiv014|fdiv01401|fdiv01401|Test1 +javasoft/sqe/tests/vm/fdiv/fdiv014/fdiv01401/fdiv01401 +JCK-114a|vm|instr|fmul|fmul001|fmul00101|fmul00101|Test1 +javasoft/sqe/tests/vm/fmul/fmul001/fmul00101/fmul00101 +JCK-114a|vm|instr|fmul|fmul002|fmul00201|fmul00201|Test1 +javasoft/sqe/tests/vm/fmul/fmul002/fmul00201/fmul00201 +JCK-114a|vm|instr|fmul|fmul003|fmul00301|fmul00301|Test1 +javasoft/sqe/tests/vm/fmul/fmul003/fmul00301/fmul00301 +JCK-114a|vm|instr|fmul|fmul004|fmul00401|fmul00401|Test1 +javasoft/sqe/tests/vm/fmul/fmul004/fmul00401/fmul00401 +JCK-114a|vm|instr|fmul|fmul005|fmul00501|fmul00501|Test1 +javasoft/sqe/tests/vm/fmul/fmul005/fmul00501/fmul00501 +JCK-114a|vm|instr|fmul|fmul005|fmul00502|fmul00502|Test1 +javasoft/sqe/tests/vm/fmul/fmul005/fmul00502/fmul00502 +JCK-114a|vm|instr|fmul|fmul006|fmul00601|fmul00601|Test1 +javasoft/sqe/tests/vm/fmul/fmul006/fmul00601/fmul00601 +JCK-114a|vm|instr|fmul|fmul007|fmul00701|fmul00701|Test1 +javasoft/sqe/tests/vm/fmul/fmul007/fmul00701/fmul00701 +JCK-114a|vm|instr|fmul|fmul008|fmul00801|fmul00801|Test1 +javasoft/sqe/tests/vm/fmul/fmul008/fmul00801/fmul00801 +JCK-114a|vm|instr|fmul|fmul011|fmul01101|fmul01101|Test1 +javasoft/sqe/tests/vm/fmul/fmul011/fmul01101/fmul01101 +JCK-114a|vm|instr|fneg|fneg001|fneg00101|fneg00101|Test1 +javasoft/sqe/tests/vm/fneg/fneg001/fneg00101/fneg00101 +JCK-114a|vm|instr|fneg|fneg002|fneg00201|fneg00201|Test1 +javasoft/sqe/tests/vm/fneg/fneg002/fneg00201/fneg00201 +JCK-114a|vm|instr|fneg|fneg003|fneg00301|fneg00301|Test1 +javasoft/sqe/tests/vm/fneg/fneg003/fneg00301/fneg00301 +JCK-114a|vm|instr|fneg|fneg004|fneg00401|fneg00401|Test1 +javasoft/sqe/tests/vm/fneg/fneg004/fneg00401/fneg00401 +JCK-114a|vm|instr|fneg|fneg006|fneg00601|fneg00601|Test1 +javasoft/sqe/tests/vm/fneg/fneg006/fneg00601/fneg00601 +JCK-114a|vm|instr|frem|frem001|frem00101|frem00101|Test1 +javasoft/sqe/tests/vm/frem/frem001/frem00101/frem00101 +JCK-114a|vm|instr|frem|frem002|frem00201|frem00201|Test1 +javasoft/sqe/tests/vm/frem/frem002/frem00201/frem00201 +JCK-114a|vm|instr|frem|frem003|frem00301|frem00301|Test1 +javasoft/sqe/tests/vm/frem/frem003/frem00301/frem00301 +JCK-114a|vm|instr|frem|frem004|frem00401|frem00401|Test1 +javasoft/sqe/tests/vm/frem/frem004/frem00401/frem00401 +JCK-114a|vm|instr|frem|frem005|frem00501|frem00501|Test1 +javasoft/sqe/tests/vm/frem/frem005/frem00501/frem00501 +JCK-114a|vm|instr|frem|frem006|frem00601|frem00601|Test1 +javasoft/sqe/tests/vm/frem/frem006/frem00601/frem00601 +JCK-114a|vm|instr|frem|frem007|frem00701|frem00701|Test1 +javasoft/sqe/tests/vm/frem/frem007/frem00701/frem00701 +JCK-114a|vm|instr|frem|frem008|frem00801|frem00801|Test1 +javasoft/sqe/tests/vm/frem/frem008/frem00801/frem00801 +JCK-114a|vm|instr|fsub|fsub001|fsub00101|fsub00101|Test1 +javasoft/sqe/tests/vm/fsub/fsub001/fsub00101/fsub00101 +JCK-114a|vm|instr|fsub|fsub001|fsub00102|fsub00102|Test1 +javasoft/sqe/tests/vm/fsub/fsub001/fsub00102/fsub00102 +JCK-114a|vm|instr|fsub|fsub001|fsub00103|fsub00103|Test1 +javasoft/sqe/tests/vm/fsub/fsub001/fsub00103/fsub00103 +JCK-114a|vm|instr|fsub|fsub001|fsub00104|fsub00104|Test1 +javasoft/sqe/tests/vm/fsub/fsub001/fsub00104/fsub00104 +JCK-114a|vm|instr|fsub|fsub001|fsub00105|fsub00105|Test1 +javasoft/sqe/tests/vm/fsub/fsub001/fsub00105/fsub00105 +JCK-114a|vm|instr|fsub|fsub001|fsub00106|fsub00106|Test1 +javasoft/sqe/tests/vm/fsub/fsub001/fsub00106/fsub00106 +JCK-114a|vm|instr|fsub|fsub001|fsub00107|fsub00107|Test1 +javasoft/sqe/tests/vm/fsub/fsub001/fsub00107/fsub00107 +JCK-114a|vm|instr|fsub|fsub001|fsub00108|fsub00108|Test1 +javasoft/sqe/tests/vm/fsub/fsub001/fsub00108/fsub00108 +JCK-114a|vm|instr|fsub|fsub001|fsub00109|fsub00109|Test1 +javasoft/sqe/tests/vm/fsub/fsub001/fsub00109/fsub00109 +JCK-114a|vm|instr|fsub|fsub001|fsub00110|fsub00110|Test1 +javasoft/sqe/tests/vm/fsub/fsub001/fsub00110/fsub00110 +JCK-114a|vm|instr|fsub|fsub002|fsub00201|fsub00201|Test1 +javasoft/sqe/tests/vm/fsub/fsub002/fsub00201/fsub00201 +JCK-114a|vm|instr|fsub|fsub003|fsub00301|fsub00301|Test1 +javasoft/sqe/tests/vm/fsub/fsub003/fsub00301/fsub00301 +JCK-114a|vm|instr|fsub|fsub004|fsub00401|fsub00401|Test1 +javasoft/sqe/tests/vm/fsub/fsub004/fsub00401/fsub00401 +JCK-114a|vm|instr|faload|faload002|faload00201|faload00201|Test1 +javasoft/sqe/tests/vm/faload/faload002/faload00201/faload00201 +JCK-114a|vm|instr|faload|faload006|faload00601|faload00601|Test1 +javasoft/sqe/tests/vm/faload/faload006/faload00601/faload00601 +JCK-114a|vm|instr|faload|faload007|faload00701|faload00701|Test1 +javasoft/sqe/tests/vm/faload/faload007/faload00701/faload00701 +JCK-114a|vm|instr|fastore|fastore001|fastore00101|fastore00101|Test1 +javasoft/sqe/tests/vm/fastore/fastore001/fastore00101/fastore00101 +JCK-114a|vm|instr|fastore|fastore003|fastore00301|fastore00301|Test1 +javasoft/sqe/tests/vm/fastore/fastore003/fastore00301/fastore00301 +JCK-114a|vm|instr|fastore|fastore008|fastore00801|fastore00801|Test1 +javasoft/sqe/tests/vm/fastore/fastore008/fastore00801/fastore00801 +JCK-114a|vm|instr|fcmpop|fcmpop001|fcmpop00101|fcmpop00101|Test1 +javasoft/sqe/tests/vm/fcmpop/fcmpop001/fcmpop00101/fcmpop00101 +JCK-114a|vm|instr|fcmpop|fcmpop002|fcmpop00201|fcmpop00201|Test1 +javasoft/sqe/tests/vm/fcmpop/fcmpop002/fcmpop00201/fcmpop00201 +JCK-114a|vm|instr|fcmpop|fcmpop003|fcmpop00301|fcmpop00301|Test1 +javasoft/sqe/tests/vm/fcmpop/fcmpop003/fcmpop00301/fcmpop00301 +JCK-114a|vm|instr|fcmpop|fcmpop004|fcmpop00401|fcmpop00401|Test1 +javasoft/sqe/tests/vm/fcmpop/fcmpop004/fcmpop00401/fcmpop00401 +JCK-114a|vm|instr|fcmpop|fcmpop005|fcmpop00501|fcmpop00501|Test1 +javasoft/sqe/tests/vm/fcmpop/fcmpop005/fcmpop00501/fcmpop00501 +JCK-114a|vm|instr|fcmpop|fcmpop006|fcmpop00601|fcmpop00601|Test1 +javasoft/sqe/tests/vm/fcmpop/fcmpop006/fcmpop00601/fcmpop00601 +JCK-114a|vm|instr|f2d|f2d001|f2d00101|f2d00101|Test1 +javasoft/sqe/tests/vm/f2d/f2d001/f2d00101/f2d00101 +JCK-114a|vm|instr|fload|fload001|fload00101|fload00101|Test1 +javasoft/sqe/tests/vm/fload/fload001/fload00101/fload00101 +JCK-114a|vm|instr|fload|fload003|fload00301|fload00301|Test1 +javasoft/sqe/tests/vm/fload/fload003/fload00301/fload00301 +JCK-114a|vm|instr|floadN|floadN002|floadN00202|floadN00202|Test1 +javasoft/sqe/tests/vm/floadN/floadN002/floadN00202/floadN00202 +JCK-114a|vm|instr|floadN|floadN002|floadN00203|floadN00203|Test1 +javasoft/sqe/tests/vm/floadN/floadN002/floadN00203/floadN00203 +JCK-114a|vm|instr|floadN|floadN002|floadN00204|floadN00204|Test1 +javasoft/sqe/tests/vm/floadN/floadN002/floadN00204/floadN00204 +JCK-114a|vm|instr|floadN|floadN002|floadN00205|floadN00205|Test1 +javasoft/sqe/tests/vm/floadN/floadN002/floadN00205/floadN00205 +JCK-114a|vm|instr|fload_w|fload_w001|fload_w00101|fload_w00101|Test1 +javasoft/sqe/tests/vm/fload_w/fload_w001/fload_w00101/fload_w00101 +JCK-114a|vm|instr|fload_w|fload_w003|fload_w00301|fload_w00301|Test1 +javasoft/sqe/tests/vm/fload_w/fload_w003/fload_w00301/fload_w00301 +JCK-114a|vm|instr|fstore|fstore001|fstore00101|fstore00101|Test1 +javasoft/sqe/tests/vm/fstore/fstore001/fstore00101/fstore00101 +JCK-114a|vm|instr|fstore|fstore005|fstore00501|fstore00501|Test1 +javasoft/sqe/tests/vm/fstore/fstore005/fstore00501/fstore00501 +JCK-114a|vm|instr|fstoreN|fstoreN004|fstoreN00401|fstoreN00401|Test1 +javasoft/sqe/tests/vm/fstoreN/fstoreN004/fstoreN00401/fstoreN00401 +JCK-114a|vm|instr|fstoreN|fstoreN004|fstoreN00402|fstoreN00402|Test1 +javasoft/sqe/tests/vm/fstoreN/fstoreN004/fstoreN00402/fstoreN00402 +JCK-114a|vm|instr|fstoreN|fstoreN004|fstoreN00403|fstoreN00403|Test1 +javasoft/sqe/tests/vm/fstoreN/fstoreN004/fstoreN00403/fstoreN00403 +JCK-114a|vm|instr|fstoreN|fstoreN004|fstoreN00404|fstoreN00404|Test1 +javasoft/sqe/tests/vm/fstoreN/fstoreN004/fstoreN00404/fstoreN00404 +JCK-114a|vm|instr|fstore_w|fstore_w001|fstore_w00101|fstore_w00101|Test1 +javasoft/sqe/tests/vm/fstore_w/fstore_w001/fstore_w00101/fstore_w00101 +JCK-114a|vm|instr|fstore_w|fstore_w005|fstore_w00501|fstore_w00501|Test1 +javasoft/sqe/tests/vm/fstore_w/fstore_w005/fstore_w00501/fstore_w00501 +JCK-114a|vm|instr|freturn|freturn001|freturn00101|freturn00101|Test1 +javasoft/sqe/tests/vm/freturn/freturn001/freturn00101/freturn00101 +JCK-114a|vm|instr|freturn|freturn002|freturn00201|freturn00201|Test1 +javasoft/sqe/tests/vm/freturn/freturn002/freturn00201/freturn00201 +JCK-114a|vm|instr|freturn|freturn003|freturn00301|freturn00301|Test1 +javasoft/sqe/tests/vm/freturn/freturn003/freturn00301/freturn00301 +JCK-114a|vm|instr|freturn|freturn004|freturn00401|freturn00401|Test1 +javasoft/sqe/tests/vm/freturn/freturn004/freturn00401/freturn00401 +JCK-114a|vm|instr|freturn|freturn007|freturn00701|freturn00701|Test1 +javasoft/sqe/tests/vm/freturn/freturn007/freturn00701/freturn00701 +JCK-114a|vm|instr|freturn|freturn007|freturn00702|freturn00702|Test1 +javasoft/sqe/tests/vm/freturn/freturn007/freturn00702/freturn00702 +JCK-114a|vm|instr|fconstF|fconstF001|fconstF00102|fconstF00102|Test1 +javasoft/sqe/tests/vm/fconstF/fconstF001/fconstF00102/fconstF00102 +JCK-114a|vm|instr|fconstF|fconstF001|fconstF00103|fconstF00103|Test1 +javasoft/sqe/tests/vm/fconstF/fconstF001/fconstF00103/fconstF00103 +JCK-114a|vm|instr|fconstF|fconstF001|fconstF00104|fconstF00104|Test1 +javasoft/sqe/tests/vm/fconstF/fconstF001/fconstF00104/fconstF00104 +JCK-114a|vm|instr|f2i|f2i002|f2i00201|f2i00201|Test1 +javasoft/sqe/tests/vm/f2i/f2i002/f2i00201/f2i00201 +JCK-114a|vm|instr|f2i|f2i003|f2i00301|f2i00301|Test1 +javasoft/sqe/tests/vm/f2i/f2i003/f2i00301/f2i00301 +JCK-114a|vm|instr|f2i|f2i004|f2i00401|f2i00401|Test1 +javasoft/sqe/tests/vm/f2i/f2i004/f2i00401/f2i00401 +JCK-114a|vm|instr|f2l|f2l002|f2l00201|f2l00201|Test1 +javasoft/sqe/tests/vm/f2l/f2l002/f2l00201/f2l00201 +JCK-114a|vm|instr|f2l|f2l003|f2l00301|f2l00301|Test1 +javasoft/sqe/tests/vm/f2l/f2l003/f2l00301/f2l00301 +JCK-114a|vm|instr|f2l|f2l004|f2l00401|f2l00401|Test1 +javasoft/sqe/tests/vm/f2l/f2l004/f2l00401/f2l00401 +JCK-114a|vm|instr|goto|goto001|goto00101|goto00101|Test1 +javasoft/sqe/tests/vm/go_to/goto001/goto00101/goto00101 +JCK-114a|vm|instr|goto|goto001|goto00103|goto00103|Test1 +javasoft/sqe/tests/vm/go_to/goto001/goto00103/goto00103 +JCK-114a|vm|instr|goto|goto001|goto00104|goto00104|Test1 +javasoft/sqe/tests/vm/go_to/goto001/goto00104/goto00104 +JCK-114a|vm|instr|goto_w|goto_w001|goto_w00101|goto_w00101|Test1 +javasoft/sqe/tests/vm/goto_w/goto_w001/goto_w00101/goto_w00101 +JCK-114a|vm|instr|goto_w|goto_w001|goto_w00103|goto_w00103|Test1 +javasoft/sqe/tests/vm/goto_w/goto_w001/goto_w00103/goto_w00103 +JCK-114a|vm|instr|goto_w|goto_w001|goto_w00104|goto_w00104|Test1 +javasoft/sqe/tests/vm/goto_w/goto_w001/goto_w00104/goto_w00104 +JCK-114a|vm|instr|goto_w|goto_w003|goto_w00301|goto_w00301|Test1 +javasoft/sqe/tests/vm/goto_w/goto_w003/goto_w00301/goto_w00301 +JCK-114a|vm|instr|getfield|getfield001|getfield00101|getfield00101|Test1 +javasoft/sqe/tests/vm/getfield/getfield001/getfield00101/getfield00101 +JCK-114a|vm|instr|getfield|getfield002|getfield00201|getfield00201|Test1 +javasoft/sqe/tests/vm/getfield/getfield002/getfield00201/getfield00201 +JCK-114a|vm|instr|getfield|getfield002|getfield00203|getfield00203|Test1 +javasoft/sqe/tests/vm/getfield/getfield002/getfield00203/getfield00203 +JCK-114a|vm|instr|getfield|getfield003|getfield00301|getfield00301|Test1 +javasoft/sqe/tests/vm/getfield/getfield003/getfield00301/getfield00301 +JCK-114a|vm|instr|getfield|getfield003|getfield00302|getfield00302|Test1 +javasoft/sqe/tests/vm/getfield/getfield003/getfield00302/getfield00302 +JCK-114a|vm|instr|getfield|getfield004|getfield00401|getfield00401|Test1 +javasoft/sqe/tests/vm/getfield/getfield004/getfield00401/getfield00401 +JCK-114a|vm|instr|getfield|getfield005|getfield00501|getfield00501|Test1 +javasoft/sqe/tests/vm/getfield/getfield005/getfield00501/getfield00501 +JCK-114a|vm|instr|getfield|getfield006|getfield00601|getfield00601|Test1 +javasoft/sqe/tests/vm/getfield/getfield006/getfield00601/getfield00601 +JCK-114a|vm|instr|getfield|getfield006|getfield00602|getfield00602|Test1 +javasoft/sqe/tests/vm/getfield/getfield006/getfield00602/getfield00602 +JCK-114a|vm|instr|getfield|getfield007|getfield00701|getfield00701|Test1 +javasoft/sqe/tests/vm/getfield/getfield007/getfield00701/getfield00701 +JCK-114a|vm|instr|getfield|getfield008|getfield00801|getfield00801|Test1 +javasoft/sqe/tests/vm/getfield/getfield008/getfield00801/getfield00801 +JCK-114a|vm|instr|getfield|getfield009|getfield00901|getfield00901|Test1 +javasoft/sqe/tests/vm/getfield/getfield009/getfield00901/getfield00901 +JCK-114a|vm|instr|getfield|getfield010|getfield01001|getfield01001|Test1 +javasoft/sqe/tests/vm/getfield/getfield010/getfield01001/getfield01001 +JCK-114a|vm|instr|getfield|getfield010|getfield01002|getfield01002|Test1 +javasoft/sqe/tests/vm/getfield/getfield010/getfield01002/getfield01002 +JCK-114a|vm|instr|getfield|getfield011|getfield01101|getfield01101|Test1 +javasoft/sqe/tests/vm/getfield/getfield011/getfield01101/getfield01101 +JCK-114a|vm|instr|getfield|getfield011|getfield01102|getfield01102|Test1 +javasoft/sqe/tests/vm/getfield/getfield011/getfield01102/getfield01102 +JCK-114a|vm|instr|getfield|getfield011|getfield01103|getfield01103|Test1 +javasoft/sqe/tests/vm/getfield/getfield011/getfield01103/getfield01103 +JCK-114a|vm|instr|getfield|getfield012|getfield01202|getfield01202|Test1 +javasoft/sqe/tests/vm/getfield/getfield012/getfield01202/getfield01202 +JCK-114a|vm|instr|getfield|getfield013|getfield01301|getfield01301|Test1 +javasoft/sqe/tests/vm/getfield/getfield013/getfield01301/getfield01301 +JCK-114a|vm|instr|getfield|getfield017|getfield01701|getfield01701|Test1 +javasoft/sqe/tests/vm/getfield/getfield017/getfield01701/getfield01701 +JCK-114a|vm|instr|getstatic|getstatic001|getstatic00101|getstatic00101|Test1 +javasoft/sqe/tests/vm/getstatic/getstatic001/getstatic00101/getstatic00101 +JCK-114a|vm|instr|getstatic|getstatic002|getstatic00201|getstatic00201|Test1 +javasoft/sqe/tests/vm/getstatic/getstatic002/getstatic00201/getstatic00201 +JCK-114a|vm|instr|getstatic|getstatic003|getstatic00301|getstatic00301|Test1 +javasoft/sqe/tests/vm/getstatic/getstatic003/getstatic00301/getstatic00301 +JCK-114a|vm|instr|getstatic|getstatic004|getstatic00401|getstatic00401|Test1 +javasoft/sqe/tests/vm/getstatic/getstatic004/getstatic00401/getstatic00401 +JCK-114a|vm|instr|getstatic|getstatic004|getstatic00402|getstatic00402|Test1 +javasoft/sqe/tests/vm/getstatic/getstatic004/getstatic00402/getstatic00402 +JCK-114a|vm|instr|getstatic|getstatic005|getstatic00501|getstatic00501|Test1 +javasoft/sqe/tests/vm/getstatic/getstatic005/getstatic00501/getstatic00501 +JCK-114a|vm|instr|getstatic|getstatic006|getstatic00601|getstatic00601|Test1 +javasoft/sqe/tests/vm/getstatic/getstatic006/getstatic00601/getstatic00601 +JCK-114a|vm|instr|getstatic|getstatic007|getstatic00701|getstatic00701|Test1 +javasoft/sqe/tests/vm/getstatic/getstatic007/getstatic00701/getstatic00701 +JCK-114a|vm|instr|getstatic|getstatic007|getstatic00702|getstatic00702|Test1 +javasoft/sqe/tests/vm/getstatic/getstatic007/getstatic00702/getstatic00702 +JCK-114a|vm|instr|getstatic|getstatic008|getstatic00801|getstatic00801|Test1 +javasoft/sqe/tests/vm/getstatic/getstatic008/getstatic00801/getstatic00801 +JCK-114a|vm|instr|getstatic|getstatic008|getstatic00802|getstatic00802|Test1 +javasoft/sqe/tests/vm/getstatic/getstatic008/getstatic00802/getstatic00802 +JCK-114a|vm|instr|getstatic|getstatic008|getstatic00803|getstatic00803|Test1 +javasoft/sqe/tests/vm/getstatic/getstatic008/getstatic00803/getstatic00803 +JCK-114a|vm|instr|getstatic|getstatic009|getstatic00901|getstatic00901|Test1 +javasoft/sqe/tests/vm/getstatic/getstatic009/getstatic00901/getstatic00901 +JCK-114a|vm|instr|iaload|iaload002|iaload00201|iaload00201|Test1 +javasoft/sqe/tests/vm/iaload/iaload002/iaload00201/iaload00201 +JCK-114a|vm|instr|iaload|iaload006|iaload00601|iaload00601|Test1 +javasoft/sqe/tests/vm/iaload/iaload006/iaload00601/iaload00601 +JCK-114a|vm|instr|iaload|iaload007|iaload00701|iaload00701|Test1 +javasoft/sqe/tests/vm/iaload/iaload007/iaload00701/iaload00701 +JCK-114a|vm|instr|iadd|iadd001|iadd00101|iadd00101|Test1 +javasoft/sqe/tests/vm/iadd/iadd001/iadd00101/iadd00101 +JCK-114a|vm|instr|iadd|iadd002|iadd00201|iadd00201|Test1 +javasoft/sqe/tests/vm/iadd/iadd002/iadd00201/iadd00201 +JCK-114a|vm|instr|iastore|iastore001|iastore00101|iastore00101|Test1 +javasoft/sqe/tests/vm/iastore/iastore001/iastore00101/iastore00101 +JCK-114a|vm|instr|iastore|iastore003|iastore00301|iastore00301|Test1 +javasoft/sqe/tests/vm/iastore/iastore003/iastore00301/iastore00301 +JCK-114a|vm|instr|iastore|iastore008|iastore00801|iastore00801|Test1 +javasoft/sqe/tests/vm/iastore/iastore008/iastore00801/iastore00801 +JCK-114a|vm|instr|idiv|idiv001|idiv00101|idiv00101|Test1 +javasoft/sqe/tests/vm/idiv/idiv001/idiv00101/idiv00101 +JCK-114a|vm|instr|idiv|idiv002|idiv00201|idiv00201|Test1 +javasoft/sqe/tests/vm/idiv/idiv002/idiv00201/idiv00201 +JCK-114a|vm|instr|idiv|idiv003|idiv00301|idiv00301|Test1 +javasoft/sqe/tests/vm/idiv/idiv003/idiv00301/idiv00301 +JCK-114a|vm|instr|idiv|idiv006|idiv00601|idiv00601|Test1 +javasoft/sqe/tests/vm/idiv/idiv006/idiv00601/idiv00601 +JCK-114a|vm|instr|imul|imul001|imul00101|imul00101|Test1 +javasoft/sqe/tests/vm/imul/imul001/imul00101/imul00101 +JCK-114a|vm|instr|imul|imul002|imul00201|imul00201|Test1 +javasoft/sqe/tests/vm/imul/imul002/imul00201/imul00201 +JCK-114a|vm|instr|ineg|ineg001|ineg00101|ineg00101|Test1 +javasoft/sqe/tests/vm/ineg/ineg001/ineg00101/ineg00101 +JCK-114a|vm|instr|ineg|ineg002|ineg00201|ineg00201|Test1 +javasoft/sqe/tests/vm/ineg/ineg002/ineg00201/ineg00201 +JCK-114a|vm|instr|ineg|ineg003|ineg00301|ineg00301|Test1 +javasoft/sqe/tests/vm/ineg/ineg003/ineg00301/ineg00301 +JCK-114a|vm|instr|ineg|ineg004|ineg00401|ineg00401|Test1 +javasoft/sqe/tests/vm/ineg/ineg004/ineg00401/ineg00401 +JCK-114a|vm|instr|irem|irem001|irem00101|irem00101|Test1 +javasoft/sqe/tests/vm/irem/irem001/irem00101/irem00101 +JCK-114a|vm|instr|irem|irem002|irem00201|irem00201|Test1 +javasoft/sqe/tests/vm/irem/irem002/irem00201/irem00201 +JCK-114a|vm|instr|irem|irem005|irem00501|irem00501|Test1 +javasoft/sqe/tests/vm/irem/irem005/irem00501/irem00501 +JCK-114a|vm|instr|irem|irem006|irem00601|irem00601|Test1 +javasoft/sqe/tests/vm/irem/irem006/irem00601/irem00601 +JCK-114a|vm|instr|irem|irem007|irem00701|irem00701|Test1 +javasoft/sqe/tests/vm/irem/irem007/irem00701/irem00701 +JCK-114a|vm|instr|isub|isub001|isub00101|isub00101|Test1 +javasoft/sqe/tests/vm/isub/isub001/isub00101/isub00101 +JCK-114a|vm|instr|isub|isub002|isub00201|isub00201|Test1 +javasoft/sqe/tests/vm/isub/isub002/isub00201/isub00201 +JCK-114a|vm|instr|isub|isub003|isub00301|isub00301|Test1 +javasoft/sqe/tests/vm/isub/isub003/isub00301/isub00301 +JCK-114a|vm|instr|isub|isub004|isub00401|isub00401|Test1 +javasoft/sqe/tests/vm/isub/isub004/isub00401/isub00401 +JCK-114a|vm|instr|if_acmpcond|if_acmpcond001|if_acmpcond00101|if_acmpcond00101|Test1 +javasoft/sqe/tests/vm/if_acmpcond/if_acmpcond001/if_acmpcond00101/if_acmpcond00101 +JCK-114a|vm|instr|if_acmpcond|if_acmpcond002|if_acmpcond00201|if_acmpcond00201|Test1 +javasoft/sqe/tests/vm/if_acmpcond/if_acmpcond002/if_acmpcond00201/if_acmpcond00201 +JCK-114a|vm|instr|if_acmpcond|if_acmpcond004|if_acmpcond00401|if_acmpcond00401|Test1 +javasoft/sqe/tests/vm/if_acmpcond/if_acmpcond004/if_acmpcond00401/if_acmpcond00401 +JCK-114a|vm|instr|if_acmpcond|if_acmpcond004|if_acmpcond00402|if_acmpcond00402|Test1 +javasoft/sqe/tests/vm/if_acmpcond/if_acmpcond004/if_acmpcond00402/if_acmpcond00402 +JCK-114a|vm|instr|if_acmpcond|if_acmpcond004|if_acmpcond00403|if_acmpcond00403|Test1 +javasoft/sqe/tests/vm/if_acmpcond/if_acmpcond004/if_acmpcond00403/if_acmpcond00403 +JCK-114a|vm|instr|if_acmpcond|if_acmpcond004|if_acmpcond00404|if_acmpcond00404|Test1 +javasoft/sqe/tests/vm/if_acmpcond/if_acmpcond004/if_acmpcond00404/if_acmpcond00404 +JCK-114a|vm|instr|if_acmpcond|if_acmpcond005|if_acmpcond00501|if_acmpcond00501|Test1 +javasoft/sqe/tests/vm/if_acmpcond/if_acmpcond005/if_acmpcond00501/if_acmpcond00501 +JCK-114a|vm|instr|if_acmpcond|if_acmpcond005|if_acmpcond00502|if_acmpcond00502|Test1 +javasoft/sqe/tests/vm/if_acmpcond/if_acmpcond005/if_acmpcond00502/if_acmpcond00502 +JCK-114a|vm|instr|if_acmpcond|if_acmpcond006|if_acmpcond00601|if_acmpcond00601|Test1 +javasoft/sqe/tests/vm/if_acmpcond/if_acmpcond006/if_acmpcond00601/if_acmpcond00601 +JCK-114a|vm|instr|if_acmpcond|if_acmpcond006|if_acmpcond00602|if_acmpcond00602|Test1 +javasoft/sqe/tests/vm/if_acmpcond/if_acmpcond006/if_acmpcond00602/if_acmpcond00602 +JCK-114a|vm|instr|if_acmpcond|if_acmpcond008|if_acmpcond00801|if_acmpcond00801|Test1 +javasoft/sqe/tests/vm/if_acmpcond/if_acmpcond008/if_acmpcond00801/if_acmpcond00801 +JCK-114a|vm|instr|if_acmpcond|if_acmpcond008|if_acmpcond00802|if_acmpcond00802|Test1 +javasoft/sqe/tests/vm/if_acmpcond/if_acmpcond008/if_acmpcond00802/if_acmpcond00802 +JCK-114a|vm|instr|if_acmpcond|if_acmpcond008|if_acmpcond00803|if_acmpcond00803|Test1 +javasoft/sqe/tests/vm/if_acmpcond/if_acmpcond008/if_acmpcond00803/if_acmpcond00803 +JCK-114a|vm|instr|if_acmpcond|if_acmpcond008|if_acmpcond00804|if_acmpcond00804|Test1 +javasoft/sqe/tests/vm/if_acmpcond/if_acmpcond008/if_acmpcond00804/if_acmpcond00804 +JCK-114a|vm|instr|if_acmpcond|if_acmpcond010|if_acmpcond01001|if_acmpcond01001|Test1 +javasoft/sqe/tests/vm/if_acmpcond/if_acmpcond010/if_acmpcond01001/if_acmpcond01001 +JCK-114a|vm|instr|if_acmpcond|if_acmpcond010|if_acmpcond01002|if_acmpcond01002|Test1 +javasoft/sqe/tests/vm/if_acmpcond/if_acmpcond010/if_acmpcond01002/if_acmpcond01002 +JCK-114a|vm|instr|if_icmpcond|if_icmpcond001|if_icmpcond00101|if_icmpcond00101|Test1 +javasoft/sqe/tests/vm/if_icmpcond/if_icmpcond001/if_icmpcond00101/if_icmpcond00101 +JCK-114a|vm|instr|if_icmpcond|if_icmpcond002|if_icmpcond00201|if_icmpcond00201|Test1 +javasoft/sqe/tests/vm/if_icmpcond/if_icmpcond002/if_icmpcond00201/if_icmpcond00201 +JCK-114a|vm|instr|if_icmpcond|if_icmpcond003|if_icmpcond00301|if_icmpcond00301|Test1 +javasoft/sqe/tests/vm/if_icmpcond/if_icmpcond003/if_icmpcond00301/if_icmpcond00301 +JCK-114a|vm|instr|if_icmpcond|if_icmpcond004|if_icmpcond00401|if_icmpcond00401|Test1 +javasoft/sqe/tests/vm/if_icmpcond/if_icmpcond004/if_icmpcond00401/if_icmpcond00401 +JCK-114a|vm|instr|if_icmpcond|if_icmpcond005|if_icmpcond00501|if_icmpcond00501|Test1 +javasoft/sqe/tests/vm/if_icmpcond/if_icmpcond005/if_icmpcond00501/if_icmpcond00501 +JCK-114a|vm|instr|if_icmpcond|if_icmpcond006|if_icmpcond00601|if_icmpcond00601|Test1 +javasoft/sqe/tests/vm/if_icmpcond/if_icmpcond006/if_icmpcond00601/if_icmpcond00601 +JCK-114a|vm|instr|if_icmpcond|if_icmpcond007|if_icmpcond00701|if_icmpcond00701|Test1 +javasoft/sqe/tests/vm/if_icmpcond/if_icmpcond007/if_icmpcond00701/if_icmpcond00701 +JCK-114a|vm|instr|if_icmpcond|if_icmpcond007|if_icmpcond00705|if_icmpcond00705|Test1 +javasoft/sqe/tests/vm/if_icmpcond/if_icmpcond007/if_icmpcond00705/if_icmpcond00705 +JCK-114a|vm|instr|if_icmpcond|if_icmpcond007|if_icmpcond00709|if_icmpcond00709|Test1 +javasoft/sqe/tests/vm/if_icmpcond/if_icmpcond007/if_icmpcond00709/if_icmpcond00709 +JCK-114a|vm|instr|if_icmpcond|if_icmpcond007|if_icmpcond00713|if_icmpcond00713|Test1 +javasoft/sqe/tests/vm/if_icmpcond/if_icmpcond007/if_icmpcond00713/if_icmpcond00713 +JCK-114a|vm|instr|if_icmpcond|if_icmpcond007|if_icmpcond00717|if_icmpcond00717|Test1 +javasoft/sqe/tests/vm/if_icmpcond/if_icmpcond007/if_icmpcond00717/if_icmpcond00717 +JCK-114a|vm|instr|if_icmpcond|if_icmpcond007|if_icmpcond00721|if_icmpcond00721|Test1 +javasoft/sqe/tests/vm/if_icmpcond/if_icmpcond007/if_icmpcond00721/if_icmpcond00721 +JCK-114a|vm|instr|if_icmpcond|if_icmpcond008|if_icmpcond00801|if_icmpcond00801|Test1 +javasoft/sqe/tests/vm/if_icmpcond/if_icmpcond008/if_icmpcond00801/if_icmpcond00801 +JCK-114a|vm|instr|if_icmpcond|if_icmpcond008|if_icmpcond00802|if_icmpcond00802|Test1 +javasoft/sqe/tests/vm/if_icmpcond/if_icmpcond008/if_icmpcond00802/if_icmpcond00802 +JCK-114a|vm|instr|if_icmpcond|if_icmpcond008|if_icmpcond00803|if_icmpcond00803|Test1 +javasoft/sqe/tests/vm/if_icmpcond/if_icmpcond008/if_icmpcond00803/if_icmpcond00803 +JCK-114a|vm|instr|if_icmpcond|if_icmpcond008|if_icmpcond00804|if_icmpcond00804|Test1 +javasoft/sqe/tests/vm/if_icmpcond/if_icmpcond008/if_icmpcond00804/if_icmpcond00804 +JCK-114a|vm|instr|if_icmpcond|if_icmpcond008|if_icmpcond00805|if_icmpcond00805|Test1 +javasoft/sqe/tests/vm/if_icmpcond/if_icmpcond008/if_icmpcond00805/if_icmpcond00805 +JCK-114a|vm|instr|if_icmpcond|if_icmpcond008|if_icmpcond00806|if_icmpcond00806|Test1 +javasoft/sqe/tests/vm/if_icmpcond/if_icmpcond008/if_icmpcond00806/if_icmpcond00806 +JCK-114a|vm|instr|if_icmpcond|if_icmpcond008|if_icmpcond00807|if_icmpcond00807|Test1 +javasoft/sqe/tests/vm/if_icmpcond/if_icmpcond008/if_icmpcond00807/if_icmpcond00807 +JCK-114a|vm|instr|if_icmpcond|if_icmpcond008|if_icmpcond00808|if_icmpcond00808|Test1 +javasoft/sqe/tests/vm/if_icmpcond/if_icmpcond008/if_icmpcond00808/if_icmpcond00808 +JCK-114a|vm|instr|if_icmpcond|if_icmpcond008|if_icmpcond00809|if_icmpcond00809|Test1 +javasoft/sqe/tests/vm/if_icmpcond/if_icmpcond008/if_icmpcond00809/if_icmpcond00809 +JCK-114a|vm|instr|if_icmpcond|if_icmpcond008|if_icmpcond00810|if_icmpcond00810|Test1 +javasoft/sqe/tests/vm/if_icmpcond/if_icmpcond008/if_icmpcond00810/if_icmpcond00810 +JCK-114a|vm|instr|if_icmpcond|if_icmpcond008|if_icmpcond00811|if_icmpcond00811|Test1 +javasoft/sqe/tests/vm/if_icmpcond/if_icmpcond008/if_icmpcond00811/if_icmpcond00811 +JCK-114a|vm|instr|if_icmpcond|if_icmpcond008|if_icmpcond00812|if_icmpcond00812|Test1 +javasoft/sqe/tests/vm/if_icmpcond/if_icmpcond008/if_icmpcond00812/if_icmpcond00812 +JCK-114a|vm|instr|if_icmpcond|if_icmpcond009|if_icmpcond00901|if_icmpcond00901|Test1 +javasoft/sqe/tests/vm/if_icmpcond/if_icmpcond009/if_icmpcond00901/if_icmpcond00901 +JCK-114a|vm|instr|if_icmpcond|if_icmpcond009|if_icmpcond00902|if_icmpcond00902|Test1 +javasoft/sqe/tests/vm/if_icmpcond/if_icmpcond009/if_icmpcond00902/if_icmpcond00902 +JCK-114a|vm|instr|if_icmpcond|if_icmpcond009|if_icmpcond00903|if_icmpcond00903|Test1 +javasoft/sqe/tests/vm/if_icmpcond/if_icmpcond009/if_icmpcond00903/if_icmpcond00903 +JCK-114a|vm|instr|if_icmpcond|if_icmpcond009|if_icmpcond00904|if_icmpcond00904|Test1 +javasoft/sqe/tests/vm/if_icmpcond/if_icmpcond009/if_icmpcond00904/if_icmpcond00904 +JCK-114a|vm|instr|if_icmpcond|if_icmpcond009|if_icmpcond00905|if_icmpcond00905|Test1 +javasoft/sqe/tests/vm/if_icmpcond/if_icmpcond009/if_icmpcond00905/if_icmpcond00905 +JCK-114a|vm|instr|if_icmpcond|if_icmpcond009|if_icmpcond00906|if_icmpcond00906|Test1 +javasoft/sqe/tests/vm/if_icmpcond/if_icmpcond009/if_icmpcond00906/if_icmpcond00906 +JCK-114a|vm|instr|if_icmpcond|if_icmpcond010|if_icmpcond01001|if_icmpcond01001|Test1 +javasoft/sqe/tests/vm/if_icmpcond/if_icmpcond010/if_icmpcond01001/if_icmpcond01001 +JCK-114a|vm|instr|if_icmpcond|if_icmpcond010|if_icmpcond01002|if_icmpcond01002|Test1 +javasoft/sqe/tests/vm/if_icmpcond/if_icmpcond010/if_icmpcond01002/if_icmpcond01002 +JCK-114a|vm|instr|if_icmpcond|if_icmpcond011|if_icmpcond01101|if_icmpcond01101|Test1 +javasoft/sqe/tests/vm/if_icmpcond/if_icmpcond011/if_icmpcond01101/if_icmpcond01101 +JCK-114a|vm|instr|if_icmpcond|if_icmpcond011|if_icmpcond01102|if_icmpcond01102|Test1 +javasoft/sqe/tests/vm/if_icmpcond/if_icmpcond011/if_icmpcond01102/if_icmpcond01102 +JCK-114a|vm|instr|if_icmpcond|if_icmpcond012|if_icmpcond01201|if_icmpcond01201|Test1 +javasoft/sqe/tests/vm/if_icmpcond/if_icmpcond012/if_icmpcond01201/if_icmpcond01201 +JCK-114a|vm|instr|if_icmpcond|if_icmpcond012|if_icmpcond01202|if_icmpcond01202|Test1 +javasoft/sqe/tests/vm/if_icmpcond/if_icmpcond012/if_icmpcond01202/if_icmpcond01202 +JCK-114a|vm|instr|if_icmpcond|if_icmpcond013|if_icmpcond01301|if_icmpcond01301|Test1 +javasoft/sqe/tests/vm/if_icmpcond/if_icmpcond013/if_icmpcond01301/if_icmpcond01301 +JCK-114a|vm|instr|if_icmpcond|if_icmpcond013|if_icmpcond01302|if_icmpcond01302|Test1 +javasoft/sqe/tests/vm/if_icmpcond/if_icmpcond013/if_icmpcond01302/if_icmpcond01302 +JCK-114a|vm|instr|if_icmpcond|if_icmpcond014|if_icmpcond01401|if_icmpcond01401|Test1 +javasoft/sqe/tests/vm/if_icmpcond/if_icmpcond014/if_icmpcond01401/if_icmpcond01401 +JCK-114a|vm|instr|if_icmpcond|if_icmpcond014|if_icmpcond01402|if_icmpcond01402|Test1 +javasoft/sqe/tests/vm/if_icmpcond/if_icmpcond014/if_icmpcond01402/if_icmpcond01402 +JCK-114a|vm|instr|if_icmpcond|if_icmpcond015|if_icmpcond01501|if_icmpcond01501|Test1 +javasoft/sqe/tests/vm/if_icmpcond/if_icmpcond015/if_icmpcond01501/if_icmpcond01501 +JCK-114a|vm|instr|if_icmpcond|if_icmpcond015|if_icmpcond01502|if_icmpcond01502|Test1 +javasoft/sqe/tests/vm/if_icmpcond/if_icmpcond015/if_icmpcond01502/if_icmpcond01502 +JCK-114a|vm|instr|if_icmpcond|if_icmpcond016|if_icmpcond01601|if_icmpcond01601|Test1 +javasoft/sqe/tests/vm/if_icmpcond/if_icmpcond016/if_icmpcond01601/if_icmpcond01601 +JCK-114a|vm|instr|if_icmpcond|if_icmpcond016|if_icmpcond01602|if_icmpcond01602|Test1 +javasoft/sqe/tests/vm/if_icmpcond/if_icmpcond016/if_icmpcond01602/if_icmpcond01602 +JCK-114a|vm|instr|if_icmpcond|if_icmpcond016|if_icmpcond01603|if_icmpcond01603|Test1 +javasoft/sqe/tests/vm/if_icmpcond/if_icmpcond016/if_icmpcond01603/if_icmpcond01603 +JCK-114a|vm|instr|if_icmpcond|if_icmpcond016|if_icmpcond01604|if_icmpcond01604|Test1 +javasoft/sqe/tests/vm/if_icmpcond/if_icmpcond016/if_icmpcond01604/if_icmpcond01604 +JCK-114a|vm|instr|if_icmpcond|if_icmpcond016|if_icmpcond01605|if_icmpcond01605|Test1 +javasoft/sqe/tests/vm/if_icmpcond/if_icmpcond016/if_icmpcond01605/if_icmpcond01605 +JCK-114a|vm|instr|if_icmpcond|if_icmpcond016|if_icmpcond01606|if_icmpcond01606|Test1 +javasoft/sqe/tests/vm/if_icmpcond/if_icmpcond016/if_icmpcond01606/if_icmpcond01606 +JCK-114a|vm|instr|if_icmpcond|if_icmpcond016|if_icmpcond01607|if_icmpcond01607|Test1 +javasoft/sqe/tests/vm/if_icmpcond/if_icmpcond016/if_icmpcond01607/if_icmpcond01607 +JCK-114a|vm|instr|if_icmpcond|if_icmpcond016|if_icmpcond01608|if_icmpcond01608|Test1 +javasoft/sqe/tests/vm/if_icmpcond/if_icmpcond016/if_icmpcond01608/if_icmpcond01608 +JCK-114a|vm|instr|if_icmpcond|if_icmpcond016|if_icmpcond01609|if_icmpcond01609|Test1 +javasoft/sqe/tests/vm/if_icmpcond/if_icmpcond016/if_icmpcond01609/if_icmpcond01609 +JCK-114a|vm|instr|if_icmpcond|if_icmpcond016|if_icmpcond01610|if_icmpcond01610|Test1 +javasoft/sqe/tests/vm/if_icmpcond/if_icmpcond016/if_icmpcond01610/if_icmpcond01610 +JCK-114a|vm|instr|if_icmpcond|if_icmpcond016|if_icmpcond01611|if_icmpcond01611|Test1 +javasoft/sqe/tests/vm/if_icmpcond/if_icmpcond016/if_icmpcond01611/if_icmpcond01611 +JCK-114a|vm|instr|if_icmpcond|if_icmpcond016|if_icmpcond01612|if_icmpcond01612|Test1 +javasoft/sqe/tests/vm/if_icmpcond/if_icmpcond016/if_icmpcond01612/if_icmpcond01612 +JCK-114a|vm|instr|if_icmpcond|if_icmpcond018|if_icmpcond01801|if_icmpcond01801|Test1 +javasoft/sqe/tests/vm/if_icmpcond/if_icmpcond018/if_icmpcond01801/if_icmpcond01801 +JCK-114a|vm|instr|if_icmpcond|if_icmpcond018|if_icmpcond01802|if_icmpcond01802|Test1 +javasoft/sqe/tests/vm/if_icmpcond/if_icmpcond018/if_icmpcond01802/if_icmpcond01802 +JCK-114a|vm|instr|if_icmpcond|if_icmpcond018|if_icmpcond01803|if_icmpcond01803|Test1 +javasoft/sqe/tests/vm/if_icmpcond/if_icmpcond018/if_icmpcond01803/if_icmpcond01803 +JCK-114a|vm|instr|if_icmpcond|if_icmpcond018|if_icmpcond01804|if_icmpcond01804|Test1 +javasoft/sqe/tests/vm/if_icmpcond/if_icmpcond018/if_icmpcond01804/if_icmpcond01804 +JCK-114a|vm|instr|if_icmpcond|if_icmpcond018|if_icmpcond01805|if_icmpcond01805|Test1 +javasoft/sqe/tests/vm/if_icmpcond/if_icmpcond018/if_icmpcond01805/if_icmpcond01805 +JCK-114a|vm|instr|if_icmpcond|if_icmpcond018|if_icmpcond01806|if_icmpcond01806|Test1 +javasoft/sqe/tests/vm/if_icmpcond/if_icmpcond018/if_icmpcond01806/if_icmpcond01806 +JCK-114a|vm|instr|ifcond|ifcond001|ifcond00101|ifcond00101|Test1 +javasoft/sqe/tests/vm/ifcond/ifcond001/ifcond00101/ifcond00101 +JCK-114a|vm|instr|ifcond|ifcond002|ifcond00201|ifcond00201|Test1 +javasoft/sqe/tests/vm/ifcond/ifcond002/ifcond00201/ifcond00201 +JCK-114a|vm|instr|ifcond|ifcond003|ifcond00301|ifcond00301|Test1 +javasoft/sqe/tests/vm/ifcond/ifcond003/ifcond00301/ifcond00301 +JCK-114a|vm|instr|ifcond|ifcond004|ifcond00401|ifcond00401|Test1 +javasoft/sqe/tests/vm/ifcond/ifcond004/ifcond00401/ifcond00401 +JCK-114a|vm|instr|ifcond|ifcond005|ifcond00501|ifcond00501|Test1 +javasoft/sqe/tests/vm/ifcond/ifcond005/ifcond00501/ifcond00501 +JCK-114a|vm|instr|ifcond|ifcond006|ifcond00601|ifcond00601|Test1 +javasoft/sqe/tests/vm/ifcond/ifcond006/ifcond00601/ifcond00601 +JCK-114a|vm|instr|ifcond|ifcond007|ifcond00701|ifcond00701|Test1 +javasoft/sqe/tests/vm/ifcond/ifcond007/ifcond00701/ifcond00701 +JCK-114a|vm|instr|ifcond|ifcond007|ifcond00703|ifcond00703|Test1 +javasoft/sqe/tests/vm/ifcond/ifcond007/ifcond00703/ifcond00703 +JCK-114a|vm|instr|ifcond|ifcond007|ifcond00705|ifcond00705|Test1 +javasoft/sqe/tests/vm/ifcond/ifcond007/ifcond00705/ifcond00705 +JCK-114a|vm|instr|ifcond|ifcond007|ifcond00707|ifcond00707|Test1 +javasoft/sqe/tests/vm/ifcond/ifcond007/ifcond00707/ifcond00707 +JCK-114a|vm|instr|ifcond|ifcond007|ifcond00709|ifcond00709|Test1 +javasoft/sqe/tests/vm/ifcond/ifcond007/ifcond00709/ifcond00709 +JCK-114a|vm|instr|ifcond|ifcond007|ifcond00711|ifcond00711|Test1 +javasoft/sqe/tests/vm/ifcond/ifcond007/ifcond00711/ifcond00711 +JCK-114a|vm|instr|ifcond|ifcond008|ifcond00801|ifcond00801|Test1 +javasoft/sqe/tests/vm/ifcond/ifcond008/ifcond00801/ifcond00801 +JCK-114a|vm|instr|ifcond|ifcond008|ifcond00802|ifcond00802|Test1 +javasoft/sqe/tests/vm/ifcond/ifcond008/ifcond00802/ifcond00802 +JCK-114a|vm|instr|ifcond|ifcond008|ifcond00803|ifcond00803|Test1 +javasoft/sqe/tests/vm/ifcond/ifcond008/ifcond00803/ifcond00803 +JCK-114a|vm|instr|ifcond|ifcond008|ifcond00804|ifcond00804|Test1 +javasoft/sqe/tests/vm/ifcond/ifcond008/ifcond00804/ifcond00804 +JCK-114a|vm|instr|ifcond|ifcond008|ifcond00805|ifcond00805|Test1 +javasoft/sqe/tests/vm/ifcond/ifcond008/ifcond00805/ifcond00805 +JCK-114a|vm|instr|ifcond|ifcond008|ifcond00806|ifcond00806|Test1 +javasoft/sqe/tests/vm/ifcond/ifcond008/ifcond00806/ifcond00806 +JCK-114a|vm|instr|ifcond|ifcond008|ifcond00807|ifcond00807|Test1 +javasoft/sqe/tests/vm/ifcond/ifcond008/ifcond00807/ifcond00807 +JCK-114a|vm|instr|ifcond|ifcond008|ifcond00808|ifcond00808|Test1 +javasoft/sqe/tests/vm/ifcond/ifcond008/ifcond00808/ifcond00808 +JCK-114a|vm|instr|ifcond|ifcond008|ifcond00809|ifcond00809|Test1 +javasoft/sqe/tests/vm/ifcond/ifcond008/ifcond00809/ifcond00809 +JCK-114a|vm|instr|ifcond|ifcond008|ifcond00810|ifcond00810|Test1 +javasoft/sqe/tests/vm/ifcond/ifcond008/ifcond00810/ifcond00810 +JCK-114a|vm|instr|ifcond|ifcond008|ifcond00811|ifcond00811|Test1 +javasoft/sqe/tests/vm/ifcond/ifcond008/ifcond00811/ifcond00811 +JCK-114a|vm|instr|ifcond|ifcond008|ifcond00812|ifcond00812|Test1 +javasoft/sqe/tests/vm/ifcond/ifcond008/ifcond00812/ifcond00812 +JCK-114a|vm|instr|ifcond|ifcond009|ifcond00901|ifcond00901|Test1 +javasoft/sqe/tests/vm/ifcond/ifcond009/ifcond00901/ifcond00901 +JCK-114a|vm|instr|ifcond|ifcond009|ifcond00902|ifcond00902|Test1 +javasoft/sqe/tests/vm/ifcond/ifcond009/ifcond00902/ifcond00902 +JCK-114a|vm|instr|ifcond|ifcond009|ifcond00903|ifcond00903|Test1 +javasoft/sqe/tests/vm/ifcond/ifcond009/ifcond00903/ifcond00903 +JCK-114a|vm|instr|ifcond|ifcond009|ifcond00904|ifcond00904|Test1 +javasoft/sqe/tests/vm/ifcond/ifcond009/ifcond00904/ifcond00904 +JCK-114a|vm|instr|ifcond|ifcond009|ifcond00905|ifcond00905|Test1 +javasoft/sqe/tests/vm/ifcond/ifcond009/ifcond00905/ifcond00905 +JCK-114a|vm|instr|ifcond|ifcond009|ifcond00906|ifcond00906|Test1 +javasoft/sqe/tests/vm/ifcond/ifcond009/ifcond00906/ifcond00906 +JCK-114a|vm|instr|ifcond|ifcond010|ifcond01001|ifcond01001|Test1 +javasoft/sqe/tests/vm/ifcond/ifcond010/ifcond01001/ifcond01001 +JCK-114a|vm|instr|ifcond|ifcond010|ifcond01002|ifcond01002|Test1 +javasoft/sqe/tests/vm/ifcond/ifcond010/ifcond01002/ifcond01002 +JCK-114a|vm|instr|ifcond|ifcond011|ifcond01101|ifcond01101|Test1 +javasoft/sqe/tests/vm/ifcond/ifcond011/ifcond01101/ifcond01101 +JCK-114a|vm|instr|ifcond|ifcond011|ifcond01102|ifcond01102|Test1 +javasoft/sqe/tests/vm/ifcond/ifcond011/ifcond01102/ifcond01102 +JCK-114a|vm|instr|ifcond|ifcond012|ifcond01201|ifcond01201|Test1 +javasoft/sqe/tests/vm/ifcond/ifcond012/ifcond01201/ifcond01201 +JCK-114a|vm|instr|ifcond|ifcond012|ifcond01202|ifcond01202|Test1 +javasoft/sqe/tests/vm/ifcond/ifcond012/ifcond01202/ifcond01202 +JCK-114a|vm|instr|ifcond|ifcond013|ifcond01301|ifcond01301|Test1 +javasoft/sqe/tests/vm/ifcond/ifcond013/ifcond01301/ifcond01301 +JCK-114a|vm|instr|ifcond|ifcond013|ifcond01302|ifcond01302|Test1 +javasoft/sqe/tests/vm/ifcond/ifcond013/ifcond01302/ifcond01302 +JCK-114a|vm|instr|ifcond|ifcond014|ifcond01401|ifcond01401|Test1 +javasoft/sqe/tests/vm/ifcond/ifcond014/ifcond01401/ifcond01401 +JCK-114a|vm|instr|ifcond|ifcond014|ifcond01402|ifcond01402|Test1 +javasoft/sqe/tests/vm/ifcond/ifcond014/ifcond01402/ifcond01402 +JCK-114a|vm|instr|ifcond|ifcond015|ifcond01501|ifcond01501|Test1 +javasoft/sqe/tests/vm/ifcond/ifcond015/ifcond01501/ifcond01501 +JCK-114a|vm|instr|ifcond|ifcond015|ifcond01502|ifcond01502|Test1 +javasoft/sqe/tests/vm/ifcond/ifcond015/ifcond01502/ifcond01502 +JCK-114a|vm|instr|ifcond|ifcond016|ifcond01601|ifcond01601|Test1 +javasoft/sqe/tests/vm/ifcond/ifcond016/ifcond01601/ifcond01601 +JCK-114a|vm|instr|ifcond|ifcond016|ifcond01602|ifcond01602|Test1 +javasoft/sqe/tests/vm/ifcond/ifcond016/ifcond01602/ifcond01602 +JCK-114a|vm|instr|ifcond|ifcond016|ifcond01603|ifcond01603|Test1 +javasoft/sqe/tests/vm/ifcond/ifcond016/ifcond01603/ifcond01603 +JCK-114a|vm|instr|ifcond|ifcond016|ifcond01604|ifcond01604|Test1 +javasoft/sqe/tests/vm/ifcond/ifcond016/ifcond01604/ifcond01604 +JCK-114a|vm|instr|ifcond|ifcond016|ifcond01605|ifcond01605|Test1 +javasoft/sqe/tests/vm/ifcond/ifcond016/ifcond01605/ifcond01605 +JCK-114a|vm|instr|ifcond|ifcond016|ifcond01606|ifcond01606|Test1 +javasoft/sqe/tests/vm/ifcond/ifcond016/ifcond01606/ifcond01606 +JCK-114a|vm|instr|ifcond|ifcond016|ifcond01607|ifcond01607|Test1 +javasoft/sqe/tests/vm/ifcond/ifcond016/ifcond01607/ifcond01607 +JCK-114a|vm|instr|ifcond|ifcond016|ifcond01608|ifcond01608|Test1 +javasoft/sqe/tests/vm/ifcond/ifcond016/ifcond01608/ifcond01608 +JCK-114a|vm|instr|ifcond|ifcond016|ifcond01609|ifcond01609|Test1 +javasoft/sqe/tests/vm/ifcond/ifcond016/ifcond01609/ifcond01609 +JCK-114a|vm|instr|ifcond|ifcond016|ifcond01610|ifcond01610|Test1 +javasoft/sqe/tests/vm/ifcond/ifcond016/ifcond01610/ifcond01610 +JCK-114a|vm|instr|ifcond|ifcond016|ifcond01611|ifcond01611|Test1 +javasoft/sqe/tests/vm/ifcond/ifcond016/ifcond01611/ifcond01611 +JCK-114a|vm|instr|ifcond|ifcond016|ifcond01612|ifcond01612|Test1 +javasoft/sqe/tests/vm/ifcond/ifcond016/ifcond01612/ifcond01612 +JCK-114a|vm|instr|ifcond|ifcond018|ifcond01801|ifcond01801|Test1 +javasoft/sqe/tests/vm/ifcond/ifcond018/ifcond01801/ifcond01801 +JCK-114a|vm|instr|ifcond|ifcond018|ifcond01802|ifcond01802|Test1 +javasoft/sqe/tests/vm/ifcond/ifcond018/ifcond01802/ifcond01802 +JCK-114a|vm|instr|ifcond|ifcond018|ifcond01803|ifcond01803|Test1 +javasoft/sqe/tests/vm/ifcond/ifcond018/ifcond01803/ifcond01803 +JCK-114a|vm|instr|ifcond|ifcond018|ifcond01804|ifcond01804|Test1 +javasoft/sqe/tests/vm/ifcond/ifcond018/ifcond01804/ifcond01804 +JCK-114a|vm|instr|ifcond|ifcond018|ifcond01805|ifcond01805|Test1 +javasoft/sqe/tests/vm/ifcond/ifcond018/ifcond01805/ifcond01805 +JCK-114a|vm|instr|ifcond|ifcond018|ifcond01806|ifcond01806|Test1 +javasoft/sqe/tests/vm/ifcond/ifcond018/ifcond01806/ifcond01806 +JCK-114a|vm|instr|ifnonnull|ifnonnull001|ifnonnull00102|ifnonnull00102|Test1 +javasoft/sqe/tests/vm/ifnonnull/ifnonnull001/ifnonnull00102/ifnonnull00102 +JCK-114a|vm|instr|ifnonnull|ifnonnull002|ifnonnull00201|ifnonnull00201|Test1 +javasoft/sqe/tests/vm/ifnonnull/ifnonnull002/ifnonnull00201/ifnonnull00201 +JCK-114a|vm|instr|ifnonnull|ifnonnull004|ifnonnull00401|ifnonnull00401|Test1 +javasoft/sqe/tests/vm/ifnonnull/ifnonnull004/ifnonnull00401/ifnonnull00401 +JCK-114a|vm|instr|ifnonnull|ifnonnull004|ifnonnull00402|ifnonnull00402|Test1 +javasoft/sqe/tests/vm/ifnonnull/ifnonnull004/ifnonnull00402/ifnonnull00402 +JCK-114a|vm|instr|ifnonnull|ifnonnull005|ifnonnull00501|ifnonnull00501|Test1 +javasoft/sqe/tests/vm/ifnonnull/ifnonnull005/ifnonnull00501/ifnonnull00501 +JCK-114a|vm|instr|ifnonnull|ifnonnull005|ifnonnull00502|ifnonnull00502|Test1 +javasoft/sqe/tests/vm/ifnonnull/ifnonnull005/ifnonnull00502/ifnonnull00502 +JCK-114a|vm|instr|ifnonnull|ifnonnull007|ifnonnull00701|ifnonnull00701|Test1 +javasoft/sqe/tests/vm/ifnonnull/ifnonnull007/ifnonnull00701/ifnonnull00701 +JCK-114a|vm|instr|ifnull|ifnull001|ifnull00101|ifnull00101|Test1 +javasoft/sqe/tests/vm/ifnull/ifnull001/ifnull00101/ifnull00101 +JCK-114a|vm|instr|ifnull|ifnull002|ifnull00201|ifnull00201|Test1 +javasoft/sqe/tests/vm/ifnull/ifnull002/ifnull00201/ifnull00201 +JCK-114a|vm|instr|ifnull|ifnull003|ifnull00301|ifnull00301|Test1 +javasoft/sqe/tests/vm/ifnull/ifnull003/ifnull00301/ifnull00301 +JCK-114a|vm|instr|ifnull|ifnull003|ifnull00302|ifnull00302|Test1 +javasoft/sqe/tests/vm/ifnull/ifnull003/ifnull00302/ifnull00302 +JCK-114a|vm|instr|ifnull|ifnull004|ifnull00401|ifnull00401|Test1 +javasoft/sqe/tests/vm/ifnull/ifnull004/ifnull00401/ifnull00401 +JCK-114a|vm|instr|ifnull|ifnull004|ifnull00402|ifnull00402|Test1 +javasoft/sqe/tests/vm/ifnull/ifnull004/ifnull00402/ifnull00402 +JCK-114a|vm|instr|ifnull|ifnull006|ifnull00601|ifnull00601|Test1 +javasoft/sqe/tests/vm/ifnull/ifnull006/ifnull00601/ifnull00601 +JCK-114a|vm|instr|iinc|iinc001|iinc00101|iinc00101|Test1 +javasoft/sqe/tests/vm/iinc/iinc001/iinc00101/iinc00101 +JCK-114a|vm|instr|iinc|iinc002|iinc00201|iinc00201|Test1 +javasoft/sqe/tests/vm/iinc/iinc002/iinc00201/iinc00201 +JCK-114a|vm|instr|iinc|iinc003|iinc00302|iinc00302|Test1 +javasoft/sqe/tests/vm/iinc/iinc003/iinc00302/iinc00302 +JCK-114a|vm|instr|iinc|iinc004|iinc00401|iinc00401|Test1 +javasoft/sqe/tests/vm/iinc/iinc004/iinc00401/iinc00401 +JCK-114a|vm|instr|iinc_w|iinc_w001|iinc_w00101|iinc_w00101|Test1 +javasoft/sqe/tests/vm/iinc_w/iinc_w001/iinc_w00101/iinc_w00101 +JCK-114a|vm|instr|iinc_w|iinc_w002|iinc_w00201|iinc_w00201|Test1 +javasoft/sqe/tests/vm/iinc_w/iinc_w002/iinc_w00201/iinc_w00201 +JCK-114a|vm|instr|iinc_w|iinc_w003|iinc_w00302|iinc_w00302|Test1 +javasoft/sqe/tests/vm/iinc_w/iinc_w003/iinc_w00302/iinc_w00302 +JCK-114a|vm|instr|iinc_w|iinc_w004|iinc_w00401|iinc_w00401|Test1 +javasoft/sqe/tests/vm/iinc_w/iinc_w004/iinc_w00401/iinc_w00401 +JCK-114a|vm|instr|iload|iload001|iload00101|iload00101|Test1 +javasoft/sqe/tests/vm/iload/iload001/iload00101/iload00101 +JCK-114a|vm|instr|iload|iload003|iload00301|iload00301|Test1 +javasoft/sqe/tests/vm/iload/iload003/iload00301/iload00301 +JCK-114a|vm|instr|iloadN|iloadN002|iloadN00202|iloadN00202|Test1 +javasoft/sqe/tests/vm/iloadN/iloadN002/iloadN00202/iloadN00202 +JCK-114a|vm|instr|iloadN|iloadN002|iloadN00203|iloadN00203|Test1 +javasoft/sqe/tests/vm/iloadN/iloadN002/iloadN00203/iloadN00203 +JCK-114a|vm|instr|iloadN|iloadN002|iloadN00204|iloadN00204|Test1 +javasoft/sqe/tests/vm/iloadN/iloadN002/iloadN00204/iloadN00204 +JCK-114a|vm|instr|iloadN|iloadN002|iloadN00205|iloadN00205|Test1 +javasoft/sqe/tests/vm/iloadN/iloadN002/iloadN00205/iloadN00205 +JCK-114a|vm|instr|iload_w|iload_w001|iload_w00101|iload_w00101|Test1 +javasoft/sqe/tests/vm/iload_w/iload_w001/iload_w00101/iload_w00101 +JCK-114a|vm|instr|iload_w|iload_w003|iload_w00301|iload_w00301|Test1 +javasoft/sqe/tests/vm/iload_w/iload_w003/iload_w00301/iload_w00301 +JCK-114a|vm|instr|istore|istore001|istore00101|istore00101|Test1 +javasoft/sqe/tests/vm/istore/istore001/istore00101/istore00101 +JCK-114a|vm|instr|istore|istore005|istore00501|istore00501|Test1 +javasoft/sqe/tests/vm/istore/istore005/istore00501/istore00501 +JCK-114a|vm|instr|istoreN|istoreN004|istoreN00401|istoreN00401|Test1 +javasoft/sqe/tests/vm/istoreN/istoreN004/istoreN00401/istoreN00401 +JCK-114a|vm|instr|istoreN|istoreN004|istoreN00402|istoreN00402|Test1 +javasoft/sqe/tests/vm/istoreN/istoreN004/istoreN00402/istoreN00402 +JCK-114a|vm|instr|istoreN|istoreN004|istoreN00403|istoreN00403|Test1 +javasoft/sqe/tests/vm/istoreN/istoreN004/istoreN00403/istoreN00403 +JCK-114a|vm|instr|istoreN|istoreN004|istoreN00404|istoreN00404|Test1 +javasoft/sqe/tests/vm/istoreN/istoreN004/istoreN00404/istoreN00404 +JCK-114a|vm|instr|istore_w|istore_w001|istore_w00101|istore_w00101|Test1 +javasoft/sqe/tests/vm/istore_w/istore_w001/istore_w00101/istore_w00101 +JCK-114a|vm|instr|istore_w|istore_w005|istore_w00501|istore_w00501|Test1 +javasoft/sqe/tests/vm/istore_w/istore_w005/istore_w00501/istore_w00501 +JCK-114a|vm|instr|iand|iand001|iand00101|iand00101|Test1 +javasoft/sqe/tests/vm/iand/iand001/iand00101/iand00101 +JCK-114a|vm|instr|ior|ior001|ior00101|ior00101|Test1 +javasoft/sqe/tests/vm/ior/ior001/ior00101/ior00101 +JCK-114a|vm|instr|ishl|ishl001|ishl00101|ishl00101|Test1 +javasoft/sqe/tests/vm/ishl/ishl001/ishl00101/ishl00101 +JCK-114a|vm|instr|ishl|ishl002|ishl00201|ishl00201|Test1 +javasoft/sqe/tests/vm/ishl/ishl002/ishl00201/ishl00201 +JCK-114a|vm|instr|ishl|ishl003|ishl00301|ishl00301|Test1 +javasoft/sqe/tests/vm/ishl/ishl003/ishl00301/ishl00301 +JCK-114a|vm|instr|ishr|ishr001|ishr00101|ishr00101|Test1 +javasoft/sqe/tests/vm/ishr/ishr001/ishr00101/ishr00101 +JCK-114a|vm|instr|ishr|ishr002|ishr00201|ishr00201|Test1 +javasoft/sqe/tests/vm/ishr/ishr002/ishr00201/ishr00201 +JCK-114a|vm|instr|ishr|ishr003|ishr00301|ishr00301|Test1 +javasoft/sqe/tests/vm/ishr/ishr003/ishr00301/ishr00301 +JCK-114a|vm|instr|iushr|iushr001|iushr00101|iushr00101|Test1 +javasoft/sqe/tests/vm/iushr/iushr001/iushr00101/iushr00101 +JCK-114a|vm|instr|iushr|iushr002|iushr00201|iushr00201|Test1 +javasoft/sqe/tests/vm/iushr/iushr002/iushr00201/iushr00201 +JCK-114a|vm|instr|iushr|iushr003|iushr00301|iushr00301|Test1 +javasoft/sqe/tests/vm/iushr/iushr003/iushr00301/iushr00301 +JCK-114a|vm|instr|iushr|iushr004|iushr00401|iushr00401|Test1 +javasoft/sqe/tests/vm/iushr/iushr004/iushr00401/iushr00401 +JCK-114a|vm|instr|ixor|ixor001|ixor00101|ixor00101|Test1 +javasoft/sqe/tests/vm/ixor/ixor001/ixor00101/ixor00101 +JCK-114a|vm|instr|invokeinterface|invokeinterface001|invokeinterface00101|invokeinterface00101|Test1 +javasoft/sqe/tests/vm/invokeinterface/invokeinterface001/invokeinterface00101/invokeinterface00101 +JCK-114a|vm|instr|invokespecial|invokespecial001|invokespecial00101|invokespecial00101|Test1 +javasoft/sqe/tests/vm/invokespecial/invokespecial001/invokespecial00101/invokespecial00101 +JCK-114a|vm|instr|invokespecial|invokespecial014|invokespecial01401|invokespecial01401|Test1 +javasoft/sqe/tests/vm/invokespecial/invokespecial014/invokespecial01401/invokespecial01401 +JCK-114a|vm|instr|invokespecial|invokespecial015|invokespecial01501|invokespecial01501|Test1 +javasoft/sqe/tests/vm/invokespecial/invokespecial015/invokespecial01501/invokespecial01501 +JCK-114a|vm|instr|invokespecial|invokespecial017|invokespecial01701|invokespecial01701|Test1 +javasoft/sqe/tests/vm/invokespecial/invokespecial017/invokespecial01701/invokespecial01701 +JCK-114a|vm|instr|invokespecial|invokespecial018|invokespecial01801|invokespecial01801|Test1 +javasoft/sqe/tests/vm/invokespecial/invokespecial018/invokespecial01801/invokespecial01801 +JCK-114a|vm|instr|invokespecial|invokespecial021|invokespecial02101|invokespecial02101|Test1 +javasoft/sqe/tests/vm/invokespecial/invokespecial021/invokespecial02101/invokespecial02101 +JCK-114a|vm|instr|invokestatic|invokestatic001|invokestatic00101|invokestatic00101|Test1 +javasoft/sqe/tests/vm/invokestatic/invokestatic001/invokestatic00101/invokestatic00101 +JCK-114a|vm|instr|invokestatic|invokestatic008|invokestatic00801|invokestatic00801|Test1 +javasoft/sqe/tests/vm/invokestatic/invokestatic008/invokestatic00801/invokestatic00801 +JCK-114a|vm|instr|invokestatic|invokestatic009|invokestatic00901|invokestatic00901|Test1 +javasoft/sqe/tests/vm/invokestatic/invokestatic009/invokestatic00901/invokestatic00901 +JCK-114a|vm|instr|invokestatic|invokestatic010|invokestatic01001|invokestatic01001|Test1 +javasoft/sqe/tests/vm/invokestatic/invokestatic010/invokestatic01001/invokestatic01001 +JCK-114a|vm|instr|invokestatic|invokestatic013|invokestatic01301|invokestatic01301|Test1 +javasoft/sqe/tests/vm/invokestatic/invokestatic013/invokestatic01301/invokestatic01301 +JCK-114a|vm|instr|invokestatic|invokestatic014|invokestatic01401|invokestatic01401|Test1 +javasoft/sqe/tests/vm/invokestatic/invokestatic014/invokestatic01401/invokestatic01401 +JCK-114a|vm|instr|invokevirtual|invokevirtual001|invokevirtual00101|invokevirtual00101|Test1 +javasoft/sqe/tests/vm/invokevirtual/invokevirtual001/invokevirtual00101/invokevirtual00101 +JCK-114a|vm|instr|invokevirtual|invokevirtual008|invokevirtual00801|invokevirtual00801|Test1 +javasoft/sqe/tests/vm/invokevirtual/invokevirtual008/invokevirtual00801/invokevirtual00801 +JCK-114a|vm|instr|invokevirtual|invokevirtual014|invokevirtual01401|invokevirtual01401|Test1 +javasoft/sqe/tests/vm/invokevirtual/invokevirtual014/invokevirtual01401/invokevirtual01401 +JCK-114a|vm|instr|invokevirtual|invokevirtual015|invokevirtual01501|invokevirtual01501|Test1 +javasoft/sqe/tests/vm/invokevirtual/invokevirtual015/invokevirtual01501/invokevirtual01501 +JCK-114a|vm|instr|invokevirtual|invokevirtual016|invokevirtual01601|invokevirtual01601|Test1 +javasoft/sqe/tests/vm/invokevirtual/invokevirtual016/invokevirtual01601/invokevirtual01601 +JCK-114a|vm|instr|invokevirtual|invokevirtual019|invokevirtual01901|invokevirtual01901|Test1 +javasoft/sqe/tests/vm/invokevirtual/invokevirtual019/invokevirtual01901/invokevirtual01901 +JCK-114a|vm|instr|invokevirtual|invokevirtual022|invokevirtual02201|invokevirtual02201|Test1 +javasoft/sqe/tests/vm/invokevirtual/invokevirtual022/invokevirtual02201/invokevirtual02201 +JCK-114a|vm|instr|iconstI|iconstI001|iconstI00103|iconstI00103|Test1 +javasoft/sqe/tests/vm/iconstI/iconstI001/iconstI00103/iconstI00103 +JCK-114a|vm|instr|iconstI|iconstI001|iconstI00104|iconstI00104|Test1 +javasoft/sqe/tests/vm/iconstI/iconstI001/iconstI00104/iconstI00104 +JCK-114a|vm|instr|iconstI|iconstI001|iconstI00105|iconstI00105|Test1 +javasoft/sqe/tests/vm/iconstI/iconstI001/iconstI00105/iconstI00105 +JCK-114a|vm|instr|iconstI|iconstI001|iconstI00106|iconstI00106|Test1 +javasoft/sqe/tests/vm/iconstI/iconstI001/iconstI00106/iconstI00106 +JCK-114a|vm|instr|iconstI|iconstI001|iconstI00107|iconstI00107|Test1 +javasoft/sqe/tests/vm/iconstI/iconstI001/iconstI00107/iconstI00107 +JCK-114a|vm|instr|iconstI|iconstI001|iconstI00108|iconstI00108|Test1 +javasoft/sqe/tests/vm/iconstI/iconstI001/iconstI00108/iconstI00108 +JCK-114a|vm|instr|iconstI|iconstI001|iconstI00109|iconstI00109|Test1 +javasoft/sqe/tests/vm/iconstI/iconstI001/iconstI00109/iconstI00109 +JCK-114a|vm|instr|i2b|i2b001|i2b00101|i2b00101|Test1 +javasoft/sqe/tests/vm/i2b/i2b001/i2b00101/i2b00101 +JCK-114a|vm|instr|i2b|i2b002|i2b00201|i2b00201|Test1 +javasoft/sqe/tests/vm/i2b/i2b002/i2b00201/i2b00201 +JCK-114a|vm|instr|i2b|i2b003|i2b00301|i2b00301|Test1 +javasoft/sqe/tests/vm/i2b/i2b003/i2b00301/i2b00301 +JCK-114a|vm|instr|i2c|i2c001|i2c00101|i2c00101|Test1 +javasoft/sqe/tests/vm/i2c/i2c001/i2c00101/i2c00101 +JCK-114a|vm|instr|i2c|i2c002|i2c00201|i2c00201|Test1 +javasoft/sqe/tests/vm/i2c/i2c002/i2c00201/i2c00201 +JCK-114a|vm|instr|i2c|i2c003|i2c00301|i2c00301|Test1 +javasoft/sqe/tests/vm/i2c/i2c003/i2c00301/i2c00301 +JCK-114a|vm|instr|i2d|i2d001|i2d00101|i2d00101|Test1 +javasoft/sqe/tests/vm/i2d/i2d001/i2d00101/i2d00101 +JCK-114a|vm|instr|i2d|i2d004|i2d00401|i2d00401|Test1 +javasoft/sqe/tests/vm/i2d/i2d004/i2d00401/i2d00401 +JCK-114a|vm|instr|i2f|i2f001|i2f00101|i2f00101|Test1 +javasoft/sqe/tests/vm/i2f/i2f001/i2f00101/i2f00101 +JCK-114a|vm|instr|i2f|i2f002|i2f00201|i2f00201|Test1 +javasoft/sqe/tests/vm/i2f/i2f002/i2f00201/i2f00201 +JCK-114a|vm|instr|i2l|i2l001|i2l00101|i2l00101|Test1 +javasoft/sqe/tests/vm/i2l/i2l001/i2l00101/i2l00101 +JCK-114a|vm|instr|i2l|i2l004|i2l00401|i2l00401|Test1 +javasoft/sqe/tests/vm/i2l/i2l004/i2l00401/i2l00401 +JCK-114a|vm|instr|i2s|i2s001|i2s00101|i2s00101|Test1 +javasoft/sqe/tests/vm/i2s/i2s001/i2s00101/i2s00101 +JCK-114a|vm|instr|i2s|i2s002|i2s00201|i2s00201|Test1 +javasoft/sqe/tests/vm/i2s/i2s002/i2s00201/i2s00201 +JCK-114a|vm|instr|i2s|i2s003|i2s00301|i2s00301|Test1 +javasoft/sqe/tests/vm/i2s/i2s003/i2s00301/i2s00301 +JCK-114a|vm|instr|instanceof|instanceof004|instanceof00401|instanceof00401|Test1 +javasoft/sqe/tests/vm/instanceofX/instanceof004/instanceof00401/instanceof00401 +JCK-114a|vm|instr|instanceof|instanceof005|instanceof00501|instanceof00501|Test1 +javasoft/sqe/tests/vm/instanceofX/instanceof005/instanceof00501/instanceof00501 +JCK-114a|vm|instr|instanceof|instanceof006|instanceof00601|instanceof00601|Test1 +javasoft/sqe/tests/vm/instanceofX/instanceof006/instanceof00601/instanceof00601 +JCK-114a|vm|instr|instanceof|instanceof007|instanceof00701|instanceof00701|Test1 +javasoft/sqe/tests/vm/instanceofX/instanceof007/instanceof00701/instanceof00701 +JCK-114a|vm|instr|instanceof|instanceof008|instanceof00801|instanceof00801|Test1 +javasoft/sqe/tests/vm/instanceofX/instanceof008/instanceof00801/instanceof00801 +JCK-114a|vm|instr|instanceof|instanceof008|instanceof00802|instanceof00802|Test1 +javasoft/sqe/tests/vm/instanceofX/instanceof008/instanceof00802/instanceof00802 +JCK-114a|vm|instr|instanceof|instanceof008|instanceof00803|instanceof00803|Test1 +javasoft/sqe/tests/vm/instanceofX/instanceof008/instanceof00803/instanceof00803 +JCK-114a|vm|instr|instanceof|instanceof009|instanceof00901|instanceof00901|Test1 +javasoft/sqe/tests/vm/instanceofX/instanceof009/instanceof00901/instanceof00901 +JCK-114a|vm|instr|instanceof|instanceof009|instanceof00902|instanceof00902|Test1 +javasoft/sqe/tests/vm/instanceofX/instanceof009/instanceof00902/instanceof00902 +JCK-114a|vm|instr|instanceof|instanceof010|instanceof01001|instanceof01001|Test1 +javasoft/sqe/tests/vm/instanceofX/instanceof010/instanceof01001/instanceof01001 +JCK-114a|vm|instr|instanceof|instanceof010|instanceof01002|instanceof01002|Test1 +javasoft/sqe/tests/vm/instanceofX/instanceof010/instanceof01002/instanceof01002 +JCK-114a|vm|instr|instanceof|instanceof011|instanceof01101|instanceof01101|Test1 +javasoft/sqe/tests/vm/instanceofX/instanceof011/instanceof01101/instanceof01101 +JCK-114a|vm|instr|instanceof|instanceof011|instanceof01102|instanceof01102|Test1 +javasoft/sqe/tests/vm/instanceofX/instanceof011/instanceof01102/instanceof01102 +JCK-114a|vm|instr|instanceof|instanceof011|instanceof01103|instanceof01103|Test1 +javasoft/sqe/tests/vm/instanceofX/instanceof011/instanceof01103/instanceof01103 +JCK-114a|vm|instr|instanceof|instanceof011|instanceof01104|instanceof01104|Test1 +javasoft/sqe/tests/vm/instanceofX/instanceof011/instanceof01104/instanceof01104 +JCK-114a|vm|instr|instanceof|instanceof012|instanceof01201|instanceof01201|Test1 +javasoft/sqe/tests/vm/instanceofX/instanceof012/instanceof01201/instanceof01201 +JCK-114a|vm|instr|ireturn|ireturn001|ireturn00101|ireturn00101|Test1 +javasoft/sqe/tests/vm/ireturn/ireturn001/ireturn00101/ireturn00101 +JCK-114a|vm|instr|ireturn|ireturn002|ireturn00201|ireturn00201|Test1 +javasoft/sqe/tests/vm/ireturn/ireturn002/ireturn00201/ireturn00201 +JCK-114a|vm|instr|ireturn|ireturn002|ireturn00204|ireturn00204|Test1 +javasoft/sqe/tests/vm/ireturn/ireturn002/ireturn00204/ireturn00204 +JCK-114a|vm|instr|ireturn|ireturn002|ireturn00205|ireturn00205|Test1 +javasoft/sqe/tests/vm/ireturn/ireturn002/ireturn00205/ireturn00205 +JCK-114a|vm|instr|ireturn|ireturn002|ireturn00206|ireturn00206|Test1 +javasoft/sqe/tests/vm/ireturn/ireturn002/ireturn00206/ireturn00206 +JCK-114a|vm|instr|ireturn|ireturn003|ireturn00301|ireturn00301|Test1 +javasoft/sqe/tests/vm/ireturn/ireturn003/ireturn00301/ireturn00301 +JCK-114a|vm|instr|ireturn|ireturn004|ireturn00401|ireturn00401|Test1 +javasoft/sqe/tests/vm/ireturn/ireturn004/ireturn00401/ireturn00401 +JCK-114a|vm|instr|ireturn|ireturn007|ireturn00701|ireturn00701|Test1 +javasoft/sqe/tests/vm/ireturn/ireturn007/ireturn00701/ireturn00701 +JCK-114a|vm|instr|ireturn|ireturn007|ireturn00702|ireturn00702|Test1 +javasoft/sqe/tests/vm/ireturn/ireturn007/ireturn00702/ireturn00702 +JCK-114a|vm|instr|jsr|jsr001|jsr00101|jsr00101|Test1 +javasoft/sqe/tests/vm/jsr/jsr001/jsr00101/jsr00101 +JCK-114a|vm|instr|jsr|jsr002|jsr00201|jsr00201|Test1 +javasoft/sqe/tests/vm/jsr/jsr002/jsr00201/jsr00201 +JCK-114a|vm|instr|jsr|jsr003|jsr00301|jsr00301|Test1 +javasoft/sqe/tests/vm/jsr/jsr003/jsr00301/jsr00301 +JCK-114a|vm|instr|jsr|jsr003|jsr00302|jsr00302|Test1 +javasoft/sqe/tests/vm/jsr/jsr003/jsr00302/jsr00302 +JCK-114a|vm|instr|jsr_w|jsr_w001|jsr_w00101|jsr_w00101|Test1 +javasoft/sqe/tests/vm/jsr_w/jsr_w001/jsr_w00101/jsr_w00101 +JCK-114a|vm|instr|jsr_w|jsr_w002|jsr_w00201|jsr_w00201|Test1 +javasoft/sqe/tests/vm/jsr_w/jsr_w002/jsr_w00201/jsr_w00201 +JCK-114a|vm|instr|jsr_w|jsr_w003|jsr_w00301|jsr_w00301|Test1 +javasoft/sqe/tests/vm/jsr_w/jsr_w003/jsr_w00301/jsr_w00301 +JCK-114a|vm|instr|jsr_w|jsr_w003|jsr_w00302|jsr_w00302|Test1 +javasoft/sqe/tests/vm/jsr_w/jsr_w003/jsr_w00302/jsr_w00302 +JCK-114a|vm|instr|ladd|ladd001|ladd00101|ladd00101|Test1 +javasoft/sqe/tests/vm/ladd/ladd001/ladd00101/ladd00101 +JCK-114a|vm|instr|ladd|ladd002|ladd00201|ladd00201|Test1 +javasoft/sqe/tests/vm/ladd/ladd002/ladd00201/ladd00201 +JCK-114a|vm|instr|ldiv|ldiv001|ldiv00101|ldiv00101|Test1 +javasoft/sqe/tests/vm/ldiv/ldiv001/ldiv00101/ldiv00101 +JCK-114a|vm|instr|ldiv|ldiv002|ldiv00201|ldiv00201|Test1 +javasoft/sqe/tests/vm/ldiv/ldiv002/ldiv00201/ldiv00201 +JCK-114a|vm|instr|ldiv|ldiv003|ldiv00301|ldiv00301|Test1 +javasoft/sqe/tests/vm/ldiv/ldiv003/ldiv00301/ldiv00301 +JCK-114a|vm|instr|ldiv|ldiv006|ldiv00601|ldiv00601|Test1 +javasoft/sqe/tests/vm/ldiv/ldiv006/ldiv00601/ldiv00601 +JCK-114a|vm|instr|lmul|lmul001|lmul00101|lmul00101|Test1 +javasoft/sqe/tests/vm/lmul/lmul001/lmul00101/lmul00101 +JCK-114a|vm|instr|lmul|lmul002|lmul00201|lmul00201|Test1 +javasoft/sqe/tests/vm/lmul/lmul002/lmul00201/lmul00201 +JCK-114a|vm|instr|lneg|lneg001|lneg00101|lneg00101|Test1 +javasoft/sqe/tests/vm/lneg/lneg001/lneg00101/lneg00101 +JCK-114a|vm|instr|lneg|lneg002|lneg00201|lneg00201|Test1 +javasoft/sqe/tests/vm/lneg/lneg002/lneg00201/lneg00201 +JCK-114a|vm|instr|lneg|lneg003|lneg00301|lneg00301|Test1 +javasoft/sqe/tests/vm/lneg/lneg003/lneg00301/lneg00301 +JCK-114a|vm|instr|lneg|lneg004|lneg00401|lneg00401|Test1 +javasoft/sqe/tests/vm/lneg/lneg004/lneg00401/lneg00401 +JCK-114a|vm|instr|lrem|lrem001|lrem00101|lrem00101|Test1 +javasoft/sqe/tests/vm/lrem/lrem001/lrem00101/lrem00101 +JCK-114a|vm|instr|lrem|lrem002|lrem00201|lrem00201|Test1 +javasoft/sqe/tests/vm/lrem/lrem002/lrem00201/lrem00201 +JCK-114a|vm|instr|lrem|lrem005|lrem00501|lrem00501|Test1 +javasoft/sqe/tests/vm/lrem/lrem005/lrem00501/lrem00501 +JCK-114a|vm|instr|lsub|lsub001|lsub00101|lsub00101|Test1 +javasoft/sqe/tests/vm/lsub/lsub001/lsub00101/lsub00101 +JCK-114a|vm|instr|lsub|lsub002|lsub00201|lsub00201|Test1 +javasoft/sqe/tests/vm/lsub/lsub002/lsub00201/lsub00201 +JCK-114a|vm|instr|lsub|lsub003|lsub00301|lsub00301|Test1 +javasoft/sqe/tests/vm/lsub/lsub003/lsub00301/lsub00301 +JCK-114a|vm|instr|lsub|lsub004|lsub00401|lsub00401|Test1 +javasoft/sqe/tests/vm/lsub/lsub004/lsub00401/lsub00401 +JCK-114a|vm|instr|lcmp|lcmp001|lcmp00101|lcmp00101|Test1 +javasoft/sqe/tests/vm/lcmp/lcmp001/lcmp00101/lcmp00101 +JCK-114a|vm|instr|lcmp|lcmp002|lcmp00201|lcmp00201|Test1 +javasoft/sqe/tests/vm/lcmp/lcmp002/lcmp00201/lcmp00201 +JCK-114a|vm|instr|lcmp|lcmp003|lcmp00301|lcmp00301|Test1 +javasoft/sqe/tests/vm/lcmp/lcmp003/lcmp00301/lcmp00301 +JCK-114a|vm|instr|lload|lload001|lload00101|lload00101|Test1 +javasoft/sqe/tests/vm/lload/lload001/lload00101/lload00101 +JCK-114a|vm|instr|lload|lload003|lload00301|lload00301|Test1 +javasoft/sqe/tests/vm/lload/lload003/lload00301/lload00301 +JCK-114a|vm|instr|lloadN|lloadN001|lloadN00102|lloadN00102|Test1 +javasoft/sqe/tests/vm/lloadN/lloadN001/lloadN00102/lloadN00102 +JCK-114a|vm|instr|lloadN|lloadN001|lloadN00103|lloadN00103|Test1 +javasoft/sqe/tests/vm/lloadN/lloadN001/lloadN00103/lloadN00103 +JCK-114a|vm|instr|lloadN|lloadN001|lloadN00104|lloadN00104|Test1 +javasoft/sqe/tests/vm/lloadN/lloadN001/lloadN00104/lloadN00104 +JCK-114a|vm|instr|lloadN|lloadN001|lloadN00105|lloadN00105|Test1 +javasoft/sqe/tests/vm/lloadN/lloadN001/lloadN00105/lloadN00105 +JCK-114a|vm|instr|lload_w|lload_w001|lload_w00101|lload_w00101|Test1 +javasoft/sqe/tests/vm/lload_w/lload_w001/lload_w00101/lload_w00101 +JCK-114a|vm|instr|lload_w|lload_w003|lload_w00301|lload_w00301|Test1 +javasoft/sqe/tests/vm/lload_w/lload_w003/lload_w00301/lload_w00301 +JCK-114a|vm|instr|lstore|lstore001|lstore00101|lstore00101|Test1 +javasoft/sqe/tests/vm/lstore/lstore001/lstore00101/lstore00101 +JCK-114a|vm|instr|lstore|lstore005|lstore00501|lstore00501|Test1 +javasoft/sqe/tests/vm/lstore/lstore005/lstore00501/lstore00501 +JCK-114a|vm|instr|lstoreN|lstoreN004|lstoreN00401|lstoreN00401|Test1 +javasoft/sqe/tests/vm/lstoreN/lstoreN004/lstoreN00401/lstoreN00401 +JCK-114a|vm|instr|lstoreN|lstoreN004|lstoreN00402|lstoreN00402|Test1 +javasoft/sqe/tests/vm/lstoreN/lstoreN004/lstoreN00402/lstoreN00402 +JCK-114a|vm|instr|lstoreN|lstoreN004|lstoreN00403|lstoreN00403|Test1 +javasoft/sqe/tests/vm/lstoreN/lstoreN004/lstoreN00403/lstoreN00403 +JCK-114a|vm|instr|lstoreN|lstoreN004|lstoreN00404|lstoreN00404|Test1 +javasoft/sqe/tests/vm/lstoreN/lstoreN004/lstoreN00404/lstoreN00404 +JCK-114a|vm|instr|lstore_w|lstore_w001|lstore_w00101|lstore_w00101|Test1 +javasoft/sqe/tests/vm/lstore_w/lstore_w001/lstore_w00101/lstore_w00101 +JCK-114a|vm|instr|lstore_w|lstore_w005|lstore_w00501|lstore_w00501|Test1 +javasoft/sqe/tests/vm/lstore_w/lstore_w005/lstore_w00501/lstore_w00501 +JCK-114a|vm|instr|land|land001|land00101|land00101|Test1 +javasoft/sqe/tests/vm/land/land001/land00101/land00101 +JCK-114a|vm|instr|lor|lor001|lor00101|lor00101|Test1 +javasoft/sqe/tests/vm/lor/lor001/lor00101/lor00101 +JCK-114a|vm|instr|lshl|lshl001|lshl00101|lshl00101|Test1 +javasoft/sqe/tests/vm/lshl/lshl001/lshl00101/lshl00101 +JCK-114a|vm|instr|lshl|lshl002|lshl00201|lshl00201|Test1 +javasoft/sqe/tests/vm/lshl/lshl002/lshl00201/lshl00201 +JCK-114a|vm|instr|lshl|lshl003|lshl00301|lshl00301|Test1 +javasoft/sqe/tests/vm/lshl/lshl003/lshl00301/lshl00301 +JCK-114a|vm|instr|lshr|lshr001|lshr00101|lshr00101|Test1 +javasoft/sqe/tests/vm/lshr/lshr001/lshr00101/lshr00101 +JCK-114a|vm|instr|lshr|lshr002|lshr00201|lshr00201|Test1 +javasoft/sqe/tests/vm/lshr/lshr002/lshr00201/lshr00201 +JCK-114a|vm|instr|lshr|lshr003|lshr00301|lshr00301|Test1 +javasoft/sqe/tests/vm/lshr/lshr003/lshr00301/lshr00301 +JCK-114a|vm|instr|lushr|lushr001|lushr00101|lushr00101|Test1 +javasoft/sqe/tests/vm/lushr/lushr001/lushr00101/lushr00101 +JCK-114a|vm|instr|lushr|lushr002|lushr00201|lushr00201|Test1 +javasoft/sqe/tests/vm/lushr/lushr002/lushr00201/lushr00201 +JCK-114a|vm|instr|lushr|lushr003|lushr00301|lushr00301|Test1 +javasoft/sqe/tests/vm/lushr/lushr003/lushr00301/lushr00301 +JCK-114a|vm|instr|lushr|lushr004|lushr00401|lushr00401|Test1 +javasoft/sqe/tests/vm/lushr/lushr004/lushr00401/lushr00401 +JCK-114a|vm|instr|lxor|lxor001|lxor00101|lxor00101|Test1 +javasoft/sqe/tests/vm/lxor/lxor001/lxor00101/lxor00101 +JCK-114a|vm|instr|lconstL|lconstL001|lconstL00102|lconstL00102|Test1 +javasoft/sqe/tests/vm/lconstL/lconstL001/lconstL00102/lconstL00102 +JCK-114a|vm|instr|lconstL|lconstL001|lconstL00103|lconstL00103|Test1 +javasoft/sqe/tests/vm/lconstL/lconstL001/lconstL00103/lconstL00103 +JCK-114a|vm|instr|ldc|ldc001|ldc00101|ldc00101|Test1 +javasoft/sqe/tests/vm/ldc/ldc001/ldc00101/ldc00101 +JCK-114a|vm|instr|ldc|ldc006|ldc00601|ldc00601|Test1 +javasoft/sqe/tests/vm/ldc/ldc006/ldc00601/ldc00601 +JCK-114a|vm|instr|ldc|ldc007|ldc00701|ldc00701|Test1 +javasoft/sqe/tests/vm/ldc/ldc007/ldc00701/ldc00701 +JCK-114a|vm|instr|ldc|ldc007|ldc00702|ldc00702|Test1 +javasoft/sqe/tests/vm/ldc/ldc007/ldc00702/ldc00702 +JCK-114a|vm|instr|ldc2_w|ldc2_w001|ldc2_w00101|ldc2_w00101|Test1 +javasoft/sqe/tests/vm/ldc2_w/ldc2_w001/ldc2_w00101/ldc2_w00101 +JCK-114a|vm|instr|ldc2_w|ldc2_w004|ldc2_w00401|ldc2_w00401|Test1 +javasoft/sqe/tests/vm/ldc2_w/ldc2_w004/ldc2_w00401/ldc2_w00401 +JCK-114a|vm|instr|ldc2_w|ldc2_w004|ldc2_w00402|ldc2_w00402|Test1 +javasoft/sqe/tests/vm/ldc2_w/ldc2_w004/ldc2_w00402/ldc2_w00402 +JCK-114a|vm|instr|ldc_w|ldc_w001|ldc_w00101|ldc_w00101|Test1 +javasoft/sqe/tests/vm/ldc_w/ldc_w001/ldc_w00101/ldc_w00101 +JCK-114a|vm|instr|ldc_w|ldc_w005|ldc_w00501|ldc_w00501|Test1 +javasoft/sqe/tests/vm/ldc_w/ldc_w005/ldc_w00501/ldc_w00501 +JCK-114a|vm|instr|ldc_w|ldc_w007|ldc_w00701|ldc_w00701|Test1 +javasoft/sqe/tests/vm/ldc_w/ldc_w007/ldc_w00701/ldc_w00701 +JCK-114a|vm|instr|ldc_w|ldc_w007|ldc_w00702|ldc_w00702|Test1 +javasoft/sqe/tests/vm/ldc_w/ldc_w007/ldc_w00702/ldc_w00702 +JCK-114a|vm|instr|laload|laload002|laload00201|laload00201|Test1 +javasoft/sqe/tests/vm/laload/laload002/laload00201/laload00201 +JCK-114a|vm|instr|laload|laload006|laload00601|laload00601|Test1 +javasoft/sqe/tests/vm/laload/laload006/laload00601/laload00601 +JCK-114a|vm|instr|laload|laload007|laload00701|laload00701|Test1 +javasoft/sqe/tests/vm/laload/laload007/laload00701/laload00701 +JCK-114a|vm|instr|lastore|lastore002|lastore00201|lastore00201|Test1 +javasoft/sqe/tests/vm/lastore/lastore002/lastore00201/lastore00201 +JCK-114a|vm|instr|lastore|lastore003|lastore00301|lastore00301|Test1 +javasoft/sqe/tests/vm/lastore/lastore003/lastore00301/lastore00301 +JCK-114a|vm|instr|lastore|lastore009|lastore00901|lastore00901|Test1 +javasoft/sqe/tests/vm/lastore/lastore009/lastore00901/lastore00901 +JCK-114a|vm|instr|lookupswitch|lookupswitch005|lookupswitch00501|lookupswitch00501|Test1 +javasoft/sqe/tests/vm/lookupswitch/lookupswitch005/lookupswitch00501/lookupswitch00501 +JCK-114a|vm|instr|lookupswitch|lookupswitch005|lookupswitch00502|lookupswitch00502|Test1 +javasoft/sqe/tests/vm/lookupswitch/lookupswitch005/lookupswitch00502/lookupswitch00502 +JCK-114a|vm|instr|lookupswitch|lookupswitch005|lookupswitch00503|lookupswitch00503|Test1 +javasoft/sqe/tests/vm/lookupswitch/lookupswitch005/lookupswitch00503/lookupswitch00503 +JCK-114a|vm|instr|lookupswitch|lookupswitch005|lookupswitch00504|lookupswitch00504|Test1 +javasoft/sqe/tests/vm/lookupswitch/lookupswitch005/lookupswitch00504/lookupswitch00504 +JCK-114a|vm|instr|lookupswitch|lookupswitch006|lookupswitch00601|lookupswitch00601|Test1 +javasoft/sqe/tests/vm/lookupswitch/lookupswitch006/lookupswitch00601/lookupswitch00601 +JCK-114a|vm|instr|lookupswitch|lookupswitch007|lookupswitch00701|lookupswitch00701|Test1 +javasoft/sqe/tests/vm/lookupswitch/lookupswitch007/lookupswitch00701/lookupswitch00701 +JCK-114a|vm|instr|lookupswitch|lookupswitch008|lookupswitch00801|lookupswitch00801|Test1 +javasoft/sqe/tests/vm/lookupswitch/lookupswitch008/lookupswitch00801/lookupswitch00801 +JCK-114a|vm|instr|lookupswitch|lookupswitch009|lookupswitch00901|lookupswitch00901|Test1 +javasoft/sqe/tests/vm/lookupswitch/lookupswitch009/lookupswitch00901/lookupswitch00901 +JCK-114a|vm|instr|l2d|l2d001|l2d00101|l2d00101|Test1 +javasoft/sqe/tests/vm/l2d/l2d001/l2d00101/l2d00101 +JCK-114a|vm|instr|l2d|l2d002|l2d00201|l2d00201|Test1 +javasoft/sqe/tests/vm/l2d/l2d002/l2d00201/l2d00201 +JCK-114a|vm|instr|l2f|l2f001|l2f00101|l2f00101|Test1 +javasoft/sqe/tests/vm/l2f/l2f001/l2f00101/l2f00101 +JCK-114a|vm|instr|l2f|l2f002|l2f00201|l2f00201|Test1 +javasoft/sqe/tests/vm/l2f/l2f002/l2f00201/l2f00201 +JCK-114a|vm|instr|l2i|l2i001|l2i00101|l2i00101|Test1 +javasoft/sqe/tests/vm/l2i/l2i001/l2i00101/l2i00101 +JCK-114a|vm|instr|l2i|l2i002|l2i00201|l2i00201|Test1 +javasoft/sqe/tests/vm/l2i/l2i002/l2i00201/l2i00201 +JCK-114a|vm|instr|l2i|l2i003|l2i00301|l2i00301|Test1 +javasoft/sqe/tests/vm/l2i/l2i003/l2i00301/l2i00301 +JCK-114a|vm|instr|lreturn|lreturn001|lreturn00101|lreturn00101|Test1 +javasoft/sqe/tests/vm/lreturn/lreturn001/lreturn00101/lreturn00101 +JCK-114a|vm|instr|lreturn|lreturn002|lreturn00201|lreturn00201|Test1 +javasoft/sqe/tests/vm/lreturn/lreturn002/lreturn00201/lreturn00201 +JCK-114a|vm|instr|lreturn|lreturn003|lreturn00301|lreturn00301|Test1 +javasoft/sqe/tests/vm/lreturn/lreturn003/lreturn00301/lreturn00301 +JCK-114a|vm|instr|lreturn|lreturn004|lreturn00401|lreturn00401|Test1 +javasoft/sqe/tests/vm/lreturn/lreturn004/lreturn00401/lreturn00401 +JCK-114a|vm|instr|lreturn|lreturn007|lreturn00701|lreturn00701|Test1 +javasoft/sqe/tests/vm/lreturn/lreturn007/lreturn00701/lreturn00701 +JCK-114a|vm|instr|lreturn|lreturn007|lreturn00702|lreturn00702|Test1 +javasoft/sqe/tests/vm/lreturn/lreturn007/lreturn00702/lreturn00702 +JCK-114a|vm|instr|monitorenter|monitorenter002|monitorenter00202|monitorenter00202|Test1 +javasoft/sqe/tests/vm/monitorenter/monitorenter002/monitorenter00202/monitorenter00202 +JCK-114a|vm|instr|monitorenter|monitorenter003|monitorenter00301|monitorenter00301|Test1 +javasoft/sqe/tests/vm/monitorenter/monitorenter003/monitorenter00301/monitorenter00301 +JCK-114a|vm|instr|monitorenter|monitorenter006|monitorenter00601|monitorenter00601|Test1 +javasoft/sqe/tests/vm/monitorenter/monitorenter006/monitorenter00601/monitorenter00601 +JCK-114a|vm|instr|monitorenter|monitorenter007|monitorenter00701|monitorenter00701|Test1 +javasoft/sqe/tests/vm/monitorenter/monitorenter007/monitorenter00701/monitorenter00701 +JCK-114a|vm|instr|monitorexit|monitorexit002|monitorexit00201|monitorexit00201|Test1 +javasoft/sqe/tests/vm/monitorexit/monitorexit002/monitorexit00201/monitorexit00201 +JCK-114a|vm|instr|monitorexit|monitorexit004|monitorexit00401|monitorexit00401|Test1 +javasoft/sqe/tests/vm/monitorexit/monitorexit004/monitorexit00401/monitorexit00401 +JCK-114a|vm|instr|monitorexit|monitorexit005|monitorexit00501|monitorexit00501|Test1 +javasoft/sqe/tests/vm/monitorexit/monitorexit005/monitorexit00501/monitorexit00501 +JCK-114a|vm|instr|monitorexit|monitorexit006|monitorexit00601|monitorexit00601|Test1 +javasoft/sqe/tests/vm/monitorexit/monitorexit006/monitorexit00601/monitorexit00601 +JCK-114a|vm|instr|multianewarray|multianewarray006|multianewarray00601|multianewarray00601|Test1 +javasoft/sqe/tests/vm/multianewarray/multianewarray006/multianewarray00601/multianewarray00601 +JCK-114a|vm|instr|multianewarray|multianewarray007|multianewarray00701|multianewarray00701|Test1 +javasoft/sqe/tests/vm/multianewarray/multianewarray007/multianewarray00701/multianewarray00701 +JCK-114a|vm|instr|multianewarray|multianewarray008|multianewarray00801|multianewarray00801|Test1 +javasoft/sqe/tests/vm/multianewarray/multianewarray008/multianewarray00801/multianewarray00801 +JCK-114a|vm|instr|multianewarray|multianewarray011|multianewarray01101|multianewarray01101|Test1 +javasoft/sqe/tests/vm/multianewarray/multianewarray011/multianewarray01101/multianewarray01101 +JCK-114a|vm|instr|newarray|newarray003|newarray00301|newarray00301|Test1 +javasoft/sqe/tests/vm/newarray/newarray003/newarray00301/newarray00301 +JCK-114a|vm|instr|newarray|newarray004|newarray00401|newarray00401|Test1 +javasoft/sqe/tests/vm/newarray/newarray004/newarray00401/newarray00401 +JCK-114a|vm|instr|newarray|newarray005|newarray00501|newarray00501|Test1 +javasoft/sqe/tests/vm/newarray/newarray005/newarray00501/newarray00501 +JCK-114a|vm|instr|newarray|newarray006|newarray00601|newarray00601|Test1 +javasoft/sqe/tests/vm/newarray/newarray006/newarray00601/newarray00601 +JCK-114a|vm|instr|new|new002|new00201|new00201|Test1 +javasoft/sqe/tests/vm/ne_w/new002/new00201/new00201 +JCK-114a|vm|instr|new|new002|new00202|new00202|Test1 +javasoft/sqe/tests/vm/ne_w/new002/new00202/new00202 +JCK-114a|vm|instr|new|new003|new00301|new00301|Test1 +javasoft/sqe/tests/vm/new_/new003/new00301/new00301 +JCK-114a|vm|instr|new|new006|new00601|new00601|Test1 +javasoft/sqe/tests/vm/new/new006/new00601/new00601 +JCK-114a|vm|instr|nop|nop001|nop00101|nop00101|Test1 +javasoft/sqe/tests/vm/nop/nop001/nop00101/nop00101 +JCK-114a|vm|instr|pop|pop001|pop00101|pop00101|Test1 +javasoft/sqe/tests/vm/pop/pop001/pop00101/pop00101 +JCK-114a|vm|instr|pop|pop001|pop00102|pop00102|Test1 +javasoft/sqe/tests/vm/pop/pop001/pop00102/pop00102 +JCK-114a|vm|instr|pop|pop001|pop00103|pop00103|Test1 +javasoft/sqe/tests/vm/pop/pop001/pop00103/pop00103 +JCK-114a|vm|instr|pop2|pop2001|pop200101|pop200101|Test1 +javasoft/sqe/tests/vm/pop2/pop2001/pop200101/pop200101 +JCK-114a|vm|instr|pop2|pop2001|pop200102|pop200102|Test1 +javasoft/sqe/tests/vm/pop2/pop2001/pop200102/pop200102 +JCK-114a|vm|instr|pop2|pop2001|pop200103|pop200103|Test1 +javasoft/sqe/tests/vm/pop2/pop2001/pop200103/pop200103 +JCK-114a|vm|instr|pop2|pop2001|pop200104|pop200104|Test1 +javasoft/sqe/tests/vm/pop2/pop2001/pop200104/pop200104 +JCK-114a|vm|instr|pop2|pop2001|pop200105|pop200105|Test1 +javasoft/sqe/tests/vm/pop2/pop2001/pop200105/pop200105 +JCK-114a|vm|instr|pop2|pop2001|pop200106|pop200106|Test1 +javasoft/sqe/tests/vm/pop2/pop2001/pop200106/pop200106 +JCK-114a|vm|instr|putfield|putfield001|putfield00101|putfield00101|Test1 +javasoft/sqe/tests/vm/putfield/putfield001/putfield00101/putfield00101 +JCK-114a|vm|instr|putfield|putfield002|putfield00201|putfield00201|Test1 +javasoft/sqe/tests/vm/putfield/putfield002/putfield00201/putfield00201 +JCK-114a|vm|instr|putfield|putfield002|putfield00202|putfield00202|Test1 +javasoft/sqe/tests/vm/putfield/putfield002/putfield00202/putfield00202 +JCK-114a|vm|instr|putfield|putfield003|putfield00301|putfield00301|Test1 +javasoft/sqe/tests/vm/putfield/putfield003/putfield00301/putfield00301 +JCK-114a|vm|instr|putfield|putfield004|putfield00401|putfield00401|Test1 +javasoft/sqe/tests/vm/putfield/putfield004/putfield00401/putfield00401 +JCK-114a|vm|instr|putfield|putfield005|putfield00501|putfield00501|Test1 +javasoft/sqe/tests/vm/putfield/putfield005/putfield00501/putfield00501 +JCK-114a|vm|instr|putfield|putfield005|putfield00502|putfield00502|Test1 +javasoft/sqe/tests/vm/putfield/putfield005/putfield00502/putfield00502 +JCK-114a|vm|instr|putfield|putfield006|putfield00601|putfield00601|Test1 +javasoft/sqe/tests/vm/putfield/putfield006/putfield00601/putfield00601 +JCK-114a|vm|instr|putfield|putfield007|putfield00701|putfield00701|Test1 +javasoft/sqe/tests/vm/putfield/putfield007/putfield00701/putfield00701 +JCK-114a|vm|instr|putfield|putfield008|putfield00801|putfield00801|Test1 +javasoft/sqe/tests/vm/putfield/putfield008/putfield00801/putfield00801 +JCK-114a|vm|instr|putfield|putfield009|putfield00901|putfield00901|Test1 +javasoft/sqe/tests/vm/putfield/putfield009/putfield00901/putfield00901 +JCK-114a|vm|instr|putfield|putfield009|putfield00902|putfield00902|Test1 +javasoft/sqe/tests/vm/putfield/putfield009/putfield00902/putfield00902 +JCK-114a|vm|instr|putfield|putfield010|putfield01001|putfield01001|Test1 +javasoft/sqe/tests/vm/putfield/putfield010/putfield01001/putfield01001 +JCK-114a|vm|instr|putfield|putfield010|putfield01002|putfield01002|Test1 +javasoft/sqe/tests/vm/putfield/putfield010/putfield01002/putfield01002 +JCK-114a|vm|instr|putfield|putfield010|putfield01003|putfield01003|Test1 +javasoft/sqe/tests/vm/putfield/putfield010/putfield01003/putfield01003 +JCK-114a|vm|instr|putfield|putfield012|putfield01201|putfield01201|Test1 +javasoft/sqe/tests/vm/putfield/putfield012/putfield01201/putfield01201 +JCK-114a|vm|instr|putfield|putfield013|putfield01301|putfield01301|Test1 +javasoft/sqe/tests/vm/putfield/putfield013/putfield01301/putfield01301 +JCK-114a|vm|instr|putfield|putfield013|putfield01303|putfield01303|Test1 +javasoft/sqe/tests/vm/putfield/putfield013/putfield01303/putfield01303 +JCK-114a|vm|instr|putfield|putfield013|putfield01305|putfield01305|Test1 +javasoft/sqe/tests/vm/putfield/putfield013/putfield01305/putfield01305 +JCK-114a|vm|instr|putfield|putfield013|putfield01307|putfield01307|Test1 +javasoft/sqe/tests/vm/putfield/putfield013/putfield01307/putfield01307 +JCK-114a|vm|instr|putfield|putfield014|putfield01401|putfield01401|Test1 +javasoft/sqe/tests/vm/putfield/putfield014/putfield01401/putfield01401 +JCK-114a|vm|instr|putfield|putfield014|putfield01403|putfield01403|Test1 +javasoft/sqe/tests/vm/putfield/putfield014/putfield01403/putfield01403 +JCK-114a|vm|instr|putfield|putfield014|putfield01405|putfield01405|Test1 +javasoft/sqe/tests/vm/putfield/putfield014/putfield01405/putfield01405 +JCK-114a|vm|instr|putfield|putfield015|putfield01501|putfield01501|Test1 +javasoft/sqe/tests/vm/putfield/putfield015/putfield01501/putfield01501 +JCK-114a|vm|instr|putfield|putfield018|putfield01801|putfield01801|Test1 +javasoft/sqe/tests/vm/putfield/putfield018/putfield01801/putfield01801 +JCK-114a|vm|instr|putstatic|putstatic001|putstatic00101|putstatic00101|Test1 +javasoft/sqe/tests/vm/putstatic/putstatic001/putstatic00101/putstatic00101 +JCK-114a|vm|instr|putstatic|putstatic002|putstatic00201|putstatic00201|Test1 +javasoft/sqe/tests/vm/putstatic/putstatic002/putstatic00201/putstatic00201 +JCK-114a|vm|instr|putstatic|putstatic002|putstatic00202|putstatic00202|Test1 +javasoft/sqe/tests/vm/putstatic/putstatic002/putstatic00202/putstatic00202 +JCK-114a|vm|instr|putstatic|putstatic002|putstatic00203|putstatic00203|Test1 +javasoft/sqe/tests/vm/putstatic/putstatic002/putstatic00203/putstatic00203 +JCK-114a|vm|instr|putstatic|putstatic003|putstatic00301|putstatic00301|Test1 +javasoft/sqe/tests/vm/putstatic/putstatic003/putstatic00301/putstatic00301 +JCK-114a|vm|instr|putstatic|putstatic004|putstatic00401|putstatic00401|Test1 +javasoft/sqe/tests/vm/putstatic/putstatic004/putstatic00401/putstatic00401 +JCK-114a|vm|instr|putstatic|putstatic005|putstatic00501|putstatic00501|Test1 +javasoft/sqe/tests/vm/putstatic/putstatic005/putstatic00501/putstatic00501 +JCK-114a|vm|instr|putstatic|putstatic005|putstatic00502|putstatic00502|Test1 +javasoft/sqe/tests/vm/putstatic/putstatic005/putstatic00502/putstatic00502 +JCK-114a|vm|instr|putstatic|putstatic006|putstatic00601|putstatic00601|Test1 +javasoft/sqe/tests/vm/putstatic/putstatic006/putstatic00601/putstatic00601 +JCK-114a|vm|instr|putstatic|putstatic007|putstatic00701|putstatic00701|Test1 +javasoft/sqe/tests/vm/putstatic/putstatic007/putstatic00701/putstatic00701 +JCK-114a|vm|instr|putstatic|putstatic008|putstatic00801|putstatic00801|Test1 +javasoft/sqe/tests/vm/putstatic/putstatic008/putstatic00801/putstatic00801 +JCK-114a|vm|instr|putstatic|putstatic008|putstatic00802|putstatic00802|Test1 +javasoft/sqe/tests/vm/putstatic/putstatic008/putstatic00802/putstatic00802 +JCK-114a|vm|instr|putstatic|putstatic009|putstatic00901|putstatic00901|Test1 +javasoft/sqe/tests/vm/putstatic/putstatic009/putstatic00901/putstatic00901 +JCK-114a|vm|instr|putstatic|putstatic009|putstatic00902|putstatic00902|Test1 +javasoft/sqe/tests/vm/putstatic/putstatic009/putstatic00902/putstatic00902 +JCK-114a|vm|instr|putstatic|putstatic009|putstatic00903|putstatic00903|Test1 +javasoft/sqe/tests/vm/putstatic/putstatic009/putstatic00903/putstatic00903 +JCK-114a|vm|instr|putstatic|putstatic010|putstatic01001|putstatic01001|Test1 +javasoft/sqe/tests/vm/putstatic/putstatic010/putstatic01001/putstatic01001 +JCK-114a|vm|instr|putstatic|putstatic011|putstatic01101|putstatic01101|Test1 +javasoft/sqe/tests/vm/putstatic/putstatic011/putstatic01101/putstatic01101 +JCK-114a|vm|instr|putstatic|putstatic011|putstatic01103|putstatic01103|Test1 +javasoft/sqe/tests/vm/putstatic/putstatic011/putstatic01103/putstatic01103 +JCK-114a|vm|instr|putstatic|putstatic011|putstatic01105|putstatic01105|Test1 +javasoft/sqe/tests/vm/putstatic/putstatic011/putstatic01105/putstatic01105 +JCK-114a|vm|instr|putstatic|putstatic011|putstatic01107|putstatic01107|Test1 +javasoft/sqe/tests/vm/putstatic/putstatic011/putstatic01107/putstatic01107 +JCK-114a|vm|instr|putstatic|putstatic012|putstatic01201|putstatic01201|Test1 +javasoft/sqe/tests/vm/putstatic/putstatic012/putstatic01201/putstatic01201 +JCK-114a|vm|instr|putstatic|putstatic012|putstatic01203|putstatic01203|Test1 +javasoft/sqe/tests/vm/putstatic/putstatic012/putstatic01203/putstatic01203 +JCK-114a|vm|instr|putstatic|putstatic012|putstatic01205|putstatic01205|Test1 +javasoft/sqe/tests/vm/putstatic/putstatic012/putstatic01205/putstatic01205 +JCK-114a|vm|instr|putstatic|putstatic013|putstatic01301|putstatic01301|Test1 +javasoft/sqe/tests/vm/putstatic/putstatic013/putstatic01301/putstatic01301 +JCK-114a|vm|instr|ret|ret001|ret00101|ret00101|Test1 +javasoft/sqe/tests/vm/ret/ret001/ret00101/ret00101 +JCK-114a|vm|instr|ret|ret002|ret00201|ret00201|Test1 +javasoft/sqe/tests/vm/ret/ret002/ret00201/ret00201 +JCK-114a|vm|instr|ret|ret002|ret00202|ret00202|Test1 +javasoft/sqe/tests/vm/ret/ret002/ret00202/ret00202 +JCK-114a|vm|instr|ret|ret003|ret00301|ret00301|Test1 +javasoft/sqe/tests/vm/ret/ret003/ret00301/ret00301 +JCK-114a|vm|instr|ret|ret004|ret00401|ret00401|Test1 +javasoft/sqe/tests/vm/ret/ret004/ret00401/ret00401 +JCK-114a|vm|instr|return|return001|return00101|return00101|Test1 +javasoft/sqe/tests/vm/returnX/return001/return00101/return00101 +JCK-114a|vm|instr|return|return001|return00102|return00102|Test1 +javasoft/sqe/tests/vm/returnX/return001/return00102/return00102 +JCK-114a|vm|instr|return|return001|return00103|return00103|Test1 +javasoft/sqe/tests/vm/returnX/return001/return00103/return00103 +JCK-114a|vm|instr|return|return002|return00201|return00201|Test1 +javasoft/sqe/tests/vm/returnX/return002/return00201/return00201 +JCK-114a|vm|instr|return|return002|return00202|return00202|Test1 +javasoft/sqe/tests/vm/returnX/return002/return00202/return00202 +JCK-114a|vm|instr|ret_w|ret_w001|ret_w00101|ret_w00101|Test1 +javasoft/sqe/tests/vm/ret_w/ret_w001/ret_w00101/ret_w00101 +JCK-114a|vm|instr|ret_w|ret_w002|ret_w00201|ret_w00201|Test1 +javasoft/sqe/tests/vm/ret_w/ret_w002/ret_w00201/ret_w00201 +JCK-114a|vm|instr|ret_w|ret_w002|ret_w00202|ret_w00202|Test1 +javasoft/sqe/tests/vm/ret_w/ret_w002/ret_w00202/ret_w00202 +JCK-114a|vm|instr|ret_w|ret_w003|ret_w00301|ret_w00301|Test1 +javasoft/sqe/tests/vm/ret_w/ret_w003/ret_w00301/ret_w00301 +JCK-114a|vm|instr|ret_w|ret_w004|ret_w00401|ret_w00401|Test1 +javasoft/sqe/tests/vm/ret_w/ret_w004/ret_w00401/ret_w00401 +JCK-114a|vm|instr|saload|saload002|saload00201|saload00201|Test1 +javasoft/sqe/tests/vm/saload/saload002/saload00201/saload00201 +JCK-114a|vm|instr|saload|saload006|saload00601|saload00601|Test1 +javasoft/sqe/tests/vm/saload/saload006/saload00601/saload00601 +JCK-114a|vm|instr|saload|saload007|saload00701|saload00701|Test1 +javasoft/sqe/tests/vm/saload/saload007/saload00701/saload00701 +JCK-114a|vm|instr|sastore|sastore002|sastore00201|sastore00201|Test1 +javasoft/sqe/tests/vm/sastore/sastore002/sastore00201/sastore00201 +JCK-114a|vm|instr|sastore|sastore005|sastore00501|sastore00501|Test1 +javasoft/sqe/tests/vm/sastore/sastore005/sastore00501/sastore00501 +JCK-114a|vm|instr|sastore|sastore008|sastore00801|sastore00801|Test1 +javasoft/sqe/tests/vm/sastore/sastore008/sastore00801/sastore00801 +JCK-114a|vm|instr|swap|swap001|swap00101|swap00101|Test1 +javasoft/sqe/tests/vm/swap/swap001/swap00101/swap00101 +JCK-114a|vm|instr|swap|swap003|swap00301|swap00301|Test1 +javasoft/sqe/tests/vm/swap/swap003/swap00301/swap00301 +JCK-114a|vm|instr|swap|swap003|swap00302|swap00302|Test1 +javasoft/sqe/tests/vm/swap/swap003/swap00302/swap00302 +JCK-114a|vm|instr|swap|swap003|swap00303|swap00303|Test1 +javasoft/sqe/tests/vm/swap/swap003/swap00303/swap00303 +JCK-114a|vm|instr|swap|swap003|swap00304|swap00304|Test1 +javasoft/sqe/tests/vm/swap/swap003/swap00304/swap00304 +JCK-114a|vm|instr|sipush|sipush001|sipush00101|sipush00101|Test1 +javasoft/sqe/tests/vm/sipush/sipush001/sipush00101/sipush00101 +JCK-114a|vm|instr|wide|wide004|wide00401|wide00401|Test1 +javasoft/sqe/tests/vm/wide/wide004/wide00401/wide00401 diff --git a/ef/Quality/TestScript/jckJNI.txt b/ef/Quality/TestScript/jckJNI.txt new file mode 100644 index 000000000000..d55872f82074 --- /dev/null +++ b/ef/Quality/TestScript/jckJNI.txt @@ -0,0 +1,494 @@ +JCK-114a|vm|jni|AllocObject|alob001|alob00101|alob00101|Test1 +javasoft.sqe.tests.vm.alob001.alob00101.alob00101 +JCK-114a|vm|jni|CallBooleanMethod|czmt001|czmt00101|czmt00101|Test1 +javasoft.sqe.tests.vm.czmt001.czmt00101.czmt00101 +JCK-114a|vm|jni|CallBooleanMethod|czmt001|czmt00102|czmt00102|Test1 +javasoft.sqe.tests.vm.czmt001.czmt00102.czmt00102 +JCK-114a|vm|jni|CallBooleanMethodA|czma001|czma00101|czma00101|Test1 +javasoft.sqe.tests.vm.czma001.czma00101.czma00101 +JCK-114a|vm|jni|CallBooleanMethodV|czmv001|czmv00101|czmv00101|Test1 +javasoft.sqe.tests.vm.czmv001.czmv00101.czmv00101 +JCK-114a|vm|jni|CallByteMethod|cbmt001|cbmt00101|cbmt00101|Test1 +javasoft.sqe.tests.vm.cbmt001.cbmt00101.cbmt00101 +JCK-114a|vm|jni|CallByteMethodA|cbma001|cbma00101|cbma00101|Test1 +javasoft.sqe.tests.vm.cbma001.cbma00101.cbma00101 +JCK-114a|vm|jni|CallByteMethodV|cbmv001|cbmv00101|cbmv00101|Test1 +javasoft.sqe.tests.vm.cbmv001.cbmv00101.cbmv00101 +JCK-114a|vm|jni|CallCharMethod|ccmt001|ccmt00101|ccmt00101|Test1 +javasoft.sqe.tests.vm.ccmt001.ccmt00101.ccmt00101 +JCK-114a|vm|jni|CallCharMethodA|ccma001|ccma00101|ccma00101|Test1 +javasoft.sqe.tests.vm.ccma001.ccma00101.ccma00101 +JCK-114a|vm|jni|CallCharMethodV|ccmv001|ccmv00101|ccmv00101|Test1 +javasoft.sqe.tests.vm.ccmv001.ccmv00101.ccmv00101 +JCK-114a|vm|jni|CallDoubleMethod|cdmt001|cdmt00101|cdmt00101|Test1 +javasoft.sqe.tests.vm.cdmt001.cdmt00101.cdmt00101 +JCK-114a|vm|jni|CallDoubleMethodA|cdma001|cdma00101|cdma00101|Test1 +javasoft.sqe.tests.vm.cdma001.cdma00101.cdma00101 +JCK-114a|vm|jni|CallDoubleMethodA|cdma001|cdma00102|cdma00102|Test1 +javasoft.sqe.tests.vm.cdma001.cdma00102.cdma00102 +JCK-114a|vm|jni|CallDoubleMethodV|cdmv001|cdmv00101|cdmv00101|Test1 +javasoft.sqe.tests.vm.cdmv001.cdmv00101.cdmv00101 +JCK-114a|vm|jni|CallFloatMethod|cfmt001|cfmt00101|cfmt00101|Test1 +javasoft.sqe.tests.vm.cfmt001.cfmt00101.cfmt00101 +JCK-114a|vm|jni|CallFloatMethodA|cfma001|cfma00101|cfma00101|Test1 +javasoft.sqe.tests.vm.cfma001.cfma00101.cfma00101 +JCK-114a|vm|jni|CallFloatMethodV|cfmv001|cfmv00101|cfmv00101|Test1 +javasoft.sqe.tests.vm.cfmv001.cfmv00101.cfmv00101 +JCK-114a|vm|jni|CallIntMethod|cimt001|cimt00101|cimt00101|Test1 +javasoft.sqe.tests.vm.cimt001.cimt00101.cimt00101 +JCK-114a|vm|jni|CallIntMethod|cimt001|cimt00103|cimt00103|Test1 +javasoft.sqe.tests.vm.cimt001.cimt00103.cimt00103 +JCK-114a|vm|jni|CallIntMethodA|cima001|cima00101|cima00101|Test1 +javasoft.sqe.tests.vm.cima001.cima00101.cima00101 +JCK-114a|vm|jni|CallIntMethodV|cimv001|cimv00101|cimv00101|Test1 +javasoft.sqe.tests.vm.cimv001.cimv00101.cimv00101 +JCK-114a|vm|jni|CallLongMethod|cjmt001|cjmt00101|cjmt00101|Test1 +javasoft.sqe.tests.vm.cjmt001.cjmt00101.cjmt00101 +JCK-114a|vm|jni|CallLongMethodA|cjma001|cjma00101|cjma00101|Test1 +javasoft.sqe.tests.vm.cjma001.cjma00101.cjma00101 +JCK-114a|vm|jni|CallLongMethodA|cjma001|cjma00103|cjma00103|Test1 +javasoft.sqe.tests.vm.cjma001.cjma00103.cjma00103 +JCK-114a|vm|jni|CallLongMethodV|cjmv001|cjmv00101|cjmv00101|Test1 +javasoft.sqe.tests.vm.cjmv001.cjmv00101.cjmv00101 +JCK-114a|vm|jni|CallNonvirtualBooleanMethod|cnzm001|cnzm00101|cnzm00101|Test1 +javasoft.sqe.tests.vm.cnzm001.cnzm00101.cnzm00101 +JCK-114a|vm|jni|CallNonvirtualBooleanMethod|cnzm001|cnzm00103|cnzm00103|Test1 +javasoft.sqe.tests.vm.cnzm001.cnzm00103.cnzm00103 +JCK-114a|vm|jni|CallNonvirtualBooleanMethodA|cnza001|cnza00101|cnza00101|Test1 +javasoft.sqe.tests.vm.cnza001.cnza00101.cnza00101 +JCK-114a|vm|jni|CallNonvirtualBooleanMethodV|cnzv001|cnzv00101|cnzv00101|Test1 +javasoft.sqe.tests.vm.cnzv001.cnzv00101.cnzv00101 +JCK-114a|vm|jni|CallNonvirtualByteMethod|cnbm001|cnbm00101|cnbm00101|Test1 +javasoft.sqe.tests.vm.cnbm001.cnbm00101.cnbm00101 +JCK-114a|vm|jni|CallNonvirtualByteMethodA|cnba001|cnba00101|cnba00101|Test1 +javasoft.sqe.tests.vm.cnba001.cnba00101.cnba00101 +JCK-114a|vm|jni|CallNonvirtualByteMethodV|cnbv001|cnbv00101|cnbv00101|Test1 +javasoft.sqe.tests.vm.cnbv001.cnbv00101.cnbv00101 +JCK-114a|vm|jni|CallNonvirtualCharMethod|cncm001|cncm00101|cncm00101|Test1 +javasoft.sqe.tests.vm.cncm001.cncm00101.cncm00101 +JCK-114a|vm|jni|CallNonvirtualCharMethod|cncm001|cncm00102|cncm00102|Test1 +javasoft.sqe.tests.vm.cncm001.cncm00102.cncm00102 +JCK-114a|vm|jni|CallNonvirtualCharMethodA|cnca001|cnca00101|cnca00101|Test1 +javasoft.sqe.tests.vm.cnca001.cnca00101.cnca00101 +JCK-114a|vm|jni|CallNonvirtualCharMethodA|cnca001|cnca00103|cnca00103|Test1 +javasoft.sqe.tests.vm.cnca001.cnca00103.cnca00103 +JCK-114a|vm|jni|CallNonvirtualCharMethodV|cncv001|cncv00101|cncv00101|Test1 +javasoft.sqe.tests.vm.cncv001.cncv00101.cncv00101 +JCK-114a|vm|jni|CallNonvirtualDoubleMethod|cndm001|cndm00101|cndm00101|Test1 +javasoft.sqe.tests.vm.cndm001.cndm00101.cndm00101 +JCK-114a|vm|jni|CallNonvirtualDoubleMethodA|cnda001|cnda00101|cnda00101|Test1 +javasoft.sqe.tests.vm.cnda001.cnda00101.cnda00101 +JCK-114a|vm|jni|CallNonvirtualDoubleMethodV|cndv001|cndv00101|cndv00101|Test1 +javasoft.sqe.tests.vm.cndv001.cndv00101.cndv00101 +JCK-114a|vm|jni|CallNonvirtualFloatMethod|cnfm001|cnfm00101|cnfm00101|Test1 +javasoft.sqe.tests.vm.cnfm001.cnfm00101.cnfm00101 +JCK-114a|vm|jni|CallNonvirtualFloatMethodA|cnfa001|cnfa00101|cnfa00101|Test1 +javasoft.sqe.tests.vm.cnfa001.cnfa00101.cnfa00101 +JCK-114a|vm|jni|CallNonvirtualFloatMethodV|cnfv001|cnfv00101|cnfv00101|Test1 +javasoft.sqe.tests.vm.cnfv001.cnfv00101.cnfv00101 +JCK-114a|vm|jni|CallNonvirtualIntMethod|cnim001|cnim00101|cnim00101|Test1 +javasoft.sqe.tests.vm.cnim001.cnim00101.cnim00101 +JCK-114a|vm|jni|CallNonvirtualIntMethodA|cnia001|cnia00101|cnia00101|Test1 +javasoft.sqe.tests.vm.cnia001.cnia00101.cnia00101 +JCK-114a|vm|jni|CallNonvirtualIntMethodV|cniv001|cniv00101|cniv00101|Test1 +javasoft.sqe.tests.vm.cniv001.cniv00101.cniv00101 +JCK-114a|vm|jni|CallNonvirtualLongMethod|cnjm001|cnjm00101|cnjm00101|Test1 +javasoft.sqe.tests.vm.cnjm001.cnjm00101.cnjm00101 +JCK-114a|vm|jni|CallNonvirtualLongMethodA|cnja001|cnja00101|cnja00101|Test1 +javasoft.sqe.tests.vm.cnja001.cnja00101.cnja00101 +JCK-114a|vm|jni|CallNonvirtualLongMethodV|cnjv001|cnjv00101|cnjv00101|Test1 +javasoft.sqe.tests.vm.cnjv001.cnjv00101.cnjv00101 +JCK-114a|vm|jni|CallNonvirtualObjectMethod|cnom001|cnom00101|cnom00101|Test1 +javasoft.sqe.tests.vm.cnom001.cnom00101.cnom00101 +JCK-114a|vm|jni|CallNonvirtualObjectMethodA|cnoa001|cnoa00101|cnoa00101|Test1 +javasoft.sqe.tests.vm.cnoa001.cnoa00101.cnoa00101 +JCK-114a|vm|jni|CallNonvirtualObjectMethodA|cnoa001|cnoa00102|cnoa00102|Test1 +javasoft.sqe.tests.vm.cnoa001.cnoa00102.cnoa00102 +JCK-114a|vm|jni|CallNonvirtualObjectMethodV|cnov001|cnov00101|cnov00101|Test1 +javasoft.sqe.tests.vm.cnov001.cnov00101.cnov00101 +JCK-114a|vm|jni|CallNonvirtualShortMethod|cnsm001|cnsm00101|cnsm00101|Test1 +javasoft.sqe.tests.vm.cnsm001.cnsm00101.cnsm00101 +JCK-114a|vm|jni|CallNonvirtualShortMethodA|cnsa001|cnsa00101|cnsa00101|Test1 +javasoft.sqe.tests.vm.cnsa001.cnsa00101.cnsa00101 +JCK-114a|vm|jni|CallNonvirtualShortMethodV|cnsv001|cnsv00101|cnsv00101|Test1 +javasoft.sqe.tests.vm.cnsv001.cnsv00101.cnsv00101 +JCK-114a|vm|jni|CallNonvirtualShortMethodV|cnsv001|cnsv00102|cnsv00102|Test1 +javasoft.sqe.tests.vm.cnsv001.cnsv00102.cnsv00102 +JCK-114a|vm|jni|CallNonvirtualVoidMethod|cnvm001|cnvm00101|cnvm00101|Test1 +javasoft.sqe.tests.vm.cnvm001.cnvm00101.cnvm00101 +JCK-114a|vm|jni|CallNonvirtualVoidMethod|cnvm001|cnvm00104|cnvm00104|Test1 +javasoft.sqe.tests.vm.cnvm001.cnvm00104.cnvm00104 +JCK-114a|vm|jni|CallNonvirtualVoidMethodA|cnva001|cnva00101|cnva00101|Test1 +javasoft.sqe.tests.vm.cnva001.cnva00101.cnva00101 +JCK-114a|vm|jni|CallNonvirtualVoidMethodA|cnva001|cnva00104|cnva00104|Test1 +javasoft.sqe.tests.vm.cnva001.cnva00104.cnva00104 +JCK-114a|vm|jni|CallNonvirtualVoidMethodV|cnvv001|cnvv00101|cnvv00101|Test1 +javasoft.sqe.tests.vm.cnvv001.cnvv00101.cnvv00101 +JCK-114a|vm|jni|CallNonvirtualVoidMethodV|cnvv001|cnvv00103|cnvv00103|Test1 +javasoft.sqe.tests.vm.cnvv001.cnvv00103.cnvv00103 +JCK-114a|vm|jni|CallNonvirtualVoidMethodV|cnvv001|cnvv00104|cnvv00104|Test1 +javasoft.sqe.tests.vm.cnvv001.cnvv00104.cnvv00104 +JCK-114a|vm|jni|CallObjectMethod|comt001|comt00101|comt00101|Test1 +javasoft.sqe.tests.vm.comt001.comt00101.comt00101 +JCK-114a|vm|jni|CallObjectMethodA|coma001|coma00101|coma00101|Test1 +javasoft.sqe.tests.vm.coma001.coma00101.coma00101 +JCK-114a|vm|jni|CallObjectMethodV|comv001|comv00101|comv00101|Test1 +javasoft.sqe.tests.vm.comv001.comv00101.comv00101 +JCK-114a|vm|jni|CallObjectMethodV|comv001|comv00103|comv00103|Test1 +javasoft.sqe.tests.vm.comv001.comv00103.comv00103 +JCK-114a|vm|jni|CallShortMethod|csmt001|csmt00101|csmt00101|Test1 +javasoft.sqe.tests.vm.csmt001.csmt00101.csmt00101 +JCK-114a|vm|jni|CallShortMethodA|csma001|csma00101|csma00101|Test1 +javasoft.sqe.tests.vm.csma001.csma00101.csma00101 +JCK-114a|vm|jni|CallShortMethodV|csmv001|csmv00101|csmv00101|Test1 +javasoft.sqe.tests.vm.csmv001.csmv00101.csmv00101 +JCK-114a|vm|jni|CallStaticBooleanMethod|cszm001|cszm00101|cszm00101|Test1 +javasoft.sqe.tests.vm.cszm001.cszm00101.cszm00101 +JCK-114a|vm|jni|CallStaticBooleanMethod|cszm001|cszm00103|cszm00103|Test1 +javasoft.sqe.tests.vm.cszm001.cszm00103.cszm00103 +JCK-114a|vm|jni|CallStaticBooleanMethodA|csza001|csza00101|csza00101|Test1 +javasoft.sqe.tests.vm.csza001.csza00101.csza00101 +JCK-114a|vm|jni|CallStaticBooleanMethodV|cszv001|cszv00101|cszv00101|Test1 +javasoft.sqe.tests.vm.cszv001.cszv00101.cszv00101 +JCK-114a|vm|jni|CallStaticByteMethod|csbm001|csbm00101|csbm00101|Test1 +javasoft.sqe.tests.vm.csbm001.csbm00101.csbm00101 +JCK-114a|vm|jni|CallStaticByteMethod|csbm001|csbm00102|csbm00102|Test1 +javasoft.sqe.tests.vm.csbm001.csbm00102.csbm00102 +JCK-114a|vm|jni|CallStaticByteMethodA|csba001|csba00101|csba00101|Test1 +javasoft.sqe.tests.vm.csba001.csba00101.csba00101 +JCK-114a|vm|jni|CallStaticByteMethodV|csbv001|csbv00101|csbv00101|Test1 +javasoft.sqe.tests.vm.csbv001.csbv00101.csbv00101 +JCK-114a|vm|jni|CallStaticCharMethod|cscm001|cscm00101|cscm00101|Test1 +javasoft.sqe.tests.vm.cscm001.cscm00101.cscm00101 +JCK-114a|vm|jni|CallStaticCharMethodA|csca001|csca00101|csca00101|Test1 +javasoft.sqe.tests.vm.csca001.csca00101.csca00101 +JCK-114a|vm|jni|CallStaticCharMethodA|csca001|csca00103|csca00103|Test1 +javasoft.sqe.tests.vm.csca001.csca00103.csca00103 +JCK-114a|vm|jni|CallStaticCharMethodV|cscv001|cscv00101|cscv00101|Test1 +javasoft.sqe.tests.vm.cscv001.cscv00101.cscv00101 +JCK-114a|vm|jni|CallStaticDoubleMethod|csdm001|csdm00101|csdm00101|Test1 +javasoft.sqe.tests.vm.csdm001.csdm00101.csdm00101 +JCK-114a|vm|jni|CallStaticDoubleMethodA|csda001|csda00101|csda00101|Test1 +javasoft.sqe.tests.vm.csda001.csda00101.csda00101 +JCK-114a|vm|jni|CallStaticDoubleMethodV|csdv001|csdv00101|csdv00101|Test1 +javasoft.sqe.tests.vm.csdv001.csdv00101.csdv00101 +JCK-114a|vm|jni|CallStaticDoubleMethodV|csdv001|csdv00103|csdv00103|Test1 +javasoft.sqe.tests.vm.csdv001.csdv00103.csdv00103 +JCK-114a|vm|jni|CallStaticFloatMethod|csfm001|csfm00101|csfm00101|Test1 +javasoft.sqe.tests.vm.csfm001.csfm00101.csfm00101 +JCK-114a|vm|jni|CallStaticFloatMethodA|csfa001|csfa00101|csfa00101|Test1 +javasoft.sqe.tests.vm.csfa001.csfa00101.csfa00101 +JCK-114a|vm|jni|CallStaticFloatMethodA|csfa001|csfa00102|csfa00102|Test1 +javasoft.sqe.tests.vm.csfa001.csfa00102.csfa00102 +JCK-114a|vm|jni|CallStaticFloatMethodV|csfv001|csfv00101|csfv00101|Test1 +javasoft.sqe.tests.vm.csfv001.csfv00101.csfv00101 +JCK-114a|vm|jni|CallStaticIntMethod|csim001|csim00101|csim00101|Test1 +javasoft.sqe.tests.vm.csim001.csim00101.csim00101 +JCK-114a|vm|jni|CallStaticIntMethodA|csia001|csia00101|csia00101|Test1 +javasoft.sqe.tests.vm.csia001.csia00101.csia00101 +JCK-114a|vm|jni|CallStaticIntMethodV|csiv001|csiv00101|csiv00101|Test1 +javasoft.sqe.tests.vm.csiv001.csiv00101.csiv00101 +JCK-114a|vm|jni|CallStaticLongMethod|csjm001|csjm00101|csjm00101|Test1 +javasoft.sqe.tests.vm.csjm001.csjm00101.csjm00101 +JCK-114a|vm|jni|CallStaticLongMethodA|csja001|csja00101|csja00101|Test1 +javasoft.sqe.tests.vm.csja001.csja00101.csja00101 +JCK-114a|vm|jni|CallStaticLongMethodV|csjv001|csjv00101|csjv00101|Test1 +javasoft.sqe.tests.vm.csjv001.csjv00101.csjv00101 +JCK-114a|vm|jni|CallStaticLongMethodV|csjv001|csjv00102|csjv00102|Test1 +javasoft.sqe.tests.vm.csjv001.csjv00102.csjv00102 +JCK-114a|vm|jni|CallStaticObjectMethod|csom001|csom00101|csom00101|Test1 +javasoft.sqe.tests.vm.csom001.csom00101.csom00101 +JCK-114a|vm|jni|CallStaticObjectMethodA|csoa001|csoa00101|csoa00101|Test1 +javasoft.sqe.tests.vm.csoa001.csoa00101.csoa00101 +JCK-114a|vm|jni|CallStaticObjectMethodV|csov001|csov00101|csov00101|Test1 +javasoft.sqe.tests.vm.csov001.csov00101.csov00101 +JCK-114a|vm|jni|CallStaticShortMethod|cssm001|cssm00101|cssm00101|Test1 +javasoft.sqe.tests.vm.cssm001.cssm00101.cssm00101 +JCK-114a|vm|jni|CallStaticShortMethodA|cssa001|cssa00101|cssa00101|Test1 +javasoft.sqe.tests.vm.cssa001.cssa00101.cssa00101 +JCK-114a|vm|jni|CallStaticShortMethodV|cssv001|cssv00101|cssv00101|Test1 +javasoft.sqe.tests.vm.cssv001.cssv00101.cssv00101 +JCK-114a|vm|jni|CallStaticVoidMethod|csvm001|csvm00101|csvm00101|Test1 +javasoft.sqe.tests.vm.csvm001.csvm00101.csvm00101 +JCK-114a|vm|jni|CallStaticVoidMethodA|csva001|csva00101|csva00101|Test1 +javasoft.sqe.tests.vm.csva001.csva00101.csva00101 +JCK-114a|vm|jni|CallStaticVoidMethodV|csvv001|csvv00101|csvv00101|Test1 +javasoft.sqe.tests.vm.csvv001.csvv00101.csvv00101 +JCK-114a|vm|jni|CallVoidMethod|cvmt001|cvmt00101|cvmt00101|Test1 +javasoft.sqe.tests.vm.cvmt001.cvmt00101.cvmt00101 +JCK-114a|vm|jni|CallVoidMethod|cvmt001|cvmt00104|cvmt00104|Test1 +javasoft.sqe.tests.vm.cvmt001.cvmt00104.cvmt00104 +JCK-114a|vm|jni|CallVoidMethodA|cvma001|cvma00101|cvma00101|Test1 +javasoft.sqe.tests.vm.cvma001.cvma00101.cvma00101 +JCK-114a|vm|jni|CallVoidMethodA|cvma001|cvma00104|cvma00104|Test1 +javasoft.sqe.tests.vm.cvma001.cvma00104.cvma00104 +JCK-114a|vm|jni|CallVoidMethodV|cvmv001|cvmv00101|cvmv00101|Test1 +javasoft.sqe.tests.vm.cvmv001.cvmv00101.cvmv00101 +JCK-114a|vm|jni|CallVoidMethodV|cvmv001|cvmv00102|cvmv00102|Test1 +javasoft.sqe.tests.vm.cvmv001.cvmv00102.cvmv00102 +JCK-114a|vm|jni|CallVoidMethodV|cvmv001|cvmv00104|cvmv00104|Test1 +javasoft.sqe.tests.vm.cvmv001.cvmv00104.cvmv00104 +JCK-114a|vm|jni|DefineClass|dfcl001|dfcl00101|dfcl00101|Test1 +javasoft.sqe.tests.vm.dfcl001.dfcl00101.dfcl00101 +JCK-114a|vm|jni|DeleteGlobalRef|dglr001|dglr00101|dglr00101|Test1 +javasoft.sqe.tests.vm.dglr001.dglr00101.dglr00101 +JCK-114a|vm|jni|DeleteLocalRef|dlcr001|dlcr00101|dlcr00101|Test1 +javasoft.sqe.tests.vm.dlcr001.dlcr00101.dlcr00101 +JCK-114a|vm|jni|ExceptionClear|excl001|excl00101|excl00101|Test1 +javasoft.sqe.tests.vm.excl001.excl00101.excl00101 +JCK-114a|vm|jni|ExceptionDescribe|exds001|exds00101|exds00101|Test1 +javasoft.sqe.tests.vm.exds001.exds00101.exds00101 +JCK-114a|vm|jni|ExceptionOccurred|exoc001|exoc00101|exoc00101|Test1 +javasoft.sqe.tests.vm.exoc001.exoc00101.exoc00101 +JCK-114a|vm|jni|FindClass|fncl001|fncl00103|fncl00103|Test1 +javasoft.sqe.tests.vm.fncl001.fncl00103.fncl00103 +JCK-114a|vm|jni|GetArrayLength|garl001|garl00101|garl00101|Test1 +javasoft.sqe.tests.vm.garl001.garl00101.garl00101 +JCK-114a|vm|jni|GetBooleanArrayElements|gzae001|gzae00101|gzae00101|Test1 +javasoft.sqe.tests.vm.gzae001.gzae00101.gzae00101 +JCK-114a|vm|jni|GetBooleanArrayRegion|gzar001|gzar00101|gzar00101|Test1 +javasoft.sqe.tests.vm.gzar001.gzar00101.gzar00101 +JCK-114a|vm|jni|GetBooleanField|gzfl001|gzfl00101|gzfl00101|Test1 +javasoft.sqe.tests.vm.gzfl001.gzfl00101.gzfl00101 +JCK-114a|vm|jni|GetByteArrayElements|gbae001|gbae00101|gbae00101|Test1 +javasoft.sqe.tests.vm.gbae001.gbae00101.gbae00101 +JCK-114a|vm|jni|GetByteArrayRegion|gbar001|gbar00101|gbar00101|Test1 +javasoft.sqe.tests.vm.gbar001.gbar00101.gbar00101 +JCK-114a|vm|jni|GetByteField|gbfl001|gbfl00101|gbfl00101|Test1 +javasoft.sqe.tests.vm.gbfl001.gbfl00101.gbfl00101 +JCK-114a|vm|jni|GetCharArrayElements|gcae001|gcae00101|gcae00101|Test1 +javasoft.sqe.tests.vm.gcae001.gcae00101.gcae00101 +JCK-114a|vm|jni|GetCharArrayRegion|gcar001|gcar00101|gcar00101|Test1 +javasoft.sqe.tests.vm.gcar001.gcar00101.gcar00101 +JCK-114a|vm|jni|GetCharField|gcfl001|gcfl00101|gcfl00101|Test1 +javasoft.sqe.tests.vm.gcfl001.gcfl00101.gcfl00101 +JCK-114a|vm|jni|GetDoubleArrayElements|gdae001|gdae00101|gdae00101|Test1 +javasoft.sqe.tests.vm.gdae001.gdae00101.gdae00101 +JCK-114a|vm|jni|GetDoubleArrayRegion|gdar001|gdar00101|gdar00101|Test1 +javasoft.sqe.tests.vm.gdar001.gdar00101.gdar00101 +JCK-114a|vm|jni|GetDoubleField|gdfl001|gdfl00101|gdfl00101|Test1 +javasoft.sqe.tests.vm.gdfl001.gdfl00101.gdfl00101 +JCK-114a|vm|jni|GetFieldID|gfid001|gfid00101|gfid00101|Test1 +javasoft.sqe.tests.vm.gfid001.gfid00101.gfid00101 +JCK-114a|vm|jni|GetFloatArrayElements|gfae001|gfae00101|gfae00101|Test1 +javasoft.sqe.tests.vm.gfae001.gfae00101.gfae00101 +JCK-114a|vm|jni|GetFloatArrayRegion|gfar001|gfar00101|gfar00101|Test1 +javasoft.sqe.tests.vm.gfar001.gfar00101.gfar00101 +JCK-114a|vm|jni|GetFloatField|gffl001|gffl00101|gffl00101|Test1 +javasoft.sqe.tests.vm.gffl001.gffl00101.gffl00101 +JCK-114a|vm|jni|GetIntArrayElements|giae001|giae00101|giae00101|Test1 +javasoft.sqe.tests.vm.giae001.giae00101.giae00101 +JCK-114a|vm|jni|GetIntArrayRegion|giar001|giar00101|giar00101|Test1 +javasoft.sqe.tests.vm.giar001.giar00101.giar00101 +JCK-114a|vm|jni|GetIntField|gifl001|gifl00101|gifl00101|Test1 +javasoft.sqe.tests.vm.gifl001.gifl00101.gifl00101 +JCK-114a|vm|jni|GetJavaVM|gjvm001|gjvm00101|gjvm00101|Test1 +javasoft.sqe.tests.vm.gjvm001.gjvm00101.gjvm00101 +JCK-114a|vm|jni|GetLongArrayElements|gjae001|gjae00101|gjae00101|Test1 +javasoft.sqe.tests.vm.gjae001.gjae00101.gjae00101 +JCK-114a|vm|jni|GetLongArrayRegion|gjar001|gjar00101|gjar00101|Test1 +javasoft.sqe.tests.vm.gjar001.gjar00101.gjar00101 +JCK-114a|vm|jni|GetLongField|gjfl001|gjfl00101|gjfl00101|Test1 +javasoft.sqe.tests.vm.gjfl001.gjfl00101.gjfl00101 +JCK-114a|vm|jni|GetMethodID|gmid001|gmid00105|gmid00105|Test1 +javasoft.sqe.tests.vm.gmid001.gmid00105.gmid00105 +JCK-114a|vm|jni|GetMethodID|gmid001|gmid00107|gmid00107|Test1 +javasoft.sqe.tests.vm.gmid001.gmid00107.gmid00107 +JCK-114a|vm|jni|GetObjectArrayElement|goae001|goae00101|goae00101|Test1 +javasoft.sqe.tests.vm.goae001.goae00101.goae00101 +JCK-114a|vm|jni|GetObjectClass|gocl001|gocl00101|gocl00101|Test1 +javasoft.sqe.tests.vm.gocl001.gocl00101.gocl00101 +JCK-114a|vm|jni|GetObjectField|gofl001|gofl00101|gofl00101|Test1 +javasoft.sqe.tests.vm.gofl001.gofl00101.gofl00101 +JCK-114a|vm|jni|GetShortArrayElements|gsae001|gsae00101|gsae00101|Test1 +javasoft.sqe.tests.vm.gsae001.gsae00101.gsae00101 +JCK-114a|vm|jni|GetShortArrayRegion|gsar001|gsar00101|gsar00101|Test1 +javasoft.sqe.tests.vm.gsar001.gsar00101.gsar00101 +JCK-114a|vm|jni|GetShortField|gsfl001|gsfl00101|gsfl00101|Test1 +javasoft.sqe.tests.vm.gsfl001.gsfl00101.gsfl00101 +JCK-114a|vm|jni|GetStaticBooleanField|gszf001|gszf00101|gszf00101|Test1 +javasoft.sqe.tests.vm.gszf001.gszf00101.gszf00101 +JCK-114a|vm|jni|GetStaticByteField|gsbf001|gsbf00101|gsbf00101|Test1 +javasoft.sqe.tests.vm.gsbf001.gsbf00101.gsbf00101 +JCK-114a|vm|jni|GetStaticCharField|gscf001|gscf00101|gscf00101|Test1 +javasoft.sqe.tests.vm.gscf001.gscf00101.gscf00101 +JCK-114a|vm|jni|GetStaticDoubleField|gsdf001|gsdf00101|gsdf00101|Test1 +javasoft.sqe.tests.vm.gsdf001.gsdf00101.gsdf00101 +JCK-114a|vm|jni|GetStaticFieldID|gsfi001|gsfi00101|gsfi00101|Test1 +javasoft.sqe.tests.vm.gsfi001.gsfi00101.gsfi00101 +JCK-114a|vm|jni|GetStaticFloatField|gsff001|gsff00101|gsff00101|Test1 +javasoft.sqe.tests.vm.gsff001.gsff00101.gsff00101 +JCK-114a|vm|jni|GetStaticIntField|gsif001|gsif00101|gsif00101|Test1 +javasoft.sqe.tests.vm.gsif001.gsif00101.gsif00101 +JCK-114a|vm|jni|GetStaticLongField|gsjf001|gsjf00101|gsjf00101|Test1 +javasoft.sqe.tests.vm.gsjf001.gsjf00101.gsjf00101 +JCK-114a|vm|jni|GetStaticMethodID|gsmi001|gsmi00105|gsmi00105|Test1 +javasoft.sqe.tests.vm.gsmi001.gsmi00105.gsmi00105 +JCK-114a|vm|jni|GetStaticMethodID|gsmi001|gsmi00107|gsmi00107|Test1 +javasoft.sqe.tests.vm.gsmi001.gsmi00107.gsmi00107 +JCK-114a|vm|jni|GetStaticObjectField|gsof001|gsof00101|gsof00101|Test1 +javasoft.sqe.tests.vm.gsof001.gsof00101.gsof00101 +JCK-114a|vm|jni|GetStaticShortField|gssf001|gssf00101|gssf00101|Test1 +javasoft.sqe.tests.vm.gssf001.gssf00101.gssf00101 +JCK-114a|vm|jni|GetStringChars|gsch001|gsch00101|gsch00101|Test1 +javasoft.sqe.tests.vm.gsch001.gsch00101.gsch00101 +JCK-114a|vm|jni|GetStringLength|gstl001|gstl00101|gstl00101|Test1 +javasoft.sqe.tests.vm.gstl001.gstl00101.gstl00101 +JCK-114a|vm|jni|GetStringUTFChars|gsuc001|gsuc00101|gsuc00101|Test1 +javasoft.sqe.tests.vm.gsuc001.gsuc00101.gsuc00101 +JCK-114a|vm|jni|GetStringUTFLength|gsul001|gsul00101|gsul00101|Test1 +javasoft.sqe.tests.vm.gsul001.gsul00101.gsul00101 +JCK-114a|vm|jni|GetSuperclass|gscl001|gscl00103|gscl00103|Test1 +javasoft.sqe.tests.vm.gscl001.gscl00103.gscl00103 +JCK-114a|vm|jni|GetVersion|gver001|gver00101|gver00101|Test1 +javasoft.sqe.tests.vm.gver001.gver00101.gver00101 +JCK-114a|vm|jni|IsInstanceOf|isio001|isio00101|isio00101|Test1 +javasoft.sqe.tests.vm.isio001.isio00101.isio00101 +JCK-114a|vm|jni|IsSameObject|isso001|isso00101|isso00101|Test1 +javasoft.sqe.tests.vm.isso001.isso00101.isso00101 +JCK-114a|vm|jni|IsAssignableFrom|isaf001|isaf00103|isaf00103|Test1 +javasoft.sqe.tests.vm.isaf001.isaf00103.isaf00103 +JCK-114a|vm|jni|MonitorEnter|mnte001|mnte00101|mnte00101|Test1 +javasoft.sqe.tests.vm.mnte001.mnte00101.mnte00101 +JCK-114a|vm|jni|NativeMethods|nmtd001|nmtd00101|nmtd00101|Test1 +javasoft.sqe.tests.vm.nmtd001.nmtd00101.nmtd00101 +JCK-114a|vm|jni|NativeMethods|nmtd001|nmtd00102|nmtd00102|Test1 +javasoft.sqe.tests.vm.nmtd001.nmtd00102.nmtd00102 +JCK-114a|vm|jni|NativeMethods|nmtd001|nmtd00103|nmtd00103|Test1 +javasoft.sqe.tests.vm.nmtd001.nmtd00103.nmtd00103 +JCK-114a|vm|jni|NativeMethods|nmtd001|nmtd00104|nmtd00104|Test1 +javasoft.sqe.tests.vm.nmtd001.nmtd00104.nmtd00104 +JCK-114a|vm|jni|NativeMethods|nmtd001|nmtd00105|nmtd00105|Test1 +javasoft.sqe.tests.vm.nmtd001.nmtd00105.nmtd00105 +JCK-114a|vm|jni|NativeMethods|nmtd001|nmtd00106|nmtd00106|Test1 +javasoft.sqe.tests.vm.nmtd001.nmtd00106.nmtd00106 +JCK-114a|vm|jni|NativeMethods|nmtd001|nmtd00107|nmtd00107|Test1 +javasoft.sqe.tests.vm.nmtd001.nmtd00107.nmtd00107 +JCK-114a|vm|jni|NativeMethods|nmtd001|nmtd00108|nmtd00108|Test1 +javasoft.sqe.tests.vm.nmtd001.nmtd00108.nmtd00108 +JCK-114a|vm|jni|NativeMethods|nmtd001|nmtd00109|nmtd00109|Test1 +javasoft.sqe.tests.vm.nmtd001.nmtd00109.nmtd00109 +JCK-114a|vm|jni|NativeMethods|nmtd002|nmtd00201|nmtd00201|Test1 +javasoft.sqe.tests.vm.nmtd002.nmtd00201.nmtd00201 +JCK-114a|vm|jni|NativeMethods|nmtd002|nmtd00202|nmtd00202|Test1 +javasoft.sqe.tests.vm.nmtd002.nmtd00202.nmtd00202 +JCK-114a|vm|jni|NativeMethods|nmtd002|nmtd00203|nmtd00203|Test1 +javasoft.sqe.tests.vm.nmtd002.nmtd00203.nmtd00203 +JCK-114a|vm|jni|NativeMethods|nmtd002|nmtd00204|nmtd00204|Test1 +javasoft.sqe.tests.vm.nmtd002.nmtd00204.nmtd00204 +JCK-114a|vm|jni|NativeMethods|nmtd002|nmtd00205|nmtd00205|Test1 +javasoft.sqe.tests.vm.nmtd002.nmtd00205.nmtd00205 +JCK-114a|vm|jni|NativeMethods|nmtd003|nmtd00301|nmtd00301|Test1 +javasoft.sqe.tests.vm.nmtd003.nmtd00301.nmtd00301 +JCK-114a|vm|jni|NewBooleanArray|nzar001|nzar00101|nzar00101|Test1 +javasoft.sqe.tests.vm.nzar001.nzar00101.nzar00101 +JCK-114a|vm|jni|NewByteArray|nbar001|nbar00101|nbar00101|Test1 +javasoft.sqe.tests.vm.nbar001.nbar00101.nbar00101 +JCK-114a|vm|jni|NewCharArray|ncar001|ncar00101|ncar00101|Test1 +javasoft.sqe.tests.vm.ncar001.ncar00101.ncar00101 +JCK-114a|vm|jni|NewDoubleArray|ndar001|ndar00101|ndar00101|Test1 +javasoft.sqe.tests.vm.ndar001.ndar00101.ndar00101 +JCK-114a|vm|jni|NewFloatArray|nfar001|nfar00101|nfar00101|Test1 +javasoft.sqe.tests.vm.nfar001.nfar00101.nfar00101 +JCK-114a|vm|jni|NewGlobalRef|nglr001|nglr00101|nglr00101|Test1 +javasoft.sqe.tests.vm.nglr001.nglr00101.nglr00101 +JCK-114a|vm|jni|NewIntArray|niar001|niar00101|niar00101|Test1 +javasoft.sqe.tests.vm.niar001.niar00101.niar00101 +JCK-114a|vm|jni|NewLongArray|njar001|njar00101|njar00101|Test1 +javasoft.sqe.tests.vm.njar001.njar00101.njar00101 +JCK-114a|vm|jni|NewObject|nobj001|nobj00101|nobj00101|Test1 +javasoft.sqe.tests.vm.nobj001.nobj00101.nobj00101 +JCK-114a|vm|jni|NewObjectA|noba001|noba00101|noba00101|Test1 +javasoft.sqe.tests.vm.noba001.noba00101.noba00101 +JCK-114a|vm|jni|NewObjectArray|noar001|noar00101|noar00101|Test1 +javasoft.sqe.tests.vm.noar001.noar00101.noar00101 +JCK-114a|vm|jni|NewObjectV|nobv001|nobv00101|nobv00101|Test1 +javasoft.sqe.tests.vm.nobv001.nobv00101.nobv00101 +JCK-114a|vm|jni|NewShortArray|nsar001|nsar00101|nsar00101|Test1 +javasoft.sqe.tests.vm.nsar001.nsar00101.nsar00101 +JCK-114a|vm|jni|NewString|nstr001|nstr00101|nstr00101|Test1 +javasoft.sqe.tests.vm.nstr001.nstr00101.nstr00101 +JCK-114a|vm|jni|NewStringUTF|nstu001|nstu00101|nstu00101|Test1 +javasoft.sqe.tests.vm.nstu001.nstu00101.nstu00101 +JCK-114a|vm|jni|RegisterNatives|rgnt001|rgnt00101|rgnt00101|Test1 +javasoft.sqe.tests.vm.rgnt001.rgnt00101.rgnt00101 +JCK-114a|vm|jni|ReleaseBooleanArrayElements|rzae001|rzae00101|rzae00101|Test1 +javasoft.sqe.tests.vm.rzae001.rzae00101.rzae00101 +JCK-114a|vm|jni|ReleaseByteArrayElements|rbae001|rbae00101|rbae00101|Test1 +javasoft.sqe.tests.vm.rbae001.rbae00101.rbae00101 +JCK-114a|vm|jni|ReleaseCharArrayElements|rcae001|rcae00101|rcae00101|Test1 +javasoft.sqe.tests.vm.rcae001.rcae00101.rcae00101 +JCK-114a|vm|jni|ReleaseDoubleArrayElements|rdae001|rdae00101|rdae00101|Test1 +javasoft.sqe.tests.vm.rdae001.rdae00101.rdae00101 +JCK-114a|vm|jni|ReleaseFloatArrayElements|rfae001|rfae00101|rfae00101|Test1 +javasoft.sqe.tests.vm.rfae001.rfae00101.rfae00101 +JCK-114a|vm|jni|ReleaseIntArrayElements|riae001|riae00101|riae00101|Test1 +javasoft.sqe.tests.vm.riae001.riae00101.riae00101 +JCK-114a|vm|jni|ReleaseLongArrayElements|rjae001|rjae00101|rjae00101|Test1 +javasoft.sqe.tests.vm.rjae001.rjae00101.rjae00101 +JCK-114a|vm|jni|ReleaseShortArrayElements|rsae001|rsae00101|rsae00101|Test1 +javasoft.sqe.tests.vm.rsae001.rsae00101.rsae00101 +JCK-114a|vm|jni|ReleaseStringChars|rsch001|rsch00101|rsch00101|Test1 +javasoft.sqe.tests.vm.rsch001.rsch00101.rsch00101 +JCK-114a|vm|jni|ReleaseStringUTFChars|rsuc001|rsuc00101|rsuc00101|Test1 +javasoft.sqe.tests.vm.rsuc001.rsuc00101.rsuc00101 +JCK-114a|vm|jni|SetBooleanArrayRegion|szar001|szar00101|szar00101|Test1 +javasoft.sqe.tests.vm.szar001.szar00101.szar00101 +JCK-114a|vm|jni|SetBooleanField|szfl001|szfl00101|szfl00101|Test1 +javasoft.sqe.tests.vm.szfl001.szfl00101.szfl00101 +JCK-114a|vm|jni|SetByteArrayRegion|sbar001|sbar00101|sbar00101|Test1 +javasoft.sqe.tests.vm.sbar001.sbar00101.sbar00101 +JCK-114a|vm|jni|SetByteField|sbfl001|sbfl00101|sbfl00101|Test1 +javasoft.sqe.tests.vm.sbfl001.sbfl00101.sbfl00101 +JCK-114a|vm|jni|SetCharArrayRegion|scar001|scar00101|scar00101|Test1 +javasoft.sqe.tests.vm.scar001.scar00101.scar00101 +JCK-114a|vm|jni|SetCharField|scfl001|scfl00101|scfl00101|Test1 +javasoft.sqe.tests.vm.scfl001.scfl00101.scfl00101 +JCK-114a|vm|jni|SetDoubleArrayRegion|sdar001|sdar00101|sdar00101|Test1 +javasoft.sqe.tests.vm.sdar001.sdar00101.sdar00101 +JCK-114a|vm|jni|SetDoubleField|sdfl001|sdfl00101|sdfl00101|Test1 +javasoft.sqe.tests.vm.sdfl001.sdfl00101.sdfl00101 +JCK-114a|vm|jni|SetFloatArrayRegion|sfar001|sfar00101|sfar00101|Test1 +javasoft.sqe.tests.vm.sfar001.sfar00101.sfar00101 +JCK-114a|vm|jni|SetFloatField|sffl001|sffl00101|sffl00101|Test1 +javasoft.sqe.tests.vm.sffl001.sffl00101.sffl00101 +JCK-114a|vm|jni|SetIntArrayRegion|siar001|siar00101|siar00101|Test1 +javasoft.sqe.tests.vm.siar001.siar00101.siar00101 +JCK-114a|vm|jni|SetIntField|sifl001|sifl00101|sifl00101|Test1 +javasoft.sqe.tests.vm.sifl001.sifl00101.sifl00101 +JCK-114a|vm|jni|SetLongArrayRegion|sjar001|sjar00101|sjar00101|Test1 +javasoft.sqe.tests.vm.sjar001.sjar00101.sjar00101 +JCK-114a|vm|jni|SetLongField|sjfl001|sjfl00101|sjfl00101|Test1 +javasoft.sqe.tests.vm.sjfl001.sjfl00101.sjfl00101 +JCK-114a|vm|jni|SetObjectArrayElement|soae001|soae00101|soae00101|Test1 +javasoft.sqe.tests.vm.soae001.soae00101.soae00101 +JCK-114a|vm|jni|SetObjectField|sofl001|sofl00101|sofl00101|Test1 +javasoft.sqe.tests.vm.sofl001.sofl00101.sofl00101 +JCK-114a|vm|jni|SetShortArrayRegion|ssar001|ssar00101|ssar00101|Test1 +javasoft.sqe.tests.vm.ssar001.ssar00101.ssar00101 +JCK-114a|vm|jni|SetShortField|ssfl001|ssfl00101|ssfl00101|Test1 +javasoft.sqe.tests.vm.ssfl001.ssfl00101.ssfl00101 +JCK-114a|vm|jni|SetStaticBooleanField|sszf001|sszf00101|sszf00101|Test1 +javasoft.sqe.tests.vm.sszf001.sszf00101.sszf00101 +JCK-114a|vm|jni|SetStaticByteField|ssbf001|ssbf00101|ssbf00101|Test1 +javasoft.sqe.tests.vm.ssbf001.ssbf00101.ssbf00101 +JCK-114a|vm|jni|SetStaticCharField|sscf001|sscf00101|sscf00101|Test1 +javasoft.sqe.tests.vm.sscf001.sscf00101.sscf00101 +JCK-114a|vm|jni|SetStaticDoubleField|ssdf001|ssdf00101|ssdf00101|Test1 +javasoft.sqe.tests.vm.ssdf001.ssdf00101.ssdf00101 +JCK-114a|vm|jni|SetStaticFloatField|ssff001|ssff00101|ssff00101|Test1 +javasoft.sqe.tests.vm.ssff001.ssff00101.ssff00101 +JCK-114a|vm|jni|SetStaticIntField|ssif001|ssif00101|ssif00101|Test1 +javasoft.sqe.tests.vm.ssif001.ssif00101.ssif00101 +JCK-114a|vm|jni|SetStaticLongField|ssjf001|ssjf00101|ssjf00101|Test1 +javasoft.sqe.tests.vm.ssjf001.ssjf00101.ssjf00101 +JCK-114a|vm|jni|SetStaticObjectField|ssof001|ssof00101|ssof00101|Test1 +javasoft.sqe.tests.vm.ssof001.ssof00101.ssof00101 +JCK-114a|vm|jni|SetStaticShortField|sssf001|sssf00101|sssf00101|Test1 +javasoft.sqe.tests.vm.sssf001.sssf00101.sssf00101 +JCK-114a|vm|jni|Throw|thrw001|thrw00101|thrw00101|Test1 +javasoft.sqe.tests.vm.thrw001.thrw00101.thrw00101 +JCK-114a|vm|jni|ThrowNew|thrn001|thrn00101|thrn00101|Test1 +javasoft.sqe.tests.vm.thrn001.thrn00101.thrn00101 +JCK-114a|vm|jni|UnregisterNatives|urnt001|urnt00101|urnt00101|Test1 +javasoft.sqe.tests.vm.urnt001.urnt00101.urnt00101 diff --git a/ef/Quality/TestScript/jckJavaIo.txt b/ef/Quality/TestScript/jckJavaIo.txt new file mode 100644 index 000000000000..fe51ba5395e1 --- /dev/null +++ b/ef/Quality/TestScript/jckJavaIo.txt @@ -0,0 +1,972 @@ +JCK-114a|api|java_io|FileInputStream|FISTestDescriptions|Test1 +javasoft.sqe.tests.api.java.io.FISConstructorTest1 -WorkDir E:/tmp/ +JCK-114a|api|java_io|FileInputStream|FISTestDescriptions|Test2 +javasoft.sqe.tests.api.java.io.FISConstructorTest2 -WorkDir E:/tmp/ +JCK-114a|api|java_io|FileInputStream|FISTestDescriptions|Test3 +javasoft.sqe.tests.api.java.io.FISConstructorTest3 -WorkDir E:/tmp/ +JCK-114a|api|java_io|FileInputStream|FISTestDescriptions|Test4 +javasoft.sqe.tests.api.java.io.FISAvailableTest1 -TestCaseID smallTest -WorkDir E:/tmp/ +JCK-114a|api|java_io|FileInputStream|FISTestDescriptions|Test6 +javasoft.sqe.tests.api.java.io.FISReadTest1 -TestCaseID smallTest -WorkDir E:/tmp/ +JCK-114a|api|java_io|FileInputStream|FISTestDescriptions|Test7 +javasoft.sqe.tests.api.java.io.FISReadTest2 -WorkDir E:/tmp/ +JCK-114a|api|java_io|FileInputStream|FISTestDescriptions|Test8 +javasoft.sqe.tests.api.java.io.FISReadTest3 -WorkDir E:/tmp/ +JCK-114a|api|java_io|FileInputStream|FISTestDescriptions|Test9 +javasoft.sqe.tests.api.java.io.FISReadArrayTest1 -TestCaseID smallTest -WorkDir E:/tmp/ +JCK-114a|api|java_io|FileInputStream|FISTestDescriptions|Test10 +javasoft.sqe.tests.api.java.io.FISReadArrayTest2 -WorkDir E:/tmp/ +JCK-114a|api|java_io|FileInputStream|FISTestDescriptions|Test11 +javasoft.sqe.tests.api.java.io.FISReadArrayTest3 -TestCaseID smallTest -WorkDir E:/tmp/ +JCK-114a|api|java_io|FileInputStream|FISTestDescriptions|Test12 +javasoft.sqe.tests.api.java.io.FISReadArrayTest4 -WorkDir E:/tmp/ +JCK-114a|api|java_io|FileInputStream|FISTestDescriptions|Test13 +javasoft.sqe.tests.api.java.io.FISReadIndexedTest1 -TestCaseID smallTest -WorkDir E:/tmp/ +JCK-114a|api|java_io|FileInputStream|FISTestDescriptions|Test14 +javasoft.sqe.tests.api.java.io.FISReadIndexedTest2 -TestCaseID smallTest -WorkDir E:/tmp/ +JCK-114a|api|java_io|FileInputStream|FISTestDescriptions|Test15 +javasoft.sqe.tests.api.java.io.FISReadIndexedTest3 -WorkDir E:/tmp/ +JCK-114a|api|java_io|FileInputStream|FISTestDescriptions|Test16 +javasoft.sqe.tests.api.java.io.FISReadIndexedTest4 -WorkDir E:/tmp/ +JCK-114a|api|java_io|FileInputStream|FISTestDescriptions|Test17 +javasoft.sqe.tests.api.java.io.FISReadIndexedTest5 -WorkDir E:/tmp/ +JCK-114a|api|java_io|FileInputStream|FISTestDescriptions|Test18 +javasoft.sqe.tests.api.java.io.FISReadIndexedTest6 -WorkDir E:/tmp/ +JCK-114a|api|java_io|FileInputStream|FISTestDescriptions|Test19 +javasoft.sqe.tests.api.java.io.FISReadIndexedTest7 -WorkDir E:/tmp/ +JCK-114a|api|java_io|FileInputStream|FISTestDescriptions|Test20 +javasoft.sqe.tests.api.java.io.FISReadIndexedTest8 -WorkDir E:/tmp/ +JCK-114a|api|java_io|FileInputStream|FISTestDescriptions|Test21 +javasoft.sqe.tests.api.java.io.FISgetFDTest1 -WorkDir E:/tmp/ +JCK-114a|api|java_io|FileInputStream|FISTestDescriptions|Test22 +javasoft.sqe.tests.api.java.io.FISgetFDTest2 -WorkDir E:/tmp/ +JCK-114a|api|java_io|FileInputStream|FISTestDescriptions|Test23 +javasoft.sqe.tests.api.java.io.FISskipTest1 -WorkDir E:/tmp/ +JCK-114a|api|java_io|FileInputStream|FISTestDescriptions|Test24 +javasoft.sqe.tests.api.java.io.FISskipTest2 -WorkDir E:/tmp/ +JCK-114a|api|java_io|FileInputStream|FISTestDescriptions|Test25 +javasoft.sqe.tests.api.java.io.FISskipTest3 -WorkDir E:/tmp/ +JCK-114a|api|java_io|FileInputStream|FISTestDescriptions|Test26 +javasoft.sqe.tests.api.java.io.FISskipTest4 -WorkDir E:/tmp/ +JCK-114a|api|java_io|FileInputStream|FISTestDescriptions|Test27 +javasoft.sqe.tests.api.java.io.FISskipTest5 -WorkDir E:/tmp/ +JCK-114a|api|java_io|FileInputStream|FISTestDescriptions|Test28 +javasoft.sqe.tests.api.java.io.FISCloseTest1 -WorkDir E:/tmp/ +JCK-114a|api|java_io|BufferedInputStream|BISTestDescriptions|Test1 +javasoft.sqe.tests.api.java.io.BISConstructorTest1 +JCK-114a|api|java_io|BufferedInputStream|BISTestDescriptions|Test2 +javasoft.sqe.tests.api.java.io.BISConstructorTest2 +JCK-114a|api|java_io|BufferedInputStream|BISTestDescriptions|Test3 +javasoft.sqe.tests.api.java.io.BISConstructorTest3 +JCK-114a|api|java_io|BufferedInputStream|BISTestDescriptions|Test4 +javasoft.sqe.tests.api.java.io.BISConstructorTest4 +JCK-114a|api|java_io|BufferedInputStream|BISTestDescriptions|Test8 +javasoft.sqe.tests.api.java.io.BISAvailableTest2 +JCK-114a|api|java_io|BufferedInputStream|BISTestDescriptions|Test12 +javasoft.sqe.tests.api.java.io.BISMarkTest2 +JCK-114a|api|java_io|BufferedInputStream|BISTestDescriptions|Test18 +javasoft.sqe.tests.api.java.io.BISReadTest2 +JCK-114a|api|java_io|BufferedInputStream|BISTestDescriptions|Test19 +javasoft.sqe.tests.api.java.io.BISReadTest3 +JCK-114a|api|java_io|BufferedInputStream|BISTestDescriptions|Test20 +javasoft.sqe.tests.api.java.io.BISReadTest4 +JCK-114a|api|java_io|BufferedInputStream|BISTestDescriptions|Test21 +javasoft.sqe.tests.api.java.io.BISReadArrayTest1 -TestCaseID smallTest +JCK-114a|api|java_io|BufferedInputStream|BISTestDescriptions|Test22 +javasoft.sqe.tests.api.java.io.BISReadArrayTest1 -TestCaseID mediumTest +JCK-114a|api|java_io|BufferedInputStream|BISTestDescriptions|Test23 +javasoft.sqe.tests.api.java.io.BISReadArrayTest1 -TestCaseID largeTest +JCK-114a|api|java_io|BufferedInputStream|BISTestDescriptions|Test24 +javasoft.sqe.tests.api.java.io.BISReadArrayTest2 +JCK-114a|api|java_io|BufferedInputStream|BISTestDescriptions|Test25 +javasoft.sqe.tests.api.java.io.BISReadArrayTest3 +JCK-114a|api|java_io|BufferedInputStream|BISTestDescriptions|Test26 +javasoft.sqe.tests.api.java.io.BISReadArrayTest4 +JCK-114a|api|java_io|BufferedInputStream|BISTestDescriptions|Test27 +javasoft.sqe.tests.api.java.io.BISReadArrayTest5 +JCK-114a|api|java_io|BufferedInputStream|BISTestDescriptions|Test28 +javasoft.sqe.tests.api.java.io.BISReadIndexedTest1 -TestCaseID smallTest +JCK-114a|api|java_io|BufferedInputStream|BISTestDescriptions|Test29 +javasoft.sqe.tests.api.java.io.BISReadIndexedTest1 -TestCaseID mediumTest +JCK-114a|api|java_io|BufferedInputStream|BISTestDescriptions|Test30 +javasoft.sqe.tests.api.java.io.BISReadIndexedTest1 -TestCaseID largeTest +JCK-114a|api|java_io|BufferedInputStream|BISTestDescriptions|Test31 +javasoft.sqe.tests.api.java.io.BISReadIndexedTest2 +JCK-114a|api|java_io|BufferedInputStream|BISTestDescriptions|Test32 +javasoft.sqe.tests.api.java.io.BISReadIndexedTest3 +JCK-114a|api|java_io|BufferedInputStream|BISTestDescriptions|Test33 +javasoft.sqe.tests.api.java.io.BISReadIndexedTest4 +JCK-114a|api|java_io|BufferedInputStream|BISTestDescriptions|Test34 +javasoft.sqe.tests.api.java.io.BISReadIndexedTest5 +JCK-114a|api|java_io|BufferedInputStream|BISTestDescriptions|Test35 +javasoft.sqe.tests.api.java.io.BISReadIndexedTest6 +JCK-114a|api|java_io|BufferedInputStream|BISTestDescriptions|Test36 +javasoft.sqe.tests.api.java.io.BISReadIndexedTest7 +JCK-114a|api|java_io|BufferedInputStream|BISTestDescriptions|Test37 +javasoft.sqe.tests.api.java.io.BISReadIndexedTest8 +JCK-114a|api|java_io|BufferedInputStream|BISTestDescriptions|Test38 +javasoft.sqe.tests.api.java.io.BISmarkSupportedTest1 +JCK-114a|api|java_io|BufferedInputStream|BISTestDescriptions|Test40 +javasoft.sqe.tests.api.java.io.BISresetTest2 +JCK-114a|api|java_io|BufferedInputStream|BISTestDescriptions|Test42 +javasoft.sqe.tests.api.java.io.BISskipTest1 -TestCaseID smallTest +JCK-114a|api|java_io|BufferedInputStream|BISTestDescriptions|Test43 +javasoft.sqe.tests.api.java.io.BISskipTest1 -TestCaseID mediumTest +JCK-114a|api|java_io|BufferedInputStream|BISTestDescriptions|Test44 +javasoft.sqe.tests.api.java.io.BISskipTest1 -TestCaseID largeTest +JCK-114a|api|java_io|BufferedInputStream|BISTestDescriptions|Test45 +javasoft.sqe.tests.api.java.io.BISskipTest2 +JCK-114a|api|java_io|BufferedInputStream|BISTestDescriptions|Test46 +javasoft.sqe.tests.api.java.io.BISskipTest3 +JCK-114a|api|java_io|BufferedInputStream|BISTestDescriptions|Test47 +javasoft.sqe.tests.api.java.io.BISskipTest4 +JCK-114a|api|java_io|ByteArrayInputStream|BAISTestDescriptions|Test1 +javasoft.sqe.tests.api.java.io.BAISConstructorTest1 +JCK-114a|api|java_io|ByteArrayInputStream|BAISTestDescriptions|Test2 +javasoft.sqe.tests.api.java.io.BAISConstructorTest2 +JCK-114a|api|java_io|ByteArrayInputStream|BAISTestDescriptions|Test3 +javasoft.sqe.tests.api.java.io.BAISConstructorTest3 +JCK-114a|api|java_io|ByteArrayInputStream|BAISTestDescriptions|Test4 +javasoft.sqe.tests.api.java.io.BAISConstructorTest4 +JCK-114a|api|java_io|ByteArrayInputStream|BAISTestDescriptions|Test5 +javasoft.sqe.tests.api.java.io.BAISAvailableTest1 -TestCaseID smallTest +JCK-114a|api|java_io|ByteArrayInputStream|BAISTestDescriptions|Test6 +javasoft.sqe.tests.api.java.io.BAISAvailableTest1 -TestCaseID mediumTest +JCK-114a|api|java_io|ByteArrayInputStream|BAISTestDescriptions|Test7 +javasoft.sqe.tests.api.java.io.BAISAvailableTest1 -TestCaseID largeTest +JCK-114a|api|java_io|ByteArrayInputStream|BAISTestDescriptions|Test8 +javasoft.sqe.tests.api.java.io.BAISAvailableTest2 +JCK-114a|api|java_io|ByteArrayInputStream|BAISTestDescriptions|Test9 +javasoft.sqe.tests.api.java.io.BAISReadTest1 -TestCaseID smallTest +JCK-114a|api|java_io|ByteArrayInputStream|BAISTestDescriptions|Test10 +javasoft.sqe.tests.api.java.io.BAISReadTest1 -TestCaseID mediumTest +JCK-114a|api|java_io|ByteArrayInputStream|BAISTestDescriptions|Test11 +javasoft.sqe.tests.api.java.io.BAISReadTest1 -TestCaseID largeTest +JCK-114a|api|java_io|ByteArrayInputStream|BAISTestDescriptions|Test12 +javasoft.sqe.tests.api.java.io.BAISReadTest2 +JCK-114a|api|java_io|ByteArrayInputStream|BAISTestDescriptions|Test13 +javasoft.sqe.tests.api.java.io.BAISReadIndexedTest1 -TestCaseID smallTest +JCK-114a|api|java_io|ByteArrayInputStream|BAISTestDescriptions|Test14 +javasoft.sqe.tests.api.java.io.BAISReadIndexedTest1 -TestCaseID mediumTest +JCK-114a|api|java_io|ByteArrayInputStream|BAISTestDescriptions|Test15 +javasoft.sqe.tests.api.java.io.BAISReadIndexedTest1 -TestCaseID largeTest +JCK-114a|api|java_io|ByteArrayInputStream|BAISTestDescriptions|Test16 +javasoft.sqe.tests.api.java.io.BAISReadIndexedTest2 -TestCaseID largeTest +JCK-114a|api|java_io|ByteArrayInputStream|BAISTestDescriptions|Test17 +javasoft.sqe.tests.api.java.io.BAISReadIndexedTest3 +JCK-114a|api|java_io|ByteArrayInputStream|BAISTestDescriptions|Test18 +javasoft.sqe.tests.api.java.io.BAISresetTest1 -TestCaseID smallTest +JCK-114a|api|java_io|ByteArrayInputStream|BAISTestDescriptions|Test19 +javasoft.sqe.tests.api.java.io.BAISresetTest1 -TestCaseID mediumTest +JCK-114a|api|java_io|ByteArrayInputStream|BAISTestDescriptions|Test20 +javasoft.sqe.tests.api.java.io.BAISresetTest1 -TestCaseID largeTest +JCK-114a|api|java_io|ByteArrayInputStream|BAISTestDescriptions|Test21 +javasoft.sqe.tests.api.java.io.BAISresetTest2 +JCK-114a|api|java_io|ByteArrayInputStream|BAISTestDescriptions|Test22 +javasoft.sqe.tests.api.java.io.BAISskipTest1 -TestCaseID smallTest +JCK-114a|api|java_io|ByteArrayInputStream|BAISTestDescriptions|Test23 +javasoft.sqe.tests.api.java.io.BAISskipTest1 -TestCaseID mediumTest +JCK-114a|api|java_io|ByteArrayInputStream|BAISTestDescriptions|Test24 +javasoft.sqe.tests.api.java.io.BAISskipTest1 -TestCaseID largeTest +JCK-114a|api|java_io|ByteArrayInputStream|BAISTestDescriptions|Test25 +javasoft.sqe.tests.api.java.io.BAISskipTest2 +JCK-114a|api|java_io|ByteArrayInputStream|BAISTestDescriptions|Test26 +javasoft.sqe.tests.api.java.io.BAISskipTest3 +JCK-114a|api|java_io|ByteArrayInputStream|BAISTestDescriptions|Test27 +javasoft.sqe.tests.api.java.io.BAISskipTest4 +JCK-114a|api|java_io|DataInputStream|DISAvailableTest|Test1 +javasoft.sqe.tests.api.java.io.DISAvailableTest -TestCaseID smallTest +JCK-114a|api|java_io|DataInputStream|DISAvailableTest|Test2 +javasoft.sqe.tests.api.java.io.DISAvailableTest -TestCaseID mediumTest +JCK-114a|api|java_io|DataInputStream|DISAvailableTest|Test3 +javasoft.sqe.tests.api.java.io.DISAvailableTest -TestCaseID largeTest +JCK-114a|api|java_io|DataInputStream|DISReadBooleanTest|Test1 +javasoft.sqe.tests.api.java.io.DISReadBooleanTest -TestCaseID Test-1 +JCK-114a|api|java_io|DataInputStream|DISReadBooleanTest|Test2 +javasoft.sqe.tests.api.java.io.DISReadBooleanTest -TestCaseID Test-2 +JCK-114a|api|java_io|DataInputStream|DISReadByteTest|Test1 +javasoft.sqe.tests.api.java.io.DISReadByteTest -TestCaseID Test-1 +JCK-114a|api|java_io|DataInputStream|DISReadByteTest|Test2 +javasoft.sqe.tests.api.java.io.DISReadByteTest -TestCaseID Test-2 +JCK-114a|api|java_io|DataInputStream|DISReadIndexedTest|Test1 +javasoft.sqe.tests.api.java.io.DISReadIndexedTest -TestCaseID smallRead +JCK-114a|api|java_io|DataInputStream|DISReadIndexedTest|Test2 +javasoft.sqe.tests.api.java.io.DISReadIndexedTest -TestCaseID mediumRead +JCK-114a|api|java_io|DataInputStream|DISReadIndexedTest|Test3 +javasoft.sqe.tests.api.java.io.DISReadIndexedTest -TestCaseID largeRead +JCK-114a|api|java_io|DataInputStream|DISReadIntTest|Test1 +javasoft.sqe.tests.api.java.io.DISReadIntTest +JCK-114a|api|java_io|DataInputStream|DISReadTest|Test1 +javasoft.sqe.tests.api.java.io.DISReadTest -TestCaseID smallRead +JCK-114a|api|java_io|DataInputStream|DISReadTest|Test2 +javasoft.sqe.tests.api.java.io.DISReadTest -TestCaseID mediumRead +JCK-114a|api|java_io|DataInputStream|DISReadTest|Test3 +javasoft.sqe.tests.api.java.io.DISReadTest -TestCaseID largeRead +JCK-114a|api|java_io|BAOSTest|Test1 +javasoft.sqe.tests.api.java.io.BAOSTest -test 1 +JCK-114a|api|java_io|BAOSTest|Test2 +javasoft.sqe.tests.api.java.io.BAOSTest -test 2 +JCK-114a|api|java_io|RandomAccessFile|manual|Test11 +javasoft.sqe.tests.api.java.io.RandomAccessFile.SecurityExTests -TestCaseID ALL -WorkDir E:/tmp/ -Test file:/g:/JCK-114a/tests/api/java_io/RandomAccessFile/manual.html +JCK-114a|api|java_io|CharacterEncoding|primarySBCS|Test1 +javasoft.sqe.tests.api.java.io.CharacterEncoding.Test8859_1 -Encoding 8859_1 +JCK-114a|api|java_io|CharacterEncoding|primarySBCS|Test2 +javasoft.sqe.tests.api.java.io.CharacterEncoding.Test8859_2 -Encoding 8859_2 -optional +JCK-114a|api|java_io|CharacterEncoding|primarySBCS|Test3 +javasoft.sqe.tests.api.java.io.CharacterEncoding.Test8859_3 -Encoding 8859_3 -optional +JCK-114a|api|java_io|CharacterEncoding|primarySBCS|Test4 +javasoft.sqe.tests.api.java.io.CharacterEncoding.Test8859_4 -Encoding 8859_4 -optional +JCK-114a|api|java_io|CharacterEncoding|primarySBCS|Test5 +javasoft.sqe.tests.api.java.io.CharacterEncoding.Test8859_5 -Encoding 8859_5 -optional +JCK-114a|api|java_io|CharacterEncoding|primarySBCS|Test6 +javasoft.sqe.tests.api.java.io.CharacterEncoding.Test8859_6 -Encoding 8859_6 -optional +JCK-114a|api|java_io|CharacterEncoding|primarySBCS|Test7 +javasoft.sqe.tests.api.java.io.CharacterEncoding.Test8859_7 -Encoding 8859_7 -optional +JCK-114a|api|java_io|CharacterEncoding|primarySBCS|Test8 +javasoft.sqe.tests.api.java.io.CharacterEncoding.Test8859_8 -Encoding 8859_8 -optional +JCK-114a|api|java_io|CharacterEncoding|primarySBCS|Test9 +javasoft.sqe.tests.api.java.io.CharacterEncoding.Test8859_9 -Encoding 8859_9 -optional +JCK-114a|api|java_io|CharacterEncoding|primarySBCS|Test10 +javasoft.sqe.tests.api.java.io.CharacterEncoding.TestCp1250 -Encoding Cp1250 -optional +JCK-114a|api|java_io|CharacterEncoding|primarySBCS|Test11 +javasoft.sqe.tests.api.java.io.CharacterEncoding.TestCp1251 -Encoding Cp1251 -optional +JCK-114a|api|java_io|CharacterEncoding|primarySBCS|Test12 +javasoft.sqe.tests.api.java.io.CharacterEncoding.TestCp1252 -Encoding Cp1252 -optional +JCK-114a|api|java_io|CharacterEncoding|primarySBCS|Test13 +javasoft.sqe.tests.api.java.io.CharacterEncoding.TestCp1253 -Encoding Cp1253 -optional +JCK-114a|api|java_io|CharacterEncoding|primarySBCS|Test14 +javasoft.sqe.tests.api.java.io.CharacterEncoding.TestCp1254 -Encoding Cp1254 -optional +JCK-114a|api|java_io|CharacterEncoding|primarySBCS|Test15 +javasoft.sqe.tests.api.java.io.CharacterEncoding.TestCp1255 -Encoding Cp1255 -optional +JCK-114a|api|java_io|CharacterEncoding|primarySBCS|Test16 +javasoft.sqe.tests.api.java.io.CharacterEncoding.TestCp1256 -Encoding Cp1256 -optional +JCK-114a|api|java_io|CharacterEncoding|primarySBCS|Test17 +javasoft.sqe.tests.api.java.io.CharacterEncoding.TestCp1257 -Encoding Cp1257 -optional +JCK-114a|api|java_io|CharacterEncoding|primarySBCS|Test18 +javasoft.sqe.tests.api.java.io.CharacterEncoding.TestCp1258 -Encoding Cp1258 -optional +JCK-114a|api|java_io|CharacterEncoding|primarySBCS|Test19 +javasoft.sqe.tests.api.java.io.CharacterEncoding.TestCp437 -Encoding Cp437 -optional +JCK-114a|api|java_io|CharacterEncoding|primarySBCS|Test20 +javasoft.sqe.tests.api.java.io.CharacterEncoding.TestCp737 -Encoding Cp737 -optional +JCK-114a|api|java_io|CharacterEncoding|primarySBCS|Test21 +javasoft.sqe.tests.api.java.io.CharacterEncoding.TestCp775 -Encoding Cp775 -optional +JCK-114a|api|java_io|CharacterEncoding|primarySBCS|Test22 +javasoft.sqe.tests.api.java.io.CharacterEncoding.TestCp850 -Encoding Cp850 -optional +JCK-114a|api|java_io|CharacterEncoding|primarySBCS|Test23 +javasoft.sqe.tests.api.java.io.CharacterEncoding.TestCp852 -Encoding Cp852 -optional +JCK-114a|api|java_io|CharacterEncoding|primarySBCS|Test24 +javasoft.sqe.tests.api.java.io.CharacterEncoding.TestCp855 -Encoding Cp885 -optional +JCK-114a|api|java_io|CharacterEncoding|primarySBCS|Test25 +javasoft.sqe.tests.api.java.io.CharacterEncoding.TestCp857 -Encoding Cp857 -optional +JCK-114a|api|java_io|CharacterEncoding|primarySBCS|Test26 +javasoft.sqe.tests.api.java.io.CharacterEncoding.TestCp860 -Encoding Cp860 -optional +JCK-114a|api|java_io|CharacterEncoding|primarySBCS|Test27 +javasoft.sqe.tests.api.java.io.CharacterEncoding.TestCp861 -Encoding Cp861 -optional +JCK-114a|api|java_io|CharacterEncoding|primarySBCS|Test28 +javasoft.sqe.tests.api.java.io.CharacterEncoding.TestCp862 -Encoding Cp862 -optional +JCK-114a|api|java_io|CharacterEncoding|primarySBCS|Test29 +javasoft.sqe.tests.api.java.io.CharacterEncoding.TestCp863 -Encoding Cp863 -optional +JCK-114a|api|java_io|CharacterEncoding|primarySBCS|Test30 +javasoft.sqe.tests.api.java.io.CharacterEncoding.TestCp864 -Encoding Cp864 -optional +JCK-114a|api|java_io|CharacterEncoding|primarySBCS|Test31 +javasoft.sqe.tests.api.java.io.CharacterEncoding.TestCp865 -Encoding Cp865 -optional +JCK-114a|api|java_io|CharacterEncoding|primarySBCS|Test32 +javasoft.sqe.tests.api.java.io.CharacterEncoding.TestCp866 -Encoding Cp866 -optional +JCK-114a|api|java_io|CharacterEncoding|primarySBCS|Test33 +javasoft.sqe.tests.api.java.io.CharacterEncoding.TestCp869 -Encoding Cp869 -optional +JCK-114a|api|java_io|CharacterEncoding|primarySBCS|Test35 +javasoft.sqe.tests.api.java.io.CharacterEncoding.TestMacCentralEurope -Encoding MacCentralEurope -optional +JCK-114a|api|java_io|CharacterEncoding|primarySBCS|Test36 +javasoft.sqe.tests.api.java.io.CharacterEncoding.TestMacCroatian -Encoding MacCroatian -optional +JCK-114a|api|java_io|CharacterEncoding|primarySBCS|Test37 +javasoft.sqe.tests.api.java.io.CharacterEncoding.TestMacCyrillic -Encoding MacCyrillic -optional +JCK-114a|api|java_io|CharacterEncoding|primarySBCS|Test38 +javasoft.sqe.tests.api.java.io.CharacterEncoding.TestMacGreek -Encoding MacGreek -optional +JCK-114a|api|java_io|CharacterEncoding|primarySBCS|Test39 +javasoft.sqe.tests.api.java.io.CharacterEncoding.TestMacIceland -Encoding MacIceland -optional +JCK-114a|api|java_io|CharacterEncoding|primarySBCS|Test40 +javasoft.sqe.tests.api.java.io.CharacterEncoding.TestMacRoman -Encoding MacRoman -optional +JCK-114a|api|java_io|CharacterEncoding|primarySBCS|Test41 +javasoft.sqe.tests.api.java.io.CharacterEncoding.TestMacRomania -Encoding MacRomania -optional +JCK-114a|api|java_io|CharacterEncoding|primarySBCS|Test42 +javasoft.sqe.tests.api.java.io.CharacterEncoding.TestMacThai -Encoding MacThai -optional +JCK-114a|api|java_io|CharacterEncoding|primarySBCS|Test43 +javasoft.sqe.tests.api.java.io.CharacterEncoding.TestMacTurkish -Encoding MacTurkish -optional +JCK-114a|api|java_io|CharacterEncoding|primarySBCS|Test44 +javasoft.sqe.tests.api.java.io.CharacterEncoding.TestMacUkraine -Encoding MacUkraine -optional +JCK-114a|api|java_io|CharacterEncoding|secondarySBCS|Test1 +javasoft.sqe.tests.api.java.io.CharacterEncoding.TestCp037 -Encoding Cp037 -optional +JCK-114a|api|java_io|CharacterEncoding|secondarySBCS|Test2 +javasoft.sqe.tests.api.java.io.CharacterEncoding.TestCp1006 -Encoding Cp1006 -optional +JCK-114a|api|java_io|CharacterEncoding|secondarySBCS|Test3 +javasoft.sqe.tests.api.java.io.CharacterEncoding.TestCp1025 -Encoding Cp1025 -optional +JCK-114a|api|java_io|CharacterEncoding|secondarySBCS|Test4 +javasoft.sqe.tests.api.java.io.CharacterEncoding.TestCp1026 -Encoding Cp1026 -optional +JCK-114a|api|java_io|CharacterEncoding|secondarySBCS|Test5 +javasoft.sqe.tests.api.java.io.CharacterEncoding.TestCp1046 -Encoding Cp1046 -optional +JCK-114a|api|java_io|CharacterEncoding|secondarySBCS|Test6 +javasoft.sqe.tests.api.java.io.CharacterEncoding.TestCp1097 -Encoding Cp1097 -optional +JCK-114a|api|java_io|CharacterEncoding|secondarySBCS|Test7 +javasoft.sqe.tests.api.java.io.CharacterEncoding.TestCp1098 -Encoding Cp1098 -optional +JCK-114a|api|java_io|CharacterEncoding|secondarySBCS|Test8 +javasoft.sqe.tests.api.java.io.CharacterEncoding.TestCp1112 -Encoding Cp1112 -optional +JCK-114a|api|java_io|CharacterEncoding|secondarySBCS|Test9 +javasoft.sqe.tests.api.java.io.CharacterEncoding.TestCp1122 -Encoding Cp1122 -optional +JCK-114a|api|java_io|CharacterEncoding|secondarySBCS|Test10 +javasoft.sqe.tests.api.java.io.CharacterEncoding.TestCp1123 -Encoding Cp1123 -optional +JCK-114a|api|java_io|CharacterEncoding|secondarySBCS|Test11 +javasoft.sqe.tests.api.java.io.CharacterEncoding.TestCp1124 -Encoding Cp1124 -optional +JCK-114a|api|java_io|CharacterEncoding|secondarySBCS|Test12 +javasoft.sqe.tests.api.java.io.CharacterEncoding.TestCp273 -Encoding Cp273 -optional +JCK-114a|api|java_io|CharacterEncoding|secondarySBCS|Test13 +javasoft.sqe.tests.api.java.io.CharacterEncoding.TestCp277 -Encoding Cp277 -optional +JCK-114a|api|java_io|CharacterEncoding|secondarySBCS|Test14 +javasoft.sqe.tests.api.java.io.CharacterEncoding.TestCp278 -Encoding Cp278 -optional +JCK-114a|api|java_io|CharacterEncoding|secondarySBCS|Test15 +javasoft.sqe.tests.api.java.io.CharacterEncoding.TestCp280 -Encoding Cp280 -optional +JCK-114a|api|java_io|CharacterEncoding|secondarySBCS|Test16 +javasoft.sqe.tests.api.java.io.CharacterEncoding.TestCp284 -Encoding Cp284 -optional +JCK-114a|api|java_io|CharacterEncoding|secondarySBCS|Test17 +javasoft.sqe.tests.api.java.io.CharacterEncoding.TestCp285 -Encoding Cp285 -optional +JCK-114a|api|java_io|CharacterEncoding|secondarySBCS|Test18 +javasoft.sqe.tests.api.java.io.CharacterEncoding.TestCp297 -Encoding Cp297 -optional +JCK-114a|api|java_io|CharacterEncoding|secondarySBCS|Test19 +javasoft.sqe.tests.api.java.io.CharacterEncoding.TestCp420 -Encoding Cp420 -optional +JCK-114a|api|java_io|CharacterEncoding|secondarySBCS|Test20 +javasoft.sqe.tests.api.java.io.CharacterEncoding.TestCp424 -Encoding Cp424 -optional +JCK-114a|api|java_io|CharacterEncoding|secondarySBCS|Test21 +javasoft.sqe.tests.api.java.io.CharacterEncoding.TestCp500 -Encoding Cp500 -optional +JCK-114a|api|java_io|CharacterEncoding|secondarySBCS|Test22 +javasoft.sqe.tests.api.java.io.CharacterEncoding.TestCp856 -Encoding Cp856 -optional +JCK-114a|api|java_io|CharacterEncoding|secondarySBCS|Test23 +javasoft.sqe.tests.api.java.io.CharacterEncoding.TestCp868 -Encoding Cp868 -optional +JCK-114a|api|java_io|CharacterEncoding|secondarySBCS|Test24 +javasoft.sqe.tests.api.java.io.CharacterEncoding.TestCp870 -Encoding Cp870 -optional +JCK-114a|api|java_io|CharacterEncoding|secondarySBCS|Test25 +javasoft.sqe.tests.api.java.io.CharacterEncoding.TestCp871 -Encoding Cp871 -optional +JCK-114a|api|java_io|CharacterEncoding|secondarySBCS|Test26 +javasoft.sqe.tests.api.java.io.CharacterEncoding.TestCp875 -Encoding Cp875 -optional +JCK-114a|api|java_io|CharacterEncoding|secondarySBCS|Test27 +javasoft.sqe.tests.api.java.io.CharacterEncoding.TestCp918 -Encoding Cp918 -optional +JCK-114a|api|java_io|CharacterEncoding|secondarySBCS|Test28 +javasoft.sqe.tests.api.java.io.CharacterEncoding.TestCp921 -Encoding Cp921 -optional +JCK-114a|api|java_io|CharacterEncoding|secondarySBCS|Test29 +javasoft.sqe.tests.api.java.io.CharacterEncoding.TestCp922 -Encoding Cp922 -optional +JCK-114a|api|java_io|mbCharEncoding|index|Test1 +javasoft.sqe.tests.api.java.io.CharacterEncoding.TestBig5 -Encoding Big5 -optional +JCK-114a|api|java_io|mbCharEncoding|index|Test5 +javasoft.sqe.tests.api.java.io.CharacterEncoding.TestEUCJIS -Encoding EUCJIS -optional +JCK-114a|api|java_io|Serialization|Externalizable|wrExt|Test1 +javasoft.sqe.tests.api.java.io.Serialization.Externalizable.WrExtTests -TestCaseID writeExternal0001 +JCK-114a|api|java_io|Serialization|Externalizable|wrExt|Test2 +javasoft.sqe.tests.api.java.io.Serialization.Externalizable.WrExtTests -TestCaseID writeExternal0002 +JCK-114a|api|java_io|Serialization|Externalizable|rdExt|Test1 +javasoft.sqe.tests.api.java.io.Serialization.Externalizable.RdExtTests -TestCaseID readExternal0001 +JCK-114a|api|java_io|Serialization|Externalizable|rdExt|Test2 +javasoft.sqe.tests.api.java.io.Serialization.Externalizable.RdExtTests -TestCaseID readExternal0002 +JCK-114a|api|java_io|Serialization|ObjSerExceptions|InvalidClassException|index|Test1 +javasoft.sqe.tests.api.java.io.Serialization.ObjSerExceptions.InvalidClassException.CtorTests -TestCaseID InvalidClassException0001 +JCK-114a|api|java_io|Serialization|ObjSerExceptions|InvalidClassException|index|Test2 +javasoft.sqe.tests.api.java.io.Serialization.ObjSerExceptions.InvalidClassException.CtorTests -TestCaseID InvalidClassException0002 +JCK-114a|api|java_io|Serialization|ObjSerExceptions|InvalidClassException|index|Test3 +javasoft.sqe.tests.api.java.io.Serialization.ObjSerExceptions.InvalidClassException.CtorTests -TestCaseID InvalidClassException0003 +JCK-114a|api|java_io|Serialization|ObjSerExceptions|InvalidClassException|index|Test4 +javasoft.sqe.tests.api.java.io.Serialization.ObjSerExceptions.InvalidClassException.CtorTests -TestCaseID InvalidClassException0004 +JCK-114a|api|java_io|Serialization|ObjSerExceptions|InvalidClassException|index|Test5 +javasoft.sqe.tests.api.java.io.Serialization.ObjSerExceptions.InvalidClassException.CtorTests -TestCaseID InvalidClassException0005 +JCK-114a|api|java_io|Serialization|ObjSerExceptions|InvalidClassException|index|Test6 +javasoft.sqe.tests.api.java.io.Serialization.ObjSerExceptions.InvalidClassException.CtorTests -TestCaseID InvalidClassException0006 +JCK-114a|api|java_io|Serialization|ObjSerExceptions|InvalidClassException|index|Test7 +javasoft.sqe.tests.api.java.io.Serialization.ObjSerExceptions.InvalidClassException.GetMsgTests -TestCaseID GetMsg0001 +JCK-114a|api|java_io|Serialization|ObjSerExceptions|InvalidClassException|index|Test8 +javasoft.sqe.tests.api.java.io.Serialization.ObjSerExceptions.InvalidClassException.GetMsgTests -TestCaseID GetMsg0002 +JCK-114a|api|java_io|Serialization|ObjSerExceptions|InvalidObjectException|index|Test1 +javasoft.sqe.tests.api.java.io.Serialization.ObjSerExceptions.InvalidObjectException.CtorTests -TestCaseID InvalidObjectException0001 +JCK-114a|api|java_io|Serialization|ObjSerExceptions|InvalidObjectException|index|Test2 +javasoft.sqe.tests.api.java.io.Serialization.ObjSerExceptions.InvalidObjectException.CtorTests -TestCaseID InvalidObjectException0002 +JCK-114a|api|java_io|Serialization|ObjSerExceptions|NotActiveException|index|Test1 +javasoft.sqe.tests.api.java.io.Serialization.ObjSerExceptions.NotActiveException.CtorTests -TestCaseID NotActiveException0001 +JCK-114a|api|java_io|Serialization|ObjSerExceptions|NotActiveException|index|Test2 +javasoft.sqe.tests.api.java.io.Serialization.ObjSerExceptions.NotActiveException.CtorTests -TestCaseID NotActiveException0002 +JCK-114a|api|java_io|Serialization|ObjSerExceptions|NotActiveException|index|Test3 +javasoft.sqe.tests.api.java.io.Serialization.ObjSerExceptions.NotActiveException.CtorTests -TestCaseID NotActiveException0003 +JCK-114a|api|java_io|Serialization|ObjSerExceptions|NotSerializableException|index|Test1 +javasoft.sqe.tests.api.java.io.Serialization.ObjSerExceptions.NotSerializableException.CtorTests -TestCaseID NotSerializableException0001 +JCK-114a|api|java_io|Serialization|ObjSerExceptions|NotSerializableException|index|Test2 +javasoft.sqe.tests.api.java.io.Serialization.ObjSerExceptions.NotSerializableException.CtorTests -TestCaseID NotSerializableException0002 +JCK-114a|api|java_io|Serialization|ObjSerExceptions|NotSerializableException|index|Test3 +javasoft.sqe.tests.api.java.io.Serialization.ObjSerExceptions.NotSerializableException.CtorTests -TestCaseID NotSerializableException0003 +JCK-114a|api|java_io|Serialization|ObjSerExceptions|StreamCorruptedException|index|Test1 +javasoft.sqe.tests.api.java.io.Serialization.ObjSerExceptions.StreamCorruptedException.CtorTests -TestCaseID StreamCorruptedException0001 +JCK-114a|api|java_io|Serialization|ObjSerExceptions|StreamCorruptedException|index|Test2 +javasoft.sqe.tests.api.java.io.Serialization.ObjSerExceptions.StreamCorruptedException.CtorTests -TestCaseID StreamCorruptedException0002 +JCK-114a|api|java_io|Serialization|ObjSerExceptions|StreamCorruptedException|index|Test3 +javasoft.sqe.tests.api.java.io.Serialization.ObjSerExceptions.StreamCorruptedException.CtorTests -TestCaseID StreamCorruptedException0003 +JCK-114a|api|java_io|Serialization|ObjSerExceptions|WriteAbortedException|index|Test1 +javasoft.sqe.tests.api.java.io.Serialization.ObjSerExceptions.WriteAbortedException.CtorTests -TestCaseID WriteAbortedException0001 +JCK-114a|api|java_io|Serialization|ObjSerExceptions|WriteAbortedException|index|Test2 +javasoft.sqe.tests.api.java.io.Serialization.ObjSerExceptions.WriteAbortedException.CtorTests -TestCaseID WriteAbortedException0002 +JCK-114a|api|java_io|Serialization|ObjSerExceptions|WriteAbortedException|index|Test3 +javasoft.sqe.tests.api.java.io.Serialization.ObjSerExceptions.WriteAbortedException.CtorTests -TestCaseID WriteAbortedException0003 +JCK-114a|api|java_io|Serialization|ObjSerExceptions|WriteAbortedException|index|Test4 +javasoft.sqe.tests.api.java.io.Serialization.ObjSerExceptions.WriteAbortedException.CtorTests -TestCaseID WriteAbortedException0004 +JCK-114a|api|java_io|Serialization|ObjSerExceptions|WriteAbortedException|index|Test5 +javasoft.sqe.tests.api.java.io.Serialization.ObjSerExceptions.WriteAbortedException.GetMsgTests -TestCaseID GetMsg0001 +JCK-114a|api|java_io|Serialization|ObjSerExceptions|WriteAbortedException|index|Test6 +javasoft.sqe.tests.api.java.io.Serialization.ObjSerExceptions.WriteAbortedException.GetMsgTests -TestCaseID GetMsg0002 +JCK-114a|api|java_io|Serialization|ObjectOutputStream|ctor|Test1 +javasoft.sqe.tests.api.java.io.Serialization.ObjectOutputStream.CtorTests -TestCaseID ObjectOutputStream0001 +JCK-114a|api|java_io|Serialization|ObjectOutputStream|ctor|Test2 +javasoft.sqe.tests.api.java.io.Serialization.ObjectOutputStream.CtorTests -TestCaseID ObjectOutputStream0002 +JCK-114a|api|java_io|Serialization|ObjectOutputStream|func|Test1 +javasoft.sqe.tests.api.java.io.Serialization.ObjectOutputStream.PrimitivesTest +JCK-114a|api|java_io|Serialization|ObjectOutputStream|func|Test2 +javasoft.sqe.tests.api.java.io.Serialization.ObjectOutputStream.ArrayArrayTest +JCK-114a|api|java_io|Serialization|ObjectOutputStream|func|Test3 +javasoft.sqe.tests.api.java.io.Serialization.ObjectOutputStream.ArraysTest +JCK-114a|api|java_io|Serialization|ObjectOutputStream|func|Test4 +javasoft.sqe.tests.api.java.io.Serialization.ObjectOutputStream.BlockDataTest +JCK-114a|api|java_io|Serialization|ObjectOutputStream|func|Test5 +javasoft.sqe.tests.api.java.io.Serialization.ObjectOutputStream.ExternTest +JCK-114a|api|java_io|Serialization|ObjectOutputStream|func|Test6 +javasoft.sqe.tests.api.java.io.Serialization.ObjectOutputStream.MissingWrRdTest +JCK-114a|api|java_io|Serialization|ObjectOutputStream|func|Test7 +javasoft.sqe.tests.api.java.io.Serialization.ObjectOutputStream.NotSerialTest +JCK-114a|api|java_io|Serialization|ObjectOutputStream|func|Test8 +javasoft.sqe.tests.api.java.io.Serialization.ObjectOutputStream.OutputExceptionTest +JCK-114a|api|java_io|Serialization|ObjectOutputStream|func|Test9 +javasoft.sqe.tests.api.java.io.Serialization.ObjectOutputStream.ResetTest +JCK-114a|api|java_io|Serialization|ObjectOutputStream|func|Test10 +javasoft.sqe.tests.api.java.io.Serialization.ObjectOutputStream.StringTest +JCK-114a|api|java_io|Serialization|ObjectOutputStream|func|Test11 +javasoft.sqe.tests.api.java.io.Serialization.ObjectOutputStream.StringBufferTest +JCK-114a|api|java_io|Serialization|ObjectOutputStream|func|Test12 +javasoft.sqe.tests.api.java.io.Serialization.ObjectOutputStream.ClassesTest +JCK-114a|api|java_io|Serialization|ObjectOutputStream|func|Test13 +javasoft.sqe.tests.api.java.io.Serialization.ObjectOutputStream.ExceptTest +JCK-114a|api|java_io|Serialization|ObjectOutputStream|func|Test14 +javasoft.sqe.tests.api.java.io.Serialization.ObjectOutputStream.SubclassTest +JCK-114a|api|java_io|Serialization|ObjectOutputStream|func|Test15 +javasoft.sqe.tests.api.java.io.Serialization.ObjectOutputStream.VectorTest +JCK-114a|api|java_io|Serialization|ObjectOutputStream|wrobj|Test1 +javasoft.sqe.tests.api.java.io.Serialization.ObjectOutputStream.WrObjTests -TestCaseID WrObj0001 +JCK-114a|api|java_io|Serialization|ObjectOutputStream|wrobj|Test2 +javasoft.sqe.tests.api.java.io.Serialization.ObjectOutputStream.WrObjTests -TestCaseID WrObj0002 +JCK-114a|api|java_io|Serialization|ObjectOutputStream|wrobj|Test3 +javasoft.sqe.tests.api.java.io.Serialization.ObjectOutputStream.WrObjTests -TestCaseID WrObj0003 +JCK-114a|api|java_io|Serialization|ObjectOutputStream|defwrobj|Test1 +javasoft.sqe.tests.api.java.io.Serialization.ObjectOutputStream.DefWrObjTests -TestCaseID DefWrObj0001 +JCK-114a|api|java_io|Serialization|ObjectOutputStream|write|Test1 +javasoft.sqe.tests.api.java.io.Serialization.ObjectOutputStream.WriteTests -TestCaseID Write0001 +JCK-114a|api|java_io|Serialization|ObjectOutputStream|write|Test2 +javasoft.sqe.tests.api.java.io.Serialization.ObjectOutputStream.WriteTests -TestCaseID Write0002 +JCK-114a|api|java_io|Serialization|ObjectOutputStream|write|Test3 +javasoft.sqe.tests.api.java.io.Serialization.ObjectOutputStream.WriteTests -TestCaseID Write0003 +JCK-114a|api|java_io|Serialization|ObjectOutputStream|write|Test4 +javasoft.sqe.tests.api.java.io.Serialization.ObjectOutputStream.WriteTests -TestCaseID Write0004 +JCK-114a|api|java_io|Serialization|ObjectOutputStream|write|Test5 +javasoft.sqe.tests.api.java.io.Serialization.ObjectOutputStream.WriteTests -TestCaseID Write0005 +JCK-114a|api|java_io|Serialization|ObjectOutputStream|write|Test6 +javasoft.sqe.tests.api.java.io.Serialization.ObjectOutputStream.WriteTests -TestCaseID Write0006 +JCK-114a|api|java_io|Serialization|ObjectOutputStream|write|Test7 +javasoft.sqe.tests.api.java.io.Serialization.ObjectOutputStream.WriteTests -TestCaseID Write0007 +JCK-114a|api|java_io|Serialization|ObjectOutputStream|write|Test8 +javasoft.sqe.tests.api.java.io.Serialization.ObjectOutputStream.WriteTests -TestCaseID Write0008 +JCK-114a|api|java_io|Serialization|ObjectOutputStream|write|Test9 +javasoft.sqe.tests.api.java.io.Serialization.ObjectOutputStream.WriteTests -TestCaseID Write0009 +JCK-114a|api|java_io|Serialization|ObjectOutputStream|write|Test10 +javasoft.sqe.tests.api.java.io.Serialization.ObjectOutputStream.WriteTests -TestCaseID Write0010 +JCK-114a|api|java_io|Serialization|ObjectOutputStream|write|Test11 +javasoft.sqe.tests.api.java.io.Serialization.ObjectOutputStream.WriteTests -TestCaseID Write0011 +JCK-114a|api|java_io|Serialization|ObjectOutputStream|write|Test12 +javasoft.sqe.tests.api.java.io.Serialization.ObjectOutputStream.WriteTests -TestCaseID Write0012 +JCK-114a|api|java_io|Serialization|ObjectOutputStream|write|Test13 +javasoft.sqe.tests.api.java.io.Serialization.ObjectOutputStream.WriteTests -TestCaseID Write0013 +JCK-114a|api|java_io|Serialization|ObjectOutputStream|write|Test14 +javasoft.sqe.tests.api.java.io.Serialization.ObjectOutputStream.WriteTests -TestCaseID Write0014 +JCK-114a|api|java_io|Serialization|ObjectOutputStream|writeboolean|Test1 +javasoft.sqe.tests.api.java.io.Serialization.ObjectOutputStream.WriteBooleanTests -TestCaseID WriteBoolean0001 +JCK-114a|api|java_io|Serialization|ObjectOutputStream|writeboolean|Test2 +javasoft.sqe.tests.api.java.io.Serialization.ObjectOutputStream.WriteBooleanTests -TestCaseID WriteBoolean0002 +JCK-114a|api|java_io|Serialization|ObjectOutputStream|writebyte|Test1 +javasoft.sqe.tests.api.java.io.Serialization.ObjectOutputStream.WriteByteTests -TestCaseID WriteByte0001 +JCK-114a|api|java_io|Serialization|ObjectOutputStream|writebyte|Test2 +javasoft.sqe.tests.api.java.io.Serialization.ObjectOutputStream.WriteByteTests -TestCaseID WriteByte0002 +JCK-114a|api|java_io|Serialization|ObjectOutputStream|writebyte|Test3 +javasoft.sqe.tests.api.java.io.Serialization.ObjectOutputStream.WriteByteTests -TestCaseID WriteByte0003 +JCK-114a|api|java_io|Serialization|ObjectOutputStream|writebyte|Test4 +javasoft.sqe.tests.api.java.io.Serialization.ObjectOutputStream.WriteByteTests -TestCaseID WriteByte0004 +JCK-114a|api|java_io|Serialization|ObjectOutputStream|writebytes|Test1 +javasoft.sqe.tests.api.java.io.Serialization.ObjectOutputStream.WriteBytesTests -TestCaseID WriteBytes0001 +JCK-114a|api|java_io|Serialization|ObjectOutputStream|writebytes|Test2 +javasoft.sqe.tests.api.java.io.Serialization.ObjectOutputStream.WriteBytesTests -TestCaseID WriteBytes0002 +JCK-114a|api|java_io|Serialization|ObjectOutputStream|writechar|Test1 +javasoft.sqe.tests.api.java.io.Serialization.ObjectOutputStream.WriteCharTests -TestCaseID WriteChar0001 +JCK-114a|api|java_io|Serialization|ObjectOutputStream|writechar|Test2 +javasoft.sqe.tests.api.java.io.Serialization.ObjectOutputStream.WriteCharTests -TestCaseID WriteChar0002 +JCK-114a|api|java_io|Serialization|ObjectOutputStream|writechar|Test3 +javasoft.sqe.tests.api.java.io.Serialization.ObjectOutputStream.WriteCharTests -TestCaseID WriteChar0003 +JCK-114a|api|java_io|Serialization|ObjectOutputStream|writechar|Test4 +javasoft.sqe.tests.api.java.io.Serialization.ObjectOutputStream.WriteCharTests -TestCaseID WriteChar0004 +JCK-114a|api|java_io|Serialization|ObjectOutputStream|writechars|Test1 +javasoft.sqe.tests.api.java.io.Serialization.ObjectOutputStream.WriteCharsTests -TestCaseID WriteChars0001 +JCK-114a|api|java_io|Serialization|ObjectOutputStream|writechars|Test2 +javasoft.sqe.tests.api.java.io.Serialization.ObjectOutputStream.WriteCharsTests -TestCaseID WriteChars0002 +JCK-114a|api|java_io|Serialization|ObjectOutputStream|writedouble|Test1 +javasoft.sqe.tests.api.java.io.Serialization.ObjectOutputStream.WriteDoubleTests -TestCaseID WriteDouble0001 +JCK-114a|api|java_io|Serialization|ObjectOutputStream|writedouble|Test2 +javasoft.sqe.tests.api.java.io.Serialization.ObjectOutputStream.WriteDoubleTests -TestCaseID WriteDouble0002 +JCK-114a|api|java_io|Serialization|ObjectOutputStream|writedouble|Test3 +javasoft.sqe.tests.api.java.io.Serialization.ObjectOutputStream.WriteDoubleTests -TestCaseID WriteDouble0003 +JCK-114a|api|java_io|Serialization|ObjectOutputStream|writedouble|Test4 +javasoft.sqe.tests.api.java.io.Serialization.ObjectOutputStream.WriteDoubleTests -TestCaseID WriteDouble0004 +JCK-114a|api|java_io|Serialization|ObjectOutputStream|writedouble|Test5 +javasoft.sqe.tests.api.java.io.Serialization.ObjectOutputStream.WriteDoubleTests -TestCaseID WriteDouble0005 +JCK-114a|api|java_io|Serialization|ObjectOutputStream|writedouble|Test6 +javasoft.sqe.tests.api.java.io.Serialization.ObjectOutputStream.WriteDoubleTests -TestCaseID WriteDouble0006 +JCK-114a|api|java_io|Serialization|ObjectOutputStream|writedouble|Test7 +javasoft.sqe.tests.api.java.io.Serialization.ObjectOutputStream.WriteDoubleTests -TestCaseID WriteDouble0007 +JCK-114a|api|java_io|Serialization|ObjectOutputStream|writefloat|Test1 +javasoft.sqe.tests.api.java.io.Serialization.ObjectOutputStream.WriteFloatTests -TestCaseID WriteFloat0001 +JCK-114a|api|java_io|Serialization|ObjectOutputStream|writefloat|Test2 +javasoft.sqe.tests.api.java.io.Serialization.ObjectOutputStream.WriteFloatTests -TestCaseID WriteFloat0002 +JCK-114a|api|java_io|Serialization|ObjectOutputStream|writefloat|Test3 +javasoft.sqe.tests.api.java.io.Serialization.ObjectOutputStream.WriteFloatTests -TestCaseID WriteFloat0003 +JCK-114a|api|java_io|Serialization|ObjectOutputStream|writefloat|Test4 +javasoft.sqe.tests.api.java.io.Serialization.ObjectOutputStream.WriteFloatTests -TestCaseID WriteFloat0004 +JCK-114a|api|java_io|Serialization|ObjectOutputStream|writefloat|Test5 +javasoft.sqe.tests.api.java.io.Serialization.ObjectOutputStream.WriteFloatTests -TestCaseID WriteFloat0005 +JCK-114a|api|java_io|Serialization|ObjectOutputStream|writefloat|Test6 +javasoft.sqe.tests.api.java.io.Serialization.ObjectOutputStream.WriteFloatTests -TestCaseID WriteFloat0006 +JCK-114a|api|java_io|Serialization|ObjectOutputStream|writefloat|Test7 +javasoft.sqe.tests.api.java.io.Serialization.ObjectOutputStream.WriteFloatTests -TestCaseID WriteFloat0007 +JCK-114a|api|java_io|Serialization|ObjectOutputStream|writeint|Test1 +javasoft.sqe.tests.api.java.io.Serialization.ObjectOutputStream.WriteIntTests -TestCaseID WriteInt0001 +JCK-114a|api|java_io|Serialization|ObjectOutputStream|writeint|Test2 +javasoft.sqe.tests.api.java.io.Serialization.ObjectOutputStream.WriteIntTests -TestCaseID WriteInt0002 +JCK-114a|api|java_io|Serialization|ObjectOutputStream|writeint|Test3 +javasoft.sqe.tests.api.java.io.Serialization.ObjectOutputStream.WriteIntTests -TestCaseID WriteInt0003 +JCK-114a|api|java_io|Serialization|ObjectOutputStream|writeint|Test4 +javasoft.sqe.tests.api.java.io.Serialization.ObjectOutputStream.WriteIntTests -TestCaseID WriteInt0004 +JCK-114a|api|java_io|Serialization|ObjectOutputStream|writelong|Test1 +javasoft.sqe.tests.api.java.io.Serialization.ObjectOutputStream.WriteLongTests -TestCaseID WriteLong0001 +JCK-114a|api|java_io|Serialization|ObjectOutputStream|writelong|Test2 +javasoft.sqe.tests.api.java.io.Serialization.ObjectOutputStream.WriteLongTests -TestCaseID WriteLong0002 +JCK-114a|api|java_io|Serialization|ObjectOutputStream|writelong|Test3 +javasoft.sqe.tests.api.java.io.Serialization.ObjectOutputStream.WriteLongTests -TestCaseID WriteLong0003 +JCK-114a|api|java_io|Serialization|ObjectOutputStream|writelong|Test4 +javasoft.sqe.tests.api.java.io.Serialization.ObjectOutputStream.WriteLongTests -TestCaseID WriteLong0004 +JCK-114a|api|java_io|Serialization|ObjectOutputStream|writeshort|Test1 +javasoft.sqe.tests.api.java.io.Serialization.ObjectOutputStream.WriteShortTests -TestCaseID WriteShort0001 +JCK-114a|api|java_io|Serialization|ObjectOutputStream|writeshort|Test2 +javasoft.sqe.tests.api.java.io.Serialization.ObjectOutputStream.WriteShortTests -TestCaseID WriteShort0002 +JCK-114a|api|java_io|Serialization|ObjectOutputStream|writeshort|Test3 +javasoft.sqe.tests.api.java.io.Serialization.ObjectOutputStream.WriteShortTests -TestCaseID WriteShort0003 +JCK-114a|api|java_io|Serialization|ObjectOutputStream|writeshort|Test4 +javasoft.sqe.tests.api.java.io.Serialization.ObjectOutputStream.WriteShortTests -TestCaseID WriteShort0004 +JCK-114a|api|java_io|Serialization|ObjectOutputStream|fldrcl|Test1 +javasoft.sqe.tests.api.java.io.Serialization.ObjectOutputStream.FlushDrainCloseTests -TestCaseID Flush0001 +JCK-114a|api|java_io|Serialization|ObjectOutputStream|fldrcl|Test2 +javasoft.sqe.tests.api.java.io.Serialization.ObjectOutputStream.FlushDrainCloseTests -TestCaseID Drain0001 +JCK-114a|api|java_io|Serialization|ObjectOutputStream|fldrcl|Test3 +javasoft.sqe.tests.api.java.io.Serialization.ObjectOutputStream.FlushDrainCloseTests -TestCaseID Close0001 +JCK-114a|api|java_io|Serialization|ObjectInputStream|ctor|Test1 +javasoft.sqe.tests.api.java.io.Serialization.ObjectInputStream.CtorTests -TestCaseID ObjectInputStream0001 +JCK-114a|api|java_io|Serialization|ObjectInputStream|ctor|Test2 +javasoft.sqe.tests.api.java.io.Serialization.ObjectInputStream.CtorTests -TestCaseID ObjectInputStream0002 +JCK-114a|api|java_io|Serialization|ObjectInputStream|ctor|Test3 +javasoft.sqe.tests.api.java.io.Serialization.ObjectInputStream.CtorTests -TestCaseID ObjectInputStream0003 +JCK-114a|api|java_io|Serialization|ObjectInputStream|rdobj|Test1 +javasoft.sqe.tests.api.java.io.Serialization.ObjectInputStream.RdObjTests -TestCaseID RdObj0001 +JCK-114a|api|java_io|Serialization|ObjectInputStream|rdobj|Test2 +javasoft.sqe.tests.api.java.io.Serialization.ObjectInputStream.RdObjTests -TestCaseID RdObj0002 +JCK-114a|api|java_io|Serialization|ObjectInputStream|rdobj|Test3 +javasoft.sqe.tests.api.java.io.Serialization.ObjectInputStream.RdObjTests -TestCaseID RdObj0003 +JCK-114a|api|java_io|Serialization|ObjectInputStream|read|Test1 +javasoft.sqe.tests.api.java.io.Serialization.ObjectInputStream.ReadTests -TestCaseID Read0001 +JCK-114a|api|java_io|Serialization|ObjectInputStream|read|Test2 +javasoft.sqe.tests.api.java.io.Serialization.ObjectInputStream.ReadTests -TestCaseID Read0002 +JCK-114a|api|java_io|Serialization|ObjectInputStream|read|Test3 +javasoft.sqe.tests.api.java.io.Serialization.ObjectInputStream.ReadTests -TestCaseID Read0003 +JCK-114a|api|java_io|Serialization|ObjectInputStream|read|Test4 +javasoft.sqe.tests.api.java.io.Serialization.ObjectInputStream.ReadTests -TestCaseID Read0004 +JCK-114a|api|java_io|Serialization|ObjectInputStream|read|Test5 +javasoft.sqe.tests.api.java.io.Serialization.ObjectInputStream.ReadTests -TestCaseID Read0005 +JCK-114a|api|java_io|Serialization|ObjectInputStream|read|Test6 +javasoft.sqe.tests.api.java.io.Serialization.ObjectInputStream.ReadTests -TestCaseID Read0006 +JCK-114a|api|java_io|Serialization|ObjectInputStream|read|Test7 +javasoft.sqe.tests.api.java.io.Serialization.ObjectInputStream.ReadTests -TestCaseID Read0007 +JCK-114a|api|java_io|Serialization|ObjectInputStream|read|Test8 +javasoft.sqe.tests.api.java.io.Serialization.ObjectInputStream.ReadTests -TestCaseID Read0008 +JCK-114a|api|java_io|Serialization|ObjectInputStream|read|Test9 +javasoft.sqe.tests.api.java.io.Serialization.ObjectInputStream.ReadTests -TestCaseID Read0009 +JCK-114a|api|java_io|Serialization|ObjectInputStream|read|Test10 +javasoft.sqe.tests.api.java.io.Serialization.ObjectInputStream.ReadTests -TestCaseID Read0010 +JCK-114a|api|java_io|Serialization|ObjectInputStream|read|Test11 +javasoft.sqe.tests.api.java.io.Serialization.ObjectInputStream.ReadTests -TestCaseID Read0011 +JCK-114a|api|java_io|Serialization|ObjectInputStream|read|Test12 +javasoft.sqe.tests.api.java.io.Serialization.ObjectInputStream.ReadTests -TestCaseID Read0012 +JCK-114a|api|java_io|Serialization|ObjectInputStream|close|Test1 +javasoft.sqe.tests.api.java.io.Serialization.ObjectInputStream.CloseTests -TestCaseID Close0001 +JCK-114a|api|java_io|Serialization|ObjectInputStream|skip|Test1 +javasoft.sqe.tests.api.java.io.Serialization.ObjectInputStream.SkipBytesTests -TestCaseID SkipBytes0001 +JCK-114a|api|java_io|Serialization|ObjectInputStream|skip|Test2 +javasoft.sqe.tests.api.java.io.Serialization.ObjectInputStream.SkipBytesTests -TestCaseID SkipBytes0002 +JCK-114a|api|java_io|Serialization|ObjectInputStream|skip|Test3 +javasoft.sqe.tests.api.java.io.Serialization.ObjectInputStream.SkipBytesTests -TestCaseID SkipBytes0003 +JCK-114a|api|java_io|Serialization|ObjectInputStream|avail|Test1 +javasoft.sqe.tests.api.java.io.Serialization.ObjectInputStream.AvailTests -TestCaseID Avail0001 +JCK-114a|api|java_io|Serialization|ObjectInputStream|avail|Test2 +javasoft.sqe.tests.api.java.io.Serialization.ObjectInputStream.AvailTests -TestCaseID Avail0002 +JCK-114a|api|java_io|Serialization|ObjectInputStream|regvalid|Test1 +javasoft.sqe.tests.api.java.io.Serialization.ObjectInputStream.RegValidTests -TestCaseID RegValid0001 +JCK-114a|api|java_io|Serialization|ObjectInputStream|regvalid|Test2 +javasoft.sqe.tests.api.java.io.Serialization.ObjectInputStream.RegValidTests -TestCaseID RegValid0002 +JCK-114a|api|java_io|Serialization|ObjectInputStream|regvalid|Test3 +javasoft.sqe.tests.api.java.io.Serialization.ObjectInputStream.RegValidTests -TestCaseID RegValid0003 +JCK-114a|api|java_io|Serialization|ObjectInputStream|readboolean|Test1 +javasoft.sqe.tests.api.java.io.Serialization.ObjectInputStream.ReadBooleanTests -TestCaseID ReadBoolean0001 +JCK-114a|api|java_io|Serialization|ObjectInputStream|readboolean|Test2 +javasoft.sqe.tests.api.java.io.Serialization.ObjectInputStream.ReadBooleanTests -TestCaseID ReadBoolean0002 +JCK-114a|api|java_io|Serialization|ObjectInputStream|readbyte|Test1 +javasoft.sqe.tests.api.java.io.Serialization.ObjectInputStream.ReadByteTests -TestCaseID ReadByte0001 +JCK-114a|api|java_io|Serialization|ObjectInputStream|readbyte|Test2 +javasoft.sqe.tests.api.java.io.Serialization.ObjectInputStream.ReadByteTests -TestCaseID ReadByte0002 +JCK-114a|api|java_io|Serialization|ObjectInputStream|readbyte|Test3 +javasoft.sqe.tests.api.java.io.Serialization.ObjectInputStream.ReadByteTests -TestCaseID ReadByte0003 +JCK-114a|api|java_io|Serialization|ObjectInputStream|readbyte|Test4 +javasoft.sqe.tests.api.java.io.Serialization.ObjectInputStream.ReadByteTests -TestCaseID ReadByte0004 +JCK-114a|api|java_io|Serialization|ObjectInputStream|readbyte|Test5 +javasoft.sqe.tests.api.java.io.Serialization.ObjectInputStream.ReadByteTests -TestCaseID ReadByte0005 +JCK-114a|api|java_io|Serialization|ObjectInputStream|readbyte|Test6 +javasoft.sqe.tests.api.java.io.Serialization.ObjectInputStream.ReadByteTests -TestCaseID ReadByte0006 +JCK-114a|api|java_io|Serialization|ObjectInputStream|readbyte|Test7 +javasoft.sqe.tests.api.java.io.Serialization.ObjectInputStream.ReadByteTests -TestCaseID ReadByte0007 +JCK-114a|api|java_io|Serialization|ObjectInputStream|readchar|Test1 +javasoft.sqe.tests.api.java.io.Serialization.ObjectInputStream.ReadCharTests -TestCaseID ReadChar0001 +JCK-114a|api|java_io|Serialization|ObjectInputStream|readchar|Test2 +javasoft.sqe.tests.api.java.io.Serialization.ObjectInputStream.ReadCharTests -TestCaseID ReadChar0002 +JCK-114a|api|java_io|Serialization|ObjectInputStream|readchar|Test3 +javasoft.sqe.tests.api.java.io.Serialization.ObjectInputStream.ReadCharTests -TestCaseID ReadChar0003 +JCK-114a|api|java_io|Serialization|ObjectInputStream|readchar|Test4 +javasoft.sqe.tests.api.java.io.Serialization.ObjectInputStream.ReadCharTests -TestCaseID ReadChar0004 +JCK-114a|api|java_io|Serialization|ObjectInputStream|readdouble|Test1 +javasoft.sqe.tests.api.java.io.Serialization.ObjectInputStream.ReadDoubleTests -TestCaseID ReadDouble0001 +JCK-114a|api|java_io|Serialization|ObjectInputStream|readdouble|Test2 +javasoft.sqe.tests.api.java.io.Serialization.ObjectInputStream.ReadDoubleTests -TestCaseID ReadDouble0002 +JCK-114a|api|java_io|Serialization|ObjectInputStream|readdouble|Test3 +javasoft.sqe.tests.api.java.io.Serialization.ObjectInputStream.ReadDoubleTests -TestCaseID ReadDouble0003 +JCK-114a|api|java_io|Serialization|ObjectInputStream|readdouble|Test4 +javasoft.sqe.tests.api.java.io.Serialization.ObjectInputStream.ReadDoubleTests -TestCaseID ReadDouble0004 +JCK-114a|api|java_io|Serialization|ObjectInputStream|readdouble|Test5 +javasoft.sqe.tests.api.java.io.Serialization.ObjectInputStream.ReadDoubleTests -TestCaseID ReadDouble0005 +JCK-114a|api|java_io|Serialization|ObjectInputStream|readdouble|Test6 +javasoft.sqe.tests.api.java.io.Serialization.ObjectInputStream.ReadDoubleTests -TestCaseID ReadDouble0006 +JCK-114a|api|java_io|Serialization|ObjectInputStream|readdouble|Test7 +javasoft.sqe.tests.api.java.io.Serialization.ObjectInputStream.ReadDoubleTests -TestCaseID ReadDouble0007 +JCK-114a|api|java_io|Serialization|ObjectInputStream|readfloat|Test1 +javasoft.sqe.tests.api.java.io.Serialization.ObjectInputStream.ReadFloatTests -TestCaseID ReadFloat0001 +JCK-114a|api|java_io|Serialization|ObjectInputStream|readfloat|Test2 +javasoft.sqe.tests.api.java.io.Serialization.ObjectInputStream.ReadFloatTests -TestCaseID ReadFloat0002 +JCK-114a|api|java_io|Serialization|ObjectInputStream|readfloat|Test3 +javasoft.sqe.tests.api.java.io.Serialization.ObjectInputStream.ReadFloatTests -TestCaseID ReadFloat0003 +JCK-114a|api|java_io|Serialization|ObjectInputStream|readfloat|Test4 +javasoft.sqe.tests.api.java.io.Serialization.ObjectInputStream.ReadFloatTests -TestCaseID ReadFloat0004 +JCK-114a|api|java_io|Serialization|ObjectInputStream|readfloat|Test5 +javasoft.sqe.tests.api.java.io.Serialization.ObjectInputStream.ReadFloatTests -TestCaseID ReadFloat0005 +JCK-114a|api|java_io|Serialization|ObjectInputStream|readfloat|Test6 +javasoft.sqe.tests.api.java.io.Serialization.ObjectInputStream.ReadFloatTests -TestCaseID ReadFloat0006 +JCK-114a|api|java_io|Serialization|ObjectInputStream|readfloat|Test7 +javasoft.sqe.tests.api.java.io.Serialization.ObjectInputStream.ReadFloatTests -TestCaseID ReadFloat0007 +JCK-114a|api|java_io|Serialization|ObjectInputStream|readfully|Test1 +javasoft.sqe.tests.api.java.io.Serialization.ObjectInputStream.ReadFullyTests -TestCaseID ReadFully0001 +JCK-114a|api|java_io|Serialization|ObjectInputStream|readfully|Test2 +javasoft.sqe.tests.api.java.io.Serialization.ObjectInputStream.ReadFullyTests -TestCaseID ReadFully0002 +JCK-114a|api|java_io|Serialization|ObjectInputStream|readfully|Test3 +javasoft.sqe.tests.api.java.io.Serialization.ObjectInputStream.ReadFullyTests -TestCaseID ReadFully0003 +JCK-114a|api|java_io|Serialization|ObjectInputStream|readfully|Test4 +javasoft.sqe.tests.api.java.io.Serialization.ObjectInputStream.ReadFullyTests -TestCaseID ReadFully0004 +JCK-114a|api|java_io|Serialization|ObjectInputStream|readfully|Test5 +javasoft.sqe.tests.api.java.io.Serialization.ObjectInputStream.ReadFullyTests -TestCaseID ReadFully0005 +JCK-114a|api|java_io|Serialization|ObjectInputStream|readfully|Test6 +javasoft.sqe.tests.api.java.io.Serialization.ObjectInputStream.ReadFullyTests -TestCaseID ReadFully0006 +JCK-114a|api|java_io|Serialization|ObjectInputStream|readfully|Test7 +javasoft.sqe.tests.api.java.io.Serialization.ObjectInputStream.ReadFullyTests -TestCaseID ReadFully0007 +JCK-114a|api|java_io|Serialization|ObjectInputStream|readfully|Test8 +javasoft.sqe.tests.api.java.io.Serialization.ObjectInputStream.ReadFullyTests -TestCaseID ReadFully0008 +JCK-114a|api|java_io|Serialization|ObjectInputStream|readfully|Test9 +javasoft.sqe.tests.api.java.io.Serialization.ObjectInputStream.ReadFullyTests -TestCaseID ReadFully0009 +JCK-114a|api|java_io|Serialization|ObjectInputStream|readfully|Test10 +javasoft.sqe.tests.api.java.io.Serialization.ObjectInputStream.ReadFullyTests -TestCaseID ReadFully0010 +JCK-114a|api|java_io|Serialization|ObjectInputStream|readint|Test1 +javasoft.sqe.tests.api.java.io.Serialization.ObjectInputStream.ReadIntTests -TestCaseID ReadInt0001 +JCK-114a|api|java_io|Serialization|ObjectInputStream|readint|Test2 +javasoft.sqe.tests.api.java.io.Serialization.ObjectInputStream.ReadIntTests -TestCaseID ReadInt0002 +JCK-114a|api|java_io|Serialization|ObjectInputStream|readint|Test3 +javasoft.sqe.tests.api.java.io.Serialization.ObjectInputStream.ReadIntTests -TestCaseID ReadInt0003 +JCK-114a|api|java_io|Serialization|ObjectInputStream|readint|Test4 +javasoft.sqe.tests.api.java.io.Serialization.ObjectInputStream.ReadIntTests -TestCaseID ReadInt0004 +JCK-114a|api|java_io|Serialization|ObjectInputStream|readline|Test1 +javasoft.sqe.tests.api.java.io.Serialization.ObjectInputStream.ReadLineTests -TestCaseID ReadLine0001 +JCK-114a|api|java_io|Serialization|ObjectInputStream|readlong|Test1 +javasoft.sqe.tests.api.java.io.Serialization.ObjectInputStream.ReadLongTests -TestCaseID ReadLong0001 +JCK-114a|api|java_io|Serialization|ObjectInputStream|readlong|Test2 +javasoft.sqe.tests.api.java.io.Serialization.ObjectInputStream.ReadLongTests -TestCaseID ReadLong0002 +JCK-114a|api|java_io|Serialization|ObjectInputStream|readlong|Test3 +javasoft.sqe.tests.api.java.io.Serialization.ObjectInputStream.ReadLongTests -TestCaseID ReadLong0003 +JCK-114a|api|java_io|Serialization|ObjectInputStream|readlong|Test4 +javasoft.sqe.tests.api.java.io.Serialization.ObjectInputStream.ReadLongTests -TestCaseID ReadLong0004 +JCK-114a|api|java_io|Serialization|ObjectInputStream|readshort|Test1 +javasoft.sqe.tests.api.java.io.Serialization.ObjectInputStream.ReadShortTests -TestCaseID ReadShort0001 +JCK-114a|api|java_io|Serialization|ObjectInputStream|readshort|Test2 +javasoft.sqe.tests.api.java.io.Serialization.ObjectInputStream.ReadShortTests -TestCaseID ReadShort0002 +JCK-114a|api|java_io|Serialization|ObjectInputStream|readshort|Test3 +javasoft.sqe.tests.api.java.io.Serialization.ObjectInputStream.ReadShortTests -TestCaseID ReadShort0003 +JCK-114a|api|java_io|Serialization|ObjectInputStream|readshort|Test4 +javasoft.sqe.tests.api.java.io.Serialization.ObjectInputStream.ReadShortTests -TestCaseID ReadShort0004 +JCK-114a|api|java_io|Serialization|ObjectInputStream|readunsignedbyte|Test1 +javasoft.sqe.tests.api.java.io.Serialization.ObjectInputStream.ReadUnsignedByteTests -TestCaseID ReadUnsignedByte0001 +JCK-114a|api|java_io|Serialization|ObjectInputStream|readunsignedbyte|Test2 +javasoft.sqe.tests.api.java.io.Serialization.ObjectInputStream.ReadUnsignedByteTests -TestCaseID ReadUnsignedByte0002 +JCK-114a|api|java_io|Serialization|ObjectInputStream|readunsignedbyte|Test3 +javasoft.sqe.tests.api.java.io.Serialization.ObjectInputStream.ReadUnsignedByteTests -TestCaseID ReadUnsignedByte0003 +JCK-114a|api|java_io|Serialization|ObjectInputStream|readunsignedbyte|Test4 +javasoft.sqe.tests.api.java.io.Serialization.ObjectInputStream.ReadUnsignedByteTests -TestCaseID ReadUnsignedByte0004 +JCK-114a|api|java_io|Serialization|ObjectInputStream|readunsignedbyte|Test5 +javasoft.sqe.tests.api.java.io.Serialization.ObjectInputStream.ReadUnsignedByteTests -TestCaseID ReadUnsignedByte0005 +JCK-114a|api|java_io|Serialization|ObjectInputStream|readunsignedbyte|Test6 +javasoft.sqe.tests.api.java.io.Serialization.ObjectInputStream.ReadUnsignedByteTests -TestCaseID ReadUnsignedByte0006 +JCK-114a|api|java_io|Serialization|ObjectInputStream|readunsignedshort|Test1 +javasoft.sqe.tests.api.java.io.Serialization.ObjectInputStream.ReadUnsignedShortTests -TestCaseID ReadUnsignedShort0001 +JCK-114a|api|java_io|Serialization|ObjectInputStream|readunsignedshort|Test2 +javasoft.sqe.tests.api.java.io.Serialization.ObjectInputStream.ReadUnsignedShortTests -TestCaseID ReadUnsignedShort0002 +JCK-114a|api|java_io|Serialization|ObjectInputStream|readunsignedshort|Test3 +javasoft.sqe.tests.api.java.io.Serialization.ObjectInputStream.ReadUnsignedShortTests -TestCaseID ReadUnsignedShort0003 +JCK-114a|api|java_io|Serialization|ObjectInputStream|readunsignedshort|Test4 +javasoft.sqe.tests.api.java.io.Serialization.ObjectInputStream.ReadUnsignedShortTests -TestCaseID ReadUnsignedShort0004 +JCK-114a|api|java_io|Serialization|ObjectInputStream|readunsignedshort|Test5 +javasoft.sqe.tests.api.java.io.Serialization.ObjectInputStream.ReadUnsignedShortTests -TestCaseID ReadUnsignedShort0005 +JCK-114a|api|java_io|Serialization|ObjectInputValidation|index|Test1 +javasoft.sqe.tests.api.java.io.Serialization.ObjectInputValidation.ValObjTests -TestCaseID ValObj0001 +JCK-114a|api|java_io|Serialization|ObjectStreamClass|misc|Test1 +javasoft.sqe.tests.api.java.io.Serialization.ObjectStreamClass.MiscTests -TestCaseID GetName0001 +JCK-114a|api|java_io|Serialization|ObjectStreamClass|misc|Test2 +javasoft.sqe.tests.api.java.io.Serialization.ObjectStreamClass.MiscTests -TestCaseID ForClass0001 +JCK-114a|api|java_io|Serialization|ObjectStreamClass|misc|Test4 +javasoft.sqe.tests.api.java.io.Serialization.ObjectStreamClass.MiscTests -TestCaseID ToStr0001 +JCK-114a|api|java_io|Serialization|ObjectStreamClass|lookup|Test1 +javasoft.sqe.tests.api.java.io.Serialization.ObjectStreamClass.LookupTests -TestCaseID Lookup0001 +JCK-114a|api|java_io|Serialization|ObjectStreamClass|lookup|Test2 +javasoft.sqe.tests.api.java.io.Serialization.ObjectStreamClass.LookupTests -TestCaseID Lookup0002 +JCK-114a|api|java_io|Serialization|ObjectStreamClass|lookup|Test3 +javasoft.sqe.tests.api.java.io.Serialization.ObjectStreamClass.LookupTests -TestCaseID Lookup0003 +JCK-114a|api|java_io|OutputStream|manual|Test2 +javasoft.sqe.tests.api.java.io.OutputStream.AssertionsTests -TestCaseID ALL -WorkDir E:/tmp/ -Test file:/g:/JCK-114a/tests/api/java_io/OutputStream/manual.html +JCK-114a|api|java_io|LineNumberInputStream|manual|Test2 +javasoft.sqe.tests.api.java.io.LineNumberInputStream.ReadTests -TestCaseID ALL -WorkDir E:/tmp/ -Test file:/g:/JCK-114a/tests/api/java_io/LineNumberInputStream/manual.html +JCK-114a|api|java_io|LineNumberInputStream|manual|Test5 +javasoft.sqe.tests.api.java.io.LineNumberInputStream.AvailableTests -TestCaseID ALL -WorkDir E:/tmp/ -Test file:/g:/JCK-114a/tests/api/java_io/LineNumberInputStream/manual.html +JCK-114a|api|java_io|LineNumberInputStream|manual|Test7 +javasoft.sqe.tests.api.java.io.LineNumberInputStream.LineNumberTests -TestCaseID ALL -WorkDir E:/tmp/ -Test file:/g:/JCK-114a/tests/api/java_io/LineNumberInputStream/manual.html +JCK-114a|api|java_io|StreamTokenizer|manual|Test2 +javasoft.sqe.tests.api.java.io.StreamTokenizer.resetSyntaxTests -TestCaseID ALL -WorkDir E:/tmp/ -Test file:/g:/JCK-114a/tests/api/java_io/StreamTokenizer/manual.html +JCK-114a|api|java_io|StreamTokenizer|manual|Test3 +javasoft.sqe.tests.api.java.io.StreamTokenizer.wordCharsTests -TestCaseID ALL -WorkDir E:/tmp/ -Test file:/g:/JCK-114a/tests/api/java_io/StreamTokenizer/manual.html +JCK-114a|api|java_io|StreamTokenizer|manual|Test4 +javasoft.sqe.tests.api.java.io.StreamTokenizer.whitespaceCharsTests -TestCaseID ALL -WorkDir E:/tmp/ -Test file:/g:/JCK-114a/tests/api/java_io/StreamTokenizer/manual.html +JCK-114a|api|java_io|StreamTokenizer|manual|Test5 +javasoft.sqe.tests.api.java.io.StreamTokenizer.ordinaryCharsTests -TestCaseID ALL -WorkDir E:/tmp/ -Test file:/g:/JCK-114a/tests/api/java_io/StreamTokenizer/manual.html +JCK-114a|api|java_io|StreamTokenizer|manual|Test6 +javasoft.sqe.tests.api.java.io.StreamTokenizer.ordinaryCharTests -TestCaseID ALL -WorkDir E:/tmp/ -Test file:/g:/JCK-114a/tests/api/java_io/StreamTokenizer/manual.html +JCK-114a|api|java_io|StreamTokenizer|manual|Test7 +javasoft.sqe.tests.api.java.io.StreamTokenizer.commentCharTests -TestCaseID ALL -WorkDir E:/tmp/ -Test file:/g:/JCK-114a/tests/api/java_io/StreamTokenizer/manual.html +JCK-114a|api|java_io|StreamTokenizer|manual|Test8 +javasoft.sqe.tests.api.java.io.StreamTokenizer.quoteCharTests -TestCaseID ALL -WorkDir E:/tmp/ -Test file:/g:/JCK-114a/tests/api/java_io/StreamTokenizer/manual.html +JCK-114a|api|java_io|StreamTokenizer|manual|Test9 +javasoft.sqe.tests.api.java.io.StreamTokenizer.parseNumbersTests -TestCaseID ALL -WorkDir E:/tmp/ -Test file:/g:/JCK-114a/tests/api/java_io/StreamTokenizer/manual.html +JCK-114a|api|java_io|StreamTokenizer|manual|Test10 +javasoft.sqe.tests.api.java.io.StreamTokenizer.eolIsSignificantTests -TestCaseID ALL -WorkDir E:/tmp/ -Test file:/g:/JCK-114a/tests/api/java_io/StreamTokenizer/manual.html +JCK-114a|api|java_io|StreamTokenizer|manual|Test11 +javasoft.sqe.tests.api.java.io.StreamTokenizer.slashStarCommentsTests -TestCaseID ALL -WorkDir E:/tmp/ -Test file:/g:/JCK-114a/tests/api/java_io/StreamTokenizer/manual.html +JCK-114a|api|java_io|StreamTokenizer|manual|Test12 +javasoft.sqe.tests.api.java.io.StreamTokenizer.slashSlashCommentsTests -TestCaseID ALL -WorkDir E:/tmp/ -Test file:/g:/JCK-114a/tests/api/java_io/StreamTokenizer/manual.html +JCK-114a|api|java_io|StreamTokenizer|manual|Test13 +javasoft.sqe.tests.api.java.io.StreamTokenizer.lowerCaseModeTests -TestCaseID ALL -WorkDir E:/tmp/ -Test file:/g:/JCK-114a/tests/api/java_io/StreamTokenizer/manual.html +JCK-114a|api|java_io|StreamTokenizer|manual|Test14 +javasoft.sqe.tests.api.java.io.StreamTokenizer.constTests -TestCaseID ALL -WorkDir E:/tmp/ -Test file:/g:/JCK-114a/tests/api/java_io/StreamTokenizer/manual.html +JCK-114a|api|java_io|StreamTokenizer|manual|Test16 +javasoft.sqe.tests.api.java.io.StreamTokenizer.linenoTests -TestCaseID ALL -WorkDir E:/tmp/ -Test file:/g:/JCK-114a/tests/api/java_io/StreamTokenizer/manual.html +JCK-114a|api|java_io|StreamTokenizer|manual|Test17 +javasoft.sqe.tests.api.java.io.StreamTokenizer.toStringTests -TestCaseID ALL -WorkDir E:/tmp/ -Test file:/g:/JCK-114a/tests/api/java_io/StreamTokenizer/manual.html +JCK-114a|api|java_io|File|manual|Test1 +javasoft.sqe.tests.api.java.io.File.separatorsTests -TestCaseID ALL -WorkDir E:/tmp/ -Test file:/g:/JCK-114a/tests/api/java_io/File/manual.html +JCK-114a|api|java_io|File|manual|Test3 +javasoft.sqe.tests.api.java.io.File.toStringTests -TestCaseID ALL -WorkDir E:/tmp/ -Test file:/g:/JCK-114a/tests/api/java_io/File/manual.html +JCK-114a|api|java_io|File|manual|Test4 +javasoft.sqe.tests.api.java.io.File.equalsTests -TestCaseID ALL -WorkDir E:/tmp/ -Test file:/g:/JCK-114a/tests/api/java_io/File/manual.html +JCK-114a|api|java_io|File|manual|Test5 +javasoft.sqe.tests.api.java.io.File.hashCodeTests -TestCaseID ALL -WorkDir E:/tmp/ -Test file:/g:/JCK-114a/tests/api/java_io/File/manual.html +JCK-114a|api|java_io|File|manual|Test7 +javasoft.sqe.tests.api.java.io.File.getPathTests -TestCaseID ALL -WorkDir E:/tmp/ -Test file:/g:/JCK-114a/tests/api/java_io/File/manual.html +JCK-114a|api|java_io|File|manual|Test9 +javasoft.sqe.tests.api.java.io.File.getAbsolutePathTests -TestCaseID ALL -WorkDir E:/tmp/ -Test file:/g:/JCK-114a/tests/api/java_io/File/manual.html +JCK-114a|api|java_io|File|manual|Test10 +javasoft.sqe.tests.api.java.io.File.isAbsoluteTests -TestCaseID ALL -WorkDir E:/tmp/ -Test file:/g:/JCK-114a/tests/api/java_io/File/manual.html +JCK-114a|api|java_io|File|manual|Test11 +javasoft.sqe.tests.api.java.io.File.existsTests -TestCaseID ALL -WorkDir E:/tmp/ -Test file:/g:/JCK-114a/tests/api/java_io/File/manual.html +JCK-114a|api|java_io|File|manual|Test12 +javasoft.sqe.tests.api.java.io.File.canReadTests -TestCaseID ALL -WorkDir E:/tmp/ -Test file:/g:/JCK-114a/tests/api/java_io/File/manual.html +JCK-114a|api|java_io|File|manual|Test13 +javasoft.sqe.tests.api.java.io.File.canWriteTests -TestCaseID ALL -WorkDir E:/tmp/ -Test file:/g:/JCK-114a/tests/api/java_io/File/manual.html +JCK-114a|api|java_io|File|manual|Test14 +javasoft.sqe.tests.api.java.io.File.isFileTests -TestCaseID ALL -WorkDir E:/tmp/ -Test file:/g:/JCK-114a/tests/api/java_io/File/manual.html +JCK-114a|api|java_io|File|manual|Test15 +javasoft.sqe.tests.api.java.io.File.isDirectoryTests -TestCaseID ALL -WorkDir E:/tmp/ -Test file:/g:/JCK-114a/tests/api/java_io/File/manual.html +JCK-114a|api|java_io|File|manual|Test16 +javasoft.sqe.tests.api.java.io.File.lastModifiedTests -TestCaseID ALL -WorkDir E:/tmp/ -Test file:/g:/JCK-114a/tests/api/java_io/File/manual.html +JCK-114a|api|java_io|File|manual|Test17 +javasoft.sqe.tests.api.java.io.File.lengthTests -TestCaseID ALL -WorkDir E:/tmp/ -Test file:/g:/JCK-114a/tests/api/java_io/File/manual.html +JCK-114a|api|java_io|File|manual|Test18 +javasoft.sqe.tests.api.java.io.File.mkdirTests -TestCaseID ALL -WorkDir E:/tmp/ -Test file:/g:/JCK-114a/tests/api/java_io/File/manual.html +JCK-114a|api|java_io|File|manual|Test19 +javasoft.sqe.tests.api.java.io.File.mkdirsTests -TestCaseID ALL -WorkDir E:/tmp/ -Test file:/g:/JCK-114a/tests/api/java_io/File/manual.html +JCK-114a|api|java_io|File|manual|Test20 +javasoft.sqe.tests.api.java.io.File.deleteTests -TestCaseID ALL -WorkDir E:/tmp/ -Test file:/g:/JCK-114a/tests/api/java_io/File/manual.html +JCK-114a|api|java_io|File|manual|Test22 +javasoft.sqe.tests.api.java.io.File.listTests -TestCaseID ALL -WorkDir E:/tmp/ -Test file:/g:/JCK-114a/tests/api/java_io/File/manual.html +JCK-114a|api|java_io|File|manual|Test23 +javasoft.sqe.tests.api.java.io.File.noSMTests -TestCaseID ALL -WorkDir E:/tmp/ -Test file:/g:/JCK-114a/tests/api/java_io/File/manual.html +JCK-114a|api|java_io|File|manual|Test24 +javasoft.sqe.tests.api.java.io.File.SecurityExTests -TestCaseID ALL -WorkDir E:/tmp/ -Test file:/g:/JCK-114a/tests/api/java_io/File/manual.html +JCK-114a|api|java_io|FileDescriptor|manual|Test1 +javasoft.sqe.tests.api.java.io.FileDescriptor.fieldsTests -TestCaseID ALL -WorkDir E:/tmp/ -Test file:/g:/JCK-114a/tests/api/java_io/FileDescriptor/manual.html +JCK-114a|api|java_io|FileDescriptor|manual|Test2 +javasoft.sqe.tests.api.java.io.FileDescriptor.validTests -TestCaseID ALL -WorkDir E:/tmp/ -Test file:/g:/JCK-114a/tests/api/java_io/FileDescriptor/manual.html +JCK-114a|api|java_io|SequenceInputStream|manual|Test2 +javasoft.sqe.tests.api.java.io.SequenceInputStream.AssertionsTests -TestCaseID ALL -WorkDir E:/tmp/ -Test file:/g:/JCK-114a/tests/api/java_io/SequenceInputStream/manual.html +JCK-114a|api|java_io|PipedInputStream|manual|Test1 +javasoft.sqe.tests.api.java.io.PipedInputStream.CtorTests -TestCaseID ALL -WorkDir E:/tmp/ -Test file:/g:/JCK-114a/tests/api/java_io/PipedInputStream/manual.html +JCK-114a|api|java_io|PipedInputStream|manual|Test2 +javasoft.sqe.tests.api.java.io.PipedInputStream.ConnectTests -TestCaseID ALL -WorkDir E:/tmp/ -Test file:/g:/JCK-114a/tests/api/java_io/PipedInputStream/manual.html +JCK-114a|api|java_io|PipedInputStream|manual|Test4 +javasoft.sqe.tests.api.java.io.PipedInputStream.CloseTests -TestCaseID ALL -WorkDir E:/tmp/ -Test file:/g:/JCK-114a/tests/api/java_io/PipedInputStream/manual.html +JCK-114a|api|java_io|PipedInputStream|manual|Test5 +javasoft.sqe.tests.api.java.io.PipedInputStream.AvailableTests -TestCaseID ALL -WorkDir E:/tmp/ -Test file:/g:/JCK-114a/tests/api/java_io/PipedInputStream/manual.html +JCK-114a|api|java_io|ByteArrayOutputStream|manual|Test1 +javasoft.sqe.tests.api.java.io.ByteArrayOutputStream.CtorTests -TestCaseID ALL -WorkDir E:/tmp/ -Test file:/g:/JCK-114a/tests/api/java_io/ByteArrayOutputStream/manual.html +JCK-114a|api|java_io|ByteArrayOutputStream|manual|Test3 +javasoft.sqe.tests.api.java.io.ByteArrayOutputStream.resetTests -TestCaseID ALL -WorkDir E:/tmp/ -Test file:/g:/JCK-114a/tests/api/java_io/ByteArrayOutputStream/manual.html +JCK-114a|api|java_io|ByteArrayOutputStream|manual|Test4 +javasoft.sqe.tests.api.java.io.ByteArrayOutputStream.sizeTests -TestCaseID ALL -WorkDir E:/tmp/ -Test file:/g:/JCK-114a/tests/api/java_io/ByteArrayOutputStream/manual.html +JCK-114a|api|java_io|ByteArrayOutputStream|manual|Test5 +javasoft.sqe.tests.api.java.io.ByteArrayOutputStream.toByteArrayTests -TestCaseID ALL -WorkDir E:/tmp/ -Test file:/g:/JCK-114a/tests/api/java_io/ByteArrayOutputStream/manual.html +JCK-114a|api|java_io|ByteArrayOutputStream|manual|Test6 +javasoft.sqe.tests.api.java.io.ByteArrayOutputStream.toStringTests -TestCaseID ALL -WorkDir E:/tmp/ -Test file:/g:/JCK-114a/tests/api/java_io/ByteArrayOutputStream/manual.html +JCK-114a|api|java_io|ByteArrayOutputStream|manual|Test7 +javasoft.sqe.tests.api.java.io.ByteArrayOutputStream.WriteToTests -TestCaseID ALL -WorkDir E:/tmp/ -Test file:/g:/JCK-114a/tests/api/java_io/ByteArrayOutputStream/manual.html +JCK-114a|api|java_io|BufferedOutputStream|manual|Test2 +javasoft.sqe.tests.api.java.io.BufferedOutputStream.writeTests -TestCaseID ALL -WorkDir E:/tmp/ -Test file:/g:/JCK-114a/tests/api/java_io/BufferedOutputStream/manual.html +JCK-114a|api|java_io|BufferedOutputStream|manual|Test3 +javasoft.sqe.tests.api.java.io.BufferedOutputStream.flushTests -TestCaseID ALL -WorkDir E:/tmp/ -Test file:/g:/JCK-114a/tests/api/java_io/BufferedOutputStream/manual.html +JCK-114a|api|java_io|DataOutputStream|manual|Test2 +javasoft.sqe.tests.api.java.io.DataOutputStream.writeTests -TestCaseID ALL -WorkDir E:/tmp/ -Test file:/g:/JCK-114a/tests/api/java_io/DataOutputStream/manual.html +JCK-114a|api|java_io|DataOutputStream|manual|Test3 +javasoft.sqe.tests.api.java.io.DataOutputStream.flushTests -TestCaseID ALL -WorkDir E:/tmp/ -Test file:/g:/JCK-114a/tests/api/java_io/DataOutputStream/manual.html +JCK-114a|api|java_io|DataOutputStream|manual|Test4 +javasoft.sqe.tests.api.java.io.DataOutputStream.writeBooleanTests -TestCaseID ALL -WorkDir E:/tmp/ -Test file:/g:/JCK-114a/tests/api/java_io/DataOutputStream/manual.html +JCK-114a|api|java_io|DataOutputStream|manual|Test5 +javasoft.sqe.tests.api.java.io.DataOutputStream.writeByteTests -TestCaseID ALL -WorkDir E:/tmp/ -Test file:/g:/JCK-114a/tests/api/java_io/DataOutputStream/manual.html +JCK-114a|api|java_io|DataOutputStream|manual|Test6 +javasoft.sqe.tests.api.java.io.DataOutputStream.writeShortTests -TestCaseID ALL -WorkDir E:/tmp/ -Test file:/g:/JCK-114a/tests/api/java_io/DataOutputStream/manual.html +JCK-114a|api|java_io|DataOutputStream|manual|Test7 +javasoft.sqe.tests.api.java.io.DataOutputStream.writeCharTests -TestCaseID ALL -WorkDir E:/tmp/ -Test file:/g:/JCK-114a/tests/api/java_io/DataOutputStream/manual.html +JCK-114a|api|java_io|DataOutputStream|manual|Test8 +javasoft.sqe.tests.api.java.io.DataOutputStream.writeIntTests -TestCaseID ALL -WorkDir E:/tmp/ -Test file:/g:/JCK-114a/tests/api/java_io/DataOutputStream/manual.html +JCK-114a|api|java_io|DataOutputStream|manual|Test9 +javasoft.sqe.tests.api.java.io.DataOutputStream.writeLongTests -TestCaseID ALL -WorkDir E:/tmp/ -Test file:/g:/JCK-114a/tests/api/java_io/DataOutputStream/manual.html +JCK-114a|api|java_io|DataOutputStream|manual|Test10 +javasoft.sqe.tests.api.java.io.DataOutputStream.writeFloatTests -TestCaseID ALL -WorkDir E:/tmp/ -Test file:/g:/JCK-114a/tests/api/java_io/DataOutputStream/manual.html +JCK-114a|api|java_io|DataOutputStream|manual|Test11 +javasoft.sqe.tests.api.java.io.DataOutputStream.writeDoubleTests -TestCaseID ALL -WorkDir E:/tmp/ -Test file:/g:/JCK-114a/tests/api/java_io/DataOutputStream/manual.html +JCK-114a|api|java_io|DataOutputStream|manual|Test12 +javasoft.sqe.tests.api.java.io.DataOutputStream.writeBytesTests -TestCaseID ALL -WorkDir E:/tmp/ -Test file:/g:/JCK-114a/tests/api/java_io/DataOutputStream/manual.html +JCK-114a|api|java_io|DataOutputStream|manual|Test13 +javasoft.sqe.tests.api.java.io.DataOutputStream.writeCharsTests -TestCaseID ALL -WorkDir E:/tmp/ -Test file:/g:/JCK-114a/tests/api/java_io/DataOutputStream/manual.html +JCK-114a|api|java_io|DataOutputStream|manual|Test14 +javasoft.sqe.tests.api.java.io.DataOutputStream.writeUTFTests -TestCaseID ALL -WorkDir E:/tmp/ -Test file:/g:/JCK-114a/tests/api/java_io/DataOutputStream/manual.html +JCK-114a|api|java_io|FilterInputStream|manual|Test2 +javasoft.sqe.tests.api.java.io.FilterInputStream.AssertionTests -TestCaseID ALL -WorkDir E:/tmp/ -Test file:/g:/JCK-114a/tests/api/java_io/FilterInputStream/manual.html +JCK-114a|api|java_io|FileOutputStream|manual|Test1 +javasoft.sqe.tests.api.java.io.FileOutputStream.CtorTests -TestCaseID ALL -WorkDir E:/tmp/ -Test file:/g:/JCK-114a/tests/api/java_io/FileOutputStream/manual.html +JCK-114a|api|java_io|FileOutputStream|manual|Test2 +javasoft.sqe.tests.api.java.io.FileOutputStream.getFDTests -TestCaseID ALL -WorkDir E:/tmp/ -Test file:/g:/JCK-114a/tests/api/java_io/FileOutputStream/manual.html +JCK-114a|api|java_io|FileOutputStream|manual|Test4 +javasoft.sqe.tests.api.java.io.FileOutputStream.closeTests -TestCaseID ALL -WorkDir E:/tmp/ -Test file:/g:/JCK-114a/tests/api/java_io/FileOutputStream/manual.html +JCK-114a|api|java_io|FileOutputStream|manual|Test5 +javasoft.sqe.tests.api.java.io.FileOutputStream.finalizeTests -TestCaseID ALL -WorkDir E:/tmp/ -Test file:/g:/JCK-114a/tests/api/java_io/FileOutputStream/manual.html +JCK-114a|api|java_io|FileOutputStream|manual|Test6 +javasoft.sqe.tests.api.java.io.FileOutputStream.SecurityExTests -TestCaseID ALL -WorkDir E:/tmp/ -Test file:/g:/JCK-114a/tests/api/java_io/FileOutputStream/manual.html +JCK-114a|api|java_io|PrintStream|manual|Test3 +javasoft.sqe.tests.api.java.io.PrintStream.checkErrorTests -TestCaseID ALL -WorkDir E:/tmp/ -Test file:/g:/JCK-114a/tests/api/java_io/PrintStream/manual.html +JCK-114a|api|java_io|PrintStream|manual|Test4 +javasoft.sqe.tests.api.java.io.PrintStream.closeTests -TestCaseID ALL -WorkDir E:/tmp/ -Test file:/g:/JCK-114a/tests/api/java_io/PrintStream/manual.html +JCK-114a|api|java_io|PrintStream|manual|Test5 +javasoft.sqe.tests.api.java.io.PrintStream.flushTests -TestCaseID ALL -WorkDir E:/tmp/ -Test file:/g:/JCK-114a/tests/api/java_io/PrintStream/manual.html +JCK-114a|api|java_io|StringBufferInputStream|manual|Test1 +javasoft.sqe.tests.api.java.io.StringBufferInputStream.CtorTests -TestCaseID ALL -WorkDir E:/tmp/ -Test file:/g:/JCK-114a/tests/api/java_io/StringBufferInputStream/manual.html +JCK-114a|api|java_io|StringBufferInputStream|manual|Test3 +javasoft.sqe.tests.api.java.io.StringBufferInputStream.SkipTests -TestCaseID ALL -WorkDir E:/tmp/ -Test file:/g:/JCK-114a/tests/api/java_io/StringBufferInputStream/manual.html +JCK-114a|api|java_io|StringBufferInputStream|manual|Test4 +javasoft.sqe.tests.api.java.io.StringBufferInputStream.AvailableTests -TestCaseID ALL -WorkDir E:/tmp/ -Test file:/g:/JCK-114a/tests/api/java_io/StringBufferInputStream/manual.html +JCK-114a|api|java_io|StringBufferInputStream|manual|Test5 +javasoft.sqe.tests.api.java.io.StringBufferInputStream.ResetTests -TestCaseID ALL -WorkDir E:/tmp/ -Test file:/g:/JCK-114a/tests/api/java_io/StringBufferInputStream/manual.html +JCK-114a|api|java_io|StringBufferInputStream|manual|Test6 +javasoft.sqe.tests.api.java.io.StringBufferInputStream.AssertionsTests -TestCaseID ALL -WorkDir E:/tmp/ -Test file:/g:/JCK-114a/tests/api/java_io/StringBufferInputStream/manual.html +JCK-114a|api|java_io|IOException|manual|Test1 +javasoft.sqe.tests.api.java.io.IOException.CtorTests -TestCaseID ALL -WorkDir E:/tmp/ -Test file:/g:/JCK-114a/tests/api/java_io/IOException/manual.html +JCK-114a|api|java_io|InterruptedIOException|manual|Test1 +javasoft.sqe.tests.api.java.io.InterruptedIOException.CtorTests -TestCaseID ALL -WorkDir E:/tmp/ -Test file:/g:/JCK-114a/tests/api/java_io/InterruptedIOException/manual.html +JCK-114a|api|java_io|InterruptedIOException|manual|Test2 +javasoft.sqe.tests.api.java.io.InterruptedIOException.bytesTransferredTests -TestCaseID ALL -WorkDir E:/tmp/ -Test file:/g:/JCK-114a/tests/api/java_io/InterruptedIOException/manual.html +JCK-114a|api|java_io|EOFException|manual|Test1 +javasoft.sqe.tests.api.java.io.EOFException.CtorTests -TestCaseID ALL -WorkDir E:/tmp/ -Test file:/g:/JCK-114a/tests/api/java_io/EOFException/manual.html +JCK-114a|api|java_io|FileNotFoundException|manual|Test1 +javasoft.sqe.tests.api.java.io.FileNotFoundException.CtorTests -TestCaseID ALL -WorkDir E:/tmp/ -Test file:/g:/JCK-114a/tests/api/java_io/FileNotFoundException/manual.html +JCK-114a|api|java_io|UTFDataFormatException|manual|Test1 +javasoft.sqe.tests.api.java.io.UTFDataFormatException.CtorTests -TestCaseID ALL -WorkDir E:/tmp/ -Test file:/g:/JCK-114a/tests/api/java_io/UTFDataFormatException/manual.html +JCK-114a|api|java_io|IOStreamTest|index|Test1 +javasoft.sqe.tests.api.java.io.IOStreamTest.BAInputStreamTest +JCK-114a|api|java_io|IOStreamTest|index|Test2 +javasoft.sqe.tests.api.java.io.IOStreamTest.BAOutputStreamTest +JCK-114a|api|java_io|IOStreamTest|index|Test3 +javasoft.sqe.tests.api.java.io.IOStreamTest.LNInputStreamTest +JCK-114a|api|java_io|IOStreamTest|index|Test4 +javasoft.sqe.tests.api.java.io.IOStreamTest.SBInputStreamTest +JCK-114a|api|java_io|BuffWriter|index|Test1 +javasoft.sqe.tests.api.java.io.BuffWriter.BuffWriterTest +JCK-114a|api|java_io|CharArrayReader|index|Test1 +javasoft.sqe.tests.api.java.io.CharArrayReader.CAReaderTest +JCK-114a|api|java_io|CharArrayWriter|index|Test1 +javasoft.sqe.tests.api.java.io.CharArrayWriter.CAWriterTest +JCK-114a|api|java_io|FileReader|index|Test1 +javasoft.sqe.tests.api.java.io.FileReader.FileReaderTest +JCK-114a|api|java_io|FileWriter|index|Test1 +javasoft.sqe.tests.api.java.io.FileWriter.FileWriterTest +JCK-114a|api|java_io|FilterReader|index|Test1 +javasoft.sqe.tests.api.java.io.FilterReader.FilterReaderTest +JCK-114a|api|java_io|FilterWriter|index|Test1 +javasoft.sqe.tests.api.java.io.FilterWriter.FilterWriterTest +JCK-114a|api|java_io|InputStreamReader|index|Test1 +javasoft.sqe.tests.api.java.io.InputStreamReader.IStreamReaderTest +JCK-114a|api|java_io|LineNumberReader|index|Test1 +javasoft.sqe.tests.api.java.io.LineNumberReader.LineNumberReaderTest +JCK-114a|api|java_io|OutputStreamWriter|index|Test1 +javasoft.sqe.tests.api.java.io.OutputStreamWriter.OStreamWriterTest +JCK-114a|api|java_io|PipedReaderWriter|index|Test1 +javasoft.sqe.tests.api.java.io.PipedReaderWriter.PipedReaderWriterTest +JCK-114a|api|java_io|PushbackReader|index|Test1 +javasoft.sqe.tests.api.java.io.PushbackReader.PushbackReaderTest +JCK-114a|api|java_io|StringReader|index|Test1 +javasoft.sqe.tests.api.java.io.StringReader.StringReaderTest +JCK-114a|api|java_io|StringWriter|index|Test1 +javasoft.sqe.tests.api.java.io.StringWriter.StringWriterTest diff --git a/ef/Quality/TestScript/jckJavaLang.txt b/ef/Quality/TestScript/jckJavaLang.txt new file mode 100644 index 000000000000..c2eb01a7a7dd --- /dev/null +++ b/ef/Quality/TestScript/jckJavaLang.txt @@ -0,0 +1,1616 @@ +JCK-114a|api|java_lang|Boolean|desc|Test1 +javasoft.sqe.tests.api.java.lang.Boolean.GetBooleanTests -TestCaseID testTrueString testFalseString testCaseValue testNotSetValue testEmptyValue testNonBoolean testNullValue +JCK-114a|api|java_lang|Boolean|desc|Test3 +javasoft.sqe.tests.api.java.lang.Boolean.SerializeTests -TestURL file:/G:/JCK-114a/tests/api/java_lang/Boolean/desc.html -FileName serial.ser -TestCaseID ALL +JCK-114a|api|java_lang|Boolean|BooleanTests|Test1 +javasoft.sqe.tests.api.java.lang.Boolean.BooleanTests1 +JCK-114a|api|java_lang|Boolean|BooleanTests|Test2 +javasoft.sqe.tests.api.java.lang.Boolean.BooleanTests4 +JCK-114a|api|java_lang|Boolean|BooleanTests|Test3 +javasoft.sqe.tests.api.java.lang.Boolean.BooleanTests7 +JCK-114a|api|java_lang|Boolean|BooleanTests|Test4 +javasoft.sqe.tests.api.java.lang.Boolean.BooleanTests10 +JCK-114a|api|java_lang|Boolean|BooleanTests|Test5 +javasoft.sqe.tests.api.java.lang.Boolean.BooleanTests13 +JCK-114a|api|java_lang|Boolean|BooleanTests|Test6 +javasoft.sqe.tests.api.java.lang.Boolean.BooleanTests16 +JCK-114a|api|java_lang|Boolean|BooleanTests|Test7 +javasoft.sqe.tests.api.java.lang.Boolean.BooleanTests19 +JCK-114a|api|java_lang|Boolean|Assertion|Test1 +javasoft.sqe.tests.api.java.lang.Boolean.VariablesTests -TestCaseID Boolean3001 +JCK-114a|api|java_lang|Byte|ByteTests|Test1 +javasoft.sqe.tests.api.java.lang.Byte.ByteTests1 +JCK-114a|api|java_lang|Byte|ByteTests|Test2 +javasoft.sqe.tests.api.java.lang.Byte.ByteTests4 +JCK-114a|api|java_lang|Byte|ByteTests|Test3 +javasoft.sqe.tests.api.java.lang.Byte.ByteTests7 +JCK-114a|api|java_lang|Byte|ByteTests|Test4 +javasoft.sqe.tests.api.java.lang.Byte.ByteTests10 +JCK-114a|api|java_lang|Byte|ByteTests|Test5 +javasoft.sqe.tests.api.java.lang.Byte.ByteTests13 +JCK-114a|api|java_lang|Byte|ByteTests|Test6 +javasoft.sqe.tests.api.java.lang.Byte.ByteTests16 +JCK-114a|api|java_lang|Byte|ByteTests|Test7 +javasoft.sqe.tests.api.java.lang.Byte.ByteTests19 +JCK-114a|api|java_lang|Byte|ByteTests|Test8 +javasoft.sqe.tests.api.java.lang.Byte.ByteTests22 +JCK-114a|api|java_lang|Byte|ByteTests|Test9 +javasoft.sqe.tests.api.java.lang.Byte.ByteTests25 +JCK-114a|api|java_lang|Byte|ByteTests|Test10 +javasoft.sqe.tests.api.java.lang.Byte.ByteTests28 +JCK-114a|api|java_lang|Byte|ByteTests|Test11 +javasoft.sqe.tests.api.java.lang.Byte.ByteTests32 +JCK-114a|api|java_lang|Byte|ByteTests|Test12 +javasoft.sqe.tests.api.java.lang.Byte.ByteTests35 +JCK-114a|api|java_lang|Byte|ByteTests|Test13 +javasoft.sqe.tests.api.java.lang.Byte.ByteTests38 +JCK-114a|api|java_lang|Byte|ByteTests|Test14 +javasoft.sqe.tests.api.java.lang.Byte.ByteTests41 +JCK-114a|api|java_lang|Byte|ByteTests|Test15 +javasoft.sqe.tests.api.java.lang.Byte.ByteTests44 +JCK-114a|api|java_lang|Byte|ByteTests|Test16 +javasoft.sqe.tests.api.java.lang.Byte.ByteTests47 +JCK-114a|api|java_lang|Byte|ByteTests|Test17 +javasoft.sqe.tests.api.java.lang.Byte.ByteTests51 +JCK-114a|api|java_lang|Byte|manual|Test1 +javasoft.sqe.tests.api.java.lang.Byte.VariableTest +JCK-114a|api|java_lang|Byte|manual|Test2 +javasoft.sqe.tests.api.java.lang.Byte.StringValues +JCK-114a|api|java_lang|Byte|manual|Test3 +javasoft.sqe.tests.api.java.lang.Byte.SerializeTests -TestURL file:/G:/JCK-114a/tests/api/java_lang/Byte/manual.html -TestCaseID ALL +JCK-114a|api|java_lang|Character|index|Test1 +javasoft.sqe.tests.api.java.lang.Character.CharacterTest +JCK-114a|api|java_lang|Character|index|Test2 +javasoft.sqe.tests.api.java.lang.Character.CharacterTest001 +JCK-114a|api|java_lang|Character|index|Test3 +javasoft.sqe.tests.api.java.lang.Character.CharacterTest002 +JCK-114a|api|java_lang|Character|index|Test4 +javasoft.sqe.tests.api.java.lang.Character.SerializeTests -TestURL file:/G:/JCK-114a/tests/api/java_lang/Character/index.html -TestCaseID ALL +JCK-114a|api|java_lang|Class|EquivClass|Test1 +javasoft.sqe.tests.api.java.lang.Class.ForNameTests -TestCaseID Class0101 +JCK-114a|api|java_lang|Class|EquivClass|Test2 +javasoft.sqe.tests.api.java.lang.Class.ForNameTests -TestCaseID Class0102 +JCK-114a|api|java_lang|Class|EquivClass|Test3 +javasoft.sqe.tests.api.java.lang.Class.ForNameTests -TestCaseID Class0103 +JCK-114a|api|java_lang|Class|EquivClass|Test4 +javasoft.sqe.tests.api.java.lang.Class.ForNameTests -TestCaseID Class0104 +JCK-114a|api|java_lang|Class|EquivClass|Test5 +javasoft.sqe.tests.api.java.lang.Class.ForNameTests -TestCaseID Class0105 +JCK-114a|api|java_lang|Class|EquivClass|Test7 +javasoft.sqe.tests.api.java.lang.Class.NewInstanceTests -TestCaseID Class0201 +JCK-114a|api|java_lang|Class|EquivClass|Test8 +javasoft.sqe.tests.api.java.lang.Class.NewInstanceTests -TestCaseID Class0202 +JCK-114a|api|java_lang|Class|EquivClass|Test9 +javasoft.sqe.tests.api.java.lang.Class.NewInstanceTests -TestCaseID Class0203 +JCK-114a|api|java_lang|Class|EquivClass|Test10 +javasoft.sqe.tests.api.java.lang.Class.NewInstanceTests -TestCaseID Class0204 +JCK-114a|api|java_lang|Class|EquivClass|Test11 +javasoft.sqe.tests.api.java.lang.Class.NewInstanceTests -TestCaseID Class0205 +JCK-114a|api|java_lang|Class|EquivClass|Test12 +javasoft.sqe.tests.api.java.lang.Class.GetNameTests -TestCaseID Class0301 +JCK-114a|api|java_lang|Class|EquivClass|Test13 +javasoft.sqe.tests.api.java.lang.Class.GetNameTests -TestCaseID Class0302 +JCK-114a|api|java_lang|Class|EquivClass|Test14 +javasoft.sqe.tests.api.java.lang.Class.GetSuperclassTests -TestCaseID Class0401 +JCK-114a|api|java_lang|Class|EquivClass|Test15 +javasoft.sqe.tests.api.java.lang.Class.GetSuperclassTests -TestCaseID Class0402 +JCK-114a|api|java_lang|Class|EquivClass|Test18 +javasoft.sqe.tests.api.java.lang.Class.GetSuperclassTests -TestCaseID Class0405 +JCK-114a|api|java_lang|Class|EquivClass|Test19 +javasoft.sqe.tests.api.java.lang.Class.GetInterfacesTests -TestCaseID Class0501 +JCK-114a|api|java_lang|Class|EquivClass|Test20 +javasoft.sqe.tests.api.java.lang.Class.GetInterfacesTests -TestCaseID Class0502 +JCK-114a|api|java_lang|Class|EquivClass|Test21 +javasoft.sqe.tests.api.java.lang.Class.GetInterfacesTests -TestCaseID Class0503 +JCK-114a|api|java_lang|Class|EquivClass|Test22 +javasoft.sqe.tests.api.java.lang.Class.GetInterfacesTests -TestCaseID Class0504 +JCK-114a|api|java_lang|Class|EquivClass|Test23 +javasoft.sqe.tests.api.java.lang.Class.GetInterfacesTests -TestCaseID Class0505 +JCK-114a|api|java_lang|Class|EquivClass|Test24 +javasoft.sqe.tests.api.java.lang.Class.GetInterfacesTests -TestCaseID Class0506 +JCK-114a|api|java_lang|Class|EquivClass|Test25 +javasoft.sqe.tests.api.java.lang.Class.GetInterfacesTests -TestCaseID Class0507 +JCK-114a|api|java_lang|Class|EquivClass|Test26 +javasoft.sqe.tests.api.java.lang.Class.GetClassLoaderTests -WorkDir E:/tmp/ -TestCaseID Class0601 +JCK-114a|api|java_lang|Class|EquivClass|Test27 +javasoft.sqe.tests.api.java.lang.Class.GetClassLoaderTests -WorkDir E:/tmp/ -TestCaseID Class0602 +JCK-114a|api|java_lang|Class|EquivClass|Test30 +javasoft.sqe.tests.api.java.lang.Class.GetClassLoaderTests -WorkDir E:/tmp/ -TestCaseID Class0605 +JCK-114a|api|java_lang|Class|EquivClass|Test31 +javasoft.sqe.tests.api.java.lang.Class.IsInterfaceTests -TestCaseID Class0701 +JCK-114a|api|java_lang|Class|EquivClass|Test32 +javasoft.sqe.tests.api.java.lang.Class.IsInterfaceTests -TestCaseID Class0702 +JCK-114a|api|java_lang|Class|EquivClass|Test33 +javasoft.sqe.tests.api.java.lang.Class.IsInterfaceTests -TestCaseID Class0703 +JCK-114a|api|java_lang|Class|EquivClass|Test34 +javasoft.sqe.tests.api.java.lang.Class.ToStringTests -TestCaseID Class0801 +JCK-114a|api|java_lang|Class|EquivClass|Test35 +javasoft.sqe.tests.api.java.lang.Class.ToStringTests -TestCaseID Class0802 +JCK-114a|api|java_lang|Class|EquivClass|Test36 +javasoft.sqe.tests.api.java.lang.Class.ToStringTests -TestCaseID Class0803 +JCK-114a|api|java_lang|Class|BoundValue|Test1 +javasoft.sqe.tests.api.java.lang.Class.NewInstanceTests -TestCaseID Class1202 +JCK-114a|api|java_lang|Class|BoundValue|Test2 +javasoft.sqe.tests.api.java.lang.Class.GetSuperclassTests -TestCaseID Class1402 +JCK-114a|api|java_lang|Class|BoundValue|Test3 +javasoft.sqe.tests.api.java.lang.Class.GetInterfacesTests -TestCaseID Class1503 +JCK-114a|api|java_lang|Class|BoundValue|Test4 +javasoft.sqe.tests.api.java.lang.Class.GetInterfacesTests -TestCaseID Class1506 +JCK-114a|api|java_lang|Class|BoundValue|Test5 +javasoft.sqe.tests.api.java.lang.Class.GetNameTests -TestCaseID Class1302 +JCK-114a|api|java_lang|Class|BoundValue|Test6 +javasoft.sqe.tests.api.java.lang.Class.GetNameTests -TestCaseID Class1303 +JCK-114a|api|java_lang|Class|ReflectTests|Test1 +javasoft.sqe.tests.api.java.lang.Class.ReflectTests -TestCaseID ReflectTest2101 +JCK-114a|api|java_lang|Class|ReflectTests|Test2 +javasoft.sqe.tests.api.java.lang.Class.ReflectTests -TestCaseID ReflectTest2102 +JCK-114a|api|java_lang|Class|ReflectTests|Test3 +javasoft.sqe.tests.api.java.lang.Class.ReflectTests -TestCaseID ReflectTest2103 +JCK-114a|api|java_lang|Class|ReflectTests|Test4 +javasoft.sqe.tests.api.java.lang.Class.ReflectTests -TestCaseID ReflectTest2104 +JCK-114a|api|java_lang|Class|ReflectTests|Test5 +javasoft.sqe.tests.api.java.lang.Class.ReflectTests -TestCaseID ReflectTest2105 +JCK-114a|api|java_lang|Class|ReflectTests|Test6 +javasoft.sqe.tests.api.java.lang.Class.ReflectTests -TestCaseID ReflectTest2106 +JCK-114a|api|java_lang|Class|ReflectTests|Test7 +javasoft.sqe.tests.api.java.lang.Class.ReflectTests -TestCaseID ReflectTest2107 +JCK-114a|api|java_lang|Class|ReflectTests|Test8 +javasoft.sqe.tests.api.java.lang.Class.ReflectTests -TestCaseID ReflectTest2108 +JCK-114a|api|java_lang|Class|ReflectTests|Test9 +javasoft.sqe.tests.api.java.lang.Class.ReflectTests -TestCaseID ReflectTest2109 +JCK-114a|api|java_lang|Class|ReflectTests|Test10 +javasoft.sqe.tests.api.java.lang.Class.ReflectTests -TestCaseID ReflectTest2110 +JCK-114a|api|java_lang|Class|ReflectTests|Test11 +javasoft.sqe.tests.api.java.lang.Class.ReflectTests -TestCaseID ReflectTest2111 +JCK-114a|api|java_lang|Class|ReflectTests|Test12 +javasoft.sqe.tests.api.java.lang.Class.ReflectTests -TestCaseID ReflectTest2112 +JCK-114a|api|java_lang|Class|ReflectTests|Test13 +javasoft.sqe.tests.api.java.lang.Class.ReflectTests -TestCaseID ReflectTest2113 +JCK-114a|api|java_lang|Class|ReflectTests|Test14 +javasoft.sqe.tests.api.java.lang.Class.ReflectTests -TestCaseID ReflectTest2114 +JCK-114a|api|java_lang|Class|ReflectTests|Test15 +javasoft.sqe.tests.api.java.lang.Class.ReflectTests -TestCaseID ReflectTest2115 +JCK-114a|api|java_lang|Class|ReflectTests|Test16 +javasoft.sqe.tests.api.java.lang.Class.ReflectTests -TestCaseID ReflectTest2116 +JCK-114a|api|java_lang|Class|ReflectTests|Test17 +javasoft.sqe.tests.api.java.lang.Class.ReflectTests -TestCaseID ReflectTest2117 +JCK-114a|api|java_lang|Class|ReflectTests|Test18 +javasoft.sqe.tests.api.java.lang.Class.ReflectTests -TestCaseID ReflectTest2118 +JCK-114a|api|java_lang|Class|ReflectTests|Test19 +javasoft.sqe.tests.api.java.lang.Class.ReflectTests -TestCaseID ReflectTest2119 +JCK-114a|api|java_lang|Class|ReflectTests|Test20 +javasoft.sqe.tests.api.java.lang.Class.ReflectTests -TestCaseID ReflectTest2120 +JCK-114a|api|java_lang|Class|ReflectTests|Test21 +javasoft.sqe.tests.api.java.lang.Class.ReflectTests -TestCaseID ReflectTest2121 +JCK-114a|api|java_lang|Class|ReflectTests|Test22 +javasoft.sqe.tests.api.java.lang.Class.ReflectTests -TestCaseID ReflectTest2122 +JCK-114a|api|java_lang|Class|ReflectTests|Test23 +javasoft.sqe.tests.api.java.lang.Class.ReflectTests -TestCaseID ReflectTest2123 +JCK-114a|api|java_lang|Class|ReflectTests|Test24 +javasoft.sqe.tests.api.java.lang.Class.ReflectTests -TestCaseID ReflectTest2124 +JCK-114a|api|java_lang|Class|ReflectTests|Test25 +javasoft.sqe.tests.api.java.lang.Class.ReflectTests -TestCaseID ReflectTest2125 +JCK-114a|api|java_lang|Class|ReflectTests|Test26 +javasoft.sqe.tests.api.java.lang.Class.ReflectTests -TestCaseID ReflectTest2126 +JCK-114a|api|java_lang|Class|ReflectTests|Test27 +javasoft.sqe.tests.api.java.lang.Class.ReflectTests -TestCaseID ReflectTest2127 +JCK-114a|api|java_lang|Class|ReflectTests|Test28 +javasoft.sqe.tests.api.java.lang.Class.ReflectTests -TestCaseID ReflectTest2128 +JCK-114a|api|java_lang|Class|ReflectTests|Test29 +javasoft.sqe.tests.api.java.lang.Class.ReflectTests -TestCaseID ReflectTest2129 +JCK-114a|api|java_lang|Class|ReflectTests|Test30 +javasoft.sqe.tests.api.java.lang.Class.ReflectTests -TestCaseID ReflectTest2130 +JCK-114a|api|java_lang|Class|ReflectTests|Test31 +javasoft.sqe.tests.api.java.lang.Class.ReflectTests -TestCaseID ReflectTest2131 +JCK-114a|api|java_lang|Class|SerializeTests|Test1 +javasoft.sqe.tests.api.java.lang.Class.SerializeTests -TestURL file:/G:/JCK-114a/tests/api/java_lang/Class/SerializeTests.html -TestCaseID ALL +JCK-114a|api|java_lang|Double|DoubleTests|Test1 +javasoft.sqe.tests.api.java.lang.Double.DoubleTests1 +JCK-114a|api|java_lang|Double|DoubleTests|Test3 +javasoft.sqe.tests.api.java.lang.Double.DoubleTests7 +JCK-114a|api|java_lang|Double|DoubleTests|Test4 +javasoft.sqe.tests.api.java.lang.Double.DoubleTests10 +JCK-114a|api|java_lang|Double|DoubleTests|Test5 +javasoft.sqe.tests.api.java.lang.Double.DoubleTests13 +JCK-114a|api|java_lang|Double|DoubleTests|Test6 +javasoft.sqe.tests.api.java.lang.Double.DoubleTests16 +JCK-114a|api|java_lang|Double|DoubleTests|Test7 +javasoft.sqe.tests.api.java.lang.Double.DoubleTests19 +JCK-114a|api|java_lang|Double|DoubleTests|Test8 +javasoft.sqe.tests.api.java.lang.Double.DoubleTests22 +JCK-114a|api|java_lang|Double|DoubleTests|Test9 +javasoft.sqe.tests.api.java.lang.Double.DoubleTests25 +JCK-114a|api|java_lang|Double|DoubleTests|Test10 +javasoft.sqe.tests.api.java.lang.Double.DoubleTests28 +JCK-114a|api|java_lang|Double|DoubleTests|Test11 +javasoft.sqe.tests.api.java.lang.Double.DoubleTests31 +JCK-114a|api|java_lang|Double|DoubleTests|Test12 +javasoft.sqe.tests.api.java.lang.Double.DoubleTests34 +JCK-114a|api|java_lang|Double|DoubleTests|Test13 +javasoft.sqe.tests.api.java.lang.Double.DoubleTests37 +JCK-114a|api|java_lang|Double|DoubleTests|Test14 +javasoft.sqe.tests.api.java.lang.Double.DoubleTests40 +JCK-114a|api|java_lang|Double|DoubleTests|Test15 +javasoft.sqe.tests.api.java.lang.Double.DoubleTests43 +JCK-114a|api|java_lang|Double|DoubleTests|Test17 +javasoft.sqe.tests.api.java.lang.Double.DoubleTests49 +JCK-114a|api|java_lang|Double|DoubleTests|Test18 +javasoft.sqe.tests.api.java.lang.Double.DoubleTests52 +JCK-114a|api|java_lang|Double|DoubleTests|Test19 +javasoft.sqe.tests.api.java.lang.Double.DoubleTests56 +JCK-114a|api|java_lang|Double|manual|Test1 +javasoft.sqe.tests.api.java.lang.Double.VariableTest +JCK-114a|api|java_lang|Double|manual|Test2 +javasoft.sqe.tests.api.java.lang.Double.StringValues +JCK-114a|api|java_lang|Double|manual|Test3 +javasoft.sqe.tests.api.java.lang.Double.SerializeTests -TestURL file:/G:/JCK-114a/tests/api/java_lang/Double/manual.html -TestCaseID ALL +JCK-114a|api|java_lang|Float|FloatTests|Test1 +javasoft.sqe.tests.api.java.lang.Float.FloatTests1 +JCK-114a|api|java_lang|Float|FloatTests|Test2 +javasoft.sqe.tests.api.java.lang.Float.FloatTests4 +JCK-114a|api|java_lang|Float|FloatTests|Test3 +javasoft.sqe.tests.api.java.lang.Float.FloatTests7 +JCK-114a|api|java_lang|Float|FloatTests|Test4 +javasoft.sqe.tests.api.java.lang.Float.FloatTests10 +JCK-114a|api|java_lang|Float|FloatTests|Test5 +javasoft.sqe.tests.api.java.lang.Float.FloatTests13 +JCK-114a|api|java_lang|Float|FloatTests|Test6 +javasoft.sqe.tests.api.java.lang.Float.FloatTests16 +JCK-114a|api|java_lang|Float|FloatTests|Test7 +javasoft.sqe.tests.api.java.lang.Float.FloatTests19 +JCK-114a|api|java_lang|Float|FloatTests|Test8 +javasoft.sqe.tests.api.java.lang.Float.FloatTests22 +JCK-114a|api|java_lang|Float|FloatTests|Test9 +javasoft.sqe.tests.api.java.lang.Float.FloatTests25 +JCK-114a|api|java_lang|Float|FloatTests|Test10 +javasoft.sqe.tests.api.java.lang.Float.FloatTests28 +JCK-114a|api|java_lang|Float|FloatTests|Test11 +javasoft.sqe.tests.api.java.lang.Float.FloatTests31 +JCK-114a|api|java_lang|Float|FloatTests|Test12 +javasoft.sqe.tests.api.java.lang.Float.FloatTests34 +JCK-114a|api|java_lang|Float|FloatTests|Test13 +javasoft.sqe.tests.api.java.lang.Float.FloatTests37 +JCK-114a|api|java_lang|Float|FloatTests|Test14 +javasoft.sqe.tests.api.java.lang.Float.FloatTests40 +JCK-114a|api|java_lang|Float|FloatTests|Test15 +javasoft.sqe.tests.api.java.lang.Float.FloatTests43 +JCK-114a|api|java_lang|Float|FloatTests|Test17 +javasoft.sqe.tests.api.java.lang.Float.FloatTests49 +JCK-114a|api|java_lang|Float|FloatTests|Test18 +javasoft.sqe.tests.api.java.lang.Float.FloatTests52 +JCK-114a|api|java_lang|Float|FloatTests|Test19 +javasoft.sqe.tests.api.java.lang.Float.FloatTests55 +JCK-114a|api|java_lang|Float|FloatTests|Test20 +javasoft.sqe.tests.api.java.lang.Float.FloatTests58 +JCK-114a|api|java_lang|Float|manual|Test1 +javasoft.sqe.tests.api.java.lang.Float.VariableTest +JCK-114a|api|java_lang|Float|manual|Test2 +javasoft.sqe.tests.api.java.lang.Float.StringValues +JCK-114a|api|java_lang|Float|manual|Test3 +javasoft.sqe.tests.api.java.lang.Float.SerializeTests -TestURL file:/G:/JCK-114a/tests/api/java_lang/Float/manual.html -TestCaseID ALL +JCK-114a|api|java_lang|Integer|IntegerTests|Test1 +javasoft.sqe.tests.api.java.lang.Integer.IntegerTests1 +JCK-114a|api|java_lang|Integer|IntegerTests|Test2 +javasoft.sqe.tests.api.java.lang.Integer.IntegerTests4 +JCK-114a|api|java_lang|Integer|IntegerTests|Test3 +javasoft.sqe.tests.api.java.lang.Integer.IntegerTests8 +JCK-114a|api|java_lang|Integer|IntegerTests|Test4 +javasoft.sqe.tests.api.java.lang.Integer.IntegerTests11 +JCK-114a|api|java_lang|Integer|IntegerTests|Test5 +javasoft.sqe.tests.api.java.lang.Integer.IntegerTests14 +JCK-114a|api|java_lang|Integer|IntegerTests|Test6 +javasoft.sqe.tests.api.java.lang.Integer.IntegerTests17 +JCK-114a|api|java_lang|Integer|IntegerTests|Test7 +javasoft.sqe.tests.api.java.lang.Integer.IntegerTests20 +JCK-114a|api|java_lang|Integer|IntegerTests|Test8 +javasoft.sqe.tests.api.java.lang.Integer.IntegerTests23 +JCK-114a|api|java_lang|Integer|IntegerTests|Test9 +javasoft.sqe.tests.api.java.lang.Integer.IntegerTests26 +JCK-114a|api|java_lang|Integer|IntegerTests|Test10 +javasoft.sqe.tests.api.java.lang.Integer.IntegerTests29 +JCK-114a|api|java_lang|Integer|IntegerTests|Test11 +javasoft.sqe.tests.api.java.lang.Integer.IntegerTests32 +JCK-114a|api|java_lang|Integer|IntegerTests|Test12 +javasoft.sqe.tests.api.java.lang.Integer.IntegerTests35 +JCK-114a|api|java_lang|Integer|IntegerTests|Test13 +javasoft.sqe.tests.api.java.lang.Integer.IntegerTests39 +JCK-114a|api|java_lang|Integer|IntegerTests|Test14 +javasoft.sqe.tests.api.java.lang.Integer.IntegerTests42 +JCK-114a|api|java_lang|Integer|IntegerTests|Test15 +javasoft.sqe.tests.api.java.lang.Integer.IntegerTests45 +JCK-114a|api|java_lang|Integer|IntegerTests|Test16 +javasoft.sqe.tests.api.java.lang.Integer.IntegerTests49 +JCK-114a|api|java_lang|Integer|IntegerTests|Test18 +javasoft.sqe.tests.api.java.lang.Integer.IntegerTests56 +JCK-114a|api|java_lang|Integer|IntegerTests|Test19 +javasoft.sqe.tests.api.java.lang.Integer.IntegerTests59 +JCK-114a|api|java_lang|Integer|IntegerTests|Test20 +javasoft.sqe.tests.api.java.lang.Integer.IntegerTests62 +JCK-114a|api|java_lang|Integer|IntegerTests|Test21 +javasoft.sqe.tests.api.java.lang.Integer.IntegerTests65 +JCK-114a|api|java_lang|Integer|IntegerTests|Test22 +javasoft.sqe.tests.api.java.lang.Integer.IntegerTests68 +JCK-114a|api|java_lang|Integer|IntegerTests|Test23 +javasoft.sqe.tests.api.java.lang.Integer.IntegerTests72 +JCK-114a|api|java_lang|Integer|manual|Test1 +javasoft.sqe.tests.api.java.lang.Integer.VariableTest +JCK-114a|api|java_lang|Integer|manual|Test2 +javasoft.sqe.tests.api.java.lang.Integer.StringValues +JCK-114a|api|java_lang|Integer|manual|Test3 +javasoft.sqe.tests.api.java.lang.Integer.SerializeTests -TestURL file:/G:/JCK-114a/tests/api/java_lang/Integer/manual.html -TestCaseID ALL -FileName serial.ser +JCK-114a|api|java_lang|Long|LongTests|Test1 +javasoft.sqe.tests.api.java.lang.Long.LongTests1 +JCK-114a|api|java_lang|Long|LongTests|Test2 +javasoft.sqe.tests.api.java.lang.Long.LongTests4 +JCK-114a|api|java_lang|Long|LongTests|Test3 +javasoft.sqe.tests.api.java.lang.Long.LongTests7 +JCK-114a|api|java_lang|Long|LongTests|Test4 +javasoft.sqe.tests.api.java.lang.Long.LongTests10 +JCK-114a|api|java_lang|Long|LongTests|Test5 +javasoft.sqe.tests.api.java.lang.Long.LongTests13 +JCK-114a|api|java_lang|Long|LongTests|Test6 +javasoft.sqe.tests.api.java.lang.Long.LongTests16 +JCK-114a|api|java_lang|Long|LongTests|Test7 +javasoft.sqe.tests.api.java.lang.Long.LongTests19 +JCK-114a|api|java_lang|Long|LongTests|Test9 +javasoft.sqe.tests.api.java.lang.Long.LongTests27 +JCK-114a|api|java_lang|Long|LongTests|Test10 +javasoft.sqe.tests.api.java.lang.Long.LongTests30 +JCK-114a|api|java_lang|Long|LongTests|Test11 +javasoft.sqe.tests.api.java.lang.Long.LongTests33 +JCK-114a|api|java_lang|Long|LongTests|Test12 +javasoft.sqe.tests.api.java.lang.Long.LongTests37 +JCK-114a|api|java_lang|Long|LongTests|Test13 +javasoft.sqe.tests.api.java.lang.Long.LongTests40 +JCK-114a|api|java_lang|Long|LongTests|Test14 +javasoft.sqe.tests.api.java.lang.Long.LongTests43 +JCK-114a|api|java_lang|Long|LongTests|Test15 +javasoft.sqe.tests.api.java.lang.Long.LongTests47 +JCK-114a|api|java_lang|Long|LongTests|Test16 +javasoft.sqe.tests.api.java.lang.Long.LongTests50 +JCK-114a|api|java_lang|Long|LongTests|Test17 +javasoft.sqe.tests.api.java.lang.Long.LongTests53 +JCK-114a|api|java_lang|Long|LongTests|Test18 +javasoft.sqe.tests.api.java.lang.Long.LongTests56 +JCK-114a|api|java_lang|Long|LongTests|Test19 +javasoft.sqe.tests.api.java.lang.Long.LongTests59 +JCK-114a|api|java_lang|Long|LongTests|Test20 +javasoft.sqe.tests.api.java.lang.Long.LongTests62 +JCK-114a|api|java_lang|Long|LongTests|Test21 +javasoft.sqe.tests.api.java.lang.Long.LongTests65 +JCK-114a|api|java_lang|Long|LongTests|Test22 +javasoft.sqe.tests.api.java.lang.Long.LongTests69 +JCK-114a|api|java_lang|Long|LongTests|Test23 +javasoft.sqe.tests.api.java.lang.Long.LongTests72 +JCK-114a|api|java_lang|Long|manual|Test1 +javasoft.sqe.tests.api.java.lang.Long.VariableTest +JCK-114a|api|java_lang|Long|manual|Test2 +javasoft.sqe.tests.api.java.lang.Long.StringValues +JCK-114a|api|java_lang|Long|manual|Test3 +javasoft.sqe.tests.api.java.lang.Long.SerializeTests -TestURL file:/G:/JCK-114a/tests/api/java_lang/Long/manual.html -TestCaseID ALL +JCK-114a|api|java_lang|Math|MathTests|Test1 +javasoft.sqe.tests.api.java.lang.Math.MathTests1 +JCK-114a|api|java_lang|Math|MathTests|Test2 +javasoft.sqe.tests.api.java.lang.Math.MathTests5 +JCK-114a|api|java_lang|Math|MathTests|Test3 +javasoft.sqe.tests.api.java.lang.Math.MathTests9 +JCK-114a|api|java_lang|Math|MathTests|Test4 +javasoft.sqe.tests.api.java.lang.Math.MathTests13 +JCK-114a|api|java_lang|Math|MathTests|Test5 +javasoft.sqe.tests.api.java.lang.Math.MathTests17 +JCK-114a|api|java_lang|Math|MathTests|Test6 +javasoft.sqe.tests.api.java.lang.Math.MathTests20 +JCK-114a|api|java_lang|Math|MathTests|Test7 +javasoft.sqe.tests.api.java.lang.Math.MathTests24 +JCK-114a|api|java_lang|Math|MathTests|Test9 +javasoft.sqe.tests.api.java.lang.Math.MathTests31 +JCK-114a|api|java_lang|Math|MathTests|Test10 +javasoft.sqe.tests.api.java.lang.Math.MathTests34 +JCK-114a|api|java_lang|Math|MathTests|Test11 +javasoft.sqe.tests.api.java.lang.Math.MathTests37 +JCK-114a|api|java_lang|Math|MathTests|Test12 +javasoft.sqe.tests.api.java.lang.Math.MathTests40 +JCK-114a|api|java_lang|Math|MathTests|Test13 +javasoft.sqe.tests.api.java.lang.Math.MathTests42 +JCK-114a|api|java_lang|Math|MathTests|Test14 +javasoft.sqe.tests.api.java.lang.Math.MathTests45 +JCK-114a|api|java_lang|Math|MathTests|Test15 +javasoft.sqe.tests.api.java.lang.Math.MathTests48 +JCK-114a|api|java_lang|Math|MathTests|Test16 +javasoft.sqe.tests.api.java.lang.Math.MathTests52 +JCK-114a|api|java_lang|Math|MathTests|Test17 +javasoft.sqe.tests.api.java.lang.Math.MathTests56 +JCK-114a|api|java_lang|Math|MathTests|Test18 +javasoft.sqe.tests.api.java.lang.Math.MathTests59 +JCK-114a|api|java_lang|Math|manual|Test7 +javasoft.sqe.tests.api.java.lang.Math.IEEEremainder_test +JCK-114a|api|java_lang|Math|manual|Test11 +javasoft.sqe.tests.api.java.lang.Math.sqrt_test +JCK-114a|api|java_lang|Number|index|Test1 +javasoft.sqe.tests.api.java.lang.Number.NumberTest +JCK-114a|api|java_lang|Number|index|Test2 +javasoft.sqe.tests.api.java.lang.Number.SerializeTests -TestURL file:/G:/JCK-114a/tests/api/java_lang/Number/index.html -TestCaseID ALL +JCK-114a|api|java_lang|Object|desc|Test1 +javasoft.sqe.tests.api.java.lang.Object.CtorTests -TestCaseID ALL +JCK-114a|api|java_lang|Object|desc|Test2 +javasoft.sqe.tests.api.java.lang.Object.CloneTests -TestCaseID ALL +JCK-114a|api|java_lang|Object|desc|Test3 +javasoft.sqe.tests.api.java.lang.Object.EqualsTests -TestCaseID ALL +JCK-114a|api|java_lang|Object|desc|Test4 +javasoft.sqe.tests.api.java.lang.Object.FinalTests -TestCaseID ALL +JCK-114a|api|java_lang|Object|desc|Test5 +javasoft.sqe.tests.api.java.lang.Object.GetClassTests -TestCaseID ALL +JCK-114a|api|java_lang|Object|desc|Test6 +javasoft.sqe.tests.api.java.lang.Object.HashTests -TestCaseID ALL +JCK-114a|api|java_lang|Object|desc|Test7 +javasoft.sqe.tests.api.java.lang.Object.NotifyTests -TestCaseID ALL +JCK-114a|api|java_lang|Object|desc|Test8 +javasoft.sqe.tests.api.java.lang.Object.NotifyAllTests -TestCaseID ALL +JCK-114a|api|java_lang|Object|desc|Test9 +javasoft.sqe.tests.api.java.lang.Object.ToStringTests -TestCaseID ALL +JCK-114a|api|java_lang|Object|desc|Test10 +javasoft.sqe.tests.api.java.lang.Object.WaitTests -TestCaseID Object0014 Object0030 Object0049 +JCK-114a|api|java_lang|Object|desc|Test11 +javasoft.sqe.tests.api.java.lang.Object.WaitTests -TestCaseID Object0007 Object0008 Object0009 Object0031 Object0032 Object0033 Object0034 Object0035 Object0036 +JCK-114a|api|java_lang|Object|desc|Test12 +javasoft.sqe.tests.api.java.lang.Object.WaitTests -TestCaseID Object0010 Object0011 Object0012 Object0013 Object0037 Object0038 Object0039 Object0040 Object0041 Object0042 Object0043 Object0044 Object0045 Object0046 Object0047 Object0048 +JCK-114a|api|java_lang|RunnableTest|Test1 +javasoft.sqe.tests.api.java.lang.RunnableTest +JCK-114a|api|java_lang|Runtime|RuntimeTests|Test1 +javasoft.sqe.tests.api.java.lang.Runtime.RuntimeTests1 +JCK-114a|api|java_lang|Runtime|RuntimeTests|Test2 +javasoft.sqe.tests.api.java.lang.Runtime.RuntimeTests3 +JCK-114a|api|java_lang|Runtime|RuntimeTests|Test3 +javasoft.sqe.tests.api.java.lang.Runtime.RuntimeTests6 +JCK-114a|api|java_lang|Runtime|RuntimeTests|Test4 +javasoft.sqe.tests.api.java.lang.Runtime.RuntimeTests10 +JCK-114a|api|java_lang|Runtime|RuntimeTests|Test5 +javasoft.sqe.tests.api.java.lang.Runtime.RuntimeTests14 +JCK-114a|api|java_lang|Runtime|RuntimeTests|Test6 +javasoft.sqe.tests.api.java.lang.Runtime.RuntimeTests18 +JCK-114a|api|java_lang|Runtime|RuntimeTests|Test7 +javasoft.sqe.tests.api.java.lang.Runtime.RuntimeTests21 +JCK-114a|api|java_lang|Runtime|RuntimeTests|Test8 +javasoft.sqe.tests.api.java.lang.Runtime.RuntimeTests26 +JCK-114a|api|java_lang|Runtime|RuntimeTests|Test9 +javasoft.sqe.tests.api.java.lang.Runtime.RuntimeTests30 +JCK-114a|api|java_lang|Runtime|RuntimeTests|Test10 +javasoft.sqe.tests.api.java.lang.Runtime.RuntimeTests35 +JCK-114a|api|java_lang|Runtime|RuntimeTests|Test11 +javasoft.sqe.tests.api.java.lang.Runtime.RuntimeTests38 +JCK-114a|api|java_lang|Runtime|RuntimeTests|Test12 +javasoft.sqe.tests.api.java.lang.Runtime.RuntimeTests41 +JCK-114a|api|java_lang|Runtime|RuntimeTests|Test13 +javasoft.sqe.tests.api.java.lang.Runtime.RuntimeTests45 +JCK-114a|api|java_lang|Runtime|RuntimeTests|Test14 +javasoft.sqe.tests.api.java.lang.Runtime.RuntimeTests49 +JCK-114a|api|java_lang|Short|ShortTests|Test1 +javasoft.sqe.tests.api.java.lang.Short.ShortTests1 +JCK-114a|api|java_lang|Short|ShortTests|Test2 +javasoft.sqe.tests.api.java.lang.Short.ShortTests4 +JCK-114a|api|java_lang|Short|ShortTests|Test3 +javasoft.sqe.tests.api.java.lang.Short.ShortTests7 +JCK-114a|api|java_lang|Short|ShortTests|Test4 +javasoft.sqe.tests.api.java.lang.Short.ShortTests10 +JCK-114a|api|java_lang|Short|ShortTests|Test5 +javasoft.sqe.tests.api.java.lang.Short.ShortTests14 +JCK-114a|api|java_lang|Short|ShortTests|Test6 +javasoft.sqe.tests.api.java.lang.Short.ShortTests17 +JCK-114a|api|java_lang|Short|ShortTests|Test7 +javasoft.sqe.tests.api.java.lang.Short.ShortTests20 +JCK-114a|api|java_lang|Short|ShortTests|Test8 +javasoft.sqe.tests.api.java.lang.Short.ShortTests23 +JCK-114a|api|java_lang|Short|ShortTests|Test9 +javasoft.sqe.tests.api.java.lang.Short.ShortTests26 +JCK-114a|api|java_lang|Short|ShortTests|Test10 +javasoft.sqe.tests.api.java.lang.Short.ShortTests29 +JCK-114a|api|java_lang|Short|ShortTests|Test11 +javasoft.sqe.tests.api.java.lang.Short.ShortTests32 +JCK-114a|api|java_lang|Short|ShortTests|Test12 +javasoft.sqe.tests.api.java.lang.Short.ShortTests35 +JCK-114a|api|java_lang|Short|ShortTests|Test13 +javasoft.sqe.tests.api.java.lang.Short.ShortTests38 +JCK-114a|api|java_lang|Short|ShortTests|Test14 +javasoft.sqe.tests.api.java.lang.Short.ShortTests41 +JCK-114a|api|java_lang|Short|ShortTests|Test15 +javasoft.sqe.tests.api.java.lang.Short.ShortTests45 +JCK-114a|api|java_lang|Short|ShortTests|Test16 +javasoft.sqe.tests.api.java.lang.Short.ShortTests48 +JCK-114a|api|java_lang|Short|ShortTests|Test17 +javasoft.sqe.tests.api.java.lang.Short.ShortTests52 +JCK-114a|api|java_lang|Short|manual|Test1 +javasoft.sqe.tests.api.java.lang.Short.VariableTest +JCK-114a|api|java_lang|Short|manual|Test2 +javasoft.sqe.tests.api.java.lang.Short.StringValues +JCK-114a|api|java_lang|Short|manual|Test3 +javasoft.sqe.tests.api.java.lang.Short.SerializeTests -TestURL file:/G:/JCK-114a/tests/api/java_lang/Short/manual.html -TestCaseID ALL +JCK-114a|api|java_lang|String|LocaleStringTest|Test1 +javasoft.sqe.tests.api.java.lang.String.LocaleStringTest +JCK-114a|api|java_lang|String|serialize|Test1 +javasoft.sqe.tests.api.java.lang.String.SerializeTests -TestURL file:/G:/JCK-114a/tests/api/java_lang/String/serialize.html -TestCaseID ALL +JCK-114a|api|java_lang|String|manual|Test1 +javasoft.sqe.tests.api.java.lang.String.CtorTests -TestCaseID ALL -WorkDir E:/tmp/ -Test file:/G:/JCK-114a/tests/api/java_lang/String/manual.html +JCK-114a|api|java_lang|String|manual|Test2 +javasoft.sqe.tests.api.java.lang.String.CharAtTests -TestCaseID ALL -WorkDir E:/tmp/ -Test file:/G:/JCK-114a/tests/api/java_lang/String/manual.html +JCK-114a|api|java_lang|String|manual|Test3 +javasoft.sqe.tests.api.java.lang.String.CompareToTests -TestCaseID ALL -WorkDir E:/tmp/ -Test file:/G:/JCK-114a/tests/api/java_lang/String/manual.html +JCK-114a|api|java_lang|String|manual|Test4 +javasoft.sqe.tests.api.java.lang.String.ConcatTests -TestCaseID ALL -WorkDir E:/tmp/ -Test file:/G:/JCK-114a/tests/api/java_lang/String/manual.html +JCK-114a|api|java_lang|String|manual|Test5 +javasoft.sqe.tests.api.java.lang.String.CopyValueOfTests -TestCaseID ALL -WorkDir E:/tmp/ -Test file:/G:/JCK-114a/tests/api/java_lang/String/manual.html +JCK-114a|api|java_lang|String|manual|Test6 +javasoft.sqe.tests.api.java.lang.String.EndsWithTests -TestCaseID ALL -WorkDir E:/tmp/ -Test file:/G:/JCK-114a/tests/api/java_lang/String/manual.html +JCK-114a|api|java_lang|String|manual|Test7 +javasoft.sqe.tests.api.java.lang.String.EqualsTests -TestCaseID ALL -WorkDir E:/tmp/ -Test file:/G:/JCK-114a/tests/api/java_lang/String/manual.html +JCK-114a|api|java_lang|String|manual|Test8 +javasoft.sqe.tests.api.java.lang.String.EqualsIgnoreCaseTests -TestCaseID ALL -WorkDir E:/tmp/ -Test file:/G:/JCK-114a/tests/api/java_lang/String/manual.html +JCK-114a|api|java_lang|String|manual|Test9 +javasoft.sqe.tests.api.java.lang.String.GetBytesTests -TestCaseID ALL -WorkDir E:/tmp/ -Test file:/G:/JCK-114a/tests/api/java_lang/String/manual.html +JCK-114a|api|java_lang|String|manual|Test10 +javasoft.sqe.tests.api.java.lang.String.GetCharsTests -TestCaseID ALL -WorkDir E:/tmp/ -Test file:/G:/JCK-114a/tests/api/java_lang/String/manual.html +JCK-114a|api|java_lang|String|manual|Test11 +javasoft.sqe.tests.api.java.lang.String.HashCodeTests -TestCaseID ALL -WorkDir E:/tmp/ -Test file:/G:/JCK-114a/tests/api/java_lang/String/manual.html +JCK-114a|api|java_lang|String|manual|Test12 +javasoft.sqe.tests.api.java.lang.String.IndexOfTests -TestCaseID ALL -WorkDir E:/tmp/ -Test file:/G:/JCK-114a/tests/api/java_lang/String/manual.html +JCK-114a|api|java_lang|String|manual|Test13 +javasoft.sqe.tests.api.java.lang.String.InternTests -TestCaseID ALL -WorkDir E:/tmp/ -Test file:/G:/JCK-114a/tests/api/java_lang/String/manual.html +JCK-114a|api|java_lang|String|manual|Test14 +javasoft.sqe.tests.api.java.lang.String.LastIndexOfTests -TestCaseID ALL -WorkDir E:/tmp/ -Test file:/G:/JCK-114a/tests/api/java_lang/String/manual.html +JCK-114a|api|java_lang|String|manual|Test15 +javasoft.sqe.tests.api.java.lang.String.LengthTests -TestCaseID ALL -WorkDir E:/tmp/ -Test file:/G:/JCK-114a/tests/api/java_lang/String/manual.html +JCK-114a|api|java_lang|String|manual|Test17 +javasoft.sqe.tests.api.java.lang.String.ReplaceTests -TestCaseID ALL -WorkDir E:/tmp/ -Test file:/G:/JCK-114a/tests/api/java_lang/String/manual.html +JCK-114a|api|java_lang|String|manual|Test18 +javasoft.sqe.tests.api.java.lang.String.StartsWithTests -TestCaseID ALL -WorkDir E:/tmp/ -Test file:/G:/JCK-114a/tests/api/java_lang/String/manual.html +JCK-114a|api|java_lang|String|manual|Test19 +javasoft.sqe.tests.api.java.lang.String.SubstringTests -TestCaseID ALL -WorkDir E:/tmp/ -Test file:/G:/JCK-114a/tests/api/java_lang/String/manual.html +JCK-114a|api|java_lang|String|manual|Test20 +javasoft.sqe.tests.api.java.lang.String.ToCharArrayTests -TestCaseID ALL -WorkDir E:/tmp/ -Test file:/G:/JCK-114a/tests/api/java_lang/String/manual.html +JCK-114a|api|java_lang|String|manual|Test21 +javasoft.sqe.tests.api.java.lang.String.ToLowerCaseTests -TestCaseID ALL -WorkDir E:/tmp/ -Test file:/G:/JCK-114a/tests/api/java_lang/String/manual.html +JCK-114a|api|java_lang|String|manual|Test22 +javasoft.sqe.tests.api.java.lang.String.ToUpperCaseTests -TestCaseID ALL -WorkDir E:/tmp/ -Test file:/G:/JCK-114a/tests/api/java_lang/String/manual.html +JCK-114a|api|java_lang|String|manual|Test23 +javasoft.sqe.tests.api.java.lang.String.ToStringTests -TestCaseID ALL -WorkDir E:/tmp/ -Test file:/G:/JCK-114a/tests/api/java_lang/String/manual.html +JCK-114a|api|java_lang|String|manual|Test24 +javasoft.sqe.tests.api.java.lang.String.TrimTests -TestCaseID ALL -WorkDir E:/tmp/ -Test file:/G:/JCK-114a/tests/api/java_lang/String/manual.html +JCK-114a|api|java_lang|String|manual|Test25 +javasoft.sqe.tests.api.java.lang.String.ValueOfTests -TestCaseID ALL -WorkDir E:/tmp/ -Test file:/G:/JCK-114a/tests/api/java_lang/String/manual.html +JCK-114a|api|java_lang|StringBuffer|StringBufferTests|Test1 +javasoft.sqe.tests.api.java.lang.StringBuffer.StringBufferTests1 +JCK-114a|api|java_lang|StringBuffer|StringBufferTests|Test2 +javasoft.sqe.tests.api.java.lang.StringBuffer.StringBufferTests6 +JCK-114a|api|java_lang|StringBuffer|StringBufferTests|Test3 +javasoft.sqe.tests.api.java.lang.StringBuffer.StringBufferTests11 +JCK-114a|api|java_lang|StringBuffer|StringBufferTests|Test4 +javasoft.sqe.tests.api.java.lang.StringBuffer.StringBufferTests15 +JCK-114a|api|java_lang|StringBuffer|StringBufferTests|Test5 +javasoft.sqe.tests.api.java.lang.StringBuffer.StringBufferTests20 +JCK-114a|api|java_lang|StringBuffer|StringBufferTests|Test6 +javasoft.sqe.tests.api.java.lang.StringBuffer.StringBufferTests24 +JCK-114a|api|java_lang|StringBuffer|StringBufferTests|Test7 +javasoft.sqe.tests.api.java.lang.StringBuffer.StringBufferTests28 +JCK-114a|api|java_lang|StringBuffer|StringBufferTests|Test8 +javasoft.sqe.tests.api.java.lang.StringBuffer.StringBufferTests33 +JCK-114a|api|java_lang|StringBuffer|StringBufferTests|Test9 +javasoft.sqe.tests.api.java.lang.StringBuffer.StringBufferTests38 +JCK-114a|api|java_lang|StringBuffer|StringBufferTests|Test10 +javasoft.sqe.tests.api.java.lang.StringBuffer.StringBufferTests42 +JCK-114a|api|java_lang|StringBuffer|StringBufferTests|Test11 +javasoft.sqe.tests.api.java.lang.StringBuffer.StringBufferTests47 +JCK-114a|api|java_lang|StringBuffer|StringBufferTests|Test12 +javasoft.sqe.tests.api.java.lang.StringBuffer.StringBufferTests51 +JCK-114a|api|java_lang|StringBuffer|StringBufferTests|Test13 +javasoft.sqe.tests.api.java.lang.StringBuffer.StringBufferTests55 +JCK-114a|api|java_lang|StringBuffer|StringBufferTests|Test14 +javasoft.sqe.tests.api.java.lang.StringBuffer.StringBufferTests60 +JCK-114a|api|java_lang|StringBuffer|StringBufferTests|Test15 +javasoft.sqe.tests.api.java.lang.StringBuffer.StringBufferTests64 +JCK-114a|api|java_lang|StringBuffer|StringBufferTests|Test16 +javasoft.sqe.tests.api.java.lang.StringBuffer.StringBufferTests71 +JCK-114a|api|java_lang|StringBuffer|StringBufferTests|Test17 +javasoft.sqe.tests.api.java.lang.StringBuffer.StringBufferTests76 +JCK-114a|api|java_lang|StringBuffer|StringBufferTests|Test18 +javasoft.sqe.tests.api.java.lang.StringBuffer.StringBufferTests80 +JCK-114a|api|java_lang|StringBuffer|StringBufferTests|Test19 +javasoft.sqe.tests.api.java.lang.StringBuffer.StringBufferTests84 +JCK-114a|api|java_lang|StringBuffer|StringBufferTests|Test20 +javasoft.sqe.tests.api.java.lang.StringBuffer.StringBufferTests91 +JCK-114a|api|java_lang|StringBuffer|StringBufferTests|Test21 +javasoft.sqe.tests.api.java.lang.StringBuffer.StringBufferTests96 +JCK-114a|api|java_lang|StringBuffer|StringBufferTests|Test22 +javasoft.sqe.tests.api.java.lang.StringBuffer.StringBufferTests100 +JCK-114a|api|java_lang|StringBuffer|StringBufferTests|Test23 +javasoft.sqe.tests.api.java.lang.StringBuffer.StringBufferTests104 +JCK-114a|api|java_lang|StringBuffer|StringBufferTests|Test24 +javasoft.sqe.tests.api.java.lang.StringBuffer.StringBufferTests107 +JCK-114a|api|java_lang|StringBuffer|StringBufferTests|Test25 +javasoft.sqe.tests.api.java.lang.StringBuffer.StringBufferTests109 +JCK-114a|api|java_lang|StringBuffer|StringBufferTests|Test26 +javasoft.sqe.tests.api.java.lang.StringBuffer.StringBufferTests112 +JCK-114a|api|java_lang|StringBuffer|StringBufferTests|Test27 +javasoft.sqe.tests.api.java.lang.StringBuffer.StringBufferTests116 +JCK-114a|api|java_lang|StringBuffer|StringBufferTests|Test28 +javasoft.sqe.tests.api.java.lang.StringBuffer.StringBufferTests119 +JCK-114a|api|java_lang|StringBuffer|StringBufferTests|Test29 +javasoft.sqe.tests.api.java.lang.StringBuffer.StringBufferTests123 +JCK-114a|api|java_lang|StringBuffer|StringBufferTests|Test30 +javasoft.sqe.tests.api.java.lang.StringBuffer.StringBufferTests130 +JCK-114a|api|java_lang|StringBuffer|StringBufferTests|Test31 +javasoft.sqe.tests.api.java.lang.StringBuffer.StringBufferTests133 +JCK-114a|api|java_lang|StringBuffer|StringBufferTests|Test32 +javasoft.sqe.tests.api.java.lang.StringBuffer.StringBufferTests136 +JCK-114a|api|java_lang|StringBuffer|StringBufferTests|Test33 +javasoft.sqe.tests.api.java.lang.StringBuffer.StringBufferTests141 +JCK-114a|api|java_lang|StringBuffer|StringBufferTests|Test34 +javasoft.sqe.tests.api.java.lang.StringBuffer.StringBufferTests147 +JCK-114a|api|java_lang|StringBuffer|StringBufferTests|Test35 +javasoft.sqe.tests.api.java.lang.StringBuffer.StringBufferTests153 +JCK-114a|api|java_lang|StringBuffer|StringBufferTests|Test36 +javasoft.sqe.tests.api.java.lang.StringBuffer.StringBufferTests159 +JCK-114a|api|java_lang|StringBuffer|StringBufferTests|Test37 +javasoft.sqe.tests.api.java.lang.StringBuffer.StringBufferTests165 +JCK-114a|api|java_lang|StringBuffer|StringBufferTests|Test38 +javasoft.sqe.tests.api.java.lang.StringBuffer.StringBufferTests168 +JCK-114a|api|java_lang|StringBuffer|index|Test1 +javasoft.sqe.tests.api.java.lang.StringBuffer.SerializeTests -TestURL file:/G:/JCK-114a/tests/api/java_lang/StringBuffer/index.html -TestCaseID ALL +JCK-114a|api|java_lang|System|SystemTests|Test1 +javasoft.sqe.tests.api.java.lang.System.SystemTests1 +JCK-114a|api|java_lang|System|SystemTests|Test2 +javasoft.sqe.tests.api.java.lang.System.SystemTests4 +JCK-114a|api|java_lang|System|SystemTests|Test3 +javasoft.sqe.tests.api.java.lang.System.SystemTests7 +JCK-114a|api|java_lang|System|SystemTests|Test4 +javasoft.sqe.tests.api.java.lang.System.SystemTests10 +JCK-114a|api|java_lang|System|SystemTests|Test5 +javasoft.sqe.tests.api.java.lang.System.SystemTests12 +JCK-114a|api|java_lang|System|SystemTests|Test6 +javasoft.sqe.tests.api.java.lang.System.SystemTests19 +JCK-114a|api|java_lang|System|SystemTests|Test7 +javasoft.sqe.tests.api.java.lang.System.SystemTests22 +JCK-114a|api|java_lang|System|SystemTests|Test8 +javasoft.sqe.tests.api.java.lang.System.SystemTests24 +JCK-114a|api|java_lang|System|SystemTests|Test9 +javasoft.sqe.tests.api.java.lang.System.SystemTests28 +JCK-114a|api|java_lang|System|SystemTests|Test10 +javasoft.sqe.tests.api.java.lang.System.SystemTests32 +JCK-114a|api|java_lang|System|SystemTests|Test11 +javasoft.sqe.tests.api.java.lang.System.SystemTests35 +JCK-114a|api|java_lang|System|SystemTests|Test12 +javasoft.sqe.tests.api.java.lang.System.SystemTests38 +JCK-114a|api|java_lang|System|SystemTests|Test13 +javasoft.sqe.tests.api.java.lang.System.SystemTests41 +JCK-114a|api|java_lang|System|SystemTests|Test14 +javasoft.sqe.tests.api.java.lang.System.SystemTests44 +JCK-114a|api|java_lang|System|SystemTests|Test15 +javasoft.sqe.tests.api.java.lang.System.SystemTests46 +JCK-114a|api|java_lang|System|SystemTests|Test16 +javasoft.sqe.tests.api.java.lang.System.SystemTests48 +JCK-114a|api|java_lang|System|SystemTests|Test17 +javasoft.sqe.tests.api.java.lang.System.SystemTests51 +JCK-114a|api|java_lang|System|SystemTests|Test18 +javasoft.sqe.tests.api.java.lang.System.SystemTests54 +JCK-114a|api|java_lang|System|SystemTests|Test19 +javasoft.sqe.tests.api.java.lang.System.SystemTests57 +JCK-114a|api|java_lang|System|SystemTests|Test20 +javasoft.sqe.tests.api.java.lang.System.SystemTests60 +JCK-114a|api|java_lang|System|manual|Test1 +javasoft.sqe.tests.api.java.lang.System.SetSecurityMgrTest -TestCaseID ALL +JCK-114a|api|java_lang|Thread|ThreadTests|Test1 +javasoft.sqe.tests.api.java.lang.Thread.ThreadTests1 +JCK-114a|api|java_lang|Thread|ThreadTests|Test2 +javasoft.sqe.tests.api.java.lang.Thread.ThreadTests6 +JCK-114a|api|java_lang|Thread|ThreadTests|Test3 +javasoft.sqe.tests.api.java.lang.Thread.ThreadTests9 +JCK-114a|api|java_lang|Thread|ThreadTests|Test4 +javasoft.sqe.tests.api.java.lang.Thread.ThreadTests12 +JCK-114a|api|java_lang|Thread|ThreadTests|Test5 +javasoft.sqe.tests.api.java.lang.Thread.ThreadTests16 +JCK-114a|api|java_lang|Thread|ThreadTests|Test6 +javasoft.sqe.tests.api.java.lang.Thread.ThreadTests19 +JCK-114a|api|java_lang|Thread|ThreadTests|Test7 +javasoft.sqe.tests.api.java.lang.Thread.ThreadTests23 +JCK-114a|api|java_lang|Thread|ThreadTests|Test8 +javasoft.sqe.tests.api.java.lang.Thread.ThreadTests27 +JCK-114a|api|java_lang|Thread|ThreadTests|Test9 +javasoft.sqe.tests.api.java.lang.Thread.ThreadTests31 +JCK-114a|api|java_lang|Thread|ThreadTests|Test10 +javasoft.sqe.tests.api.java.lang.Thread.ThreadTests34 +JCK-114a|api|java_lang|Thread|ThreadTests|Test11 +javasoft.sqe.tests.api.java.lang.Thread.ThreadTests38 +JCK-114a|api|java_lang|Thread|ThreadTests|Test12 +javasoft.sqe.tests.api.java.lang.Thread.ThreadTests41 +JCK-114a|api|java_lang|Thread|ThreadTests|Test13 +javasoft.sqe.tests.api.java.lang.Thread.ThreadTests43 +JCK-114a|api|java_lang|Thread|ThreadTests|Test14 +javasoft.sqe.tests.api.java.lang.Thread.ThreadTests46 +JCK-114a|api|java_lang|Thread|ThreadTests|Test15 +javasoft.sqe.tests.api.java.lang.Thread.ThreadTests50 +JCK-114a|api|java_lang|Thread|ThreadTests|Test16 +javasoft.sqe.tests.api.java.lang.Thread.ThreadTests52 +JCK-114a|api|java_lang|Thread|ThreadTests|Test17 +javasoft.sqe.tests.api.java.lang.Thread.ThreadTests54 +JCK-114a|api|java_lang|Thread|ThreadTests|Test18 +javasoft.sqe.tests.api.java.lang.Thread.ThreadTests57 +JCK-114a|api|java_lang|Thread|ThreadTests|Test19 +javasoft.sqe.tests.api.java.lang.Thread.ThreadTests60 +JCK-114a|api|java_lang|Thread|ThreadTests|Test20 +javasoft.sqe.tests.api.java.lang.Thread.ThreadTests63 +JCK-114a|api|java_lang|Thread|ThreadTests|Test21 +javasoft.sqe.tests.api.java.lang.Thread.ThreadTests66 +JCK-114a|api|java_lang|Thread|ThreadTests|Test22 +javasoft.sqe.tests.api.java.lang.Thread.ThreadTests72 +JCK-114a|api|java_lang|Thread|ThreadTests|Test23 +javasoft.sqe.tests.api.java.lang.Thread.ThreadTests75 +JCK-114a|api|java_lang|Thread|ThreadTests|Test24 +javasoft.sqe.tests.api.java.lang.Thread.ThreadTests78 +JCK-114a|api|java_lang|Thread|ThreadTests|Test25 +javasoft.sqe.tests.api.java.lang.Thread.ThreadTests80 +JCK-114a|api|java_lang|Thread|ThreadTests|Test26 +javasoft.sqe.tests.api.java.lang.Thread.ThreadTests83 +JCK-114a|api|java_lang|Thread|ThreadTests|Test27 +javasoft.sqe.tests.api.java.lang.Thread.ThreadTests86 +JCK-114a|api|java_lang|Thread|ThreadTests|Test28 +javasoft.sqe.tests.api.java.lang.Thread.ThreadTests90 +JCK-114a|api|java_lang|Thread|ThreadTests|Test29 +javasoft.sqe.tests.api.java.lang.Thread.ThreadTests94 +JCK-114a|api|java_lang|Thread|ThreadTests|Test30 +javasoft.sqe.tests.api.java.lang.Thread.ThreadTests97 +JCK-114a|api|java_lang|Thread|ThreadTests|Test31 +javasoft.sqe.tests.api.java.lang.Thread.ThreadTests104 +JCK-114a|api|java_lang|Thread|ThreadTests|Test32 +javasoft.sqe.tests.api.java.lang.Thread.ThreadTests107 +JCK-114a|api|java_lang|Thread|ThreadTests|Test33 +javasoft.sqe.tests.api.java.lang.Thread.ThreadTests109 +JCK-114a|api|java_lang|Thread|ThreadTests|Test34 +javasoft.sqe.tests.api.java.lang.Thread.ThreadTests112 +JCK-114a|api|java_lang|ThreadGroup|ThreadGroupTests|Test1 +javasoft.sqe.tests.api.java.lang.ThreadGroup.ThreadGroupTests1 +JCK-114a|api|java_lang|ThreadGroup|ThreadGroupTests|Test2 +javasoft.sqe.tests.api.java.lang.ThreadGroup.ThreadGroupTests4 +JCK-114a|api|java_lang|ThreadGroup|ThreadGroupTests|Test3 +javasoft.sqe.tests.api.java.lang.ThreadGroup.ThreadGroupTests7 +JCK-114a|api|java_lang|ThreadGroup|ThreadGroupTests|Test4 +javasoft.sqe.tests.api.java.lang.ThreadGroup.ThreadGroupTests10 +JCK-114a|api|java_lang|ThreadGroup|ThreadGroupTests|Test5 +javasoft.sqe.tests.api.java.lang.ThreadGroup.ThreadGroupTests13 +JCK-114a|api|java_lang|ThreadGroup|ThreadGroupTests|Test6 +javasoft.sqe.tests.api.java.lang.ThreadGroup.ThreadGroupTests16 +JCK-114a|api|java_lang|ThreadGroup|ThreadGroupTests|Test7 +javasoft.sqe.tests.api.java.lang.ThreadGroup.ThreadGroupTests19 +JCK-114a|api|java_lang|ThreadGroup|ThreadGroupTests|Test9 +javasoft.sqe.tests.api.java.lang.ThreadGroup.ThreadGroupTests32 +JCK-114a|api|java_lang|ThreadGroup|ThreadGroupTests|Test10 +javasoft.sqe.tests.api.java.lang.ThreadGroup.ThreadGroupTests35 +JCK-114a|api|java_lang|ThreadGroup|ThreadGroupTests|Test11 +javasoft.sqe.tests.api.java.lang.ThreadGroup.ThreadGroupTests38 +JCK-114a|api|java_lang|ThreadGroup|ThreadGroupTests|Test13 +javasoft.sqe.tests.api.java.lang.ThreadGroup.ThreadGroupTests44 +JCK-114a|api|java_lang|ThreadGroup|ThreadGroupTests|Test14 +javasoft.sqe.tests.api.java.lang.ThreadGroup.ThreadGroupTests51 +JCK-114a|api|java_lang|ThreadGroup|ThreadGroupTests|Test16 +javasoft.sqe.tests.api.java.lang.ThreadGroup.ThreadGroupTests58 +JCK-114a|api|java_lang|ThreadGroup|ThreadGroupTests|Test17 +javasoft.sqe.tests.api.java.lang.ThreadGroup.ThreadGroupTests62 +JCK-114a|api|java_lang|Throwable|ThrowableTests|Test1 +javasoft.sqe.tests.api.java.lang.Throwable.ThrowableTests1 +JCK-114a|api|java_lang|Throwable|ThrowableTests|Test2 +javasoft.sqe.tests.api.java.lang.Throwable.ThrowableTests4 +JCK-114a|api|java_lang|Throwable|ThrowableTests|Test3 +javasoft.sqe.tests.api.java.lang.Throwable.ThrowableTests7 +JCK-114a|api|java_lang|Throwable|index|Test1 +javasoft.sqe.tests.api.java.lang.Throwable.SerializeTests -TestURL file:/G:/JCK-114a/tests/api/java_lang/Throwable/index.html -FileName serial.ser -TestCaseID ALL +JCK-114a|api|java_lang|errors|errors|Test1 +javasoft.sqe.tests.api.java.lang.ErrorsTest +JCK-114a|api|java_lang|exceptions|exceptions|Test1 +javasoft.sqe.tests.api.java.lang.ExceptionsTest +JCK-114a|api|java_lang|reflect|InvocationTargetException|index|Test1 +javasoft.sqe.tests.api.java.lang.reflect.InvocationTargetException.CtorTests -TestCaseID InvocationException0001 +JCK-114a|api|java_lang|reflect|InvocationTargetException|index|Test2 +javasoft.sqe.tests.api.java.lang.reflect.InvocationTargetException.CtorTests -TestCaseID InvocationException0002 +JCK-114a|api|java_lang|reflect|InvocationTargetException|index|Test3 +javasoft.sqe.tests.api.java.lang.reflect.InvocationTargetException.CtorTests -TestCaseID InvocationException0003 +JCK-114a|api|java_lang|reflect|Method|index|Test1 +javasoft.sqe.tests.api.java.lang.reflect.Method.MethodTests -TestCaseID MethodTest0101 +JCK-114a|api|java_lang|reflect|Method|index|Test2 +javasoft.sqe.tests.api.java.lang.reflect.Method.MethodTests -TestCaseID MethodTest0102 +JCK-114a|api|java_lang|reflect|Method|index|Test3 +javasoft.sqe.tests.api.java.lang.reflect.Method.MethodTests -TestCaseID MethodTest0103 +JCK-114a|api|java_lang|reflect|Method|index|Test4 +javasoft.sqe.tests.api.java.lang.reflect.Method.MethodTests -TestCaseID GetNameTest0201 +JCK-114a|api|java_lang|reflect|Method|index|Test5 +javasoft.sqe.tests.api.java.lang.reflect.Method.MethodTests -TestCaseID GetNameTest0202 +JCK-114a|api|java_lang|reflect|Method|index|Test6 +javasoft.sqe.tests.api.java.lang.reflect.Method.MethodTests -TestCaseID ReturnTypeTest0301 +JCK-114a|api|java_lang|reflect|Method|index|Test7 +javasoft.sqe.tests.api.java.lang.reflect.Method.MethodTests -TestCaseID ReturnTypeTest0302 +JCK-114a|api|java_lang|reflect|Method|index|Test8 +javasoft.sqe.tests.api.java.lang.reflect.Method.MethodTests -TestCaseID ModifierTest0401 +JCK-114a|api|java_lang|reflect|Method|index|Test9 +javasoft.sqe.tests.api.java.lang.reflect.Method.MethodTests -TestCaseID ModifierTest0402 +JCK-114a|api|java_lang|reflect|Method|index|Test10 +javasoft.sqe.tests.api.java.lang.reflect.Method.MethodTests -TestCaseID ToStringTest0501 +JCK-114a|api|java_lang|reflect|Method|index|Test11 +javasoft.sqe.tests.api.java.lang.reflect.Method.MethodTests -TestCaseID ToStringTest0502 +JCK-114a|api|java_lang|reflect|Method|index|Test12 +javasoft.sqe.tests.api.java.lang.reflect.Method.MethodTests -TestCaseID ParameterTest0601 +JCK-114a|api|java_lang|reflect|Method|index|Test13 +javasoft.sqe.tests.api.java.lang.reflect.Method.MethodTests -TestCaseID ParameterTest0602 +JCK-114a|api|java_lang|reflect|Method|index|Test14 +javasoft.sqe.tests.api.java.lang.reflect.Method.MHashEqualTests -TestCaseID MHashEqualTest0001 +JCK-114a|api|java_lang|reflect|Method|index|Test15 +javasoft.sqe.tests.api.java.lang.reflect.Method.MHashEqualTests -TestCaseID MHashEqualTest0002 +JCK-114a|api|java_lang|reflect|Method|index|Test16 +javasoft.sqe.tests.api.java.lang.reflect.Method.MHashEqualTests -TestCaseID MHashEqualTest0003 +JCK-114a|api|java_lang|reflect|Method|index|Test17 +javasoft.sqe.tests.api.java.lang.reflect.Method.MHashEqualTests -TestCaseID MHashEqualTest0004 +JCK-114a|api|java_lang|reflect|Method|index|Test18 +javasoft.sqe.tests.api.java.lang.reflect.Method.InvokeTests -TestCaseID InvokeTest0001 +JCK-114a|api|java_lang|reflect|Method|index|Test19 +javasoft.sqe.tests.api.java.lang.reflect.Method.InvokeTests -TestCaseID InvokeTest0002 +JCK-114a|api|java_lang|reflect|Method|index|Test20 +javasoft.sqe.tests.api.java.lang.reflect.Method.InvokeTests -TestCaseID InvokeTest0003 +JCK-114a|api|java_lang|reflect|Method|index|Test21 +javasoft.sqe.tests.api.java.lang.reflect.Method.InvokeTests -TestCaseID InvokeTest0004 +JCK-114a|api|java_lang|reflect|Method|index|Test22 +javasoft.sqe.tests.api.java.lang.reflect.Method.InvokeTests -TestCaseID InvokeTest0005 +JCK-114a|api|java_lang|reflect|Method|index|Test23 +javasoft.sqe.tests.api.java.lang.reflect.Method.InvokeTests -TestCaseID InvokeTest0006 +JCK-114a|api|java_lang|reflect|Method|index|Test24 +javasoft.sqe.tests.api.java.lang.reflect.Method.InvokeTests -TestCaseID InvokeTest0007 +JCK-114a|api|java_lang|reflect|Method|index|Test25 +javasoft.sqe.tests.api.java.lang.reflect.Method.InvokeTests -TestCaseID InvokeTest0008 +JCK-114a|api|java_lang|reflect|Method|index|Test26 +javasoft.sqe.tests.api.java.lang.reflect.Method.InvokeTests -TestCaseID InvokeTest0009 +JCK-114a|api|java_lang|reflect|Method|index|Test27 +javasoft.sqe.tests.api.java.lang.reflect.Method.InvokeTests -TestCaseID InvokeTest0010 +JCK-114a|api|java_lang|reflect|Method|index|Test28 +javasoft.sqe.tests.api.java.lang.reflect.Method.InvokeTests -TestCaseID InvokeTest0011 +JCK-114a|api|java_lang|reflect|Constructor|index|Test1 +javasoft.sqe.tests.api.java.lang.reflect.Constructor.ConstructorTests -TestCaseID ConstructorTest0001 +JCK-114a|api|java_lang|reflect|Constructor|index|Test2 +javasoft.sqe.tests.api.java.lang.reflect.Constructor.ConstructorTests -TestCaseID ConstructorTest0002 +JCK-114a|api|java_lang|reflect|Constructor|index|Test3 +javasoft.sqe.tests.api.java.lang.reflect.Constructor.ConstructorTests -TestCaseID ConstructorTest0003 +JCK-114a|api|java_lang|reflect|Constructor|index|Test4 +javasoft.sqe.tests.api.java.lang.reflect.Constructor.ConstructorTests -TestCaseID ConstructorTest0004 +JCK-114a|api|java_lang|reflect|Constructor|index|Test5 +javasoft.sqe.tests.api.java.lang.reflect.Constructor.ConstructorTests -TestCaseID ConstructorTest0005 +JCK-114a|api|java_lang|reflect|Constructor|index|Test6 +javasoft.sqe.tests.api.java.lang.reflect.Constructor.CHashEqualTests -TestCaseID CHashEqualTest0001 +JCK-114a|api|java_lang|reflect|Constructor|index|Test7 +javasoft.sqe.tests.api.java.lang.reflect.Constructor.CHashEqualTests -TestCaseID CHashEqualTest0002 +JCK-114a|api|java_lang|reflect|Constructor|index|Test8 +javasoft.sqe.tests.api.java.lang.reflect.Constructor.CHashEqualTests -TestCaseID CHashEqualTest0003 +JCK-114a|api|java_lang|reflect|Constructor|index|Test9 +javasoft.sqe.tests.api.java.lang.reflect.Constructor.CHashEqualTests -TestCaseID CHashEqualTest0004 +JCK-114a|api|java_lang|reflect|Constructor|index|Test10 +javasoft.sqe.tests.api.java.lang.reflect.Constructor.CNewInstanceTests -TestCaseID CNewInstanceTest0001 +JCK-114a|api|java_lang|reflect|Constructor|index|Test11 +javasoft.sqe.tests.api.java.lang.reflect.Constructor.CNewInstanceTests -TestCaseID CNewInstanceTest0002 +JCK-114a|api|java_lang|reflect|Constructor|index|Test12 +javasoft.sqe.tests.api.java.lang.reflect.Constructor.CNewInstanceTests -TestCaseID CNewInstanceTest0003 +JCK-114a|api|java_lang|reflect|Constructor|index|Test13 +javasoft.sqe.tests.api.java.lang.reflect.Constructor.CNewInstanceTests -TestCaseID CNewInstanceTest0004 +JCK-114a|api|java_lang|reflect|Constructor|index|Test14 +javasoft.sqe.tests.api.java.lang.reflect.Constructor.CNewInstanceTests -TestCaseID CNewInstanceTest0005 +JCK-114a|api|java_lang|reflect|Constructor|index|Test15 +javasoft.sqe.tests.api.java.lang.reflect.Constructor.CNewInstanceTests -TestCaseID CNewInstanceTest0006 +JCK-114a|api|java_lang|reflect|Constructor|index|Test16 +javasoft.sqe.tests.api.java.lang.reflect.Constructor.CNewInstanceTests -TestCaseID CNewInstanceTest0007 +JCK-114a|api|java_lang|reflect|Array|BoolArrayTests|Test1 +javasoft.sqe.tests.api.java.lang.reflect.Array.BoolArrayTests -TestCaseID BoolArrayTest0001 +JCK-114a|api|java_lang|reflect|Array|BoolArrayTests|Test2 +javasoft.sqe.tests.api.java.lang.reflect.Array.BoolArrayTests -TestCaseID BoolArrayTest0002 +JCK-114a|api|java_lang|reflect|Array|BoolArrayTests|Test3 +javasoft.sqe.tests.api.java.lang.reflect.Array.BoolArrayTests -TestCaseID BoolArrayTest0003 +JCK-114a|api|java_lang|reflect|Array|BoolArrayTests|Test4 +javasoft.sqe.tests.api.java.lang.reflect.Array.BoolArrayTests -TestCaseID BoolArrayTest0004 +JCK-114a|api|java_lang|reflect|Array|BoolArrayTests|Test5 +javasoft.sqe.tests.api.java.lang.reflect.Array.BoolArrayTests -TestCaseID BoolArrayTest0005 +JCK-114a|api|java_lang|reflect|Array|BoolArrayTests|Test6 +javasoft.sqe.tests.api.java.lang.reflect.Array.BoolArrayTests -TestCaseID BoolArrayTest0006 +JCK-114a|api|java_lang|reflect|Array|BoolArrayTests|Test7 +javasoft.sqe.tests.api.java.lang.reflect.Array.BoolArrayTests -TestCaseID BoolArrayTest0007 +JCK-114a|api|java_lang|reflect|Array|BoolArrayTests|Test8 +javasoft.sqe.tests.api.java.lang.reflect.Array.BoolArrayTests -TestCaseID BoolArrayTest0008 +JCK-114a|api|java_lang|reflect|Array|BoolArrayTests|Test9 +javasoft.sqe.tests.api.java.lang.reflect.Array.BoolArrayTests -TestCaseID BoolArrayTest0009 +JCK-114a|api|java_lang|reflect|Array|BoolArrayTests|Test10 +javasoft.sqe.tests.api.java.lang.reflect.Array.BoolArrayTests -TestCaseID BoolArrayTest0010 +JCK-114a|api|java_lang|reflect|Array|BoolArrayTests|Test11 +javasoft.sqe.tests.api.java.lang.reflect.Array.BoolArrayTests -TestCaseID BoolArrayTest0011 +JCK-114a|api|java_lang|reflect|Array|BoolArrayTests|Test12 +javasoft.sqe.tests.api.java.lang.reflect.Array.BoolArrayTests -TestCaseID BoolArrayTest0012 +JCK-114a|api|java_lang|reflect|Array|BoolArrayTests|Test13 +javasoft.sqe.tests.api.java.lang.reflect.Array.BoolArrayTests -TestCaseID BoolArrayTest0013 +JCK-114a|api|java_lang|reflect|Array|BoolArrayTests|Test14 +javasoft.sqe.tests.api.java.lang.reflect.Array.BoolArrayTests -TestCaseID BoolArrayTest0014 +JCK-114a|api|java_lang|reflect|Array|BoolArrayTests|Test15 +javasoft.sqe.tests.api.java.lang.reflect.Array.BoolArrayTests -TestCaseID BoolArrayTest0015 +JCK-114a|api|java_lang|reflect|Array|BoolArrayTests|Test16 +javasoft.sqe.tests.api.java.lang.reflect.Array.BoolArrayTests -TestCaseID BoolArrayTest0016 +JCK-114a|api|java_lang|reflect|Array|BoolArrayTests|Test17 +javasoft.sqe.tests.api.java.lang.reflect.Array.BoolArrayTests -TestCaseID BoolArrayTest0017 +JCK-114a|api|java_lang|reflect|Array|BoolArrayTests|Test18 +javasoft.sqe.tests.api.java.lang.reflect.Array.BoolArrayTests -TestCaseID BoolArrayTest0018 +JCK-114a|api|java_lang|reflect|Array|BoolArrayTests|Test19 +javasoft.sqe.tests.api.java.lang.reflect.Array.BoolArrayTests -TestCaseID BoolArrayTest0019 +JCK-114a|api|java_lang|reflect|Array|BoolArrayTests|Test20 +javasoft.sqe.tests.api.java.lang.reflect.Array.BoolArrayTests -TestCaseID BoolArrayTest0020 +JCK-114a|api|java_lang|reflect|Array|BoolArrayTests|Test21 +javasoft.sqe.tests.api.java.lang.reflect.Array.BoolArrayTests -TestCaseID BoolArrayTest0021 +JCK-114a|api|java_lang|reflect|Array|BoolArrayTests|Test22 +javasoft.sqe.tests.api.java.lang.reflect.Array.BoolArrayTests -TestCaseID BoolArrayTest0022 +JCK-114a|api|java_lang|reflect|Array|BoolArrayTests|Test23 +javasoft.sqe.tests.api.java.lang.reflect.Array.BoolArrayTests -TestCaseID BoolArrayTest0023 +JCK-114a|api|java_lang|reflect|Array|BoolArrayTests|Test24 +javasoft.sqe.tests.api.java.lang.reflect.Array.BoolArrayTests -TestCaseID BoolArrayTest0024 +JCK-114a|api|java_lang|reflect|Array|ByteArrayTests|Test1 +javasoft.sqe.tests.api.java.lang.reflect.Array.ByteArrayTests -TestCaseID ByteArrayTest0001 +JCK-114a|api|java_lang|reflect|Array|ByteArrayTests|Test2 +javasoft.sqe.tests.api.java.lang.reflect.Array.ByteArrayTests -TestCaseID ByteArrayTest0002 +JCK-114a|api|java_lang|reflect|Array|ByteArrayTests|Test3 +javasoft.sqe.tests.api.java.lang.reflect.Array.ByteArrayTests -TestCaseID ByteArrayTest0003 +JCK-114a|api|java_lang|reflect|Array|ByteArrayTests|Test4 +javasoft.sqe.tests.api.java.lang.reflect.Array.ByteArrayTests -TestCaseID ByteArrayTest0004 +JCK-114a|api|java_lang|reflect|Array|ByteArrayTests|Test5 +javasoft.sqe.tests.api.java.lang.reflect.Array.ByteArrayTests -TestCaseID ByteArrayTest0005 +JCK-114a|api|java_lang|reflect|Array|ByteArrayTests|Test6 +javasoft.sqe.tests.api.java.lang.reflect.Array.ByteArrayTests -TestCaseID ByteArrayTest0006 +JCK-114a|api|java_lang|reflect|Array|ByteArrayTests|Test7 +javasoft.sqe.tests.api.java.lang.reflect.Array.ByteArrayTests -TestCaseID ByteArrayTest0007 +JCK-114a|api|java_lang|reflect|Array|ByteArrayTests|Test8 +javasoft.sqe.tests.api.java.lang.reflect.Array.ByteArrayTests -TestCaseID ByteArrayTest0008 +JCK-114a|api|java_lang|reflect|Array|ByteArrayTests|Test9 +javasoft.sqe.tests.api.java.lang.reflect.Array.ByteArrayTests -TestCaseID ByteArrayTest0009 +JCK-114a|api|java_lang|reflect|Array|ByteArrayTests|Test10 +javasoft.sqe.tests.api.java.lang.reflect.Array.ByteArrayTests -TestCaseID ByteArrayTest0010 +JCK-114a|api|java_lang|reflect|Array|ByteArrayTests|Test11 +javasoft.sqe.tests.api.java.lang.reflect.Array.ByteArrayTests -TestCaseID ByteArrayTest0011 +JCK-114a|api|java_lang|reflect|Array|ByteArrayTests|Test12 +javasoft.sqe.tests.api.java.lang.reflect.Array.ByteArrayTests -TestCaseID ByteArrayTest0012 +JCK-114a|api|java_lang|reflect|Array|ByteArrayTests|Test13 +javasoft.sqe.tests.api.java.lang.reflect.Array.ByteArrayTests -TestCaseID ByteArrayTest0013 +JCK-114a|api|java_lang|reflect|Array|ByteArrayTests|Test14 +javasoft.sqe.tests.api.java.lang.reflect.Array.ByteArrayTests -TestCaseID ByteArrayTest0014 +JCK-114a|api|java_lang|reflect|Array|ByteArrayTests|Test15 +javasoft.sqe.tests.api.java.lang.reflect.Array.ByteArrayTests -TestCaseID ByteArrayTest0015 +JCK-114a|api|java_lang|reflect|Array|ByteArrayTests|Test16 +javasoft.sqe.tests.api.java.lang.reflect.Array.ByteArrayTests -TestCaseID ByteArrayTest0016 +JCK-114a|api|java_lang|reflect|Array|ByteArrayTests|Test17 +javasoft.sqe.tests.api.java.lang.reflect.Array.ByteArrayTests -TestCaseID ByteArrayTest0017 +JCK-114a|api|java_lang|reflect|Array|ByteArrayTests|Test18 +javasoft.sqe.tests.api.java.lang.reflect.Array.ByteArrayTests -TestCaseID ByteArrayTest0018 +JCK-114a|api|java_lang|reflect|Array|ByteArrayTests|Test19 +javasoft.sqe.tests.api.java.lang.reflect.Array.ByteArrayTests -TestCaseID ByteArrayTest0019 +JCK-114a|api|java_lang|reflect|Array|ByteArrayTests|Test20 +javasoft.sqe.tests.api.java.lang.reflect.Array.ByteArrayTests -TestCaseID ByteArrayTest0020 +JCK-114a|api|java_lang|reflect|Array|ByteArrayTests|Test21 +javasoft.sqe.tests.api.java.lang.reflect.Array.ByteArrayTests -TestCaseID ByteArrayTest0021 +JCK-114a|api|java_lang|reflect|Array|ByteArrayTests|Test22 +javasoft.sqe.tests.api.java.lang.reflect.Array.ByteArrayTests -TestCaseID ByteArrayTest0022 +JCK-114a|api|java_lang|reflect|Array|ByteArrayTests|Test23 +javasoft.sqe.tests.api.java.lang.reflect.Array.ByteArrayTests -TestCaseID ByteArrayTest0023 +JCK-114a|api|java_lang|reflect|Array|ByteArrayTests|Test24 +javasoft.sqe.tests.api.java.lang.reflect.Array.ByteArrayTests -TestCaseID ByteArrayTest0024 +JCK-114a|api|java_lang|reflect|Array|CharArrayTests|Test1 +javasoft.sqe.tests.api.java.lang.reflect.Array.CharArrayTests -TestCaseID CharArrayTest0001 +JCK-114a|api|java_lang|reflect|Array|CharArrayTests|Test2 +javasoft.sqe.tests.api.java.lang.reflect.Array.CharArrayTests -TestCaseID CharArrayTest0002 +JCK-114a|api|java_lang|reflect|Array|CharArrayTests|Test3 +javasoft.sqe.tests.api.java.lang.reflect.Array.CharArrayTests -TestCaseID CharArrayTest0003 +JCK-114a|api|java_lang|reflect|Array|CharArrayTests|Test4 +javasoft.sqe.tests.api.java.lang.reflect.Array.CharArrayTests -TestCaseID CharArrayTest0004 +JCK-114a|api|java_lang|reflect|Array|CharArrayTests|Test5 +javasoft.sqe.tests.api.java.lang.reflect.Array.CharArrayTests -TestCaseID CharArrayTest0005 +JCK-114a|api|java_lang|reflect|Array|CharArrayTests|Test6 +javasoft.sqe.tests.api.java.lang.reflect.Array.CharArrayTests -TestCaseID CharArrayTest0006 +JCK-114a|api|java_lang|reflect|Array|CharArrayTests|Test7 +javasoft.sqe.tests.api.java.lang.reflect.Array.CharArrayTests -TestCaseID CharArrayTest0007 +JCK-114a|api|java_lang|reflect|Array|CharArrayTests|Test8 +javasoft.sqe.tests.api.java.lang.reflect.Array.CharArrayTests -TestCaseID CharArrayTest0008 +JCK-114a|api|java_lang|reflect|Array|CharArrayTests|Test9 +javasoft.sqe.tests.api.java.lang.reflect.Array.CharArrayTests -TestCaseID CharArrayTest0009 +JCK-114a|api|java_lang|reflect|Array|CharArrayTests|Test10 +javasoft.sqe.tests.api.java.lang.reflect.Array.CharArrayTests -TestCaseID CharArrayTest0010 +JCK-114a|api|java_lang|reflect|Array|CharArrayTests|Test11 +javasoft.sqe.tests.api.java.lang.reflect.Array.CharArrayTests -TestCaseID CharArrayTest0011 +JCK-114a|api|java_lang|reflect|Array|CharArrayTests|Test12 +javasoft.sqe.tests.api.java.lang.reflect.Array.CharArrayTests -TestCaseID CharArrayTest0012 +JCK-114a|api|java_lang|reflect|Array|CharArrayTests|Test13 +javasoft.sqe.tests.api.java.lang.reflect.Array.CharArrayTests -TestCaseID CharArrayTest0013 +JCK-114a|api|java_lang|reflect|Array|CharArrayTests|Test14 +javasoft.sqe.tests.api.java.lang.reflect.Array.CharArrayTests -TestCaseID CharArrayTest0014 +JCK-114a|api|java_lang|reflect|Array|CharArrayTests|Test15 +javasoft.sqe.tests.api.java.lang.reflect.Array.CharArrayTests -TestCaseID CharArrayTest0015 +JCK-114a|api|java_lang|reflect|Array|CharArrayTests|Test16 +javasoft.sqe.tests.api.java.lang.reflect.Array.CharArrayTests -TestCaseID CharArrayTest0016 +JCK-114a|api|java_lang|reflect|Array|CharArrayTests|Test17 +javasoft.sqe.tests.api.java.lang.reflect.Array.CharArrayTests -TestCaseID CharArrayTest0017 +JCK-114a|api|java_lang|reflect|Array|CharArrayTests|Test18 +javasoft.sqe.tests.api.java.lang.reflect.Array.CharArrayTests -TestCaseID CharArrayTest0018 +JCK-114a|api|java_lang|reflect|Array|CharArrayTests|Test19 +javasoft.sqe.tests.api.java.lang.reflect.Array.CharArrayTests -TestCaseID CharArrayTest0019 +JCK-114a|api|java_lang|reflect|Array|CharArrayTests|Test20 +javasoft.sqe.tests.api.java.lang.reflect.Array.CharArrayTests -TestCaseID CharArrayTest0020 +JCK-114a|api|java_lang|reflect|Array|CharArrayTests|Test21 +javasoft.sqe.tests.api.java.lang.reflect.Array.CharArrayTests -TestCaseID CharArrayTest0021 +JCK-114a|api|java_lang|reflect|Array|CharArrayTests|Test22 +javasoft.sqe.tests.api.java.lang.reflect.Array.CharArrayTests -TestCaseID CharArrayTest0022 +JCK-114a|api|java_lang|reflect|Array|CharArrayTests|Test23 +javasoft.sqe.tests.api.java.lang.reflect.Array.CharArrayTests -TestCaseID CharArrayTest0023 +JCK-114a|api|java_lang|reflect|Array|CharArrayTests|Test24 +javasoft.sqe.tests.api.java.lang.reflect.Array.CharArrayTests -TestCaseID CharArrayTest0024 +JCK-114a|api|java_lang|reflect|Array|DoubleArrayTests|Test1 +javasoft.sqe.tests.api.java.lang.reflect.Array.DoubleArrayTests -TestCaseID DoubleArrayTest0001 +JCK-114a|api|java_lang|reflect|Array|DoubleArrayTests|Test2 +javasoft.sqe.tests.api.java.lang.reflect.Array.DoubleArrayTests -TestCaseID DoubleArrayTest0002 +JCK-114a|api|java_lang|reflect|Array|DoubleArrayTests|Test3 +javasoft.sqe.tests.api.java.lang.reflect.Array.DoubleArrayTests -TestCaseID DoubleArrayTest0003 +JCK-114a|api|java_lang|reflect|Array|DoubleArrayTests|Test4 +javasoft.sqe.tests.api.java.lang.reflect.Array.DoubleArrayTests -TestCaseID DoubleArrayTest0004 +JCK-114a|api|java_lang|reflect|Array|DoubleArrayTests|Test5 +javasoft.sqe.tests.api.java.lang.reflect.Array.DoubleArrayTests -TestCaseID DoubleArrayTest0005 +JCK-114a|api|java_lang|reflect|Array|DoubleArrayTests|Test6 +javasoft.sqe.tests.api.java.lang.reflect.Array.DoubleArrayTests -TestCaseID DoubleArrayTest0006 +JCK-114a|api|java_lang|reflect|Array|DoubleArrayTests|Test7 +javasoft.sqe.tests.api.java.lang.reflect.Array.DoubleArrayTests -TestCaseID DoubleArrayTest0007 +JCK-114a|api|java_lang|reflect|Array|DoubleArrayTests|Test8 +javasoft.sqe.tests.api.java.lang.reflect.Array.DoubleArrayTests -TestCaseID DoubleArrayTest0008 +JCK-114a|api|java_lang|reflect|Array|DoubleArrayTests|Test9 +javasoft.sqe.tests.api.java.lang.reflect.Array.DoubleArrayTests -TestCaseID DoubleArrayTest0009 +JCK-114a|api|java_lang|reflect|Array|DoubleArrayTests|Test10 +javasoft.sqe.tests.api.java.lang.reflect.Array.DoubleArrayTests -TestCaseID DoubleArrayTest0010 +JCK-114a|api|java_lang|reflect|Array|DoubleArrayTests|Test11 +javasoft.sqe.tests.api.java.lang.reflect.Array.DoubleArrayTests -TestCaseID DoubleArrayTest0011 +JCK-114a|api|java_lang|reflect|Array|DoubleArrayTests|Test12 +javasoft.sqe.tests.api.java.lang.reflect.Array.DoubleArrayTests -TestCaseID DoubleArrayTest0012 +JCK-114a|api|java_lang|reflect|Array|DoubleArrayTests|Test13 +javasoft.sqe.tests.api.java.lang.reflect.Array.DoubleArrayTests -TestCaseID DoubleArrayTest0013 +JCK-114a|api|java_lang|reflect|Array|DoubleArrayTests|Test14 +javasoft.sqe.tests.api.java.lang.reflect.Array.DoubleArrayTests -TestCaseID DoubleArrayTest0014 +JCK-114a|api|java_lang|reflect|Array|DoubleArrayTests|Test15 +javasoft.sqe.tests.api.java.lang.reflect.Array.DoubleArrayTests -TestCaseID DoubleArrayTest0015 +JCK-114a|api|java_lang|reflect|Array|DoubleArrayTests|Test16 +javasoft.sqe.tests.api.java.lang.reflect.Array.DoubleArrayTests -TestCaseID DoubleArrayTest0016 +JCK-114a|api|java_lang|reflect|Array|DoubleArrayTests|Test17 +javasoft.sqe.tests.api.java.lang.reflect.Array.DoubleArrayTests -TestCaseID DoubleArrayTest0017 +JCK-114a|api|java_lang|reflect|Array|DoubleArrayTests|Test18 +javasoft.sqe.tests.api.java.lang.reflect.Array.DoubleArrayTests -TestCaseID DoubleArrayTest0018 +JCK-114a|api|java_lang|reflect|Array|DoubleArrayTests|Test19 +javasoft.sqe.tests.api.java.lang.reflect.Array.DoubleArrayTests -TestCaseID DoubleArrayTest0019 +JCK-114a|api|java_lang|reflect|Array|DoubleArrayTests|Test20 +javasoft.sqe.tests.api.java.lang.reflect.Array.DoubleArrayTests -TestCaseID DoubleArrayTest0020 +JCK-114a|api|java_lang|reflect|Array|DoubleArrayTests|Test21 +javasoft.sqe.tests.api.java.lang.reflect.Array.DoubleArrayTests -TestCaseID DoubleArrayTest0021 +JCK-114a|api|java_lang|reflect|Array|DoubleArrayTests|Test22 +javasoft.sqe.tests.api.java.lang.reflect.Array.DoubleArrayTests -TestCaseID DoubleArrayTest0022 +JCK-114a|api|java_lang|reflect|Array|DoubleArrayTests|Test23 +javasoft.sqe.tests.api.java.lang.reflect.Array.DoubleArrayTests -TestCaseID DoubleArrayTest0023 +JCK-114a|api|java_lang|reflect|Array|DoubleArrayTests|Test24 +javasoft.sqe.tests.api.java.lang.reflect.Array.DoubleArrayTests -TestCaseID DoubleArrayTest0024 +JCK-114a|api|java_lang|reflect|Array|FloatArrayTests|Test1 +javasoft.sqe.tests.api.java.lang.reflect.Array.FloatArrayTests -TestCaseID FloatArrayTest0001 +JCK-114a|api|java_lang|reflect|Array|FloatArrayTests|Test2 +javasoft.sqe.tests.api.java.lang.reflect.Array.FloatArrayTests -TestCaseID FloatArrayTest0002 +JCK-114a|api|java_lang|reflect|Array|FloatArrayTests|Test3 +javasoft.sqe.tests.api.java.lang.reflect.Array.FloatArrayTests -TestCaseID FloatArrayTest0003 +JCK-114a|api|java_lang|reflect|Array|FloatArrayTests|Test4 +javasoft.sqe.tests.api.java.lang.reflect.Array.FloatArrayTests -TestCaseID FloatArrayTest0004 +JCK-114a|api|java_lang|reflect|Array|FloatArrayTests|Test5 +javasoft.sqe.tests.api.java.lang.reflect.Array.FloatArrayTests -TestCaseID FloatArrayTest0005 +JCK-114a|api|java_lang|reflect|Array|FloatArrayTests|Test6 +javasoft.sqe.tests.api.java.lang.reflect.Array.FloatArrayTests -TestCaseID FloatArrayTest0006 +JCK-114a|api|java_lang|reflect|Array|FloatArrayTests|Test7 +javasoft.sqe.tests.api.java.lang.reflect.Array.FloatArrayTests -TestCaseID FloatArrayTest0007 +JCK-114a|api|java_lang|reflect|Array|FloatArrayTests|Test8 +javasoft.sqe.tests.api.java.lang.reflect.Array.FloatArrayTests -TestCaseID FloatArrayTest0008 +JCK-114a|api|java_lang|reflect|Array|FloatArrayTests|Test9 +javasoft.sqe.tests.api.java.lang.reflect.Array.FloatArrayTests -TestCaseID FloatArrayTest0009 +JCK-114a|api|java_lang|reflect|Array|FloatArrayTests|Test10 +javasoft.sqe.tests.api.java.lang.reflect.Array.FloatArrayTests -TestCaseID FloatArrayTest0010 +JCK-114a|api|java_lang|reflect|Array|FloatArrayTests|Test11 +javasoft.sqe.tests.api.java.lang.reflect.Array.FloatArrayTests -TestCaseID FloatArrayTest0011 +JCK-114a|api|java_lang|reflect|Array|FloatArrayTests|Test12 +javasoft.sqe.tests.api.java.lang.reflect.Array.FloatArrayTests -TestCaseID FloatArrayTest0012 +JCK-114a|api|java_lang|reflect|Array|FloatArrayTests|Test13 +javasoft.sqe.tests.api.java.lang.reflect.Array.FloatArrayTests -TestCaseID FloatArrayTest0013 +JCK-114a|api|java_lang|reflect|Array|FloatArrayTests|Test14 +javasoft.sqe.tests.api.java.lang.reflect.Array.FloatArrayTests -TestCaseID FloatArrayTest0014 +JCK-114a|api|java_lang|reflect|Array|FloatArrayTests|Test15 +javasoft.sqe.tests.api.java.lang.reflect.Array.FloatArrayTests -TestCaseID FloatArrayTest0015 +JCK-114a|api|java_lang|reflect|Array|FloatArrayTests|Test16 +javasoft.sqe.tests.api.java.lang.reflect.Array.FloatArrayTests -TestCaseID FloatArrayTest0016 +JCK-114a|api|java_lang|reflect|Array|FloatArrayTests|Test17 +javasoft.sqe.tests.api.java.lang.reflect.Array.FloatArrayTests -TestCaseID FloatArrayTest0017 +JCK-114a|api|java_lang|reflect|Array|FloatArrayTests|Test18 +javasoft.sqe.tests.api.java.lang.reflect.Array.FloatArrayTests -TestCaseID FloatArrayTest0018 +JCK-114a|api|java_lang|reflect|Array|FloatArrayTests|Test19 +javasoft.sqe.tests.api.java.lang.reflect.Array.FloatArrayTests -TestCaseID FloatArrayTest0019 +JCK-114a|api|java_lang|reflect|Array|FloatArrayTests|Test20 +javasoft.sqe.tests.api.java.lang.reflect.Array.FloatArrayTests -TestCaseID FloatArrayTest0020 +JCK-114a|api|java_lang|reflect|Array|FloatArrayTests|Test21 +javasoft.sqe.tests.api.java.lang.reflect.Array.FloatArrayTests -TestCaseID FloatArrayTest0021 +JCK-114a|api|java_lang|reflect|Array|FloatArrayTests|Test22 +javasoft.sqe.tests.api.java.lang.reflect.Array.FloatArrayTests -TestCaseID FloatArrayTest0022 +JCK-114a|api|java_lang|reflect|Array|FloatArrayTests|Test23 +javasoft.sqe.tests.api.java.lang.reflect.Array.FloatArrayTests -TestCaseID FloatArrayTest0023 +JCK-114a|api|java_lang|reflect|Array|FloatArrayTests|Test24 +javasoft.sqe.tests.api.java.lang.reflect.Array.FloatArrayTests -TestCaseID FloatArrayTest0024 +JCK-114a|api|java_lang|reflect|Array|IntArrayTests|Test1 +javasoft.sqe.tests.api.java.lang.reflect.Array.IntArrayTests -TestCaseID IntArrayTest0001 +JCK-114a|api|java_lang|reflect|Array|IntArrayTests|Test2 +javasoft.sqe.tests.api.java.lang.reflect.Array.IntArrayTests -TestCaseID IntArrayTest0002 +JCK-114a|api|java_lang|reflect|Array|IntArrayTests|Test3 +javasoft.sqe.tests.api.java.lang.reflect.Array.IntArrayTests -TestCaseID IntArrayTest0003 +JCK-114a|api|java_lang|reflect|Array|IntArrayTests|Test4 +javasoft.sqe.tests.api.java.lang.reflect.Array.IntArrayTests -TestCaseID IntArrayTest0004 +JCK-114a|api|java_lang|reflect|Array|IntArrayTests|Test5 +javasoft.sqe.tests.api.java.lang.reflect.Array.IntArrayTests -TestCaseID IntArrayTest0005 +JCK-114a|api|java_lang|reflect|Array|IntArrayTests|Test6 +javasoft.sqe.tests.api.java.lang.reflect.Array.IntArrayTests -TestCaseID IntArrayTest0006 +JCK-114a|api|java_lang|reflect|Array|IntArrayTests|Test7 +javasoft.sqe.tests.api.java.lang.reflect.Array.IntArrayTests -TestCaseID IntArrayTest0007 +JCK-114a|api|java_lang|reflect|Array|IntArrayTests|Test8 +javasoft.sqe.tests.api.java.lang.reflect.Array.IntArrayTests -TestCaseID IntArrayTest0008 +JCK-114a|api|java_lang|reflect|Array|IntArrayTests|Test9 +javasoft.sqe.tests.api.java.lang.reflect.Array.IntArrayTests -TestCaseID IntArrayTest0009 +JCK-114a|api|java_lang|reflect|Array|IntArrayTests|Test10 +javasoft.sqe.tests.api.java.lang.reflect.Array.IntArrayTests -TestCaseID IntArrayTest0010 +JCK-114a|api|java_lang|reflect|Array|IntArrayTests|Test11 +javasoft.sqe.tests.api.java.lang.reflect.Array.IntArrayTests -TestCaseID IntArrayTest0011 +JCK-114a|api|java_lang|reflect|Array|IntArrayTests|Test12 +javasoft.sqe.tests.api.java.lang.reflect.Array.IntArrayTests -TestCaseID IntArrayTest0012 +JCK-114a|api|java_lang|reflect|Array|IntArrayTests|Test13 +javasoft.sqe.tests.api.java.lang.reflect.Array.IntArrayTests -TestCaseID IntArrayTest0013 +JCK-114a|api|java_lang|reflect|Array|IntArrayTests|Test14 +javasoft.sqe.tests.api.java.lang.reflect.Array.IntArrayTests -TestCaseID IntArrayTest0014 +JCK-114a|api|java_lang|reflect|Array|IntArrayTests|Test15 +javasoft.sqe.tests.api.java.lang.reflect.Array.IntArrayTests -TestCaseID IntArrayTest0015 +JCK-114a|api|java_lang|reflect|Array|IntArrayTests|Test16 +javasoft.sqe.tests.api.java.lang.reflect.Array.IntArrayTests -TestCaseID IntArrayTest0016 +JCK-114a|api|java_lang|reflect|Array|IntArrayTests|Test17 +javasoft.sqe.tests.api.java.lang.reflect.Array.IntArrayTests -TestCaseID IntArrayTest0017 +JCK-114a|api|java_lang|reflect|Array|IntArrayTests|Test18 +javasoft.sqe.tests.api.java.lang.reflect.Array.IntArrayTests -TestCaseID IntArrayTest0018 +JCK-114a|api|java_lang|reflect|Array|IntArrayTests|Test19 +javasoft.sqe.tests.api.java.lang.reflect.Array.IntArrayTests -TestCaseID IntArrayTest0019 +JCK-114a|api|java_lang|reflect|Array|IntArrayTests|Test20 +javasoft.sqe.tests.api.java.lang.reflect.Array.IntArrayTests -TestCaseID IntArrayTest0020 +JCK-114a|api|java_lang|reflect|Array|IntArrayTests|Test21 +javasoft.sqe.tests.api.java.lang.reflect.Array.IntArrayTests -TestCaseID IntArrayTest0021 +JCK-114a|api|java_lang|reflect|Array|IntArrayTests|Test22 +javasoft.sqe.tests.api.java.lang.reflect.Array.IntArrayTests -TestCaseID IntArrayTest0022 +JCK-114a|api|java_lang|reflect|Array|IntArrayTests|Test23 +javasoft.sqe.tests.api.java.lang.reflect.Array.IntArrayTests -TestCaseID IntArrayTest0023 +JCK-114a|api|java_lang|reflect|Array|IntArrayTests|Test24 +javasoft.sqe.tests.api.java.lang.reflect.Array.IntArrayTests -TestCaseID IntArrayTest0024 +JCK-114a|api|java_lang|reflect|Array|LongArrayTests|Test1 +javasoft.sqe.tests.api.java.lang.reflect.Array.LongArrayTests -TestCaseID LongArrayTest0001 +JCK-114a|api|java_lang|reflect|Array|LongArrayTests|Test2 +javasoft.sqe.tests.api.java.lang.reflect.Array.LongArrayTests -TestCaseID LongArrayTest0002 +JCK-114a|api|java_lang|reflect|Array|LongArrayTests|Test3 +javasoft.sqe.tests.api.java.lang.reflect.Array.LongArrayTests -TestCaseID LongArrayTest0003 +JCK-114a|api|java_lang|reflect|Array|LongArrayTests|Test4 +javasoft.sqe.tests.api.java.lang.reflect.Array.LongArrayTests -TestCaseID LongArrayTest0004 +JCK-114a|api|java_lang|reflect|Array|LongArrayTests|Test5 +javasoft.sqe.tests.api.java.lang.reflect.Array.LongArrayTests -TestCaseID LongArrayTest0005 +JCK-114a|api|java_lang|reflect|Array|LongArrayTests|Test6 +javasoft.sqe.tests.api.java.lang.reflect.Array.LongArrayTests -TestCaseID LongArrayTest0006 +JCK-114a|api|java_lang|reflect|Array|LongArrayTests|Test7 +javasoft.sqe.tests.api.java.lang.reflect.Array.LongArrayTests -TestCaseID LongArrayTest0007 +JCK-114a|api|java_lang|reflect|Array|LongArrayTests|Test8 +javasoft.sqe.tests.api.java.lang.reflect.Array.LongArrayTests -TestCaseID LongArrayTest0008 +JCK-114a|api|java_lang|reflect|Array|LongArrayTests|Test9 +javasoft.sqe.tests.api.java.lang.reflect.Array.LongArrayTests -TestCaseID LongArrayTest0009 +JCK-114a|api|java_lang|reflect|Array|LongArrayTests|Test10 +javasoft.sqe.tests.api.java.lang.reflect.Array.LongArrayTests -TestCaseID LongArrayTest0010 +JCK-114a|api|java_lang|reflect|Array|LongArrayTests|Test11 +javasoft.sqe.tests.api.java.lang.reflect.Array.LongArrayTests -TestCaseID LongArrayTest0011 +JCK-114a|api|java_lang|reflect|Array|LongArrayTests|Test12 +javasoft.sqe.tests.api.java.lang.reflect.Array.LongArrayTests -TestCaseID LongArrayTest0012 +JCK-114a|api|java_lang|reflect|Array|LongArrayTests|Test13 +javasoft.sqe.tests.api.java.lang.reflect.Array.LongArrayTests -TestCaseID LongArrayTest0013 +JCK-114a|api|java_lang|reflect|Array|LongArrayTests|Test14 +javasoft.sqe.tests.api.java.lang.reflect.Array.LongArrayTests -TestCaseID LongArrayTest0014 +JCK-114a|api|java_lang|reflect|Array|LongArrayTests|Test15 +javasoft.sqe.tests.api.java.lang.reflect.Array.LongArrayTests -TestCaseID LongArrayTest0015 +JCK-114a|api|java_lang|reflect|Array|LongArrayTests|Test16 +javasoft.sqe.tests.api.java.lang.reflect.Array.LongArrayTests -TestCaseID LongArrayTest0016 +JCK-114a|api|java_lang|reflect|Array|LongArrayTests|Test17 +javasoft.sqe.tests.api.java.lang.reflect.Array.LongArrayTests -TestCaseID LongArrayTest0017 +JCK-114a|api|java_lang|reflect|Array|LongArrayTests|Test18 +javasoft.sqe.tests.api.java.lang.reflect.Array.LongArrayTests -TestCaseID LongArrayTest0018 +JCK-114a|api|java_lang|reflect|Array|LongArrayTests|Test19 +javasoft.sqe.tests.api.java.lang.reflect.Array.LongArrayTests -TestCaseID LongArrayTest0019 +JCK-114a|api|java_lang|reflect|Array|LongArrayTests|Test20 +javasoft.sqe.tests.api.java.lang.reflect.Array.LongArrayTests -TestCaseID LongArrayTest0020 +JCK-114a|api|java_lang|reflect|Array|LongArrayTests|Test21 +javasoft.sqe.tests.api.java.lang.reflect.Array.LongArrayTests -TestCaseID LongArrayTest0021 +JCK-114a|api|java_lang|reflect|Array|LongArrayTests|Test22 +javasoft.sqe.tests.api.java.lang.reflect.Array.LongArrayTests -TestCaseID LongArrayTest0022 +JCK-114a|api|java_lang|reflect|Array|LongArrayTests|Test23 +javasoft.sqe.tests.api.java.lang.reflect.Array.LongArrayTests -TestCaseID LongArrayTest0023 +JCK-114a|api|java_lang|reflect|Array|LongArrayTests|Test24 +javasoft.sqe.tests.api.java.lang.reflect.Array.LongArrayTests -TestCaseID LongArrayTest0024 +JCK-114a|api|java_lang|reflect|Array|ShortArrayTests|Test1 +javasoft.sqe.tests.api.java.lang.reflect.Array.ShortArrayTests -TestCaseID ShortArrayTest0001 +JCK-114a|api|java_lang|reflect|Array|ShortArrayTests|Test2 +javasoft.sqe.tests.api.java.lang.reflect.Array.ShortArrayTests -TestCaseID ShortArrayTest0002 +JCK-114a|api|java_lang|reflect|Array|ShortArrayTests|Test3 +javasoft.sqe.tests.api.java.lang.reflect.Array.ShortArrayTests -TestCaseID ShortArrayTest0003 +JCK-114a|api|java_lang|reflect|Array|ShortArrayTests|Test4 +javasoft.sqe.tests.api.java.lang.reflect.Array.ShortArrayTests -TestCaseID ShortArrayTest0004 +JCK-114a|api|java_lang|reflect|Array|ShortArrayTests|Test5 +javasoft.sqe.tests.api.java.lang.reflect.Array.ShortArrayTests -TestCaseID ShortArrayTest0005 +JCK-114a|api|java_lang|reflect|Array|ShortArrayTests|Test6 +javasoft.sqe.tests.api.java.lang.reflect.Array.ShortArrayTests -TestCaseID ShortArrayTest0006 +JCK-114a|api|java_lang|reflect|Array|ShortArrayTests|Test7 +javasoft.sqe.tests.api.java.lang.reflect.Array.ShortArrayTests -TestCaseID ShortArrayTest0007 +JCK-114a|api|java_lang|reflect|Array|ShortArrayTests|Test8 +javasoft.sqe.tests.api.java.lang.reflect.Array.ShortArrayTests -TestCaseID ShortArrayTest0008 +JCK-114a|api|java_lang|reflect|Array|ShortArrayTests|Test9 +javasoft.sqe.tests.api.java.lang.reflect.Array.ShortArrayTests -TestCaseID ShortArrayTest0009 +JCK-114a|api|java_lang|reflect|Array|ShortArrayTests|Test10 +javasoft.sqe.tests.api.java.lang.reflect.Array.ShortArrayTests -TestCaseID ShortArrayTest0010 +JCK-114a|api|java_lang|reflect|Array|ShortArrayTests|Test11 +javasoft.sqe.tests.api.java.lang.reflect.Array.ShortArrayTests -TestCaseID ShortArrayTest0011 +JCK-114a|api|java_lang|reflect|Array|ShortArrayTests|Test12 +javasoft.sqe.tests.api.java.lang.reflect.Array.ShortArrayTests -TestCaseID ShortArrayTest0012 +JCK-114a|api|java_lang|reflect|Array|ShortArrayTests|Test13 +javasoft.sqe.tests.api.java.lang.reflect.Array.ShortArrayTests -TestCaseID ShortArrayTest0013 +JCK-114a|api|java_lang|reflect|Array|ShortArrayTests|Test14 +javasoft.sqe.tests.api.java.lang.reflect.Array.ShortArrayTests -TestCaseID ShortArrayTest0014 +JCK-114a|api|java_lang|reflect|Array|ShortArrayTests|Test15 +javasoft.sqe.tests.api.java.lang.reflect.Array.ShortArrayTests -TestCaseID ShortArrayTest0015 +JCK-114a|api|java_lang|reflect|Array|ShortArrayTests|Test16 +javasoft.sqe.tests.api.java.lang.reflect.Array.ShortArrayTests -TestCaseID ShortArrayTest0016 +JCK-114a|api|java_lang|reflect|Array|ShortArrayTests|Test17 +javasoft.sqe.tests.api.java.lang.reflect.Array.ShortArrayTests -TestCaseID ShortArrayTest0017 +JCK-114a|api|java_lang|reflect|Array|ShortArrayTests|Test18 +javasoft.sqe.tests.api.java.lang.reflect.Array.ShortArrayTests -TestCaseID ShortArrayTest0018 +JCK-114a|api|java_lang|reflect|Array|ShortArrayTests|Test19 +javasoft.sqe.tests.api.java.lang.reflect.Array.ShortArrayTests -TestCaseID ShortArrayTest0019 +JCK-114a|api|java_lang|reflect|Array|ShortArrayTests|Test20 +javasoft.sqe.tests.api.java.lang.reflect.Array.ShortArrayTests -TestCaseID ShortArrayTest0020 +JCK-114a|api|java_lang|reflect|Array|ShortArrayTests|Test21 +javasoft.sqe.tests.api.java.lang.reflect.Array.ShortArrayTests -TestCaseID ShortArrayTest0021 +JCK-114a|api|java_lang|reflect|Array|ShortArrayTests|Test22 +javasoft.sqe.tests.api.java.lang.reflect.Array.ShortArrayTests -TestCaseID ShortArrayTest0022 +JCK-114a|api|java_lang|reflect|Array|ShortArrayTests|Test23 +javasoft.sqe.tests.api.java.lang.reflect.Array.ShortArrayTests -TestCaseID ShortArrayTest0023 +JCK-114a|api|java_lang|reflect|Array|ShortArrayTests|Test24 +javasoft.sqe.tests.api.java.lang.reflect.Array.ShortArrayTests -TestCaseID ShortArrayTest0024 +JCK-114a|api|java_lang|reflect|Array|GetSetArrayTests|Test1 +javasoft.sqe.tests.api.java.lang.reflect.Array.GetSetArrayTests -TestCaseID GetSetArrayTest0001 +JCK-114a|api|java_lang|reflect|Array|GetSetArrayTests|Test2 +javasoft.sqe.tests.api.java.lang.reflect.Array.GetSetArrayTests -TestCaseID GetSetArrayTest0002 +JCK-114a|api|java_lang|reflect|Array|GetSetArrayTests|Test3 +javasoft.sqe.tests.api.java.lang.reflect.Array.GetSetArrayTests -TestCaseID GetSetArrayTest0003 +JCK-114a|api|java_lang|reflect|Array|GetSetArrayTests|Test4 +javasoft.sqe.tests.api.java.lang.reflect.Array.GetSetArrayTests -TestCaseID GetSetArrayTest0004 +JCK-114a|api|java_lang|reflect|Array|GetSetArrayTests|Test5 +javasoft.sqe.tests.api.java.lang.reflect.Array.GetSetArrayTests -TestCaseID GetSetArrayTest0005 +JCK-114a|api|java_lang|reflect|Array|GetSetArrayTests|Test6 +javasoft.sqe.tests.api.java.lang.reflect.Array.GetSetArrayTests -TestCaseID GetSetArrayTest0006 +JCK-114a|api|java_lang|reflect|Array|GetSetArrayTests|Test7 +javasoft.sqe.tests.api.java.lang.reflect.Array.GetSetArrayTests -TestCaseID GetSetArrayTest0007 +JCK-114a|api|java_lang|reflect|Array|GetSetArrayTests|Test8 +javasoft.sqe.tests.api.java.lang.reflect.Array.GetSetArrayTests -TestCaseID GetSetArrayTest0008 +JCK-114a|api|java_lang|reflect|Array|GetSetArrayTests|Test9 +javasoft.sqe.tests.api.java.lang.reflect.Array.GetSetArrayTests -TestCaseID GetSetArrayTest0009 +JCK-114a|api|java_lang|reflect|Array|GetSetArrayTests|Test10 +javasoft.sqe.tests.api.java.lang.reflect.Array.GetSetArrayTests -TestCaseID GetSetArrayTest0010 +JCK-114a|api|java_lang|reflect|Array|GetSetArrayTests|Test11 +javasoft.sqe.tests.api.java.lang.reflect.Array.GetSetArrayTests -TestCaseID GetSetArrayTest0011 +JCK-114a|api|java_lang|reflect|Array|GetSetArrayTests|Test12 +javasoft.sqe.tests.api.java.lang.reflect.Array.GetSetArrayTests -TestCaseID GetSetArrayTest0012 +JCK-114a|api|java_lang|reflect|Array|GetSetArrayTests|Test13 +javasoft.sqe.tests.api.java.lang.reflect.Array.GetSetArrayTests -TestCaseID GetSetArrayTest0013 +JCK-114a|api|java_lang|reflect|Array|GetSetArrayTests|Test14 +javasoft.sqe.tests.api.java.lang.reflect.Array.GetSetArrayTests -TestCaseID GetSetArrayTest0014 +JCK-114a|api|java_lang|reflect|Array|GetSetArrayTests|Test15 +javasoft.sqe.tests.api.java.lang.reflect.Array.GetSetArrayTests -TestCaseID GetSetArrayTest0015 +JCK-114a|api|java_lang|reflect|Array|GetSetArrayTests|Test16 +javasoft.sqe.tests.api.java.lang.reflect.Array.GetSetArrayTests -TestCaseID GetSetArrayTest0016 +JCK-114a|api|java_lang|reflect|Array|GetSetArrayTests|Test17 +javasoft.sqe.tests.api.java.lang.reflect.Array.GetSetArrayTests -TestCaseID GetSetArrayTest0017 +JCK-114a|api|java_lang|reflect|Array|GetSetArrayTests|Test18 +javasoft.sqe.tests.api.java.lang.reflect.Array.GetSetArrayTests -TestCaseID GetSetArrayTest0018 +JCK-114a|api|java_lang|reflect|Array|NewInstanceTests|Test1 +javasoft.sqe.tests.api.java.lang.reflect.Array.NewInstanceTests -TestCaseID NewInstanceTest0001 +JCK-114a|api|java_lang|reflect|Array|NewInstanceTests|Test2 +javasoft.sqe.tests.api.java.lang.reflect.Array.NewInstanceTests -TestCaseID NewInstanceTest0002 +JCK-114a|api|java_lang|reflect|Array|NewInstanceTests|Test3 +javasoft.sqe.tests.api.java.lang.reflect.Array.NewInstanceTests -TestCaseID NewInstanceTest0003 +JCK-114a|api|java_lang|reflect|Array|NewInstanceTests|Test4 +javasoft.sqe.tests.api.java.lang.reflect.Array.NewInstanceTests -TestCaseID NewInstanceTest0004 +JCK-114a|api|java_lang|reflect|Array|NewInstanceTests|Test5 +javasoft.sqe.tests.api.java.lang.reflect.Array.NewInstanceTests -TestCaseID NewInstanceTest0005 +JCK-114a|api|java_lang|reflect|Array|NewInstanceTests|Test6 +javasoft.sqe.tests.api.java.lang.reflect.Array.NewInstanceTests -TestCaseID NewInstanceTest0006 +JCK-114a|api|java_lang|reflect|Array|NewInstanceTests|Test7 +javasoft.sqe.tests.api.java.lang.reflect.Array.NewInstanceTests -TestCaseID NewInstanceTest0007 +JCK-114a|api|java_lang|reflect|Array|GetLengthTests|Test1 +javasoft.sqe.tests.api.java.lang.reflect.Array.GetLengthTests -TestCaseID GetLengthTest0001 +JCK-114a|api|java_lang|reflect|Array|GetLengthTests|Test2 +javasoft.sqe.tests.api.java.lang.reflect.Array.GetLengthTests -TestCaseID GetLengthTest0002 +JCK-114a|api|java_lang|reflect|Array|GetLengthTests|Test3 +javasoft.sqe.tests.api.java.lang.reflect.Array.GetLengthTests -TestCaseID GetLengthTest0003 +JCK-114a|api|java_lang|reflect|Array|GetLengthTests|Test4 +javasoft.sqe.tests.api.java.lang.reflect.Array.GetLengthTests -TestCaseID GetLengthTest0004 +JCK-114a|api|java_lang|reflect|Modifier|index|Test1 +javasoft.sqe.tests.api.java.lang.reflect.Modifier.ModifierTests -TestCaseID ModifierTest0001 +JCK-114a|api|java_lang|reflect|Modifier|index|Test2 +javasoft.sqe.tests.api.java.lang.reflect.Modifier.ModifierTests -TestCaseID ModifierTest0002 +JCK-114a|api|java_lang|reflect|Modifier|index|Test3 +javasoft.sqe.tests.api.java.lang.reflect.Modifier.ModifierTests -TestCaseID ModifierTest0003 +JCK-114a|api|java_lang|reflect|Modifier|index|Test4 +javasoft.sqe.tests.api.java.lang.reflect.Modifier.ModifierTests -TestCaseID ModifierTest0004 +JCK-114a|api|java_lang|reflect|Modifier|index|Test5 +javasoft.sqe.tests.api.java.lang.reflect.Modifier.ModifierTests -TestCaseID ModifierTest0005 +JCK-114a|api|java_lang|reflect|Modifier|index|Test6 +javasoft.sqe.tests.api.java.lang.reflect.Modifier.ModifierTests -TestCaseID ModifierTest0006 +JCK-114a|api|java_lang|reflect|Modifier|index|Test7 +javasoft.sqe.tests.api.java.lang.reflect.Modifier.ModifierTests -TestCaseID ModifierTest0007 +JCK-114a|api|java_lang|reflect|Modifier|index|Test8 +javasoft.sqe.tests.api.java.lang.reflect.Modifier.ModifierTests -TestCaseID ModifierTest0008 +JCK-114a|api|java_lang|reflect|Modifier|index|Test9 +javasoft.sqe.tests.api.java.lang.reflect.Modifier.ModifierTests -TestCaseID ModifierTest0009 +JCK-114a|api|java_lang|reflect|Modifier|index|Test10 +javasoft.sqe.tests.api.java.lang.reflect.Modifier.ModifierTests -TestCaseID ModifierTest0010 +JCK-114a|api|java_lang|reflect|Modifier|index|Test11 +javasoft.sqe.tests.api.java.lang.reflect.Modifier.ModifierTests -TestCaseID ModifierTest0011 +JCK-114a|api|java_lang|reflect|Modifier|index|Test12 +javasoft.sqe.tests.api.java.lang.reflect.Modifier.ToStringTests -TestCaseID StringTest0001 +JCK-114a|api|java_lang|reflect|Modifier|index|Test13 +javasoft.sqe.tests.api.java.lang.reflect.Modifier.ToStringTests -TestCaseID StringTest0002 +JCK-114a|api|java_lang|reflect|Field|BoolFieldTests|Test1 +javasoft.sqe.tests.api.java.lang.reflect.Field.BoolFieldTests -TestCaseID BoolFieldTest0801 +JCK-114a|api|java_lang|reflect|Field|BoolFieldTests|Test2 +javasoft.sqe.tests.api.java.lang.reflect.Field.BoolFieldTests -TestCaseID BoolFieldTest0802 +JCK-114a|api|java_lang|reflect|Field|BoolFieldTests|Test3 +javasoft.sqe.tests.api.java.lang.reflect.Field.BoolFieldTests -TestCaseID BoolFieldTest0803 +JCK-114a|api|java_lang|reflect|Field|BoolFieldTests|Test4 +javasoft.sqe.tests.api.java.lang.reflect.Field.BoolFieldTests -TestCaseID BoolFieldTest0804 +JCK-114a|api|java_lang|reflect|Field|BoolFieldTests|Test5 +javasoft.sqe.tests.api.java.lang.reflect.Field.BoolFieldTests -TestCaseID BoolFieldTest0805 +JCK-114a|api|java_lang|reflect|Field|BoolFieldTests|Test6 +javasoft.sqe.tests.api.java.lang.reflect.Field.BoolFieldTests -TestCaseID BoolFieldTest0806 +JCK-114a|api|java_lang|reflect|Field|BoolFieldTests|Test7 +javasoft.sqe.tests.api.java.lang.reflect.Field.BoolFieldTests -TestCaseID BoolFieldTest0807 +JCK-114a|api|java_lang|reflect|Field|BoolFieldTests|Test8 +javasoft.sqe.tests.api.java.lang.reflect.Field.BoolFieldTests -TestCaseID BoolFieldTest0808 +JCK-114a|api|java_lang|reflect|Field|BoolFieldTests|Test9 +javasoft.sqe.tests.api.java.lang.reflect.Field.BoolFieldTests -TestCaseID BoolFieldTest0809 +JCK-114a|api|java_lang|reflect|Field|BoolFieldTests|Test10 +javasoft.sqe.tests.api.java.lang.reflect.Field.BoolFieldTests -TestCaseID BoolFieldTest0810 +JCK-114a|api|java_lang|reflect|Field|BoolFieldTests|Test11 +javasoft.sqe.tests.api.java.lang.reflect.Field.BoolFieldTests -TestCaseID BoolFieldTest0811 +JCK-114a|api|java_lang|reflect|Field|BoolFieldTests|Test12 +javasoft.sqe.tests.api.java.lang.reflect.Field.BoolFieldTests -TestCaseID BoolFieldTest0812 +JCK-114a|api|java_lang|reflect|Field|BoolFieldTests|Test13 +javasoft.sqe.tests.api.java.lang.reflect.Field.BoolFieldTests -TestCaseID BoolFieldTest0813 +JCK-114a|api|java_lang|reflect|Field|ByteFieldTests|Test1 +javasoft.sqe.tests.api.java.lang.reflect.Field.ByteFieldTests -TestCaseID ByteFieldTest0401 +JCK-114a|api|java_lang|reflect|Field|ByteFieldTests|Test2 +javasoft.sqe.tests.api.java.lang.reflect.Field.ByteFieldTests -TestCaseID ByteFieldTest0402 +JCK-114a|api|java_lang|reflect|Field|ByteFieldTests|Test3 +javasoft.sqe.tests.api.java.lang.reflect.Field.ByteFieldTests -TestCaseID ByteFieldTest0403 +JCK-114a|api|java_lang|reflect|Field|ByteFieldTests|Test4 +javasoft.sqe.tests.api.java.lang.reflect.Field.ByteFieldTests -TestCaseID ByteFieldTest0404 +JCK-114a|api|java_lang|reflect|Field|ByteFieldTests|Test5 +javasoft.sqe.tests.api.java.lang.reflect.Field.ByteFieldTests -TestCaseID ByteFieldTest0405 +JCK-114a|api|java_lang|reflect|Field|ByteFieldTests|Test6 +javasoft.sqe.tests.api.java.lang.reflect.Field.ByteFieldTests -TestCaseID ByteFieldTest0406 +JCK-114a|api|java_lang|reflect|Field|ByteFieldTests|Test7 +javasoft.sqe.tests.api.java.lang.reflect.Field.ByteFieldTests -TestCaseID ByteFieldTest0407 +JCK-114a|api|java_lang|reflect|Field|ByteFieldTests|Test8 +javasoft.sqe.tests.api.java.lang.reflect.Field.ByteFieldTests -TestCaseID ByteFieldTest0408 +JCK-114a|api|java_lang|reflect|Field|ByteFieldTests|Test9 +javasoft.sqe.tests.api.java.lang.reflect.Field.ByteFieldTests -TestCaseID ByteFieldTest0409 +JCK-114a|api|java_lang|reflect|Field|ByteFieldTests|Test10 +javasoft.sqe.tests.api.java.lang.reflect.Field.ByteFieldTests -TestCaseID ByteFieldTest0410 +JCK-114a|api|java_lang|reflect|Field|ByteFieldTests|Test11 +javasoft.sqe.tests.api.java.lang.reflect.Field.ByteFieldTests -TestCaseID ByteFieldTest0411 +JCK-114a|api|java_lang|reflect|Field|ByteFieldTests|Test12 +javasoft.sqe.tests.api.java.lang.reflect.Field.ByteFieldTests -TestCaseID ByteFieldTest0412 +JCK-114a|api|java_lang|reflect|Field|ByteFieldTests|Test13 +javasoft.sqe.tests.api.java.lang.reflect.Field.ByteFieldTests -TestCaseID ByteFieldTest0413 +JCK-114a|api|java_lang|reflect|Field|CharFieldTests|Test1 +javasoft.sqe.tests.api.java.lang.reflect.Field.CharFieldTests -TestCaseID CharFieldTest0701 +JCK-114a|api|java_lang|reflect|Field|CharFieldTests|Test2 +javasoft.sqe.tests.api.java.lang.reflect.Field.CharFieldTests -TestCaseID CharFieldTest0702 +JCK-114a|api|java_lang|reflect|Field|CharFieldTests|Test3 +javasoft.sqe.tests.api.java.lang.reflect.Field.CharFieldTests -TestCaseID CharFieldTest0703 +JCK-114a|api|java_lang|reflect|Field|CharFieldTests|Test4 +javasoft.sqe.tests.api.java.lang.reflect.Field.CharFieldTests -TestCaseID CharFieldTest0704 +JCK-114a|api|java_lang|reflect|Field|CharFieldTests|Test5 +javasoft.sqe.tests.api.java.lang.reflect.Field.CharFieldTests -TestCaseID CharFieldTest0705 +JCK-114a|api|java_lang|reflect|Field|CharFieldTests|Test6 +javasoft.sqe.tests.api.java.lang.reflect.Field.CharFieldTests -TestCaseID CharFieldTest0706 +JCK-114a|api|java_lang|reflect|Field|CharFieldTests|Test7 +javasoft.sqe.tests.api.java.lang.reflect.Field.CharFieldTests -TestCaseID CharFieldTest0707 +JCK-114a|api|java_lang|reflect|Field|CharFieldTests|Test8 +javasoft.sqe.tests.api.java.lang.reflect.Field.CharFieldTests -TestCaseID CharFieldTest0708 +JCK-114a|api|java_lang|reflect|Field|CharFieldTests|Test9 +javasoft.sqe.tests.api.java.lang.reflect.Field.CharFieldTests -TestCaseID CharFieldTest0709 +JCK-114a|api|java_lang|reflect|Field|CharFieldTests|Test10 +javasoft.sqe.tests.api.java.lang.reflect.Field.CharFieldTests -TestCaseID CharFieldTest0710 +JCK-114a|api|java_lang|reflect|Field|CharFieldTests|Test11 +javasoft.sqe.tests.api.java.lang.reflect.Field.CharFieldTests -TestCaseID CharFieldTest0711 +JCK-114a|api|java_lang|reflect|Field|CharFieldTests|Test12 +javasoft.sqe.tests.api.java.lang.reflect.Field.CharFieldTests -TestCaseID CharFieldTest0712 +JCK-114a|api|java_lang|reflect|Field|CharFieldTests|Test13 +javasoft.sqe.tests.api.java.lang.reflect.Field.CharFieldTests -TestCaseID CharFieldTest0713 +JCK-114a|api|java_lang|reflect|Field|DoubleFieldTests|Test1 +javasoft.sqe.tests.api.java.lang.reflect.Field.DoubleFieldTests -TestCaseID DoubleFieldTest0601 +JCK-114a|api|java_lang|reflect|Field|DoubleFieldTests|Test2 +javasoft.sqe.tests.api.java.lang.reflect.Field.DoubleFieldTests -TestCaseID DoubleFieldTest0602 +JCK-114a|api|java_lang|reflect|Field|DoubleFieldTests|Test3 +javasoft.sqe.tests.api.java.lang.reflect.Field.DoubleFieldTests -TestCaseID DoubleFieldTest0603 +JCK-114a|api|java_lang|reflect|Field|DoubleFieldTests|Test4 +javasoft.sqe.tests.api.java.lang.reflect.Field.DoubleFieldTests -TestCaseID DoubleFieldTest0604 +JCK-114a|api|java_lang|reflect|Field|DoubleFieldTests|Test5 +javasoft.sqe.tests.api.java.lang.reflect.Field.DoubleFieldTests -TestCaseID DoubleFieldTest0605 +JCK-114a|api|java_lang|reflect|Field|DoubleFieldTests|Test6 +javasoft.sqe.tests.api.java.lang.reflect.Field.DoubleFieldTests -TestCaseID DoubleFieldTest0606 +JCK-114a|api|java_lang|reflect|Field|DoubleFieldTests|Test7 +javasoft.sqe.tests.api.java.lang.reflect.Field.DoubleFieldTests -TestCaseID DoubleFieldTest0607 +JCK-114a|api|java_lang|reflect|Field|DoubleFieldTests|Test8 +javasoft.sqe.tests.api.java.lang.reflect.Field.DoubleFieldTests -TestCaseID DoubleFieldTest0608 +JCK-114a|api|java_lang|reflect|Field|DoubleFieldTests|Test9 +javasoft.sqe.tests.api.java.lang.reflect.Field.DoubleFieldTests -TestCaseID DoubleFieldTest0609 +JCK-114a|api|java_lang|reflect|Field|DoubleFieldTests|Test10 +javasoft.sqe.tests.api.java.lang.reflect.Field.DoubleFieldTests -TestCaseID DoubleFieldTest0610 +JCK-114a|api|java_lang|reflect|Field|DoubleFieldTests|Test11 +javasoft.sqe.tests.api.java.lang.reflect.Field.DoubleFieldTests -TestCaseID DoubleFieldTest0611 +JCK-114a|api|java_lang|reflect|Field|DoubleFieldTests|Test12 +javasoft.sqe.tests.api.java.lang.reflect.Field.DoubleFieldTests -TestCaseID DoubleFieldTest0612 +JCK-114a|api|java_lang|reflect|Field|DoubleFieldTests|Test13 +javasoft.sqe.tests.api.java.lang.reflect.Field.DoubleFieldTests -TestCaseID DoubleFieldTest0613 +JCK-114a|api|java_lang|reflect|Field|FloatFieldTests|Test1 +javasoft.sqe.tests.api.java.lang.reflect.Field.FloatFieldTests -TestCaseID FloatFieldTest0501 +JCK-114a|api|java_lang|reflect|Field|FloatFieldTests|Test2 +javasoft.sqe.tests.api.java.lang.reflect.Field.FloatFieldTests -TestCaseID FloatFieldTest0502 +JCK-114a|api|java_lang|reflect|Field|FloatFieldTests|Test3 +javasoft.sqe.tests.api.java.lang.reflect.Field.FloatFieldTests -TestCaseID FloatFieldTest0503 +JCK-114a|api|java_lang|reflect|Field|FloatFieldTests|Test4 +javasoft.sqe.tests.api.java.lang.reflect.Field.FloatFieldTests -TestCaseID FloatFieldTest0504 +JCK-114a|api|java_lang|reflect|Field|FloatFieldTests|Test5 +javasoft.sqe.tests.api.java.lang.reflect.Field.FloatFieldTests -TestCaseID FloatFieldTest0505 +JCK-114a|api|java_lang|reflect|Field|FloatFieldTests|Test6 +javasoft.sqe.tests.api.java.lang.reflect.Field.FloatFieldTests -TestCaseID FloatFieldTest0506 +JCK-114a|api|java_lang|reflect|Field|FloatFieldTests|Test7 +javasoft.sqe.tests.api.java.lang.reflect.Field.FloatFieldTests -TestCaseID FloatFieldTest0507 +JCK-114a|api|java_lang|reflect|Field|FloatFieldTests|Test8 +javasoft.sqe.tests.api.java.lang.reflect.Field.FloatFieldTests -TestCaseID FloatFieldTest0508 +JCK-114a|api|java_lang|reflect|Field|FloatFieldTests|Test9 +javasoft.sqe.tests.api.java.lang.reflect.Field.FloatFieldTests -TestCaseID FloatFieldTest0509 +JCK-114a|api|java_lang|reflect|Field|FloatFieldTests|Test10 +javasoft.sqe.tests.api.java.lang.reflect.Field.FloatFieldTests -TestCaseID FloatFieldTest0510 +JCK-114a|api|java_lang|reflect|Field|FloatFieldTests|Test11 +javasoft.sqe.tests.api.java.lang.reflect.Field.FloatFieldTests -TestCaseID FloatFieldTest0511 +JCK-114a|api|java_lang|reflect|Field|FloatFieldTests|Test12 +javasoft.sqe.tests.api.java.lang.reflect.Field.FloatFieldTests -TestCaseID FloatFieldTest0512 +JCK-114a|api|java_lang|reflect|Field|FloatFieldTests|Test13 +javasoft.sqe.tests.api.java.lang.reflect.Field.FloatFieldTests -TestCaseID FloatFieldTest0513 +JCK-114a|api|java_lang|reflect|Field|IntFieldTests|Test1 +javasoft.sqe.tests.api.java.lang.reflect.Field.IntFieldTests -TestCaseID IntFieldTest0101 +JCK-114a|api|java_lang|reflect|Field|IntFieldTests|Test2 +javasoft.sqe.tests.api.java.lang.reflect.Field.IntFieldTests -TestCaseID IntFieldTest0102 +JCK-114a|api|java_lang|reflect|Field|IntFieldTests|Test3 +javasoft.sqe.tests.api.java.lang.reflect.Field.IntFieldTests -TestCaseID IntFieldTest0103 +JCK-114a|api|java_lang|reflect|Field|IntFieldTests|Test4 +javasoft.sqe.tests.api.java.lang.reflect.Field.IntFieldTests -TestCaseID IntFieldTest0104 +JCK-114a|api|java_lang|reflect|Field|IntFieldTests|Test5 +javasoft.sqe.tests.api.java.lang.reflect.Field.IntFieldTests -TestCaseID IntFieldTest0105 +JCK-114a|api|java_lang|reflect|Field|IntFieldTests|Test6 +javasoft.sqe.tests.api.java.lang.reflect.Field.IntFieldTests -TestCaseID IntFieldTest0106 +JCK-114a|api|java_lang|reflect|Field|IntFieldTests|Test7 +javasoft.sqe.tests.api.java.lang.reflect.Field.IntFieldTests -TestCaseID IntFieldTest0107 +JCK-114a|api|java_lang|reflect|Field|IntFieldTests|Test8 +javasoft.sqe.tests.api.java.lang.reflect.Field.IntFieldTests -TestCaseID IntFieldTest0108 +JCK-114a|api|java_lang|reflect|Field|IntFieldTests|Test9 +javasoft.sqe.tests.api.java.lang.reflect.Field.IntFieldTests -TestCaseID IntFieldTest0109 +JCK-114a|api|java_lang|reflect|Field|IntFieldTests|Test10 +javasoft.sqe.tests.api.java.lang.reflect.Field.IntFieldTests -TestCaseID IntFieldTest0110 +JCK-114a|api|java_lang|reflect|Field|IntFieldTests|Test11 +javasoft.sqe.tests.api.java.lang.reflect.Field.IntFieldTests -TestCaseID IntFieldTest0111 +JCK-114a|api|java_lang|reflect|Field|IntFieldTests|Test12 +javasoft.sqe.tests.api.java.lang.reflect.Field.IntFieldTests -TestCaseID IntFieldTest0112 +JCK-114a|api|java_lang|reflect|Field|IntFieldTests|Test13 +javasoft.sqe.tests.api.java.lang.reflect.Field.IntFieldTests -TestCaseID IntFieldTest0113 +JCK-114a|api|java_lang|reflect|Field|IntFieldTests|Test14 +javasoft.sqe.tests.api.java.lang.reflect.Field.IntFieldTests -TestCaseID IntFieldTest0114 +JCK-114a|api|java_lang|reflect|Field|IntFieldTests|Test15 +javasoft.sqe.tests.api.java.lang.reflect.Field.IntFieldTests -TestCaseID IntFieldTest0115 +JCK-114a|api|java_lang|reflect|Field|IntFieldTests|Test16 +javasoft.sqe.tests.api.java.lang.reflect.Field.IntFieldTests -TestCaseID IntFieldTest0116 +JCK-114a|api|java_lang|reflect|Field|IntFieldTests|Test17 +javasoft.sqe.tests.api.java.lang.reflect.Field.IntFieldTests -TestCaseID IntFieldTest0117 +JCK-114a|api|java_lang|reflect|Field|IntFieldTests|Test18 +javasoft.sqe.tests.api.java.lang.reflect.Field.IntFieldTests -TestCaseID IntFieldTest0118 +JCK-114a|api|java_lang|reflect|Field|IntFieldTests|Test19 +javasoft.sqe.tests.api.java.lang.reflect.Field.IntFieldTests -TestCaseID IntFieldTest0119 +JCK-114a|api|java_lang|reflect|Field|LongFieldTests|Test1 +javasoft.sqe.tests.api.java.lang.reflect.Field.LongFieldTests -TestCaseID LongFieldTest0301 +JCK-114a|api|java_lang|reflect|Field|LongFieldTests|Test2 +javasoft.sqe.tests.api.java.lang.reflect.Field.LongFieldTests -TestCaseID LongFieldTest0302 +JCK-114a|api|java_lang|reflect|Field|LongFieldTests|Test3 +javasoft.sqe.tests.api.java.lang.reflect.Field.LongFieldTests -TestCaseID LongFieldTest0303 +JCK-114a|api|java_lang|reflect|Field|LongFieldTests|Test4 +javasoft.sqe.tests.api.java.lang.reflect.Field.LongFieldTests -TestCaseID LongFieldTest0304 +JCK-114a|api|java_lang|reflect|Field|LongFieldTests|Test5 +javasoft.sqe.tests.api.java.lang.reflect.Field.LongFieldTests -TestCaseID LongFieldTest0305 +JCK-114a|api|java_lang|reflect|Field|LongFieldTests|Test6 +javasoft.sqe.tests.api.java.lang.reflect.Field.LongFieldTests -TestCaseID LongFieldTest0306 +JCK-114a|api|java_lang|reflect|Field|LongFieldTests|Test7 +javasoft.sqe.tests.api.java.lang.reflect.Field.LongFieldTests -TestCaseID LongFieldTest0307 +JCK-114a|api|java_lang|reflect|Field|LongFieldTests|Test8 +javasoft.sqe.tests.api.java.lang.reflect.Field.LongFieldTests -TestCaseID LongFieldTest0308 +JCK-114a|api|java_lang|reflect|Field|LongFieldTests|Test9 +javasoft.sqe.tests.api.java.lang.reflect.Field.LongFieldTests -TestCaseID LongFieldTest0309 +JCK-114a|api|java_lang|reflect|Field|LongFieldTests|Test10 +javasoft.sqe.tests.api.java.lang.reflect.Field.LongFieldTests -TestCaseID LongFieldTest0310 +JCK-114a|api|java_lang|reflect|Field|LongFieldTests|Test11 +javasoft.sqe.tests.api.java.lang.reflect.Field.LongFieldTests -TestCaseID LongFieldTest0311 +JCK-114a|api|java_lang|reflect|Field|LongFieldTests|Test12 +javasoft.sqe.tests.api.java.lang.reflect.Field.LongFieldTests -TestCaseID LongFieldTest0312 +JCK-114a|api|java_lang|reflect|Field|LongFieldTests|Test13 +javasoft.sqe.tests.api.java.lang.reflect.Field.LongFieldTests -TestCaseID LongFieldTest0313 +JCK-114a|api|java_lang|reflect|Field|ShortFieldTests|Test1 +javasoft.sqe.tests.api.java.lang.reflect.Field.ShortFieldTests -TestCaseID ShortFieldTest0201 +JCK-114a|api|java_lang|reflect|Field|ShortFieldTests|Test2 +javasoft.sqe.tests.api.java.lang.reflect.Field.ShortFieldTests -TestCaseID ShortFieldTest0202 +JCK-114a|api|java_lang|reflect|Field|ShortFieldTests|Test3 +javasoft.sqe.tests.api.java.lang.reflect.Field.ShortFieldTests -TestCaseID ShortFieldTest0203 +JCK-114a|api|java_lang|reflect|Field|ShortFieldTests|Test4 +javasoft.sqe.tests.api.java.lang.reflect.Field.ShortFieldTests -TestCaseID ShortFieldTest0204 +JCK-114a|api|java_lang|reflect|Field|ShortFieldTests|Test5 +javasoft.sqe.tests.api.java.lang.reflect.Field.ShortFieldTests -TestCaseID ShortFieldTest0205 +JCK-114a|api|java_lang|reflect|Field|ShortFieldTests|Test6 +javasoft.sqe.tests.api.java.lang.reflect.Field.ShortFieldTests -TestCaseID ShortFieldTest0206 +JCK-114a|api|java_lang|reflect|Field|ShortFieldTests|Test7 +javasoft.sqe.tests.api.java.lang.reflect.Field.ShortFieldTests -TestCaseID ShortFieldTest0207 +JCK-114a|api|java_lang|reflect|Field|ShortFieldTests|Test8 +javasoft.sqe.tests.api.java.lang.reflect.Field.ShortFieldTests -TestCaseID ShortFieldTest0208 +JCK-114a|api|java_lang|reflect|Field|ShortFieldTests|Test9 +javasoft.sqe.tests.api.java.lang.reflect.Field.ShortFieldTests -TestCaseID ShortFieldTest0209 +JCK-114a|api|java_lang|reflect|Field|ShortFieldTests|Test10 +javasoft.sqe.tests.api.java.lang.reflect.Field.ShortFieldTests -TestCaseID ShortFieldTest0210 +JCK-114a|api|java_lang|reflect|Field|ShortFieldTests|Test11 +javasoft.sqe.tests.api.java.lang.reflect.Field.ShortFieldTests -TestCaseID ShortFieldTest0211 +JCK-114a|api|java_lang|reflect|Field|ShortFieldTests|Test12 +javasoft.sqe.tests.api.java.lang.reflect.Field.ShortFieldTests -TestCaseID ShortFieldTest0212 +JCK-114a|api|java_lang|reflect|Field|ShortFieldTests|Test13 +javasoft.sqe.tests.api.java.lang.reflect.Field.ShortFieldTests -TestCaseID ShortFieldTest0213 +JCK-114a|api|java_lang|reflect|Field|FHashEqualTests|Test1 +javasoft.sqe.tests.api.java.lang.reflect.Field.FHashEqualTests -TestCaseID FHashEqualTest0901 +JCK-114a|api|java_lang|reflect|Field|FHashEqualTests|Test2 +javasoft.sqe.tests.api.java.lang.reflect.Field.FHashEqualTests -TestCaseID FHashEqualTest0902 +JCK-114a|api|java_lang|reflect|Field|FHashEqualTests|Test3 +javasoft.sqe.tests.api.java.lang.reflect.Field.FHashEqualTests -TestCaseID FHashEqualTest0903 +JCK-114a|api|java_lang|reflect|Field|FHashEqualTests|Test4 +javasoft.sqe.tests.api.java.lang.reflect.Field.FHashEqualTests -TestCaseID FHashEqualTest0904 +JCK-114a|api|java_lang|reflect|Field|PosFieldTests|Test1 +javasoft.sqe.tests.api.java.lang.reflect.Field.PosFieldTests -TestCaseID PosFieldTest1001 +JCK-114a|api|java_lang|reflect|Field|PosFieldTests|Test2 +javasoft.sqe.tests.api.java.lang.reflect.Field.PosFieldTests -TestCaseID PosFieldTest1002 +JCK-114a|api|java_lang|reflect|Field|PosFieldTests|Test3 +javasoft.sqe.tests.api.java.lang.reflect.Field.PosFieldTests -TestCaseID PosFieldTest1003 +JCK-114a|api|java_lang|reflect|Field|PosFieldTests|Test4 +javasoft.sqe.tests.api.java.lang.reflect.Field.PosFieldTests -TestCaseID PosFieldTest1004 +JCK-114a|api|java_lang|reflect|Field|PosFieldTests|Test5 +javasoft.sqe.tests.api.java.lang.reflect.Field.PosFieldTests -TestCaseID PosFieldTest1005 +JCK-114a|api|java_lang|reflect|Field|PosFieldTests|Test6 +javasoft.sqe.tests.api.java.lang.reflect.Field.PosFieldTests -TestCaseID PosFieldTest1006 +JCK-114a|api|java_lang|reflect|Field|PosFieldTests|Test7 +javasoft.sqe.tests.api.java.lang.reflect.Field.PosFieldTests -TestCaseID PosFieldTest1007 +JCK-114a|api|java_lang|reflect|Field|PosFieldTests|Test8 +javasoft.sqe.tests.api.java.lang.reflect.Field.PosFieldTests -TestCaseID PosFieldTest1008 +JCK-114a|api|java_lang|reflect|Field|PosFieldTests|Test9 +javasoft.sqe.tests.api.java.lang.reflect.Field.PosFieldTests -TestCaseID PosFieldTest1009 +JCK-114a|api|java_lang|reflect|Field|PosFieldTests|Test10 +javasoft.sqe.tests.api.java.lang.reflect.Field.PosFieldTests -TestCaseID PosFieldTest1010 diff --git a/ef/Quality/TestScript/jckjni.dll b/ef/Quality/TestScript/jckjni.dll new file mode 100644 index 000000000000..bbda4fcac108 Binary files /dev/null and b/ef/Quality/TestScript/jckjni.dll differ diff --git a/ef/Quality/TestScript/readme.html b/ef/Quality/TestScript/readme.html new file mode 100644 index 000000000000..a57eb246d3cc --- /dev/null +++ b/ef/Quality/TestScript/readme.html @@ -0,0 +1,59 @@ + + + EF Test Script + + + +Electrical Fire Test Script + +


+

+ +Usage +

+Before running the script, make sure sajava.exe is in your path and +your classpath is set. +

+perl runTests.pl < test file > [ options... ]
+perl runTests.pl -h
+
+ +Options +
+-q				Quite mode.  Print non-passing tests only.
+-gr				Generate an html report.
+-uw < class >			Use a wrapper class.
+-classpath < path >		Use the given classpath.
+-workdir < dir >		Use the directory as the working dir.
+-testroot < path >		Use the given path as the test root.
+-keyword < keyword >		Run tests with the given keyword only.
+-h				Help.
+
+ +Description +

+This test script's main purpose is to test Electrical Fire. It obviously, +with a few modifications, can be changed to test any Java Runtime. +

+The option -uw is to allow a wrapper class to be used to invoke +the tests. You can provided your own wrapper class as long as it prints +out the following results, which the test script will use to determine +if a test pass or failed. +

+

+For passing tests, print "STATUS:Passed."
+For failing tests, print "STATUS:Failed."
+
+Any tests that don't print out these two results will cause the test +script to make the test result as a Check Test. +

+The options -workdir and -testroot are JCK specific test +arguments. You don't need to specify them by default. The -workdir +argument is just a temp directory were some tests can perform I/O. The +-testroot is a path to the html test description of a JCK test. +If you want to specify a testroot, you will need to give the url path. +

+For example, "-testroot file:/g:/JCK-114a".
+
+ + diff --git a/ef/Quality/TestScript/runTests.pl b/ef/Quality/TestScript/runTests.pl new file mode 100644 index 000000000000..105d5c4baeea --- /dev/null +++ b/ef/Quality/TestScript/runTests.pl @@ -0,0 +1,38 @@ +#!perl + +# Add our lib path to the Perl search path. +use lib "../PerlLib/"; +use TestsMod; + +# Check arguments. +if (!(TestsMod::checkArgs(@ARGV))) { + + die "Usage: perl runTests.pl [options...]\n"; + +} + +# Check if the the first argument is the help option. +if ( $ARGV[0] eq '-h' ){ + print("runTests\n"); + print("Usage: perl runTests.pl [options....]\n"); + print("Options:\n"); + print("\t-q\t\t\tQuiet mode. Print non-passing tests only.\n"); + print("\t-gr\t\t\tGenerate report files.\n"); + print("\t-uw \t\tUse specfied class as a wrapper class.\n"); + print("\t-classpath \tUse specified path as the classpath.\n"); + print("\t-workdir \t\tUse specified dir as the working dir.\n"); + print("\t-testroot \tUse specified path as the test root.\n"); + print("\t-keyword \tRun tests with the specified keyword only.\n"); + print("\t-h\t\t\tHelp. You're in it.\n"); + exit; +} + +# Run the conformance tests. +TestsMod::runTests(@ARGV); + + + + + + + diff --git a/ef/Quality/UserTests/TinyClass.java b/ef/Quality/UserTests/TinyClass.java new file mode 100644 index 000000000000..74763f949219 --- /dev/null +++ b/ef/Quality/UserTests/TinyClass.java @@ -0,0 +1,1913 @@ +import java.io.PrintStream; + +// import java.lang.Exception; +final class MyException extends Exception +{ + String tag; + + public MyException(String inString) + { + tag = inString; + } + + public String toString() + { + return tag; + } + + public int intValue() + { + return Integer.parseInt(tag); + } +} + + +//---------------------------------------------------------- +// For JCKaastore01003 +class Subclss1_of_Object extends Object +{ + public int cc1; +} + +class Subclss2_of_Object extends Subclss1_of_Object +{ + public int cc2; +} +//---------------------------------------------------------- +// For JCKaastore01102 + +interface SomeInterface1 { + int SEVENS = 777; + + void printFields(PrintStream out); +} + +class SomeClass1 implements SomeInterface1 { + int i; + + public void printFields(PrintStream out) { + out.print("i = "); + out.println(i); + } + + SomeClass1(int i) { + this.i = i; + } +} + +interface AnotherInterface1 { + int THIRDS = 33; + + void printFields(PrintStream out); +} + +class AnotherClass1 implements AnotherInterface1 { + int i; + + public void printFields(PrintStream out) { + out.print("i = "); + out.println(i); + } + + AnotherClass1(int i) { + this.i = i; + } +} + +//---------------------------------------------------------- +// For JCKaastore01401 +interface SomeInterface2 { + int SEVENS = 777; +} + +interface Subinterface2 extends SomeInterface2 { + int THIRDS = 33; +} + +class SomeClass2 implements Subinterface2 { + int i; + + SomeClass2(int i) { + this.i = i; + } +} + +class ImmediateSubclass2 extends SomeClass2 implements SomeInterface2 { + float f; + + ImmediateSubclass2(int i, float f) { + super(i); + this.f = f; + } +} + +final class FinalSubclass2 extends ImmediateSubclass2 { + double d; + + FinalSubclass2(int i, float f, double d) { + super(i, f); + this.d = d; + } +} +//---------------------------------------------------------- + +// Very Simple tests that must pass before many serious tests will pass +public class TinyClass +{ + /* + public static long longAdd(long a, long b) + { + return a + b; + } + + public static long longAdd4(long a, long b, long c, long d) + { + return a + b + c + d; + } + + public static int mulTest(int a, int b, int c, int d, int e, int f, int g, int h) + { + int aa = a * b; + int cc = c * d; + int ee = e * f; + int gg = g * h; + return a + b + c + d + e + f + g + h + aa + cc + ee + gg; + } + */ + +//---------------------------------------------------------- +// Switch Test + public static int switchTest(int a) + { + int c = 0; + switch(a) + { + case 2: c = 1; break; + case 6: c = 13; break; + case 1: c = 1; break; + case 3: c = 3; break; + case 7: c = 21; break; + case 4: c = 5; break; + case 5: c = 8; break; + case 8: c = 34; break; + default: c = 55; + } + return c; + } + + public static boolean switchTestAll() + { + boolean result = ( + (switchTest(2) == 1) && + (switchTest(6) == 13) && + (switchTest(1) == 1) && + (switchTest(3) == 3) && + (switchTest(7) == 21) && + (switchTest(4) == 5) && + (switchTest(5) == 8) && + (switchTest(8) == 34) && + (switchTest(55) == 55) ); + report(result, "switchTestAll"); + return result; + } + + public static long switchLong(int a) + { + long result = 0; + switch(a) + { + case 0xcafebabe: result = 0x1234567812345678L; break; + case 0x01234567: result = 0xdeaddeaddeaddeadL; break; + case 0x11111111: result = 0xffffffffffffffffL; break; + default: result = 0xdeadc0dedeadc0deL; + } + return result; + } + + public static boolean switchLongHarness() + { + long t1 = switchLong(0xcafebabe); + long t2 = switchLong(0x01234567); + long t3 = switchLong(0x11111111); + long t4 = switchLong(0xffffffff); + + boolean r1 = t1 == 0x1234567812345678L; // find out real values + boolean r2 = t2 == 0xdeaddeaddeaddeadL; + boolean r3 = t3 == 0xffffffffffffffffL; + boolean r4 = t4 == 0xdeadc0dedeadc0deL; + + report(r1, "switchLong1"); + report(r2, "switchLong2"); + report(r3, "switchLong3"); + report(r4, "switchLong4"); + + return(r1 && r2 && r3 && r4); + } + + public static boolean switchTestNeg() + { + boolean result = ( + (switchTest( 0) == 55) && + (switchTest(-1) == 55) && + (switchTest(0xcafebabe) == 55)); + report(result, "switchTestNeg"); + return result; + } + + public static void switchTestHarness() + { + switchTestAll(); + switchTestNeg(); + switchLongHarness(); + } + +//---------------------------------------------------------- +// Seive Test + public static void Sieve(int[] an) + { + int k1 = 1; + int i2 = 0; + int j2 = 0; + + j2++; + an[0] = 1; + an[1] = 2; + k1 = 2; + + int length = an.length; + for (int i1 = 3; k1 < length; i1++) + { + boolean flag1; + i2 = 1; + for (flag1 = true; i2 < k1 && flag1; i2++) + if (an[i2] > 0 && an[i2] <= i1 / 2 && i1 % an[i2] == 0) + flag1 = false; + if (flag1) + { + k1++; + an[k1 - 1] = i1; + } + } + } + + public static boolean sieveHarness() + { + int a[] = new int[20]; + Sieve(a); + boolean result = false; + + if( a[ 0]==1 && a[ 1]==2 && a[ 2]==3 && a[ 3]==5 && a[ 4]==7 && + a[ 5]==11 && a[ 6]==13 && a[ 7]==17 && a[ 8]==19 && a[ 9]==23 && + a[10]==29 && a[11]==31 && a[12]==37 && a[13]==41 && a[14]==43 && + a[15]==47 && a[16]==53 && a[17]==59 && a[18]==61 && a[19]==67 ) + { + result = true; + } + else + { + for(int i = 0; i < 20; i++) + System.out.println(a[i]); + } + + report(result, "sieveTest"); + return result; + } + +//---------------------------------------------------------- +// Instance Test + public static boolean isStringObject(Object p) + { + return (p instanceof String); + } + + public static boolean instanceTestHarness() + { + int[] i = new int[5]; + String s = new String("test"); + + boolean result = (isStringObject(s) && !isStringObject(i)); + report(result, "instanceTest"); + return result; + } + +//---------------------------------------------------------- +// ArgumentOrdering Test +// sinple test to ensure that arguments are being passed in in the correct order + public static boolean orderTest(int a, int b, int c, int d) + { + return(a < b && b < c && c < d); + } + + public static boolean orderTestHarness() + { + boolean result = orderTest(12, 45, 78, 128); + report(result, "orderTest"); + return result; + } + +//---------------------------------------------------------- +// Aritmetic Tests + + public static int negTest(int a, int b) + { + int bb = -a; + int cc = -b; + int c = 0; + switch(a) + { + case 0: + c += bb; + case 1: + c += cc; + case 2: + c += a; + default: + c += b; + } + return c; + } + + public static boolean negTestHarness() + { + int a = 1; + int b = 20; + int intResult = negTest(a, b); + // bb = -1 + // cc = -20 + // c= 0 + -20 + // c+= 1 + // c+= 20 + // c should == 1 + boolean result = (intResult == 1); + report(result, "negTestHarness"); + return result; + } + +//---------------------------------------------------------- +// Long Multiply + public static long longMult(int temp, long a, long b, int temp2) + { + return a * b; + } + + public static void testMulHarness() + { + long mulResult = longMult(0xaa, 0x0dadbabeL, 0x10000L, 0xbb); + report(mulResult == 0x00000dadbabe0000L, "Long Multiply"); + } + +//---------------------------------------------------------- +// Integer Subtraction + public static int subTest(int a, int b) + { + return a - b; + } + + public static void subTestHarness() + { + report( 10 == subTest(56, 46), "subTest1"); + report(111 == subTest(222, 111), "subTest2"); + report(-10 == subTest(12, 22), "subTest3"); + report(993 == subTest(1000, 7), "subTest4"); + } + +//---------------------------------------------------------- +// Integer Comparisons + public static int cmpTestSigned(int a, int b) + { + if(a < b) + return -1; + if(a == b) + return 0; + else + return 1; + } + + public static void cmpTestsIntegers() + { + report( 1 == cmpTestSigned(34, 23), "cmpTestsIntegers1"); + report(-1 == cmpTestSigned(0x55, 0x77), "cmpTestsIntegers2"); + report(-1 == cmpTestSigned(-5, 7), "cmpTestsIntegers3"); + report( 0 == cmpTestSigned(1234, 1234), "cmpTestsIntegers4"); + } + + public static int cmpTestArray(int[] a, int b, int c) + { + int result = -99; + try + { + if(a[b] < a[c]) + result = -1; + else if(a[b] == a[c]) + result = 0; + else + result = 1; + } + catch (ArrayIndexOutOfBoundsException ex) + { + System.out.println("ArrayIndexOutOfBoundsException caught in cmpTestArray"); + } + return result; + } + + public static void cmpTestArrayHarness() + { + int[] a = new int[4]; + try + { + a[0] = 12; + a[1] = 44; + a[2] = 33; + a[3] = 33; + } + catch (ArrayIndexOutOfBoundsException ex) + { + System.out.println("ArrayIndexOutOfBoundsException caught in cmpTestArrayHarness pt 1"); + } + + try + { + report( 1 == cmpTestArray(a, 1, 0), "cmpTestArray1"); + report( 0 == cmpTestArray(a, 2, 3), "cmpTestArray2"); + report(-1 == cmpTestArray(a, 0, 3), "cmpTestArray3"); + report( 1 == cmpTestArray(a, 1, 3), "cmpTestArray4"); + } + catch (ArrayIndexOutOfBoundsException ex) + { + System.out.println("ArrayIndexOutOfBoundsException caught in cmpTestArrayHarness pt 2"); + } + } + + public static void cmpTestHarness() + { + cmpTestsIntegers(); + cmpTestArrayHarness(); + } + +//---------------------------------------------------------- +// Test Integer Divides + public static int divTest(int a, int b) + { + return a/b; + } + + public static int modTest(int a, int b) + { + return a%b; + } + + public static boolean divTestHarness(boolean debug) + { + boolean t1 = (divTest(12, 3) == 4); + boolean t2 = (divTest(12, 12) == 1); + boolean t3 = (divTest(12, -1) == -12); + boolean t4 = (divTest(110, 10) == 11); + if(debug) + { + report(t1, "div 12/3"); + report(t2, "div 12/12"); + report(t3, "div 12/-1"); + report(t4, "div 110/10"); + } + boolean result = (t1 && t2 && t3 && t4); + report(result, "divTestHarness"); + return result; + } + + public static boolean modTestHarness(boolean debug) + { + boolean t1 = (modTest(12, 5) == 2); + boolean t2 = (modTest(12, 12) == 0); + boolean t3 = (modTest(12, 14) == 12); + boolean t4 = (modTest(10, 3) == 1); + if(debug) + { + report(t1, "mod1"); + report(t2, "mod2"); + report(t3, "mod3"); + report(t4, "mod4"); + } + boolean result = (t1 && t2 && t3 && t4); + report(result, "modTestHarness"); + return result; + } + + public static boolean divModTest(int a, int b, boolean debug) + { + int quotient = divTest(a, b); + int remainder = modTest(a, b); + int original = (b * quotient) + remainder; + + boolean result = (a == original); + if(debug) + { + String s = "divModTest " + a + "/" + b; + if(!result) + s += " q=" + quotient + " r=" + remainder + " o=" + original; + report(result, s); + } + return result; + } + + public static int divModSumTestHarness() + { + boolean verbose = true; + int count = 0; + if(divModTest(123, 5, verbose)) + count++; + if(divModTest(45, 12, verbose)) + count++; + if(divModTest(13, 14, verbose)) + count++; + if(divModTest(0, 3, verbose)) + count++; + + report(count == 4, "divModSumTestHarness"); + return count; + } + + + public static int divModTestHarness() + { + int count = 0; + if(divTestHarness(true)) + count++; + if(modTestHarness(true)) + count++; + if(divModSumTestHarness() == 4) + count++; + + report(count == 3, "divModTestHarness"); + return count; + } + +//---------------------------------------------------------- +// Test Long Comparisons + + public static boolean cmpLongLessThan(long a, long b) { return (a < b); } + public static boolean cmpLongEqual(long a, long b) { return (a == b); } + public static boolean cmpLongGreaterThan(long a, long b) { return (a > b); } + public static boolean cmpLongGreaterThanEqual(long a, long b) { return (a >= b); } + public static boolean cmpLongLessThanEqual(long a, long b) { return (a <= b); } + public static boolean cmpLongNotEqual(long a, long b) { return (a != b); } + + public static int cmpLongTestHarnessHelper(long a, long b, boolean debug) + { + if(debug) + { + System.out.println("\n_______________________________________\nComparing " + a + " and " + b); + } + boolean lt = cmpLongLessThan(a, b); + boolean eq = cmpLongEqual(a, b); + boolean gt = cmpLongGreaterThan(a, b); + + boolean geq = cmpLongGreaterThanEqual(a, b); + boolean leq = cmpLongLessThanEqual(a, b); + boolean neq = cmpLongNotEqual(a, b); + + if(debug) + { + System.out.print(lt ? "lt:true " : "lt:false "); + System.out.print(eq ? "eq:true " : "eq:false "); + System.out.print(gt ? "gt:true " : "gt:false "); + System.out.print(geq ? "geq:true " : "geq:false "); + System.out.print(leq ? "leq:true " : "leq:false "); + System.out.println(neq ? "neq:true " : "neq:false "); + } + + int count = 0; + int returnValue = -255; + if(lt) + { + if(debug) System.out.print(" <, "); + returnValue = -1; + count++; + } + + if(eq) + { + if(debug) System.out.print(" ==, "); + returnValue = 0; + count++; + } + + if(gt) + { + if(debug) System.out.print(" >, "); + returnValue = 1; + count++; + } + + try + { + if(count != 1) + { + throw new MyException("cmpLongTest failed: mutual exclusion failure 1"); + } + + if(eq && neq) throw new MyException("cmpLongTest failed: mutual exclusion failure 2"); + if(lt && geq) throw new MyException("cmpLongTest failed: mutual exclusion failure 3"); + if(gt && leq) throw new MyException("cmpLongTest failed: mutual exclusion failure 4"); + if(geq && leq && neq) throw new MyException("cmpLongTest failed: mutual exclusion failure 5"); + } + catch (MyException ex) + { + System.out.println(ex.toString()); + } + + return returnValue; + } + + public static void cmpLongTestHarness() + { + report( 1 == cmpLongTestHarnessHelper(34, 23, false), "Long Comparison Test: 34 > 23"); + report( 1 == cmpLongTestHarnessHelper(34, 23, false), "Long Comparison Test: 34 > 23"); + report(-1 == cmpLongTestHarnessHelper(0x55, 0x77, false), "Long Comparison Test: 0x55 < 0x77"); + report( 0 == cmpLongTestHarnessHelper(98, 98, false), "Long Comparison Test: 98 == 98"); + report( 1 == cmpLongTestHarnessHelper(1234, 6, false), "Long Comparison Test: 1234 > 6"); + + report(-1 == cmpLongTestHarnessHelper(0x1234567812345678L, 0x2345678923456789L, false), "Long Comparison Test: a < b"); + report( 0 == cmpLongTestHarnessHelper(0x1234567812345678L, 0x1234567812345678L, false), "Long Comparison Test: a == b"); + report( 1 == cmpLongTestHarnessHelper(0x2345678923456789L, 0x1234567812345678L, false), "Long Comparison Test: a > b "); + } + + public static void cmpLongSimple() + { + report(cmpLongLessThan(500, 1000), "cmpLongSimple"); + } + +//---------------------------------------------------------- +// Test Int Comparisons + public static boolean cmpIntLessThan(int a, int b) + { + return (a < b); + } + + public static void cmpIntSimple() + { + report(cmpIntLessThan(500, 1000), "cmpIntSimple"); + } + +//---------------------------------------------------------- +// Test Long Shifts + public static long shiftLong(long a, int b) + { + return (a << b) + (a >> b) + (a >>> b); + } + + public static void shlLongHarness() + { + long t1 = shiftLong(0x00000000cafebabeL, 0); + long t2 = shiftLong(0xcafebabe00000000L, 16); + long t3 = shiftLong(0x1234567812345678L, 32); + long t4 = shiftLong(0x00000000deadbeefL, 64); + + boolean r1 = t1 == 0; // find out real values + boolean r2 = t2 == 0; + boolean r3 = t3 == 0; + boolean r4 = t4 == 0; + +/* + report(r1, "shiftLong1"); + report(r2, "shiftLong2"); + report(r3, "shiftLong3"); + report(r4, "shiftLong4"); + */ + } + + public static long convertToLongTest(int in) + { + return (long)in; + } + + public static void convertToLongHarness() + { + boolean r1 = convertToLongTest(12) == 12L; + boolean r2 = convertToLongTest(0xcafebabe) == 0xffffffffcafebabeL; + boolean r3 = convertToLongTest(0xdeadbeef) == 0xffffffffdeadbeefL; + boolean r4 = convertToLongTest(-1) == 0xffffffffffffffffL; + + report(r1, "convertToLong1"); + report(r2, "convertToLong2"); + report(r3, "convertToLong3"); + report(r4, "convertToLong4"); + } + + public static int convertToIntTest(long in, long in2) + { + return (int)in + (int)in2; + } + + public static void convertToIntHarness() + { + int t1 = convertToIntTest(14L, 20L); + int t2 = convertToIntTest(0x9999999966666666, 0x6666666699999999L); + int t3 = convertToIntTest(-1L, -2L); + int t4 = convertToIntTest(200L, 100L); + + boolean r1 = t1 == 34; + boolean r2 = t2 == -1; + boolean r3 = t3 == -3; + boolean r4 = t4 == 300; + + report(r1, "convertToIntTest1"); + if(!r1) System.out.println("int1 = " + t1); + + report(r2, "convertToIntTest2"); + if(!r2) System.out.println("int2 = " + t2); + + report(r3, "convertToIntTest3"); + if(!r3) System.out.println("int3 = " + t3); + + report(r4, "convertToIntTest4"); + if(!r4) System.out.println("int3 = " + t4); + } + + public static void convertHarness() + { + convertToLongHarness(); + convertToIntHarness(); + + boolean r1 = convertToIntTest(convertToLongTest(5), convertToLongTest(10)) == 15; + report(r1, "convertHarness"); + } + +//---------------------------------------------------------- +// Nested Exception Test + private static void throwIf0(int a) throws MyException { if(a == 0) throw new MyException("0"); } + private static void throwIf1(int a) throws MyException { if(a == 1) throw new MyException("1"); } + private static void throwIf2(int a) throws MyException { if(a == 2) throw new MyException("2"); } + private static void throwIf3(int a) throws MyException { if(a == 3) throw new MyException("3"); } + private static void throwIf4(int a) throws MyException { if(a == 4) throw new MyException("4"); } + private static void throwIf5(int a) throws MyException { if(a == 5) throw new MyException("5"); } + private static void throwIf6(int a) throws MyException { if(a == 6) throw new MyException("6"); } + private static void throwIf7(int a) throws MyException { if(a == 7) throw new MyException("7"); } + + public static void primeThrows() + { + try{ + throwIf0(-1); throwIf1(-1); throwIf2(-1); throwIf3(-1); + throwIf4(-1); throwIf5(-1); throwIf6(-1); throwIf7(-1); + } + catch (MyException ex) + { + System.out.println("Serious error--primeThrows"); + } + } + + // should return exactly 1 if 0 <= a <=7 + private static int nestedTryTest(int a) + { + int result = 0; + try { + try { + + throwIf6(a); + + try { + + try { + throwIf3(a); + try { throwIf0(a); } catch (MyException ex) { result+= ex.intValue(); } // 0 + try { throwIf1(a); } catch (MyException ex) { result+= ex.intValue(); } // 1 + } catch (MyException ex) { result+= ex.intValue(); } // 3 + + throwIf4(a); + + try { + throwIf5(a); + try { throwIf2(a); } catch (MyException ex) { result+= ex.intValue(); } // 2 + } catch (MyException ex) { result+= ex.intValue(); } // 5 + + } catch (MyException ex) { result+= ex.intValue(); } // 4 + + } catch (MyException ex) { result+= ex.intValue(); } // 6 + + throwIf7(a); + } catch (MyException ex) { result+= ex.intValue(); } // 7 + + return result; + } + + public static void nestedTryTester() + { + primeThrows(); + + if (false) + { + report(nestedTryTest(6) == 6, "nestedTry" + 6); + } + else + { + for(int i = 0; i < 8; i++) + { + int result = nestedTryTest(i); + report(result == i, "nestedTry" + i); + if(result != i) + System.out.println("result = " + result); + } + + report(nestedTryTest(-1) == 0, "nestedTry" + -1); + report(nestedTryTest(10) == 0, "nestedTry" + 10); + } + } + +//---------------------------------------------------------- +// Exception Test +// Simple Throw and Catch in same method + public static int goo(int i) + throws MyException + { + try + { + if(i == 23) + throw new MyException("I am an exception!"); + } + catch (ArithmeticException ex) + { + System.out.println("\n*** SHIT! I shouldn't be here!"); + } + return i + 47; + } + + public static int bar(int i) + throws MyException + { + int p = i - 2 + goo(i); + return p; + } + + public static int foo(int i) + throws MyException + { + int q = i + 37 - bar(i); + return q; + } + + public static boolean excTestSingleLocalThrowLocalCatch() + { + boolean result = false; + try + { + throw new MyException("thrown exception"); + } + catch (MyException ex) + { + result = true; + } + return result; + } + + public static boolean excTestSingleRemoteThrowLocalCatch() + { + boolean result = false; + try + { + foo(23); + } + catch (MyException ex) + { + result = true; + } + return result; + } + + public static boolean excTestMultiRemoteThrowRemoteCatch() + { + int testCount = 0; + for(int i = 0; i < 10; i++) + if(excTestSingleLocalThrowLocalCatch()) + testCount++; + return (testCount == 10); + } + + // test multiple catches from a remote throw + public static boolean excTestMultiRemoteThrowLocalCatch() + { + int testCount = 0; + for(int i = 0; i < 10; i++) + { + try + { + foo(23); + } + catch (MyException ex) + { + testCount ++; + } + } + return (testCount == 10); + } + + // test multiple catches from a local throw + public static boolean excTestMultiLocalThrowLocalCatch() + { + int testCount = 0; + for(int i = 0; i < 10; i++) + { + try + { + throw new MyException("hi"); + } + catch (MyException ex) + { + testCount ++; + } + } + return (testCount == 10); + } + + public static void excTestHarness() + { + report(excTestSingleLocalThrowLocalCatch(), "excTestSingleLocalThrowLocalCatch"); + report(excTestSingleRemoteThrowLocalCatch(), "excTestSingleLocalThrowLocalCatch"); + report(excTestMultiRemoteThrowRemoteCatch(), "excTestMultiRemoteThrowRemoteCatch"); + report(excTestMultiLocalThrowLocalCatch(), "excTestMultiLocalThrowLocalCatch"); + report(excTestMultiRemoteThrowLocalCatch(), "excTestMultiRemoteThrowLocalCatch"); + } + +//---------------------------------------------------------- + // call with a = 23, result = 1 + 2 + 4 + 8 + 16 + 32 == 63 + // otherwise result = 1 + 64 + 4 + 128 + 16 + 256 + 1024 == 1431 + private static int complexCatch(int a) + { + int result = 0; + try + { + result = 1; + try + { + foo(a); + result += 64; + } + catch (MyException ex) + { + result += 2; + } + + result += 4; + try + { + foo(a); + result += 128; + } + catch (MyException ex) + { + result += 8; + } + + result += 16; + foo(a); // should generate exception here + result += 256; + + try + { + foo(a); + } + catch (MyException ex) + { + result += 512; + } + result += 1024; + } + catch (MyException ex) + { + result += 32; + } + + return result; // should be 1 + 2 + 4 + 8 + } + + public static void complexCatchHarness() + { + int t0 = complexCatch(23); + int t1 = complexCatch(22); + + boolean r0 = t0 == (1 + 2 + 4 + 8 + 16 + 32); + boolean r1 = t1 == (1 + 64 + 4 + 128 + 16 + 256 + 1024); + + report(r0, "ComplexCatchTrue"); + if(!r0) System.out.println("ComplexCatchTrue = " + t0); + + report(r1, "ComplexCatchFalse"); + if(!r1) System.out.println("ComplexCatchFalse = " + t1); + } + +//========================================================== +// Store Long Test + + // store into an array and test that the values were actually stored + public static void storeIntoLongArray(long[] a) + { + a[0] = 1; + a[1] = 1; + a[2] = 3; + a[3] = 5; + a[4] = 8; + a[5] = 13; + a[6] = 21; + a[7] = 34; + } + + public static boolean loadFromLongArray(long[] a) + { + if ( (a[0] != 1) || (a[1] != 1) || (a[2] != 3) || (a[3] != 5) || (a[4] != 8) || + (a[5] != 13) || (a[6] != 21) || (a[7] != 34) ) + return false; + return true; + } + + public static boolean longStoreTestHarness() + { + long[] a = new long[8]; + storeIntoLongArray(a); + boolean r1 = loadFromLongArray(a); + report(r1, "longStoreTest"); + return r1; + } + + // no output! + public static void storeLongTest2() + { + long[] l = new long[100]; + long b = 32; + for(int i = 0; i < 100; i++) + { + b += i; + l[i] = b; + } + } + + public static boolean simpleLongStoreTestHarness() + { + long[] a = new long[1]; + a[0] = 0xdeadbeefcafebabeL; + boolean r1 = a[0] == 0xdeadbeefcafebabeL; + report(r1, "simpleLongStoreTest"); + return r1; + } + + public static boolean sillyLongConstTest() + { + return cmpLongEqual(0xdeadbeefcafebabeL, 0xdeadbeefcafebabeL); + } + + // Test Addition + public static long longAddTest(long a, long b) + { + return (a + b); + } + + public static void longAddTestHarness() + { + long t0 = longAddTest(1000L, 1L); + long t1 = longAddTest(0xdeadbeef00000000L, 0x00000000cafebabeL); + long t2 = longAddTest(0x1010101010101010L, 0x0101010101010101L); + long t3 = longAddTest(0x9999999999999999L, 0x6666666666666666L); + + boolean r0 = t0 == 1001; + boolean r1 = t1 == 0xdeadbeefcafebabeL; + boolean r2 = t2 == 0x1111111111111111L; + boolean r3 = t3 == 0xffffffffffffffffL; + + report(r0, "longAddTest0"); + if(!r0) System.out.println("long0 = " + t0); + + report(r1, "longAddTest1"); + if(!r1) System.out.println("long1 = " + t1); + + report(r2, "longAddTest2"); + if(!r2) System.out.println("long2 = " + t2); + + report(r3, "longAddTest3"); + if(!r3) System.out.println("long3 = " + t3); + } + + // Test 'Or' Operator + public static long longOrTest(long a, long b) + { + return (a | b); + } + + public static void longOrTestHarness() + { + long t0 = longOrTest(1000L, 1L); + long t1 = longOrTest(0xdeadbeef00000000L, 0x00000000cafebabeL); + long t2 = longOrTest(0x1010101010101010L, 0x0101010101010101L); + long t3 = longOrTest(0x9999999999999999L, 0x6666666666666666L); + + boolean r0 = t0 == 1001; + boolean r1 = t1 == 0xdeadbeefcafebabeL; + boolean r2 = t2 == 0x1111111111111111L; + boolean r3 = t3 == 0xffffffffffffffffL; + + report(r0, "longOrTest0"); + if(!r0) System.out.println("long0 = " + t0); + + report(r1, "longOrTest1"); + if(!r1) System.out.println("long1 = " + t1); + + report(r2, "longOrTest2"); + if(!r2) System.out.println("long2 = " + t2); + + report(r3, "longOrTest3"); + if(!r3) System.out.println("long3 = " + t3); + } + + // tests lots of things + public static String longToHexString(long a) + { + String result = ""; + + for(int i = 0; i < 16; i++) + { + int digit = (int) (a & 0x000000000000000fL); + switch(digit) + { + case 10: result = "a" + result; break; + case 11: result = "b" + result; break; + case 12: result = "c" + result; break; + case 13: result = "d" + result; break; + case 14: result = "e" + result; break; + case 15: result = "f" + result; break; + default: result = digit + result; + } + a = a >> 4; + } + + return "0x" + result; + } + + public static void longToHexStringTest() + { + String t1 = longToHexString (0xdeadbeefcafebabeL); + boolean r1 = t1.equals("0xdeadbeefcafebabe"); + + if(!r1) + System.out.println("0xdeadbeefcafebabe != " + t1); + + report(r1, "longToHexStringTest"); + } + + public static void longTestHarness() + { + longAddTestHarness(); + longOrTestHarness(); + longStoreTestHarness(); + longToHexStringTest(); + simpleLongStoreTestHarness(); + report(sillyLongConstTest(), "sillyLongConstTest"); + storeLongTest2(); // no output + } + +//========================================================== +// Array Access Exceptions + public static void testArrayStore(int[] b, int a) + { + b[a] = 3; + } + + public static int arrayExceptionHelper(int[] array, int index) + { + int result = 0; + try + { + testArrayStore(array, index); + } + catch (ArrayIndexOutOfBoundsException ex) + { + result = 0; + } + catch (IndexOutOfBoundsException ex) + { + result = 1; + } + catch (NullPointerException ex) + { + result = 2; + } + catch (NegativeArraySizeException ex) + { + result = 3; + } + return result; + } + + public static boolean testNullPointerException() + { + boolean result = (arrayExceptionHelper(null, 1) == 2); + report(result, "testNullPointerException"); + return result; + } + + public static boolean testIndexOutOfBoundsException1() + { + boolean result = (arrayExceptionHelper(new int[10], 10) == 0); + report(result, "testIndexOutOfBoundsException1"); + return result; + } + + public static boolean testIndexOutOfBoundsException2() + { + boolean result = (arrayExceptionHelper(new int[10], -1) == 0); + report(result, "testIndexOutOfBoundsException2"); + return result; + } + + public static int[] makeNewArray(int a) + { + return new int[a]; + } + + public static boolean testNegativeArraySizeException() + { + boolean result = false; + try + { + int[] a = makeNewArray(-5); + } + catch (NegativeArraySizeException ex) + { + result = true; + } + report(result, "testNegativeArraySizeException"); + return result; + } + + public static void testArrayAccessExceptions() + { + int count = 0; + if(testNullPointerException()) + count++; + if(testNegativeArraySizeException()) + count++; + if(testIndexOutOfBoundsException1()) + count++; + if(testIndexOutOfBoundsException2()) + count++; + report(count == 4, "testArrayAccessExceptions"); + } + +//========================================================== +// Hardware Exceptions + public static boolean testHardwareExceptions() + { + boolean result = false; + try + { + divTest(3, 0); + } + catch (ArithmeticException ex) + { + result = true; + } + report(result, "testHardwareExceptions"); + return result; + } + + +//========================================================== +// JCK Store Tests + static Object[] arrayref=new String[10]; + + private static int JCKaastore00701b() + { + try + { + arrayref[1]=arrayref; + return 2; + } catch (ArrayStoreException e) { + return 0; + } + } + + private static int JCKaastore00701c(PrintStream out) + { + try + { + arrayref[2]=out; + return 3; + } + catch (ArrayStoreException e) + { + } + return 0; + } + + private static int JCKaastore00701(PrintStream out, boolean debug) + { +// if(debug) System.out.println("Begin JCKaastore00701"); + try { + arrayref[0]=null; + } catch (ArrayStoreException e) { + return 1; + } + // if(debug) System.out.println("done1 JCKaastore00701"); + try { + arrayref[1]=arrayref; + return 2; + } catch (ArrayStoreException e) { + } + // if(debug) System.out.println("done2 JCKaastore00701"); + try { + arrayref[2]=out; + return 3; + } catch (ArrayStoreException e) { + } +// if(debug) System.out.println("done3 JCKaastore00701"); + return 0; + } + + static final int len=10; + static PrintStream outStream; + private static int JCKaastore01003(PrintStream out) + { + Subclss1_of_Object arrayref[]=new Subclss1_of_Object[len]; + Subclss2_of_Object obj=new Subclss2_of_Object(); + + outStream=out; + try + { + obj.cc2=1; + arrayref[1]=obj; + outStream.println("aastore01003: Array Store Error"); + return 2; + } + catch (ArrayStoreException e) + { + return 0; + } + } + + private static int JCKaastore01102(PrintStream out) + { + SomeInterface1 u[]=new SomeInterface1[len]; + AnotherInterface1 v[]=new AnotherInterface1[len];; + SomeClass1 x; + AnotherClass1 y; + + outStream=out; + x = new SomeClass1(1); + y = new AnotherClass1(1); + try + { + u[1] = x; + v[1] = y; + outStream.println("aastore01102: Array Store Error"); + return 2; + } + catch (ArrayStoreException e) + { + return 0; + } + } + + private static int JCKaastore01301(PrintStream out) + { + byte b1[]=new byte[2], b2[][]=new byte[3][4]; + short s1[]=new short[2], s2[][]=new short[3][4]; + int i1[]=new int[2], i2[][]=new int[3][4]; + long l1[]=new long[2], l2[][]=new long[3][4]; + char c1[]=new char[2], c2[][]=new char[3][4]; + float f1[]=new float[2], f2[][]=new float[3][4]; + double d1[]=new double[2], d2[][]=new double[3][4]; + + outStream=out; + try { + b2[0] = b1; + s2[0] = s1; + i2[0] = i1; + l2[0] = l1; + c2[0] = c1; + f2[0] = f1; + d2[0] = d1; + return 0; + } catch (ArrayStoreException e) { + outStream.println("aastore01301: Array Store Error"); + return 2; + } + } + + public static int JCKaastore01401a(PrintStream out) + { + SomeClass2 x [] []; + try { + x = new SomeClass2 [3] []; + x[0] = new ImmediateSubclass2 [4]; + return 0; + } catch (ArrayStoreException e) { + return -1; + } + } + + public static int JCKaastore01401(PrintStream out) + { + int i [], j []; + SomeInterface2 u [], v[] []; + Subinterface2 w []; + SomeClass2 x [] []; + ImmediateSubclass2 y []; + FinalSubclass2 z []; + Object obj []; + + int result = 0; + + try { + result = 1; + i = new int [10]; + result = 2; + i[0] = 777; + result = 3; + j = i; + result = 4; + x = new SomeClass2 [3] []; + result = 5; + x[0] = new ImmediateSubclass2 [4]; + result = 6; + z = new FinalSubclass2 [4]; + result = 7; + x[1] = z; + result = 8; + x[0][0] = new ImmediateSubclass2(1, 3.14f); + result = 9; + x[1][1] = new FinalSubclass2(-1, -3.14f, -2.71d); + result = 10; + u = x[0]; + result = 11; + u = x[1]; + result = 12; + v = x; + result = 13; + w = x[0]; + result = 14; + u = w; + result = 15; + obj = x[1]; + result = 16; + obj = x; + result = 17; + v = null; + result = 18; + v = (SomeInterface2 [] []) obj; + return 0; + } catch (ArrayStoreException e) { + return result; + } + } + + public static boolean JCKStoreTests() + { + boolean result = true; + + result &= fullReport(JCKaastore00701b(), 0, "JCKaastore00701b"); + result &= fullReport(JCKaastore00701c(System.out), 0, "JCKaastore00701c"); + result &= fullReport(JCKaastore00701(System.out, true), 0, "JCKaastore00701"); + result &= fullReport(JCKaastore01003(System.out), 0, "JCKaastore01003"); + result &= fullReport(JCKaastore01102(System.out), 0, "JCKaastore01102"); + result &= fullReport(JCKaastore01401a(System.out), 0, "JCKaastore01401a"); + result &= fullReport(JCKaastore01401(System.out), 0, "JCKaastore01401"); + result &= fullReport(JCKaastore01301(System.out), 0, "JCKaastore01301"); + return result; + } + +//========================================================== +// JCK LongTests + private static int JCKlsub00401() + { + long l1 = 0xFFFFFFFFFFFFFFFFl; + long l2 = 0x7FFFFFFFFFFFFFFFl; + long l3 = 0x8000000000000000l; + long negOne = -1l; + long res; + + if ((res = l1 - negOne) < 0) + return 1; + else if (res != 0) + return 2; + else if ((res = l2 - negOne) >= 0) + return 3; + else if (res != l3) + return 4; + else if ((res = l3 - 1l) <= 0) + return 5; + else if (res != l2) + return 6; + return 0; + } + + public static boolean JCKLongTests() + { + boolean r0 = fullReport(JCKlsub00401(), 0, "JCKlsub00401"); + return r0; + } + +//========================================================== +// Byte/Float/Double stuff + private static boolean simpleByteTest(byte value, boolean debug) + { + Byte b = new Byte(value); + boolean result = true; + + result &= conditionalFullReport(b.floatValue() == (float)value,true, "simpleByteTest.float with " + value, debug); + if(debug && (b.floatValue() == (float)value) == false) + System.out.println("simpleByteTest.float: apparently " + b.floatValue() + " and " + (float)value + " aren't equal\n"); + + result &= conditionalFullReport(b.doubleValue() == (double)value,true, "simpleByteTest.double with " + value, debug); + if(debug && (b.doubleValue() == (double)value) == false) + System.out.println("simpleByteTest.double: apparently " + b.doubleValue() + " and " + (double)value + " aren't equal\n"); + + return result; + } + + private static boolean byteTest(byte value, boolean debug) + { + Byte b = new Byte(value); + boolean result = true; + result &= conditionalFullReport(b.equals(new Byte(value)), true, "byteTest.equals with " + value, debug); + result &= conditionalFullReport(b.hashCode() == value, true, "byteTest.hash with " + value, debug); + result &= conditionalFullReport(b.intValue() == value,true, "byteTest.int with " + value, debug); + result &= conditionalFullReport(b.longValue() == (long)value,true, "byteTest.long with " + value, debug); + result &= conditionalFullReport(b.floatValue() == (float)value,true, "byteTest.float with " + value, debug); + if(debug && (b.floatValue() == (float)value) == false) + System.out.println("byteTest.float: apparently " + b.floatValue() + " and " + (float)value + " were supposed to be the same"); + + result &= conditionalFullReport(b.doubleValue() == (double)value,true, "byteTest.double with " + value, debug); + if(debug && (b.doubleValue() == (double)value) == false) + System.out.println("byteTest.double: apparently " + b.doubleValue() + " and " + (double)value + " were supposed to be the same"); + + result &= conditionalFullReport(b.shortValue() == (short)value,true, "byteTest.short with " + value, debug); + return result; + } + + private static boolean byteTestHelper(int value) + { + boolean result = true; + + boolean r1 = byteTest((byte)value, false); + if(!r1) + byteTest((byte)value, true); + result &= r1; + + boolean r2 = simpleByteTest((byte)value, false); + if(!r2) + simpleByteTest((byte)value, true); + result &= r2; + + return result; + } + + public static void byteTestHarness() + { + stupidByteTestHarness(); + byteTestHelper(9); + simpleByteTest((byte)9, true); + byteTestHelper(9); + simpleByteTest((byte)9, true); + byteTestHelper(12); + byteTestHelper(0); + byteTestHelper(-3); + byteTestHelper(17); + } + +//========================================================== +// Stupid Test + // returns 3 if both tests pass + private static int stupidByteTest(byte value) + { + Byte b = new Byte(value); + int result = 0; + + if(b.floatValue() == (float)value) + result |= 1; + + if(b.doubleValue() == (double)value) + result |= 2; + + return result; + } + + public static void stupidByteTestHarness() + { + for(byte i = (byte)-10; i <= 10; i++) + { + int result = stupidByteTest(i); + if(result != 3) + { + if((result & 1) == 0) + System.out.println("stupidByteTest " + i + " (float) failed"); + if((result & 2) == 0) + System.out.println("stupidByteTest " + i + " (double) failed"); + } + } + } + +//========================================================== +// Integer Object + + public static int hextoint(String s) + { + int sum = 0; + int length = s.length(); + for(int i = 0; i < length; i++) + { + int digit = 0; + char c = s.charAt(i); + switch(c) + { + case '0': digit = 0; break; + case '1': digit = 1; break; + case '2': digit = 2; break; + case '3': digit = 3; break; + case '4': digit = 4; break; + case '5': digit = 5; break; + case '6': digit = 6; break; + case '7': digit = 7; break; + case '8': digit = 8; break; + case '9': digit = 9; break; + case 'a': digit = 10; break; + case 'b': digit = 11; break; + case 'c': digit = 12; break; + case 'd': digit = 13; break; + case 'e': digit = 14; break; + case 'f': digit = 15; break; + default: + System.out.println("hextointtest internal error: '" + c + "'"); + } + sum = sum * 16 + digit; + } + return sum; + } + + public static boolean inttohextest(int input) + { + String string = Integer.toHexString(input); + int integer = hextoint(string); + + boolean result = (input == integer); + + if(!result) + { + System.out.print("in:" + input); + System.out.print(", string:'" + string + "'"); + System.out.println(", out:" + integer); + } + + return result; + } + + public static void simplehextest() + { + report(Integer.toHexString(12).equals("c"), "simplehextest1"); + report(Integer.toHexString(-1).equals("ffffffff"), "simplehextest2"); + report(Integer.toHexString(0).equals("0"), "simplehextest3"); + } + + public static void betterHexTest() + { + report(inttohextest(27), "integerHexTest1"); + report(inttohextest(-1), "integerHexTest1"); + report(inttohextest(255), "integerHexTest1"); + } + + // From JDK -- Convert the integer to an unsigned number. + private static String toUnsignedString(int i, int shift, boolean debug) + { + + StringBuffer buf = new StringBuffer(shift >= 3 ? 11 : 32); + int radix = 1 << shift; + int mask = radix - 1; + + if(debug) + System.out.println("radix: " + radix + "\nmask: " + mask); + + do + { + buf.append(Character.forDigit(i & mask, radix)); + + if(debug) + System.out.println( + "i=" + i + " i&mask=" + (i & mask) + " radix=" + + radix + " --> append: '" + Character.forDigit(i & mask, radix) + "'"); + + i >>>= shift; + } while (i != 0); + + if(debug) + System.out.println("before reversing: '" + buf + "'\n"); + + return buf.reverse().toString(); + } + + private static boolean mytoHexTest(int input, String expected) + { + String hex = toUnsignedString(input, 4, false); + boolean result = hex.equals(expected); + + report(result, "mytoHexTest" + expected); + if(!result) + { + System.out.println("in: " + input + " out:'" + hex + "' expected:'" + expected + "'"); + toUnsignedString(input, 4, true); + } + + return result; + } + + public static boolean mytoHexTestHarness() + { + boolean r0 = mytoHexTest(0x00, "0"); + boolean r1 = mytoHexTest(0x0a, "a"); + boolean r2 = mytoHexTest(0xdeadbeef, "deadbeef"); + boolean r3 = mytoHexTest(-1, "ffffffff"); + return r0 && r1 && r2 && r3; + } + + public static void integerHarness() + { + mytoHexTestHarness(); + simplehextest(); + betterHexTest(); + } + +//========================================================== +// Simple Character Tests + public static boolean charForDigitTestSimple() + { + boolean r0 = + Character.forDigit(0x00, 16) == '0' && + Character.forDigit(0x01, 16) == '1' && + Character.forDigit(0x02, 16) == '2' && + Character.forDigit(0x03, 16) == '3' && + Character.forDigit(0x04, 16) == '4' && + Character.forDigit(0x05, 16) == '5' && + Character.forDigit(0x06, 16) == '6' && + Character.forDigit(0x07, 16) == '7' && + Character.forDigit(0x08, 16) == '8' && + Character.forDigit(0x09, 16) == '9' && + Character.forDigit(0x0a, 16) == 'a' && + Character.forDigit(0x0b, 16) == 'b' && + Character.forDigit(0x0c, 16) == 'c' && + Character.forDigit(0x0d, 16) == 'd' && + Character.forDigit(0x0e, 16) == 'e' && + Character.forDigit(0x0f, 16) == 'f'; + + report(r0, "charForDigitTestSimple"); + return r0; + } + + public static boolean charForDigitTest() + { + char t0 = Character.forDigit(0x0a, 16); + boolean r0 = t0 == 'a'; + + char t1 = Character.forDigit(0, 2); + boolean r1 = t1 == '0'; + + char t2 = Character.forDigit(15, 10); + boolean r2 = t2 == '\u0000'; + + char t3 = Character.forDigit(9, 36); + boolean r3 = t3 == '9'; + + report(r0, "charForDigitTest0"); + if(!r0) System.out.println("char0 = '" + t0 + "'"); + + report(r1, "charForDigitTest1"); + if(!r1) System.out.println("char1 = '" + t1 + "'"); + + report(r2, "charForDigitTest2"); + if(!r2) System.out.println("char2 = '" + t2 + "'"); + + report(r3, "charForDigitTest3"); + if(!r3) System.out.println("char3 = '" + t3 + "'"); + + return r0 && r1 && r2 && r3; + } + + public static void characterTests() + { + charForDigitTestSimple(); + charForDigitTest(); + } + +//========================================================== +// Utility + + public static boolean conditionalFullReport(String result, String expected, String testName, boolean debug) + { + boolean r0 = result.equals(expected); + if (debug) + { + String text = testName; + if(!r0) + text += " returned " + result + "(expected " + expected + ")"; + report(r0, text, debug); + } + return r0; + } + + public static boolean conditionalFullReport(boolean result, boolean expected, String testName, boolean debug) + { + boolean r0 = result == expected; + if (debug) + { + String text = testName; + if(!r0) + text += " returned " + result; + report(r0, text, debug); + } + return r0; + } + + public static boolean fullReport(int result, int expected, String testName) + { + boolean r0 = result == expected; + String text = testName; + if(!r0) + text += " returned " + result; + report(r0, text); + return r0; + } + + public static void report(boolean result, String testName) + { + report(result, testName, true); + } + public static void report(boolean result, String testName, boolean debug) + { + //if(true) + { + if(result) + System.out.print(" Passed "); + else + System.out.print("*Failed* "); + + System.out.println("'" + testName + "'"); + } + /* + else + { + System.out.println("\n%\nNAME: " + testName); + if(result) + System.out.print("STATUS: PASSED."); + else + System.out.print("STATUS: FAILED."); + } + */ + } + +//========================================================== +// Main + + public static void runAllTests() + { + System.out.println("Begin Tests"); + subTestHarness(); + switchTestHarness(); + excTestHarness(); + complexCatchHarness(); + cmpLongTestHarness(); + cmpLongSimple(); + cmpIntSimple(); + convertHarness(); + byteTestHarness(); + longTestHarness(); + testMulHarness(); + cmpTestHarness(); + shlLongHarness(); + testArrayAccessExceptions(); + orderTestHarness(); + instanceTestHarness(); + negTestHarness(); + divModTestHarness(); + sieveHarness(); + testHardwareExceptions(); + characterTests(); + integerHarness(); + JCKLongTests(); + // JCKStoreTests(); + nestedTryTester(); + System.out.println("End Tests"); + } + + public static float fadd(float a, float b) + { + if (a < 3.0 && b > 12.5) + return a + b; + else + return b - a; + } + +/* + public static int idiv(int a, int b) + { + return a/b; + } +*/ + public static void main(String[] args) + { + runAllTests(); + // fadd(12.5f, 34.5f); + // idiv(0x80000000, 0xffffffff); + } +} \ No newline at end of file diff --git a/ef/README.html b/ef/README.html new file mode 100644 index 000000000000..ec51cc3ee57e --- /dev/null +++ b/ef/README.html @@ -0,0 +1,135 @@ + + + + + + + Electrical Fire README + + + +

+1. What is Electrical Fire ?

+Electrical Fire is the code name for a multi-platform Just-In-Time Java +compiler (JIT).  For more information, see the Electrical +Fire homepage . +

+2. How to build Electrical Fire on Windows

+ +

+2.1 Requirements

+ +
The canonical development environment for Windows platforms +is NT 4.0.  (It's probable that Win95/98 work, but it has not been +tested.)  The following tools need to be installed: +
    +
  • +MSVC 5.0.
  • + +
  • +GNU Tools for Microsoft Windows, located:
  • + + +Specifically, you'll need: +
      cp.exe +
      rm.exe +
      uname.exe +
      flex.exe +
      bison.exe +
       
    + +
  • +Netscape has internally modified version of gmake, shmsdos and win32gnu +that we use to get around some problems we were having keeping in sync +with the Unix version of gmake. This version of gmake can be found in the +Windows Build Tools package, which can be ftp'd from +the +Mozilla Download page. The three files you will need are:
  • + +
      gmake.exe +
      shmsdos.exe +
      uname.exe +
       
    + +
  • +Download the BURG tool: ftp://ftp.cs.arizona.edu/people/todd/burg.shar.Z +You'll need to download this file on a unix box, since this is distributed +as a shell archive.  Put the resulting files in the mozilla/ef/tools/Burg +directory.  (We can eliminate this download step if we can get permission +to redistribute BURG.)
  • + +
  • +Obtain jvmdi.h:  Download +JDK1.2 from Sun.  After installing, copy the jvmdi.h file into +the mozilla/ef/Debugger directory.  (We can eliminate this download +step if we can get Sun to give us permission to redistribute the file, +the way they've done for us with jni.h)
  • +
+
+ +

+2.2 Get the code

+ +
Download the code using CVS:
+ +
+
cvs co mozilla/ef +
cvs co mozilla/nsprpub +

(Need to add a CVS module for EF)

+
+ +

+2.3 Setup the Build Environment

+ +
+
  • +Set your MOZ_TOOLS environment variable to point to the parent +directory of the GNU tools 'bin' directory. The build looks for MOZ_TOOLS\bin\gmake.exe, +so make sure that the gmake.exe from the Windows Build Tools package resides +there, e.g.
  • + +
      set MOZ_TOOLS=C:\moztools
    + +
  • +Create a \tmp directory for temporary files in the root of the +drive which you are using to build, e.g. D:\tmp.  (You must +do this even if you have TEMP or TMP environment variables +that point to another directory, as bison ignores these variables).
  • + +
  • +Add the mozilla\dist\$(OBJDIR)\bin directory to your PATH
  • +
    + +

    +2.4 Build ElectricalFire

    + +
      +
    • +Build the NSPR library:
    • + +
        cd mozilla\nsprpub
        +gmake
      + +
    • +Start MSVC 5.0 and load the following workspace
    • + +
        +
        mozilla\ef\Driver\StandAloneJava\winbuild\ElectricalFire.dsw
        +
      + +
    • +Under MSVC's Build menu, select "Build electricalfire.exe"
    • +
    + + + diff --git a/ef/Runtime/ClassInfo/ClassCentral.cpp b/ef/Runtime/ClassInfo/ClassCentral.cpp new file mode 100644 index 000000000000..c85cc1d9defd --- /dev/null +++ b/ef/Runtime/ClassInfo/ClassCentral.cpp @@ -0,0 +1,540 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#include "prenv.h" +#include "prio.h" +#include "ClassCentral.h" +#include "ErrorHandling.h" +#include "DiskFileReader.h" + +#include "CUtils.h" +#include "StringUtils.h" + +#include "plstr.h" +#include "prprf.h" + + +UT_DEFINE_LOG_MODULE(ClassCentral); + + +ClassCentral::ClassCentral(Pool &p, ClassWorld &world, StringPool &sp, + const char *cp) : + classPool(staticPool), world(world), sp(sp), dynamicPool(p) +{ + classPath = 0; + setClassPath(cp); +} + + +/* Returns a new path string formed by concatenating the + * path string t to the path string s. A path string is a + * colon-separated list of (canonical) directory names. + */ +char *ClassCentral::concatPath(const char *s, const char *t) +{ + char *newStr = new (staticPool) char[PL_strlen(s)+PL_strlen(t)+1]; + + PL_strcpy(newStr, s); + + if (newStr[PL_strlen(s)-1] != ':') + PL_strcat(newStr, ":"); + + PL_strcat(newStr, t); + + return newStr; +} + +char *ClassCentral::getEnvPath() +{ + char *env; + if ((env = PR_GetEnv("CLASSPATH")) != 0) + return dupString(env, staticPool); + else + return 0; +} + +#ifdef NO_NSPR + #ifdef EF_WINDOWS + #define PATH_SEPARATOR '\\' + #endif +#else +#define PATH_SEPARATOR '/' +#endif + + +static bool fileExists(const char *fn) +{ +#ifdef NO_NSPR + fn = 0; // Dummy + return true; +#else + PRFileInfo info; + return (PR_GetFileInfo(fn, &info) >= 0); +#endif +} + + +/* Look for a file name that matches maxFileNameLen characters + * of className. This is to look for truncated files on the + * MAC. + */ +FileReader *ClassCentral::lookForClassFile(const char* className, + size_t maxFileNameLen) +{ + for (DoublyLinkedList::iterator i = pathList.begin(); + !pathList.done(i); i = pathList.advance(i)) { + PathComponent *component = pathList.get(i).component; + FileReader *fileReader = component->getFile(className, maxFileNameLen); + + if (fileReader) + return fileReader; + } + + return 0; +} + +/* Returns the canonical filename of the class from the fully + * qualified className. The current class path is searched to + * find the file and the first available match is returned. + * Returns NULL if no matching file was found. + */ +FileReader *ClassCentral::resolveClassName(const char *className) +{ + FileReader *reader; + +#ifdef XP_MAC + /* first look for the class file with a maximum length of 31 + * for the name + */ + if ((reader = lookForClassFile(className, 30)) != 0) + return reader; +#endif + + /* now look for the class file with its whole name */ + if ((reader = lookForClassFile(className)) != 0) + return reader; + + return 0; +} + + +/* Adds the paths represented in cpath either to the + * end of, or at the beginning of, the current classPath + * depending on whether end is true or false. cpath is + * a colon-separated list of canonical pathnames. cpath + * is altered as a result of this routine. + */ +void ClassCentral::addPath(char *cpath, bool end) +{ + Strtok tok(cpath); + char *s = tok.get(":"); + + if (end) { + while (s) { + PathNode *pathNode = new (staticPool) PathNode; + pathNode->component = new (staticPool) PathComponent(s, staticPool); + + pathList.addLast(*pathNode); + s = tok.get(":"); + } + } else { + if (s) { + /* Add the first component to the beginning */ + PathNode *firstNode = new (staticPool) PathNode; + firstNode->component = new (staticPool) PathComponent(s, staticPool); + + pathList.addFirst(*firstNode); + s = tok.get(":"); + + /* Now add the rest of the components */ + while (s) { + PathNode *pathNode = new (staticPool) PathNode; + pathNode->component = new (staticPool) PathComponent(s, staticPool); + + pathList.insertAfter(*pathNode, pathList.location(*firstNode)); + s = tok.get(":"); + + } + } + } +} + +void ClassCentral::setClassPath(const char *cp) +{ + pathList.clear(); + + classPath = (cp) ? dupString(cp, staticPool) : getEnvPath(); + + if (classPath) { + char *cpath = dupString(classPath, staticPool); + + addPath(cpath, true); + } + + /* Always add the current directory to the CLASSPATH; this might result + * in the current directory being searched twice if it's already in the + * CLASSPATH, but that's OK. + */ + addPath(dupString(".", staticPool), true); +} + +void ClassCentral::prefixClassPath(const char *path) +{ + classPath = concatPath(path, classPath); + char *cpath = dupString(path, staticPool); + + addPath(cpath, false); +} + +void ClassCentral::suffixClassPath(const char *path) +{ + classPath = concatPath(classPath, path); + + char *cpath = dupString(path, staticPool); + + addPath(cpath, true); +} + +/* Create a new ClassFileSummary object with the given parameters without + * adding it to our repository (classPool). Verify that the name of the + * class matches className. See the documentation for + * ClassFileSummary::ClassFileSummary for the interpretation of the + * className, fileName, arrayType, numDimensions, primitiveElementType, + * tk, and component parameters. + */ +ClassFileSummary &ClassCentral::newSummary(const char *className, + FileReader *fileReader, + bool arrayType, + Uint32 numDimensions, + bool primitiveElementType, + TypeKind tk, + ClassFileSummary *component) +{ + ClassFileSummary *info; + + info = new (staticPool) ClassFileSummary(staticPool, + dynamicPool, + sp, + *this, + world, + className, + fileReader, + arrayType, + numDimensions, + primitiveElementType, + tk, + component); + + /* XXX Will this result in calling of the correct destructor? */ + if (fileReader) + fileReader->FileReader::~FileReader(); + + if (*className != '[') { + const char *classNameInFile = + info->getClassName(); + + + /* Check to see if the class defined in this class file is indeed + * the classname we're looking for + */ + if (PL_strcmp(classNameInFile, className) != 0) + verifyError(VerifyError::classNotFound); + } + + return *info; +} + +/* Loads (but does not fully resolve) the class whose fully qualified name is + * className and stores it in ClassCentral's + * classPool. If fileName is non-NULL, it is the canonical name of the + * file in which to find the class; if it is NULL, classPath is used to + * construct the name of the file. If the class has already been loaded + * or if the class is actually an array or an interface, + * loadParents is set to false; otherwise, loadParents is set to true, + * indicating that the parent classes of this class must be loaded + * by the caller. + * components is a vector of ClassFileSummary objects that have already been + * loaded in recursive calls to Classcentral::addClass; this is passed on + * to recursive calls, if any, to ClassCentral::addClass(). + */ +ClassFileSummary &ClassCentral::loadClass(Vector &components, + const char *className, + const char *fileName, + bool &alreadyLoaded, + bool &loadParents) +{ + ClassFileSummary *hashNodeData; + loadParents = false; + + /* Has Class already been loaded? */ + if (classPool.get(className, &hashNodeData)) { + alreadyLoaded = true; + return *hashNodeData; + } + alreadyLoaded = false; + + /* Array classes */ + if (*className == '[') { + const char *cname = className; + + Uint32 numDimensions = 1; + while (*++cname == '[') + numDimensions++; + + if (!*cname) + verifyError(VerifyError::noClassDefFound); + + TypeKind tk; + switch (*cname) { + case 'L': + if (!*++cname) + verifyError(VerifyError::noClassDefFound); + else { + ClassFileSummary *elementSummary; + + TemporaryStringCopy copy(cname); + char *cnameCopy = copy; + + /* Over-write the semi-colon, if we can find it */ + char *t; + for (t = cnameCopy; *t && *t != ';' ; t++) + ; + + if (*t != ';' || *(t+1)) + verifyError(VerifyError::badClassFormat); + + *t = 0; + + if (classPool.get(cnameCopy, &hashNodeData)) + elementSummary = hashNodeData; + else + elementSummary = &addClass(components, cnameCopy); + + return newSummary(className, + (FileReader *) 0, + true, numDimensions, + false, + tkVoid, + elementSummary); + + } + break; + + default: + if (!getTypeKindFromDescriptor(*cname, tk) || *(cname+1)) + verifyError(VerifyError::badClassFormat); + + break; + } + + /* If we're here, we have an array of a primitive type */ + return newSummary(className, + (FileReader *) 0, + true, numDimensions, + true, + tk, + 0); + } + + + UT_LOG(ClassCentral, PR_LOG_DEBUG, ("\tLoading class %s\n", className)); + + + /* If we're here, we're a non-array class or interface that must be loaded from + * a class file. + */ + + FileReader *fileReader; + loadParents = true; + + if (fileName && fileExists(fileName)) + fileReader = new DiskFileReader(staticPool, fileName); + else { + if (!(fileReader = resolveClassName(className))) + verifyError(VerifyError::badClassFormat); + } + + return newSummary(className, + fileReader, + false, 0, false, tkVoid, + 0); +} + +/* Add a class, ensuring that none of the summaries in the Vector + * component represent the class to be resolved. + */ +ClassFileSummary &ClassCentral::addClass(Vector &components, + const char *className, + const char *fileName) +{ + bool loadParents, alreadyLoaded; + ClassFileSummary *pParentInfo; + + /* Make sure we're not already on the component vector. If we are, + * we've detected a circularity + */ + Uint32 size = components.size(); + for (Uint32 i = 0; i < size; i++) { + ClassFileSummary *summ = components[i]; + + /* Note that this has to be a strcmp since className may or may + * not be an interned string + */ + if (!strcmp(className, summ->getClassName())) + verifyError(VerifyError::classCircularity); + } + + ClassFileSummary &info = loadClass(components, + className, fileName, alreadyLoaded, loadParents); + + if (alreadyLoaded) + return info; + + components.append(&info); + + /* All interfaces have a null superclass, despite the fact that the .class file + lists Object as the superclass of all interfaces. */ + if ((className[0] != '[') && // Ensure non-array class + (info.getAccessFlags() & CR_ACC_INTERFACE)) { + pParentInfo = NULL; + } else if (loadParents) { + const char *superclassName = info.getSuperclassName(); + + if (superclassName) { + ClassFileSummary &parentInfo = addClass(components, superclassName, 0); + + /* Our parent must be a class; it cannot be a final class */ + Uint16 accessFlags = parentInfo.getAccessFlags(); + if ((accessFlags & CR_ACC_INTERFACE) || + (parentInfo.getAccessFlags() & CR_ACC_FINAL)) { + verifyError(VerifyError::badClassFormat); + } + + /* Our parent shouldn't be an array class */ + Type *parentType = parentInfo.getThisClass(); + if (parentType->typeKind != tkObject) + verifyError(VerifyError::badClassFormat); + + pParentInfo = &parentInfo; + } else { + + /* This must be the Object class */ + pParentInfo = NULL; + } + } else { + /* This must be an array class. Arrays always have Object as the superclass */ + pParentInfo = Standard::get(cObject).summary; + } + + classPool.add(className, &info); + info.setParent(pParentInfo); + + return info; +} + +/* This routine enforces a series of constraints on the className + * and returns true if the className satisfies all the constraints. + * Otherwise, returns false + */ +bool ClassCentral::validateName(const char *className) const +{ + + if (!className) + return false; + + + /* Make sure that the className is not relative. Currently, + * this means that it does not have a relative path (.) in it. + */ + for (const char *s = className; *s; s++) + if (*s == '.') + return false; + + return true; +} + +ClassFileSummary &ClassCentral::addClass(const char *className, + const char *fileName) +{ + if (!validateName(className)) + verifyError(VerifyError::illegalAccess); + + Vector vec(5); + + return addClass(vec, className, fileName); +} + +void ClassCentral::removeClass(const char * /* className */) +{ + +} + +void ClassCentral::removeClass(ClassFileSummary * /* info */) +{ + +} + +Type &ClassCentral::parseFieldDescriptor(const char *s, const char *&next) +{ + TypeKind tk; + + switch (*s) { + case '[': { + Type &type = parseFieldDescriptor(s+1, next); + return *(const_cast(static_cast (&type.getArrayType()))); + } + + case 'L': { + char *t = PL_strchr(++s, ';'); + + if (!t) + verifyError(VerifyError::badClassFormat); + + Int32 len = t-s+1; + char *instanceClass = new char [len]; + + if (!instanceClass) + verifyError(VerifyError::badClassFormat); + + PL_strncpy(instanceClass, s, len-1); + instanceClass[len-1] = 0; + next = t+1; + + ClassFileSummary &summ = addClass(instanceClass); + delete [] instanceClass; + + return *summ.getThisClass(); + } + + default: + if (!(getTypeKindFromDescriptor(*s, tk))) + verifyError(VerifyError::badClassFormat); + break; + } + + /* If we're here, we're a primitive type */ + Type &type = *(const_cast(static_cast(&PrimitiveType::obtain(tk)))); + next = s+1; + return type; +} + + + + + + + diff --git a/ef/Runtime/ClassInfo/ClassCentral.h b/ef/Runtime/ClassInfo/ClassCentral.h new file mode 100644 index 000000000000..3ad3880540ef --- /dev/null +++ b/ef/Runtime/ClassInfo/ClassCentral.h @@ -0,0 +1,156 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#ifndef _CLASS_CENTRAL_H_ +#define _CLASS_CENTRAL_H_ + +#include "DoublyLinkedList.h" +#include "HashTable.h" +#include "Pool.h" +#include "Vector.h" +#include "ClassFileSummary.h" +#include "ClassWorld.h" +#include "PathComponent.h" + +/* A node on pathList; represents a canonical path in which + * to find classes + */ +class PathNode : public DoublyLinkedEntry { +public: + PathComponent *component; +}; + +/* ClassCentral is a repository of all classes currently loaded + */ +class NS_EXTERN ClassCentral { +public: + /* classPath is a colon-separated list of directories in which to search + * for class files. If this is NULL, the system-dependent environment + * setting (the env variable CLASSPATH on Unix and Windows, on MAC?) + * is used to determine the directories to search for class files. + * This routine makes its own copy of classPath, so it does not need to + * persist after this routine exits. + * world is a runtime repository used to hold Class, Interface and + * Type objects for all runtime objects that ClassCentral creates. + * sp is a repository that will hold all strings interned + * during class-file resolution. + * p is a pool that will be used to allocate runtime objects. + */ + ClassCentral(Pool &p, ClassWorld &world, StringPool &sp, + const char *classPath=0); + + /* Set the path to search for class files. The path must be canonical + * (Unix-like). An argument of zero resets the value of the classPath + * to whatever is derived from the environment; in effect, it "resets" + * the classPath to the default. + * This routine makes its own copy of classPath, so it does not need to + * persist after this routine exits. + */ + void setClassPath(const char *classPath=0); + + /* Get the current class path */ + const char *getClassPath() const { + return classPath; + } + + /* Add the set of directories in path in front of, or behind, the current + * classPath + */ + void prefixClassPath(const char *path); + void suffixClassPath(const char *path); + + /* Load a class and return a pointer to the class information. If a class + * is already loaded, it just returns a pointer to the loaded class. + * Will also recursively load all of the class's ancestor classes (but not + * interfaces) that haven't already been loaded. + * className is the fully qualified name of the class. + * (eg., java/lang/Object) + * fileName, if non-NULL, points to an absolute or relative pathname + * which represents the file that contains this class. If fileName + * is set to NULL, then the user's CLASSPATH is searched to determine + * the location of the file. fileName can be either a native or + * canonical (Unix-like) file-path. + */ + ClassFileSummary &addClass(const char *className, const char *fileName=0); + + /* Load a class using the given FileReader class to read the raw bytes + * in the class. Return a pointer to the loaded class. className is the + * fully qualified name of the class. + * If the class is already loaded, it returns a pointer to the loaded + * class (not sure if it should do this). + */ + ClassFileSummary &addClass(const char *className, FileReader &reader); + + /* Remove a class from the pool. Need to properly define the semantics + * of this, but the idea is that this will attempt to also clean up + * as many dependent classes as possible. + */ + void removeClass(const char *className); + void removeClass(ClassFileSummary *info); + + /* Parse the Java field descriptor string starting at s. Construct + * and return a Type class corresponding to the parsed descriptor, + * loading classes if neccessary. Sets *next to point to + * remaining string on success. + */ + Type &parseFieldDescriptor(const char *s, const char *&next); + + /* Return a reference to the string pool used to intern strings */ + StringPool &getStringPool() { return sp; } + + /* return a reference to the ClassWorld object used internally */ + ClassWorld &getClassWorld() { return world; } + +private: + char *classPath; + DoublyLinkedList pathList; + + HashTable classPool; + Pool staticPool; /* Pool to allocate static information */ + ClassWorld &world; + StringPool &sp; + Pool &dynamicPool; /* Pool to allocate dynamic types that will be used + * by the runtime + */ + + char *getEnvPath(); + char *concatPath(const char *s, const char *t); + void addPath(char *cpath, bool end); + + bool validateName(const char *className) const; + FileReader *resolveClassName(const char *className); + FileReader *lookForClassFile(const char* className, + size_t maxFileNameLen = 0); + + ClassFileSummary &loadClass(Vector &vec, + const char *className, const char *fileName, + bool &alreadyLoaded, + bool &loadParents); + + ClassFileSummary &newSummary(const char *className, + FileReader *fr, + bool arrayType, + Uint32 numDimensions, + bool primitiveComponentType, + TypeKind tk, + ClassFileSummary *component); + + ClassFileSummary &addClass(Vector &vec, + const char *className, const char *fileName=0); +}; + +#endif /* _CLASS_CENTRAL_H_ */ diff --git a/ef/Runtime/ClassInfo/ClassFileSummary.cpp b/ef/Runtime/ClassInfo/ClassFileSummary.cpp new file mode 100644 index 000000000000..ee2f4b7e76e5 --- /dev/null +++ b/ef/Runtime/ClassInfo/ClassFileSummary.cpp @@ -0,0 +1,2255 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#include "ClassFileSummary.h" +#include "ClassCentral.h" +#include "ErrorHandling.h" +#include "JavaObject.h" +#include "FieldOrMethod.h" + +#include "plstr.h" +#include "prprf.h" +#include "LogModule.h" + +UT_DEFINE_LOG_MODULE(ClassFileSummary); + +/* symbolic V-Table node */ +struct VTableNode { + Method *method; + ClassFileSummary *summary; /* If method is NULL, summary points to defining class. + This is used for instanceof() calculations. */ +}; + +/* Annotation information for each item in the constant pool */ +struct _AnnotationItem { + bool resolved; /* Has it been resolved? */ + + + /* Resolved information about field/method */ + union { + const MethodInfo *m; /* For method refs/interface method refs, + * name-and-type + */ + const FieldInfo *f; /* For field refs, name and type */ + const InfoItem *item; /* Holds MethodInfo/FieldInfo */ + }; + const FieldOrMethod *descriptor; + + ClassFileSummary *info; /* Info for class referenced by this entry */ + bool isInit, isClinit; /* True if method is or respectively */ +}; + +/* Run the static initializers of this class if necessary */ +inline void ClassFileSummary::runStatics(ClassOrInterface *declaringClass) +{ + if (!declaringClass->isArray() && !declaringClass->isInterface()) { + Class *clz = static_cast (declaringClass); + + if (!clz->isInitialized()) + clz->runStaticInitializers(); + } +} + +/* Return the UTF8 name of the superclass or nil if there is no superclass. + */ +const char *ClassFileSummary::getSuperclassName() const +{ + if (arrayType) + verifyError(VerifyError::illegalAccess); + + ConstantClass *superClass = reader->getSuperClass(); + return superClass ? superClass->getUtf()->getUtfString() : 0; +} + +/* returns the minor version of this class from the class file */ +Uint16 ClassFileSummary::getMinorVersion() const +{ + if (arrayType) + verifyError(VerifyError::illegalAccess); + + return reader->getMinorVersion(); +} + +/* Returns the major version of this class from the class file */ +Uint16 ClassFileSummary::getMajorVersion() const +{ + if (arrayType) + verifyError(VerifyError::illegalAccess); + + return reader->getMajorVersion(); +} + +/* returns the access flags for this class from the class file */ +Uint16 ClassFileSummary::getAccessFlags() const +{ + if (arrayType) + verifyError(VerifyError::illegalAccess); + + return reader->getAccessFlags(); +} + + +/* A ClassFileSummary object generates all static and runtime information + * about a class, resolving references to other classes as neccessary. + * staticPool is a pool which this class will use to allocate objects not + * directly used by the runtime. + * runtimePool is used by this class to create runtime objects. + * strPool is a string pool used to intern strings encountered during + * class loading. + * central is the repository that holds all loaded classes. + * cName is the fully qualified name of the class. + * FileReader is an object that can read the class file. + * If arrayType is true, indicates this class is an array class. + * If arrayType is true, numDimensions indicates the number of dimensions + * of the array. + * If arrayType is true and primitiveElementType is true, then this + * class is an array class of primitive types whose type is tk. + * If arrayType is true and primitiveElementType is false, then this + * class is an array class of elements with non-primitive type whose summary is + * is elementSummary. + */ +ClassFileSummary::ClassFileSummary(Pool &staticPool, Pool &runtimePool, + StringPool &strPool, + ClassCentral ¢ral, + ClassWorld &world, + const char *cName, + FileReader *fileReader, + bool arrayType, + Uint32 numDimensions, + bool primitiveElementType, + TypeKind tk, + ClassFileSummary *elementSummary) : + staticPool(staticPool), runtimePool(runtimePool), + sp(strPool), central(central), world(world), + parentInfo(0), clazz(0), + fields(runtimePool), publicFields(runtimePool), + methods(runtimePool), declaredMethods(runtimePool), + publicMethods(runtimePool), + constructors(runtimePool), publicConstructors(runtimePool), + interfaces(runtimePool), + arrayType(arrayType), numDimensions(numDimensions), + elementSummary(elementSummary), + primitiveElementType(primitiveElementType), + tk(tk), vIndicesUsed(runtimePool), subClasses(10) +{ + initp = sp.intern(""); + clinitp = sp.intern(""); + + if (!arrayType) { + assert(fileReader); + reader = new (staticPool) ClassFileReader(staticPool, sp, *fileReader); + className = reader->getThisClass()->getUtf()->getUtfString(); + } else { + nConstants = 0; + annotations = 0; + reader = 0; + className = sp.intern(cName); + } + + if (arrayType) + return; + + constantPool = reader->getConstantPool(); + nConstants = reader->getConstantPoolCount(); + + annotations = new (staticPool) AnnotationItem[nConstants]; + memset(annotations, 0, nConstants*sizeof(AnnotationItem)); + + /* Set the sizes of fields, methods and interfaces */ + fields.setSize(reader->getFieldCount()); + + methods.setSize(reader->getMethodCount()); + declaredMethods.setSize(reader->getDeclaredMethodCount()); + interfaces.setSize(reader->getInterfaceCount()); + constructors.setSize(reader->getConstructorCount()); + publicConstructors.setSize(reader->getPublicConstructorCount()); + + fieldOffsets = new Uint32[fields.getSize()]; + Uint32 i; + for (i = 0; i < fields.getSize(); i++) + fieldOffsets[i] = 0; +} + + +/* Update a class with parent information about its parent. setParent() + * is called by ClassCentral after it has loaded and has information + * about the parent classes of this class. + */ +void ClassFileSummary::setParent(ClassFileSummary *info) +{ + getPackageNames(); + parentInfo = info; + + if (arrayType) { + makeClazz(); + return; + } + + Int32 parentPublicFieldCount = 0, parentPublicMethodCount = 0; + + if (parentInfo) { + parentSize = info->getObjSize(); + parentPublicFieldCount = parentInfo->getPublicFieldCount(); + parentPublicMethodCount = parentInfo->getPublicMethodCount(); + parentInfo->addSubclass(*this); + } else + parentSize = sizeof(JavaObject); + + computeSize(); + buildVTable(); + makeClazz(); + + publicFields.setSize(reader->getPublicFieldCount() + + parentPublicFieldCount); + publicMethods.setSize(reader->getPublicMethodCount() + + parentPublicMethodCount); + +} + + +/* Build the Field class for a field located at index fieldIndex in the + * fields array of the class. fields.set() must have been called + * with the correct field count before this routine is + * called. This routine uses ClassCentral::addClass to resolve all + * classes and interfaces that it encounters when parsing the field + * descriptor. + */ +Field &ClassFileSummary::buildField(Uint32 fieldIndex) +{ + Field *field; + + if ((field = fields.get(fieldIndex)) != 0) + return *field; + + const FieldInfo **fieldInfos = reader->getFieldInfo(); + const FieldInfo *fieldInfo = fieldInfos[fieldIndex]; + + field = new (runtimePool) Field(packageName, unqualName, + fieldInfo->getName()->getUtfString(), + *this, + central, + runtimePool, + fieldOffsets[fieldIndex], + *fieldInfo); + + + /* If this is a static primitive/string field, look for a ConstantValue attribute that will + * set the value of this field + */ + if (field->getModifiers() & CR_FIELD_STATIC) { + /* We will not resolve the type here completely since that will lead to + * circularities that we do not wish to deal with. Instead, examine the + * signature to determine the type + */ + const char *sigString = fieldInfo->getDescriptor()->getUtfString(); + + if (Field::primitiveOrStringSignature(sigString)) { + const AttributeInfoItem *attribute = fieldInfo->getAttribute(CR_ATTRIBUTE_CONSTANTVALUE); + if (attribute) { + const AttributeConstantValue *cval = static_cast(attribute); + ConstantPoolIndex cpi = cval->getConstantPoolIndex(); + + ValueKind vk; + Value value; + + if (!(reader->lookupConstant(cpi, vk, value))) + verifyError(VerifyError::badClassFormat); + + field->setFromValue(vk, value); + } + } + } + + fields.set(fieldIndex, field); + return *field; +} + +/* Build the Method class for a field located at index methodIndex in the + * methods array of the class. methods.set() must have been called + * with the correct method count before this routine is + * called. This routine uses ClassCentral::addClass to resolve all + * classes and interfaces that it encounters when parsing the method + * descriptor. + */ +Method &ClassFileSummary::buildMethod(Uint32 methodIndex) +{ + Method *method; + + assert(methodIndex < methods.getSize()); + + const MethodInfo **methodInfos = reader->getMethodInfo(); + const MethodInfo *methodInfo = methodInfos[methodIndex]; + + if (methodInfo->getName()->getUtfString() == initp) + method = new (runtimePool) Constructor(packageName, unqualName, + methodInfo->getName()->getUtfString(), + *this, + central, + runtimePool, + *methodInfo); + else + method = new (runtimePool) Method(packageName, unqualName, + methodInfo->getName()->getUtfString(), + *this, + central, + runtimePool, + *methodInfo); + + methods.set(methodIndex, method); + world.addMethod(method->toString(), method); /* necessary for debugger right now, don't we have this information somewhere else */ + + return *method; +} + + +/* Build the Interface class for the interface located at index + * interfaceIndex in the interfaces array of the class. interfaces.set() + * must have been called with the correct interface count before this + * routine is called. This routine uses ClassCentral::addClass to resolve all + * classes and interfaces that it encounters when parsing the method + * descriptor. + */ +Interface &ClassFileSummary::buildInterface(Uint32 interfaceIndex) +{ + Interface *iface; + + assert(interfaceIndex < interfaces.getSize()); + + if ((iface = interfaces.get(interfaceIndex)) != 0) + return *iface; + + const ConstantPool *interfaceInfo = reader->getInterfaceInfo(); + const ConstantPoolItem *item = interfaceInfo->get(interfaceIndex); + const ConstantClass *inf = static_cast(item); + + ClassFileSummary &info = central.addClass(inf->getUtf()->getUtfString()); + + if (!(info.getAccessFlags() & CR_ACC_INTERFACE)) { + UT_LOG(ClassFileSummary, PR_LOG_DEBUG, ("class %s: Cannot resolve or not an interface", + inf->getUtf()->getUtfString())); + verifyError(VerifyError::noClassDefFound); + } + + iface = static_cast(info.getThisClass()); + interfaces.set(interfaceIndex, iface); + return *iface; +} + +/* Build a public field located at given index in the publicFields + * array of the class. Since this points to an entry in the Fields + * array of the class, it will build this entry if it doesn't already + * exist. The order in which we build the fields is as follows: + * fields declared in superclasses of this class, fields declared in + * interfaces implemented by this class, fields declared in the current class + */ +Field &ClassFileSummary::buildPublicField(Uint32 index) +{ + assert(index < publicFields.getSize()); + Uint32 parentCount = (parentInfo) ? parentInfo->getPublicFieldCount() : 0; + +#if 0 + Uint32 fieldCount = reader->getPublicFieldCount(); + + Field *field; + if (index < fieldCount) { /* Field declared in this class */ + const Uint16 *publicFieldIndices = reader->getPublicFields(); + Uint32 actualIndex = publicFieldIndices[index]; + if (!(field = fields.get(actualIndex))) + field = &buildField(actualIndex); + } else if (index < (fieldCount+parentCount)) + field = &parentInfo->buildPublicField(index-fieldCount); + else { + assert(0); + } + + publicFields.set(index, field); + return *field; + + +#else + Field *field; + if (parentInfo && (index < parentCount)) { + field = &parentInfo->buildPublicField(index); + publicFields.set(index, field); + return *field; + } + + const Uint16 *publicFieldIndices = reader->getPublicFields(); + Uint32 actualIndex = publicFieldIndices[index-parentCount]; + if (!(field = fields.get(actualIndex))) + field = &buildField(actualIndex); + + publicFields.set(index, field); + return *field; +#endif +} + +/* Build a public method located at given index in the publicMethods + * array of the class. Since this points to an entry in the Methods + * array of the class, it will build this entry if it doesn't already + * exist. + */ +Method &ClassFileSummary::buildPublicMethod(Uint32 index) +{ + assert(index < publicMethods.getSize()); + + Uint32 parentCount = (parentInfo) ? parentInfo->getPublicMethodCount() : 0; + Method *method; + if (parentInfo && (index < parentCount)) { + method = &parentInfo->buildPublicMethod(index); + publicMethods.set(index, method); + return *method; + } + + const Uint16 *publicMethodIndices = reader->getPublicMethods(); + Uint32 actualIndex = publicMethodIndices[index-parentCount]; + + if (!(method = methods.get(actualIndex))) + method = &buildMethod(actualIndex); + + publicMethods.set(index, method); + return *method; +} + + +/* Build a declared method located at given index in the declaredMethods + * array of the class. Since this points to an entry in the Methods + * array of the class, it will build this entry if it doesn't already + * exist. + */ +Method &ClassFileSummary::buildDeclaredMethod(Uint32 index) +{ + assert(index < publicMethods.getSize()); + + const Uint16 *declaredMethodIndices = reader->getDeclaredMethods(); + Uint32 actualIndex = declaredMethodIndices[index]; + + Method *method; + if (!(method = methods.get(actualIndex))) + method = &buildMethod(actualIndex); + + declaredMethods.set(index, method); + return *method; +} + +/* Build a constructor located at given index in the constructors + * array of the class. + */ +Constructor &ClassFileSummary::buildConstructor(Uint32 index) +{ + assert(index < constructors.getSize()); + + Constructor *cons; + + const Uint16 *constructorIndices = reader->getConstructors(); + Uint32 actualIndex = constructorIndices[index]; + Method *method; + if (!(method = methods.get(actualIndex))) + method = &buildMethod(actualIndex); + + cons = static_cast (method); + constructors.set(index, cons); + return *cons; +} + +/* Build a public constructor located at given index in the + * publicConstructors array of the class. + */ +Constructor &ClassFileSummary::buildPublicConstructor(Uint32 index) +{ + assert(index < publicConstructors.getSize()); + Uint32 parentCount = 0; + Constructor *cons; + + const Uint16 *publicConstructorIndices = reader->getPublicConstructors(); + Uint32 actualIndex = publicConstructorIndices[index-parentCount]; + + Method *method; + if (!(method = methods.get(actualIndex))) + method = &buildMethod(actualIndex); + + cons = static_cast (method); + publicConstructors.set(index, cons); + return *cons; +} + + +/* Build Field objects for all fields in the class. fields.set() must + * have been set with the correct field count before this routine is called. + * This routine uses ClassCentral::addClass + * to resolve all classes and interfaces that it encounters when parsing + * the field descriptor. + */ +void ClassFileSummary::buildFields() +{ + for (Uint32 i = 0; i < fields.getSize(); i++) + if (!fields.get(i)) + buildField(i); +} + + +/* Build Method objects for all methods in the class. methods.set() must + * have been set with the method count before this routine is called. + * This routine resolves all classes and interfaces that it encounters when + * parsing the method descriptor. + */ +void ClassFileSummary::buildMethods() +{ + for (Uint32 i = 0; i < methods.getSize(); i++) + if (!methods.get(i)) + buildMethod(i); +} + + + +/* Build Interface objects for all interfaces in the class. interfaces.set() + * must have been called with the correct interface count + * before this routine is called. This routine uses + * ClassCentral::addClass to load the interface classes. + */ +void ClassFileSummary::buildInterfaces() +{ + for (Uint32 i = 0; i < interfaces.getSize(); i++) + if (!interfaces.get(i)) + buildInterface(i); +} + +/* Build Field objects for all public fields in the class. */ +void ClassFileSummary::buildPublicFields() +{ + for (Uint32 i = 0; i < publicFields.getSize(); i++) + if (!publicFields.get(i)) + buildPublicField(i); +} + + +/* Build Method objects for all public methods in the class. */ +void ClassFileSummary::buildPublicMethods() +{ + for (Uint32 i = 0; i < publicMethods.getSize(); i++) + if (!publicMethods.get(i)) + buildPublicMethod(i); +} + + +/* Build Method objects for all declared methods in the class. */ +void ClassFileSummary::buildDeclaredMethods() +{ + for (Uint32 i = 0; i < declaredMethods.getSize(); i++) + if (!declaredMethods.get(i)) + buildDeclaredMethod(i); +} + +/* Build Constructor objects for all constructors in the class. */ +void ClassFileSummary::buildConstructors() +{ + for (Uint32 i = 0; i < constructors.getSize(); i++) + if (!constructors.get(i)) + buildConstructor(i); +} + +/* Build Constructor objects for all public constructors in the class. */ +void ClassFileSummary::buildPublicConstructors() +{ + for (Uint32 i = 0; i < publicConstructors.getSize(); i++) + if (!publicConstructors.get(i)) + buildPublicConstructor(i); +} + + +/* return the field object corresponding to the given name + * in the public fields of the class. Return NULL if + * there is no field with the given name. If interned is true, + * then _name is interned. If publik is true, then look in public + * fields only; otherwise, look in all fields. + */ +Field *ClassFileSummary::getField(const char *_name, bool publik, + bool interned) +{ + if (arrayType) + verifyError(VerifyError::illegalAccess); + + const char *name = (interned) ? _name : sp.get(_name); + + if (!name) + return 0; + + const FieldInfo **fieldInfos = reader->getFieldInfo(); + for (Uint32 i = 0; i < fields.getSize(); i++) { + const FieldInfo *fieldInfo = fieldInfos[i]; + + if (publik && !(fieldInfo->getAccessFlags() & CR_FIELD_PUBLIC)) + continue; + + if (name == fieldInfo->getName()->getUtfString()) + return (fields.get(i)) ? fields.get(i) : &buildField(i); + } + + /* If we're here, the field is not a declared field in this class. + * Try the parent class if we're looking for a public field. + */ + if (publik) + return (parentInfo) ? parentInfo->getField(name, true, true) : 0; + else + return 0; +} + +/* return the field object corresponding to the given name + * in the public fields of the class. Return NULL if + * there is no field with the given name. + */ +Field *ClassFileSummary::getField(const char *name) +{ + return getField(name, true, false); +} + + +/* return the field object corresponding to the given name + * in the fields of the class (including protected and private + * fields). Return NULL if there is no field with the given name and type. + */ +Field *ClassFileSummary::getDeclaredField(const char *name) +{ + return getField(name, false, false); +} + +/* return the Method object corresponding to the given name and + * parameter types in the public methods of the class. Return NULL if + * there is no method with the given name and signature. If publik is true, + * look in public methods only; otherwise, look in all declared methods. + * If interned is true, then _name is an interned string. + * Notes: This function ends up resolving all candidate methods with + * the matching name in order to generate their signatures, adding classes + * as necessary. + */ +Method *ClassFileSummary::getMethod(const char *_name, + const Type *parameterTypes[], + Int32 numParameterTypes, + bool publik, bool interned) +{ + if (arrayType) + verifyError(VerifyError::illegalAccess); + + const char *name = (interned) ? _name : sp.get(_name); + + if (!name) + return 0; + + const MethodInfo **minfos = reader->getMethodInfo(); + for (Uint32 i = 0; i < methods.getSize(); i++) { + const MethodInfo *minfo = minfos[i]; + Uint32 modifiers = minfo->getAccessFlags(); + + if (publik && !(modifiers & CR_METHOD_PUBLIC)) + continue; + + if (minfo->getName()->getUtfString() == name) { + Method *m; + + if (!(m = methods.get(i))) + m = &buildMethod(i); + + const Signature &sig = m->getSignature(); + + /* The number of arguments is one higher than actual in the signature + * of instance methods to account for the self argument + */ + Uint32 start; + Uint32 nArgs; + + if (modifiers & CR_METHOD_STATIC) { + nArgs = numParameterTypes; + start = 0; + } else { + nArgs = numParameterTypes+1; + start = 1; + } + + if (nArgs == sig.nArguments) { + Uint32 j; + for (j = start; j < sig.nArguments; j++) + if (sig.argumentTypes[j] != parameterTypes[j-start]) + break; + + if (j == sig.nArguments) /* We have a match! */ + return m; + } + } + } + + /* If we're here, we couldn't find a match in our methods. Try in + * our superclass' methods if we're looking for a public method. + */ + if (publik && (name != initp)) + return (parentInfo) ? parentInfo->getMethod(name, parameterTypes, + numParameterTypes, true, + true) : 0; + else + return 0; +} + + +/* return the Method object corresponding to the given name and + * parameter types in the public methods of the class. Return NULL if + * there is no method with the given name and signature. + */ +Method *ClassFileSummary::getMethod(const char *name, + const Type *parameterTypes[], + Int32 numParameterTypes) +{ + return getMethod(name, parameterTypes, numParameterTypes, true, false); +} + + +/* Return the method with given name and signature. Looks only in the + * methods defined in this class (and not in methods this class might have + * inherited from a parent class). Both name and sig are assumed to be + * interned strings; however, sig can be nil if the method is not overloaded. + * Returns NULL on failure. + */ +Method *ClassFileSummary::getMethod(const char *name, const char *sig) +{ + if (arrayType) + return 0; + + Uint16 methodIndex; + const MethodInfo *minfo; + minfo = reader->lookupMethod(name, sig, methodIndex); + if (!minfo) + return NULL; + + return &getMethod(methodIndex); +} + +/* return the method object corresponding to the given name and + * parameter types in the methods of the class (including protected and + * private methods). Return NULL if there is no method with the given name + * and signature. + */ +Method *ClassFileSummary::getDeclaredMethod(const char *name, + const Type *parameterTypes[], + Int32 numParameterTypes) +{ + return getMethod(name, parameterTypes, numParameterTypes, false, false); +} + + +/* return the Constructor object corresponding to the given name + * and parameter types on the methods of the class (including protected + * and private methods). Return NULL if there is no method with + * the given name and signature. + */ +Constructor *ClassFileSummary::getConstructor(const Type *parameterTypes[], + Int32 numParameterTypes) +{ + return static_cast(getMethod(initp, parameterTypes, + numParameterTypes, true, + true)); +} + + +/* return the public Constructor object corresponding to the given name + * and parameter types on the methods of the class (including protected + * and private methods). Return NULL if there is no method with + * the given name and signature. + */ +Constructor *ClassFileSummary::getDeclaredConstructor(const Type *parameterTypes[], + Int32 numParameterTypes) +{ + return static_cast(getMethod(initp, parameterTypes, + numParameterTypes, false, + true)); +} + + +/* If a field/method/interface method reference with the given name and + * signature is present of the field/method array of the class, then + * return the corresponding Field/Method descriptor; also return + * compile-time information about the field/method via item. Otherwise, + * return NULL. 'type' indicates whether to look for a field, method or + * interface method; valid values for type are CR_CONSTANT_FIELDREF, + * CR_CONSTANT_METHODREF, CR_CONSTANT_INTERFACEMETHODREF. + * resolveName only returns non-NULL for fields and methods that are + * actually present in the class (as opposed to being inherited without + * being overridden). + */ +const FieldOrMethod *ClassFileSummary::resolveName(const Uint8 type, + const char *name, + const char *desc, + const InfoItem *&item) +{ + if (arrayType) + verifyError(VerifyError::illegalAccess); + + + Uint16 index; + if (!(item = reader->lookupFieldOrMethod(type, name, desc, index))) + return 0; + + if (type == CR_CONSTANT_FIELDREF) { + if (!fields.get(index)) + buildField(index); + return fields.get(index); + } else { + if (!methods.get(index)) + buildMethod(index); + return methods.get(index); + } +} + +/* + * Annotate a constantPool entry at index cpi with given information. + * Also check whether this class has access permissions to the item, + * which is defined inside class "info". + */ +void ClassFileSummary::annotate(Uint8 type, + ConstantPoolIndex index, + const InfoItem *item, + const FieldOrMethod *descriptor, + ClassFileSummary *info, + const char *name, + const char * /*sig*/) +{ + if (item) { + /* Check whether we have permissions to access this field or method */ + Uint32 modifiers = descriptor->getModifiers(); + + if ((modifiers & CR_FIELD_PRIVATE) && info != this) + verifyError(VerifyError::illegalAccess); + else if ((modifiers & CR_FIELD_PROTECTED)) { + /* We should be a subclass of the given class */ + +#if 0 + /* For now this check is ignored since we need to check for more + * things than subclassing to see if access is allowed + */ + if (!isSubClassOf(info)) + verifyError(VerifyError::illegalAccess); +#endif + } + + annotations[index].item = item; + annotations[index].info = info; + annotations[index].descriptor = descriptor; + + if (type != CR_CONSTANT_FIELDREF) { + annotations[index].isInit = (name == initp); + annotations[index].isClinit = (name == clinitp); + } + + annotations[index].resolved = true; + + } else + verifyError(VerifyError::noClassDefFound); + +} + +/* + * Lookup a method with the given name and signature only in superclasses + * of the current class; annotate the current class' annotation information + * with the closest superclass with a match. type + * indicates whether to look for a method (CR_CONSTANT_METHODREF) or + * interface method (CR_CONSTANT_INTERFACEMETHODREF) + */ +void ClassFileSummary::resolveSpecial(const Uint8 type, + ConstantPoolIndex index) +{ + if (arrayType) + verifyError(VerifyError::illegalAccess); + + ConstantRef *ref = (ConstantRef *) constantPool->get(index); + ConstantNameAndType *nt = ref->getTypeInfo(); + const char *name = nt->getName()->getUtfString(); + const char *sig = nt->getDesc()->getUtfString(); + const InfoItem *item; + const FieldOrMethod *descriptor; + + ClassFileSummary *parent; + for (parent = parentInfo; parent; parent = parent->getParentInfo()) { + if ((descriptor = parent->resolveName(type, name, sig, item)) != 0) + break; + } + + if (!parent) + verifyError(VerifyError::badConstantPoolIndex); + + annotate(type, index, item, descriptor, parent, name, sig); +} + + +/* Resolve a field/method/interface present whose index in the + * ConstantPool of this class is given by "index". If successful, update + * annotation information for this field. + */ +void ClassFileSummary::resolveFieldOrMethod(const Uint8 type, + ConstantPoolIndex index) +{ + if (arrayType) + verifyError(VerifyError::illegalAccess); + + ConstantRef *ref = (ConstantRef *) constantPool->get(index); + + if (ref->getType() != type) + verifyError(VerifyError::badClassFormat); + + ConstantClass *classInfo = ref->getClassInfo(); + ClassFileSummary &info = central.addClass(classInfo->getUtf()->getUtfString()); + + ConstantNameAndType *nt = ref->getTypeInfo(); + const char *name = nt->getName()->getUtfString(); + const char *sig = nt->getDesc()->getUtfString(); + + const InfoItem *item; + const FieldOrMethod *descriptor = info.resolveName(type, name, sig, item); + + annotate(type, index, item, descriptor, &info, name, sig); +} + +/* Break up the fully qualified name of this class into a packageName + * and an unqualified class name. + */ +void ClassFileSummary::getPackageNames() +{ + const char *s = &className[PL_strlen(className)-1]; + char *t; + + while (s != className && *s != '/') + s--; + + const char *mark = s; + + if (*s == '/') + s++; + + t = new char[PL_strlen(s)+1]; + PL_strcpy(t, s); + + char *unqualNameTemp = t; + + int len = mark-className+1; + char *packageNameTemp = new char[len]; + + PL_strncpy((char *) packageNameTemp, className, len-1); + packageNameTemp[len-1] = 0; + + /* Replace all slashes with dots in packageName */ + for (char *temp = packageNameTemp; *temp; temp++) + if (*temp == '/') *temp = '.'; + + /* Now intern these names and free the originals */ + packageName = sp.intern(packageNameTemp); + unqualName = sp.intern(unqualNameTemp); + + delete [] packageNameTemp; + delete [] unqualNameTemp; +} + + + +/* Compute the size of the class. Note that we don't actually parse field + * descriptors or do any actual resolution here.. + * that is done when we actually resolve the field. + * This function must not be called until the parent's size is available. + * XXX This should be optimized eventually, since we generate padding bytes + * for every char and short field. + */ +void ClassFileSummary::computeSize() +{ + totalSize = parentSize; + + if (arrayType) { + /* parentSize is sizeof(Object), which is 4 */ + assert(parentSize == 4); + return; + } + + const FieldInfo **finfos = reader->getFieldInfo(); + Uint16 fieldCount = reader->getFieldCount(); + + for (Uint16 i = 0; i < fieldCount; i++) { + const char *desc = finfos[i]->getDescriptor()->getUtfString(); + + if ((finfos[i]->getAccessFlags() & CR_FIELD_STATIC)) + continue; + + int size, alignment = 4; /* For everything except float and double */ + + switch (*desc) { + case 'B': + case 'C': + size = 1; + break; + + case 'J': + case 'D': + size = 8; + alignment = 8; + break; + + case 'F': + case 'I': + size = 4; + break; + + case 'S': + size = 2; + break; + + case 'Z': + size = 1; + break; + + case '[': + case 'L': + size = 4; + break; + + default: + verifyError(VerifyError::badClassFormat); + + } + + /* Make sure this field is aligned on the proper alignment */ + totalSize = ALIGN(totalSize, alignment); + fieldOffsets[i] = totalSize; + totalSize += size; + } +} + +/* An interface method was invoked for which there is no + corresponding implementation. + */ +static void +throwIncompatibleClassChangeError() +{ + assert(0); + /* XXX - We need to throw a Java error here, not a C++ one. */ + /* XXX - Should be CloneNotSupportedException if method is "clone" */ + verifyError(VerifyError::incompatibleClassChange); +} + +/* Make the Class or Interface object representing the class. At this point, + * we are actually making an incomplete class without the complete field/ + * method information; this gets patched up as we resolve fields and + * methods. + */ +Type *ClassFileSummary::makeClazz() +{ + Type *parentType = NULL; + + if (clazz) + return clazz; + + /* If this class is already in the pool, it is not neccessarily an error + * since it might have been put there by someone else. + */ + if (world.getType(getClassName(), clazz)) { + assert(0); /* fur - I don't think this can happen */ + return clazz; + } + + /* Construction of array objects is handled specially */ + if (arrayType) { + Type *elementClass; + Type *arrayType; + + /* An array of non-primitive element type ? */ + if (elementSummary) { + elementClass = elementSummary->getThisClass(); + } else { + assert (primitiveElementType); + elementClass = const_cast(static_cast(&PrimitiveType::obtain(tk))); + } + + /* Array components can themselves be arrays, but element types cannot. */ + assert(elementClass->typeKind != tkArray); + + /* Obtain the type of the array */ + arrayType = elementClass; + for (Uint32 i = 0; i < numDimensions; i++) + arrayType = const_cast(static_cast(&arrayType->getArrayType())); + + return (clazz = arrayType); + } + + if (parentInfo) { + parentType = parentInfo->getThisClass(); + assert(parentType); + } + + Package *pkg; + pkg = new (runtimePool) Package(packageName); + + + /* We will first build a Class object and resolve its fields lazily. + */ + if (!(reader->getAccessFlags() & CR_ACC_INTERFACE)) { + clazz = &Class::make(*pkg, unqualName, + static_cast(parentType), + interfaces.getSize(), + interfaces.getEntries(), this, + ((reader->getAccessFlags() & CR_ACC_FINAL) != 0), + totalSize, numVTableEntries, + interfaceDispatchTable->getVOffsetTableBaseAddress(), + interfaceDispatchTable->getAssignableTableBaseAddress()); + + /* Construct the actual vtable used for runtime method dispatch from the + symbolic vtable. Each vtable entry points to a small stub that causes + the corresponding method to be compiled and the vtable backpatched. */ + Class *thisClass = (static_cast(clazz)); + void *classOrCodePtr; + +#if 0 + if (!strcmp(getClassName(), "java/lang/reflect/Method")) + assert(0); +#endif + + for (Uint32 i = 0; i < numVTableEntries; i++) { + Method *method = vtable[i].method; + if (method) { + classOrCodePtr = addressFunction(method->getCode(true)); + } else if (vtable[i].summary) { + classOrCodePtr = vtable[i].summary->getThisClass(); + } else { + /* We've encountered an interface method for which there is no + corresponding implementation. This case is specifically + permitted by the JLS, so we don't throw a compile-time error. + Rather, if this method is actually invoked, an + IncompatibleClassChangeError is thrown. */ + classOrCodePtr = throwIncompatibleClassChangeError; + } + assert(classOrCodePtr); + thisClass->setVTableEntry(i, classOrCodePtr); + } + + /* Setup the Class object so that assignability tests can be done at runtime where + the target type is either an interface or an array of interfaces. */ + thisClass->assignableMatchValue = interfaceDispatchTable->getAssignableMatchValue(); + } else + clazz = new (runtimePool) Interface(*pkg, unqualName, + interfaces.getSize(), + interfaces.getEntries(), this); + + world.addType(getClassName(), clazz); + return clazz; +} + + +/* + * Look up a constant in this class's constant pool. cpi is the index of + * this constant in the constant pool of the class. Return the constant's + * ValueKind and value. + */ +ValueKind ClassFileSummary::lookupConstant(ConstantPoolIndex cpi, + Value &value) const +{ + if (arrayType) + verifyError(VerifyError::illegalAccess); + + ValueKind vk; + if (!(reader->lookupConstant(cpi, vk, value))) + verifyError(VerifyError::badConstantPoolIndex); + + return vk; +} + +/* Lookup a field whose index in the class' constant pool is cpi. + * Return information about the class on success; throw a VerifyError + * on failure. If this method sets isConstant to true, it guarantees that + * the field will never change value from its current value. + */ +const Field *ClassFileSummary::lookupField(ConstantPoolIndex cpi, + ValueKind &vk, + TypeKind &tk, + bool &isVolatile, + bool &isConstant, + bool &isStatic) +{ + if (arrayType) + verifyError(VerifyError::illegalAccess); + + if (constantPool->get(cpi)->getType() != CR_CONSTANT_FIELDREF) + verifyError(VerifyError::badConstantPoolIndex); + + if (!annotations[cpi].resolved) + resolveFieldOrMethod(CR_CONSTANT_FIELDREF, cpi); + + Uint32 modifiers = annotations[cpi].descriptor->getModifiers(); + + isStatic = (modifiers & CR_FIELD_STATIC) != 0; + + const Field *field = static_cast + (annotations[cpi].descriptor); + + tk = field->getType().typeKind; + vk = typeKindToValueKind(tk); + + isVolatile = (modifiers & CR_FIELD_VOLATILE) != 0; + isConstant = false; // isConstant = (modifiers & CR_FIELD_CONSTANT) != 0; + + /* Run static initializers for this class if necessary */ + runStatics(field->getDeclaringClass()); + + return field; +} + + +/* + * Look up a static field whose index in the class's constant pool is + * represented by cpi. Return the field's Java type, the corresponding + * ValueKind, the field's address in memory, and two flags indicating + * whether the field is volatile and whether it is a constant. If this + * method sets isConstant to true, it guarantees that + * the field will never change value from its current value + * (currently in memory at a). + */ +TypeKind ClassFileSummary::lookupStaticField(ConstantPoolIndex cpi, + ValueKind &vk, addr &a, + bool &isVolatile, + bool &isConstant) +{ + bool isStatic; + + TypeKind tk; + const Field *field = lookupField(cpi, vk, tk, isVolatile, isConstant, + isStatic); + + if (!isStatic) + verifyError(VerifyError::noSuchField); + + a = field->getAddress(); + assert(addressFunction(a)); + return tk; +} + + +/* + * Look up an instance field in this class's constant pool. Return the + * field's Java type, the corresponding ValueKind, the field's offset from + * the beginning of an instance object, and two flags indicating whether the + * field is volatile and whether it is a constant. If this method sets + * isConstant to true, it guarantees that reading the field multiple times + * from a given instance object will always return the same value (which + * may, however, be different for different instance objects). + */ +TypeKind ClassFileSummary::lookupInstanceField(ConstantPoolIndex cpi, + ValueKind &vk, Uint32 &offset, + bool &isVolatile, + bool &isConstant) +{ + bool isStatic; + + TypeKind tk; + const Field *field = lookupField(cpi, vk, tk, isVolatile, isConstant, + isStatic); + + if (isStatic) + verifyError(VerifyError::noSuchField); + + offset = field->getOffset(); + return tk; + +} + +/* + * Look up a class or interface stored at index cpi in this class's constant + * pool. This method sets isInterface to true if the resolved item is an + * interface, false if it is a class. + */ +ClassOrInterface &ClassFileSummary::lookupClassOrInterface(ConstantPoolIndex cpi, + bool &isInterface) +{ + if (arrayType) + verifyError(VerifyError::illegalAccess); + + /* Constant-pool index must be a CONSTANT_CLASS */ + if (constantPool->get(cpi)->getType() != CR_CONSTANT_CLASS) + verifyError(VerifyError::badConstantPoolIndex); + + const char *className = ((ConstantClass *) constantPool->get(cpi))->getUtf()->getUtfString(); + + ClassFileSummary &info = central.addClass(className); + + /* Array classes are never interfaces */ + if (*className == '[') + isInterface = false; + else + isInterface = (info.getAccessFlags() & CR_ACC_INTERFACE) != 0; + + return *(static_cast(info.getThisClass())); +} + +/* + * Look up a class stored at index cpi in this class's constant pool. + * Ensure that the constant pool entry at index cpi is a CONSTANT_Class that + * refers to a class (not an interface). + */ +Class &ClassFileSummary::lookupClass(ConstantPoolIndex cpi) +{ + bool isInterface; + ClassOrInterface &clazz = lookupClassOrInterface(cpi, isInterface); + + if (isInterface) + verifyError(VerifyError::badConstantPoolIndex); + + return *(static_cast(&clazz)); +} + + +/* + * Look up an interface stored at index cpi in this class's constant pool. + * Ensure that the constant pool entry at index cpi is a CONSTANT_Class that + * refers to an interface (not a class). + */ +Interface &ClassFileSummary::lookupInterface(ConstantPoolIndex cpi) +{ + bool isInterface; + ClassOrInterface &clazz = lookupClassOrInterface(cpi, isInterface); + + if (!isInterface) + verifyError(VerifyError::badConstantPoolIndex); + + return *(static_cast(&clazz)); +} + + +/* + * Look up a class, interface, or array type stored at index cpi in this + * class's constant pool. Ensure that the constant pool entry at index cpi + * is a CONSTANT_Class. + */ +Type &ClassFileSummary::lookupType(ConstantPoolIndex cpi) +{ + bool isInterface; + ClassOrInterface &clazz = lookupClassOrInterface(cpi, isInterface); + + return *(static_cast(&clazz)); +} + + +/* Update the vtable entry for a given method to reflect its resolved address + in this class and all subclasses. */ +void ClassFileSummary::updateVTable(Method &method) +{ + Vector *vIndices = NULL; + vIndicesUsed.get(const_cast(&method), &vIndices); + + if (!vIndices) + return; + + Uint32 numVIndices = vIndices->size(); + Uint32 i; + for (i = 0; i < numVIndices; i++) { + Uint32 vIndex = (*vIndices)[i]; + assert(vIndex < numVTableEntries); + getThisClass()->setVTableEntry(vIndex, addressFunction(method.getCode(true))); + } + + /* Update subclass vtables */ + Uint32 size = subClasses.size(); + for (i = 0; i < size; i++) + subClasses[i]->updateVTable(method); +} + +/* + * Look up a method stored at index cpi in this class's constant pool. + * Return the method's signature and whether or not it is static. If + * special is true, the method is resolved as specified in the + * Java VM specification for invoke-special. If this function sets + * dynamicallyResolved to true, it indicates that a vtable entry + * exists for this function at index vIndex. Otherwise, this method + * has been resolved statically; the address of the method is returned + * through a. isStatic is set to true if the method is a static method. + * (Note that non-static methods can also be statically resolved). + * isInit is set to true if this method is ; Likewise, isClInit + * is set to true if this method is . + * + * Return the Method object corresponding to the method if the method + * has been resolved statically (this includes all special resolutions). + * If the method must be resolved dynamically, return the Method object + * corresponding to that method resolved for the class given by the + * MethodRef or InterfaceMethodRef (really????) in the constant pool + * at index cpi. + */ +const Method *ClassFileSummary::lookupMethod(Uint8 type, + ConstantPoolIndex cpi, + Signature &sig, + bool &isStatic, + bool &dynamicallyResolved, + Uint32 &vIndex, + addr &a, + bool &isInit, + bool &isClInit, + bool special) + +{ + /* XXX Need to support array methods here */ + if (arrayType) + verifyError(VerifyError::illegalAccess); + + if (constantPool->get(cpi)->getType() != type) + verifyError(VerifyError::badConstantPoolIndex); + + if (!annotations[cpi].resolved) { + resolveFieldOrMethod(type, cpi); + isInit = annotations[cpi].isInit; + isClInit = annotations[cpi].isClinit; + + const Method *method = static_cast + (annotations[cpi].descriptor); + Uint16 modifiers = method->getModifiers(); + + /* Special methods may need to be resolved again */ + if (special) { + if (!isInit && !isClInit) { + if (!(modifiers & CR_METHOD_PRIVATE) && + isSubClassOf(annotations[cpi].info) && + (reader->getAccessFlags() & CR_ACC_SUPER)) { + /* We must re-resolve the method, choosing the nearest superclass */ + resolveSpecial(type, cpi); + } + } + } + } + + Method *method = const_cast + (static_cast(annotations[cpi].descriptor)); + Uint16 modifiers = method->getModifiers(); + isInit = annotations[cpi].isInit; + isClInit = annotations[cpi].isClinit; + isStatic = (modifiers & CR_METHOD_STATIC) != 0; + + if (type == CR_CONSTANT_INTERFACEMETHODREF) { + if (!(modifiers & CR_METHOD_PUBLIC)) + verifyError(VerifyError::badClassFormat); + } + + dynamicallyResolved = method->getDynamicallyDispatched(); + if (dynamicallyResolved) + method->getVIndex(vIndex); + else { + a = method->getCode(); + assert(addressFunction(a)); + } + + sig = *(const_cast(&method->getSignature())); + + return method; +} + + +/* + * Look up a static method stored at index cpi in this class's constant pool. + * Return the method's signature and address and its Method object. + */ +const Method &ClassFileSummary::lookupStaticMethod(ConstantPoolIndex cpi, + Signature &sig, addr &a) +{ + bool dynamicallyResolved, isStatic, isInit, isClInit; + Uint32 vIndex; + + const Method *method = lookupMethod(CR_CONSTANT_METHODREF, cpi, sig, isStatic, + dynamicallyResolved, vIndex, a, isInit, isClInit, false); + + if (!isStatic || isInit || isClInit) + verifyError(VerifyError::incompatibleClassChange); + + assert(method); + assert(addressFunction(a)); + return *method; +} + + +/* + * Look up a virtual method stored at index cpi in this class's constant pool. + * Return the method's signature and either the vtable index of this + * method's vtable entry or this method's address. If lookupVirtualMethod returns + * nil, then the method should be called via the vtable using the given index. + * If lookupVirtualMethod returns a Method object, then the method dispatch has been + * statically resolved (which can happen, for instance, for private methods + * and methods defined in final classes), and the method should be called + * directly using the given address and/or Method object. + */ +const Method *ClassFileSummary::lookupVirtualMethod(ConstantPoolIndex cpi, + Signature &sig, + Uint32 &vIndex, + addr &a) +{ + bool dynamicallyResolved, isStatic, isInit, isClInit; + + const Method *method = lookupMethod(CR_CONSTANT_METHODREF, cpi, sig, isStatic, + dynamicallyResolved, vIndex, a, isInit, isClInit, false); + + if (isStatic || isInit || isClInit) + verifyError(VerifyError::incompatibleClassChange); + + if (dynamicallyResolved) + return 0; + assert(method); + return method; +} + + +/* + * Look up an interface method stored at index cpi in this class's constant + * pool. Return the method's signature and either the interface index of + * this method's entry or this method's address. If lookupInterfaceMethod + * returns nil, then the method should be called via the interface table using the + * given index. If lookupInterfaceMethod returns a Method object, then the method + * dispatch has been statically resolved, and the method should be called directly + * using the given address and/or Method object. + * + * nArgs is the number of arguments as provided in the invokeinterface bytecode; + * it's redundant and provided only for verification purposes. If dynamic memory + * needs to be allocated to hold the signature's arguments array, allocate that + * memory from the given pool. + */ +const Method *ClassFileSummary::lookupInterfaceMethod(ConstantPoolIndex cpi, + Signature &sig, + Uint32 &vIndex, + Uint32 &interfaceNumber, + addr &a, uint nArgs) +{ + bool dynamicallyResolved, isStatic, isInit, isClInit; + + const Method *method = lookupMethod(CR_CONSTANT_INTERFACEMETHODREF, + cpi, sig, isStatic, + dynamicallyResolved, + vIndex, + a, isInit, isClInit, + false); + + if (isStatic || isInit || isClInit) + verifyError(VerifyError::incompatibleClassChange); + + Uint32 modifiers = method->getModifiers(); + + /* An interface method cannot be final */ + if ((modifiers & CR_METHOD_FINAL)) + verifyError(VerifyError::badClassFormat); + +#ifndef TESTING +// if (sig.nArguments != nArgs) +// verifyError(VerifyError::badClassFormat); +#else + /* Disabled for testing */ + nArgs = 0; /* Dummy */ +#endif + + interfaceNumber = asInterface(*method->getDeclaringClass()).getInterfaceNumber(); + + assert(dynamicallyResolved); + return 0; +} + + +/* + * Look up a special method stored at index cpi in this class's constant pool. + * Return the method's signature, address, and Method object. Follow the lookup + * process for invokespecial as described in the Java VM specification. + * Set isInit to true if this method is . + */ +const Method &ClassFileSummary::lookupSpecialMethod(ConstantPoolIndex cpi, + Signature &sig, bool &isInit, addr &a) +{ + bool dynamicallyResolved, isStatic, isClInit; + Uint32 vIndex; + + const Method *method = lookupMethod(CR_CONSTANT_METHODREF, cpi, sig, isStatic, + dynamicallyResolved, vIndex, a, isInit, isClInit, + true); + + if (isStatic || isClInit) + verifyError(VerifyError::incompatibleClassChange); + + /* Special methods are always dispatched statically */ + a = const_cast(method)->getCode(); + assert(addressFunction(a)); + + assert(method); + return *method; +} + +void ClassFileSummary::addInterfaceToVTable(const Interface *superInterface, + VTableNode *vtable, + Uint32 &numEntries) +{ + Uint32 firstVIndex = numEntries; + ClassFileSummary &interfaceSummary = *superInterface->summary; + + /* Record the base index of this interface's vtable for purposes + of interface method dispatch. */ + if (!(getAccessFlags() & CR_ACC_INTERFACE)) + interfaceDispatchTable->add(superInterface->getInterfaceNumber(), + vTableIndexToOffset(numEntries)); + + /* Add the vtable entries for our subinterfaces */ + int numInterfaces = interfaceSummary.getInterfaceCount(); + const Interface **interfaces = interfaceSummary.getInterfaces(); + for (int j = 0; j < numInterfaces; j++) + addInterfaceToVTable(interfaces[j], vtable, numEntries); + + Uint32 methodCount = interfaceSummary.reader->getMethodCount(); + const Method **methods = interfaceSummary.getMethods(); + for (Uint32 i = 0; i < methodCount; i++) { + Method *method = const_cast(methods[i]); + const char *name = method->getName(); + const char *signature = method->getSignatureString(); + + /* No Vtable entries for and */ + if (name == initp) { /* An interface cannot have a constructor */ + assert(0); + continue; + } + + if (name == clinitp) { + /* It is possible to have static initializers in an interface + * that initialize static final fields in the interface + */ + continue; + } + + if (getAccessFlags() & CR_ACC_INTERFACE) { + vtable[numEntries].method = method; + method->setVIndex(numEntries - firstVIndex); + numEntries++; + continue; + } + + ClassFileSummary *cfs = this; + while (1) { + Uint16 methodIndex; + const MethodInfo *minfo; + + minfo = cfs->reader->lookupMethod(name, signature, methodIndex); + if (minfo) { + const Method **implementedMethods = cfs->getMethods(); + method = const_cast(implementedMethods[methodIndex]); + method->setVIndex(numEntries); + addVIndexForMethod(method, numEntries); + vtable[numEntries].method = method; + break; + } + cfs = cfs->parentInfo; + if (!cfs) { + /* We've encountered an interface method for which there is no + corresponding implementation. This case is specifically + permitted by the JLS, so we don't throw a compile-time error. + Rather, if this method is actually invoked, an + IncompatibleClassChangeError is thrown. */ + break; + } + } + numEntries++; + } +} + + +/* Build the vtable for this class. This function must never be called + * before setParent() is called, since it needs the parent class vtable + * information. This function also builds the table used to perform + * constant-time interface method lookups at run-time. + * + * Each vtable lists entries in this order: + * 1) A copy of the vtable of the superclasses, containing all the + * inherited methods (except for those methods which are overridden by + * this class, which are replaced in the vtable) + * 2) The methods of all interfaces not inherited from superclasses, i.e. methods + * of the direct superinterfaces, including the superinterfaces of the direct + * superinterfaces. + * 3) All other virtual methods defined by this class + * 4) A single vtable entry that points to the Class or Interface that defines + * the vtable. This entry is used to perform instanceof() operations in + * constant time. + * + * It is possible for a method to be listed more than once in a single vtable. + * For example, the same method may appear in more than one interface that this + * class implements. Another possibility is that an inherited method is used to + * implement a superinterface of this class. Because a method can have more than + * one vtable index, the smallest one is stored as the canonical vIndex to be used + * for ordinary (non-interface) method lookup. + */ +void ClassFileSummary::buildVTable() +{ + /* XXX Need to do the right thing for array classes here */ + assert(!arrayType); + + VTableNode *vt; + Uint16 methodIndex; + Uint32 nvt; + Uint32 vIndex; + + if (arrayType) + return; + + interfaceDispatchTable = new InterfaceDispatchTable(); + + if (!parentInfo) { + nvt = 0; + } else { + nvt = parentInfo->getVTable(vt); + interfaceDispatchTable->inherit(parentInfo->interfaceDispatchTable); + } + + + const Method **methods = getMethods(); + int methodCount = reader->getMethodCount(); + + /* Compute the size of the vtables for interfaces which get embedded in this class' vtable */ + int numInterfaces = getInterfaceCount(); + const Interface **interfaces = getInterfaces(); + Uint32 interfaceVtablesTotalSize = 0; + int j; + for (j = 0; j < numInterfaces; j++) { + interfaceVtablesTotalSize += interfaces[j]->summary->numVTableEntries; + } + + /* The maximum possible number of entries is nvt + methodCount + interfaceVtablesSize + 1. + * The last vtable entry is used as a self-referential pointer to the class for performing + * the instanceof() operation in constant time. We may allocate more memory than + * we actually need to hold the vtable, because some of this class' methods override + * parent methods which already occupy vtable slots. + */ + Int32 numVTableElements = nvt + methodCount + interfaceVtablesTotalSize + 1; + vtable = new (staticPool) VTableNode[numVTableElements]; + memset(vtable, 0, sizeof(VTableNode)*numVTableElements); + Uint32 numEntries = 0; + + /* Copy the parent's vtable */ + for (;numEntries < nvt; numEntries++) { + vtable[numEntries] = vt[numEntries]; + Method *method = vt[numEntries].method; + + /* This might be the self-referential class pointer vtable entry of some + super-class (used for implementing instanceof), rather than a method */ + if (!method) { + assert(vt[numEntries].summary); + continue; + } + + /* See if the method is overridden by this class. */ + const char *name = method->getName(); + const char *signature = method->getSignatureString(); + const MethodInfo *minfo = reader->lookupMethod(name, signature, methodIndex); + if (minfo) { + method = const_cast(methods[methodIndex]); + method->setVIndex(numEntries); + vtable[numEntries].method = method; + } + + /* It's not permitted to have an abstract method in a non-abstract class. + (If this method is invoked, an error will be thrown, so it is not necessary + to throw an error here.) */ + assert(! ( (method->getModifiers() & CR_METHOD_ABSTRACT) && + !(getAccessFlags() & CR_ACC_ABSTRACT) )); + addVIndexForMethod(method, numEntries); + } + + /* Add the vtable entries for interfaces. It is possible that a method may + be added to the vtable for an interface even though it can be statically + resolved during normal method dispatch. That is, invoking a virtual + method on an interface variable may require a method lookup, even though + no lookup is required when the corresponding method is invoked on + the same exact object stored in a non-interface variable type. + */ + for (j = 0; j < numInterfaces; j++) { + const Interface *superInterface = interfaces[j]; + addInterfaceToVTable(superInterface, vtable, numEntries); + } + + /* Check for interface table overflow */ + if (!build(interfaceDispatchTable)) + verifyError(VerifyError::resourceExhausted); + + /* Now put in the methods defined in this class */ + for (int i = 0; i < methodCount; i++) { + Method *method = const_cast(methods[i]); + const char *name = method->getName(); + + /* No Vtable entries for and */ + if (name == initp || name == clinitp) + continue; + + /* Private methods are dispatched statically, as are static methods. */ + Uint16 accessFlags = method->getModifiers(); + if (accessFlags & (CR_METHOD_PRIVATE | CR_METHOD_STATIC)) + continue; + + /* See if we've already assigned a VIndex to this method */ + bool VIndexSet = method->getVIndex(vIndex); + + /* Final methods that are not defined in our superclasses + can also be resolved statically */ + Uint16 classFlags = reader->getAccessFlags(); + if (VIndexSet && ((accessFlags & CR_METHOD_FINAL) || (classFlags & CR_ACC_FINAL))) + continue; + + /* This method is never dispatched statically */ + method->setDynamicallyDispatched(true); + + /* Do nothing if this method already has been assigned a VTable offset, + i.e. because it overrides a method in a superclass or because it is + used in an interface. */ + if (VIndexSet) + continue; + + vtable[numEntries].method = method; + method->setVIndex(numEntries); + addVIndexForMethod(method, numEntries); + + numEntries++; + } + + if (!(getAccessFlags() & CR_ACC_INTERFACE)) { + /* We need an additional entry for a self-referential pointer to the class */ + vtable[numEntries].summary = this; + numEntries++; + } + + numVTableEntries = numEntries; + + UT_LOG(ClassFileSummary, PR_LOG_DEBUG, ("\t<%s> : %d vtable entries\n", + reader->getThisClass()->getUtf()->getUtfString(), + numVTableEntries)); + +#if 0 + dumpVTable(); +#endif +} + +#ifdef DEBUG_LOG +void ClassFileSummary::dumpVTable() +{ + for (Uint32 i=0; i < numVTableEntries; i++) { + Method *method = vtable[i].method; + if (method) { + UT_LOG(ClassFileSummary, PR_LOG_ALWAYS, ("\t\t%s\n", method->toString())); + } else { + ClassFileSummary *summary = vtable[i].summary; + assert(summary); + UT_LOG(ClassFileSummary, PR_LOG_ALWAYS, ("\t\tType: %s\n", summary->getClassName())); + } + } +} +#endif // DEBUG_LOG + +void ClassFileSummary::addVIndexForMethod(Method *method, Uint32 vIndex) { + Vector * vIndices = NULL; + vIndicesUsed.get(method, &vIndices); + if (!vIndices) { + vIndices = new Vector(2); + vIndicesUsed.add(method, vIndices); + } + vIndices->append(vIndex); +} + + + +/* Return a pointer to the method that is used to implement an + interface for a given class and interface method. The implementation + method is determined using the same tables and algorithm used by the + compiled Java code. If the method cannot be statically determined, + i.e. because it must be looked up in the class' vtable, then no + method is returned and vIndex is set to the vtable index of the + implementation. */ +const Method * +ClassFileSummary::lookupImplementationOfInterfaceMethod(const Method *interfaceMethod, + Uint32 &vIndex, + addr &a) +{ + const Interface *iface = &asInterface(*interfaceMethod->getDeclaringClass()); + ClassFileSummary *interfaceSummary = iface->summary; + + /* Get the unique serial number of the interface */ + Uint32 interfaceNumber = iface->getInterfaceNumber(); + assert(interfaceNumber < InterfaceDispatchTable::maxInterfaces); + + /* Get offset, in bytes, from the start of this class' vtable to the + start of the given interface's sub-vtable */ + Type *t = static_cast(getThisClass()); + VTableOffset interfaceVTableOffset = *(t->interfaceVIndexTable + interfaceNumber); + + /* Convert from vtable byte offset to vtable index */ + Uint32 interfaceVTableIndex = interfaceVTableOffset / sizeof(VTableOffset); + + /* Check that the given class actually implements the specified interface, using the + same technique as the compiled Java code. The last entry of each sub-table + should be a pointer to the given Interface object. */ + Uint32 interfacePointerVIndex = interfaceVTableIndex + interfaceSummary->numVTableEntries - 1; + if ((interfacePointerVIndex >= numVTableEntries) || + (vtable[interfacePointerVIndex].summary != this)) { + verifyError(VerifyError::noSuchMethod); + return NULL; // NOTREACHED + } + + /* Lookup the method within the interface's sub-vtable */ + Uint32 interfaceMethodVIndex; + bool hasVIndex = interfaceMethod->getVIndex(interfaceMethodVIndex); + assert(hasVIndex); + const Method *method; + + method = vtable[interfaceVTableIndex + interfaceMethodVIndex].method; + a = const_cast(method)->getCode(); + if (method->getDynamicallyDispatched()) { + method->getVIndex(vIndex); + return NULL; + } + return method; +} + +/* Returns true if the current class is a subclass of the class + * represented by summary + */ +bool ClassFileSummary::isSubClassOf(ClassFileSummary *summary) +{ + /* XXX What about array classes? */ + if (arrayType) + verifyError(VerifyError::illegalAccess); + + for (ClassFileSummary *parent = parentInfo; parent; + parent = parent->getParentInfo()) + if (parent == summary) + return true; + + return false; +} + +Type *ClassFileSummary::getSuperClass() const { + return const_cast(getThisClass()->getSuperClass()); +} + +/* Returns the class object corresponding to the supertype + * of this class. The supertype, which is used for computing + * assignability, provides a more detailed type taxonomy + * than the superclass. + * + * For all objects, except arrays and interfaces, the supertype + * is the same as the superclass. + */ +Type *ClassFileSummary::getSuperType() const +{ + return const_cast(getThisClass()->getSuperClass()); +} + +/* Returns total space taken up by this object. For array classes, + * returns total space taken up by the component class. + */ +Uint32 ClassFileSummary::getObjSize() const +{ + /* XXX Is this right? */ + if (arrayType) + return sizeof(JavaArray); + + return totalSize; +} + +/* returns the constantpool of the class For array classes, + * returns the constantPool of the component class. If this + * function is called on a primitive array, throws a VerifyError. + */ +const ConstantPool *ClassFileSummary::getConstantPool() const +{ + if (arrayType) + verifyError(VerifyError::illegalAccess); + + return constantPool; +} + +/* Returns number of items in the constant pool of this class + * For array classes, returns the constant pool count of the + * component class. If this function is called on a primitive array, + * throws a VerifyError. + */ +Uint32 ClassFileSummary::getConstantPoolCount() const +{ + if (arrayType) + verifyError(VerifyError::illegalAccess); + + return nConstants; +} + +/* returns an array of Interfaces that this class directly implements. + * For array classes, returns the interfaces of the component class. + * If this is called on a primitive array, throws a VerifyError. + */ +const Interface **ClassFileSummary::getInterfaces() +{ + if (arrayType) + verifyError(VerifyError::illegalAccess); + + if (!interfaces.built()) buildInterfaces(); + + return (const Interface **) interfaces.getEntries(); +} + +/* Returns number of interfaces that this class directly implements. + * For array classes, returns the number of interfaces implemented by + * the component class. If this function is called on a primitive array, + * throws a VerifyError. + */ +Uint16 ClassFileSummary::getInterfaceCount() const +{ + if (arrayType) + verifyError(VerifyError::illegalAccess); + + return reader->getInterfaceCount(); +} + +/* Returns an array of Field classes, each of which contains information + * about a field in the class. For array classes, returns fields of + * the component class. If this function is called on a primitive array, + * throws a VerifyError. + */ +const Field **ClassFileSummary::getFields() +{ + if (arrayType) + verifyError(VerifyError::illegalAccess); + + if (!fields.built()) buildFields(); + return (const Field **) fields.getEntries(); +} + +/* Returns number of fields in the class. For array classes, returns + * the field count of the component class. If this + * function is called on a primitive array, throws a VerifyError. + */ +Uint16 ClassFileSummary::getFieldCount() const +{ + if (arrayType) + verifyError(VerifyError::illegalAccess); + + return reader->getFieldCount(); +} + +/* Returns an array of method classes, each of which contains reflection + * information about a method in the class. For array classes, returns + * the methods of the component class. If this + * function is called on a primitive array, throws a VerifyError. + */ +const Method **ClassFileSummary::getMethods() +{ + if (arrayType) + verifyError(VerifyError::illegalAccess); + + if (!methods.built()) buildMethods(); + return (const Method **) methods.getEntries(); +} + + +/* Returns an array of MethodInfo structures that contain static + * (compile-time) information about methods. For array classes, + * returns MethodInfo's for the component class. If this + * function is called on a primitive array, throws a VerifyError. + */ +const MethodInfo **ClassFileSummary::getMethodInfo() const +{ + if (arrayType) + verifyError(VerifyError::illegalAccess); + + return reader->getMethodInfo(); +} + +/* Returns the number of methods in this class. For array classes, + * returns the number of methods in the component class. If this + * function is called on a primitive array, throws a VerifyError. + */ +Uint16 ClassFileSummary::getMethodCount() const +{ + if (arrayType) + verifyError(VerifyError::illegalAccess); + + return reader->getMethodCount(); +} + +/* Returns an array of public fields in the class. For array classes, + * returns the public fields in the component class. If this + * function is called on a primitive array, throws a VerifyError. + */ +Field **ClassFileSummary::getPublicFields() +{ + if (arrayType) + verifyError(VerifyError::illegalAccess); + + if (!publicFields.built()) + buildPublicFields(); + + return publicFields.getEntries(); +} + +/* Returns the number of public fields in the class. For array classes, + * returns the number of public fields in the component class. If this + * function is called on a primitive array, throws a VerifyError. + */ +Uint16 ClassFileSummary::getPublicFieldCount() +{ + if (arrayType) + verifyError(VerifyError::illegalAccess); + + return (Uint16) publicFields.getSize(); +} + +/* Returns an array of public methods in the class. For array classes, + * returns the public methods in the component class. If this + * function is called on a primitive array, throws a VerifyError. + */ +Method **ClassFileSummary::getPublicMethods() +{ + if (arrayType) + verifyError(VerifyError::illegalAccess); + + if (!publicMethods.built()) + buildPublicMethods(); + + return publicMethods.getEntries(); +} + +/* Returns the number of public methods in the class. For array classes, + * returns the number of public methods in the component class. If this + * function is called on a primitive array, throws a VerifyError. + */ +Uint16 ClassFileSummary::getPublicMethodCount() +{ + if (arrayType) + verifyError(VerifyError::illegalAccess); + + return (Uint16) publicMethods.getSize(); +} + + +/* Returns an array of declared methods in the class. */ +const Method **ClassFileSummary::getDeclaredMethods() +{ + if (arrayType) + verifyError(VerifyError::illegalAccess); + + if (!declaredMethods.built()) + buildDeclaredMethods(); + + return (const Method **) declaredMethods.getEntries(); +} + +/* Returns the number of declared methods in the class. */ +Uint16 ClassFileSummary::getDeclaredMethodCount() +{ + if (arrayType) + verifyError(VerifyError::illegalAccess); + + return (Uint16) declaredMethods.getSize(); +} + + +/* Returns an array of constructors of the class. For array classes, + * returns the constructors in the component class. If this + * function is called on a primitive array, throws a VerifyError. + */ +const Constructor **ClassFileSummary::getConstructors() +{ + /* XXX Handle array types correctly: they have one constructor! */ + if (arrayType) + verifyError(VerifyError::illegalAccess); + + if (!constructors.built()) + buildConstructors(); + + return (const Constructor **) constructors.getEntries(); + +} + +/* Returns the number of constructors in the class. For array classes, + * returns the number of constructors in the component class. If this + * function is called on a primitive array, throws a VerifyError. + */ +Uint16 ClassFileSummary::getConstructorCount() +{ + /* XXX Handle array types correctly: they have one constructor! */ + if (arrayType) + verifyError(VerifyError::illegalAccess); + + return (Uint16) constructors.getSize(); + +} + +/* Returns an array of public constructors of the class. For array classes, + * returns the public constructors in the component class. If this + * function is called on a primitive array, throws a VerifyError. + */ +Constructor **ClassFileSummary::getPublicConstructors() +{ + if (arrayType) + verifyError(VerifyError::illegalAccess); + + if (!publicConstructors.built()) + buildPublicConstructors(); + + return publicConstructors.getEntries(); +} + +/* Returns the number of public constructors in the class. For array + * classes, returns the number of constructors in the component class. + * If this function is called on a primitive array, throws a VerifyError. + */ +Uint16 ClassFileSummary::getPublicConstructorCount() +{ + /* XXX Handle array types correctly: they have one constructor! */ + if (arrayType) + verifyError(VerifyError::illegalAccess); + + return (Uint16) publicConstructors.getSize(); +} + + +/* Returns an array of (global) attributes for this class. + * For array classes, returns the attributes of the component class. + * If this function is called on a primitive array, throws a VerifyError. + */ +const AttributeInfoItem **ClassFileSummary::getAttributeInfo() const +{ + if (arrayType) + verifyError(VerifyError::illegalAccess); + + return reader->getAttributeInfo(); +} + +/* Returns number of (global) attributes in this class. For array classes, + * returns the number of attributes in the component class. If this + * function is called on a primitive array, throws a VerifyError. + */ +Uint16 ClassFileSummary::getAttributeCount() const +{ + if (arrayType) + verifyError(VerifyError::illegalAccess); + + return reader->getAttributeCount(); +} + + +/* Sets vt to the vtable of this class. Normally, this method + * should not be of interest to anyone other than other ClassFileSummary + * instances; it is used by ClassFileSummary to get its parent's vtable. + * If called from an array class, returns the vtable of the component. + * If this function is called on a primitive array, throws a VerifyError. + */ +Uint32 ClassFileSummary::getVTable(VTableNode *&vt) const +{ + /* need to handle array types */ + assert(!arrayType); + + vt = vtable; + return numVTableEntries; +} + + diff --git a/ef/Runtime/ClassInfo/ClassFileSummary.h b/ef/Runtime/ClassInfo/ClassFileSummary.h new file mode 100644 index 000000000000..67f70bdfa16a --- /dev/null +++ b/ef/Runtime/ClassInfo/ClassFileSummary.h @@ -0,0 +1,481 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#ifndef CLASSFILESUMMARY_H +#define CLASSFILESUMMARY_H + +#include "ClassReader.h" +#include "Pool.h" +#include "StringPool.h" +#include "ClassWorld.h" +#include "Method.h" +#include "Collector.h" +#include "InterfaceDispatchTable.h" + +#define ALIGN(size,mod) ((size)+(((size)%(mod)) ? ((mod)-((size)%(mod))) : 0)) +#define ALIGNMENT 4 + +typedef struct _AnnotationItem AnnotationItem; +typedef Uint16 ConstantPoolIndex; + +struct Field; +struct Method; +struct FieldOrMethod; +class ClassCentral; + + +/* Hashtable key operations where the key is a pointer to a Method */ +struct MethodKeyOps { + static bool equals(const Method * userKey, const Method * hashTableKey) { + return (userKey == hashTableKey); + } + + static Method *copyKey(Pool &/*pool*/, const Method * userKey) { + return const_cast(userKey); + } + + static Uint32 hashCode(const Method * userKey) { + return reinterpret_cast(userKey); + } +}; + +/* A hashtable where a pointer to a Method is the key */ +template +class MethodHashTable:public HashTable { +public: + MethodHashTable(Pool &p):HashTable(p) {}; +}; + +/* symbolic V-Table node */ +struct VTableNode; + +/* A ClassFileSummary encapsulates all the compile-time information about a + Java class. It is different from the Class objects which are Java objects + that describe a Java class. */ +class NS_EXTERN ClassFileSummary { +public: + ValueKind lookupConstant(ConstantPoolIndex cpi, Value &value) const; + + + TypeKind lookupStaticField(ConstantPoolIndex cpi, ValueKind &vk, addr &a, + bool &isVolatile, bool &isConstant); + + TypeKind lookupInstanceField(ConstantPoolIndex cpi, ValueKind &vk, + Uint32 &offset, bool &isVolatile, + bool &isConstant); + + Class &lookupClass(ConstantPoolIndex cpi); + + Interface &lookupInterface(ConstantPoolIndex cpi); + + Type &lookupType(ConstantPoolIndex cpi); + + const Method &lookupStaticMethod(ConstantPoolIndex cpi, Signature &sig, + addr &a); + + const Method *lookupVirtualMethod(ConstantPoolIndex cpi, Signature &sig, + Uint32 &vIndex, addr &a); + + const Method *lookupInterfaceMethod(ConstantPoolIndex cpi, Signature &sig, + Uint32 &vIndex, + Uint32 &interfaceNumber, addr &a, uint nArgs); + + const Method &lookupSpecialMethod(ConstantPoolIndex cpi, Signature &sig, + bool &isInit, addr &a); + + const Method *lookupImplementationOfInterfaceMethod(const Method *interfaceMethod, + Uint32 &vIndex, addr &a); + + /* returns the fully qualified name of this class. */ + const char *getClassName() const { + return className; + } + + const char *getSuperclassName() const; + + /* returns the minor version of this class from the class file */ + Uint16 getMinorVersion() const; + + /* Returns the major version of this class from the class file */ + Uint16 getMajorVersion() const; + + /* returns the access flags for this class from the class file */ + Uint16 getAccessFlags() const; + + /* Returns the class object corresponding to this class */ + Type *getThisClass() const { return clazz; } + + /* returns the class object corresponding to the superclass + * of this class, NIL if this class is Object or an interface. + */ + Type *getSuperClass() const; + + /* returns the class object corresponding to the supertype + * of this class, NIL if this class is Object. For all objects, + * except arrays and interfaces, the supertype is the same as the + * superclass. + */ + Type *getSuperType() const; + + /* Returns total space taken up by this object. For array classes, + * returns total space taken up by the component class. + */ + Uint32 getObjSize() const; + + const ConstantPool *getConstantPool() const; + + Uint32 getConstantPoolCount() const; + + const Interface **getInterfaces(); + + Uint16 getInterfaceCount() const; + + const Field **getFields(); + + Uint16 getFieldCount() const; + + const Method **getMethods(); + + const Method **getDeclaredMethods(); + + Uint16 getDeclaredMethodCount(); + + const Constructor **getConstructors(); + + Uint16 getConstructorCount(); + + const MethodInfo **getMethodInfo() const; + + Uint16 getMethodCount() const; + + Field **getPublicFields(); + + Uint16 getPublicFieldCount(); + + Method **getPublicMethods(); + + Uint16 getPublicMethodCount(); + + Field *getField(const char *name); + + Field *getDeclaredField(const char *name); + + Constructor **getPublicConstructors(); + Uint16 getPublicConstructorCount(); + + Method *getMethod(const char *name, const Type *parameterTypes[], + Int32 numParameterTypes); + + Method *getMethod(const char *name, const char *sig); + + Method *getDeclaredMethod(const char *name, const Type *parameterTypes[], + Int32 numParameterTypes); + + Constructor *getConstructor(const Type *parameterTypes[], + Int32 numParameterTypes); + + Constructor *getDeclaredConstructor(const Type *parameterTypes[], + Int32 numParameterTypes); + + const AttributeInfoItem **getAttributeInfo() const; + + Uint16 getAttributeCount() const; + + /* Returns parent's summary. */ + ClassFileSummary *getParentInfo() { return parentInfo; } + + /* Don't call this directly; call ClassCentral::addClass instead. */ + ClassFileSummary(Pool &staticp, Pool &runtimep, + StringPool &sp, ClassCentral ¢ral, + ClassWorld &world, + const char *className, + FileReader *fr, + bool arrayType, + Uint32 numDimensions, + bool primitiveType, + TypeKind tkind, + ClassFileSummary *component); + + /* Return a pointer to the interned version of the string . This is + * meant to be used by objects Class, Method and Constructor. + */ + const char *getInitString() { return initp; } + + /* Return a pointer to the interned version of the string . + * This is meant to be used by objects Class, Method and Constructor. + */ + const char *getClinitString() { return clinitp; } + +private: + const FieldOrMethod *resolveName(const Uint8 type, const char *name, + const char *desc, const InfoItem *&item); + + void resolveFieldOrMethod(const Uint8 type, Uint16 index); + + const Field *lookupField(ConstantPoolIndex cpi, + ValueKind &vk, + TypeKind &tk, + bool &isVolatile, + bool &isConstant, + bool &isStatic); + + void getPackageNames(); + + ClassOrInterface &lookupClassOrInterface(ConstantPoolIndex cpi, + bool &isInterface); + + const Method *lookupMethod(Uint8 type, ConstantPoolIndex cpi, + Signature &sig, + bool &isStatic, + bool &dynamicallyResolved, Uint32 &vIndex, + addr &a, + bool &isInit, bool &isClinit, bool special); + + void resolveSpecial(const Uint8 type, ConstantPoolIndex index); + + void annotate(Uint8 type, + ConstantPoolIndex index, const InfoItem *item, + const FieldOrMethod *descriptor, + ClassFileSummary *info, + const char *name, + const char *sig); + + + Type *makeClazz(); + + void computeSize(); + + /* Do not call this method directly; use the lookup methods instead */ + Uint32 getVTable(VTableNode *&vt) const; + +public: + /* Set the size of the parent object. + * Don't call this directly; this is for use by ClassCentral only. + */ + void setParent(ClassFileSummary *info); + + /* Add a sub-class, whose information is given by info, to the list + * of sub-classes of this class. + */ + void addSubclass(ClassFileSummary &info) { + subClasses.append(&info); + } + + /* Update the clazz' vtable to point to a newly compiled method's code */ + void updateVTable(Method &method); + +#ifdef DEBUG_LOG + void dumpVTable(); +#endif + + void addVIndexForMethod(Method *method, Uint32 vIndex); + + Field &buildField(Uint32 fieldIndex); + Method &getMethod(Uint32 methodIndex) { + Method *method = methods.get(methodIndex); + if (method) + return *method; + return buildMethod(methodIndex); + } + Interface &buildInterface(Uint32 interfaceIndex); + +private: + Method &buildMethod(Uint32 methodIndex); + Field &buildPublicField(Uint32 index); + Method &buildPublicMethod(Uint32 index); + Method &buildDeclaredMethod(Uint32 index); + Constructor &buildConstructor(Uint32 index); + Constructor &buildPublicConstructor(Uint32 index); + +public: + /* These are declared public only for use by internal routines of + * ClassInfo. These are not to be used directly + */ + void buildFields(); + void buildMethods(); + void buildConstructors(); + void buildPublicFields(); + void buildPublicMethods(); + void buildDeclaredMethods(); + void buildPublicConstructors(); + + const ClassFileReader *getReader() const { return reader; } + +private: + void buildInterfaces(); + + bool isSubClassOf(ClassFileSummary *summary); + + void buildVTable(); + void addInterfaceToVTable(const Interface *superInterface, + VTableNode *vtable, + Uint32 &numEntries); + + static void runStatics(ClassOrInterface *clz); + + Field *getField(const char *name, bool publik, bool interned); + Method *getMethod(const char *name, const Type *parameterTypes[], + Int32 numParameterTypes, bool publik, + bool interned); + + /* Name of the class represented by this summary */ + const char *className; + + /* Pool used to allocate all static information (other than the Class, + * Interface, Field and Method classes + */ + Pool &staticPool; + + /* Pool used to allocate all dynamic (runtime) information (Class, + * Interface, Method and Field classes + */ + Pool &runtimePool; + + /* String hash table where interned strings are kept. */ + StringPool &sp; + + /* ClassFileReader class that reads the class file into memory */ + const ClassFileReader *reader; + + /* ClassCentral class that holds all existing ClassFileSummary objects + * in the universe + */ + ClassCentral ¢ral; + + /* ClassWorld class that holds all existing Class, Interface and Type + * objects in the universe. ClassCentral is a compile-time repository, + * and ClassWorld is a runtime repository. + */ + ClassWorld &world; + + /* Constant Pool of class */ + const ConstantPool *constantPool; + Uint32 nConstants; + + /* Resolved information about each constantPool item. + * annotations[i].resolved is true if the item at index i in the + * constant pool has been resolved. + */ + AnnotationItem *annotations; + + /* Total size of instances of this class and its superclass (if any) */ + Uint32 totalSize, parentSize; + + /* VTable for this class */ + VTableNode *vtable; + Uint32 numVTableEntries; + + /* Table used to lookup interface methods within class */ + InterfaceDispatchTable *interfaceDispatchTable; + + /* Summary for the parent class of this class. NULL if this is the class Object. */ + ClassFileSummary *parentInfo; + + /* Type class for this class, if it exists */ + Type *clazz; + + /* Set of all fields (public, protected, private) declared by this class + * only. This does not include fields which may have been declared in + * a super class of this class and are accessible from this class. + */ + Collector fields; + + /* Set of offsets for each field in the "fields" array*/ + Uint32 *fieldOffsets; + + /* Set of all public fields accessible from this class. This includes + * public fields in super-classes which are accessible from this class. + * Note that those fields declared in this class will also be part of + * the fields collection. + */ + Collector publicFields; + + /* Set of all methods (public, protected, private) declared by this + * class only. This does not include methods which may have been + * declared in superclasses and are accessible from this class. + * However, this does include constructors () and static + * initializer methods (). + */ + Collector methods; + + /* Set of all methods (public, protected, private) declared by this + * class only. This does not include methods which may have been + * declared in superclasses and are accessible from this class. + * It also does not include constructors and static initializers + */ + Collector declaredMethods; + + /* Set of all public methods accessible from this class. This includes + * public methods declared in superclasses that are visible from this class. + * Note that those methods declared in this class will also be part of + * the methods collection. + */ + Collector publicMethods; + + /* Set of all constructors implemented by this class. Note that these + * will also be part of the methods collection. + */ + Collector constructors; + + /* Set of all public constructors. Note that these + * will also be part of the methods collection. + */ + Collector publicConstructors; + + /* Set of direct superinterfaces of this class */ + Collector interfaces; + + /* True if we're an array type */ + bool arrayType; + + /* If we're an array type, this is the number of dimensions in the array */ + Uint32 numDimensions; + + /* If an array type, this is the pointer to our element class + or interface, unless this is an array of primitive elements */ + ClassFileSummary *elementSummary; + + /* True if our element type is primitive */ + bool primitiveElementType; + + /* If our element type is primitive, this is its primitive type */ + TypeKind tk; + + /* Pointers to interned versions of init and clinit */ + const char *initp, *clinitp; + + /* Package Name and unqualified name of the class. + * packageName("java/lang/Object") = "java.lang"; and + * unqualifiedName("java/lang/Object") = "Object". + */ + const char *packageName; + const char *unqualName; + + /* Global lookup table for interface methods implemented by this class */ + InterfaceDispatchTable interfaceTable; + + /* Table of Vindex's used by a given Method */ + MethodHashTable* > vIndicesUsed; + + /* Set of all sub-classes of this class that have currently been loaded + * by the VM + */ + Vector subClasses; +}; + +#endif /* CLASSFILESUMMARY_H */ + diff --git a/ef/Runtime/ClassInfo/Collector.h b/ef/Runtime/ClassInfo/Collector.h new file mode 100644 index 000000000000..95b639cc8df0 --- /dev/null +++ b/ef/Runtime/ClassInfo/Collector.h @@ -0,0 +1,83 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#ifndef _COLLECTOR_H_ +#define _COLLECTOR_H_ + +#include "Pool.h" + +/* A class that holds a collection of objects of class N of a fixed size that + * may not all be added to the collection at the same time. Keeps track of + * how many objects have been actually added, and whether or not the + * collection is full (ie all objects have been added). + */ +template class Collector { +private: + N **entries; + Uint32 numEntries; + + bool allEntriesBuilt; + Uint32 numEntriesBuilt; + + Pool &pool; + +public: + Collector(Pool &p) : + entries(0), numEntries(0), allEntriesBuilt(false), numEntriesBuilt(0), + pool(p) { } + + /* Set the size of the collection. You can only do this once */ + void setSize(Uint32 n) { + assert(!numEntries); + + numEntries = n; + entries = new (pool) N *[n]; + + for (Uint32 i = 0; i < n; i++) + entries[i] = 0; + } + + /* Add an entry to the collection at index n. You can only do this once. */ + void set(Uint32 n, N *entry) { + assert(n < numEntries && !entries[n] && entry); + + entries[n] = entry; + if (++numEntriesBuilt == numEntries) + allEntriesBuilt = true; + } + + /* Get the entry at index n, NIL if none has been set yet. */ + N *get(Uint32 n) { + assert(n < numEntries); + return entries[n]; + } + + /* return true if all entries have been built */ + bool built() { return allEntriesBuilt; } + + /* Return number of entries built */ + Int32 getNumEntriesBuilt() { return numEntriesBuilt; } + + /* return all entries */ + N **getEntries() { return entries; } + + /* return number of entries */ + Uint32 getSize() { return numEntries; } +}; + + +#endif /* _COLLECTOR_H_ */ diff --git a/ef/Runtime/ClassInfo/Makefile b/ef/Runtime/ClassInfo/Makefile new file mode 100644 index 000000000000..868bc73c6c68 --- /dev/null +++ b/ef/Runtime/ClassInfo/Makefile @@ -0,0 +1,62 @@ +#!gmake +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +####################################################################### +# (1) Directory specific info # +####################################################################### + +DEPTH = ../.. + + +CPPSRCS = ClassCentral.cpp \ + ClassFileSummary.cpp \ + PathComponent.cpp \ + $(NULL) + +LOCAL_EXPORTS = ClassCentral.h \ + ClassFileSummary.h \ + Collector.h \ + PathComponent.h \ + StringPool.h \ + $(NULL) + +MODULE_NAME = EF + +####################################################################### +# (2) Include "component" configuration information. # +####################################################################### + +include $(DEPTH)/config/config.mk + +####################################################################### +# (3) Include "local" platform-dependent assignments (OPTIONAL). # +####################################################################### + + + +####################################################################### +# (4) Execute "component" rules. (OPTIONAL) # +####################################################################### + +include $(DEPTH)/config/rules.mk + +####################################################################### +# (7) Execute "local" rules. (OPTIONAL). # +####################################################################### + + + diff --git a/ef/Runtime/ClassInfo/PathComponent.cpp b/ef/Runtime/ClassInfo/PathComponent.cpp new file mode 100644 index 000000000000..bf95af67dd1b --- /dev/null +++ b/ef/Runtime/ClassInfo/PathComponent.cpp @@ -0,0 +1,130 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#include "PathComponent.h" + +#include "prio.h" +#include "plstr.h" +#include "prprf.h" + +#include "CUtils.h" +#include "StringUtils.h" + +#include "DiskFileReader.h" +#include "ZipFileReader.h" + +/* return a path component object that can handle the component given + * by path + */ +PathComponent::PathComponent(const char *path, Pool &pool) : pool(pool) +{ + PRFileInfo info; + + if (PR_GetFileInfo(path, &info) < 0) + componentType = pathComponentTypeInvalid; + else { + switch (info.type) { + case PR_FILE_DIRECTORY: + componentType = pathComponentTypeDirectory; + dirName = dupString(path, pool); + break; + + case PR_FILE_FILE: { + bool status; + ZipArchive *zarch = new (pool) ZipArchive(path, pool, status); + + if (status) { + archive = zarch; + componentType = pathComponentTypeZipFile; + } else { + zarch->ZipArchive::~ZipArchive(); + componentType = pathComponentTypeInvalid; + } + + break; + } + + default: + componentType = pathComponentTypeInvalid; + break; + } + } +} + + +FileReader *PathComponent::getFile(const char *className, + Uint32 maxFileNameLen) +{ + if (componentType == pathComponentTypeInvalid) + return 0; + + switch (componentType) { + case pathComponentTypeZipFile: { + Int32 len = PL_strlen(className)+10; + TemporaryBuffer tempBuf(len); + char *fileName = tempBuf; + + PR_snprintf(fileName, len, "%s.class", className); + const DirectoryEntry *entry = archive->lookup(fileName); + + if (!entry) + return 0; + + return new (pool) ZipFileReader(pool, *archive, entry); + } + + case pathComponentTypeDirectory: { + Int32 fileLen = PL_strlen(className) + PL_strlen(dirName)+10; + TemporaryBuffer fileBuf(fileLen); + char *fileName = fileBuf; + PR_snprintf(fileName, fileLen, "%s/%s.class", dirName, className); + + /* Normal file names on the MAC are truncated to 31 characters */ + if (maxFileNameLen > 0) { + char *classFileName = PL_strrchr(fileName, '/'); + + if (classFileName == NULL) + classFileName = fileName; + else + classFileName += 1; + + Uint32 fileNameLen = PL_strlen(classFileName); + + if (fileNameLen > maxFileNameLen) { +#ifdef XP_MAC + classFileName[maxFileNameLen] = 'É'; + classFileName[maxFileNameLen + 1] = 0; +#else + assert(false); +#endif + } + } + + PRFileInfo info; + if (PR_GetFileInfo(fileName, &info) < 0) + return 0; + + return new DiskFileReader(pool, fileName); + } + + default: + return 0; + } +} + + + diff --git a/ef/Runtime/ClassInfo/PathComponent.h b/ef/Runtime/ClassInfo/PathComponent.h new file mode 100644 index 000000000000..b152024b6578 --- /dev/null +++ b/ef/Runtime/ClassInfo/PathComponent.h @@ -0,0 +1,63 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#ifndef _PATH_COMPONENT_H_ +#define _PATH_COMPONENT_H_ + +#include "Pool.h" +#include "FileReader.h" +#include "ZipArchive.h" + +enum PathComponentType { + pathComponentTypeInvalid=0, + pathComponentTypeDirectory, + pathComponentTypeZipFile, + pathComponentTypeJarFile +}; + +/* A path component is one component in a class path. It could + * be a directory, a zip file or a jar file. + */ +class PathComponent { +public: + PathComponent(const char *path, Pool &pool); + + /* If the class given by className can be found in the domain of + * this component, return an object that is capable of reading the + * file. Otherwise, return NULL. maxFileNameLen, if non-zero, indicates + * the maximum length of a file on the native opearing system. filenames + * longer than maxFileNameLen are assumed to be truncated to maxFileNameLen. + */ + FileReader *getFile(const char *className, Uint32 maxFileNameLen = 0); + +private: + /* Pool used to allocate memory */ + Pool &pool; + + /* Type of path component */ + PathComponentType componentType; + + /* component specific information */ + union { + ZipArchive *archive; /* Zip archive reader for zip files */ + const char *dirName; /* Directory name for directories */ + }; +}; + + + +#endif /* _PATH_COMPONENT_H_ */ diff --git a/ef/Runtime/ClassInfo/StringPool.h b/ef/Runtime/ClassInfo/StringPool.h new file mode 100644 index 000000000000..ba2ff22db0a7 --- /dev/null +++ b/ef/Runtime/ClassInfo/StringPool.h @@ -0,0 +1,98 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#ifndef _STRING_POOL_H_ +#define _STRING_POOL_H_ + +#include "HashTable.h" +#include "JavaString.h" + +class StrNode { +public: + JavaString *str; /* The string object corresponding to this char */ +}; + +class StringPool : private HashTable { +public: + StringPool(Pool &p) : HashTable(p) { } + + /* Intern "str" if not already interned and return a pointer to + * the interned string + */ + const char *intern(const char *str) { + int hashIndex; + const char *key; + + node.str = 0; + + if ((key = HashTable::get(str, &node, hashIndex)) != 0) + return key; + + return add(str, node, hashIndex); + } + + /* return the String object corresponding to this string. */ + JavaString *getStringObj(const char *str) { + int hashIndex; + const char *key; + + if ((key = HashTable::get(str, &node, hashIndex)) != 0) { + if (!node.str) { + node.str = new (pool) JavaString(key); + HashTable::set(str, &node, hashIndex); + } + + return node.str; + } + + return 0; + } + + + /* Returns a pointer to the interned string if it exists, NULL + * otherwise + */ + const char *get(const char *str) { + int hashIndex; + + return HashTable::get(str, 0, hashIndex); + } + + /* Get a vector, allocated using the same internal pool, that contains + * all the elements in the string pool + */ + operator Vector& () { + Vector *vector = new (pool) Vector; + + for (Uint32 i = 0; i < _NBUCKETS_; i++) { + DoublyLinkedList >& list = buckets[i]; + if (!list.empty()) + for (DoublyLinkedNode *j = list.begin(); !list.done(j); j = list.advance(j)) { + vector->append(const_cast(list.get(j).key)); + } + } + + return *vector; + } + +private: + StrNode node; +}; + +#endif /* _STRING_POOL_H_ */ + + diff --git a/ef/Runtime/ClassInfo/main.cpp b/ef/Runtime/ClassInfo/main.cpp new file mode 100644 index 000000000000..eb626f2f47c0 --- /dev/null +++ b/ef/Runtime/ClassInfo/main.cpp @@ -0,0 +1,273 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +/* Test program for ClassFileSummary */ + +#include "prinit.h" +#include "ClassFileSummary.h" +#include "ClassCentral.h" +#include "ErrorHandling.h" + +char *fileName = 0; +char *className = 0; +char *classPath = 0; + +void printUsage() +{ + printf("Usage: classinfo [-f filename] [-cpath classpath] classname\n"); + exit(0); +} + +void parseOptions(int argc, char **argv) +{ + int i; + + for (i = 1; i < argc; i++) + if (!strcmp(argv[i], "-f")) + fileName = argv[++i]; + else if (!strcmp(argv[i], "-cpath")) + classPath = argv[++i]; + else if (!strcmp(argv[i], "-help")) + printUsage(); + else if (className) {/* must be a classname */ + printf("Syntax error or duplicate filename\n"); + printUsage(); + } else + className = argv[i]; + + if (!className) { + printf("Insufficient arguments\n"); + printUsage(); + } + +} + +Pool dynamicPool; +ClassWorld world(dynamicPool); + +int main(int argc, char **argv) +{ + int i; + +#ifndef NO_NSPR + PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 1); +#endif + + parseOptions(argc, argv); + + // Pool dynamicPool; + StringPool sp(dynamicPool); + // ClassWorld world(dynamicPool); + + ClassCentral central(dynamicPool, world, sp, classPath); + + printf("Initializing distinguished objects....\n"); + try { + initDistinguishedObjects(central); + } catch (VerifyError err) { + printf("Error initializing distinguished objects: %d\n", err.cause); + exit(1); + } + printf("Initialized distinguished objects!\n"); + + ClassFileSummary *info; + const ConstantPool *constantPool; + int constantPoolCount; + + printf("Initialized class central\n"); + + try { + if (fileName) { + printf("Loading from file %s\n", fileName); + info = ¢ral.addClass((const char *) className, + (const char *) fileName); + } else + info = ¢ral.addClass((const char *) className); + + } catch (VerifyError err) { + printf("Cannot load class %s: error %d\n", className, err.cause); + exit(1); + } + + constantPool = info->getConstantPool(); + constantPoolCount = info->getConstantPoolCount(); + + printf("Total size of object : %d\n", info->getObjSize()); + + /* Resolve fields, methods, constants, interfaceMethods */ + for (i = 0; i < constantPoolCount; i++) + if (constantPool->get(i)) { + uint8 type = constantPool->get(i)->getType(); + + if (type == CR_CONSTANT_FIELDREF) { + ConstantFieldRef *ref = (ConstantFieldRef *) constantPool->get(i); + ConstantNameAndType *nameAndType = (ConstantNameAndType *) ref->getTypeInfo(); + ConstantClass *cclass = ref->getClassInfo(); + + printf("--> Resolving field %s::%s...\n", + cclass->getUtf()->getUtfString(), + nameAndType->getName()->getUtfString()); + + uint32 offset; + bool isVolatile, isConstant; + bool isStatic = false; + TypeKind tk; + ValueKind vk; + + try { + tk = info->lookupInstanceField(i, vk, + offset, isVolatile, isConstant); + } catch (VerifyError err) { + printf("\tlookupInstanceField() failed with error %d.\n", + err.cause); + printf("\tOk, so it's not an instance field. Trying static.\n"); + addr a; + + try { + tk = info->lookupStaticField(i, vk, a, isVolatile, isConstant); + isStatic = true; + } catch (VerifyError err) { + printf("Cannot resolve field %s: %d\n", + nameAndType->getName()->getUtfString(), err.cause); + } + } + + if (isStatic) + printf("Resolved as static field.\n"); + else + printf("Resolved as instance field with offset %u\n", offset); + + } else if (type == CR_CONSTANT_METHODREF) { + ConstantMethodRef *ref = (ConstantMethodRef *) constantPool->get(i); + ConstantNameAndType *nameAndType = (ConstantNameAndType *) ref->getTypeInfo(); + ConstantClass *cclass = ref->getClassInfo(); + + const char *methodName = nameAndType->getName()->getUtfString(); + + printf("--> Resolving method %s::%s...\n", + cclass->getUtf()->getUtfString(), + methodName); + + uint32 vIndex; + addr a; + Signature sig; + bool dynamicallyResolved = false; + + if (!strcmp(methodName, "") || !strcmp(methodName, "")) { + try { + info->lookupSpecialMethod(i, sig, a); + + printf("\tResolved special method %s.\n", methodName); + + } catch (VerifyError err) { + printf("Could not resolve special method %s: error %d\n", + methodName, err.cause); + exit(1); + } + } else { + try { + dynamicallyResolved = + info->lookupVirtualMethod(i, sig, vIndex, a); + } catch (VerifyError err) { + printf("\tlookupVirtualMethod() failed with erorr %d\n", + err.cause); + printf("\tOk, so method is not virtual. trying static...\n"); + + try { + info->lookupStaticMethod(i, sig, a); + } catch (VerifyError err) { + printf("Cannot resolve method %s: %d\n", + nameAndType->getName()->getUtfString(), err.cause); + exit(1); + } + + } + } + + if (dynamicallyResolved) + printf("\tResolved method %s as virtual: vindex %u.\n", + nameAndType->getName()->getUtfString(), vIndex); + else { + printf("\tResolved method %s statically\n", + nameAndType->getName()->getUtfString()); + } + + } else if (type == CR_CONSTANT_INTERFACEMETHODREF) { + ConstantMethodRef *ref = (ConstantMethodRef *) constantPool->get(i); + ConstantNameAndType *nameAndType = (ConstantNameAndType *) ref->getTypeInfo(); + ConstantClass *cclass = ref->getClassInfo(); + + const char *methodName = nameAndType->getName()->getUtfString(); + printf("--> Resolving interface method %s::%s...\n", + cclass->getUtf()->getUtfString(), + methodName); + + Signature sig; + uint32 interfaceIndex; + addr a; + uint32 nArgs; + + if (!strcmp(methodName, "") || !strcmp(methodName, "")) { + try { + info->lookupSpecialMethod(i, sig, a); + + printf("\tResolved special method %s.\n", methodName); + + } catch (VerifyError err) { + printf("Could not resolve special method %s: error %d\n", + methodName, err.cause); + exit(1); + } + } else { + try { + bool staticallyResolved = info->lookupInterfaceMethod(i, sig, + interfaceIndex, + a, + nArgs); + printf("\tResolved interface method %s %s.\n", + nameAndType->getName()->getUtfString(), + (staticallyResolved) ? "statically" : "dynamically"); + } catch (VerifyError err) { + printf("\tCould not resolve interface method %s: error %d\n", + nameAndType->getName()->getUtfString(), err.cause); + exit(1); + } + } + } + } + + printf("Successfully loaded class file. \n"); + + printf("Getting class descriptor...\n"); + Class *clazz = static_cast(info->getThisClass()); + printf("Obtained class descriptor.\n"); + + /* Now look up all the interfaces this class implements */ + printf("Loading interfaces...\n"); + const Interface **interfaces = info->getInterfaces(); + + printf("Done!\n"); + return 0; +} + + +#ifdef DEBUG_LAURENT +#ifdef __GNUC__ +// for gcc with -fhandle-exceptions +void terminate() {} +#endif +#endif diff --git a/ef/Runtime/ClassReader/AttributeHandlers.cpp b/ef/Runtime/ClassReader/AttributeHandlers.cpp new file mode 100644 index 000000000000..162f9ce94cb1 --- /dev/null +++ b/ef/Runtime/ClassReader/AttributeHandlers.cpp @@ -0,0 +1,295 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#include "AttributeHandlers.h" +#include "ErrorHandling.h" + +#include "plstr.h" + +/* Implementation of class AttributeHandler */ +AttributeHandler::AttributeHandler(Pool &pool, FileReader *_reader, + ClassFileReader *_cfr, + const char *_name): + p(pool), name(_name), reader(_reader), cfr(_cfr) +{ + constantPool = cfr->getConstantPool(); +} + +int AttributeHandler::validateNameAndLength(const char *_name, + Uint32 *length) { + + if (_name && name && PL_strcmp(name, _name) != 0) + return false; + + /* Get the length */ + if (!reader->readU4(length, 1)) + verifyError(VerifyError::noClassDefFound); + + return true; +} + + +#define READ_INDEX(index) \ +Uint16 index;\ +if (!reader->readU2(&index, 1)) \ + verifyError(VerifyError::noClassDefFound); + +/* Implementation of AttributeHandlerSourceFile */ +AttributeInfoItem *AttributeHandlerSourceFile::handle(const char *_name) +{ + Uint32 length; + if (!validateNameAndLength(_name, &length)) + return 0; + + READ_INDEX(sourceFileIndex); + + if (invalidAttribute(sourceFileIndex, CR_CONSTANT_UTF8)) + verifyError(VerifyError::noClassDefFound); + + AttributeSourceFile *item = + new (p) + AttributeSourceFile(p, (ConstantUtf8 *) constantPool->get(sourceFileIndex)); + return item; +} + +/* Implementation of AttributeHandlerConstantValue */ +AttributeInfoItem *AttributeHandlerConstantValue::handle(const char *_name) +{ + Uint32 length; + if (!validateNameAndLength(_name, &length)) + return 0; + + READ_INDEX(constantValueIndex); + + if (invalidIndex(constantValueIndex)) + verifyError(VerifyError::noClassDefFound); + + int type = constantPool->get(constantValueIndex)->getType(); + + /* constantValueIndex must point to a long, float, double, + * integer, or string + */ + if (!((type > 2 && type < 7) || + (type == CR_CONSTANT_STRING))) + verifyError(VerifyError::noClassDefFound); + + AttributeConstantValue *item = new (p) + AttributeConstantValue(p, const_cast (constantPool->get(constantValueIndex)), constantValueIndex); + return item; +} + + +/* Implementation of AttributeHandlerCode */ +AttributeInfoItem *AttributeHandlerCode::handle(const char *_name) +{ + Uint32 length; + if (!validateNameAndLength(_name, &length)) + return 0; + + Uint16 maxStack, maxLocals; + Uint32 codeLength; + + if (!reader->readU2(&maxStack, 1)) + verifyError(VerifyError::noClassDefFound); + + if (!reader->readU2(&maxLocals, 1)) + verifyError(VerifyError::noClassDefFound); + + if (!reader->readU4(&codeLength, 1)) + verifyError(VerifyError::noClassDefFound); + + AttributeCode *code = new (p) AttributeCode(p, (Uint16) length, maxStack, + maxLocals, codeLength); + + char *codeStr = (char *) code->getCode(); + + if (codeLength > 0) { + if (!reader->readU1(codeStr, codeLength)) + verifyError(VerifyError::noClassDefFound); + } + + Uint16 numExceptions; + if (!reader->readU2(&numExceptions, 1)) + verifyError(VerifyError::noClassDefFound); + + if (!code->setNumExceptions(numExceptions)) + verifyError(VerifyError::noClassDefFound); + + ExceptionItem *exceptions = const_cast + (code->getExceptions()); + + for (int i = 0; i < numExceptions; i++) { + Uint16 array[4], catchIndex; + + /* Read in startPc, endPc, handlerPc, catchType */ + if (!reader->readU2(array, 4)) + verifyError(VerifyError::noClassDefFound); + + if ((catchIndex = array[3]) > 0 && (invalidAttribute(catchIndex, + CR_CONSTANT_CLASS))) + verifyError(VerifyError::noClassDefFound); + + exceptions[i].startPc = array[0]; + exceptions[i].endPc = array[1]; + exceptions[i].handlerPc = array[2]; + exceptions[i].catchType = catchIndex; + } + + Uint16 attrCount; + /* Ok, so we can have nested attributes here */ + if (!reader->readU2(&attrCount, 1)) + verifyError(VerifyError::noClassDefFound); + + if (!code->setNumAttributes(attrCount)) + verifyError(VerifyError::noClassDefFound); + + AttributeInfoItem **attributes = (AttributeInfoItem **) + code->getAttributes(); + + cfr->readAttributes(attributes, attrCount); + return code; +} + + +/* Implementation of AttributeHandlerLineNumberTable */ +AttributeInfoItem *AttributeHandlerLineNumberTable::handle(const char *_name) +{ + Uint32 length; + if (!validateNameAndLength(_name, &length)) + return 0; + + Uint16 numEntries; + if (!reader->readU2(&numEntries, 1)) + verifyError(VerifyError::noClassDefFound); + + AttributeLineNumberTable *table = new (p) + AttributeLineNumberTable(p, length); + + if (!table->setNumEntries(numEntries)) + verifyError(VerifyError::noClassDefFound); + + LineNumberEntry *entries = table->getEntries(); + + for (int i = 0; i < numEntries; i++) { + Uint16 temp[2]; + + if (!reader->readU2(temp, 2)) + verifyError(VerifyError::noClassDefFound); + + entries[i].startPc = temp[0]; + entries[i].lineNumber = temp[1]; + } + + return table; +} + + +/* Implementation of AttributeHandlerLocalVariableTable */ +AttributeInfoItem *AttributeHandlerLocalVariableTable::handle(const char *_name) +{ + Uint32 length; + if (!validateNameAndLength(_name, &length)) + return 0; + + Uint16 numEntries; + if (!reader->readU2(&numEntries, 1)) + verifyError(VerifyError::noClassDefFound); + + AttributeLocalVariableTable *table = new (p) + AttributeLocalVariableTable(p, length); + + if (!table->setNumEntries(numEntries)) + verifyError(VerifyError::noClassDefFound); + + LocalVariableEntry *entries = table->getEntries(); + + for (int i = 0; i < numEntries; i++) { + Uint16 temp[5]; + + if (!reader->readU2(temp, 5)) + verifyError(VerifyError::noClassDefFound); + + entries[i].startPc = temp[0]; + entries[i].length = temp[1]; + if (invalidAttribute(temp[2], CR_CONSTANT_UTF8)) + verifyError(VerifyError::noClassDefFound); + + entries[i].name = (ConstantUtf8 *) constantPool->get(temp[2]); + + if (invalidAttribute(temp[3], CR_CONSTANT_UTF8)) + verifyError(VerifyError::noClassDefFound); + + entries[i].descriptor = (ConstantUtf8 *) constantPool->get(temp[3]); + entries[i].index = temp[4]; + } + + return table; +} + + +/* Implementation of AttributeHandlerExceptions */ +AttributeInfoItem *AttributeHandlerExceptions::handle(const char *_name) +{ + Uint32 length; + if (!validateNameAndLength(_name, &length)) + return 0; + + Uint16 numExceptions; + + if (!reader->readU2(&numExceptions, 1)) + verifyError(VerifyError::noClassDefFound); + + AttributeExceptions *exception = new (p) AttributeExceptions(p, length); + ConstantClass **exceptionList; + + if (!exception->setNumExceptions(numExceptions)) + verifyError(VerifyError::noClassDefFound); + + exceptionList = exception->getExceptions(); + + for (int i = 0; i < numExceptions; i++) { + Uint16 index; + + if (!reader->readU2(&index, 1)) + verifyError(VerifyError::noClassDefFound); + + if (invalidAttribute(index, CR_CONSTANT_CLASS)) + verifyError(VerifyError::noClassDefFound); + + exceptionList[i] = (ConstantClass *) constantPool->get(index); + } + + return exception; +} + + +/* Implementation of AttributeHandlerDummy */ +AttributeInfoItem *AttributeHandlerDummy::handle(const char *_name) +{ + Uint32 length; + if (!validateNameAndLength(_name, &length)) + return 0; + + char *data = new (p) char[length]; + + /* Read the data */ + if (!reader->readU1(data, length)) + verifyError(VerifyError::noClassDefFound); + + AttributeInfoItem *item = new (p) AttributeInfoItem(p, name, 0, length); + return item; +} diff --git a/ef/Runtime/ClassReader/AttributeHandlers.h b/ef/Runtime/ClassReader/AttributeHandlers.h new file mode 100644 index 000000000000..8ab8f8cdc457 --- /dev/null +++ b/ef/Runtime/ClassReader/AttributeHandlers.h @@ -0,0 +1,174 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#ifndef _CR_ATTRIBUTEHANDLERS_H_ +#define _CR_ATTRIBUTEHANDLERS_H_ + +#include "ClassReader.h" +#include "FileReader.h" + + +/* An Attribute handler is responsible for parsing and allocating + * a particular attribute + */ +class AttributeHandler { +public: + AttributeHandler(Pool &p, FileReader *_reader, ClassFileReader *_cfr, + const char *_name); + + /* The handle() method determines whether or not it can handle an + * attribute whose name is _name. If it can, then it further parses the + * file and returns a pointer to the attribute. Else, returns NULL + */ + virtual AttributeInfoItem *handle(const char *_name) = 0; + + /* Get name of attribute that this handler will handle */ + const char *getName() const { + return name; + } + + FileReader *getReader() const { + return reader; + } + + ClassFileReader *getClassReader() const { + return cfr; + } + +protected: + Pool &p; + const char *name; + FileReader *reader; + ClassFileReader *cfr; + const ConstantPool *constantPool; + + int validateNameAndLength(const char *_name, Uint32 *length); + + bool invalidIndex(Uint32 index) const { + return index < 1 || index >= constantPool->count(); + } + + bool invalidAttribute(int index, int type) const { + return (invalidIndex(index) || constantPool->get(index)->getType() != type); + } +}; + +/* The following classes handle various attributes that we are + * currently interested in. + */ +class AttributeHandlerSourceFile : public AttributeHandler { +public: + AttributeHandlerSourceFile(Pool &pool, FileReader *_reader, + ClassFileReader *_cfr): + AttributeHandler(pool, _reader, _cfr, "SourceFile") { + + } + + virtual AttributeInfoItem *handle(const char *_name); + +private: +}; + + +class AttributeHandlerConstantValue : public AttributeHandler { +public: + AttributeHandlerConstantValue(Pool &pool, + FileReader *_reader, ClassFileReader *_cfr): + AttributeHandler(pool, _reader, _cfr, "ConstantValue") { + + } + + virtual AttributeInfoItem *handle(const char *_name); + +private: +}; + + +class AttributeHandlerCode : public AttributeHandler { +public: + AttributeHandlerCode(Pool &pool, + FileReader *_reader, ClassFileReader *_cfr): + AttributeHandler(pool, _reader, _cfr, "Code") { + + } + + virtual AttributeInfoItem *handle(const char *_name); + +private: +}; + + +class AttributeHandlerLineNumberTable : public AttributeHandler { +public: + AttributeHandlerLineNumberTable(Pool &pool, + FileReader *_reader, + ClassFileReader *_cfr): + AttributeHandler(pool, _reader, _cfr, "LineNumberTable") { + + } + + virtual AttributeInfoItem *handle(const char *_name); + +private: + +}; + + +class AttributeHandlerLocalVariableTable : public AttributeHandler { +public: + AttributeHandlerLocalVariableTable(Pool &pool, FileReader *_reader, + ClassFileReader *_cfr): + AttributeHandler(pool, _reader, _cfr, "LocalVariableTable") { + + } + + virtual AttributeInfoItem *handle(const char *_name); + +private: + +}; + + +class AttributeHandlerExceptions : public AttributeHandler { +public: + AttributeHandlerExceptions(Pool &pool, FileReader *_reader, + ClassFileReader *_cfr): + AttributeHandler(pool, _reader, _cfr, "Exceptions") { + + } + + virtual AttributeInfoItem *handle(const char *_name); + +private: + +}; + +/* This handles attributes that we don't know (or care) about */ +class AttributeHandlerDummy : public AttributeHandler { +public: + AttributeHandlerDummy(Pool &pool, + FileReader *_reader, ClassFileReader *_cfr): + AttributeHandler(pool, _reader, _cfr, 0) { + + } + + virtual AttributeInfoItem *handle(const char *_name); + +private: +}; + +#endif /* _CR_ATTRIBUTEHANDLERS_H_ */ diff --git a/ef/Runtime/ClassReader/Attributes.h b/ef/Runtime/ClassReader/Attributes.h new file mode 100644 index 000000000000..f4c4096d8fc2 --- /dev/null +++ b/ef/Runtime/ClassReader/Attributes.h @@ -0,0 +1,373 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#ifndef _CR_ATTRIBUTES_H_ +#define _CR_ATTRIBUTES_H_ + +#include "ConstantPool.h" +#include "DoublyLinkedList.h" +#include "LogModule.h" + +UT_EXTERN_LOG_MODULE(Debugger); + +/* Attribute tags for handlers that we know (care) about */ +#define CR_ATTRIBUTE_SOURCEFILE 1 +#define CR_ATTRIBUTE_CONSTANTVALUE 2 +#define CR_ATTRIBUTE_LINENUMBERTABLE 3 +#define CR_ATTRIBUTE_LOCALVARIABLETABLE 4 +#define CR_ATTRIBUTE_CODE 5 +#define CR_ATTRIBUTE_EXCEPTIONS 6 + + +class AttributeInfoItem : public DoublyLinkedEntry { +public: + AttributeInfoItem(Pool &pool, + const char *nameInfo, Uint32 _code, Uint32 _length) : + p(pool), name(nameInfo), length(_length), code(_code) { } + + Uint32 getLength() const { + return length; + } + + const char *getName() const { + return name; + } + + Uint32 getCode() const { + return code; + } + +#ifdef DEBUG + virtual void dump(int /*nIndents*/) const { + + } +#endif + +protected: + Pool &p; + +private: + const char *name; + Uint32 length; + Uint32 code; +}; + + +class AttributeSourceFile : public AttributeInfoItem { + friend class ClassFileReader; +public: + AttributeSourceFile(Pool &pool, ConstantUtf8 *utf8) : + AttributeInfoItem(pool, "SourceFile", CR_ATTRIBUTE_SOURCEFILE, 2) { + srcName = utf8; + } + + ConstantUtf8 *getSrcName() const { + return srcName; + } + +#ifdef DEBUG + virtual void dump(int nIndents) const; +#endif + +private: + ConstantUtf8 *srcName; +}; + + +class AttributeConstantValue : public AttributeInfoItem { +public: + AttributeConstantValue(Pool &pool, ConstantPoolItem *val, Int16 index) : + AttributeInfoItem(pool, "ConstantValue", CR_ATTRIBUTE_CONSTANTVALUE, 2), value(val), cindex(index) { } + + + ConstantPoolItem *getValue() const { + return value; + } + + Uint16 getConstantPoolIndex() const { + return cindex; + } + +#ifdef DEBUG + virtual void dump(int nIndents) const; +#endif + +private: + ConstantPoolItem *value; + Uint16 cindex; +}; + + +struct ExceptionItem { +#ifdef DEBUG + void dump(int nIndents) const; +#endif + + Uint16 startPc, endPc, handlerPc, catchType; +}; + + +class AttributeCode : public AttributeInfoItem { + +public: + AttributeCode(Pool &pool, Uint16 _length, + Uint16 _maxStack, Uint16 _maxLocals, Uint32 _codeLength); + + bool setNumExceptions(Uint32 _numExceptions); + + bool setNumAttributes(Uint32 _numAttributes); + + /* Get the size of the code */ + Uint32 getCodeLength() const { + return codeLength; + } + + Uint32 getMaxStack() const { + return maxStack; + } + + Uint32 getMaxLocals() const { + return maxLocals; + } + + Uint32 getNumExceptions() const { + return numExceptions; + } + + const ExceptionItem *getExceptions() const { + return exceptions; + } + + Uint32 getNumAttributes() const { + return numAttributes; + } + + const AttributeInfoItem **getAttributes() const { + return attributes; + } + + /* Looks up an attribute by attribute-name */ + const AttributeInfoItem *getAttribute(const char *_name) const; + + const char *getCode() const { + return (const char *) code; + } + +#ifdef DEBUG + virtual void dump(int nIndents) const; +#endif + +private: + Uint32 maxStack, maxLocals, codeLength, numExceptions; + char *code; + const ExceptionItem *exceptions; + Uint32 numAttributes; + const AttributeInfoItem **attributes; +}; + +class AttributeExceptions : public AttributeInfoItem { +friend class AttributeHandlerExceptions; +public: + AttributeExceptions(Pool &pool, Uint32 _length) : + AttributeInfoItem(pool, "Exceptions", CR_ATTRIBUTE_EXCEPTIONS, _length) { + numExceptions = 0, exceptions = 0; + } + + Uint32 getNumExceptions() const { + return numExceptions; + } + + ConstantClass **getExceptions() const { + return exceptions; + } + + bool setNumExceptions(Uint32 n); + +#ifdef DEBUG + virtual void dump(int nIndents) const; +#endif + +private: + Uint32 numExceptions; + ConstantClass **exceptions; +}; + +typedef struct { + Uint16 startPc; + Uint16 lineNumber; + +#ifdef DEBUG_LOG + void dump(int nIndents) const { + print(nIndents, "startPc %d lineNumber %d", startPc, lineNumber); + } +#endif + +} LineNumberEntry; + + +class AttributeLineNumberTable : public AttributeInfoItem { +public: + AttributeLineNumberTable(Pool &pool, Uint32 _length) : + AttributeInfoItem(pool, "LineNumberTable", CR_ATTRIBUTE_LINENUMBERTABLE, + _length) { + numEntries = 0, entries = 0; + } + + bool setNumEntries(Uint32 n); + + Uint32 getNumEntries() const { + return numEntries; + } + + LineNumberEntry *getEntries() const { + return entries; + } + + /* returns the Pc value corresponding to lineNumber, -1 if not found */ + Int32 getPc(Uint32 lineNumber); + +#ifdef DEBUG + virtual void dump(int nIndents) const; +#endif + +private: + Uint32 numEntries; + LineNumberEntry *entries; +}; + +class VariableLocation { + bool inRegister; // Is this variable in a register ? + bool invalid; // The variable is dead at this point + + union { + Uint8 reg; + Uint8 mem; // Need to decide a good way to represent a + // memory address. + }; + + public: + +#ifdef DEBUG_LOG + void dump() { + UT_LOG(Debugger, PR_LOG_ALWAYS, ("inreg: %d, reg: %d\n", inRegister, + reg)); + } +#endif + + VariableLocation() { + invalid = true; + } + + VariableLocation(bool _inRegister, Uint8 _reg) { + inRegister = _inRegister; + reg = _reg; + invalid = false; + } + +}; + +// +// Interval mapping is a mapping from a contiguous block of native code to a +// physical location, where the value of a given local variable may be found. +// +class IntervalMapping : public DoublyLinkedEntry { + public: + + VariableLocation &getVariableLocation() { return loc; }; + void setVariableLocation(VariableLocation l) { loc = l; }; + + IntervalMapping() : loc(VariableLocation(false, (Uint8) 0)) {}; + void setStart(Uint32 _start) { start = _start; } + void setEnd(Uint32 _end) { end = _end; } + +#ifdef DEBUG_LOG + void dump() { + UT_LOG(Debugger, PR_LOG_ALWAYS, ("start: %d, end: %d\n", start, end)); + loc.dump(); + } +#endif + + private: + VariableLocation loc; + Uint32 start; // The mapping is from the interval [start, end) + Uint32 end; + +}; + +typedef struct { + Uint16 startPc; + Uint16 length; + ConstantUtf8 *name; + ConstantUtf8 *descriptor; + Uint16 index; + DoublyLinkedList mappings; + +#ifdef DEBUG + void dump(int nIndents) const { + print(nIndents, + "startPc %d length %d index %d name %s desc %d", startPc, length, + index, name->getUtfString(), descriptor->getUtfString()); + } +#endif + +#ifdef DEBUG_LOG + void dump() { + UT_LOG(Debugger, PR_LOG_ALWAYS, ("name: %s, startpc: %d, length: %d, " + "index %d\n", name->getUtfString(), startPc, length, index)); + } +#endif +} LocalVariableEntry; + + +class AttributeLocalVariableTable : public AttributeInfoItem { +friend class ClassFileReader; + +public: + AttributeLocalVariableTable(Pool &pool, Uint32 _length) : + AttributeInfoItem(pool, "LocalVariableTable", + CR_ATTRIBUTE_LOCALVARIABLETABLE, + _length) { + entries = 0; + } + + + bool setNumEntries(Uint32 n); + + Uint32 getNumEntries() const { + return numEntries; + } + + LocalVariableEntry *getEntries() const { + return entries; + } + + LocalVariableEntry *getEntry(const char *name); + LocalVariableEntry *getEntry(Uint16 index); + LocalVariableEntry& getEntryByNumber(Uint32 index) { return entries[index]; } + +#ifdef DEBUG + virtual void dump(int nIndents) const; +#endif + +private: + Uint32 numEntries; + LocalVariableEntry *entries; +}; + + + +#endif /* _CR_ATTRIBUTES_H_ */ diff --git a/ef/Runtime/ClassReader/ClassReader.cpp b/ef/Runtime/ClassReader/ClassReader.cpp new file mode 100644 index 000000000000..f919cafd1982 --- /dev/null +++ b/ef/Runtime/ClassReader/ClassReader.cpp @@ -0,0 +1,1405 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#include "ClassReader.h" + + +#include "AttributeHandlers.h" +#include "ErrorHandling.h" +#include "DebugUtils.h" +#include "LogModule.h" + +#include +#include "plstr.h" + +UT_DEFINE_LOG_MODULE(ClassReader); + +#ifdef DEBUG_LOG +#include + +void indent(int n) +{ + for (; n; n--) + UT_LOG(ClassReader, PR_LOG_ALWAYS, (" ")); +} + +void title(int nIndents, const char *s) +{ + indent(nIndents); + UT_LOG(ClassReader, PR_LOG_ALWAYS, ("%s\n", s)); +} + +void print(int nIndents, const char *fmt, ...) +{ + va_list args; + static char buffer[2048]; + + indent(nIndents); + va_start(args, fmt); + vsprintf(buffer, fmt, args); // FIX-ME use the mallocing sprintf + va_end(args); + + UT_LOG(ClassReader, PR_LOG_ALWAYS, ("%s\n", buffer)); +} +#endif + + + +/* Implementation of ConstantPool */ +#ifdef DEBUG_LOG +// +// Print the given item of the constant pool in a compact format, never +// spanning more than one line and not including a trailing newline. +// print ???? if there is no such item. +// +void ConstantPool::printItem(LogModuleObject &f, Uint32 index) const +{ + if (index == 0) + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("NIL")); + else if (index < numItems && items[index]) + items[index]->print(f); + else + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("????")); +} +#endif + + +#ifdef DEBUG +/* Implementation of ConstantPoolItem */ +void ConstantPoolItem::dump(int indent) const +{ + ::print(indent, "Unknown item %d", type); +} +#endif + +#ifdef DEBUG_LOG +// +// Print this constant pool item in a compact format, never +// spanning more than one line and not including a trailing newline. +// +void ConstantPoolItem::print(LogModuleObject &f) const +{ + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("???? item %d", type)); +} +#endif + + +/* Implementation of ConstantUtf8 */ +ConstantUtf8::ConstantUtf8(Pool &pool, const char *str, Uint32 len) : + ConstantPoolItem(pool, CR_CONSTANT_UTF8) +{ + data = str; + dataLen = len; +} + +#ifdef DEBUG_LOG +void ConstantUtf8::dump(int nIndents) const +{ + title(nIndents, "CONSTANT_UTF8"); + ::print(nIndents, "String: %s", data); +} + +void ConstantUtf8::print(LogModuleObject &f) const +{ + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("%s", data)); +} +#endif + + +/* Implementation of ConstantClass */ +bool ConstantClass::resolveAndValidate() +{ + if (pool) + utfString = (ConstantUtf8 *) pool->get(index); + + return (utfString && utfString->getType() == CR_CONSTANT_UTF8); +} + +#ifdef DEBUG +void ConstantClass::dump(int nIndents) const +{ + title(nIndents, "CONSTANT_CLASS"); + utfString->dump(nIndents+1); +} +#endif + +#ifdef DEBUG_LOG +void ConstantClass::print(LogModuleObject &f) const +{ + utfString->print(f); +} +#endif + +/* Implementation of ConstantNameAndType */ +bool ConstantNameAndType::resolveAndValidate() +{ + if (pool) { + nameInfo = (ConstantUtf8 *) pool->get(nameIndex); + descInfo = (ConstantUtf8 *) pool->get(descIndex); + } + + return (nameInfo && descInfo && + nameInfo->getType() == CR_CONSTANT_UTF8 && + descInfo->getType() == CR_CONSTANT_UTF8); +} + +#ifdef DEBUG +void ConstantNameAndType::dump(int nIndents) const +{ + title(nIndents, "CONSTANT_NAMEANDTYPE (name/desc)"); + nameInfo->dump(nIndents+1); + descInfo->dump(nIndents+1); +} +#endif + +#ifdef DEBUG_LOG +void ConstantNameAndType::print(LogModuleObject &f) const +{ + nameInfo->print(f); + UT_OBJECTLOG(f, PR_LOG_ALWAYS, (":")); + descInfo->print(f); +} +#endif + +ConstantNameAndType::ConstantNameAndType(Pool &pool, + ConstantPool *array, + Uint16 nindex, Uint16 dIndex) : + ConstantPoolItem(pool, CR_CONSTANT_NAMEANDTYPE), pool(array) +{ + nameIndex = nindex, descIndex = dIndex; + nameInfo = descInfo = 0; +} + +/* Implementation of ConstantRef */ +bool ConstantRef::resolveAndValidate() +{ + if (pool) { + classInfo = (ConstantClass *) pool->get(classIndex); + typeInfo = (ConstantNameAndType *) pool->get(typeIndex); + } + + return (classInfo && typeInfo && + classInfo->getType() == CR_CONSTANT_CLASS && + typeInfo->getType() == CR_CONSTANT_NAMEANDTYPE); +} + +#ifdef DEBUG +void ConstantRef::dump(int nIndents) const +{ + ::print(nIndents+2, "Printing ClassInfo and typeInfo"); + classInfo->dump(nIndents+1); + typeInfo->dump(nIndents+1); +} +#endif + +#ifdef DEBUG_LOG +void ConstantRef::print(LogModuleObject &f) const +{ + classInfo->print(f); + UT_OBJECTLOG(f, PR_LOG_ALWAYS, (".")); + typeInfo->print(f); +} +#endif + +ConstantRef::ConstantRef(Pool &pool, + Uint8 _type, ConstantPool *array, Uint16 cIndex, + Uint16 tIndex) : ConstantPoolItem(pool, _type), pool(array) +{ + classIndex = cIndex, typeIndex = tIndex; + classInfo = 0; + typeInfo = 0; +} + +/* Implementation of ConstantFieldRef */ +#ifdef DEBUG +void ConstantFieldRef::dump(int nIndents) const +{ + title(nIndents, "CONSTANT_FIELD_REF"); + ConstantRef::dump(nIndents); +} + +/* Implementation of ConstantMethodRef */ +void ConstantMethodRef::dump(int nIndents) const { + title(nIndents, "CONSTANT_METHOD_REF"); + ConstantRef::dump(nIndents); +} + +/* Implementation of class ConstantInterfaceMethodRef */ +void ConstantInterfaceMethodRef::dump(int nIndents) const { + title(nIndents, "CONSTANT_INTERFACEMETHOD_REF"); + ConstantRef::dump(nIndents); + } +#endif + +/* Implementation of ConstantString */ +bool ConstantString::resolveAndValidate() +{ + if (pool) + utfString = (ConstantUtf8 *) pool->get(index); + + return (utfString && utfString->getType() == CR_CONSTANT_UTF8); +} + +#ifdef DEBUG +void ConstantString::dump(int nIndents) const +{ + title(nIndents, "CONSTANT_STRING"); + utfString->dump(nIndents+1); +} +#endif + +#ifdef DEBUG_LOG +void ConstantString::print(LogModuleObject &f) const +{ + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("\"")); + utfString->print(f); + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("\"")); +} +#endif + +/* Implementation of ConstantVal */ +#ifdef DEBUG_LOG +void ConstantVal::dump(int nIndents) const +{ + switch (vk) { + case vkInt: + title(nIndents, "CONSTANT_INT"); + ::print(nIndents, "Value: %d", value.i); + break; + + case vkFloat: + title(nIndents, "CONSTANT_FLOAT"); + ::print(nIndents, "Value: %f", value.f); + break; + + case vkDouble: + title(nIndents, "CONSTANT_DOUBLE"); + ::print(nIndents, "Value: %lf", value.d); + break; + + case vkLong: + title(nIndents, "CONSTANT_LONG"); + indent(nIndents); + printInt64(UT_LOG_MODULE(ClassReader), value.l); + UT_LOG(ClassReader, PR_LOG_ALWAYS, ("\n")); + break; + + default: + break; + } +} +#endif + +#ifdef DEBUG_LOG +void ConstantVal::print(LogModuleObject &f) const +{ + value.print(f, vk); +} +#endif + +/* Implementation of ConstantFloat */ +ConstantFloat::ConstantFloat(Pool &pool, Uint32 raw): + ConstantVal(pool, CR_CONSTANT_FLOAT, vkFloat) +{ + + value.setValueContents(*((Flt32 *) &raw)); + +#if 0 + if (raw == 0x7f80000) + value.setValueContents(floatPositiveInfinity); + else if (raw == 0xff800000) + value.setValueContents(floatNegativeInfinity); + else if ((raw >= 0x7f800001 && raw <= 0x7fffffff) || + (raw >= 0xff800001 && raw <= 0xffffffff)) + value.setValueContents(floatNaN); + else { + + Uint32 s = ((raw >> 31) == 0) ? 1 : -1; + Uint32 e = ((raw >> 23) &0xff); + Uint32 m = (e == 0) ? (raw & 0x7fffff) << 1: + (raw & 0x7fffff) | 0x800000; + + value.setValueContents((Flt32) s * m * pow(2.0, (double)e-150)); + } +#endif +} + +/* Implementation of ConstantLong */ +ConstantLong::ConstantLong(Pool &pool, Uint32 lo, Uint32 hi) : + ConstantVal(pool, CR_CONSTANT_LONG, vkLong) +{ +#ifdef HAVE_LONG_LONG + Int64 lw, llo, lhi; + + llo = (Int64) lo; + lhi = (Int64) hi; + lhi <<= 32; + + lw = llo | lhi; + + value.setValueContents(lw); +#else + value.l.lo = lo; + value.l.hi = hi; +#endif +} + + +/* Implementation of ConstantDouble */ +ConstantDouble::ConstantDouble(Pool &pool, char *data): + ConstantVal(pool, CR_CONSTANT_DOUBLE, vkDouble) +{ + union { + unsigned char c[8]; + Flt64 d; + } u; + +#ifdef IS_LITTLE_ENDIAN + u.c[0] = data[7]; + u.c[1] = data[6]; + u.c[2] = data[5]; + u.c[3] = data[4]; + + u.c[4] = data[3]; + u.c[5] = data[2]; + u.c[6] = data[1]; + u.c[7] = data[0]; +#else + u.c[0] = data[0]; + u.c[1] = data[1]; + u.c[2] = data[2]; + u.c[3] = data[3]; + + u.c[4] = data[4]; + u.c[5] = data[5]; + u.c[6] = data[6]; + u.c[7] = data[7]; +#endif + value.d = u.d; +} + +/* Implementation of AttributeSourceFile */ +#ifdef DEBUG_LOG +void AttributeSourceFile::dump(int nIndents) const { + title(nIndents, "SOURCE-FILE"); + srcName->dump(nIndents+1); +} +#endif + +/* Implementation of AttributeConstantValue */ +#ifdef DEBUG_LOG +void AttributeConstantValue::dump(int nIndents) const +{ + title(nIndents, "CONSTANT-VALUE"); + value->dump(nIndents+1); +} +#endif + +#ifdef DEBUG +void ExceptionItem::dump(int nIndents) const { + title(nIndents, "ExceptionItem"); + print(nIndents+1, + "Start %u End %u Handler %u Catcher %u", startPc, endPc, + handlerPc, catchType); +} +#endif + +/* Implementation of AttributeCode */ +AttributeCode::AttributeCode(Pool &pool, Uint16 _length, + Uint16 _maxStack, Uint16 _maxLocals, + Uint32 _codeLength) : + AttributeInfoItem(pool, "Code", CR_ATTRIBUTE_CODE, _length) +{ + maxStack = _maxStack, maxLocals = _maxLocals, + codeLength = _codeLength; + + numExceptions = 0; + exceptions = 0; + numAttributes = 0; + attributes = 0; + + if (codeLength > 0) + code = new (p) char[codeLength]; + else + code = 0; +} + +bool AttributeCode::setNumExceptions(Uint32 _numExceptions) +{ + exceptions = new (p) ExceptionItem[_numExceptions]; + numExceptions = _numExceptions; + return true; +} + +bool AttributeCode::setNumAttributes(Uint32 _numAttributes) +{ + attributes = new (p) const AttributeInfoItem *[_numAttributes]; + numAttributes = _numAttributes; + return true; +} + +const AttributeInfoItem * +AttributeCode::getAttribute(const char *_name) const +{ + for (Uint32 i = 0; i < numAttributes; i++) { + const AttributeInfoItem &attribute = *attributes[i]; + + if (!(PL_strncmp(_name, attribute.getName(), attribute.getLength()))) + return &attribute; + } + + return NULL; +} + +#ifdef DEBUG +void AttributeCode::dump(int nIndents) const { + Uint32 i; + + title(nIndents, "CODE"); + ::print(nIndents, + "maxStack %u maxLocals %u codeLength %u numExceptions %u", + maxStack, maxLocals, codeLength, numExceptions); + + if (numExceptions > 0) { + title(nIndents, "Exceptions"); + for (i = 0; i < numExceptions; i++) + exceptions[i].dump(nIndents+1); + } + + if (numAttributes > 0) { + title(nIndents, "Attributes"); + for (i = 0; i < numAttributes; i++) + attributes[i]->dump(nIndents+1); + } +} +#endif + +/* Implementation of AttributeExceptions */ +bool AttributeExceptions::setNumExceptions(Uint32 n) +{ + exceptions = new (p) ConstantClass *[n]; + numExceptions = n; + return true; +} + +#ifdef DEBUG +void AttributeExceptions::dump(int nIndents) const +{ + Uint32 i; + + title(nIndents, "EXCEPTIONS"); + ::print(nIndents, "numExceptions %d", numExceptions); + + if (numExceptions > 0) { + title(nIndents, "Exceptions"); + for (i = 0; i < numExceptions; i++) + exceptions[i]->dump(nIndents+1); + } +} +#endif + +/* Implementation of AttributeLineNumberTable */ +bool AttributeLineNumberTable::setNumEntries(Uint32 n) +{ + entries = new (p) LineNumberEntry[n]; + numEntries = n; + return true; +} + +Int32 AttributeLineNumberTable::getPc(Uint32 lineNumber) { + Uint32 i; + + /* The line numbers are not guaranteed to be in order */ + for (i = 0; i < numEntries; i++) + if (entries[i].lineNumber == lineNumber) + return entries[i].startPc; + + return -1; +} + +#ifdef DEBUG +void AttributeLineNumberTable::dump(int nIndents) const +{ + title(nIndents, "LINE-NUMBER-ENTRY"); + + for (Uint32 i = 0; i < numEntries; i++) + entries[i].dump(nIndents+1); +} +#endif + + +/* Implementation of AttributeLocalVariableTable */ +bool AttributeLocalVariableTable::setNumEntries(Uint32 n) { + entries = new (p) LocalVariableEntry[n]; + numEntries = n; + return true; +} + +// +// Looks up a local variable by name +// Returns a pointer to the LocalVariableEntry or NULL if not found +// +LocalVariableEntry * +AttributeLocalVariableTable::getEntry(const char *name) +{ + for (Uint32 i=0; i < numEntries; i++) { + if (PL_strcmp(entries[i].name->getUtfString(), name) == 0) + return &entries[i]; + } + + return NULL; +} + +// +// Looks up a local variable by index +// Returns a pointer to the LocalVariableEntry or NULL if not found +// +LocalVariableEntry * +AttributeLocalVariableTable::getEntry(Uint16 index) +{ + for (Uint32 i=0; i < numEntries; i++) { + if (entries[i].index == index) + return &entries[i]; + } + + return NULL; +} + +#ifdef DEBUG +void AttributeLocalVariableTable::dump(int nIndents) const +{ + title(nIndents, "LOCAL-VARIABLE-TABLE"); + + for (Uint32 i = 0; i < numEntries; i++) + entries[i].dump(nIndents+1); +} +#endif + +/* Implementation of InfoItem */ +InfoItem::InfoItem(Pool &pool, Uint16 aflags, ConstantUtf8 *classInfo, + ConstantUtf8 *nameInfo, + ConstantUtf8 *descInfo) : p(pool) +{ + accessFlags = aflags; + name = nameInfo; + descriptor = descInfo; + className = classInfo; + attrCount = 0; +} + +bool InfoItem::addAttribute(AttributeInfoItem &attribute) +{ + attributes.addLast(attribute); + attrCount++; + return true; +} + +AttributeInfoItem *InfoItem::getAttribute(const char *_name) const +{ + for (DoublyLinkedList::iterator i = attributes.begin(); + !attributes.done(i); i = attributes.advance(i)) { + AttributeInfoItem &attribute = attributes.get(i); + + if (!(PL_strncmp(_name, attribute.getName(), attribute.getLength()))) + return &attribute; + } + + return 0; +} + +AttributeInfoItem *InfoItem::getAttribute(const Uint32 code) const +{ + for (DoublyLinkedList::iterator i = attributes.begin(); + !attributes.done(i); i = attributes.advance(i)) { + AttributeInfoItem &attribute = attributes.get(i); + + if (attribute.getCode() == code) + return &attribute; + } + + return 0; +} + + +#ifdef DEBUG_LOG +void InfoItem::dump(int nIndents) const +{ + print(nIndents, "%s() descriptor:%s", + name->getUtfString(), descriptor->getUtfString()); + print(nIndents, "AccessFlags %x attrCount %d", + accessFlags, attrCount); + + if (attrCount > 0) { + print(nIndents, "-> Attributes (%d):", attrCount); + for (DoublyLinkedList::iterator i = + attributes.begin(); + !attributes.done(i); i = attributes.advance(i)) + attributes.get(i).dump(nIndents+1); + } +} +#endif + +/* Implementation of FieldInfo */ +void FieldInfo::getInfo(const char *&sig, + bool &isVolatile, bool &isConstant, + bool &isStatic) const +{ + Uint16 aFlags = getAccessFlags(); + + isVolatile = (aFlags & CR_FIELD_VOLATILE) != 0; + isConstant = false; + isStatic = (aFlags & CR_FIELD_STATIC) != 0; + sig = getDescriptor()->getUtfString(); +} + + +#ifdef DEBUG_LOG +void FieldInfo::dump(int nIndents) const +{ + InfoItem::dump(nIndents); + + if (getAccessFlags() & CR_FIELD_STATIC) + print(nIndents, "Field is STATIC"); + else + print(nIndents, "Field is an instance field"); + +} +#endif + +/* Implementation of MethodInfo */ +void MethodInfo::getInfo(const char *&sig, + bool &isAbstract, bool &isStatic, + bool &isFinal, bool &isSynchronized, + bool &isNative) const +{ + sig = getDescriptor()->getUtfString(); + Uint16 aFlags = getAccessFlags(); + isAbstract = (aFlags & CR_METHOD_ABSTRACT) != 0; + isStatic = (aFlags & CR_METHOD_STATIC) != 0; + isFinal = (aFlags & CR_METHOD_FINAL) != 0; + isSynchronized = (aFlags & CR_METHOD_SYNCHRONIZED) != 0; + isNative = (aFlags & CR_METHOD_NATIVE) != 0; +} + + +/* Implementation of ClassFileReader */ +/* Look up a constant of type integer, long, float, or double in + * the constant pool of the class. Returns true on success, + * false if it couldn't find the field or on error. + */ +bool ClassFileReader::lookupConstant(Uint16 index, ValueKind &vk, + Value &value) const +{ + if (index < 1 || index >= constantPool->count()) + return false; + + /* Are we dealing with a constant that returns a value? */ + int type = constantPool->get(index)->getType(); + + /* String constants */ + if (type == CR_CONSTANT_STRING) { + vk = vkAddr; + + ConstantString *str = (ConstantString *) constantPool->get(index); + JavaString *string = sp.getStringObj(str->getUtf()->getUtfString()); + assert(string); + value.a = staticAddress((void *) string); + return true; + } + + /* If we're here, index must point to a long, float, double, or integer */ + if (!((type > 2 && type < 7))) + return false; + + ConstantVal *val = (ConstantVal *) constantPool->get(index); + vk = val->getValueKind(); + value = val->getValue(); + + return true; +} + +#ifdef DEBUG_LOG +void ClassFileReader::dump() const +{ + Uint32 i; + + print(0, "AccessFlags %x", accessFlags); + print(0, "Major Version %d, Minor Version %d", majorVersion, + minorVersion); + + print(0, "\nThis Class:"); + constantPool->get(thisClassIndex)->dump(0); + + if (superClassIndex > 0) { + print(0, "\nSuper Class:"); + constantPool->get(superClassIndex)->dump(0); + } + + print(0, "\nConstant Pool Count: %d", constantPool->count()); + for (i = 1; i < constantPool->count(); i++) { + print(0, "%d.", i); + + if (constantPool->get(i)) + constantPool->get(i)->dump(0); + else + print(0, "NULL Constant-pool entry, probably result of a previous\n" + "DOUBLE or LONG"); + } + + print(0, "\nField Count: %d", fieldCount); + for (i = 0; i < fieldCount; i++) { + print(0, "%d.", i+1); + fieldInfo[i]->dump(0); + } + + print(0, "\nInterface Count: %d", interfaceInfo->count()); + for (i = 0; i < interfaceInfo->count(); i++) { + print(0, "%d.", i+1); + interfaceInfo->get(i)->dump(0); + } + + print(0, "\nMethod Count: %d", methodCount); + for (i = 0; i < methodCount; i++) { + print(0, "%d.", i+1); + methodInfo[i]->dump(0); + } +} +#endif + +#define CR_BUFFER_SIZE 16184 + + +#define JAVA_MAGIC 0xCAFEBABE + +/* Reads and parses the constant pool section of the class file. + * constantPoolCount must have been initialized and the constantPool + * array (but not its elements) allocated before calling this. + */ +void ClassFileReader::readConstantPool() +{ + Uint16 cIndex, tIndex; + Uint16 index; + Uint32 low, high; + Uint32 i; + constantPool->set(0, 0); + + Uint32 constantPoolCount = constantPool->count(); + + for (i = 1; i < constantPoolCount; i++) { + char tag; + + if (!fr.readU1(&tag, 1)) + verifyError(VerifyError::noClassDefFound); + + switch (tag) { + case CR_CONSTANT_UTF8: { + Uint16 len; + + if (!fr.readU2(&len, 1)) + verifyError(VerifyError::noClassDefFound); + + char *buf = new char[len+1]; + fr.readU1(buf, len); + buf[len] = 0; + + const char *str = sp.intern(buf); + delete [] buf; + ConstantUtf8 *utf = new (p) ConstantUtf8(p, str, len); + + constantPool->set(i, utf); + break; + } + + case CR_CONSTANT_INTEGER: { + Int32 val; + + + if (!fr.readU4((Uint32 *) &val, 1)) + verifyError(VerifyError::noClassDefFound); + + constantPool->set(i, new (p) ConstantInt(p, val)); + break; + } + + case CR_CONSTANT_FLOAT: { + Uint32 raw; + + if (!fr.readU4(&raw, 1)) + verifyError(VerifyError::noClassDefFound); + + constantPool->set(i, new (p) ConstantFloat(p, raw)); + break; + } + + case CR_CONSTANT_LONG: + if (!fr.readU4(&high, 1)) + verifyError(VerifyError::noClassDefFound); + + if (!fr.readU4(&low, 1)) + verifyError(VerifyError::noClassDefFound); + + constantPool->set(i, new (p) ConstantLong(p, low, high)); + constantPool->set(i+1, 0); + + /* Longs and doubles take up two constant-pool entries */ + i++; + break; + + case CR_CONSTANT_DOUBLE: { + char buf[8]; + + if (!fr.readU1(buf, 8)) + verifyError(VerifyError::noClassDefFound); + + constantPool->set(i, new (p) ConstantDouble(p, buf)); + constantPool->set(i+1, 0); + + /* Longs and doubles take up two constant-pool entries */ + i++; + break; + } + + case CR_CONSTANT_CLASS: + if (!fr.readU2(&index, 1)) + verifyError(VerifyError::noClassDefFound); + + if (invalidIndex(index)) + verifyError(VerifyError::noClassDefFound); + + constantPool->set(i, new (p) ConstantClass(p, constantPool, index)); + break; + + case CR_CONSTANT_STRING: + if (!fr.readU2(&index, 1)) + verifyError(VerifyError::noClassDefFound); + + if (invalidIndex(index)) + verifyError(VerifyError::noClassDefFound); + + constantPool->set(i, new (p) ConstantString(p, constantPool, index)); + break; + + + case CR_CONSTANT_FIELDREF: + if (!fr.readU2(&cIndex, 1)) + verifyError(VerifyError::noClassDefFound); + + if (!fr.readU2(&tIndex, 1)) + verifyError(VerifyError::noClassDefFound); + + if (invalidIndex(cIndex) || invalidIndex(tIndex)) + verifyError(VerifyError::noClassDefFound); + + constantPool->set(i, new (p) ConstantFieldRef(p, constantPool, + cIndex, tIndex)); + break; + + case CR_CONSTANT_METHODREF: + if (!fr.readU2(&cIndex, 1)) + verifyError(VerifyError::noClassDefFound); + + if (!fr.readU2(&tIndex, 1)) + verifyError(VerifyError::noClassDefFound); + + if (invalidIndex(cIndex) || invalidIndex(tIndex)) + verifyError(VerifyError::noClassDefFound); + + constantPool->set(i, new (p) ConstantMethodRef(p, constantPool, + cIndex, tIndex)); + break; + + case CR_CONSTANT_INTERFACEMETHODREF: + if (!fr.readU2(&cIndex, 1)) + verifyError(VerifyError::noClassDefFound); + + if (!fr.readU2(&tIndex, 1)) + verifyError(VerifyError::noClassDefFound); + + if (invalidIndex(cIndex) || invalidIndex(tIndex)) + verifyError(VerifyError::noClassDefFound); + + constantPool->set(i, new (p) ConstantInterfaceMethodRef(p, constantPool, + cIndex, tIndex)); + break; + + case CR_CONSTANT_NAMEANDTYPE: { + Uint16 nIndex, dIndex; + + if (!fr.readU2(&nIndex, 1)) + verifyError(VerifyError::noClassDefFound); + + if (!fr.readU2(&dIndex, 1)) + verifyError(VerifyError::noClassDefFound); + + if (invalidIndex(nIndex) || invalidIndex(dIndex)) + verifyError(VerifyError::noClassDefFound); + + constantPool->set(i, new (p) ConstantNameAndType(p, constantPool, + nIndex, dIndex)); + + break; + } + + default: + verifyError(VerifyError::noClassDefFound); + } + } + + for (i = 1; i < constantPoolCount; i++) { + ConstantPoolItem *item = const_cast(constantPool->get(i)); + if (item && !item->resolveAndValidate()) + verifyError(VerifyError::noClassDefFound); + } +} + + +/* Reads and parses the interface section of the class file. + * interfaceCount must have been initialized and the interfaceInfo + * array allocated before calling this. + */ +void ClassFileReader::readInterfaces() +{ + Uint32 interfaceCount = interfaceInfo->count(); + + for (Uint32 i = 0; i < interfaceCount; i++) { + Uint16 index; + + if (!fr.readU2(&index, 1)) + verifyError(VerifyError::noClassDefFound); + + const ConstantPoolItem *item = constantPool->get(index); + if (invalidIndex(index) || item->getType() != CR_CONSTANT_CLASS) + verifyError(VerifyError::noClassDefFound); + + interfaceInfo->set(i, const_cast(item)); + } +} + + +/* Read an attribute at the current position in the file, classify it + * using the list of attribute handlers, and return the resulting attribute. + * Never returns nil. + */ +AttributeInfoItem *ClassFileReader::readAttribute() +{ + Uint16 nameIndex; + AttributeInfoItem *item; + ConstantUtf8 *utf8; + + if (!fr.readU2(&nameIndex, 1)) + verifyError(VerifyError::noClassDefFound); + + if (invalidIndex(nameIndex)) + verifyError(VerifyError::noClassDefFound); + + const ConstantPoolItem *constantPoolItem = constantPool->get(nameIndex); + if (constantPoolItem->getType() != CR_CONSTANT_UTF8) + verifyError(VerifyError::noClassDefFound); + + utf8 = (ConstantUtf8 *) constantPoolItem; + + for (Int32 i = 0; i < numAttrHandlers; i++) + if ((item = attrHandlers[i]->handle(utf8->getUtfString())) != 0) + return item; + + verifyError(VerifyError::noClassDefFound); + return 0; +} + + +/* Read count InfoItems from the file and store them into the info array. + * If field is true, creates the FieldInfo array; otherwise creates the + * MethodInfo array. + */ +void ClassFileReader::readInfoItems(Uint32 count, InfoItem **info, bool field) +{ + for (Uint32 i = 0; i < count; i++) { + Uint16 aFlags, nameIndex, descIndex, attrCount; + + if (!fr.readU2(&aFlags, 1)) + verifyError(VerifyError::noClassDefFound); + + if (!fr.readU2(&nameIndex, 1)) + verifyError(VerifyError::noClassDefFound); + + if (invalidIndex(nameIndex)) + verifyError(VerifyError::noClassDefFound); + + if (!fr.readU2(&descIndex, 1)) + verifyError(VerifyError::noClassDefFound); + + if (invalidIndex(descIndex)) + verifyError(VerifyError::noClassDefFound); + + if (!fr.readU2(&attrCount, 1)) + verifyError(VerifyError::noClassDefFound); + + if (constantPool->get(nameIndex)->getType() != CR_CONSTANT_UTF8 || + constantPool->get(descIndex)->getType() != CR_CONSTANT_UTF8) + verifyError(VerifyError::noClassDefFound); + + ConstantUtf8 *desc = (ConstantUtf8 *) constantPool->get(descIndex); + ConstantUtf8 *name = (ConstantUtf8 *) constantPool->get(nameIndex); + + if (field) { + FieldInfo *fInfo = new (p) FieldInfo(p, aFlags, + (ConstantUtf8 *) constantPool->get(thisClassIndex), + name, + desc); + + + info[i] = fInfo; + + /* If this field is public, add it to the public field array */ + if (aFlags & CR_FIELD_PUBLIC) + publicFields[publicFieldCount++] = (Uint16) i; + + /* Add this field into the hashtable for faster lookup */ + InfoNode *node = new (p) InfoNode(desc->getUtfString(), i); + fieldTable.add(name->getUtfString(), node); + } else { + MethodInfo *mInfo; + + mInfo = new (p) MethodInfo(p, aFlags, + ((ConstantClass *) constantPool->get(thisClassIndex))->getUtf(), + name, + desc); + + info[i] = mInfo; + + const char *methodName = ((ConstantUtf8 *) constantPool->get(nameIndex))->getUtfString(); + + /* If this method is , then add it to the Constructor array. + * Else, if it is public, add it to the list of public methods. + */ + if (PL_strcmp(methodName, "") != 0) { + if (!PL_strcmp(methodName, "")) { + constructors[constructorCount++] = (Uint16) i; + + if ((aFlags & CR_METHOD_PUBLIC)) + publicConstructors[publicConstructorCount++] = (Uint16) i; + + } else { + if (aFlags & CR_METHOD_PUBLIC) + publicMethods[publicMethodCount++] = (Uint16) i; + + declaredMethods[declaredMethodCount++] = (Uint16) i; + } + } + + /* add this method into the method hash table for faster lookup */ + InfoNode *node = new (p) InfoNode(desc->getUtfString(), i); + methodTable.add(name->getUtfString(), node); + } + + for (Uint32 j = 0; j < attrCount; j++) { + AttributeInfoItem *attr = readAttribute(); + info[i]->addAttribute(*attr); + } + } +} + + +/* Reads and parses the methods section of the class file. + * methodCount must have been initialized and the methodInfo + * array allocated before calling this. + */ +void ClassFileReader::readMethods() +{ + readInfoItems(methodCount, (InfoItem **) methodInfo, false); +} + + +/* Reads and parses the fields section of the class file. + * fieldCount must have been initialized and the fieldInfo + * array allocated before calling this. + */ +void ClassFileReader::readFields() +{ + readInfoItems(fieldCount, (InfoItem **) fieldInfo, true); +} + + +/* Reads and parses attrCount attributes starting at the current + * place in the class file. Stores the attributes into the attrInfo + * array, which should have been allocated before calling this. + */ +void ClassFileReader::readAttributes(AttributeInfoItem **attrInfo, + Uint32 attrCount) +{ + for (Uint32 i = 0; i < attrCount; i++) + attrInfo[i] = readAttribute(); +} + +/* Reads and parses the class file given by the canonical name fileName. + * Throws a VerifyError on errors or failures. pool is used to allocate + * all dynamic structures during the process of parsing the file. strPool + * is used to intern all strings encountered during the parsing. + */ +ClassFileReader::ClassFileReader(Pool &pool, StringPool &strPool, + FileReader &fr) : + constantPool(0), + interfaceInfo(0), fieldInfo(0), fieldCount(0), + attributeInfo(0), attributeCount(0), + methodInfo(0), methodCount(0), + publicFields(0), publicFieldCount(0), + publicMethods(0), publicMethodCount(0), + declaredMethods(0), declaredMethodCount(0), + constructors(0), constructorCount(0), + publicConstructors(0), publicConstructorCount(0), + p(pool), sp(strPool), fr(fr), fieldTable(pool), methodTable(pool) +{ + Uint32 magic; + + numAttrHandlers = 0; + attrSize = 10; + attrHandlers = new (p) AttributeHandler *[attrSize]; + + if (!fr.readU4(&magic, 1)) + verifyError(VerifyError::noClassDefFound); + + if (magic != JAVA_MAGIC) + verifyError(VerifyError::noClassDefFound); + + /* get the version numbers */ + if (!fr.readU2(&minorVersion, 1) || !fr.readU2(&majorVersion, 1)) + verifyError(VerifyError::noClassDefFound); + + /* XXX Need to put a check in here to see if we can handle the version + * numbers in the file + */ + + Uint16 constantPoolCount; + /* Constant pool count */ + if (!fr.readU2(&constantPoolCount, 1)) + verifyError(VerifyError::noClassDefFound); + + constantPool = new (p) ConstantPool(constantPoolCount); + + /* Parse the constant pool */ + readConstantPool(); + + /* Register attribute handlers for all attributes that we can + * handle + */ + addAttrHandler(new (p) AttributeHandlerSourceFile(p, &fr, this)); + addAttrHandler(new (p) AttributeHandlerConstantValue(p, &fr, this)); + addAttrHandler(new (p) AttributeHandlerCode(p, &fr, this)); + addAttrHandler(new (p) AttributeHandlerExceptions(p, &fr, this)); + addAttrHandler(new (p) AttributeHandlerLineNumberTable(p, &fr, this)); + addAttrHandler(new (p) AttributeHandlerLocalVariableTable(p, &fr, this)); + + /* This must always be added after everything else, since it handles + * all attributes that we know nothing about + */ + addAttrHandler(new (p) AttributeHandlerDummy(p, &fr, this)); + + /* Access Flags */ + if (!fr.readU2(&accessFlags, 1)) + verifyError(VerifyError::noClassDefFound); + + /* This Class, super Class */ + if (!fr.readU2(&thisClassIndex, 1)) + verifyError(VerifyError::noClassDefFound); + + if (!fr.readU2(&superClassIndex, 1)) + verifyError(VerifyError::noClassDefFound); + + if (invalidIndex(thisClassIndex)) + verifyError(VerifyError::badClassFormat); + + if (superClassIndex != 0 && invalidIndex(superClassIndex)) + verifyError(VerifyError::badClassFormat); + + /* If we don't have a super-class, we must be java/lang/Object */ + if (superClassIndex == 0) { + if (PL_strcmp(ConstantClass::cast(*const_cast(constantPool->get(thisClassIndex))).getUtf()->getUtfString(), "java/lang/Object") != 0) { + UT_LOG(ClassReader, PR_LOG_DEBUG, ("No superclass, but we don't seem to be Object\n")); + verifyError(VerifyError::noClassDefFound); + } + } else { + if (constantPool->get(superClassIndex)->getType() != CR_CONSTANT_CLASS) + verifyError(VerifyError::badClassFormat); + } + + /* Interfaces */ + Uint16 interfaceCount; + if (!fr.readU2(&interfaceCount, 1)) + verifyError(VerifyError::noClassDefFound); + + if (interfaceCount > 0) { + interfaceInfo = new (p) ConstantPool(interfaceCount); + + readInterfaces(); + } + + /* Fields */ + if (!fr.readU2(&fieldCount, 1)) + verifyError(VerifyError::noClassDefFound); + + if (fieldCount > 0) { + fieldInfo = new (p) FieldInfo *[fieldCount]; + publicFields = new (p) Uint16[fieldCount]; + + readFields(); + } + + /* Methods */ + if (!fr.readU2(&methodCount, 1)) + verifyError(VerifyError::noClassDefFound); + + if (methodCount > 0) { + methodInfo = new (p) MethodInfo *[methodCount]; + publicMethods = new (p) Uint16[methodCount]; + declaredMethods = new (p) Uint16[methodCount]; + constructors = new (p) Uint16[methodCount]; + publicConstructors = new (p) Uint16[methodCount]; + + readMethods(); + } + + /* Attributes */ + if (!fr.readU2(&attributeCount, 1)) + verifyError(VerifyError::noClassDefFound); + + if (attributeCount > 0) { + attributeInfo = new (p) AttributeInfoItem *[attributeCount]; + + readAttributes(attributeInfo, attributeCount); + } + + /* At this point, we must be at the end of the file....*/ +#ifndef DEBUG_SMSILVER + char dummy; + if (fr.readU1(&dummy, 1)) + verifyError(VerifyError::noClassDefFound); +#endif +} + +/* Install an attribute handler, growing the attrHandlers array if + * needed. The attribute handlers will be called in the order in which + * they are installed until one of them succeeds. + */ +void ClassFileReader::addAttrHandler(AttributeHandler *handler) +{ + if (numAttrHandlers+1 > attrSize) { + AttributeHandler **oldAttrHandlers = attrHandlers; + attrSize += 5; + attrHandlers = new (p) AttributeHandler *[attrSize]; + + for (Int32 i = 0; i < numAttrHandlers; i++) + attrHandlers[i] = oldAttrHandlers[i]; + } + + attrHandlers[numAttrHandlers++] = handler; +} + +/* look up a fieldref, methodref or interfacemethodref with the + * given name and signature, and return the index in the field/method + * array of the class that the field/method/interface method occupies. + * returns true on success, false on failure. + */ +bool ClassFileReader::lookupConstant(const char *name, const char *sig, + Uint8 type, + Uint16 &index) const +{ + /* Get interned versions of the name and type string */ + const char *namei = sp.get(name); + const char *sigi = sp.get(sig); + + for (Uint32 i = 1; i < constantPool->count(); i++) { + const ConstantPoolItem *item = constantPool->get(i); + if (item && item->getType() == type) { + switch (type) { + case CR_CONSTANT_METHODREF: + case CR_CONSTANT_INTERFACEMETHODREF: + case CR_CONSTANT_FIELDREF: { + ConstantNameAndType *ninfo = ((ConstantRef *) item)->getTypeInfo(); + ConstantUtf8 *nameUtf = ninfo->getName(); + ConstantUtf8 *typeUtf = ninfo->getDesc(); + + if (nameUtf->getUtfString() == namei && + typeUtf->getUtfString() == sigi) { + index = (Uint16) i; + return true; + } + + break; + } + + default: + /* If we're here, we don't yet support "type" */ + return false; + } + } + } + + return false; +} + +/* Look up a field or method based on given name and type descriptor. + * On success, returns the InfoItem for the field or method; on failure, + * returns NULL. type can be either CR_CONSTANT_FIELDREF (look for a field) + * or CR_CONSTANT_METHODREF (look for a method). Assumption: both name + * and sig are interned strings; however, sig can be nil if the method is + * not overloaded. On success, index is set to the index of the matched + * field or method in the field or method table of the class. + */ +const InfoItem *ClassFileReader::lookupFieldOrMethod(Uint8 type, + const char *name, + const char *sig, + Uint16 &index) const +{ + FastHashTable *table; + const InfoItem **items; + + if (type == CR_CONSTANT_FIELDREF) { + items = (const InfoItem **) fieldInfo; + table = const_cast *>(&fieldTable); + } else { + items = (const InfoItem **) methodInfo; + table = const_cast *>(&methodTable); + } + + Vector vector(5); + + Int32 numMatches = table->getAll(name, vector); + + if (!numMatches) + return 0; + + if (!sig) { + if (numMatches == 1) + return items[(index = (Uint16) vector[0]->index)]; + else + return 0; + } + + for (Int32 i = 0; i < numMatches; i++) { + InfoNode *node = vector[i]; + if (node->sig == sig) + return items[(index = (Uint16) node->index)]; + } + + return 0; +} + + + + + + diff --git a/ef/Runtime/ClassReader/ClassReader.h b/ef/Runtime/ClassReader/ClassReader.h new file mode 100644 index 000000000000..ecfeeaa98753 --- /dev/null +++ b/ef/Runtime/ClassReader/ClassReader.h @@ -0,0 +1,369 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#ifndef _ClassFileReader_H_ +#define _ClassFileReader_H_ + +#include +#include +#include +#include + +#include "ConstantPool.h" +#include "Attributes.h" +#include "InfoItem.h" +#include "Pool.h" +#include "FastHashTable.h" +#include "StringPool.h" +#include "FileReader.h" + +class ClassFileReader; +class FileReader; +class AttributeHandler; +class AttributeHandlerCode; + +/* Class access flags */ +#define CR_ACC_PUBLIC 0x0001 +#define CR_ACC_FINAL 0x0010 +#define CR_ACC_SUPER 0x0020 +#define CR_ACC_INTERFACE 0x0200 +#define CR_ACC_ABSTRACT 0x0400 + +struct InfoNode { + const char *sig; /* descriptor for field/method */ + Int32 index; /* Index into field/method table */ + InfoNode(const char *sig, Int32 index) : sig(sig), index(index) { } +}; + +/* Reads and parses a class file */ +class ClassFileReader { + +public: + ClassFileReader(Pool &p, StringPool &sp, FileReader &fr); + + Uint16 getMinorVersion() const { + return minorVersion; + } + + Uint16 getMajorVersion() const { + return majorVersion; + } + + Uint16 getAccessFlags() const { + return accessFlags; + } + + /* returns a pointer to the class/interface described by the class file */ + ConstantClass *getThisClass() const { + return (ConstantClass *) constantPool->get(thisClassIndex); + } + + /* returns an index into the constant pool rather than a pointer to + * the class itself + */ + Uint16 getThisClassIndex() const { + return thisClassIndex; + } + + /* returns a pointer to the super-class or nil if there is none */ + ConstantClass *getSuperClass() const { + return (superClassIndex > 0) ? (ConstantClass *) + constantPool->get(superClassIndex) : 0; + } + + /* returns an index into the constant pool table that points to the + * superclass; index is zero if there is no superclass + */ + Uint16 getSuperClassIndex() const { + return superClassIndex; + } + + /* Constant pool table */ + const ConstantPool *getConstantPool() const { + return (const ConstantPool *) constantPool; + } + + Uint16 getConstantPoolCount() const { + return (constantPool) ? (Uint16) constantPool->count() : 0; + } + + /* Interface table */ + const ConstantPool *getInterfaceInfo() const { + return (const ConstantPool *) interfaceInfo; + } + + Uint16 getInterfaceCount() const { + return (interfaceInfo) ? (Uint16) interfaceInfo->count() : 0; + } + + /* Return an array of all fields in the class. */ + const FieldInfo **getFieldInfo() const { + return (const FieldInfo **) fieldInfo; + } + + /* return total number of fields in the field table of the class. */ + Uint16 getFieldCount() const { + return fieldCount; + } + + /* Return an array pointing to the public fields of the class. + * array[i] is an index into the fields array of the class, and points + * to a FieldInfo structure. + */ + const Uint16 *getPublicFields() const { + return (const Uint16 *) publicFields; + } + + /* return number of public fields in the class */ + Uint16 getPublicFieldCount() const { + return publicFieldCount; + } + + + /* return an array of all methods in the class */ + const MethodInfo **getMethodInfo() const { + return (const MethodInfo **) methodInfo; + } + + /* return total number of methods in the method table of the class */ + Uint16 getMethodCount() const { + return methodCount; + } + + /* Return an array of the public methods of the class. This does not + * include and methods. array[i] is an index into the + * methods array of the class, and points to a MethodInfo structure + * located at that index. + */ + const Uint16 *getPublicMethods() const { + return (const Uint16 *) publicMethods; + } + + /* return number of public methods in the class. */ + Uint16 getPublicMethodCount() const { + return publicMethodCount; + } + + /* Return an array of the declared methods of the class. This does not + * include and methods. array[i] is an index into the + * methods array of the class, and points to a MethodInfo structure + * located at that index. + */ + const Uint16 *getDeclaredMethods() const { + return (const Uint16 *) declaredMethods; + } + + /* return number of declared methods in the class. */ + Uint16 getDeclaredMethodCount() const { + return declaredMethodCount; + } + + /* return an array of constructors of the class. Constructors are + * methods with the special name . array[i] is an index into the + * methods array of the class, and points to a MethodInfo structure + * located at that index. + */ + const Uint16 *getConstructors() const { + return (const Uint16 *) constructors; + } + + /* return total number of constructors in the class. */ + Uint16 getConstructorCount() const { + return constructorCount; + } + + /* return an array consisting of the public constructors of the class. + * array[i] is an index into the + * methods array of the class, and points to a MethodInfo structure + * located at that index. + */ + const Uint16 *getPublicConstructors() const { + return (const Uint16 *) publicConstructors; + } + + /* return total number of public constructors in the class */ + Uint16 getPublicConstructorCount() const { + return publicConstructorCount; + } + + /* Attribute table */ + const AttributeInfoItem **getAttributeInfo() const { + return (const AttributeInfoItem **) attributeInfo; + } + + Uint16 getAttributeCount() const { + return attributeCount; + } + + /* Look up a constant of type integer, long, float, or double whose + * offset in the constant pool of the class is index. Returns true on success, + * false if it couldn't find the field or on error. + */ + bool lookupConstant(Uint16 index, ValueKind &vk, Value &value) const; + + /* look up a fieldref, methodref or interfacemethodref with the + * given name and signature, and return the index in the field/method + * array of the class that the field/method/interface method occupies. + * returns true on success, false on failure. + */ + bool lookupConstant(const char *name, const char *sig, + Uint8 type, Uint16 &index) const; + + + /* Look up a field based on given name and type descriptor. On success, + * returns the FieldInfo for the field; on failure, returns NULL + */ + const FieldInfo *lookupField(const char *name, const char *type, + Uint16 &index) const { + return static_cast + (lookupFieldOrMethod(CR_CONSTANT_FIELDREF, name, type, index)); + } + + /* Look up a method based on given name and signature. On success, + * returns the MethodInfo for the field; on failure, returns NULL. + * sig can be nil if the method is not overloaded. + */ + const MethodInfo *lookupMethod(const char *name, const char *sig, + Uint16 &index) const { + return static_cast + (lookupFieldOrMethod(CR_CONSTANT_METHODREF, name, sig, index)); + } + + /* Look up a field or method based on given name and type descriptor. + * On success, returns the InfoItem for the field or method; on failure, + * returns NULL. type can be either CR_CONSTANT_FIELDREF (look for a field) + * or CR_CONSTANT_METHODREF (look for a method). Assumption: both name + * and sig are interned strings. On success, index is set to the + * index of the matched field or method in the field or method table + * of the class. + */ + const InfoItem *lookupFieldOrMethod(Uint8 type, const char *name, + const char *sig, Uint16 &index) const; + +#ifdef DEBUG + void dump() const; +#endif + +private: + /* Copies of data read from the class file */ + Uint16 minorVersion, majorVersion; + Uint16 accessFlags; + Uint16 thisClassIndex, superClassIndex; + + /* Array of constantpoolCount constant pool items */ + ConstantPool *constantPool; + + /* Array of interfaceCount interface references */ + ConstantPool *interfaceInfo; + + /* Array of fieldCount fields */ + FieldInfo **fieldInfo; + Uint16 fieldCount; + + /* Array of attributeCount global attributes */ + AttributeInfoItem **attributeInfo; + Uint16 attributeCount; + + /* Array of methodCount methods */ + MethodInfo **methodInfo; + Uint16 methodCount; + + /* Array of publicFieldCount public fields. publicFields[i] is an + * index into the field array (fieldInfo) + */ + Uint16 *publicFields; + Uint16 publicFieldCount; + + /* Array of publicMethodCount public methods. publicMethods[i] is an + * index into the method array (methodInfo) + */ + Uint16 *publicMethods; + Uint16 publicMethodCount; + + /* Array of declaredMethodCount declared methods. declaredMethods[i] is an + * index into the method array (methodInfo). A declared method is a public, + * protected or private method that is not or . + */ + Uint16 *declaredMethods; + Uint16 declaredMethodCount; + + /* Array of constructorCount constructors. constructors[i] is an + * index into the method array (methodInfo) + */ + Uint16 *constructors; + Uint16 constructorCount; + + /* Array of publicConstructorCount public constructors. + * publicConstructors[i] is an index into the method array (methodInfo) + */ + Uint16 *publicConstructors; + Uint16 publicConstructorCount; + + /* Array of numAttrHandlers handler functions that handle attributes that + * we know about + */ + AttributeHandler **attrHandlers; + int numAttrHandlers; + /* Physical size of the attrHandlers array */ + int attrSize; + + /* Pool used to allocate dynamic structures */ + Pool &p; + + /* Pool that holds interned strings */ + StringPool &sp; + + /* Class that reads from the class file */ + FileReader &fr; + + /* Hashtables for fast lookups for fields and methods, indexed by the + * name of the field/method + */ + FastHashTable fieldTable, methodTable; + + /* Reads and parses the constant pool section of the class file */ + void readConstantPool(); + + /* Reads and parses the interface section of the class file */ + void readInterfaces(); + + /* Reads and parses the method section of the class file */ + void readMethods(); + +public: + void readAttributes(AttributeInfoItem **attrInfo, + Uint32 attrCount); +private: + void readFields(); + void readInfoItems(Uint32 count, InfoItem **info, bool field); + + /* Read one attribute from the current position in the file */ + AttributeInfoItem *readAttribute(); + + void addAttrHandler(AttributeHandler *handler); + + bool invalidIndex(Uint32 index) { + return (index < 1 || index >= constantPool->count()); + } + +}; + + +#endif /* _ClassFileReader_H_ */ + + + diff --git a/ef/Runtime/ClassReader/ConstantPool.h b/ef/Runtime/ClassReader/ConstantPool.h new file mode 100644 index 000000000000..a9aeae02e3a3 --- /dev/null +++ b/ef/Runtime/ClassReader/ConstantPool.h @@ -0,0 +1,432 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#ifndef _CONSTANT_POOL_H_ +#define _CONSTANT_POOL_H_ + +#include "FloatUtils.h" +#include "prtypes.h" +#include "utils.h" +#include "Pool.h" +#include "ErrorHandling.h" +#include "Value.h" +#include "LogModule.h" + +/* Constant pool types */ +#define CR_CONSTANT_CLASS 7 +#define CR_CONSTANT_FIELDREF 9 +#define CR_CONSTANT_METHODREF 10 +#define CR_CONSTANT_INTERFACEMETHODREF 11 +#define CR_CONSTANT_STRING 8 +#define CR_CONSTANT_INTEGER 3 +#define CR_CONSTANT_FLOAT 4 +#define CR_CONSTANT_LONG 5 +#define CR_CONSTANT_DOUBLE 6 +#define CR_CONSTANT_NAMEANDTYPE 12 +#define CR_CONSTANT_UTF8 1 + +class ConstantPoolItem; + +/* The Constant Pool */ +class ConstantPool { +private: + const ConstantPoolItem **items; + Uint32 numItems; + +public: + /* Only ClassFileReader can create the constant pool */ + ConstantPool(Uint32 numItems) : numItems(numItems) { + items = new const ConstantPoolItem *[numItems]; + } + + /* Set the item at given index in the constant pool. */ + void set(Uint32 index, const ConstantPoolItem *item) { + assert(index < numItems); items[index] = item; + } + + /* Get the constant pool item at index "index" in the constant pool. */ + const ConstantPoolItem *get(Uint32 index) const { + return items[index]; + } + + /* return the number of items in the constant pool */ + Uint32 count() const { + return numItems; + } + +#ifdef DEBUG_LOG + void printItem(LogModuleObject &f, Uint32 index) const; +#endif +}; + + +/* Denizens of the ConstantPool */ +class ConstantPoolItem { +protected: + ConstantPoolItem(Pool &pool, Uint8 type) : + p(pool), type(type) { } + +public: + Uint8 getType() const { + return type; + } + + /* ResolveAndValidate indices into actual pointers; return true if successful */ + virtual bool resolveAndValidate() { + return true; + } + +#ifdef DEBUG + virtual void dump(int indent) const; +#endif +#ifdef DEBUG_LOG + virtual void print(LogModuleObject &f) const; +#endif + +protected: + // Pool for allocating dynamic storage for this ConstantPoolItem + Pool &p; + +private: + // CR_CONSTANT_ type of this ConstantPoolItem + Uint8 type; +}; + + + +class ConstantUtf8 : public ConstantPoolItem { +public: + ConstantUtf8(Pool &p, const char *str, Uint32 len); + + const char *getUtfString() const { + return data; + } + + const int getUtfLen() const { + return dataLen; + } + +#ifdef DEBUG + virtual void dump(int nIndents) const; +#endif +#ifdef DEBUG_LOG + void print(LogModuleObject &f) const; +#endif + +private: + /* Pointer to the interned version of the string */ + const char *data; + Uint32 dataLen; +}; + + +/* A base class for constant-pool items that point to Utf strings */ +class ConstantUtf : public ConstantPoolItem { +friend class ClassFileReader; +public: + ConstantUtf(Pool &p, Uint8 _type, ConstantUtf8 *utf8) : + ConstantPoolItem(p, _type) { + utfString = utf8; + } + + ConstantUtf8 *getUtf() const { + return utfString; + } + +protected: + ConstantUtf(Pool &p, Uint8 _type) : + ConstantPoolItem(p, _type) { + utfString = 0; + } + + ConstantUtf8 *utfString; +}; + + + +class ConstantClass : public ConstantUtf { +public: + static ConstantClass &cast(ConstantPoolItem &item) { + if (item.getType() != CR_CONSTANT_CLASS) + verifyError(VerifyError::noClassDefFound); + return *static_cast(&item); + } + + virtual bool resolveAndValidate(); + +#ifdef DEBUG + virtual void dump(int nIndents) const; +#endif +#ifdef DEBUG_LOG + void print(LogModuleObject &f) const; +#endif + + ConstantClass(Pool &p, ConstantPool *array, int _index) : + ConstantUtf(p, CR_CONSTANT_CLASS), index(_index), pool(array) {} +private: + int index; + // The constant pool of which this ConstantPoolItem is a member + ConstantPool *pool; +}; + + +class ConstantNameAndType : public ConstantPoolItem { +friend class ClassFileReader; +public: + ConstantNameAndType(Pool &p, ConstantUtf8 *name, ConstantUtf8 *desc): + ConstantPoolItem(p, CR_CONSTANT_NAMEANDTYPE) { + nameInfo = name; + descInfo = desc; + } + + /* Get the name of the constant */ + ConstantUtf8 *getName() const { + return nameInfo; + } + + /* returns a class that points to the type string */ + ConstantUtf8 *getDesc() const { + return descInfo; + } + + virtual bool resolveAndValidate(); + +#ifdef DEBUG + virtual void dump(int nIndents) const; +#endif +#ifdef DEBUG_LOG + void print(LogModuleObject &f) const; +#endif + +private: + ConstantNameAndType(Pool &p, + ConstantPool *array, Uint16 nindex, Uint16 dIndex); + + // The constant pool of which this ConstantPoolItem is a member + ConstantPool *pool; + + ConstantUtf8 *nameInfo; + ConstantUtf8 *descInfo; + + int nameIndex, descIndex; +}; + + +/* Base class used by ConstantFieldRef, ConstantMethodRef, + * ConstantInterfaceMethodRef: members of a class + */ +class ConstantRef : public ConstantPoolItem { +friend class ClassFileReader; +public: + ConstantRef(Pool &p, Uint8 _type, + ConstantClass *cInfo, ConstantNameAndType *_typeInfo) : + ConstantPoolItem(p, _type) { + classInfo = cInfo; + typeInfo = _typeInfo; + } + + ConstantClass *getClassInfo() const { + return classInfo; + } + + ConstantNameAndType *getTypeInfo() const { + return typeInfo; + } + + virtual bool resolveAndValidate(); + +#ifdef DEBUG + virtual void dump(int nIndents) const; +#endif +#ifdef DEBUG_LOG + void print(LogModuleObject &f) const; +#endif + +protected: + ConstantRef(Pool &p, Uint8 _type, ConstantPool *array, Uint16 cIndex, + Uint16 tIndex); + + // The constant pool of which this ConstantPoolItem is a member + ConstantPool *pool; + + ConstantClass *classInfo; + ConstantNameAndType *typeInfo; + + int classIndex, typeIndex; +}; + + +class ConstantFieldRef : public ConstantRef { +friend class ClassFileReader; +public: + ConstantFieldRef(Pool &p, ConstantClass *cInfo, + ConstantNameAndType *_type): + ConstantRef(p, CR_CONSTANT_FIELDREF, cInfo, _type) { + + } + +#ifdef DEBUG + virtual void dump(int nIndents) const; +#endif + +private: + ConstantFieldRef(Pool &p, ConstantPool *array, int cIndex, + int tIndex) : + ConstantRef(p, CR_CONSTANT_FIELDREF, array, cIndex, tIndex) { + + } +}; + +class ConstantMethodRef : public ConstantRef { +friend class ClassFileReader; + +public: + ConstantMethodRef(Pool &p, ConstantClass *cInfo, + ConstantNameAndType *_type): + ConstantRef(p, CR_CONSTANT_METHODREF, cInfo, _type) { + + } + +#ifdef DEBUG + virtual void dump(int nIndents) const; +#endif + +private: +ConstantMethodRef(Pool &p, ConstantPool *array, int cIndex, + int tIndex) : + ConstantRef(p, CR_CONSTANT_METHODREF, array, cIndex, tIndex) { + + } + +}; + +class ConstantInterfaceMethodRef : public ConstantRef { +friend class ClassFileReader; + +public: + ConstantInterfaceMethodRef(Pool &p, ConstantClass *cInfo, + ConstantNameAndType *_type): + ConstantRef(p, CR_CONSTANT_INTERFACEMETHODREF, cInfo, _type) { + + } + +#ifdef DEBUG + virtual void dump(int nIndents) const; +#endif + +private: + ConstantInterfaceMethodRef(Pool &p, ConstantPool *array, int cIndex, + int tIndex) : + ConstantRef(p, CR_CONSTANT_INTERFACEMETHODREF, array, cIndex, tIndex) { + + } + +}; + + +class ConstantString : public ConstantUtf { +friend class ClassFileReader; +public: + ConstantString(Pool &p, ConstantUtf8 *utf8) : + ConstantUtf(p, CR_CONSTANT_STRING, utf8) { + utfString = utf8; + } + + ConstantUtf8 *getUtf() const { + return utfString; + } + + virtual bool resolveAndValidate(); + +#ifdef DEBUG + virtual void dump(int nIndents) const; +#endif +#ifdef DEBUG_LOG + void print(LogModuleObject &f) const; +#endif + + ConstantString(Pool &p, ConstantPool *array, int _index): + ConstantUtf(p, CR_CONSTANT_STRING), pool(array), index(_index) { } + +private: + // The constant pool of which this ConstantPoolItem is a member + ConstantPool *pool; + + int index; +}; + +/* Base class for all constant types that hold a numberic value */ +class ConstantVal : public ConstantPoolItem { +public: + ConstantVal(Pool &p, Uint8 _type, ValueKind kind) : + ConstantPoolItem(p, _type), vk(kind) { + + } + + Value getValue() const { + return value; + } + + ValueKind getValueKind() const { + return vk; + } + +#ifdef DEBUG + virtual void dump(int nIndents) const; +#endif +#ifdef DEBUG_LOG + void print(LogModuleObject &f) const; +#endif + +protected: + Value value; + ValueKind vk; +}; + +class ConstantInt : public ConstantVal { +public: + ConstantInt(Pool &p, Int32 val): + ConstantVal(p, CR_CONSTANT_INTEGER, vkInt) { + value.setValueContents(val); + } + +}; + + +class ConstantFloat : public ConstantVal { +public: + ConstantFloat(Pool &p, Uint32 raw); +}; + + +class ConstantLong : public ConstantVal { +public: + ConstantLong(Pool &p, Uint32 lo, Uint32 hi); + +}; + + +class ConstantDouble : public ConstantVal { +public: + ConstantDouble(Pool &p, char *data); + +}; + + +#endif /* _CONSTANT_POOL_H_ */ + + diff --git a/ef/Runtime/ClassReader/InfoItem.h b/ef/Runtime/ClassReader/InfoItem.h new file mode 100644 index 000000000000..29a9ceff2938 --- /dev/null +++ b/ef/Runtime/ClassReader/InfoItem.h @@ -0,0 +1,139 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#ifndef _CR_INFOITEM_H_ +#define _CR_INFOITEM_H_ + +#include "ConstantPool.h" +#include "DoublyLinkedList.h" + +#define CR_FIELD_VOLATILE 0x0040 +#define CR_FIELD_STATIC 0x0008 +#define CR_FIELD_PUBLIC 0x0001 +#define CR_FIELD_PROTECTED 0x0004 +#define CR_FIELD_PRIVATE 0x0002 +#define CR_FIELD_FINAL 0x0010 +#define CR_FIELD_TRANSIENT 0x0080 + +#define CR_METHOD_STATIC 0x0008 +#define CR_METHOD_NATIVE 0x0100 +#define CR_METHOD_ABSTRACT 0x0400 +#define CR_METHOD_PRIVATE 0x0002 +#define CR_METHOD_PUBLIC 0x0001 +#define CR_METHOD_PROTECTED 0x0004 +#define CR_METHOD_FINAL 0x0010 +#define CR_METHOD_SYNCHRONIZED 0x0020 + + +/* Base class for types FieldInfo and MethodInfo */ +class InfoItem { +public: + InfoItem(Pool &p, Uint16 aflags, ConstantUtf8 *classInfo, + ConstantUtf8 *nameInfo, ConstantUtf8 *descInfo); + + + Uint16 getAccessFlags() const { + return accessFlags; + } + + ConstantUtf8 *getName() const { + return name; + } + + /* Returns a class that points to the string representing the + * type descriptor of the field/method + */ + ConstantUtf8 *getDescriptor() const { + return descriptor; + } + + /* returns the name of the class that this field/method is a member of */ + ConstantUtf8 *getClassName() const { + return className; + } + + int getAttributeCount() const { + return attrCount; + } + + const DoublyLinkedList &getAttributes() const { + return attributes; + } + + + /* Looks up an attribute by attribute-name */ + AttributeInfoItem *getAttribute(const char *_name) const; + + /* Look up a known attribute by code name */ + AttributeInfoItem *getAttribute(const Uint32 code) const; + +#ifdef DEBUG + virtual void dump(int nIndents) const; +#endif + + bool addAttribute(AttributeInfoItem &attribute); + +protected: + Pool &p; + +private: + Uint16 accessFlags; + ConstantUtf8 *name, *descriptor, *className; + + int attrCount; + DoublyLinkedList attributes; + +}; + +/* A FieldInfo represents one field in a class or interface */ +class FieldInfo: public InfoItem { +friend class ClassFileReader; + +public: + FieldInfo(Pool &p, Uint16 aflags, ConstantUtf8 *classInfo, + ConstantUtf8 *nameInfo, ConstantUtf8 *descInfo) : + InfoItem(p, aflags, classInfo, nameInfo, descInfo) {} + + void getInfo(const char *&sig, + bool &isVolatile, bool &isConstant, bool &isStatic) const; + + +#ifdef DEBUG + virtual void dump(int nIndents) const; +#endif + +}; + +/* A MethodInfo represents one method in a class or interface */ +class MethodInfo: public InfoItem { +public: + MethodInfo(Pool &p, Uint16 aflags, ConstantUtf8 *classInfo, + ConstantUtf8 *nameInfo, ConstantUtf8 *descInfo) : + InfoItem(p, aflags, classInfo, nameInfo, descInfo) + { } + + /* Get the signature of the method and a few of its flags */ + void getInfo(const char *&sig, + bool &isAbstract, bool &isStatic, + bool &isFinal, bool &isSynchronized, + bool &isNative) const; + bool isNative() const { return (getAccessFlags() & CR_METHOD_NATIVE) != 0; }; +}; + + +#endif /* _CR_INFOITEM_H_ */ + diff --git a/ef/Runtime/ClassReader/Makefile b/ef/Runtime/ClassReader/Makefile new file mode 100644 index 000000000000..1bf504411f60 --- /dev/null +++ b/ef/Runtime/ClassReader/Makefile @@ -0,0 +1,62 @@ +#!gmake +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +####################################################################### +# (1) Directory specific info # +####################################################################### + +DEPTH = ../.. + + +CPPSRCS = AttributeHandlers.cpp \ + ClassReader.cpp \ + $(NULL) + +LOCAL_EXPORTS = ClassReader.h \ + ConstantPool.h \ + Attributes.h \ + AttributeHandlers.h \ + utils.h \ + InfoItem.h \ + $(NULL) + +MODULE_NAME = EF + +####################################################################### +# (2) Include "component" configuration information. # +####################################################################### + +include $(DEPTH)/config/config.mk + +####################################################################### +# (3) Include "local" platform-dependent assignments (OPTIONAL). # +####################################################################### + + + +####################################################################### +# (4) Execute "component" rules. (OPTIONAL) # +####################################################################### + +include $(DEPTH)/config/rules.mk + +####################################################################### +# (7) Execute "local" rules. (OPTIONAL). # +####################################################################### + + + diff --git a/ef/Runtime/ClassReader/config/config.mk b/ef/Runtime/ClassReader/config/config.mk new file mode 100644 index 000000000000..27de25c8ab26 --- /dev/null +++ b/ef/Runtime/ClassReader/config/config.mk @@ -0,0 +1,70 @@ +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +# +# Configuration Makefile +# + +machine := $(shell uname) + +ifeq ($(machine),SunOS) + version := $(shell uname -r) + ifneq ($(word 1, $(subst ., , $(version))), 4) + arch := sol24 + nspr_arch :=SunOS5.4_DBG.OBJ + else + arch := sunos + nspr_arch :=SunOS5.4_DBG.OBJ + endif +else + ifeq ($(machine), HP-UX) + nspr_arch :=HP-UXA.09_DBG.OBJ + + version := $(shell uname -r) + + ifneq ($(word 2, $(subst ., , $(version))), 09) + arch := hpux10 + else + arch := hpux + endif + else + ifeq ($(machine), AIX) + arch := aix + nspr_arch :=AIX4.1_DBG.OBJ + else + ifeq ($(machine), OSF1) + arch := axp + nspr_arch :=OSF1V3_DBG.OBJ + else + ifeq ($(machine), IRIX) + arch := irix + nspr_arch :=IRIX5.3_DBG.OBJ + else + ifeq ($(machine), Linux) + arch := linux + nspr_arch :=LinuxELF2.0_DBG.OBJ + endif + endif + endif + endif + endif +endif + +OBJHOME := $(DEPTH)/build/obj/$(arch) +BINHOME := $(DEPTH)/build/bin/$(arch) +CFLAGS += -DXP_UNIX -Wno-format -I$(DEPTH)/build/../../../nspr20/pr/include \ + -I$(DEPTH)/build/../../../nspr20/pr/include/md/$(nspr_arch) + diff --git a/ef/Runtime/ClassReader/main.cpp b/ef/Runtime/ClassReader/main.cpp new file mode 100644 index 000000000000..9ef0e26792fd --- /dev/null +++ b/ef/Runtime/ClassReader/main.cpp @@ -0,0 +1,49 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +/* Test program for ClassReader */ + +#include "ClassReader.h" +#include "ErrorHandling.h" + +#include "nspr.h" + +void goAway(const char *name, VerifyError err) +{ + printf("Exception %s thrown; cause %d\n", name, err.cause); + exit(1); +} + +int main(int /* argc */, char **argv) +{ + Pool pool; + StringPool sp(pool); + + PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 1); + + try { + ClassFileReader reader(pool, sp, argv[1]); +#ifdef DEBUG + reader.dump(); +#endif + } catch (VerifyError err) { + goAway("VerifyError", err); + } + + printf("Read Class File\n"); + return 0; +} diff --git a/ef/Runtime/ClassReader/utils.h b/ef/Runtime/ClassReader/utils.h new file mode 100644 index 000000000000..2e4cd52bacf7 --- /dev/null +++ b/ef/Runtime/ClassReader/utils.h @@ -0,0 +1,28 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#ifndef _CR_UTILS_H_ +#define _CR_UTILS_H_ + +#ifdef DEBUG_LOG +void indent(int n); +void title(int nIndents, const char *s); +void print(int nIndents, const char *fmt, ...); +#endif + + +#endif /* _CR_UTILS_H_ */ diff --git a/ef/Runtime/FileReader/BufferedFileReader.cpp b/ef/Runtime/FileReader/BufferedFileReader.cpp new file mode 100644 index 000000000000..ff37bd5be823 --- /dev/null +++ b/ef/Runtime/FileReader/BufferedFileReader.cpp @@ -0,0 +1,38 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +// BufferedFileReader.h +// +// Sriram Kini + +#include "BufferedFileReader.h" +#include + +bool BufferedFileReader::read1(char *destp, int size) +{ + if (curp+size > limit) + return false; + + memcpy(destp, curp, size); + curp += size; + return true; +} + + + + + diff --git a/ef/Runtime/FileReader/BufferedFileReader.h b/ef/Runtime/FileReader/BufferedFileReader.h new file mode 100644 index 000000000000..3e24abc5e46d --- /dev/null +++ b/ef/Runtime/FileReader/BufferedFileReader.h @@ -0,0 +1,46 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#ifndef _BUFFERED_FILEREADER_H_ +#define _BUFFERED_FILEREADER_H_ + +#include "FileReader.h" + +#include "prio.h" + +/* Reads a file, allocating space as neccessary */ +class BufferedFileReader : public FileReader { +public: + BufferedFileReader(char *buf, Int32 len, Pool &pool) : + FileReader(pool), buffer(buf), curp(buf), limit(buffer+len) { } + + virtual ~BufferedFileReader() { } + +private: + char *buffer; + char *curp; + char *limit; + +protected: + virtual bool read1(char *destp, int size); + +}; + + + +#endif /* _BUFFERED_FILEREADER_H_ */ + diff --git a/ef/Runtime/FileReader/DiskFileReader.cpp b/ef/Runtime/FileReader/DiskFileReader.cpp new file mode 100644 index 000000000000..ee669e46f822 --- /dev/null +++ b/ef/Runtime/FileReader/DiskFileReader.cpp @@ -0,0 +1,107 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#include +#include +#include + +#include "DiskFileReader.h" +#include "ErrorHandling.h" + +DiskFileReader::DiskFileReader(Pool &p, const char *fileName, + Int32 _bufferSize) : FileReader(p) +{ + fp = 0; + buffer = 0; + +#ifdef NO_NSPR + if (!(fp = fopen(fileName, "rb"))) { +#else + if (!(fp = PR_Open(fileName, PR_RDONLY, 0))) { +#endif + verifyError(VerifyError::noClassDefFound); + return; + } + + bufferSize = _bufferSize; + eofReached = false; + + buffer = new (pool) char[bufferSize]; + + if (!fillBuf()) + verifyError(VerifyError::noClassDefFound); +} + +/* Fill the buffer, returning number of items read */ +Int32 DiskFileReader::fillBuf() +{ + if (eofReached) + return 0; + +#ifdef NO_NSPR + Int32 nread = fread(buffer, 1, bufferSize, fp); +#else + Int32 nread = PR_Read(fp, buffer, bufferSize); +#endif + + if (nread < bufferSize) { + eofReached = true; + if (fp) +#ifdef NO_NSPR + fclose(fp); +#else + PR_Close(fp); +#endif + fp = 0; + } + + curp = buffer; + limit = buffer+nread; + + return nread; +} + +bool DiskFileReader::read1(char *destp, int size) +{ + while (curp+size > limit) { + int nread = (limit-curp); + memcpy(destp, curp, nread); + size -= nread; + destp += nread; + + if (fillBuf() <= 0) + return false; + } + + memcpy(destp, curp, size); + curp += size; + return true; +} + +DiskFileReader::~DiskFileReader() +{ + if (fp) +#ifdef NO_NSPR + fclose(fp); +#else + PR_Close(fp); +#endif +} + + + + diff --git a/ef/Runtime/FileReader/DiskFileReader.h b/ef/Runtime/FileReader/DiskFileReader.h new file mode 100644 index 000000000000..d07828a412ab --- /dev/null +++ b/ef/Runtime/FileReader/DiskFileReader.h @@ -0,0 +1,50 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#ifndef _DISK_FILEREADER_H_ +#define _DISK_FILEREADER_H_ + +#include "FileReader.h" + +#define FR_BUFFERSIZE 8192 +/* Reads an uncompressed file off the disk */ +class DiskFileReader : public FileReader { +public: + DiskFileReader(Pool &pool, const char *fileName, + Int32 bufferSize = FR_BUFFERSIZE); + + virtual ~DiskFileReader(); + +protected: + virtual bool read1(char *destp, int size); + +private: + Int32 bufferSize; + char *buffer; + char *curp, *limit; + bool eofReached; + + Int32 fillBuf(); + +#ifdef NO_NSPR + FILE *fp; +#else + PRFileDesc *fp; +#endif +}; + +#endif /* _DISK_FILEREADER_H_ */ diff --git a/ef/Runtime/FileReader/FileReader.cpp b/ef/Runtime/FileReader/FileReader.cpp new file mode 100644 index 000000000000..5cd51af1e3e7 --- /dev/null +++ b/ef/Runtime/FileReader/FileReader.cpp @@ -0,0 +1,72 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#include +#include +#include + +#include "FileReader.h" + +bool FileReader::readU1(char *destp, int numItems) +{ + return read1(destp, numItems); +} + +#ifdef IS_LITTLE_ENDIAN +#define flipU2(x) (((x) & 0xFF00) >> 8) | (((x) & 0x00FF) << 8) +#else +#define flipU2(x) (x) +#endif + +bool FileReader::readU2(Uint16 *destp, int numItems) +{ + if (!read1((char *) destp, numItems*2)) + return false; + +#ifdef IS_LITTLE_ENDIAN + for (numItems--; numItems >= 0; numItems--) + destp[numItems] = flipU2(destp[numItems]); +#endif + + return true; +} + +#ifdef IS_LITTLE_ENDIAN +#define flipU4(x) (((x) >> 24) |\ + ((((x) << 8) >> 24) << 8) |\ + ((((x) << 16) >> 24) << 16) |\ + ((x) << 24)) +#else +#define flipU4(x) (x) +#endif + +bool FileReader::readU4(Uint32 *destp, int numItems) +{ + if (!read1((char *) destp, numItems*4)) + return false; + +#ifdef IS_LITTLE_ENDIAN + for (numItems--; numItems >= 0; numItems--) + destp[numItems] = flipU4(destp[numItems]); +#endif + + return true; +} + + + + diff --git a/ef/Runtime/FileReader/FileReader.h b/ef/Runtime/FileReader/FileReader.h new file mode 100644 index 000000000000..5e1ee40cb14d --- /dev/null +++ b/ef/Runtime/FileReader/FileReader.h @@ -0,0 +1,59 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#ifndef _FILEREADER_H_ +#define _FILEREADER_H_ + +#include "prtypes.h" +#include "Pool.h" + +#ifdef NO_NSPR +#include +#else +#include "prio.h" +#endif + +/* Reads a file, allocating space as neccessary */ +class FileReader { +public: + FileReader(Pool &pool): pool(pool) { } + + /* All read routines return True on success, False on failure */ + + /* read an unsigned byte */ + bool readU1(char *destp, Int32 numItems); + + /* read numItems unsigned 16-bit quantities, flipping bytes if neccessary. + * Returns true on success, false if unable to read numItems. + */ + bool readU2(Uint16 *destp, Int32 numItems); + + /* read an unsigned 32-bit quantity, flipping bytes if neccessary */ + bool readU4(Uint32 *destp, Int32 numItems); + + virtual ~FileReader() { } + +protected: + /* Yes this is an abstract class */ + virtual bool read1(char *destp, int size) = 0; + Pool &pool; +}; + + + +#endif /* _FILEREADER_H_ */ + diff --git a/ef/Runtime/FileReader/Makefile b/ef/Runtime/FileReader/Makefile new file mode 100644 index 000000000000..aa89a022327f --- /dev/null +++ b/ef/Runtime/FileReader/Makefile @@ -0,0 +1,64 @@ +#!gmake +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +####################################################################### +# (1) Directory specific info # +####################################################################### + +DEPTH = ../.. + + +CPPSRCS = DiskFileReader.cpp \ + FileReader.cpp \ + ZipArchive.cpp \ + ZipFileReader.cpp \ + BufferedFileReader.cpp \ + $(NULL) + +LOCAL_EXPORTS = DiskFileReader.h \ + FileReader.h \ + ZipArchive.h \ + ZipFileReader.h \ + BufferedFileReader.h \ + $(NULL) + +MODULE_NAME = EF + +####################################################################### +# (2) Include "component" configuration information. # +####################################################################### + +include $(DEPTH)/config/config.mk + +####################################################################### +# (3) Include "local" platform-dependent assignments (OPTIONAL). # +####################################################################### + + + +####################################################################### +# (4) Execute "component" rules. (OPTIONAL) # +####################################################################### + +include $(DEPTH)/config/rules.mk + +####################################################################### +# (7) Execute "local" rules. (OPTIONAL). # +####################################################################### + + + diff --git a/ef/Runtime/FileReader/ZipArchive.cpp b/ef/Runtime/FileReader/ZipArchive.cpp new file mode 100644 index 000000000000..d2ff75c8a900 --- /dev/null +++ b/ef/Runtime/FileReader/ZipArchive.cpp @@ -0,0 +1,173 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#include +#include + +#include "plstr.h" +#include "prprf.h" + +#include "ZipArchive.h" +#include "CUtils.h" +#include "StringUtils.h" +#include "LogModule.h" + +UT_DEFINE_LOG_MODULE(ZipArchive); + +/* Arcane macros and stuff; borrowed from sun_java source */ + +#define HUGEP + +#ifndef max +#define max(a, b) ((a) > (b) ? (a) : (b)) +#endif + +#ifndef min +#define min(a, b) ((a) < (b) ? (a) : (b)) +#endif + +/* Comparision function for sorting and searching */ +static int direlcmp(const void *d1, const void *d2) +{ + return PL_strcmp(((DirectoryEntry *)d1)->fn, ((DirectoryEntry *)d2)->fn); +} + +/* Public functions */ +ZipArchive::ZipArchive(const char *archiveName, Pool &pool, + bool &status) : pool(pool), strm(0), dir(0) +{ + status = true; + + fp = PR_Open(archiveName, PR_RDONLY, 0); + + if (!fp || !initReader()) { + status = false; + return; + } + +} + + +ZipArchive::~ZipArchive() +{ + if (fp) + PR_Close(fp); +} + +const DirectoryEntry *ZipArchive::lookup(const char *fileName) +{ + // IMPLEMENT + PR_ASSERT(0); + return NULL; +} + +bool ZipArchive::get(const DirectoryEntry *dp, char *&buf, Int32 &len) +{ + // IMPLEMENT + return false; +} + +Uint32 ZipArchive::getNumElements(const char *fn_suffix) +{ + int suf_len = strlen(fn_suffix); + Uint32 nelems; + Uint32 i; + + for (i=0, nelems=0; i < nel; i++) { + char *fn = dir[i].fn; + int fn_len = strlen(fn); + if (PL_strncasecmp(&fn[fn_len - suf_len], fn_suffix, suf_len) == 0) { + nelems++; + } + } + return nelems; +} + +Uint32 ZipArchive::listElements(const char *fn_suffix, char **buf) +{ + int suf_len = strlen(fn_suffix); + Uint32 nelems; + Uint32 i; + buf = new (pool) char *[nel]; + + for (i=0, nelems=0; i < nel; i++) { + char *fn = dir[i].fn; + int fn_len = strlen(fn); + if ((PL_strncasecmp(&fn[fn_len - suf_len], fn_suffix, suf_len) == 0)) { + buf[nelems] = dupString(fn, pool); + nelems++; + } + } + return nelems; +} + +/* Private Functions */ +/* + * Initialize zip file reader, read in central directory and construct the + * lookup table for locating zip file members. + */ +bool ZipArchive::initReader() +{ + // IMPLEMENT + PR_ASSERT(0); + return false; +} + +/* + * Find end of central directory (END) header in zip file and set the file + * pointer to start of header. Return FALSE if the END header could not be + * found, otherwise return TRUE. + */ +bool ZipArchive::findEnd() +{ + // IMPLEMENT + PR_ASSERT(0); + return false; +} + +/* + * Read exactly 'len' bytes of data into 'buf'. Return true if all bytes + * could be read, otherwise return false. + */ +bool ZipArchive::readFully(void *buf, Int32 len) +{ + char *bp = (char *) buf; + + while (len > 0) { + Int32 n = PR_Read(fp, bp, len); + + if (n <= 0) + return false; + + bp += n; + len -= n; + } + + return true; +} + +/* Fully inflate the zip archive into buffer buf, whose length is len. + * Return true on success, false on failure. + */ +bool ZipArchive::inflateFully(Uint32 size, void *buf, Uint32 len, + char **msg) +{ + // IMPLEMENT + PR_ASSERT(0); + return false; +} + diff --git a/ef/Runtime/FileReader/ZipArchive.h b/ef/Runtime/FileReader/ZipArchive.h new file mode 100644 index 000000000000..d294a37951e6 --- /dev/null +++ b/ef/Runtime/FileReader/ZipArchive.h @@ -0,0 +1,129 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#ifndef _ZIP_ARCHIVE_H_ +#define _ZIP_ARCHIVE_H_ + +#include "Fundamentals.h" +#include "zlib.h" + +#include "prio.h" + +/* + * Central zip directory entry + */ +typedef struct { + char *fn; /* file name */ + Uint32 len; /* file size */ + Uint32 size; /* file compressed size */ + Int32 method; /* Compression method */ + Int32 mod; /* file modification time */ + Int32 off; /* local file header offset */ +} DirectoryEntry; + +/* An object that represents a zip archive */ +class ZipArchive { +public: + /* Create a zip archive reader from a zip archive whose + * canonical pathname is archiveName. Pool is used to allocate + * memory for data structures. Sets status to true if it was + * able to successfully open the archive; returns false if + * it could not. + */ + ZipArchive(const char *archiveName, Pool &pool, bool &status); + + ~ZipArchive(); + + /* Read a file given by fileName from the zip archive into + * buf, allocating as much memory as necessary. This memory + * is allocated using the pool passed into the constructor + * and will go away when the pool is destroyed. On success, + * returns true and sets len to the length of the file read. + * Returns false if the file was not found in the archive, or + * if there was an error. + */ + bool get(const char *fileName, char *&buf, Int32 &len) { + const DirectoryEntry *entry = lookup(fileName); + + if (!entry) + return false; + + return get(entry, buf, len); + } + + /* Exactly like get() above, but works with a directory entry + * obtained via lookup(). + */ + bool get(const DirectoryEntry *entry, char *&buf, Int32 &len); + + /* returns true if the given file exists in the archive, false + * otherwise. + */ + bool exists(const char *fileName) { + return (lookup(fileName) != 0); + } + + /* lookup a file and return it's directory entry if it exists. + * If not, return false. + */ + const DirectoryEntry *lookup(const char *fileName); + + /* Return number of elements in the zip archive whose filenames + * have the suffix indicated by fileNameSuffix. + */ + Uint32 getNumElements(const char *fileNameSuffix); + + /* Gets the names of all elements in the zip archive whose filenames + * have the suffix indicated by fileNameSuffix. Returns the number + * of matching elements. Memory for buf is allocated using the + * pool passed into the constructor and is destroyed when the + * pool is destroyed. + */ + Uint32 listElements(const char *fileNameSuffix, char **buf); + + +private: + Pool &pool; /* Pool used to allocate internal memory */ + + /* File descriptor */ + PRFileDesc *fp; + + /* Zip file stream */ + z_stream *strm; + + DirectoryEntry *dir; /* zip file directory */ + Uint32 nel; /* number of directory entries */ + Uint32 cenoff; /* Offset of central directory (CEN) */ + Uint32 endoff; /* Offset of end-of-central-directory record */ + + bool initReader(); + bool findEnd(); + bool readFully(void *buf, Int32 len); + bool inflateFully(Uint32 size, void *buf, Uint32 len, char **msg); +}; + + +#endif /* _ZIP_ARCHIVE_H_ */ + + + + + + + + + diff --git a/ef/Runtime/FileReader/ZipFileReader.cpp b/ef/Runtime/FileReader/ZipFileReader.cpp new file mode 100644 index 000000000000..b852591fcc7e --- /dev/null +++ b/ef/Runtime/FileReader/ZipFileReader.cpp @@ -0,0 +1,43 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#include "ZipFileReader.h" +#include "ErrorHandling.h" +#include + +ZipFileReader::ZipFileReader(Pool &pool, ZipArchive &archive, + const DirectoryEntry *entry) : FileReader(pool) +{ + if (!archive.get(entry, buf, len)) + verifyError(VerifyError::noClassDefFound); + + curr = buf; + limit = buf+len; +} + + +bool ZipFileReader::read1(char *destp, int size) +{ + if (curr+size > limit) + return false; + + memcpy(destp, curr, size); + curr += size; + + return true; +} + diff --git a/ef/Runtime/FileReader/ZipFileReader.h b/ef/Runtime/FileReader/ZipFileReader.h new file mode 100644 index 000000000000..6f7c6081a2b2 --- /dev/null +++ b/ef/Runtime/FileReader/ZipFileReader.h @@ -0,0 +1,42 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#ifndef _ZIP_FILEREADER_H_ +#define _ZIP_FILEREADER_H_ + +#include "FileReader.h" +#include "ZipArchive.h" + +/* Reads a file from a zip archive */ +class ZipFileReader : public FileReader { +public: + ZipFileReader(Pool &pool, ZipArchive &archive, + const DirectoryEntry *entry); + + virtual ~ZipFileReader() { } + +protected: + virtual bool read1(char *destp, int size); + +private: + char *buf; + Int32 len; + char *curr; + const char *limit; +}; + +#endif /* _ZIP_FILEREADER_H_ */ diff --git a/ef/Runtime/FileReader/main.cpp b/ef/Runtime/FileReader/main.cpp new file mode 100644 index 000000000000..64a38aadeec8 --- /dev/null +++ b/ef/Runtime/FileReader/main.cpp @@ -0,0 +1,62 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#include "ZipFileReader.h" +#include "ErrorHandling.h" + +/* Little test program to test ZipFileReader + * argv[1] - zip archive + * argv[2] - filename + * Prints whether the file was found in the archive or not + */ +int main(int, char **argv) +{ + bool status; + Pool pool; + + ZipArchive archive(argv[1], pool, status); + + if (!status) { + printf("Could not open archive\n"); + return 1; + } + + const DirectoryEntry *entry = archive.lookup(argv[2]); + + if (!entry) { + printf("File Name %s not found in file\n", argv[2]); + return 1; + } + + try { + ZipFileReader reader(pool, archive, entry); + } catch (VerifyError err) { + printf("Could not open ZipFileReader for file %s: error %d\n", + argv[2], err.cause); + return 1; + } + + printf("File %s was found; reader successfully created.\n", argv[2]); +} + + +#ifdef DEBUG_LAURENT +#ifdef __GNUC__ +// for gcc with -fhandle-exceptions +void terminate() {} +#endif +#endif diff --git a/ef/Runtime/Makefile b/ef/Runtime/Makefile new file mode 100644 index 000000000000..2d4373ae0ba8 --- /dev/null +++ b/ef/Runtime/Makefile @@ -0,0 +1,55 @@ +#!gmake +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +####################################################################### +# (1) Directory specific info # +####################################################################### + +DEPTH = .. + +DIRS = ClassReader ClassInfo System FileReader NativeMethods +SUBMODULES = $(DIRS) + +MODULE_NAME = EF + +NO_PROGRAM_IN_SUBDIRS = 1 +NO_INSTALL_IN_SUBDIRS = 1 + +####################################################################### +# (2) Include "component" configuration information. # +####################################################################### + +include $(DEPTH)/config/config.mk + +####################################################################### +# (3) Include "local" platform-dependent assignments (OPTIONAL). # +####################################################################### + + + +####################################################################### +# (4) Execute "component" rules. (OPTIONAL) # +####################################################################### + +include $(DEPTH)/config/rules.mk + +####################################################################### +# (7) Execute "local" rules. (OPTIONAL). # +####################################################################### + + + diff --git a/ef/Runtime/NativeMethods/JNIManglers.cpp b/ef/Runtime/NativeMethods/JNIManglers.cpp new file mode 100644 index 000000000000..b40bc87cc3c6 --- /dev/null +++ b/ef/Runtime/NativeMethods/JNIManglers.cpp @@ -0,0 +1,110 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#include "JNIManglers.h" +#include "NativeMethodStubs.h" + +#include "prprf.h" +#include "plstr.h" + +static NativeCallingConvention JNIConventions[] = { +#ifdef XP_PC + nativeCallingConventionStdCallMSVC, +#endif + nativeCallingConventionDefault +}; + +Int32 JNINumConventions = sizeof(JNIConventions) / sizeof(JNIConventions[0]); + +JNIShortMangler::JNIShortMangler() : + NameMangler(JNINumConventions, JNIConventions) { } + +char *JNIShortMangler::mangle(const char *className, + const char *methodName, + const char * /*signature*/, + char *buffer, + Int32 len) +{ + char *bufptr = buffer; + char *bufend = buffer + len; + + /* Copy over Java_ */ + PL_strcpy(bufptr, "Java_"); + bufptr += PL_strlen(bufptr); + + bufptr += NameMangler::mangleUTFString(className, bufptr, + bufend - bufptr, + NameMangler::mangleUTFJNI); + + if (bufend - bufptr > 1) + *bufptr++ = '_'; + else + return 0; + + bufptr += NameMangler::mangleUTFString(methodName, bufptr, + bufend - bufptr, + NameMangler::mangleUTFJNI); + + return buffer; + +} + +Int32 JNIShortMangler::getExtraArgsSize(bool staticMethod) +{ + if (staticMethod) + return 8; /* JNIEnv, jclass */ + else + return 4; /* JNIEnv */ +} + +void *JNIShortMangler::getCode(const Method &method, void *actualCode) +{ + return generateJNIGlue(method, actualCode); +} + +char *JNILongMangler::mangle(const char *className, + const char *methodName, + const char *signature, + char *buffer, + Int32 len) +{ + buffer = JNIShortMangler::mangle(className, methodName, signature, + buffer, len); + len -= PL_strlen(buffer); + char *bufptr = buffer+PL_strlen(buffer); + char *bufend = buffer + len; + + char sig[1024]; + int i; + if (bufend - bufptr > 2) { + *bufptr++ = '_'; + *bufptr++ = '_'; + } else + return 0; + + for (i = 0; i<1023; i++) + if ((sig[i] = signature[i]) == ')') + break; + + sig[i] = 0; + bufptr += NameMangler::mangleUTFString(sig, bufptr, + bufend - bufptr, + mangleUTFJNI); + + return buffer; +} + diff --git a/ef/Runtime/NativeMethods/JNIManglers.h b/ef/Runtime/NativeMethods/JNIManglers.h new file mode 100644 index 000000000000..c9e419216d94 --- /dev/null +++ b/ef/Runtime/NativeMethods/JNIManglers.h @@ -0,0 +1,59 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#ifndef _JNI_MANGLERS_H_ +#define _JNI_MANGLERS_H_ + +/* Name mangling for "short" versions of JNI mangled names (without + * a mangled signature) and "long" versions (with a mangled signature). + */ + +#include "NameMangler.h" + +class NS_EXTERN JNIShortMangler : public NameMangler { +public: + JNIShortMangler(); + JNIShortMangler(Int32 numCallingConventions, + NativeCallingConvention *conventions) : + NameMangler(numCallingConventions, conventions) { } + + virtual char *mangle(const char *className, + const char *methodName, + const char *signature, + char *buffer, + Int32 len); + + virtual Int32 getExtraArgsSize(bool staticMethod); + virtual void *getCode(const Method &, void *actualCode); +}; + +class NS_EXTERN JNILongMangler : public JNIShortMangler { +public: + JNILongMangler() : JNIShortMangler() { } + JNILongMangler(Int32 numCallingConventions, + NativeCallingConvention *conventions) : + JNIShortMangler(numCallingConventions, conventions) { } + + virtual char *mangle(const char *className, + const char *methodName, + const char *signature, + char *buffer, + Int32 len); + +}; + +#endif /* _JNI_SHORT_MANGLER_H_ */ diff --git a/ef/Runtime/NativeMethods/Jni.cpp b/ef/Runtime/NativeMethods/Jni.cpp new file mode 100644 index 000000000000..873fecea3602 --- /dev/null +++ b/ef/Runtime/NativeMethods/Jni.cpp @@ -0,0 +1,2333 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#include "jni.h" +#include "FieldOrMethod.h" +#include "JavaVM.h" +#include "BufferedFileReader.h" +#include "SysCallsRuntime.h" + +#include "prprf.h" + +/* Implementation of the Java Native Interface */ + +/* Some explanation about how JNI works with the native method invoker. + * What is passed in as the jobject argument in JNI methods is a pointer to a JavaObject. + * Likewise, what is passed in as the jclass argument for static JNI methods is + * a pointer to a Class (see JavaObject.h); a jfieldID is a Field; a jmethodID is a Method. + * A local reference, for now, is the same as a pointer to the actual object. We may need to + * change this, so make sure we use accessor methods to convert from objects to local- + * references. + */ + +/* Accessor methods to convert JNI-style objects to internal objects + * and vice-versa + */ +static JavaObject *asJavaObject(jobject obj) { + return (JavaObject *) obj; +} + +static JavaObject *asJavaObject(jthrowable obj) { + /* Make sure object is a sub-class of throwable.. */ + const Class &throwableClazz = Standard::get(cThrowable); + + if (!throwableClazz.isAssignableFrom(asClass(asJavaObject(obj)->getType()))) + return 0; + + return (JavaObject *) obj; +} + +static Type *asJavaType(jclass clz) { + return (Type *) clz; +} + +static Class *asJavaClass(jclass clz) { + if (!clz) + return 0; + + Type *typ = asJavaType(clz); + + if (typ->typeKind != tkObject) + return 0; + + return static_cast(typ); +} + +static Field *asJavaField(jfieldID fld) { + return (Field *) fld; +} + +static Method *asJavaMethod(jmethodID method) { + return (Method *) method; +} + +static JavaString *asJavaString(jstring obj) { + if (!obj) return 0; + + /* Ensure that the object being passed in is a string */ + if (&asJavaObject(obj)->getType() != &asType(Standard::get(cString))) + return 0; + + return (JavaString *) obj; +} + +static jobject asJNIObject(JavaObject *obj) { + return (jobject) obj; +} + +static jthrowable asJNIThrowable(JavaObject *obj) { + return (jthrowable) obj; +} + +static jclass asJNIType(Type *clz) { + return (jclass) clz; +} + +static jfieldID asJNIField(Field *fld) { + return (jfieldID) fld; +} + +static jmethodID asJNIMethod(Method *m) { + return (jmethodID) m; +} + +static jstring asJNIString(JavaString *obj) { + return (jstring) obj; +} + +/* JNI State structure and JNIEnv. There is currently a global JNIState + * and a global JNIEnv, eventually we must consider the possibility of having one of + * these per thread + */ +JNIEnv *jniEnv = 0; + +class JNIState { + static JNIState *jniState; + + /* Set to true if an exception occurred in the current JNI call, or in one + * of its callees. The exception should actually be thrown on exit from the + * JNI call. + */ + bool exceptionOccurred; + + /* Pointer to the exception object if exceptionOccurred is true. */ + JavaObject *exceptionObject; + + /* JNI Env and JNI native function structure passed to JNI methods */ + static struct JNIEnv_ theEnv; + static const struct JNINativeInterface_ jniNativeInterface; + + /* Initialize the JNI environment pointer passed to JNI methods. */ + static void initializeEnv() { + theEnv.functions = &jniNativeInterface; + jniEnv = &theEnv; + } + +public: + JNIState() : exceptionOccurred(false), exceptionObject(0) { } + + /* Initialize the JNI State */ + static void staticInit() { + jniState = new JNIState(); + initializeEnv(); + } + + /* Cleanup JNI subsystem */ + static void cleanup() { if (jniState) delete jniState; } + + /* Get the static JNIState object */ + static JNIState &getJniState() { assert(jniState); return *jniState; } + + /* Allocate a new object whose type is type. */ + jobject allocObject(const Type &type) { + if (type.typeKind == tkObject) + return asJNIObject(&const_cast(static_cast(&type))->newInstance()); + else { + trespass("JNI alloc of non-objects not implemented!"); + return 0; + } + } + + /* Allocate and return a new local reference to the given object */ + jobject newLocalObject(JavaObject *obj) { + if (!obj) return 0; + + return asJNIObject(obj); + } + + /* Allocate and return a new global reference to the given object */ + jobject newGlobalObject(JavaObject *obj) { + if (!obj) return 0; + + return asJNIObject(obj); + } + + /* Delete a local reference */ + void deleteLocalObject(jobject) { } + + /* Delete a global reference */ + void deleteGlobalObject(jobject) { } + + /* Set obj to be the current exception object, turn on exception flag. + * It is currently an error to set an exception without handling an + * already pending exception. + * XXX What does the JNI spec say about this? + */ + void setException(JavaObject *obj) { + if (exceptionOccurred) + trespass("Attempt to throw exception before handling previous one"); + + exceptionOccurred = true; + exceptionObject = obj; + } + + /* Returns true if an exception occurred */ + bool didExceptionOccur() { return exceptionOccurred; } + + /* Return the current exception object */ + JavaObject *getExceptionObject() { + return exceptionObject; + } + + /* Return the current exception message */ + const char *getExceptionMessage() { + if (!exceptionOccurred) + return 0; + + return "VerifyError"; + } + + /* Clear the exception flags */ + void exceptionClear() { + exceptionOccurred = false; + } +}; + +JNIState *JNIState::jniState = 0; + +/** Support functions for JNI Stubs ***/ +void throwJNIExceptionIfNeeded(); +void JNIInitialize(); +void JNICleanup() ; + +/* Check to see if there is a pending exception; if so, throw it. */ +void throwJNIExceptionIfNeeded() +{ + JNIState &jniState = JNIState::getJniState(); + + if (jniState.didExceptionOccur()) { + JavaObject *obj = jniState.getExceptionObject(); + + jniState.exceptionClear(); + + if (obj) + sysThrow(*obj); + else { + assert(0); + } + } +} + + +/*** Interface functions between the JNI and the VM ***/ + +/* Initialize the JNI sub-system */ +void JNIInitialize() +{ + JNIState::staticInit(); +} + +/* Shutdown and cleanup the JNI sub-system */ +void JNICleanup() +{ + JNIState::cleanup(); +} + + +/*** Utility functions used by the jni functions ***/ + +/* Check that type is the type of an object, and + * is a sub-class of java/lang/Throwable. If true, + * return the type cast into a Class. If false, + * return NULL. + */ +static Class *getExceptionClass(Type *javaType) +{ + /* The type of an exception object must be a class */ + if (javaType->typeKind != tkObject) + return 0; + + Class *javaClazz = static_cast(javaType); + + /* javaClazz must be a sub-class of java/lang/Throwable */ + const Class &throwableClazz = Standard::get(cThrowable); + + if (!javaClazz->implements(throwableClazz)) + return 0; + + return javaClazz; +} + +// FIX-ME +// This should go away once the full JNI implementation +// is finished. +#ifdef XP_MAC +#pragma warn_unusedarg off +#endif + +/*** The following are implementations of the JNI interface methods ***/ + +/* returns the version of the VM */ +static JNICALL(jint) jniGetVersion(JNIEnv *env) +{ + /* XXX Need to return the right version */ + return 1; +} + + + +/* Generates a class from the fully qualified class name and + * returns the class object corresponding to the class + */ +static JNICALL(jclass) jniDefineClass(JNIEnv *env, const char *name, + jobject loader, + const jbyte *buf, + jsize len) +{ + if (!name || !buf || !len) + return 0; + + Pool p(10); /* This will not be used anyway */ + BufferedFileReader bf((char *) buf, len, p); + + ClassFileSummary *summ; + + try { + UtfClassName utfClassName(name); + //summ = &VM::getCentral().addClass((char *) utfClassName, bf); + + } catch (VerifyError) { + JNIState &jniState = JNIState::getJniState(); + jniState.setException(0); + return 0; + } + + return asJNIType(summ->getThisClass()); + +} + +/* If the class corresponding to the fully qualified classname + * name has been loaded, returns a reference to the class. + * If not, returns null. + */ +static JNICALL(jclass) jniFindClass(JNIEnv *env, const char *name) +{ + if (!name) + return 0; + + ClassFileSummary *summ; + + try { + UtfClassName utfClassName(name); + + // XXX Need to replace this with central.findClass() + summ = &VM::getCentral().addClass((char *) utfClassName); + } catch (VerifyError) { + JNIState &jniState = JNIState::getJniState(); + jniState.setException(0); + return 0; + } + + return asJNIType(summ->getThisClass()); +} + +static JNICALL(jmethodID) jniFromReflectedMethod (JNIEnv *env, jobject method) +{ + PR_fprintf(PR_STDERR, "jnifromreflectedmethod Not implemented\n"); + return 0; +} + +static JNICALL(jfieldID) jniFromReflectedField (JNIEnv *env, jobject field) +{ + PR_fprintf(PR_STDERR, "jniFromReflectedField() Not implemented\n"); + return 0; +} + + +static JNICALL(jobject) jniToReflectedMethod (JNIEnv *env, jclass cls, jmethodID methodID) +{ + PR_fprintf(PR_STDERR, "Not implemented\n"); + return 0; +} + + +static JNICALL(jclass) jniGetSuperclass(JNIEnv *env, jclass sub) +{ + if (!sub) + return 0; + + Class *subClass = asJavaClass(sub); + + if (!subClass) + return 0; + + return asJNIType(const_cast(subClass->getSuperClass())); +} + +static JNICALL(jboolean) jniIsAssignableFrom(JNIEnv *env, jclass sub, jclass sup) +{ + if (!sub || !sup) + return false; + + Class *subClazz = asJavaClass(sub); + Class *supClazz = asJavaClass(sup); + + if (!subClazz || !supClazz) + return false; + + return supClazz->isAssignableFrom(*subClazz); +} + +static JNICALL (jobject) jniToReflectedField (JNIEnv *env, jclass cls, jfieldID fieldID) +{ + PR_fprintf(PR_STDERR, "jniToReflectedField() Not implemented\n"); + return 0; +} + + +static JNICALL(jint) jniThrow(JNIEnv *env, jthrowable obj) +{ + if (!obj) + return JNI_ERR; + + JavaObject *jobj = asJavaObject(obj); + + if (!getExceptionClass(const_cast(&jobj->getType()))) + return JNI_ERR; + + JNIState &jniState = JNIState::getJniState(); + jniState.setException(jobj); + + return JNI_OK; +} + +static JNICALL(jint) jniThrowNew(JNIEnv *env, jclass clazz, const char *msg) +{ + if (!clazz) + return JNI_ERR; + + Type *javaType = asJavaType(clazz); + + Class *javaClass = getExceptionClass(javaType); + + if (!javaClass) + return JNI_ERR; + + // FIXME msg argument not passed on to exception + JavaObject &obj = javaClass->newInstance(); + + JNIState &jniState = JNIState::getJniState(); + jniState.setException(&obj); + + return JNI_OK; +} + +static JNICALL(jthrowable) jniExceptionOccurred(JNIEnv *env) +{ + JNIState &jniState = JNIState::getJniState(); + + if (jniState.didExceptionOccur()) + return asJNIThrowable(jniState.getExceptionObject()); + else + return 0; +} + +static JNICALL(void) jniExceptionDescribe(JNIEnv *env) +{ + JNIState &jniState = JNIState::getJniState(); + + printf("Error occurred: %s\n", jniState.getExceptionMessage()); +} + +static JNICALL(void) jniExceptionClear(JNIEnv *env) +{ + JNIState &jniState = JNIState::getJniState(); + jniState.exceptionClear(); +} + +static JNICALL(void) jniFatalError(JNIEnv *env, const char *msg) +{ + assert(false); +} + +static JNICALL(jint) jniPushLocalFrame + (JNIEnv *env, jint capacity) +{ + PR_fprintf(PR_STDERR, "jniPushLocalFrame() not implemented\n"); + return 0; +} + +static JNICALL(jobject) jniPopLocalFrame + (JNIEnv *env, jobject result) +{ + PR_fprintf(PR_STDERR, "jniPopLocalFrame() not implemented\n"); + return 0; +} + + +static JNICALL(jobject) jniNewGlobalRef(JNIEnv *env, jobject lobj) +{ + JNIState &jniState = JNIState::getJniState(); + return jniState.newGlobalObject(asJavaObject(lobj)); +} + +static JNICALL(void) jniDeleteGlobalRef(JNIEnv *env, jobject gref) +{ + JNIState &jniState = JNIState::getJniState(); + jniState.deleteGlobalObject(gref); +} + +static JNICALL(void) jniDeleteLocalRef(JNIEnv *env, jobject obj) +{ + JNIState &jniState = JNIState::getJniState(); + jniState.deleteLocalObject(obj); +} + +static JNICALL(jboolean) jniIsSameObject(JNIEnv *env, jobject obj1, jobject obj2) +{ + return (asJavaObject(obj1) == asJavaObject(obj2)); +} + +static JNICALL(jobject) jniNewLocalRef + (JNIEnv *env, jobject ref) +{ + PR_fprintf(PR_STDERR, "jniNewLocalRef() not implemented\n"); + return 0; +} + +static JNICALL(jint) jniEnsureLocalCapacity + (JNIEnv *env, jint capacity) +{ + PR_fprintf(PR_STDERR, "jniEnsureLocalCapacity() not implemented\n"); + return 0; +} + + +static JNICALL(jobject) jniAllocObject(JNIEnv *env, jclass jniClazz) +{ + Class *clazz; + + if (!(clazz = asJavaClass(jniClazz))) + return 0; + + JNIState &jniState = JNIState::getJniState(); + return jniState.allocObject(*clazz); +} + +static JNICALL(jobject) jniNewObject(JNIEnv *env, jclass jniClazz, jmethodID methodID, ...) +{ + Class *clazz; + + if (!(clazz = asJavaClass(jniClazz))) + return 0; + + Method *method = asJavaMethod(methodID); + + if (!method) + return 0; + + /* Ensure that the method is a public constructor of the class */ + if (method->getDeclaringClass() != clazz || + PL_strcmp(method->getName(), "") != 0 || + !(method->getModifiers() & CR_METHOD_STATIC)) + return 0; + + JavaObject &obj = clazz->newInstance(); + + const Signature &sig = method->getSignature(); + + Uint32 *argsToMethod = new Uint32[sig.nArguments*2]; + + Uint32 nWords = 0; + + va_list args; + va_start(args, methodID); + + for (Uint32 i = 0; i < sig.nArguments; i++) { + void *rawArg = va_arg(args, void *); + + if (isDoublewordKind(sig.argumentTypes[i]->typeKind)) { + // XXX We need to keep byte order in mind here! + argsToMethod[nWords++] = (Uint32) rawArg; + argsToMethod[nWords++] = (Uint32) va_arg(args, void *); + } else + argsToMethod[nWords++] = (Uint32) rawArg; + } + + method->invokeRaw(&obj, argsToMethod, nWords); + + return asJNIObject(&obj); +} + +static JNICALL(jobject) jniNewObjectV(JNIEnv *env, jclass clazz, jmethodID methodID, + va_list args) +{ + PR_fprintf(PR_STDERR, "jni.NewObjectV() not implemented\n"); + assert(false); + return 0; +} + +static JNICALL(jobject) jniNewObjectA(JNIEnv *env, jclass clazz, jmethodID methodID, + jvalue *args) +{ + PR_fprintf(PR_STDERR, "jni.NewObjectA() not implemented\n"); + assert(false); + return 0; +} + + +static JNICALL(jclass) jniGetObjectClass(JNIEnv *env, jobject obj) +{ + PR_fprintf(PR_STDERR, "jni.GetObjectClass() not implemented\n"); + assert(false); + return 0; +} + +static JNICALL(jboolean) jniIsInstanceOf(JNIEnv *env, jobject obj, jclass clazz) +{ + if (!obj || !clazz) + return false; + + JavaObject *jobj = asJavaObject(obj); + Type *type = asJavaType(clazz); + + return type->isInstance(*jobj); +} + + +static JNICALL(jmethodID) jniGetMethodID(JNIEnv *env, jclass clazz, const char *name, + const char *sig) +{ + if (!clazz) + return 0; + + Type *javaType = asJavaType(clazz); + + if (javaType->typeKind != tkObject && javaType->typeKind != tkInterface) + return 0; + + ClassOrInterface *javaClass = static_cast(javaType); + + Method *method = javaClass->getMethod(name, sig, false); + + if (method) + return asJNIMethod(method); + else if (javaClass->typeKind == tkObject) { + for (const Class *parentClass = static_cast(javaClass)->getParent(); parentClass; parentClass = parentClass->getParent()) + if ((method = ((ClassOrInterface *)(parentClass))->getMethod(name, sig, true)) != NULL) + return asJNIMethod(method); + + return 0; + } else + return 0; +} + + +static JNICALL(jobject) jniCallObjectMethod (JNIEnv *env, jobject obj, + jmethodID methodID, ...) +{ + PR_fprintf(PR_STDERR, "jni.CallObjectMethod() not implemented\n"); + assert(false); + return 0; +} + +static JNICALL(jobject) jniCallObjectMethodV(JNIEnv *env, jobject obj, + jmethodID methodID, va_list args) +{ + PR_fprintf(PR_STDERR, "jni.CallObjectMethodV() not implemented\n"); + assert(false); + return 0; +} + +static JNICALL(jobject) jniCallObjectMethodA(JNIEnv *env, jobject obj, jmethodID methodID, + jvalue * args) +{ + PR_fprintf(PR_STDERR, "jni.CallObjectMethodA() not implemented\n"); + assert(false); + return 0; +} + + +static JNICALL(jboolean) jniCallBooleanMethod (JNIEnv *env, jobject obj, jmethodID methodID, ...) +{ + PR_fprintf(PR_STDERR, "jni.CallBooleanMethod() not implemented\n"); + assert(false); + return false; +} + +static JNICALL(jboolean) jniCallBooleanMethodV (JNIEnv *env, jobject obj, jmethodID methodID, va_list args) +{ + PR_fprintf(PR_STDERR, "jni.CallBooleanMethodV() not implemented\n"); + assert(false); + return false; +} + +static JNICALL(jboolean) jniCallBooleanMethodA (JNIEnv *env, jobject obj, jmethodID methodID, jvalue * args) +{ + PR_fprintf(PR_STDERR, "jni.CallBooleanMethodA() not implemented\n"); + assert(false); + return false; +} + + +static JNICALL(jbyte) jniCallByteMethod (JNIEnv *env, jobject obj, jmethodID methodID, ...) +{ + PR_fprintf(PR_STDERR, "jni.CallByteMethod() not implemented\n"); + assert(false); + return 0; +} + +static JNICALL(jbyte) jniCallByteMethodV (JNIEnv *env, jobject obj, jmethodID methodID, va_list args) +{ + PR_fprintf(PR_STDERR, "jni.CallByteMethodV() not implemented\n"); + assert(false); + return 0; +} + +static JNICALL(jbyte) jniCallByteMethodA (JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args) +{ + PR_fprintf(PR_STDERR, "jni.CallByteMethodA() not implemented\n"); + assert(false); + return 0; +} + + +static JNICALL(jchar) jniCallCharMethod (JNIEnv *env, jobject obj, jmethodID methodID, ...) +{ + PR_fprintf(PR_STDERR, "jni.CallCharMethod() not implemented\n"); + assert(false); + return 0; +} + +static JNICALL(jchar) jniCallCharMethodV (JNIEnv *env, jobject obj, jmethodID methodID, va_list args) +{ + PR_fprintf(PR_STDERR, "jni.CallCharMethodV() not implemented\n"); + assert(false); + return 0; +} + +static JNICALL(jchar) jniCallCharMethodA (JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args) +{ + PR_fprintf(PR_STDERR, "jni.CallCharMethodA() not implemented\n"); + assert(false); + return 0; +} + + +static JNICALL(jshort) jniCallShortMethod (JNIEnv *env, jobject obj, jmethodID methodID, ...) +{ + PR_fprintf(PR_STDERR, "jni.CallShortMethod() not implemented\n"); + assert(false); + return 0; +} + +static JNICALL(jshort) jniCallShortMethodV (JNIEnv *env, jobject obj, jmethodID methodID, va_list args) +{ + PR_fprintf(PR_STDERR, "jni.CallShortMethodV() not implemented\n"); + assert(false); + return 0; +} + +static JNICALL(jshort) jniCallShortMethodA (JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args) +{ + PR_fprintf(PR_STDERR, "jni.CallShortMethodA() not implemented\n"); + assert(false); + return 0; +} + + +static JNICALL(jint) jniCallIntMethod (JNIEnv *env, jobject obj, jmethodID methodID, ...) +{ + PR_fprintf(PR_STDERR, "jni.CallIntMethod() not implemented\n"); + assert(false); + return 0; +} + +static JNICALL(jint) jniCallIntMethodV (JNIEnv *env, jobject obj, jmethodID methodID, va_list args) +{ + PR_fprintf(PR_STDERR, "jni.CallIntMethodV() not implemented\n"); + assert(false); + return 0; +} + +static JNICALL(jint) jniCallIntMethodA (JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args) +{ + PR_fprintf(PR_STDERR, "jni.CallIntMethodA() not implemented\n"); + assert(false); + return 0; +} + + +static JNICALL(jlong) jniCallLongMethod (JNIEnv *env, jobject obj, jmethodID methodID, ...) +{ + PR_fprintf(PR_STDERR, "jni.CallLongMethod() not implemented\n"); + assert(false); + return 0; +} + +static JNICALL(jlong) jniCallLongMethodV (JNIEnv *env, jobject obj, jmethodID methodID, va_list args) +{ + PR_fprintf(PR_STDERR, "jni.CallLongMethodV() not implemented\n"); + assert(false); + return 0; +} + +static JNICALL(jlong) jniCallLongMethodA (JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args) +{ + PR_fprintf(PR_STDERR, "jni.CallLongMethodA() not implemented\n"); + assert(false); + return 0; +} + + +static JNICALL(jfloat) jniCallFloatMethod (JNIEnv *env, jobject obj, jmethodID methodID, ...) +{ + PR_fprintf(PR_STDERR, "jni.CallFloatMethod() not implemented\n"); + assert(false); + return 0; +} + +static JNICALL(jfloat) jniCallFloatMethodV (JNIEnv *env, jobject obj, jmethodID methodID, va_list args) +{ + PR_fprintf(PR_STDERR, "jni.CallFloatMethodV() not implemented\n"); + assert(false); + return 0; +} + +static JNICALL(jfloat) jniCallFloatMethodA (JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args) +{ + PR_fprintf(PR_STDERR, "jni.CallFloatMethodA() not implemented\n"); + assert(false); + return 0; +} + + +static JNICALL(jdouble) jniCallDoubleMethod (JNIEnv *env, jobject obj, jmethodID methodID, ...) +{ + PR_fprintf(PR_STDERR, "jni.CallDoubleMethod() not implemented\n"); + assert(false); + return 0; +} + +static JNICALL(jdouble) jniCallDoubleMethodV (JNIEnv *env, jobject obj, jmethodID methodID, va_list args) +{ + PR_fprintf(PR_STDERR, "jni.CallDoubleMethodV() not implemented\n"); + assert(false); + return 0; +} + +static JNICALL(jdouble) jniCallDoubleMethodA (JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args) +{ + PR_fprintf(PR_STDERR, "jni.CallDoubleMethodA() not implemented\n"); + assert(false); + return 0; +} + + +static JNICALL(void) jniCallVoidMethod (JNIEnv *env, jobject obj, jmethodID methodID, ...) +{ + PR_fprintf(PR_STDERR, "jni.CallVoidMethod() not implemented\n"); + assert(false); +} + +static JNICALL(void) jniCallVoidMethodV (JNIEnv *env, jobject obj, jmethodID methodID, va_list args) +{ + PR_fprintf(PR_STDERR, "jni.CallVoidMethodV() not implemented\n"); + assert(false); +} + +static JNICALL(void) jniCallVoidMethodA (JNIEnv *env, jobject obj, jmethodID methodID, jvalue * args) +{ + PR_fprintf(PR_STDERR, "jni.CallVoidMethodA() not implemented\n"); + assert(false); +} + + +static JNICALL(jobject) jniCallNonvirtualObjectMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...) +{ + PR_fprintf(PR_STDERR, "jni.CallNonvirtualObjectMethod() not implemented\n"); + assert(false); + return 0; +} + +static JNICALL(jobject) jniCallNonvirtualObjectMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + va_list args) +{ + PR_fprintf(PR_STDERR, "jni.CallNonvirtualObjectMethodV() not implemented\n"); + assert(false); + return 0; +} + +static JNICALL(jobject) jniCallNonvirtualObjectMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + jvalue * args) +{ + PR_fprintf(PR_STDERR, "jni.CallNonvirtualObjectMethodA() not implemented\n"); + assert(false); + return 0; +} + + +static JNICALL(jboolean) jniCallNonvirtualBooleanMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...) +{ + PR_fprintf(PR_STDERR, "jni.CallNonvirtualBooleanMethod() not implemented\n"); + assert(false); + return false; +} + +static JNICALL(jboolean) jniCallNonvirtualBooleanMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + va_list args) +{ + PR_fprintf(PR_STDERR, "jni.CallNonvirtualBooleanMethodV() not implemented\n"); + assert(false); + return false; +} + +static JNICALL(jboolean) jniCallNonvirtualBooleanMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + jvalue * args) +{ + PR_fprintf(PR_STDERR, "jni.CallNonvirtualBooleanMethodA() not implemented\n"); + assert(false); + return false; +} + + +static JNICALL(jbyte) jniCallNonvirtualByteMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...) +{ + PR_fprintf(PR_STDERR, "jni.CallNonvirtualByteMethod() not implemented\n"); + assert(false); + return false; +} + +static JNICALL(jbyte) jniCallNonvirtualByteMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + va_list args) +{ + PR_fprintf(PR_STDERR, "jni.CallNonvirtualByteMethodV() not implemented\n"); + assert(false); + return false; +} + +static JNICALL(jbyte) jniCallNonvirtualByteMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + jvalue *args) +{ + PR_fprintf(PR_STDERR, "jni.CallNonvirtualByteMethodA() not implemented\n"); + assert(false); + return false; +} + + +static JNICALL(jchar) jniCallNonvirtualCharMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...) +{ + PR_fprintf(PR_STDERR, "jni.CallNonvirtualCharMethod() not implemented\n"); + assert(false); + return false; +} + +static JNICALL(jchar) jniCallNonvirtualCharMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + va_list args) +{ + PR_fprintf(PR_STDERR, "jni.CallNonvirtualCharMethodV() not implemented\n"); + assert(false); + return false; +} + +static JNICALL(jchar) jniCallNonvirtualCharMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + jvalue *args) +{ + PR_fprintf(PR_STDERR, "jni.CallNonvirtualCharMethodA() not implemented\n"); + assert(false); + return false; +} + + +static JNICALL(jshort) jniCallNonvirtualShortMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...) +{ + PR_fprintf(PR_STDERR, "jni.CallNonvirtualShortMethod() not implemented\n"); + assert(false); + return 0; +} + +static JNICALL(jshort) jniCallNonvirtualShortMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + va_list args) +{ + PR_fprintf(PR_STDERR, "jni.CallNonvirtualShortMethodV() not implemented\n"); + assert(false); + return 0; +} + +static JNICALL(jshort) jniCallNonvirtualShortMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + jvalue *args) +{ + PR_fprintf(PR_STDERR, "jni.CallNonvirtualShortMethodA() not implemented\n"); + assert(false); + return 0; +} + + +static JNICALL(jint) jniCallNonvirtualIntMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...) +{ + PR_fprintf(PR_STDERR, "jni.CallNonvirtualIntMethod() not implemented\n"); + assert(false); + return 0; +} + +static JNICALL(jint) jniCallNonvirtualIntMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + va_list args) +{ + PR_fprintf(PR_STDERR, "jni.CallNonvirtualIntMethodV() not implemented\n"); + assert(false); + return 0; +} + +static JNICALL(jint) jniCallNonvirtualIntMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + jvalue *args) +{ + PR_fprintf(PR_STDERR, "jni.CallNonvirtualIntMethodA() not implemented\n"); + assert(false); + return 0; +} + + +static JNICALL(jlong) jniCallNonvirtualLongMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...) +{ + PR_fprintf(PR_STDERR, "jni.CallNonvirtualLongMethod() not implemented\n"); + assert(false); + return 0; +} + +static JNICALL(jlong) jniCallNonvirtualLongMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + va_list args) +{ + PR_fprintf(PR_STDERR, "jni.CallNonvirtualLongMethodV() not implemented\n"); + assert(false); + return 0; +} + +static JNICALL(jlong) jniCallNonvirtualLongMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + jvalue *args) +{ + PR_fprintf(PR_STDERR, "jni.CallNonvirtualLongMethodA() not implemented\n"); + assert(false); + return 0; +} + + +static JNICALL(jfloat) jniCallNonvirtualFloatMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...) +{ + PR_fprintf(PR_STDERR, "jni.CallNonvirtualFloatMethod() not implemented\n"); + assert(false); + return 0; +} + +static JNICALL(jfloat) jniCallNonvirtualFloatMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + va_list args) +{ + PR_fprintf(PR_STDERR, "jni.CallNonvirtualFloatMethodV() not implemented\n"); + assert(false); + return 0; +} + +static JNICALL(jfloat) jniCallNonvirtualFloatMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + jvalue *args) +{ + PR_fprintf(PR_STDERR, "jni.CallNonvirtualFloatMethodA() not implemented\n"); + assert(false); + return 0; +} + + +static JNICALL(jdouble) jniCallNonvirtualDoubleMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...) +{ + PR_fprintf(PR_STDERR, "jni.CallNonvirtualDoubleMethod() not implemented\n"); + assert(false); + return 0; +} + +static JNICALL(jdouble) jniCallNonvirtualDoubleMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + va_list args) +{ + PR_fprintf(PR_STDERR, "jni.CallNonvirtualDoubleMethodV() not implemented\n"); + assert(false); + return 0; +} + +static JNICALL(jdouble) jniCallNonvirtualDoubleMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + jvalue *args) +{ + PR_fprintf(PR_STDERR, "jni.CallNonvirtualDoubleMethodA() not implemented\n"); + assert(false); + return 0; +} + + +static JNICALL(void) jniCallNonvirtualVoidMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...) +{ + PR_fprintf(PR_STDERR, "jni.CallNonvirtualVoidMethod() not implemented\n"); + assert(false); +} + +static JNICALL(void) jniCallNonvirtualVoidMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + va_list args) +{ + PR_fprintf(PR_STDERR, "jni.CallNonvirtualVoidMethodV() not implemented\n"); + assert(false); + +} + +static JNICALL(void) jniCallNonvirtualVoidMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + jvalue * args) +{ + PR_fprintf(PR_STDERR, "jni.CallNonvirtualVoidMethodA() not implemented\n"); + assert(false); +} + + +static JNICALL(jfieldID) jniGetFieldID (JNIEnv *env, jclass clazz, const char *name, const char *sig) +{ + PR_fprintf(PR_STDERR, "jni.GetFieldID() not implemented\n"); + assert(false); + return 0; +} + + +static JNICALL(jobject) jniGetObjectField (JNIEnv *env, jobject obj, jfieldID fieldID) +{ + PR_fprintf(PR_STDERR, "jni.GetObjectField() not implemented\n"); + assert(false); + return 0; +} + +static JNICALL(jboolean) jniGetBooleanField (JNIEnv *env, jobject obj, jfieldID fieldID) +{ + PR_fprintf(PR_STDERR, "jni.GetBooleanField() not implemented\n"); + assert(false); + return 0; +} + +static JNICALL(jbyte) jniGetByteField (JNIEnv *env, jobject obj, jfieldID fieldID) +{ + PR_fprintf(PR_STDERR, "jni.GetByteField() not implemented\n"); + assert(false); + return 0; +} + +static JNICALL(jchar) jniGetCharField (JNIEnv *env, jobject obj, jfieldID fieldID) +{ + PR_fprintf(PR_STDERR, "jni.GetCharField() not implemented\n"); + assert(false); + return 0; +} + +static JNICALL(jshort) jniGetShortField (JNIEnv *env, jobject obj, jfieldID fieldID) +{ + PR_fprintf(PR_STDERR, "jni.GetShortField() not implemented\n"); + assert(false); + return 0; +} + +static JNICALL(jint) jniGetIntField (JNIEnv *env, jobject obj, jfieldID fieldID) +{ + PR_fprintf(PR_STDERR, "jni.GetIntField() not implemented\n"); + assert(false); + return 0; +} + +static JNICALL(jlong) jniGetLongField (JNIEnv *env, jobject obj, jfieldID fieldID) +{ + PR_fprintf(PR_STDERR, "jni.GetLongField() not implemented\n"); + assert(false); + return 0; +} + +static JNICALL(jfloat) jniGetFloatField (JNIEnv *env, jobject obj, jfieldID fieldID) +{ + PR_fprintf(PR_STDERR, "jni.GetFloatField() not implemented\n"); + assert(false); + return 0; +} + +static JNICALL(jdouble) jniGetDoubleField (JNIEnv *env, jobject obj, jfieldID fieldID) +{ + PR_fprintf(PR_STDERR, "jni.GetDoubleField() not implemented\n"); + assert(false); + return 0; +} + + +static JNICALL(void) jniSetObjectField (JNIEnv *env, jobject obj, jfieldID fieldID, jobject val) +{ + PR_fprintf(PR_STDERR, "jni.SetObjectField() not implemented\n"); + assert(false); +} + +static JNICALL(void) jniSetBooleanField (JNIEnv *env, jobject obj, jfieldID fieldID, jboolean val) +{ + PR_fprintf(PR_STDERR, "jni.SetBooleanField() not implemented\n"); + assert(false); +} + +static JNICALL(void) jniSetByteField (JNIEnv *env, jobject obj, jfieldID fieldID, jbyte val) +{ + PR_fprintf(PR_STDERR, "jni.SetByteField() not implemented\n"); + assert(false); +} + +static JNICALL(void) jniSetCharField (JNIEnv *env, jobject obj, jfieldID fieldID, jchar val) +{ + PR_fprintf(PR_STDERR, "jni.SetCharField() not implemented\n"); + assert(false); +} + +static JNICALL(void) jniSetShortField (JNIEnv *env, jobject obj, jfieldID fieldID, jshort val) +{ + PR_fprintf(PR_STDERR, "jni.SetShortField() not implemented\n"); + assert(false); +} + +static JNICALL(void) jniSetIntField (JNIEnv *env, jobject obj, jfieldID fieldID, jint val) +{ + PR_fprintf(PR_STDERR, "jni.SetIntField() not implemented\n"); + assert(false); +} + +static JNICALL(void) jniSetLongField (JNIEnv *env, jobject obj, jfieldID fieldID, jlong val) +{ + PR_fprintf(PR_STDERR, "jni.SetLongField() not implemented\n"); + assert(false); +} + +static JNICALL(void) jniSetFloatField (JNIEnv *env, jobject obj, jfieldID fieldID, jfloat val) +{ + PR_fprintf(PR_STDERR, "jni.SetFloatField() not implemented\n"); + assert(false); +} + +static JNICALL(void) jniSetDoubleField (JNIEnv *env, jobject obj, jfieldID fieldID, jdouble val) +{ + PR_fprintf(PR_STDERR, "jni.SetDoubleField() not implemented\n"); + assert(false); +} + + +static JNICALL(jmethodID) jniGetStaticMethodID(JNIEnv *env, jclass clazz, const char *name, const char *sig) +{ + PR_fprintf(PR_STDERR, "jni.GetStaticMethodID() not implemented\n"); + assert(false); + return 0; +} + + +static JNICALL(jobject) jniCallStaticObjectMethod (JNIEnv *env, jclass clazz, jmethodID methodID, ...) +{ + PR_fprintf(PR_STDERR, "jni.CallStaticObjectMethod() not implemented\n"); + assert(false); + return 0; +} + +static JNICALL(jobject) jniCallStaticObjectMethodV (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args) +{ + PR_fprintf(PR_STDERR, "jni.CallStaticObjectMethodV() not implemented\n"); + assert(false); + return 0; +} + +static JNICALL(jobject) jniCallStaticObjectMethodA (JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args) +{ + PR_fprintf(PR_STDERR, "jni.CallStaticObjectMethodA() not implemented\n"); + assert(false); + return 0; +} + + +static JNICALL(jboolean) jniCallStaticBooleanMethod (JNIEnv *env, jclass clazz, jmethodID methodID, ...) +{ + PR_fprintf(PR_STDERR, "jni.CallStaticBooleanMethod() not implemented\n"); + assert(false); + return false; +} + +static JNICALL(jboolean) jniCallStaticBooleanMethodV (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args) +{ + PR_fprintf(PR_STDERR, "jni.CallStaticBooleanMethodV() not implemented\n"); + assert(false); + return false; +} + +static JNICALL(jboolean) jniCallStaticBooleanMethodA (JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args) +{ + PR_fprintf(PR_STDERR, "jni.CallStaticBooleanMethodA() not implemented\n"); + assert(false); + return false; +} + + +static JNICALL(jbyte) jniCallStaticByteMethod (JNIEnv *env, jclass clazz, jmethodID methodID, ...) +{ + PR_fprintf(PR_STDERR, "jni.CallStaticByteMethod() not implemented\n"); + assert(false); + return 0; +} + +static JNICALL(jbyte) jniCallStaticByteMethodV (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args) +{ + PR_fprintf(PR_STDERR, "jni.CallStaticByteMethodV() not implemented\n"); + assert(false); + return 0; +} + +static JNICALL(jbyte) jniCallStaticByteMethodA (JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args) +{ + PR_fprintf(PR_STDERR, "jni.CallStaticByteMethodA() not implemented\n"); + assert(false); + return 0; +} + + +static JNICALL(jchar) jniCallStaticCharMethod (JNIEnv *env, jclass clazz, jmethodID methodID, ...) +{ + PR_fprintf(PR_STDERR, "jni.CallStaticCharMethod() not implemented\n"); + assert(false); + return 0; +} + +static JNICALL(jchar) jniCallStaticCharMethodV (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args) +{ + PR_fprintf(PR_STDERR, "jni.CallStaticCharMethodV() not implemented\n"); + assert(false); + return 0; +} + +static JNICALL(jchar) jniCallStaticCharMethodA (JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args) +{ + PR_fprintf(PR_STDERR, "jni.CallStaticCharMethodA() not implemented\n"); + assert(false); + return 0; +} + + +static JNICALL(jshort) jniCallStaticShortMethod (JNIEnv *env, jclass clazz, jmethodID methodID, ...) +{ + PR_fprintf(PR_STDERR, "jni.CallStaticShortMethod() not implemented\n"); + assert(false); + return 0; +} + +static JNICALL(jshort) jniCallStaticShortMethodV (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args) +{ + PR_fprintf(PR_STDERR, "jni.CallStaticShortMethodV() not implemented\n"); + assert(false); + return 0; +} + +static JNICALL(jshort) jniCallStaticShortMethodA (JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args) +{ + PR_fprintf(PR_STDERR, "jni.CallStaticShortMethodA() not implemented\n"); + assert(false); + return 0; +} + + +static JNICALL(jint) jniCallStaticIntMethod (JNIEnv *env, jclass clazz, jmethodID methodID, ...) +{ + PR_fprintf(PR_STDERR, "jni.CallStaticIntMethod() not implemented\n"); + assert(false); + return 0; +} + +static JNICALL(jint) jniCallStaticIntMethodV (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args) +{ + PR_fprintf(PR_STDERR, "jni.CallStaticIntMethodV() not implemented\n"); + assert(false); + return 0; +} + +static JNICALL(jint) jniCallStaticIntMethodA (JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args) +{ + PR_fprintf(PR_STDERR, "jni.CallStaticIntMethodA() not implemented\n"); + assert(false); + return 0; +} + + +static JNICALL(jlong) jniCallStaticLongMethod (JNIEnv *env, jclass clazz, jmethodID methodID, ...) +{ + PR_fprintf(PR_STDERR, "jni.CallStaticLongMethod() not implemented\n"); + assert(false); + return 0; +} + +static JNICALL(jlong) jniCallStaticLongMethodV (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args) +{ + PR_fprintf(PR_STDERR, "jni.CallStaticLongMethodV() not implemented\n"); + assert(false); + return 0; +} + +static JNICALL(jlong) jniCallStaticLongMethodA (JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args) +{ + PR_fprintf(PR_STDERR, "jni.CallStaticLongMethodA() not implemented\n"); + assert(false); + return 0; +} + + +static JNICALL(jfloat) jniCallStaticFloatMethod (JNIEnv *env, jclass clazz, jmethodID methodID, ...) +{ + PR_fprintf(PR_STDERR, "jni.CallStaticFloatMethod() not implemented\n"); + assert(false); + return 0; +} + +static JNICALL(jfloat) jniCallStaticFloatMethodV (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args) +{ + PR_fprintf(PR_STDERR, "jni.CallStaticFloatMethodV() not implemented\n"); + assert(false); + return 0; +} + +static JNICALL(jfloat) jniCallStaticFloatMethodA (JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args) +{ + PR_fprintf(PR_STDERR, "jni.CallStaticFloatMethodA() not implemented\n"); + assert(false); + return 0; +} + + +static JNICALL(jdouble) jniCallStaticDoubleMethod (JNIEnv *env, jclass clazz, jmethodID methodID, ...) +{ + PR_fprintf(PR_STDERR, "jni.CallStaticDoubleMethod() not implemented\n"); + assert(false); + return 0; +} + +static JNICALL(jdouble) jniCallStaticDoubleMethodV (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args) +{ + PR_fprintf(PR_STDERR, "jni.CallStaticDoubleMethodV() not implemented\n"); + assert(false); + return 0; +} + +static JNICALL(jdouble) jniCallStaticDoubleMethodA (JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args) +{ + PR_fprintf(PR_STDERR, "jni.CallStaticDoubleMethodA() not implemented\n"); + assert(false); + return 0; +} + + +static JNICALL(void) jniCallStaticVoidMethod (JNIEnv *env, jclass cls, jmethodID methodID, ...) +{ + PR_fprintf(PR_STDERR, "jni.CallStaticVoidMethod() not implemented\n"); + assert(false); +} + +static JNICALL(void) jniCallStaticVoidMethodV (JNIEnv *env, jclass cls, jmethodID methodID, va_list args) +{ + PR_fprintf(PR_STDERR, "jni.CallStaticVoidMethodV() not implemented\n"); + assert(false); +} + +static JNICALL(void) jniCallStaticVoidMethodA (JNIEnv *env, jclass cls, jmethodID methodID, jvalue * args) +{ + PR_fprintf(PR_STDERR, "jni.CallStaticVoidMethodA() not implemented\n"); + assert(false); +} + + +static JNICALL(jfieldID) jniGetStaticFieldID (JNIEnv *env, jclass clazz, const char *name, const char *sig) +{ + PR_fprintf(PR_STDERR, "jni.GetStaticFieldID() not implemented\n"); + assert(false); + return 0; +} + +static JNICALL(jobject) jniGetStaticObjectField (JNIEnv *env, jclass clazz, jfieldID fieldID) +{ + PR_fprintf(PR_STDERR, "jni.GetStaticObjectField() not implemented\n"); + assert(false); + return 0; +} + +static JNICALL(jboolean) jniGetStaticBooleanField (JNIEnv *env, jclass clazz, jfieldID fieldID) +{ + PR_fprintf(PR_STDERR, "jni.GetStaticBooleanField() not implemented\n"); + assert(false); + return 0; +} + +static JNICALL(jbyte) jniGetStaticByteField (JNIEnv *env, jclass clazz, jfieldID fieldID) +{ + PR_fprintf(PR_STDERR, "jni.GetStaticByteField() not implemented\n"); + assert(false); + return 0; +} + +static JNICALL(jchar) jniGetStaticCharField (JNIEnv *env, jclass clazz, jfieldID fieldID) +{ + PR_fprintf(PR_STDERR, "jni.GetStaticCharField() not implemented\n"); + assert(false); + return 0; +} + +static JNICALL(jshort) jniGetStaticShortField (JNIEnv *env, jclass clazz, jfieldID fieldID) +{ + PR_fprintf(PR_STDERR, "jni.GetStaticShortField() not implemented\n"); + assert(false); + return 0; +} + +static JNICALL(jint) jniGetStaticIntField (JNIEnv *env, jclass clazz, jfieldID fieldID) +{ + PR_fprintf(PR_STDERR, "jni.GetStaticIntField() not implemented\n"); + assert(false); + return 0; +} + +static JNICALL(jlong) jniGetStaticLongField (JNIEnv *env, jclass clazz, jfieldID fieldID) +{ + PR_fprintf(PR_STDERR, "jni.GetStaticLongField() not implemented\n"); + assert(false); + return 0; +} + +static JNICALL(jfloat) jniGetStaticFloatField (JNIEnv *env, jclass clazz, jfieldID fieldID) +{ + PR_fprintf(PR_STDERR, "jni.GetStaticFloatField() not implemented\n"); + assert(false); + return 0; +} + +static JNICALL(jdouble) jniGetStaticDoubleField (JNIEnv *env, jclass clazz, jfieldID fieldID) +{ + PR_fprintf(PR_STDERR, "jni.GetStaticDoubleField() not implemented\n"); + assert(false); + return 0; +} + + +static JNICALL(void) jniSetStaticObjectField (JNIEnv *env, jclass clazz, jfieldID fieldID, jobject value) +{ + PR_fprintf(PR_STDERR, "jni.SetStaticObjectField() not implemented\n"); + assert(false); +} + +static JNICALL(void) jniSetStaticBooleanField (JNIEnv *env, jclass clazz, jfieldID fieldID, jboolean value) +{ + PR_fprintf(PR_STDERR, "jni.SetStaticBooleanField() not implemented\n"); + assert(false); +} + +static JNICALL(void) jniSetStaticByteField (JNIEnv *env, jclass clazz, jfieldID fieldID, jbyte value) +{ + PR_fprintf(PR_STDERR, "jni.SetStaticByteField() not implemented\n"); + assert(false); +} + +static JNICALL(void) jniSetStaticCharField (JNIEnv *env, jclass clazz, jfieldID fieldID, jchar value) +{ + PR_fprintf(PR_STDERR, "jni.SetStaticCharField() not implemented\n"); + assert(false); +} + +static JNICALL(void) jniSetStaticShortField (JNIEnv *env, jclass clazz, jfieldID fieldID, jshort value) +{ + PR_fprintf(PR_STDERR, "jni.SetStaticShortField() not implemented\n"); + assert(false); +} + +static JNICALL(void) jniSetStaticIntField (JNIEnv *env, jclass clazz, jfieldID fieldID, jint value) +{ + PR_fprintf(PR_STDERR, "jni.SetStaticIntField() not implemented\n"); + assert(false); +} + +static JNICALL(void) jniSetStaticLongField (JNIEnv *env, jclass clazz, jfieldID fieldID, jlong value) +{ + PR_fprintf(PR_STDERR, "jni.SetStaticLongField() not implemented\n"); + assert(false); +} + +static JNICALL(void) jniSetStaticFloatField (JNIEnv *env, jclass clazz, jfieldID fieldID, jfloat value) +{ + PR_fprintf(PR_STDERR, "jni.SetStaticFloatField() not implemented\n"); + assert(false); +} + +static JNICALL(void) jniSetStaticDoubleField (JNIEnv *env, jclass clazz, jfieldID fieldID, jdouble value) +{ + PR_fprintf(PR_STDERR, "jni.SetStaticDoubleField() not implemented\n"); + assert(false); +} + + +static JNICALL(jstring) jniNewString (JNIEnv *env, const jchar *unicode, jsize len) +{ + PR_fprintf(PR_STDERR, "jni.NewString() not implemented\n"); + assert(false); + return 0; +} + +static JNICALL(jsize) jniGetStringLength (JNIEnv *env, jstring str) +{ + PR_fprintf(PR_STDERR, "jni.GetStringLength() not implemented\n"); + assert(false); + return 0; +} + +static JNICALL(const jchar *) jniGetStringChars (JNIEnv *env, jstring str, jboolean *isCopy) +{ + PR_fprintf(PR_STDERR, "jni.GetStringChars() not implemented\n"); + assert(false); + return 0; +} + +static JNICALL(void) jniReleaseStringChars (JNIEnv *env, jstring str, const jchar *chars) +{ + PR_fprintf(PR_STDERR, "jni.ReleaseStringChars() not implemented\n"); + assert(false); +} + + +static JNICALL(jstring) jniNewStringUTF (JNIEnv *env, const char *utf) +{ + PR_fprintf(PR_STDERR, "jni.NewStringUTF() not implemented\n"); + assert(false); + return 0; +} + +static JNICALL(jsize) jniGetStringUTFLength(JNIEnv *env, jstring str) +{ + JavaString *jstr = asJavaString(str); + + if (!jstr) + return 0; + + // XXX This returns the length of the string; not sure if + // this is what they mean. + return jstr->getLength(); +} + +static JNICALL(const char*) jniGetStringUTFChars(JNIEnv *env, jstring str, jboolean *isCopy) +{ + JavaString *jstr = asJavaString(str); + + if (!jstr) return 0; + + if (isCopy) *isCopy = true; + + return jstr->convertUtf(); +} + +static JNICALL(void) jniReleaseStringUTFChars(JNIEnv *env, jstring str, const char *chars) +{ + if (!chars) + return; + + JavaString::freeUtf((char *) chars); +} + + + +static JNICALL(jsize) jniGetArrayLength(JNIEnv *env, jarray array) +{ + PR_fprintf(PR_STDERR, "jni.GetArrayLength() not implemented\n"); + assert(false); + return 0; +} + + +static JNICALL(jobjectArray) jniNewObjectArray (JNIEnv *env, jsize len, jclass clazz, jobject init) +{ + PR_fprintf(PR_STDERR, "jni.NewObjectArray() not implemented\n"); + assert(false); + return 0; +} + +static JNICALL(jobject) jniGetObjectArrayElement (JNIEnv *env, jobjectArray array, jsize index) +{ + PR_fprintf(PR_STDERR, "jni.GetObjectArrayElement() not implemented\n"); + assert(false); + return 0; +} + +static JNICALL(void) jniSetObjectArrayElement (JNIEnv *env, jobjectArray array, jsize index, jobject val) +{ + PR_fprintf(PR_STDERR, "jni.SetObjectArrayElement() not implemented\n"); + assert(false); +} + + +static JNICALL(jbooleanArray) jniNewBooleanArray (JNIEnv *env, jsize len) +{ + PR_fprintf(PR_STDERR, "jni.NewBooleanArray() not implemented\n"); + assert(false); + return 0; +} + +static JNICALL(jbyteArray) jniNewByteArray (JNIEnv *env, jsize len) +{ + PR_fprintf(PR_STDERR, "jni.NewByteArray() not implemented\n"); + assert(false); + return 0; +} + +static JNICALL(jcharArray) jniNewCharArray (JNIEnv *env, jsize len) +{ + PR_fprintf(PR_STDERR, "jni.NewCharArray() not implemented\n"); + assert(false); + return 0; +} + +static JNICALL(jshortArray) jniNewShortArray (JNIEnv *env, jsize len) +{ + PR_fprintf(PR_STDERR, "jni.NewShortArray() not implemented\n"); + assert(false); + return 0; +} + +static JNICALL(jintArray) jniNewIntArray (JNIEnv *env, jsize len) +{ + PR_fprintf(PR_STDERR, "jni.NewIntArray() not implemented\n"); + assert(false); + return 0; +} + +static JNICALL(jlongArray) jniNewLongArray (JNIEnv *env, jsize len) +{ + PR_fprintf(PR_STDERR, "jni.NewLongArray() not implemented\n"); + assert(false); + return 0; +} + +static JNICALL(jfloatArray) jniNewFloatArray (JNIEnv *env, jsize len) +{ + PR_fprintf(PR_STDERR, "jni.NewFloatArray() not implemented\n"); + assert(false); + return 0; +} + +static JNICALL(jdoubleArray) jniNewDoubleArray (JNIEnv *env, jsize len) +{ + PR_fprintf(PR_STDERR, "jni.NewDoubleArray() not implemented\n"); + assert(false); + return 0; +} + + +static JNICALL(jboolean *) jniGetBooleanArrayElements (JNIEnv *env, jbooleanArray array, jboolean *isCopy) +{ + PR_fprintf(PR_STDERR, "jni.GetBooleanArrayElements() not implemented\n"); + assert(false); + return 0; +} + +static JNICALL(jbyte *) jniGetByteArrayElements (JNIEnv *env, jbyteArray array, jboolean *isCopy) +{ + PR_fprintf(PR_STDERR, "jni.GetByteArrayElements() not implemented\n"); + assert(false); + return 0; +} + +static JNICALL(jchar *) jniGetCharArrayElements (JNIEnv *env, jcharArray array, jboolean *isCopy) +{ + PR_fprintf(PR_STDERR, "jni.GetCharArrayElements() not implemented\n"); + assert(false); + return 0; +} + +static JNICALL(jshort *) jniGetShortArrayElements (JNIEnv *env, jshortArray array, jboolean *isCopy) +{ + PR_fprintf(PR_STDERR, "jni.GetShortArrayElements() not implemented\n"); + assert(false); + return 0; +} + +static JNICALL(jint *) jniGetIntArrayElements (JNIEnv *env, jintArray array, jboolean *isCopy) +{ + PR_fprintf(PR_STDERR, "jni.GetIntArrayElements() not implemented\n"); + assert(false); + return 0; +} + +static JNICALL(jlong *) jniGetLongArrayElements (JNIEnv *env, jlongArray array, jboolean *isCopy) +{ + PR_fprintf(PR_STDERR, "jni.GetLongArrayElements() not implemented\n"); + assert(false); + return 0; +} + +static JNICALL(jfloat *) jniGetFloatArrayElements (JNIEnv *env, jfloatArray array, jboolean *isCopy) +{ + PR_fprintf(PR_STDERR, "jni.GetFloatArrayElements() not implemented\n"); + assert(false); + return 0; +} + +static JNICALL(jdouble *) jniGetDoubleArrayElements (JNIEnv *env, jdoubleArray array, jboolean *isCopy) +{ + PR_fprintf(PR_STDERR, "jni.GetDoubleArrayElements() not implemented\n"); + assert(false); + return 0; +} + + +static JNICALL(void) jniReleaseBooleanArrayElements (JNIEnv *env, jbooleanArray array, jboolean *elems, jint mode) +{ + PR_fprintf(PR_STDERR, "jni.ReleaseBooleanArrayElements() not implemented\n"); + assert(false); +} + +static JNICALL(void) jniReleaseByteArrayElements (JNIEnv *env, jbyteArray array, jbyte *elems, jint mode) +{ + PR_fprintf(PR_STDERR, "jni.ReleaseByteArrayElements() not implemented\n"); + assert(false); +} + +static JNICALL(void) jniReleaseCharArrayElements (JNIEnv *env, jcharArray array, jchar *elems, jint mode) +{ + assert(false); +} + +static JNICALL(void) jniReleaseShortArrayElements (JNIEnv *env, jshortArray array, jshort *elems, jint mode) +{ + PR_fprintf(PR_STDERR, "jni.ReleaseShortArrayElements() not implemented\n"); + assert(false); +} + +static JNICALL(void) jniReleaseIntArrayElements (JNIEnv *env, jintArray array, jint *elems, jint mode) +{ + PR_fprintf(PR_STDERR, "jni.ReleaseIntArrayElements() not implemented\n"); + assert(false); +} + +static JNICALL(void) jniReleaseLongArrayElements (JNIEnv *env, jlongArray array, jlong *elems, jint mode) +{ + PR_fprintf(PR_STDERR, "jni.ReleaseLongArrayElements() not implemented\n"); + assert(false); +} + +static JNICALL(void) jniReleaseFloatArrayElements (JNIEnv *env, jfloatArray array, jfloat *elems, jint mode) +{ + PR_fprintf(PR_STDERR, "jni.ReleaseFloatArrayElements() not implemented\n"); + assert(false); +} + +static JNICALL(void) jniReleaseDoubleArrayElements (JNIEnv *env, jdoubleArray array, jdouble *elems, jint mode) +{ + PR_fprintf(PR_STDERR, "jni.ReleaseDoubleArrayElements() not implemented\n"); + assert(false); +} + + +static JNICALL(void) jniGetBooleanArrayRegion (JNIEnv *env, jbooleanArray array, jsize start, jsize l, jboolean *buf) +{ + PR_fprintf(PR_STDERR, "jni.GetBooleanArrayRegion() not implemented\n"); + assert(false); +} + +static JNICALL(void) jniGetByteArrayRegion (JNIEnv *env, jbyteArray array, jsize start, jsize len, jbyte *buf) +{ + PR_fprintf(PR_STDERR, "jni.GetByteArrayRegion() not implemented\n"); + assert(false); +} + +static JNICALL(void) jniGetCharArrayRegion (JNIEnv *env, jcharArray array, jsize start, jsize len, jchar *buf) +{ + PR_fprintf(PR_STDERR, "jni.GetCharArrayRegion() not implemented\n"); + assert(false); +} + +static JNICALL(void) jniGetShortArrayRegion (JNIEnv *env, jshortArray array, jsize start, jsize len, jshort *buf) +{ + PR_fprintf(PR_STDERR, "jni.GetShortArrayRegion() not implemented\n"); + assert(false); +} + +static JNICALL(void) jniGetIntArrayRegion (JNIEnv *env, jintArray array, jsize start, jsize len, jint *buf) +{ + PR_fprintf(PR_STDERR, "jni.GetIntArrayRegion() not implemented\n"); + assert(false); +} + +static JNICALL(void) jniGetLongArrayRegion (JNIEnv *env, jlongArray array, jsize start, jsize len, jlong *buf) +{ + PR_fprintf(PR_STDERR, "jni.GetLongArrayRegion() not implemented\n"); + assert(false); +} + +static JNICALL(void) jniGetFloatArrayRegion (JNIEnv *env, jfloatArray array, jsize start, jsize len, jfloat *buf) +{ + PR_fprintf(PR_STDERR, "jni.GetFloatArrayRegion() not implemented\n"); + assert(false); +} + +static JNICALL(void) jniGetDoubleArrayRegion (JNIEnv *env, jdoubleArray array, jsize start, jsize len, jdouble *buf) +{ + PR_fprintf(PR_STDERR, "jni.GetDoubleArrayRegion() not implemented\n"); + assert(false); +} + + +static JNICALL(void) jniSetBooleanArrayRegion (JNIEnv *env, jbooleanArray array, jsize start, jsize l, jboolean *buf) +{ + PR_fprintf(PR_STDERR, "jni.SetBooleanArrayRegion() not implemented\n"); + assert(false); +} + +static JNICALL(void) jniSetByteArrayRegion (JNIEnv *env, jbyteArray array, jsize start, jsize len, jbyte *buf) +{ + PR_fprintf(PR_STDERR, "jni.SetByteArrayRegion() not implemented\n"); + assert(false); +} + +static JNICALL(void) jniSetCharArrayRegion (JNIEnv *env, jcharArray array, jsize start, jsize len, jchar *buf) +{ + PR_fprintf(PR_STDERR, "jni.SetCharArrayRegion() not implemented\n"); + assert(false); +} + +static JNICALL(void) jniSetShortArrayRegion (JNIEnv *env, jshortArray array, jsize start, jsize len, jshort *buf) +{ + PR_fprintf(PR_STDERR, "jni.SetShortArrayRegion() not implemented\n"); + assert(false); +} + +static JNICALL(void) jniSetIntArrayRegion (JNIEnv *env, jintArray array, jsize start, jsize len, jint *buf) +{ + PR_fprintf(PR_STDERR, "jni.SetIntArrayRegion() not implemented\n"); + assert(false); +} + +static JNICALL(void) jniSetLongArrayRegion (JNIEnv *env, jlongArray array, jsize start, jsize len, jlong *buf) +{ + PR_fprintf(PR_STDERR, "jni.SetLongArrayRegion() not implemented\n"); + assert(false); +} + +static JNICALL(void) jniSetFloatArrayRegion (JNIEnv *env, jfloatArray array, jsize start, jsize len, jfloat *buf) +{ + PR_fprintf(PR_STDERR, "jni.SetFloatArrayRegion() not implemented\n"); + assert(false); +} + +static JNICALL(void) jniSetDoubleArrayRegion (JNIEnv *env, jdoubleArray array, jsize start, jsize len, jdouble *buf) +{ + PR_fprintf(PR_STDERR, "jni.SetDoubleArrayRegion() not implemented\n"); + assert(false); +} + + +static JNICALL(jint) jniRegisterNatives (JNIEnv *env, jclass clazz, const JNINativeMethod *methods, + jint nMethods) +{ + PR_fprintf(PR_STDERR, "jni.RegisterNatives() not implemented\n"); + assert(false); + return 0; +} + +static JNICALL(jint) jniUnregisterNatives (JNIEnv *env, jclass clazz) +{ + PR_fprintf(PR_STDERR, "jni.UnregisterNatives() not implemented\n"); + assert(false); + return 0; +} + + +static JNICALL(jint) jniMonitorEnter (JNIEnv *env, jobject obj) +{ + PR_fprintf(PR_STDERR, "jni.MonitorEnter() not implemented\n"); + assert(false); + return 0; +} + +static JNICALL(jint) jniMonitorExit (JNIEnv *env, jobject obj) +{ + PR_fprintf(PR_STDERR, "jni.MonitorExit() not implemented\n"); + assert(false); + return 0; +} + + +static JNICALL(jint) jniGetJavaVM (JNIEnv *env, JavaVM **vm) +{ + PR_fprintf(PR_STDERR, "jni.GetJavaVM() not implemented\n"); + assert(false); + return 0; +} + +static JNICALL(void ) jniGetStringRegion + (JNIEnv *env, jstring str, jsize start, jsize len, jchar *buf) +{ + PR_fprintf(PR_STDERR, "jniGetStringRegion() not implemented\n"); + assert(false); +} + +static JNICALL(void) jniGetStringUTFRegion(JNIEnv *env, jstring str, jsize start, + jsize len, char *buf) +{ + JavaString *jstr = asJavaString(str); + + if (!jstr) + return; + + // Buf is allocated by the user. + char *utfString = jstr->convertUtf(); + Int32 stringLength = jstr->getLength(); + + if ((start+len) >= stringLength) + return; // What should we do here? + + strncpy(buf, &utfString[start], len); + buf[start+len] = 0; +} + +static JNICALL(void * ) jniGetPrimitiveArrayCritical + (JNIEnv *env, jarray array, jboolean *isCopy) +{ + PR_fprintf(PR_STDERR, "jnigetprimitivearraycritical() not implemented\n"); + return 0; +} + +static JNICALL(void ) jniReleasePrimitiveArrayCritical + (JNIEnv *env, jarray array, void *carray, jint mode) +{ + PR_fprintf(PR_STDERR, "jnireleaseprimitivearraycritical() not implemented\n"); +} + +static JNICALL(const jchar * ) jniGetStringCritical + (JNIEnv *env, jstring string, jboolean *isCopy) +{ + PR_fprintf(PR_STDERR, "jnigetstringcritical() not implemented\n"); + return 0; +} + +static JNICALL(void ) jniReleaseStringCritical + (JNIEnv *env, jstring string, const jchar *cstring) +{ + PR_fprintf(PR_STDERR, "jnireleasestringcritical() not implemented\n"); +} + + +static JNICALL(jweak ) jniNewWeakGlobalRef + (JNIEnv *env, jobject obj) +{ + PR_fprintf(PR_STDERR, "jninewweakglobalref() not implemented\n"); + return 0; +} + +static JNICALL(void ) jniDeleteWeakGlobalRef + (JNIEnv *env, jweak ref) +{ + PR_fprintf(PR_STDERR, "jnideleteweakglobalref() not implemented\n"); +} + +static JNICALL(jboolean ) jniExceptionCheck + (JNIEnv *env) +{ + PR_fprintf(PR_STDERR, "jniexceptioncheck() not implemented\n"); + return 0; +} + +const struct JNINativeInterface_ JNIState::jniNativeInterface = { + NULL, + NULL, + NULL, + + NULL, + + jniGetVersion, + + jniDefineClass, + jniFindClass, + + jniFromReflectedMethod, + jniFromReflectedField, + + jniToReflectedMethod, + + jniGetSuperclass, + jniIsAssignableFrom, + + jniToReflectedField, + + jniThrow, + jniThrowNew, + jniExceptionOccurred, + jniExceptionDescribe, + jniExceptionClear, + jniFatalError, + + jniPushLocalFrame, + jniPopLocalFrame, + + jniNewGlobalRef, + jniDeleteGlobalRef, + jniDeleteLocalRef, + jniIsSameObject, + + jniNewLocalRef, + jniEnsureLocalCapacity, + + jniAllocObject, + jniNewObject, + jniNewObjectV, + jniNewObjectA, + + jniGetObjectClass, + jniIsInstanceOf, + + jniGetMethodID, + + jniCallObjectMethod, + jniCallObjectMethodV, + jniCallObjectMethodA, + jniCallBooleanMethod, + jniCallBooleanMethodV, + jniCallBooleanMethodA, + jniCallByteMethod, + jniCallByteMethodV, + jniCallByteMethodA, + jniCallCharMethod, + jniCallCharMethodV, + jniCallCharMethodA, + jniCallShortMethod, + jniCallShortMethodV, + jniCallShortMethodA, + jniCallIntMethod, + jniCallIntMethodV, + jniCallIntMethodA, + jniCallLongMethod, + jniCallLongMethodV, + jniCallLongMethodA, + jniCallFloatMethod, + jniCallFloatMethodV, + jniCallFloatMethodA, + jniCallDoubleMethod, + jniCallDoubleMethodV, + jniCallDoubleMethodA, + jniCallVoidMethod, + jniCallVoidMethodV, + jniCallVoidMethodA, + + jniCallNonvirtualObjectMethod, + jniCallNonvirtualObjectMethodV, + jniCallNonvirtualObjectMethodA, + jniCallNonvirtualBooleanMethod, + jniCallNonvirtualBooleanMethodV, + jniCallNonvirtualBooleanMethodA, + jniCallNonvirtualByteMethod, + jniCallNonvirtualByteMethodV, + jniCallNonvirtualByteMethodA, + jniCallNonvirtualCharMethod, + jniCallNonvirtualCharMethodV, + jniCallNonvirtualCharMethodA, + jniCallNonvirtualShortMethod, + jniCallNonvirtualShortMethodV, + jniCallNonvirtualShortMethodA, + jniCallNonvirtualIntMethod, + jniCallNonvirtualIntMethodV, + jniCallNonvirtualIntMethodA, + jniCallNonvirtualLongMethod, + jniCallNonvirtualLongMethodV, + jniCallNonvirtualLongMethodA, + jniCallNonvirtualFloatMethod, + jniCallNonvirtualFloatMethodV, + jniCallNonvirtualFloatMethodA, + jniCallNonvirtualDoubleMethod, + jniCallNonvirtualDoubleMethodV, + jniCallNonvirtualDoubleMethodA, + jniCallNonvirtualVoidMethod, + jniCallNonvirtualVoidMethodV, + jniCallNonvirtualVoidMethodA, + + jniGetFieldID, + + jniGetObjectField, + jniGetBooleanField, + jniGetByteField, + jniGetCharField, + jniGetShortField, + jniGetIntField, + jniGetLongField, + jniGetFloatField, + jniGetDoubleField, + + jniSetObjectField, + jniSetBooleanField, + jniSetByteField, + jniSetCharField, + jniSetShortField, + jniSetIntField, + jniSetLongField, + jniSetFloatField, + jniSetDoubleField, + + jniGetStaticMethodID, + + jniCallStaticObjectMethod, + jniCallStaticObjectMethodV, + jniCallStaticObjectMethodA, + jniCallStaticBooleanMethod, + jniCallStaticBooleanMethodV, + jniCallStaticBooleanMethodA, + jniCallStaticByteMethod, + jniCallStaticByteMethodV, + jniCallStaticByteMethodA, + jniCallStaticCharMethod, + jniCallStaticCharMethodV, + jniCallStaticCharMethodA, + jniCallStaticShortMethod, + jniCallStaticShortMethodV, + jniCallStaticShortMethodA, + jniCallStaticIntMethod, + jniCallStaticIntMethodV, + jniCallStaticIntMethodA, + jniCallStaticLongMethod, + jniCallStaticLongMethodV, + jniCallStaticLongMethodA, + jniCallStaticFloatMethod, + jniCallStaticFloatMethodV, + jniCallStaticFloatMethodA, + jniCallStaticDoubleMethod, + jniCallStaticDoubleMethodV, + jniCallStaticDoubleMethodA, + jniCallStaticVoidMethod, + jniCallStaticVoidMethodV, + jniCallStaticVoidMethodA, + + jniGetStaticFieldID, + + jniGetStaticObjectField, + jniGetStaticBooleanField, + jniGetStaticByteField, + jniGetStaticCharField, + jniGetStaticShortField, + jniGetStaticIntField, + jniGetStaticLongField, + jniGetStaticFloatField, + jniGetStaticDoubleField, + + jniSetStaticObjectField, + jniSetStaticBooleanField, + jniSetStaticByteField, + jniSetStaticCharField, + jniSetStaticShortField, + jniSetStaticIntField, + jniSetStaticLongField, + jniSetStaticFloatField, + jniSetStaticDoubleField, + + jniNewString, + jniGetStringLength, + jniGetStringChars, + jniReleaseStringChars, + + jniNewStringUTF, + jniGetStringUTFLength, + jniGetStringUTFChars, + jniReleaseStringUTFChars, + + jniGetArrayLength, + + jniNewObjectArray, + jniGetObjectArrayElement, + jniSetObjectArrayElement, + + jniNewBooleanArray, + jniNewByteArray, + jniNewCharArray, + jniNewShortArray, + jniNewIntArray, + jniNewLongArray, + jniNewFloatArray, + jniNewDoubleArray, + + jniGetBooleanArrayElements, + jniGetByteArrayElements, + jniGetCharArrayElements, + jniGetShortArrayElements, + jniGetIntArrayElements, + jniGetLongArrayElements, + jniGetFloatArrayElements, + jniGetDoubleArrayElements, + + jniReleaseBooleanArrayElements, + jniReleaseByteArrayElements, + jniReleaseCharArrayElements, + jniReleaseShortArrayElements, + jniReleaseIntArrayElements, + jniReleaseLongArrayElements, + jniReleaseFloatArrayElements, + jniReleaseDoubleArrayElements, + + jniGetBooleanArrayRegion, + jniGetByteArrayRegion, + jniGetCharArrayRegion, + jniGetShortArrayRegion, + jniGetIntArrayRegion, + jniGetLongArrayRegion, + jniGetFloatArrayRegion, + jniGetDoubleArrayRegion, + + jniSetBooleanArrayRegion, + jniSetByteArrayRegion, + jniSetCharArrayRegion, + jniSetShortArrayRegion, + jniSetIntArrayRegion, + jniSetLongArrayRegion, + jniSetFloatArrayRegion, + jniSetDoubleArrayRegion, + + jniRegisterNatives, + jniUnregisterNatives, + + jniMonitorEnter, + jniMonitorExit, + + jniGetJavaVM, + + jniGetStringRegion, + jniGetStringUTFRegion, + + jniGetPrimitiveArrayCritical, + jniReleasePrimitiveArrayCritical, + + jniGetStringChars, + jniReleaseStringChars, + + jniNewWeakGlobalRef, + jniDeleteWeakGlobalRef, + + jniExceptionCheck + +}; + + +struct JNIEnv_ JNIState::theEnv; + +#ifdef XP_MAC +#pragma warn_unusedarg reset +#endif diff --git a/ef/Runtime/NativeMethods/JniRuntime.h b/ef/Runtime/NativeMethods/JniRuntime.h new file mode 100644 index 000000000000..5c10f234f63c --- /dev/null +++ b/ef/Runtime/NativeMethods/JniRuntime.h @@ -0,0 +1,26 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#ifndef _JNI_RUNTIME_H_ +#define _JNI_RUNTIME_H_ + +void JNIInitialize(); + +void JNICleanup(); + + +#endif /* _JNI_RUNTIME_H_ */ diff --git a/ef/Runtime/NativeMethods/Makefile b/ef/Runtime/NativeMethods/Makefile new file mode 100644 index 000000000000..997e50aece30 --- /dev/null +++ b/ef/Runtime/NativeMethods/Makefile @@ -0,0 +1,68 @@ +#!gmake +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +####################################################################### +# (1) Directory specific info # +####################################################################### + +DEPTH = ../.. + +DIRS = md +SUBMODULES = $(DIRS) + +CPPSRCS = JNIManglers.cpp \ + NameMangler.cpp \ + NativeMethodDispatcher.cpp \ + NetscapeManglers.cpp \ + Jni.cpp \ + $(NULL) + +LOCAL_EXPORTS = JNIManglers.h \ + NameMangler.h \ + NativeMethodDispatcher.h \ + NetscapeManglers.h \ + NativeDefs.h \ + NativeMethodStubs.h \ + JniRuntime.h \ + $(NULL) + +MODULE_NAME = EF + +####################################################################### +# (2) Include "component" configuration information. # +####################################################################### + +include $(DEPTH)/config/config.mk + +####################################################################### +# (3) Include "local" platform-dependent assignments (OPTIONAL). # +####################################################################### + + + +####################################################################### +# (4) Execute "component" rules. (OPTIONAL) # +####################################################################### + +include $(DEPTH)/config/rules.mk + +####################################################################### +# (7) Execute "local" rules. (OPTIONAL). # +####################################################################### + + + diff --git a/ef/Runtime/NativeMethods/NameMangler.cpp b/ef/Runtime/NativeMethods/NameMangler.cpp new file mode 100644 index 000000000000..1d5be916dd9a --- /dev/null +++ b/ef/Runtime/NativeMethods/NameMangler.cpp @@ -0,0 +1,45 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#include "NameMangler.h" + +#include + +#include "prprf.h" +#include "plstr.h" + +typedef Uint16 unicode; + +Int32 NameMangler::mangleUTFString(const char *name, + char *buffer, + int buflen, + NameMangler::MangleUTFType type) +{ + // IMPLEMENT + PR_ASSERT(0); + return 0; +} + +Int32 NameMangler::mangleUnicodeChar(Int32 ch, char *bufptr, + char *bufend) +{ + char temp[10]; + PR_snprintf(temp, 10, "_%.5x", ch); /* six characters always plus null */ + (void) PR_snprintf(bufptr, bufend - bufptr, "%s", temp); + return PL_strlen(bufptr); +} + diff --git a/ef/Runtime/NativeMethods/NameMangler.h b/ef/Runtime/NativeMethods/NameMangler.h new file mode 100644 index 000000000000..7836d0a785e3 --- /dev/null +++ b/ef/Runtime/NativeMethods/NameMangler.h @@ -0,0 +1,115 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#ifndef _NAME_MANGLER_H_ +#define _NAME_MANGLER_H_ + +#include "Fundamentals.h" +#include "FieldOrMethod.h" + +/* Some platforms (ok, windows) have more than one native calling + * convention. This enumerates the different available types. + */ +enum NativeCallingConvention { + nativeCallingConventionInvalid = 0, + nativeCallingConventionStdCallMSVC, /* Windows MS VC only: stdcall */ + nativeCallingConventionCCallMSVC, /* Windows only: C call */ + nativeCallingConventionFastCallMSVC, /* Windows only: fast call */ + nativeCallingConventionDefault /* Default C calling convention on + * platforms other than windows. + */ +}; + +/* A NameMangler class handles name-mangling for a particular type + * of native-method dispatch. It does not do the platform-specific + * name-mangling although it provides information about which calling + * conventions are supported (if the native platform supports more than + * one). + */ +class NS_EXTERN NameMangler { +public: + NameMangler(Int32 numCallingConventions, + NativeCallingConvention *conventions) : + numCallingConventions(numCallingConventions), + conventions(conventions) { } + + /* Given a classname, method name and signature string of the method, + * produce a mangled name that can be looked for in a shared lib/symbol + * table. buffer must be preallocated by the caller and must be of length + * len. If there is not enough space for the mangled name, this routine + * returns 0. + */ + virtual char *mangle(const char *className, + const char *methodName, + const char *signature, + char *buffer, + Int32 len) = 0; + + /* Return extra size in bytes of any extra arguments that are to + * be passed to the native method. Note that the VM has already taken into + * account the "this" pointer to an object, which is passed as the + * first argument to the method. if staticMethod is true, then the + * method in question is a static method. Otherwise, it's an instance + * method. + */ + virtual Int32 getExtraArgsSize(bool staticMethod) = 0; + + /* Return a pointer to the first instruction of the "processed" + * native method. "method" is the method in question, and actualCode + * is a pointer to the native code as found in a shared library. + * This method could potentially insert stubs and/or modify + * the code appropriately so that the VM can call this + * method. + */ + virtual void *getCode(const Method &method, void *actualCode) = 0; + + /* return the number of native method conventions on the given + * platform allowed for this mangling scheme. + */ + Int32 numNativeConventions() { return numCallingConventions; } + + /* Get the native calling conventions supported by this mangling + * scheme. + */ + const NativeCallingConvention *getNativeConventions() + { return conventions; } + + /* A MangleUtfType indicates type of transformation to apply to some UTF + * characters encountered in the string to be mangled. + */ + enum MangleUTFType { + mangleUTFInvalid=0, + mangleUTFClass, /* Mangle only the forward slashes in class names */ + mangleUTFFieldStub, + mangleUTFSignature, + mangleUTFJNI /* Perform JNI-style mangling; underscore -> _1, + * semicolon -> _2, etc + */ + }; + +protected: + static Int32 mangleUTFString(const char *name, char *buffer, + int buflen, MangleUTFType type); + + static Int32 mangleUnicodeChar(Int32 ch, char *bufptr, char *bufend); + + Int32 numCallingConventions; + NativeCallingConvention *conventions; +}; + + +#endif /* _NAME_MANGLER_H_ */ diff --git a/ef/Runtime/NativeMethods/NativeDefs.h b/ef/Runtime/NativeMethods/NativeDefs.h new file mode 100644 index 000000000000..5f478bfe5b7e --- /dev/null +++ b/ef/Runtime/NativeMethods/NativeDefs.h @@ -0,0 +1,48 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#ifndef _NATIVE_DEFS_H_ +#define _NATIVE_DEFS_H_ + +#include "JavaObject.h" + +/* Define an array of a generated primitive type */ +#define ARRAY_OF_PRIMITIVETYPE(X) \ +struct ArrayOf_##X : public JavaArray { \ + ArrayOf_##X(const Type &type, uint32 length) : JavaArray(type, length) { } \ + X elements[1];\ +} + +ARRAY_OF_PRIMITIVETYPE(char); +ARRAY_OF_PRIMITIVETYPE(uint8); +ARRAY_OF_PRIMITIVETYPE(int16); +ARRAY_OF_PRIMITIVETYPE(uint16); +ARRAY_OF_PRIMITIVETYPE(int32); +ARRAY_OF_PRIMITIVETYPE(uint32); +ARRAY_OF_PRIMITIVETYPE(int64); +ARRAY_OF_PRIMITIVETYPE(uint64); +ARRAY_OF_PRIMITIVETYPE(float); +ARRAY_OF_PRIMITIVETYPE(double); + +/* Define an array of a generated class type */ +#define ARRAY_OF(X) \ +struct ArrayOf_##X : public JavaArray {\ + ArrayOf_##X(const Type &type, uint32 length) : JavaArray(type, length) { }\ + X *elements[1];\ +} + +#endif /* _NATIVE_DEFS_H_ */ diff --git a/ef/Runtime/NativeMethods/NativeMethodDispatcher.cpp b/ef/Runtime/NativeMethods/NativeMethodDispatcher.cpp new file mode 100644 index 000000000000..355b085c60a1 --- /dev/null +++ b/ef/Runtime/NativeMethods/NativeMethodDispatcher.cpp @@ -0,0 +1,260 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#include "NativeMethodDispatcher.h" + +#include + +#include "prio.h" +#include "plstr.h" +#include "prprf.h" +#include "prmem.h" + +#include "CUtils.h" +#include "StringUtils.h" +#include "Address.h" +#include "NameMangler.h" + +/* Each of these manglers must be registered using + * NativeMethodDispatcher::register + */ +#include "JNIManglers.h" +#include "NetscapeManglers.h" + +Vector NativeMethodDispatcher::manglers; + +/* + * create a string for the native function name by adding the + * appropriate system-specific decorations. + * + * On Win32, "__stdcall" functions are exported differently, depending + * on the compiler. In MSVC 4.0, they are decorated with a "_" in the + * beginning, and @nnn in the end, where nnn is the number of bytes in + * the arguments (in decimal). Borland C++ exports undecorated names. + * + * buildFunName handles different encodings depending on the value + * of callType. It returns false when handed a callType it can't handle + * or which does not apply to the current platform. + */ +#if defined(XP_PC) +bool NativeMethodDispatcher::buildFunName(char *name, Int32 nameMax, + Method &m, + NativeCallingConvention callType, + NameMangler &mangler) +#else +/* Avoid those *$#&*&* unused variable warnings */ +bool NativeMethodDispatcher::buildFunName(char *, Int32, + Method &, + NativeCallingConvention callType, + NameMangler &) +#endif +{ +#if defined(XP_PC) + if (callType == nativeCallingConventionStdCallMSVC) { + /* For Microsoft MSVC 4.0/5.0 */ + char suffix[6]; /* This is enough since Java never has more than + 256 words of arguments. */ + int realArgsSize; + int nameLen; + int i; + + realArgsSize = m.getArgsSize() + + mangler.getExtraArgsSize((m.getModifiers() & CR_METHOD_STATIC) != 0); + + PR_snprintf(suffix, sizeof(suffix), "@%d", realArgsSize); + + nameLen = PL_strlen(name); + + if (nameLen >= nameMax - 7) + return false; + + for(i = nameLen; i > 0; i--) + name[i] = name[i-1]; + name[0] = '_'; + + PR_snprintf(name + nameLen + 1, sizeof(suffix), "%s", suffix); + return true; + } +#endif + + if (callType == nativeCallingConventionDefault) + return true; + else + return false; +} + +addr NativeMethodDispatcher::resolve(Method &method) +{ + const char *methodName = method.getName(); + const char *className = method.getDeclaringClass()->getName(); + + const char *signature = method.getSignatureString(); + + /* XXX This is not a correct upper-bound on the length */ + Int32 len = PL_strlen(methodName) + PL_strlen(className)*2 + + PL_strlen(signature)*2 + sizeof("Netscape_Java___"); + + TemporaryBuffer buf(len); + char *name = buf; + + /* Try all the name-mangling schemes at our disposal, one after another..*/ + for (Uint32 i = 0; i < manglers.size(); i++) { + if (!manglers[i]->mangle(className, methodName, signature, name, len)) + continue; + + Int32 numConventions = manglers[i]->numNativeConventions(); + const NativeCallingConvention *conventions = + manglers[i]->getNativeConventions(); + + /* Try all the calling conventions that this mangling scheme supports */ + for (Int32 j = 0; j < numConventions; j++) { + if (!buildFunName(name, len, method, conventions[j], + *manglers[i])) + continue; + + void *address; + PRLibrary *lib; + + if ((address = PR_FindSymbolAndLibrary(name, &lib)) != NULL) + return functionAddress((void (*)())(manglers[i]->getCode(method, address))); + } + } + + return functionAddress((void (*)()) 0); +} + + +void NativeMethodDispatcher::staticInit() +{ + registerMangler(*new JNIShortMangler()); + registerMangler(*new JNILongMangler()); + registerMangler(*new NetscapeShortMangler()); + registerMangler(*new NetscapeLongMangler()); +} + +PRLibrary *NativeMethodDispatcher::loadLibrary(const char *simpleLibName) +{ + /* For now, we parse the path *each* time we load a library. In the future, + * NativeMethodDispatcher must be capable of storing a set of paths, and + * each path could potentially be a directory, zip or jar file. + */ + char *libPath = PR_GetLibraryPath(); + char *libName = 0; + PRLibrary *lib = 0; +#if defined(XP_PC) + static const char* PATH_SEPARATOR = ";"; +#else + static const char* PATH_SEPARATOR = ":"; +#endif + + if (libPath) { + Strtok tok(libPath); + for (const char *token = tok.get(PATH_SEPARATOR); token; token = tok.get(PATH_SEPARATOR)) + if ((libName = PR_GetLibraryName(token, simpleLibName)) != 0) { + lib = PR_LoadLibrary(libName); + //free(libName); + libName = 0; + + if (lib) + break; + } + } + + /* Always search in the current directory */ + if (!lib && (libName = PR_GetLibraryName(".", simpleLibName)) != 0) { + lib = PR_LoadLibrary(libName); + //free(libName); + } + + /* XXX The NSPR doc says it's our responsibility to free this, but in + * reality PR_GetLibraryPath() returns a pointer to the actual path. + * So until they fix this or clarify how PR_GetLibraryPath() should + * behave, this line shall remain commented out -- Sriram, 8/12/97 + */ + /* if (libPath) PR_DELETE(libPath); */ + + return lib; +} + + +#if 0 +char *NativeMethodDispatcher::mangle(const char *className, + const char *methodName, + const char *signature, + char *buffer, Int32 len, + NativeMethodDispatcher::MangleType mangleType) +{ + char *bufptr = buffer; + char *bufend = buffer + len; + + /* For internal (Netscape-style) mangling, prefix a Netscape_ to the JNI- + * style mangled name + */ + if (mangleType == mangleTypeNetscapeShort || + mangleType == mangleTypeNetscapeLong) { + PR_snprintf(bufptr, bufend - bufptr, "Netscape_"); + bufptr += PL_strlen(bufptr); + mangleType = (mangleType == mangleTypeNetscapeShort) ? + mangleTypeJNIShort: mangleTypeJNILong; + + } else + *bufptr = 0; + + /* Copy over Java_ */ + PL_strcat(bufptr, "Java_"); + bufptr += PL_strlen(bufptr); + + bufptr += NativeMethodDispatcher::mangleUTFString(className, bufptr, + bufend - bufptr, + mangleUTFJNI); + + if (bufend - bufptr > 1) + *bufptr++ = '_'; + + bufptr += NativeMethodDispatcher::mangleUTFString(methodName, bufptr, + bufend - bufptr, + mangleUTFJNI); + + /* JNI long name: includes a mangled signature. */ + if (mangleType == mangleTypeJNILong) { + char sig[1024]; + int i; + if (bufend - bufptr > 2) { + *bufptr++ = '_'; + *bufptr++ = '_'; + } + + for (i = 0; i<1023; i++) + if ((sig[i] = signature[i]) == ')') + break; + + sig[i] = 0; + bufptr += NativeMethodDispatcher::mangleUTFString(sig, bufptr, + bufend - bufptr, + mangleUTFJNI); + } + + return buffer; +} +#endif + + + + + + + diff --git a/ef/Runtime/NativeMethods/NativeMethodDispatcher.h b/ef/Runtime/NativeMethods/NativeMethodDispatcher.h new file mode 100644 index 000000000000..b255a4edc387 --- /dev/null +++ b/ef/Runtime/NativeMethods/NativeMethodDispatcher.h @@ -0,0 +1,87 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#ifndef _NATIVE_METHOD_DISPATCHER_H_ +#define _NATIVE_METHOD_DISPATCHER_H_ + +#include "prlink.h" + +#include "ClassCentral.h" +#include "ClassFileSummary.h" +#include "FieldOrMethod.h" +#include "Vector.h" +#include "NameMangler.h" + +/* A quick note on "internal-style" native methods. Other than the JRI + * and JNI, the VM also supports a third kind of native-method dispatch. + * In this approach, native method names are mangled exactly as in the JNI, + * but with a Netscape_ prefixed to the JNI-style mangled name. The + * arguments to the native methods are C++ counterparts to the Java Objects + * used in the VM. The javah program will generate headers and stubs for + * these functions. Fields are accessed directly, via the C++ structures. + * Methods (for now) are called via the reflection API. + */ + + +class NativeMethodDispatcher { +public: + static void staticInit(); + + /* Loads a shared library whose simple name (without a system-specific + * extension) is given by simpleLibName. Returns a handle to the library + * on success, NULL on failure. + */ + static PRLibrary *loadLibrary(const char *simpleLibName); + + /* Resolve the native-method whose information is given by m. This method + * mangles the methodname, and returns the address of the method to call. + * Platform-specific directives (such as the __stdcall suffix on windows) + * are added by this method; the name should not contain those. + */ + static addr resolve(Method &m); + + /* Register a native name mangler */ + static void registerMangler(NameMangler &mangler) { + manglers.append(&mangler); + } + + +private: + + /* Array of name-mangler classes, each of which implements a particular + * name-mangling scheme + */ + static Vector manglers; + + /* Given a mangled function name, construct a platform and compiler- + * specific symbol that can be searched for in the set of loaded libraries. + * name is the mangled function name. method contains run-time information + * about the method. callType is the native calling convention to use. + * mangler is a class that mangles the function name and adds additional + * arguments, if neccessary. + */ + static bool buildFunName(char *name, Int32 nameMax, + Method &method, + NativeCallingConvention callType, + NameMangler &mangler); + +}; + +#endif /* _NATIVE_METHOD_DISPATCHER_H_ */ + + + diff --git a/ef/Runtime/NativeMethods/NativeMethodStubs.h b/ef/Runtime/NativeMethods/NativeMethodStubs.h new file mode 100644 index 000000000000..a403d2a2b1d3 --- /dev/null +++ b/ef/Runtime/NativeMethods/NativeMethodStubs.h @@ -0,0 +1,28 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#ifndef _NATIVE_METHOD_STUBS_H_ +#define _NATIVE_METHOD_STUBS_H_ + +#include "FieldOrMethod.h" + +/* Given a nativeFunction residing in a DLL, generate a JNI stub that + * will set up the stack frame for this native method and call it. + */ +void *generateJNIGlue(const Method &method, void *nativeFunction); + +#endif /* _NATIVE_METHOD_STUBS_H_ */ diff --git a/ef/Runtime/NativeMethods/NetscapeManglers.cpp b/ef/Runtime/NativeMethods/NetscapeManglers.cpp new file mode 100644 index 000000000000..4a171b1ae1ec --- /dev/null +++ b/ef/Runtime/NativeMethods/NetscapeManglers.cpp @@ -0,0 +1,82 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#include "NetscapeManglers.h" + +#include "prprf.h" +#include "plstr.h" + +char *NetscapeShortMangler::mangle(const char *className, + const char *methodName, + const char *signature, + char *buffer, + Int32 len) +{ + char *bufptr = buffer; + char *bufend = buffer + len; + + /* Prefix a Netscape_ to the JNI-mangled name */ + PR_snprintf(bufptr, bufend - bufptr, "Netscape_"); + Int32 bufptrLen = PL_strlen(bufptr); + bufptr += bufptrLen; + len -= bufptrLen; + + return (JNIShortMangler::mangle(className, methodName, signature, + bufptr, len)) ? buffer : 0; + +} + +Int32 NetscapeShortMangler::getExtraArgsSize(bool) +{ + return 0; /* Our call stack is the same as for a Java method */ +} + +void *NetscapeShortMangler::getCode(const Method &, void *actualCode) +{ + return actualCode; +} + + +char *NetscapeLongMangler::mangle(const char *className, + const char *methodName, + const char *signature, + char *buffer, + Int32 len) +{ + char *bufptr = buffer; + char *bufend = buffer + len; + + /* Prefix a Netscape_ to the JNI-mangled name */ + PR_snprintf(bufptr, bufend - bufptr, "Netscape_"); + Int32 bufptrLen = PL_strlen(bufptr); + bufptr += bufptrLen; + len -= bufptrLen; + + return (JNILongMangler::mangle(className, methodName, signature, + bufptr, len)) ? buffer : 0; +} + + +Int32 NetscapeLongMangler::getExtraArgsSize(bool) +{ + return 0; /* Our call stack is the same as for a Java method */ +} + +void *NetscapeLongMangler::getCode(const Method &, void *actualCode) +{ + return actualCode; +} diff --git a/ef/Runtime/NativeMethods/NetscapeManglers.h b/ef/Runtime/NativeMethods/NetscapeManglers.h new file mode 100644 index 000000000000..4feb96387af4 --- /dev/null +++ b/ef/Runtime/NativeMethods/NetscapeManglers.h @@ -0,0 +1,60 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#ifndef _NETSCAPE_MANGLERS_H_ +#define _NETSCAPE_MANGLERS_H_ + +/* Name mangling for "short" versions of Netscape-style mangled names + * (without a mangled signature) and "long" versions (with a mangled + * signature). Netscape-style mangling is essentially JNI-style mangling, + * with a Netscape_ prefixed to the function name. + */ + +#include "JNIManglers.h" + +class NS_EXTERN NetscapeShortMangler : public JNIShortMangler { +public: + /* Like JNI, we support both stdcall and regular calls */ + NetscapeShortMangler() : JNIShortMangler() { } + + virtual char *mangle(const char *className, + const char *methodName, + const char *signature, + char *buffer, + Int32 len); + + virtual Int32 getExtraArgsSize(bool); + virtual void *getCode(const Method &, void *actualCode); + +}; + +class NS_EXTERN NetscapeLongMangler : public JNILongMangler { +public: + NetscapeLongMangler() : JNILongMangler() { } + + virtual char *mangle(const char *className, + const char *methodName, + const char *signature, + char *buffer, + Int32 len); + + virtual Int32 getExtraArgsSize(bool); + virtual void *getCode(const Method &, void *actualCode); + +}; + +#endif /* _JNI_SHORT_MANGLER_H_ */ diff --git a/ef/Runtime/NativeMethods/main.cpp b/ef/Runtime/NativeMethods/main.cpp new file mode 100644 index 000000000000..a493d69d720f --- /dev/null +++ b/ef/Runtime/NativeMethods/main.cpp @@ -0,0 +1,93 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#include "NativeMethodDispatcher.h" + +Pool p; +StringPool sp(p); +ClassWorld world(p); + +/* Simple test for the native method dispatch mechanism + * argv[1] -- fully qualified classname + * argv[2] -- shared lib to load (without system-specific extension) + * argv[3] -- methodName (optional) + */ +int main(int argc, char **argv) +{ + const char *className = argv[1]; + const char *libName = argv[2]; + const char *methodName = (argc > 3) ? argv[3] : 0; + Method *theMethod = 0; + + ClassCentral central(p, world, sp, 0); + + initDistinguishedObjects(central); + NativeMethodDispatcher::staticInit(); + + ClassFileSummary &summ = central.addClass(className); + + /* Load the shared library */ + if (NativeMethodDispatcher::loadLibrary(libName) == 0) { + fprintf(stderr, "Cannot load library %s\n", libName); + return 1; + } + + /* Now display all methods and ask the user to pick a method to resolve */ + if (!methodName) { + fprintf(stderr, "Choose from the following methods:\n"); + + Method **methods = (Method **) summ.getMethods(); + int32 methodCount = summ.getMethodCount(); + for (int32 i = 0; i < methodCount; i++) { + const char *name = methods[i]->toString(); + + if (methods[i]->getModifiers() & CR_METHOD_NATIVE) + fprintf(stderr, "%d. %s\n", i+1, name); + } + + fprintf(stderr, "\nChoose number of choice-> "); + char s[80]; + gets(s); + int choice = atoi(s)-1; + if (choice > 0 && choice <= methodCount) { + methodName = methods[choice]->toString(); + theMethod = methods[choice]; + } else { + fprintf(stderr, "Bad Boy. You have entered a bad index. Try again.\n"); + return 1; + } + } else { + if (!(methodName = sp.get(methodName)) || + !(world.getMethod(methodName, theMethod))) { + fprintf(stderr, "That seems to be an invalid methodname. Try again.\n"); + return 1; + } + } + + assert(theMethod); + if (NativeMethodDispatcher::resolve(*theMethod)) + fprintf(stderr, "Resolved method.\n"); + else + fprintf(stderr, "Could not resolve method!\n"); + + return 0; +} + +#ifdef __GNUC__ +/* for gcc with -fhandle-exceptions */ +void terminate() {} +#endif diff --git a/ef/Runtime/NativeMethods/md/Makefile b/ef/Runtime/NativeMethods/md/Makefile new file mode 100644 index 000000000000..514c731f2dd2 --- /dev/null +++ b/ef/Runtime/NativeMethods/md/Makefile @@ -0,0 +1,53 @@ +#!gmake +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +####################################################################### +# (1) Directory specific info # +####################################################################### + +DEPTH = ../../.. + +DIRS = x86 + +SUBMODULES = $(DIRS) + +MODULE_NAME = EF + +####################################################################### +# (2) Include "component" configuration information. # +####################################################################### + +include $(DEPTH)/config/config.mk + +####################################################################### +# (3) Include "local" platform-dependent assignments (OPTIONAL). # +####################################################################### + + + +####################################################################### +# (4) Execute "component" rules. (OPTIONAL) # +####################################################################### + +include $(DEPTH)/config/rules.mk + +####################################################################### +# (7) Execute "local" rules. (OPTIONAL). # +####################################################################### + + + diff --git a/ef/Runtime/NativeMethods/md/PPC/Makefile b/ef/Runtime/NativeMethods/md/PPC/Makefile new file mode 100644 index 000000000000..bf6ee042d1ca --- /dev/null +++ b/ef/Runtime/NativeMethods/md/PPC/Makefile @@ -0,0 +1,52 @@ +#!gmake +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +####################################################################### +# (1) Directory specific info # +####################################################################### + +DEPTH = ../../../.. + +CPPSRCS = PPCNativeMethodStubs.cpp \ + $(NULL) + +MODULE_NAME = EF + +####################################################################### +# (2) Include "component" configuration information. # +####################################################################### + +include $(DEPTH)/config/config.mk + +####################################################################### +# (3) Include "local" platform-dependent assignments (OPTIONAL). # +####################################################################### + + + +####################################################################### +# (4) Execute "component" rules. (OPTIONAL) # +####################################################################### + +include $(DEPTH)/config/rules.mk + +####################################################################### +# (7) Execute "local" rules. (OPTIONAL). # +####################################################################### + + + diff --git a/ef/Runtime/NativeMethods/md/PPC/PPCNativeMethodStubs.cpp b/ef/Runtime/NativeMethods/md/PPC/PPCNativeMethodStubs.cpp new file mode 100644 index 000000000000..63cffd06965b --- /dev/null +++ b/ef/Runtime/NativeMethods/md/PPC/PPCNativeMethodStubs.cpp @@ -0,0 +1,24 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#include "NativeMethodStubs.h" + +void *generateJNIGlue(const Method &/*method*/, void * /*nativeFunction*/) +{ + trespass("Not implemented"); + return 0; +} diff --git a/ef/Runtime/NativeMethods/md/x86/Makefile b/ef/Runtime/NativeMethods/md/x86/Makefile new file mode 100644 index 000000000000..b1052aa98fea --- /dev/null +++ b/ef/Runtime/NativeMethods/md/x86/Makefile @@ -0,0 +1,52 @@ +#!gmake +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +####################################################################### +# (1) Directory specific info # +####################################################################### + +DEPTH = ../../../.. + +CPPSRCS = x86NativeMethodStubs.cpp \ + $(NULL) + +MODULE_NAME = EF + +####################################################################### +# (2) Include "component" configuration information. # +####################################################################### + +include $(DEPTH)/config/config.mk + +####################################################################### +# (3) Include "local" platform-dependent assignments (OPTIONAL). # +####################################################################### + + + +####################################################################### +# (4) Execute "component" rules. (OPTIONAL) # +####################################################################### + +include $(DEPTH)/config/rules.mk + +####################################################################### +# (7) Execute "local" rules. (OPTIONAL). # +####################################################################### + + + diff --git a/ef/Runtime/NativeMethods/md/x86/x86NativeMethodStubs.cpp b/ef/Runtime/NativeMethods/md/x86/x86NativeMethodStubs.cpp new file mode 100644 index 000000000000..2d310893207e --- /dev/null +++ b/ef/Runtime/NativeMethods/md/x86/x86NativeMethodStubs.cpp @@ -0,0 +1,120 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#include "NativeMethodStubs.h" +#include "NativeCodeCache.h" +#include "MemoryAccess.h" +#include "jni.h" + +extern JNIEnv *jniEnv; +extern void throwJNIExceptionIfNeeded(); + +// XXX This will eventually have to be done on a per-thread basis!! +static Uint32 JNIReturnAddressInteger = 0; +static void *JNIReturnAddress = &JNIReturnAddressInteger; + +// Stub sizes +static const JNIStaticStubSize = 34; +static const JNIInstanceStubSize = 32; + +// x86 opcodes that we're interested in +static const Uint8 popEax = 0x58; +static const Uint8 pushl = 0x68; +static const Uint8 jmpl = 0xe9; +static const Uint8 pushEax = 0x50; +static const Uint8 calll = 0xe8; +static const Uint8 moveFromEax = 0xa3; + +static const Uint16 jmplIndirectLow = 0xff; +static const Uint16 jmplIndirectHigh = 0x25; + +#define writeRelativeDisplacement(symbol) \ + writeLittleWordUnaligned(where, reinterpret_cast(symbol) - Uint32(where + 4));\ + where += 4; + +#define writeGlobalLocation(symbol) \ + writeLittleWordUnaligned(where, reinterpret_cast(symbol));\ + where += 4; + +/* Generate stub glue for a native JNI function. + * The net effect is to generate code that does the following: + * + * pop eax // Save return address in EAX + * mov JNIReturnAddress, eax // Tuck return address safely away + * push declaringClass // Push declaring class; static methods only + * push JNIenv // Push JNI pointer + * call nativeMethod // Jump to the actual JNI native method + * push eax // Store the return value on the stack + * call throwJNIExceptionIfNeeded // Check and throw JNI exceptions if needed + * pop eax // Restore the return value + * jmp [JNIReturnAddress] // jump to previously stored return address + */ +void *generateJNIGlue(const Method &method, + void *nativeFunction) +{ + void* stub; + int stubSize = (method.getModifiers() & CR_METHOD_STATIC) ? + JNIStaticStubSize : JNIInstanceStubSize; + + assert(method.getModifiers() & CR_METHOD_NATIVE); + assert(nativeFunction); + + // Write out the JNI stub + stub = NativeCodeCache::sNativeCodeCache.acquireMemory(stubSize); + + Uint8* where = (Uint8*) stub; + *where++ = popEax; // popl eax + + *where++ = moveFromEax; + writeGlobalLocation(JNIReturnAddress); + + + // We're pushing arguments right-to-left, so the jclass + // argument is pushed before the JNIEnv. + if (method.getModifiers() & CR_METHOD_STATIC) { + *where++ = pushl; // pushl + writeGlobalLocation((method.getDeclaringClass())); + } + + *where++ = pushl; // pushl + writeGlobalLocation(jniEnv); + + // Put the return address back on the stack + //*where++ = pushEax; // push eax + + *where++ = calll; // call + writeRelativeDisplacement(nativeFunction); + + // Store the return value on the stack + *where++ = pushEax; // push eax + + // Call throwJNIExceptionIfNeeded + *where++ = calll; + writeRelativeDisplacement(&throwJNIExceptionIfNeeded); + + // Restore return value + *where++ = popEax; // pop eax + + // Get back to where we once belonged... + *where++ = jmplIndirectLow; + *where++ = jmplIndirectHigh; + writeGlobalLocation(JNIReturnAddress); + + return stub; +} + + diff --git a/ef/Runtime/System/ClassWorld.cpp b/ef/Runtime/System/ClassWorld.cpp new file mode 100644 index 000000000000..54d62f9fa8ea --- /dev/null +++ b/ef/Runtime/System/ClassWorld.cpp @@ -0,0 +1,37 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#include "ClassWorld.h" + +Package pkgInternal("%"); +Package pkgJavaLang("java.lang"); + + +// ---------------------------------------------------------------------------- +// Package + +#ifdef DEBUG_LOG +// +// Print a reference to this package for debugging purposes. +// Return the number of characters printed. +// +int Package::printRef(LogModuleObject &f) const +{ + return UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("%s", name)); +} +#endif + diff --git a/ef/Runtime/System/ClassWorld.h b/ef/Runtime/System/ClassWorld.h new file mode 100644 index 000000000000..959504b87772 --- /dev/null +++ b/ef/Runtime/System/ClassWorld.h @@ -0,0 +1,80 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#ifndef CLASSWORLD_H +#define CLASSWORLD_H + +#include "JavaObject.h" +#include "Pool.h" +#include "FastHashTable.h" +#include "LogModule.h" + +struct Package +{ + const char *const name; // Name of the package (stored in the ClassWorld's pool) + + explicit Package(const char *name): name(name) {} + + #ifdef DEBUG_LOG + int printRef(LogModuleObject &f) const; + #endif +}; + + +// Pool of run-time information for a Java Program. New classes can be added +// to the pool explicitly (at runtime), or by ClassCentral. +class ClassWorld { +public: + ClassWorld(Pool &p) : typeTable(p), methodTable(p), pool(p) { } + + Type &getType(const char *packageName, const char *className); + + bool getType(const char *fullyQualifiedClassName, Type *&t) { + return typeTable.get(fullyQualifiedClassName, &t); + } + + void addType(const char *className, Type *type) { + typeTable.add(className, type); + } + + void addMethod(const char *methodName, Method *method) { + methodTable.add(methodName, method); + } + + bool getMethod(const char *methodName, Method *&m) { + return methodTable.get(methodName, &m); + } + + +private: + FastHashTable typeTable; + FastHashTable methodTable; + Pool &pool; +}; + +// ---------------------------------------------------------------------------- +// Standard packages + +extern Package pkgInternal; // Internal package for housekeeping classes +extern Package pkgJavaLang; + +#endif + + + + + diff --git a/ef/Runtime/System/Exceptions.h b/ef/Runtime/System/Exceptions.h new file mode 100644 index 000000000000..465f0a72a5d3 --- /dev/null +++ b/ef/Runtime/System/Exceptions.h @@ -0,0 +1,33 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#ifndef _EXCEPTIONS_H_ +#define _EXCEPTIONS_H_ + +#ifdef _WIN32 +#include "md/x86/x86Win32ExceptionHandler.h" +// For now use inline assembly, tidy this up later +#define installHardwareExceptionHandler(HARDWARE_EXCP) __asm { __asm push HARDWARE_EXCP __asm push fs:[0] __asm mov fs:[0],esp } +#define removeHardwareExceptionHandler() __asm { __asm mov eax,[esp] __asm mov fs:[0],eax __asm add esp,8 } + +#else + +static void installHardwareExceptionHandler() {} +static void removeHardwareExceptionHandler() {} +#endif + +#endif /* _EXCEPTIONS_H_ */ diff --git a/ef/Runtime/System/FieldOrInterfaceSummary.h b/ef/Runtime/System/FieldOrInterfaceSummary.h new file mode 100644 index 000000000000..2f6b91533afd --- /dev/null +++ b/ef/Runtime/System/FieldOrInterfaceSummary.h @@ -0,0 +1,101 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#ifndef _FIELD_H_ +#define _FIELD_H_ + +#include "JavaObject.h" + +struct classOrInterface; + +struct FieldOrMethod : JavaObject { +public: + ClassOrInterface &getDeclaringClass() const; + const char *getName() const; + int getModifiers() const; // Access Flags + + ClassOrInterface &getType() const; + virtual bool equals(JavaObject &obj) const; + + // int hashCode(); + + // Returns the fully qualified name and type of the field or method, eg, + // public static java.lang.thread.priority + const char *toString() const; +}; + +struct Field : FieldOrMethod { +public: + virtual bool equals(JavaObject &obj) const; + + // Get the value of the field + JavaObject &get(JavaObject &obj); + + // Get the value of the field, converted to boolean + boolean getBoolean(JavaObject &obj); + + // Get the value of the field in various forms. Appropriate exceptions + // are tossed if obj is not of the right type + uint8 getByte(JavaObject &obj); + char getChar(JavaObject &obj); + int16 getShort(JavaObject &obj); + int32 getInt(JavaObject &obj); + int64 getLong(JavaObject &obj); + Flt32 getFloat(JavaObject &obj); + Flt64 getDouble(JavaObject &obj); + + // Set the value of the field + void set(JavaObject &obj, JavaObject &value); + + // Set the value of the field in various forms. Appropriate exceptions + // are thrown if types don't match + void setBoolean(JavaObject &obj, bool value); + void setByte(JavaObject &obj, uint8 value); + void setChar(JavaObject &obj, char value); + void setShort(JavaObject &obj, int16 value); + void setInt(JavaObject &obj, int32 value); + void setLong(JavaObject &obj, int64 value); + void setFloat(JavaObject &obj, Flt32 value); + void setDouble(JavaObject &obj, Flt64 value); + +}; + +struct Method : public FieldOrMethod { + virtual bool equals(JavaObject &obj) const; + + ClassOrInterface &getReturnType(); + + // Returns number of params + int getParameterTypes(ClassOrInterface *¶ms); + + // Returns number of exception types + int getExceptionTypes(ClassOrInterface *¶ms); + + // Invoke the specified method on the given object with specified + // parameters. Throws gobs and gobs of exceptions if thwarted. + JavaObject &invoke(JavaObject &obj, JavaObject *&args); + + +}; + + +#endif /* _FIELD__H_ */ + + + + + diff --git a/ef/Runtime/System/FieldOrMethod.cpp b/ef/Runtime/System/FieldOrMethod.cpp new file mode 100644 index 000000000000..9b0ac83bda98 --- /dev/null +++ b/ef/Runtime/System/FieldOrMethod.cpp @@ -0,0 +1,1350 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +// FieldOrMethod.cpp +// +// Sriram Kini +// + +// Runtime representation of java fields or methods +// Most of the operations performed on fields or methods +// are located here. + +#include "ErrorHandling.h" +#include "ClassCentral.h" +#include "BytecodeTranslator.h" +#include "PrimitiveOptimizer.h" +#include "FieldOrMethod.h" +#include "CUtils.h" +#include "StringUtils.h" +#include "NativeCodeCache.h" +#include "Backend.h" +#include "Debugger.h" + +#include "plstr.h" +#include "prprf.h" +#include "FieldOrMethod_md.h" +#include "InterestingEvents.h" +#include "JavaVM.h" + +UT_DEFINE_LOG_MODULE(FieldOrMethod); + +/* Convert value valueFrom, whose typekind is tkFrom, to a value of type tkTo. + * Store the result in valueTo. It is assumed that valueTo is properly + * aligned. If a widening conversion is not possible, throw an illegalArgument + * exception. + */ +void Field::widen(void *valueFrom, void *valueTo, + TypeKind tkFrom, TypeKind tkTo) +{ + switch (tkTo) { + case tkBoolean: /* Can't widen to these */ + case tkChar: + case tkByte: + goto cantConvert; + + case tkShort: + if (tkFrom == tkByte) + *(Int16 *) valueTo = (Int16) *(Int8 *) valueFrom; + else + goto cantConvert; + + case tkInt: + switch (tkFrom) { + case tkByte: + *(Int32 *) valueTo = (Int32) *(Int8 *) valueFrom; + break; + + case tkChar: + case tkShort: + *(Int32 *) valueTo= (Int32) *(Int16 *) valueFrom; + break; + + default: + goto cantConvert; + + } + break; + + case tkLong: + switch (tkFrom) { + case tkByte: + *(Int64 *) valueTo = (Int64) *(Int8 *) valueFrom; + break; + + case tkChar: + case tkShort: + *(Int64 *) valueTo = (Int64) *(Int16 *) valueFrom; + break; + + case tkInt: + *(Int64 *) valueTo = (Int64) *(Int32 *) valueFrom; + break; + + default: + goto cantConvert; + } + break; + + case tkFloat: + switch (tkFrom) { + case tkByte: + *(Flt32 *) valueTo = (Flt32) *(Int8 *) valueFrom; + break; + + case tkChar: + case tkShort: + *(Flt32 *) valueTo = (Flt32) *(Int16 *) valueFrom; + break; + + case tkInt: + *(Flt32 *) valueTo = (Flt32) *(Int32 *) valueFrom; + break; + + case tkLong: + *(Flt32 *) valueTo = (Flt32) *(Int64 *) valueFrom; + break; + + default: + goto cantConvert; + } + break; + + case tkDouble: + switch (tkFrom) { + case tkByte: + *(Flt64 *) valueTo = (Flt64) *(Int8 *) valueFrom; + break; + + case tkChar: + case tkShort: + *(Flt64 *) valueTo = (Flt64) *(Int16 *) valueFrom; + break; + + case tkInt: + *(Flt64 *) valueTo = (Flt64) *(Int32 *) valueFrom; + break; + + case tkLong: + *(Flt64 *) valueTo = (Flt64) *(Int64 *) valueFrom; + break; + + case tkFloat: + *(Flt64 *) valueTo = (Flt64) *(Flt32 *) valueFrom; + break; + + default: + goto cantConvert; + } + break; + + default: + runtimeError(RuntimeError::internal); + } + + return; + +cantConvert: + runtimeError(RuntimeError::illegalArgument); +} + + +/* Return the full name of the field or method from the short name and the + * class name. A full name is of the form "public static int java.lang.foo.bar"; + * the correspoding package name is java.lang.foo, and the short name is bar. + */ +const char *Field::getFullName() +{ + const char *accessString = ((modifiers & CR_FIELD_STATIC)) ? "static " : ""; + const char *statusString; + const char *finalString = ((modifiers & CR_FIELD_FINAL)) ? "final " : ""; + + if ((modifiers & CR_FIELD_PUBLIC)) + statusString = "public "; + else if ((modifiers & CR_FIELD_PROTECTED)) + statusString = "protected "; + else + statusString = ""; + + char *typeString = new char[20]; + Uint32 typeStrLen = 20; + + *typeString = 0; + getTypeString(*typeOfField, typeString, typeStrLen); + + char *_fullName; + + /* The fullname is the name of the class appended by a dot, appended + * by the field name + */ + Uint32 outlen = PL_strlen(accessString) + PL_strlen(finalString)+ + PL_strlen(typeString) + PL_strlen(statusString)+ + PL_strlen(className) + PL_strlen(packageName) + PL_strlen(shortName) + 8; + + _fullName = new char[outlen]; + + if (packageName && *packageName) + PR_snprintf(_fullName, outlen, "%s%s%s%s %s.%s.%s", + statusString, accessString, finalString, typeString, + packageName, className, shortName); + else + PR_snprintf(_fullName, outlen, "%s%s%s%s %s.%s", + statusString, accessString, finalString, typeString, + className, shortName); + + fullName = central.getStringPool().intern(_fullName); + + delete [] _fullName; + delete [] typeString; + + return fullName; +} + + +/* Appends the string for the type to str, updating strLen */ +void FieldOrMethod::getTypeString(const Type &type, char *&str, Uint32 &strLen) +{ + switch (type.typeKind) { + case tkBoolean: + append(str, strLen, "boolean"); + break; + + case tkUByte: + append(str, strLen, "unsigned byte"); + break; + + case tkByte: + append(str, strLen, "byte"); + break; + + case tkChar: + append(str, strLen, "byte"); + break; + + case tkShort: + append(str, strLen, "short"); + break; + + case tkInt: + append(str, strLen, "int"); + break; + + case tkLong: + append(str, strLen, "long"); + break; + + case tkFloat: + append(str, strLen, "float"); + break; + + case tkDouble: + append(str, strLen, "double"); + break; + + case tkObject: + case tkInterface: { + const ClassOrInterface *clazz = static_cast(&type); + append(str, strLen, clazz->getName()); + break; + } + + case tkArray: { + const Array *array = static_cast(&type); + getTypeString(*const_cast (&array->componentType), str, strLen); + append(str, strLen, "[]"); + break; + } + + default: + runtimeError(RuntimeError::unknown); + break; + } +} + +/* Convert a JVM type descriptor into the long form defined by + * java.lang.reflect, e.g. [[C is emitted as "char[][]" + * Advances descriptor to point to the point beyond the argument just + * parsed. Appends description of parsed argument to out. + */ +static bool descriptorToString(char *out, Uint32 outLen, const char * &descriptor) { + char *typeString; + + switch (*descriptor) { + case 'B': + typeString = "byte"; + break; + case 'C': + typeString = "char"; + break; + case 'D': + typeString = "double"; + break; + case 'F': + typeString = "float"; + break; + case 'I': + typeString = "int"; + break; + case 'J': + typeString = "long"; + break; + case 'S': + typeString = "short"; + break; + case 'Z': + typeString = "boolean"; + break; + case 'V': + typeString = "void"; + break; + case '[': + descriptor++; + descriptorToString(out, outLen, descriptor); + append(out, outLen, "[]"); + return true; + case 'L': + { + descriptor++; + char *semicolon = strchr(descriptor, ';'); + if (!semicolon) + verifyError(VerifyError::badClassFormat); + char *tmpStr = new char[semicolon - descriptor + 1]; + char *t = tmpStr; + while (*descriptor != ';') { + if (*descriptor == '/') + *t++ = '.'; + else + *t++ = *descriptor; + descriptor++; + } + *t = 0; + descriptor++; // Advance past semi-colon + append(out, outLen, tmpStr); + delete [] tmpStr; + return true; + } + case ')': + return false; + default: + verifyError(VerifyError::badClassFormat); + return false; // NOTREACHED + } + append(out, outLen, typeString); + descriptor++; + return true; +} + +/* Return the full name of the method from the short name and the + * class name. A full name is of the form + * "public static java.lang.foo.bar(int, long, java.lang.Object)". + * the corresponding package name is java.lang.foo, and the short name is bar. + */ +const char *Method::getFullName() +{ + const char *accessString = ((modifiers & CR_METHOD_STATIC)) ? "static " : ""; + + const char *statusString; + + if ((modifiers & CR_METHOD_PUBLIC)) + statusString = "public "; + else if ((modifiers & CR_METHOD_PROTECTED)) + statusString = "protected "; + else if ((modifiers & CR_METHOD_PRIVATE)) + statusString = "private "; + else + statusString = ""; + + const char *abstractString = ((modifiers & CR_METHOD_ABSTRACT)) ? + "abstract " : ""; + + char *returnString = new char[50]; + Uint32 returnStringLen = 50; + *returnString = 0; + + char *argsString = new char[256]; + Uint32 argsStringLen = 256; + *argsString = 0; + + const char *s = signatureString; + if (*s++ != '(') + verifyError(VerifyError::badClassFormat); + + // Check for method which takes no arguments + if (*s == ')') + append(argsString, argsStringLen, "()"); + else { + append(argsString, argsStringLen, "("); + + // Convert each method argument to string + while (descriptorToString(argsString, argsStringLen, s)) + append(argsString, argsStringLen, ","); + + if (*s != ')') { + delete [] argsString; + delete [] returnString; + verifyError(VerifyError::badClassFormat); + } + + /* overwrite the last comma with closing paren and null */ + argsString[PL_strlen(argsString) - 1] = ')'; + + } + + /* Now parse the return argument, only if we're not a constructor*/ + if (shortName != summary.getInitString()) { + s++; + if (!descriptorToString(returnString, returnStringLen, s)) { + delete [] argsString; + delete [] returnString; + verifyError(VerifyError::badClassFormat); + } + + append(returnString, returnStringLen, " "); + } + + char *_fullName; + + /* Allocate enough space to hold strings for arguments */ + Uint32 outLen = PL_strlen(accessString)+PL_strlen(statusString)+ + PL_strlen(abstractString)+PL_strlen(returnString)+ + PL_strlen(className)+PL_strlen(shortName)+PL_strlen(packageName)+PL_strlen(argsString)+5; + + _fullName = new char[outLen]; + + if (shortName == summary.getInitString()) { + if (packageName && *packageName) + PR_snprintf(_fullName, outLen, "%s%s%s%s.%s%s", + accessString, statusString, returnString, packageName, className, + argsString); + else + PR_snprintf(_fullName, outLen, "%s%s%s%s%s", + accessString, statusString, returnString, className, + argsString); + } else { + if (packageName && *packageName) + PR_snprintf(_fullName, outLen, "%s%s%s%s%s.%s.%s%s", + accessString, statusString, abstractString, returnString, + packageName, className, shortName, argsString); + else + PR_snprintf(_fullName, outLen, "%s%s%s%s%s.%s%s", + accessString, statusString, abstractString, returnString, + className, shortName, argsString); + } + + fullName = central.getStringPool().intern(_fullName); + + delete [] returnString; + delete [] argsString; + delete [] _fullName; + + return fullName; +} + +/* Class Field */ + +/* Return the size occupied by objects whose type is represented by type */ +static Uint32 getTypeSize(const Type &type) +{ + if (isNonVoidPrimitiveKind(type.typeKind)) { + return isDoublewordKind(type.typeKind) ? 8 : 4; //getTypeKindSize(type.typeKind); + } else if (type.typeKind == tkObject || type.typeKind == tkInterface) { + return sizeof(ptr); + } else if (type.typeKind == tkArray) { + return sizeof(ptr); //Arrays and objects are implemented as references + } else + return 0; +} + +/* Construct a field given it's packageName, className and shortName. + * (Also see FieldOrMethod::FieldOrMethod). + * summary is the information about the declaring class; central is + * the repository used to hold ClassFileSummary structures. + * info contains compile-time information about the field. + * offset is the offset of this field in the declaring class if + * the field is an instance (ie., non-static) field. + */ +Field::Field(const char *packageName, const char *className, + const char *shortName, + ClassFileSummary &summary, + ClassCentral &c, + Pool &pool, + Uint32 offset, + const FieldInfo &info) : + FieldOrMethod(Standard::get(cField), + packageName, className, shortName, info.getDescriptor()->getUtfString(), + summary, c, pool) +{ + bool isStatic, isVolatile, isConstant; + const char *sig; + + info.getInfo(sig, isVolatile, isConstant, isStatic); + + const char *next; + typeOfField = ¢ral.parseFieldDescriptor(sig, next); + + modifiers = info.getAccessFlags(); + + if (isStatic) { + Uint32 size = getTypeKindSize(typeOfField->typeKind); + pos.address = staticAddress(new (p) char[size]); + memset(addressFunction(pos.address), 0, size); + } else + pos.offset = offset; +} + +// Get the memory address of a static field +addr Field::getAddress() const +{ + assert((modifiers & CR_FIELD_STATIC)); + + // If static initializers haven't been run, execute them now. + (const_cast(static_cast(getDeclaringClass())))->runStaticInitializers(); + + return pos.address; +} + +/* Return a JavaObject from the raw bytes located at address. For + * primitive types, wrap an object wrapper around it + */ +JavaObject &Field::convertObject(void *address) +{ + if (isPrimitiveKind(typeOfField->typeKind)) + return Class::makePrimitiveObject(typeOfField->typeKind, address); + else { + /* For object and array types, what's stored is a pointer to the + * JavaObject + */ + JavaObject *objp = *((JavaObject **)address); + return *objp; + } +} + + +/* Get the raw address of the object represented by this field */ +void *Field::getRaw(JavaObject *obj) +{ + void *address; + + if ((modifiers & CR_FIELD_STATIC)) { + address = addressFunction(getAddress()); + } else { + if (!obj) + runtimeError(RuntimeError::nullPointer); + + // Make sure that the type of the object is the + // same as the declaring class of this field, or + // a sub-class + if (! (&obj->getType() == getDeclaringClass() || + (getDeclaringClass()->isAssignableFrom(obj->getType()))) + ) + runtimeError(RuntimeError::illegalArgument); + + address = (void *) (((char *) obj) + pos.offset); + } + + return address; +} + +/* Get the value of the field, wrapped in a JavaObject + * if neccessary + */ +JavaObject &Field::get(JavaObject *obj) +{ + void *address = getRaw(obj); + + return convertObject(address); +} + +// Return true if this field represents a primitive type +inline bool Field::isPrimitive() +{ + return (typeOfField->isPrimitive()); +} + + +#define FIELD_GET_PRIMITIVE(typeTo, tkTo) \ + PR_BEGIN_MACRO \ + if (!isPrimitive()) \ + runtimeError(RuntimeError::illegalArgument); \ + \ + typeTo value; \ + void *address = getRaw(obj); \ + \ + if (typeOfField->typeKind == tkTo) \ + return *(typeTo *) address; \ + else { \ + widen(address, &value, typeOfField->typeKind, tkTo);\ + return (typeTo) value; \ + } \ + PR_END_MACRO + + +/* Get the value of this field within the object obj, + * converted to boolean. + */ +Int8 Field::getBoolean(JavaObject *obj) +{ + FIELD_GET_PRIMITIVE(Int8, tkBoolean); +} + + +Int8 Field::getByte(JavaObject *obj) +{ + FIELD_GET_PRIMITIVE(Int8, tkByte); +} + +Int16 Field::getChar(JavaObject *obj) +{ + FIELD_GET_PRIMITIVE(Int16, tkChar); +} + + +Int16 Field::getShort(JavaObject *obj) +{ + FIELD_GET_PRIMITIVE(Int16, tkShort); +} + +Int32 Field::getInt(JavaObject *obj) +{ + FIELD_GET_PRIMITIVE(Int32, tkInt); +} + +Int64 Field::getLong(JavaObject *obj) +{ + FIELD_GET_PRIMITIVE(Int64, tkLong); +} + +Flt32 Field::getFloat(JavaObject *obj) +{ + FIELD_GET_PRIMITIVE(Flt32, tkFloat); +} + +Flt64 Field::getDouble(JavaObject *obj) +{ + FIELD_GET_PRIMITIVE(Flt32, tkDouble); +} + + +void Field::setFromValue(ValueKind vk, Value value) +{ + assert(getModifiers() & CR_FIELD_STATIC); + + void *address = getRaw(0); + const char *sig = getSignatureString(); + + switch (vk) { + case vkInt: + if (*sig != 'I' && *sig != 'B' && *sig != 'C' && *sig != 'S' && + *sig != 'Z') + verifyError(VerifyError::badClassFormat); + *(Int32 *) address = value.getValueContents((Int32 *) 0); + break; + + case vkLong: + if (*sig != 'J') + verifyError(VerifyError::badClassFormat); + *(Int64 *) address = value.getValueContents((Int64 *) 0); + break; + + case vkFloat: + if (*sig != 'F') + verifyError(VerifyError::badClassFormat); + *(Flt32 *) address = value.getValueContents((Flt32 *) 0); + break; + + case vkDouble: + if (*sig != 'D') + verifyError(VerifyError::badClassFormat); + *(Flt64 *) address = value.getValueContents((Flt64 *) 0); + break; + + case vkAddr: + if (PL_strcmp(sig, "Ljava/lang/String;")) + verifyError(VerifyError::badClassFormat); + + *(JavaObject **) address = (JavaObject *) addressFunction(value.getValueContents((addr *) 0)); + break; + + default: + verifyError(VerifyError::badClassFormat); + } +} + +void Field::set(JavaObject *obj, JavaObject &value) +{ + void *address = getRaw(obj); + + int size = getTypeKindSize(typeOfField->typeKind); + + /* If this is a primitive type, then it is encased in a Java Object; + * otherwise, it is the object itself + */ + if (isPrimitiveKind(typeOfField->typeKind)) { + if (!Standard::isPrimitiveWrapperClass(*static_cast(&value.getType()))) + runtimeError(RuntimeError::illegalArgument); + + memcpy(address, (char *)&value+sizeof(JavaObject), size); + } else { + assert(size == sizeof(char *)); + *((JavaObject **) address) = &value; + } + +} + +// Set the value of the field in various ways +// This code is dependent on our current layout, and +// must be reworked when our layout changes +#define FIELD_SET_PRIMITIVE(typeFrom, tkFrom) \ + PR_BEGIN_MACRO \ + if (!isPrimitive()) \ + runtimeError(RuntimeError::illegalArgument); \ + \ + void *address = getRaw(obj); \ + \ + if (typeOfField->typeKind == tkFrom) \ + *(typeFrom *) address = value; \ + else \ + widen(&value, address, tkFrom, typeOfField->typeKind); \ + PR_END_MACRO + + +void Field::setBoolean(JavaObject *obj, Int8 value) +{ + FIELD_SET_PRIMITIVE(Int8, tkBoolean); +} + +void Field::setByte(JavaObject *obj, Int8 value) +{ + FIELD_SET_PRIMITIVE(Int8, tkByte); +} + +void Field::setChar(JavaObject *obj, Int16 value) +{ + FIELD_SET_PRIMITIVE(Int16, tkChar); +} + +void Field::setShort(JavaObject *obj, Int16 value) +{ + FIELD_SET_PRIMITIVE(Int16, tkShort); +} + +void Field::setInt(JavaObject *obj, Int32 value) +{ + FIELD_SET_PRIMITIVE(Int32, tkInt); +} + +void Field::setLong(JavaObject *obj, Int64 value) +{ + FIELD_SET_PRIMITIVE(Int64, tkLong); +} + +void Field::setFloat(JavaObject *obj, Flt32 value) +{ + FIELD_SET_PRIMITIVE(Flt32, tkFloat); +} + +void Field::setDouble(JavaObject *obj, Flt64 value) +{ + FIELD_SET_PRIMITIVE(Flt64, tkDouble); +} + + + +/* Class Method */ + +/* Parses the type descriptor of the method, resolving and + * loading classes as necessary. Creates the signature structure + * for the method. + */ +void Method::parseMethodDescriptor(const char *s) +{ + char *paramstr; + const char *t; + const Type **params, *ret; + int paramSize = 0; + int numParams = 0; + bool isStatic; + + if (!(isStatic = (getModifiers() & CR_METHOD_STATIC) != 0)) { + /* Pass in ourselves as the first argument */ + numParams = 1; + params = new (p) const Type *[(paramSize = 5)]; + params[0] = getDeclaringClass(); + } + + if (*s++ != '(') + verifyError(VerifyError::badClassFormat); + + /* Get everything between this and ')' */ + if (!(t = PL_strchr(s, ')'))) + verifyError(VerifyError::badClassFormat); + + int len = t-s+1; + + if (len != 1) { + + TemporaryStringCopy copy(s, len-1); + paramstr = copy; + + const char *next = paramstr; + + while (*next) { + + if (numParams+1 > paramSize) { + paramSize += 5; + + const Type **oldParams = params; + params = new (p) const Type *[paramSize]; + + for (int i = 0; i < numParams; i++) + params[i] = oldParams[i]; + + /* We don't do this since we're using a pool to allocate, but + * this is a potential source of runaway memory usage + */ + /* delete [] oldParams;*/ + } + + params[numParams] = ¢ral.parseFieldDescriptor(next, next); + numParams++; + } + + } + + s += len; + + /* Parse the return descriptor */ + if (*s == 'V') { + if (*(s+1)) + verifyError(VerifyError::badClassFormat); + + ret = &PrimitiveType::obtain(tkVoid); + } else { + const char *next; + ret = ¢ral.parseFieldDescriptor(s, next); + + if (*next) + verifyError(VerifyError::badClassFormat); + } + + signature.nArguments = numParams; + signature.argumentTypes = params; + signature.resultType = ret; + signature.isStatic = isStatic; +} + +/* Create a Method object for a method with given packageName, className + * and shortName. (Also see FieldOrMethod::FieldOrMethod). + * summary is the information about the declaring class; central is + * the repository used to hold ClassFileSummary structures. + * info contains compile-time information about the method. + * vtableType is the type of the object to be passed on to the + * JavaObject constructor. + */ +Method::Method(const char *packageName, const char *className, + const char *shortName, + ClassFileSummary &summary, ClassCentral &c, Pool &pool, + const MethodInfo &info, const Type *vtableType) : + FieldOrMethod((vtableType) ? *vtableType : *static_cast(&Standard::get(cMethod)), + packageName, className, shortName, info.getDescriptor()->getUtfString(), + summary, c, pool), + minfo(info), argsSize(-1), dynamicallyDispatched(false), vIndex(-1), + signatureResolved(false) +{ + modifiers = info.getAccessFlags(); + + bool isAbstract, isStatic, isFinal, isSynchronized, isNative; + const char *sig; + minfo.getInfo(sig, isAbstract, isStatic, isFinal, isSynchronized, isNative); + signatureString = sig; + + DEBUG_LOG_ONLY(htmlName = NULL); +} + + +#ifdef DEBUG_LOG +void Method::printMethodAsBytecodes(LogModuleObject &f) +{ + const Signature &signature = getSignature(); + AttributeCode *code = static_cast(minfo.getAttribute("Code")); + + assert(code); + + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("Signature: ")); + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("%d locals, %d stack words, %d code bytes\n", code->getMaxLocals(), + code->getMaxStack(), code->getCodeLength())); + + if (modifiers & CR_METHOD_ABSTRACT) + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("abstract ")); + if (modifiers & CR_METHOD_STATIC) + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("static ")); + if (modifiers & CR_METHOD_FINAL) + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("final ")); + if (modifiers & CR_METHOD_SYNCHRONIZED) + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("synchronized ")); + if (modifiers & CR_METHOD_NATIVE) + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("native ")); + + signature.resultType->printRef(UT_LOG_MODULE(FieldOrMethod)); + UT_OBJECTLOG(f, PR_LOG_ALWAYS, (" %s(", shortName)); + if (signature.nArguments) { + uint i = 0; + while (true) { + signature.argumentTypes[i]->printRef(f); + i++; + if (i == signature.nArguments) + break; + UT_OBJECTLOG(f, PR_LOG_ALWAYS, (", ")); + } + } + UT_OBJECTLOG(f, PR_LOG_ALWAYS, (")\n")); + + const bytecode *bytecodesBegin = (const bytecode *)code->getCode(); + + disassembleBytecodes(f, bytecodesBegin, bytecodesBegin + code->getCodeLength(), bytecodesBegin, summary.getConstantPool(), 0); + disassembleExceptions(f, code->getNumExceptions(), code->getExceptions(), summary.getConstantPool(), 0); +} +#endif // DEBUG_LOG + + +// A little macro that just compares our stage to test stage and +// causes the function to return if we are past our desired stage +#define COMPILE_UP_TO_STAGE(inOurStage, inTestStage) \ + PR_BEGIN_MACRO \ + if (inOurStage < inTestStage) \ + return (0); \ + PR_END_MACRO + +void* Method::compile() +{ + Class *clazz = (Class *) getDeclaringClass(); + bool inhibitBackpatching = VM::theVM.getInhibitBackpatching(); + CompileStage stage = VM::theVM.getCompileStage(); + + UT_LOG(FieldOrMethod, PR_LOG_ALWAYS, ("\n\n\n\n*** Compiling method %s::%s\n", clazz->name, getName())); + + // preprocess bytecodes + gCompileBroadcaster->broadcastEvent(gCompileBroadcaster, kBroacastCompile, this); + + if (modifiers & CR_METHOD_ABSTRACT) // not allowed to compile abstract methods + verifyError(VerifyError::abstractMethod); + + AttributeCode *code = static_cast(minfo.getAttribute("Code")); + + if (!code) { + UT_LOG(FieldOrMethod, PR_LOG_DEBUG, ("No code attribute\n")); + runtimeError(RuntimeError::illegalAccess); + } + + COMPILE_UP_TO_STAGE(stage, csPreprocess); + + Uint32 maxLocals = code->getMaxLocals(); + Uint32 maxStack = code->getMaxStack(); + const bytecode *bytecodesBegin = (const bytecode *)code->getCode(); + Uint32 codeLength = code->getCodeLength(); + + const Signature &signature = getSignature(); + const Type **argumentTypes = signature.argumentTypes; + const Type *resultType = signature.resultType; + int nArguments = signature.nArguments; + + DEBUG_LOG_printMethodAsBytecodes(UT_LOG_MODULE(FieldOrMethod)); + + // create bytecode graph + UT_LOG(FieldOrMethod, PR_LOG_ALWAYS, ("creating bytecode graph...\n")); + Pool primitivePool; + ControlGraph *cg; + + { + Pool bytecodeGraphPool; + + ValueKind *argumentKinds = new(bytecodeGraphPool) ValueKind[nArguments]; + for (int i = 0; i != nArguments; i++) + argumentKinds[i] = typeKindToValueKind(argumentTypes[i]->typeKind); + + bool isStatic = (getModifiers() & CR_METHOD_STATIC) != 0; + bool isSynchronized = (getModifiers() & CR_METHOD_SYNCHRONIZED) != 0; + BytecodeGraph bg(summary, bytecodeGraphPool, !isStatic, isSynchronized, nArguments, argumentKinds, + typeKindToValueKind(resultType->typeKind), maxLocals, maxStack, bytecodesBegin, codeLength, + code->getNumExceptions(), code->getExceptions(), + *this); + + { + Pool tempPool1; + + UT_LOG(FieldOrMethod, PR_LOG_ALWAYS, ("dividing into blocks...\n\n")); + bg.divideIntoBlocks(tempPool1); + + DEBUG_LOG_ONLY(bg.print(UT_LOG_MODULE(FieldOrMethod), summary.getConstantPool())); + COMPILE_UP_TO_STAGE(stage, csGenPrimitives); + // tempPool1 is destroyed here. + } + + { + // create primitive graph + Pool tempPool2; + cg = BytecodeTranslator::genPrimitiveGraph(bg, primitivePool, tempPool2); + // tempPool2 is destroyed here. + } + // bytecodeGraphPool is destroyed here. + } + + if (stage < csOptimize) { + DEBUG_LOG_ONLY(cg->print(UT_LOG_MODULE(FieldOrMethod))); + return 0; + } + + // optimize + UT_LOG(FieldOrMethod, PR_LOG_ALWAYS, ("optimizing primitive graph...\n")); + simpleTrimDeadPrimitives(*cg); + + DEBUG_LOG_ONLY(cg->print(UT_LOG_MODULE(FieldOrMethod))); + + COMPILE_UP_TO_STAGE(stage, csGenInstructions); + + // generate code + void *compiledCode = translateControlGraphToNative(*cg, *this); + + UT_LOG(FieldOrMethod, PR_LOG_ALWAYS, ("*** Done Compiling Method %s::%s\n", + clazz->name, shortName)); + + // anyone know what this is? +#ifdef DEBUG_LOG + if (VM::debugger.getEnabled()) + printDebugInfo(); +#endif + + if (!inhibitBackpatching) + updateVTable(); + + gCompileBroadcaster->broadcastEvent(gCompileBroadcaster, kBroacastCompile, this); + + return compiledCode; +} + +// Disassemble the bytecode to the specified logmodule +#ifdef DEBUG_LOG +void Method::dumpBytecodeDisassembly(LogModuleObject &f) +{ + AttributeCode *code = static_cast(minfo.getAttribute("Code")); + const bytecode *bytecodesBegin = (const bytecode *)code->getCode(); + Uint32 codeLength = code->getCodeLength(); + const ConstantPool *constantPool = summary.getConstantPool(); + + disassembleBytecodes(f, bytecodesBegin, bytecodesBegin + codeLength, bytecodesBegin, constantPool, 0); +} +#endif + +// Examine the type of the argument arg against the actual type type. +// If arg is a primitive wrapper class, extract the primitive value +// from the wrapper class. Otherwise, pass the arg on unchanged. +Uint32 Method::getWordArg(const Type &actualType, JavaObject &arg) +{ + // Check arguments for correctness + if (isPrimitiveKind(actualType.typeKind)) { + if (Standard::isPrimitiveWrapperClass(*static_cast(&arg.getType()))) + return Class::getPrimitiveValue(arg); + else { + runtimeError(RuntimeError::illegalArgument); + return 0; + } + } else { + // Ensure that arg is assignable to our argument + return (Uint32) &arg; + } +} + +void Method::getDoubleWordArg(const Type &, JavaObject &arg, Uint32 &hi, Uint32 &lo) +{ + struct { + Uint32 lo; + Uint32 hi; + } u; + + memcpy(&u, ((char *) &arg+sizeof(JavaObject)), 8); + + hi = u.hi; + lo = u.lo; +} + +JavaObject *Method::invoke(JavaObject * PC_ONLY(obj), JavaObject * PC_ONLY(args)[], Int32 PC_ONLY(nArgs)) +{ +#if defined (XP_PC) || defined(LINUX) +#if 0 + void *code = addressFunction(getCode()); +#endif + + Int32 i; + Int32 start = 0; + + Uint32 *argsToBePassed = 0; + + // Make sure we're passing the right kind of object + if (!(getModifiers() & CR_METHOD_STATIC)) + if (!obj || !getDeclaringClass()->isAssignableFrom(*obj->type)) + runtimeError(RuntimeError::illegalArgument); + + // Make sure we're passing the right number of arguments + Int32 nArgsToCompare = ((getModifiers() & CR_METHOD_STATIC)) ? + getSignature().nArguments : getSignature().nArguments-1; + + if (nArgs != nArgsToCompare) + runtimeError(RuntimeError::illegalArgument); + + // If we're an instance method, pass ourselves in as the first argument + if ((getModifiers() & CR_METHOD_STATIC) == 0) { + start = 1; + argsToBePassed = new Uint32[++nArgs*2]; + argsToBePassed[0] = (Uint32) obj; + } else + argsToBePassed = new Uint32[nArgs*2]; + + Int32 nWords = 0; // Number of words to push on the stack + + for (nWords = start, i = start; i < nArgs; i++) { + // FIX Currently assumes none of the args are double-word + if (!Standard::isDoubleWordPrimitiveWrapperClass(*static_cast(signature.argumentTypes[i]))) + argsToBePassed[nWords++] = (args[i-start]) ? getWordArg(*signature.argumentTypes[i], *args[i-start]): 0; + + else { + if (args[i-start]) + getDoubleWordArg(*signature.argumentTypes[i], *args[i - start], + argsToBePassed[nWords], argsToBePassed[nWords+1]); + else + argsToBePassed[nWords] = argsToBePassed[nWords+1] = 0; + + nWords += 2; + } + } + +#if 0 + //Uint32 returnValue; + for (Int32 n = nWords - 1; n >= 0; n--) { + void *arg = (void *) argsToBePassed[n]; + prepareArg(n, arg); + } + + callFunc(code); + + getReturnValue(returnValue); +#else + ReturnValue returnValue = invokeRaw(obj, argsToBePassed, nWords); +#endif + + if (argsToBePassed) + delete [] argsToBePassed; + + // Wrap up the return value inside an object if neccessary + if (signature.resultType->typeKind != tkVoid) { + if (isPrimitiveKind(signature.resultType->typeKind)) { + if (!isDoublewordKind(signature.resultType->typeKind)) + return &Class::makePrimitiveObject(signature.resultType->typeKind, + (void *) &returnValue.wordValue); + else + return &Class::makePrimitiveObject(signature.resultType->typeKind, + (void *) &returnValue.doubleWordValue); + } else + return (JavaObject *) returnValue.wordValue; + } else + return 0; + +#else + trespass("Method::invoke() not implemented for this platform\n"); + return 0; +#endif +} + + +ReturnValue Method::invokeRaw(JavaObject* /*obj*/, Uint32 argsToBePassed[], Int32 nWords) +{ + Uint32 wordRet; + ReturnValue returnValue; + void *code = addressFunction(getCode()); + + for (Int32 n = nWords - 1; n >= 0; n--) { + void *arg = (void *) argsToBePassed[n]; + prepareArg(n, arg); + } + + callFunc(code); + + getReturnValue(wordRet); + + // XXX Double-word return values are currently broken + assert(!isDoublewordKind(getSignature().resultType->typeKind)); + + returnValue.wordValue = wordRet; + + return returnValue; +} + +#undef PC_ONLY + +Int32 Method::getArgsSize() +{ + if (argsSize >= 0) + return argsSize; + + Int32 size = 0; + + // Make sure the signature has been created + getSignature(); + + for (uint i = 0; i < signature.nArguments; i++) { + const Type *t = signature.argumentTypes[i]; + + assert(t); + size += getTypeSize(*t); + } + + return (argsSize = size); +} + + +#ifdef DEBUG_LOG +// +// Print a reference to this method for debugging purposes. +// Return the number of characters printed. +// +int Method::printRef(LogModuleObject &f) const +{ + int o = getDeclaringClass()->printRef(f); + return o + UT_OBJECTLOG(f, PR_LOG_ALWAYS, (".%s", shortName)); +} +#endif + +/* Return a pointer to the compiled code of the method. This might be a + * stub that actually compiles the method when called. This stub may or + * may not "backpatch" the call site to point to the newly compiled method + * depending on whether or not the method is normally statically dispatched. + * This backpatching is not done when inhibitBackpatch is true. (This + * argument is used for implementations of interface methods which are + * always dispatched using a vtable and which, therefore, shouldn't + * backpatch their caller.) + */ +addr Method::getCode(bool inhibitBackpatch) +{ + MethodDescriptor descriptor(*this); + return NativeCodeCache::getCache().lookupByDescriptor(descriptor, + inhibitBackpatch); + +} + + +// Checks to see that the given className, methodName and signature +// represent this method. +bool Method::isSelf(const char *fullyQualifiedClassName, const char *simpleMethodName, + const char *javaSig) +{ + Class *clazz = (Class *) getDeclaringClass(); + + return (((fullyQualifiedClassName == clazz->getName()) || (*fullyQualifiedClassName == '*')) && + ((simpleMethodName == shortName) || (*simpleMethodName == '*')) && + ((javaSig == signatureString) || (*javaSig == '*'))); + +} + +#ifdef DEBUG_LOG +// Dumps the local variable table with the debug information +void +Method::printDebugInfo() +{ + AttributeCode *code = (AttributeCode *) + getMethodInfo().getAttribute("Code"); + AttributeLocalVariableTable *localVariableTable = + (AttributeLocalVariableTable *) + code->getAttribute("LocalVariableTable"); + + if (!localVariableTable) { + UT_LOG(Debugger, PR_LOG_ALWAYS, ("No debug info\n")); + return; + } + + // Walk the local variable table + Uint32 n = localVariableTable->getNumEntries(); + for(Uint32 i=0; i < n; i++) { + LocalVariableEntry& entry = localVariableTable->getEntryByNumber(i); + entry.dump(); + DoublyLinkedList& mappings = entry.mappings; + for (DoublyLinkedList::iterator j = mappings.begin(); + !mappings.done(j); + j = mappings.advance(j)) { + IntervalMapping& mapping = mappings.get(j); + mapping.dump(); + } + } +} +#endif + +/* Class Constructor */ +JavaObject &Constructor::newInstance(JavaObject *params[], Int32 numParams) +{ + ClassOrInterface *declaringClass = getDeclaringClass(); + + if (declaringClass->isArray()) + runtimeError(RuntimeError::illegalArgument); + + JavaObject &newObject = (static_cast(declaringClass))->newInstance(); + + invoke(&newObject, params, numParams); + return newObject; +} + +#ifdef DEBUG_LOG + +void Method::resolveHTMLName() +{ + if (htmlName) + return; + + // gererate a hash value from the fully qualified name + const char* p = toString(); + Uint32 hash = 0; + while(*p) + hash = (hash << 1) + *p++; + + char hashText[11]; + sprintf(hashText, "[%08x]", hash); + + // name length + const char* name = getName(); + Uint32 len = strlen(name); + if(len > 16) + len = 16; + + htmlName = new char[len + 10 + 5 + 1]; + + // copy name and clean out undesirable chars + htmlName[len] = 0; + strncpy(htmlName, name, len); + char* q = htmlName; + while(*q) { + switch(*q) { + case ':': case '<': case '>': case '/': case ' ': + *q = '_'; + } + q++; + } + + // append hash vale and .html + strcat(htmlName, hashText); + strcat(htmlName, ".html"); + Uint32 newLen = strlen(htmlName); + assert(newLen < 32); +} + +#endif // DEBUG_LOG diff --git a/ef/Runtime/System/FieldOrMethod.h b/ef/Runtime/System/FieldOrMethod.h new file mode 100644 index 000000000000..bcef0eee62e8 --- /dev/null +++ b/ef/Runtime/System/FieldOrMethod.h @@ -0,0 +1,460 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#ifndef _FIELD_OR_METHOD_H_ +#define _FIELD_OR_METHOD_H_ + +#include "plstr.h" + +#include "ClassFileSummary.h" +#include "ClassCentral.h" +#include "NativeDefs.h" +#include "LogModule.h" +#include "Debugger.h" + +/* Compiling stage for debugging purposes */ +enum CompileStage { + csRead, + csPreprocess, + csGenPrimitives, + csOptimize, + csGenInstructions, + csExecute +}; + +union ReturnValue { + Uint32 wordValue; + Uint64 doubleWordValue; +}; + +struct NS_EXTERN FieldOrMethod: JavaObject { + +public: + /* shortName is the short (unqualified name) of the field/method. + * packageName is the name of the package within which the declaring + * class is enclosed. className is the unqualified name of the declaring + * class of this field/method. summary is the ClassFileSummary of the + * declaring class. + * pool is used to allocate dynamic memory; central is a repository + * class that is used to add classes that this class might encounter + * when parsing its descriptor. + */ + FieldOrMethod(const Type &type, const char *packageName, const char *className, + const char *shortName, const char *signatureString, + ClassFileSummary &summ, ClassCentral &c, Pool &pool): + JavaObject(type), + central(c), fullName(0), shortName(shortName), className(className), + packageName(packageName), p(pool), summary(summ), + signatureString(signatureString) {} + + + /* Returns true if the signature string represents a primitive + * type or a string type. + */ + static bool primitiveOrStringSignature(const char *sig); + + /* Returns the Class or Interface that this field or method is + * a member of. In order to get the real Class you can pass this + * to asClass, in JavaObject.h -- which will attempt to safely + * cast to a Class (if possible). FIX-ME can this return NULL? + */ + ClassOrInterface *getDeclaringClass() const { + return static_cast(summary.getThisClass()); + } + + /* Returns the short (unqualified) name of the field/method */ + const char *getName() const { return shortName; } + + /* Returns the access flags of the field/method as found in + * the class file. + */ + int getModifiers() const { return modifiers; } + + /* Returns true if obj is an instance of this field. */ + bool equals(JavaObject &obj) const { + /* Since we will not be creating duplicate copies of Field objects, + * a simple pointer comparision will suffice + */ + return ((JavaObject *) this == &obj); + } + + /* return the string corresponging to the signature of the method. */ + const char *getSignatureString() { return signatureString; } + + // int hashCode(); + +protected: + /* ClassCentral object used to add classes as neccessary when parsing the + * field descriptor + */ + ClassCentral ¢ral; + + /* Full name of the field or method */ + mutable const char *fullName; + + /* Short name of the field or method */ + const char *shortName; + + /* unqualified name of the class that this field/method belongs to */ + const char *className; + + /* Package name of the field or method */ + const char *packageName; + + /* field/method modifiers and access flags */ + Uint16 modifiers; + + /* pool used to dynamically allocate memory */ + Pool &p; + + /* Summary that holds compile-time information about the class */ + ClassFileSummary &summary; + + /* The UTF string representation of the signature of this method */ + const char *signatureString; + + /* Given a type, returns a string describing the type as + * specified in the Java Reflection API. Initially, str is of + * size (not length) strLen; this method grows str as necessary and sets + * strLen to the new size. + */ + static void getTypeString(const Type &type, char *&str, Uint32 &strLen); + +}; + + +struct NS_EXTERN Field : FieldOrMethod { + +public: + Field(const char *packageName, const char *className, + const char *shortName, + ClassFileSummary &summary, ClassCentral &c, + Pool &pool, + Uint32 runningOffset, + const FieldInfo &info); + + static void widen(void *valueFrom, void *valueTo, TypeKind tkFrom, TypeKind tkTo); + + /* Returns the fully qualified name and type of the field or method, eg, + * public static java.lang.thread.priority + */ + const char *toString() { + if (!fullName) getFullName(); + return fullName; + } + + /* In all the get and set methods below, obj can be NULL if the field + * is static. otherwise, obj must be an object of the right type. + */ + + /* Get the value of this field within the object given by obj */ + JavaObject &get(JavaObject *obj); + + + /* Get the value of the field in various forms. */ + Int8 getBoolean(JavaObject *obj); + Int8 getByte(JavaObject *obj); + Int16 getChar(JavaObject *obj); + Int16 getShort(JavaObject *obj); + Int32 getInt(JavaObject *obj); + Int64 getLong(JavaObject *obj); + Flt32 getFloat(JavaObject *obj); + Flt64 getDouble(JavaObject *obj); + + /* Set the value of the field from the given valueKind and value. + * Throws a VerifyError::badClassFormat if the types do not match. + */ + void setFromValue(ValueKind vk, Value value); + + /* Set the value of this field within the object obj to value */ + void set(JavaObject *obj, JavaObject &value); + + /* Set the value of the field in various forms. Appropriate exceptions + * are thrown if types don't match + */ + void setBoolean(JavaObject *obj, Int8 value); + void setByte(JavaObject *obj, Int8 value); + void setChar(JavaObject *obj, Int16 value); + void setShort(JavaObject *obj, Int16 value); + void setInt(JavaObject *obj, Int32 value); + void setLong(JavaObject *obj, Int64 value); + void setFloat(JavaObject *obj, Flt32 value); + void setDouble(JavaObject *obj, Flt64 value); + + /* return the address of the field if static */ + addr getAddress() const; + + /* return the offset of the field if dynamic */ + Uint32 getOffset() const + { assert (!(modifiers & CR_FIELD_STATIC)); return pos.offset; } + + /* Get the type of the field */ + const Type &getType() const { return *typeOfField; } + +protected: + const char *getFullName(); + +private: + /* The Type class for this field */ + const Type *typeOfField; + + /* Address of this field in memory/Offset inside declaring class */ + union NS_EXTERN { + Uint32 offset; + addr address; + } pos; + + /* Return a new instance of an object of the given class. + */ + JavaObject &makeObject(const Class &c) { + return *new(p) JavaObject(c); + } + + JavaObject &convertObject(void *address); + JavaObject &makeObjectWrapper(void *address); + void *getRaw(JavaObject *obj); + + bool isPrimitive(); +}; + + +struct NS_EXTERN Method : public FieldOrMethod { + +public: + Method(const char *packageName, const char *className, + const char *shortName, + ClassFileSummary &summary, ClassCentral &c, Pool &p, + const MethodInfo &info, const Type *vtableType = 0); + + /* Returns the fully qualified name and type of the field or method, eg, + * public static java.lang.thread.priority + */ + const char *toString() { + if (!fullName) getFullName(); + return fullName; + } + + /* Get the vtable index of this method. */ + bool getVIndex(Uint32 &index) const + { index = vIndex; return vIndex != -1; } + + /* Set the vIndex of the method (for dynamically resolved methods only) + Note: a single method can be both statically and dynamically resolved + depending on whether or not it is called through an interface. + */ + void setVIndex(Uint32 index) { + if (getModifiers() & CR_METHOD_STATIC) + return; + if (vIndex == -1) + vIndex = index; + } + + /* getWordArg() is used to generate a 32-bit value that + * can be passed as an argument to a function. If arg is + * a JavaObject representing a non-primitive type, + * a pointer to arg is returned as a 32-bit value. If + * arg is a primitive class (java/lang/Integer...etc) + * then the corresponding primitive value is returned + * as a 32-bit unsigned (raw) quantity. + */ + static Uint32 getWordArg(const Type &type, JavaObject &arg); + + /* getDoubleWordArg() is used to generate a 64-bit value that + * can be passed as an argument to a function. + * arg is an object of class java/lang/Long or java/lang/Boolean; + * getDoubleWordArg() extracts and returns the 64-bit value + * as two 32-bit quantities. + */ + static void getDoubleWordArg(const Type &type, JavaObject &arg, Uint32 &hi, Uint32 &lo); + + /* returns the Type class corresponding to the return parameter of + * this method. + */ + const Type &getReturnType() { resolveSignature(); return *signature.resultType; } + + /* Sets params to point to the Type objects for the parameters of + * this method. Returns number of params + */ + Int32 getParameterTypes(const Type **¶ms) + { resolveSignature(); params = signature.argumentTypes; return signature.nArguments; } + + /* Sets params to point to the exception types for this method. + * Returns number of exception types + */ + Int32 getExceptionTypes(const Type *¶ms); + + /* Invoke the specified method on the given object. args is an + * array of parameters to be passed to the method. If a parameter is + * of a primitive type, then it must be wrapped inside a primitive wrapper + * class object. obj is the object to invoke the method on; it can be NULL + * if the method being invoked is static. Otherwise, it must be an object of + * the correct type. + * Returns the object returned by the method just invoked, wrapped + * inside a primitive class if neccessary. + */ + JavaObject *invoke(JavaObject *obj, JavaObject *args[], Int32 nArgs); + + /* Invoke the specified method on the given object. args is an + * array of parameters to be passed to the method. All parameters must be + * of the "raw" form: they are passed in as an array of 32-bit words. + * Double-word parameters must be passed in as two consecutive words + * in the array. obj is the object to invoke the method on; it can be NULL + * if the method being invoked is static. Otherwise, it must be an object of + * the correct type. nWords is the number of words in the array, not the + * number of arguments. + * This routine does not check for correctness of arguments; it is the caller's + * responsibility to ensure that the arguments are correct. + * + * Returns the return value of the method as a word or double-word + * depending on the return-type. + */ + ReturnValue invokeRaw(JavaObject *obj, Uint32 args[], Int32 nWords); + + /* Returns the signature of the method */ + const Signature &getSignature() { resolveSignature(); return signature; } + + /* Compile the byte code of the method. Returns a pointer to the compiled + * code. For dynamically dispatched methods, patches the vtable of the + * declaring class/interface with the pointer to the compiled code. + */ + void *compile(); + + /* Return the total size of the parameters of this method. */ + Int32 getArgsSize(); + + /* Return a pointer to the compiled code of the method. This might be a + * stub that actually compiles the method when called. + */ + addr getCode(bool inhibitBackpatch = false); + + /* A method can have a vtableIndex when it serves as the implementation + of an interface method and yet still be statically resolved during + "normal" method lookup, hence the requirement for a separate flag that + indicates whether normal method dispatch is done using a vtable. */ + bool getDynamicallyDispatched() const { return dynamicallyDispatched; } + void setDynamicallyDispatched(bool b) {dynamicallyDispatched = b; } + + /* Update the vtable of the declaring class and all subclasses that inherit + this method. */ + void updateVTable() {summary.updateVTable(*this);} + + void resolveSignature() { + if (!signatureResolved) + parseMethodDescriptor(signatureString); + } + + bool isSelf(const char *fullyQualifiedClassName, const char *simpleMethodName, + const char *javaSig); + + const MethodInfo &getMethodInfo() { return minfo; } + +#ifdef DEBUG_LOG + int printRef(LogModuleObject &f) const; + void printDebugInfo(); +#endif + pcToByteCodeTable& getPC2Bci() { return pc2bci; }; + +protected: + const char *getFullName(); + +private: + + /* Parse the signature of the method and fill up the Signature field. */ + void parseMethodDescriptor(const char *sig); + + /* Signature of the method. */ + Signature signature; + + /* Static structure that holds the byte code of the method */ + const MethodInfo &minfo; + + /* Total size of the parameters of this method. Set to -1 if it + * hasn't been computed yet. + */ + Int32 argsSize; + + /* If false, this method has been statically resolved and the caller must be + * back-patched when this method is compiled. If true, then this method + * has been dynamically resolved; the caller is not backpatched, but the + * vtable entry is. + */ + bool dynamicallyDispatched; + + /* If true, all classes mentioned in method's signature have been loaded */ + bool signatureResolved; + + /* VIndex of the method in the class that defined it if a dynamically + * resolved method; if a statically resolved method, a is the address of + * the code of the method. + */ + union { + Int32 vIndex; + addr a; + }; + + pcToByteCodeTable pc2bci; + + // HTML debug support +#ifdef DEBUG_LOG +protected: + char* htmlName; + void resolveHTMLName(); +public: + const char* getHTMLName() { resolveHTMLName(); return htmlName; } + void dumpBytecodeDisassembly(LogModuleObject &f); + + /* on in debug version that prints a method's bytecode representation */ + void printMethodAsBytecodes(LogModuleObject &f); +#define DEBUG_LOG_printMethodAsBytecodes(f) printMethodAsBytecodes(f); +#else +#define DEBUG_LOG_printMethodAsBytecodes(f) +#endif// DEBUG_LOG +}; + +struct NS_EXTERN Constructor : public Method { +public: + Constructor(const char *packageName, const char *className, + const char *shortName, + ClassFileSummary &summary, ClassCentral &c, Pool &p, + const MethodInfo &info) : + Method(packageName, className, shortName, summary, c, p, info, + &Standard::get(cConstructor)) { } + + /* Construct a new instance of the object. params is an array of + * arguments for the constructor; numParams is the length of the + * array. + */ + JavaObject &newInstance(JavaObject *params[], Int32 numParams); +}; + +inline bool FieldOrMethod::primitiveOrStringSignature(const char *sig) { + return (!PL_strcmp(sig, "Ljava/lang/String;") || + !PL_strcmp(sig, "Z") || + !PL_strcmp(sig, "B") || + !PL_strcmp(sig, "C") || + !PL_strcmp(sig, "D") || + !PL_strcmp(sig, "F") || + !PL_strcmp(sig, "I") || + !PL_strcmp(sig, "S")); +} + +#endif /* _FIELD_OR_METHOD_H_ */ + + + + + diff --git a/ef/Runtime/System/InterfaceDispatchTable.cpp b/ef/Runtime/System/InterfaceDispatchTable.cpp new file mode 100644 index 000000000000..477dabc50f88 --- /dev/null +++ b/ef/Runtime/System/InterfaceDispatchTable.cpp @@ -0,0 +1,462 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#include "InterfaceDispatchTable.h" + +/* This class is used to construct the data structures that enable fast, + constant-time assignability checks, i.e. for implementing the instanceof + and checkcast bytecodes. + + This class also builds the lookup tables used for constant-time dispatch + of interface functions. +*/ + +/* + Algorithm notes: + + Dispatch of interface methods is handled by an interface-specific "sub-vtable" + that is embedded within the vtable of each class that implements that interface. + The location of this sub-vtable within a vtable may be different for each class + (because the classes share no inheritance relationship). The mapping from a + {Class, Interface} tuple to a sub-vtable offset can be performed in constant + time by enumerating all classes and interfaces and performing a 2-D table + lookup. In the example table below, sub-vtable offsets are represented + symbolically with capital letters: + + + Interface # + | 0 1 2 3 4 5 .... + --------------------------------------------- + 0 | X Y + 1 | X Z Y + Class 2 | Y + # 3 | W + 4 | V T + | + + + For reasonably large programs, however, this lookup table can become quite + large, so we borrow a technique for compressing sparse matrices. Typically, + many classes implement some or all of the same interfaces as other classes. + The 2-D table is compressed into 1-D by shifting rows in the table until there + are no conflicting entries in each column: + + + Interface # + [SHIFT] | 0 1 2 3 4 5 .... + --------------------------------------------- + 0--> 0 | X Y + 0--> 1 | X Z Y + 4--> Class 2 | Y + 1--> # 3 | W + 1--> 4 | V T + | + + Next, the 2-D array is compressed into a 1-D vector by collapsing all the rows: + + Index # + 0 1 2 3 4 5 .... + ------------------------------------- + X W Z V Y T + + To lookup the sub-vtable location for a given class, a given class' SHIFT + value is added to the desired interface's number to form the index into + the compacted 1-D table. + + Note that this lookup table scheme assumes that, before an interface method + is dispatched, the class is known to implement the interface. However, + this same table cannot be used to perform the assignability check which + would determine if the class implemented the interface. For example, + in the sample table above class #0 does not implement interface #2, + and yet there is an entry corresponding to this combination in the + compressed 1-D lookup table. + +*/ + +/* + + For performing assignability tests (in order to implement the instanceof and + checkcast bytecodes) a separate lookup table is used, but that table employs a + similar methodology as the vtable offset table used for interface dispatch. + + As with the vtable/dispatch lookup table, a 2D array is compressed into a + 1-D vector. However, this table has stricter limitations on how this + compression can take place. + + Consider the table below in which the presence of a letter in the table + indicates that the corresponding class is implemented by the interface. + Each entry letter represents a unique color that is applied to all the + entries for a given class, i.e. all entries in the same row have the + same color. (However, if any two classes implement exactly the same + set of interfaces, they can be colored the same, as with classes 2 and + 3 below: + + Interface # + | 0 1 2 3 4 5 .... + --------------------------------------------- + 0 | A A + 1 | B B B + Class 2 | C + # 3 | C + 4 | E E + | + + + Applying shifts to each row: + + Interface # + [SHIFT] | 0 1 2 3 4 5 6 .... + ------------------------------------------------- + 0--> 0 | A A + 1--> 1 | B B B + 2--> Class 2 | C + 2--> # 3 | C + 3--> 4 | E E + | + + + Finally, the 2-D array is compressed into a 1-D vector by collapsing all the rows: + + Index # + 0 1 2 3 4 5 6 .... + ------------------------------------------- + A B C B A B E E + + To determine if an instance of a particular class is assignable to + a variable with a given interface type, we test to see if the following + expression is true: + + table[class(instance).shift + interface.number] == color(class(instance)) + +*/ + +/* The system-wide table for handling vtable-based dispatch of interface + methods for all classes/interfaces */ +VTableOffset InterfaceDispatchTable::VOffsetTable[interfaceDispatchTableSize]; + +/* The system-wide table used for performing instanceof and checkcast + operations on interface types and on arrays of interface types */ +Uint16 InterfaceDispatchTable::assignabilityTable[interfaceAssignabilityTableSize]; + +/* Counter used to assign unique values to assignability color */ +Uint16 InterfaceDispatchTable::sColorCounter; + +/* Hashtable keyed by the set of interfaces that are implemented by a class. + This is used to eliminate redundancy in the assignability table. */ +InterfaceSetHashTable *InterfaceDispatchTable::hashTable; + +/* Class initialization */ +void InterfaceDispatchTable::staticInit(Pool &pool) { + hashTable = new InterfaceSetHashTable(pool); +} + +/* Return true if the list contains a given interface, false otherwise. */ +static bool contains(InterfaceList *interfaceList, Uint32 interfaceNumber) +{ + int size = interfaceList->size(); + for (int i = 0; i < size; i++) { + if ((*interfaceList)[i].interfaceNumber == interfaceNumber) + return true; + } + return false; +} + +/* Used to implement HashTable's keyed by InterfaceLists. + Return true if two interfaceListKey1 and interfaceListKey2 + contain the identical set of interfaces. + + XXX - uses slow N^2 algorithm + */ +bool InterfaceListKeyOps::equals(InterfaceList * interfaceListKey1, + InterfaceList * interfaceListKey2) { + int size1 = interfaceListKey1->size(); + int size2 = interfaceListKey2->size(); + + if (size1 != size2) + return false; + + for (int i = 0; i < size1; i++) { + InterfaceVIndexPair iPair = (*interfaceListKey1)[i]; + if (!contains(interfaceListKey2, iPair.interfaceNumber)) + return false; + } + return true; +} + +/* Used to implement HashTable's keyed by InterfaceLists. + Returns a hashcode that is the same among any two InterfaceLists + that contain the same set of interfaces. Since InterfaceLists + are unsorted, the hashcode must not depend on the order + of elements in the list. */ +Uint32 InterfaceListKeyOps::hashCode(InterfaceList * interfaceListKey) { + Uint32 hashCode = 0; + int size = interfaceListKey->size(); + for (int i = 0; i < size; i++) { + InterfaceVIndexPair iPair = (*interfaceListKey)[i]; + Uint32 interfaceNumber = iPair.interfaceNumber; + hashCode *= (interfaceNumber + 1); + } + return hashCode; +} + +/* Check to see whether it is possible to pack a sparse vector of + interface numbers into the global vtable interface lookup table in a + conflict-free manner by shifting the vector entries uniformly + using the provided value. */ +bool InterfaceDispatchTable::tryFitVOffset(Uint32 shift) +{ + int size = interfaceList->size(); + for (int i = 0; i < size; i++) { + InterfaceVIndexPair iPair = (*interfaceList)[i]; + Uint32 tableIndex = iPair.interfaceNumber + shift; + Uint32 baseVOffset = VOffsetTable[tableIndex]; + if (baseVOffset && iPair.baseVOffset && (baseVOffset != iPair.baseVOffset)) + return false; + } + return true; +} + +/* Discover a conflict-free packing in the global vtable interface lookup + table of the given classes' vector of implemented interfaces. The + packing is made possible by shifting the vector left or right so that + the non-empty entries fall in the unoccupied interstices in the global + interface lookup table. */ +bool InterfaceDispatchTable::packIntoVOffsetTable() +{ + bool success = false; + + /* A brute-force scan to locate a collision-free packing */ + Uint32 maxShift = interfaceDispatchTableSize - maxInterfaces; + Uint32 shift = 0; + if (inheritedInterfaceTable) { + /* Since we have to accomodate all the interfaces in our parent + (as well as our own), we know that there will be no packing + that uses a shift value less than our parent's, so start there. */ + Uint32 parentShift = inheritedInterfaceTable->vShift; + shift = parentShift; + } + for (; shift <= maxShift; shift++) { + success = tryFitVOffset(shift); + if (success) + break; + } + + /* See if we overflowed the global interface lookup table */ + if (!success) + return false; + + /* We found a way to pack this class' interfaces into the global + interface dispatch table. Copy the entries into the table. */ + Uint32 size = interfaceList->size(); + for (Uint32 i = 0; i < size; i++) { + InterfaceVIndexPair ipair = (*interfaceList)[i]; + Uint32 tableIndex = ipair.interfaceNumber + shift; + if (ipair.baseVOffset) + VOffsetTable[tableIndex] = ipair.baseVOffset; + } + + vShift = shift; + + return true; +} + +/* Check to see whether it is possible to pack a sparse vector of + interface numbers into the global interface assignability table in + a conflict-free manner by shifting the vector entries uniformly + using the provided value. */ +bool InterfaceDispatchTable::tryFitAssignability(Uint32 shift) +{ + int size = interfaceList->size(); + for (int i = 0; i < size; i++) { + InterfaceVIndexPair iPair = (*interfaceList)[i]; + Uint32 tableIndex = iPair.interfaceNumber + shift; + if (assignabilityTable[tableIndex]) + return false; + } + return true; +} + +/* Discover a conflict-free packing in the global interface lookup table + of the given classes' vector of implemented interfaces. The packing + is made possible by shifting the vector left or right so that the + non-empty entries fall in the unoccupied interstices in the global + interface lookup table. */ +bool InterfaceDispatchTable::packIntoAssignabilityTable() +{ + InterfaceDispatchTable *match; + + /* If another class implements exactly the same set of interfaces + we can share our assignability testing table with that class. */ + if (hashTable->get(interfaceList, &match)) { + aShift = match->aShift; + assignabilityColor = match->assignabilityColor; + return true; + } + hashTable->add(interfaceList, this); + + assignabilityColor = ++sColorCounter; + + bool success = false; + + /* A brute-force scan to locate a collision-free packing */ + Uint32 maxShift = interfaceAssignabilityTableSize - maxInterfaces; + Uint32 shift = 0; + if (inheritedInterfaceTable) { + /* Since we have to accomodate all the interfaces in our parent + (as well as our own), we know that there will be no packing + that uses a shift value less than or the same as our parent's. */ + Uint32 parentShift = inheritedInterfaceTable->aShift; + shift = parentShift + 1; + } + for (; shift <= maxShift; shift++) { + success = tryFitAssignability(shift); + if (success) + break; + } + + /* See if we overflowed the global interface lookup table */ + if (!success) + return false; + + /* We found a way to pack this class' interfaces into the global + interface dispatch table. Copy the entries into the table. */ + Uint32 size = interfaceList->size(); + for (Uint32 i = 0; i < size; i++) { + InterfaceVIndexPair ipair = (*interfaceList)[i]; + Uint32 tableIndex = ipair.interfaceNumber + shift; + assignabilityTable[tableIndex] = assignabilityColor; + } + + aShift = shift; + + return true; +} + +/* Add an interface to the set of interfaces that is implemented by + a single class. This interface has a sub-vtable that begins at + an offset of baseVIndex from the beginning of the class' vtable. */ +void InterfaceDispatchTable::add(Uint32 interfaceNumber, + Uint32 baseVOffset) +{ + if (interfaceList == NULL) { + interfaceList = new InterfaceList(5); + } else { + /* Don't add the same interface more than once. (This can + occur when a class implements an interface that is + a sub-interface of more than one disjoint interface which + is implemented by the class.) */ + int size = interfaceList->size(); + /* Linear search is probably OK given the small size of most + interface lists */ + for (int i = 0; i < size; i++) { + if (interfaceNumber == (*interfaceList)[i].interfaceNumber) + return; + } + } + + InterfaceVIndexPair iPair; + iPair.baseVOffset = baseVOffset; + iPair.interfaceNumber = interfaceNumber; + interfaceList->append(iPair); +} + +/* Merge the list of interfaces with the list of inherited interfaces. */ +void InterfaceDispatchTable::mergeInterfaceLists() +{ + if (!inheritedInterfaceTable) + return; + InterfaceList *inheritedInterfaceList = inheritedInterfaceTable->interfaceList; + int size = inheritedInterfaceList->size(); + InterfaceVIndexPair *iPair; + for (int i = 0; i < size; i++) { + iPair = &(*inheritedInterfaceList)[i]; + add(iPair->interfaceNumber, iPair->baseVOffset); + } +} + +/* After building up the list of all implemented interfaces using + interfaceDispatchTable::add(), the build method is used to integrate + that list into the global interface/class lookup table in a + space-efficient manner. */ +InterfaceDispatchTable *InterfaceDispatchTable::build() +{ + /* If this class doesn't define any new interfaces, then we can share + the interface table packing with its parent class */ + if (interfaceList == NULL) { + if (inheritedInterfaceTable) { + InterfaceDispatchTable *tmpTable = inheritedInterfaceTable; + delete this; + return tmpTable; + } else { + return this; + } + } + + /* Merge the list of interfaces with the list of inherited interfaces. */ + mergeInterfaceLists(); + + /* The given class implements some interfaces that its direct superclass does + not. Attempt to find a conflict-free packing in each of the + global interface tables of the list of implemented interfaces for the + given class. */ + if (!packIntoVOffsetTable()) + return NULL; + + /* Build table for instanceof and checkcast operations */ + if (!packIntoAssignabilityTable()) + return NULL; + +#if 0 + /* We don't delete the interface list because it can be inherited by subclasses */ + delete interfaceList; + interfaceList = NULL; +#endif + + return this; +} + +/* Integrate the list into the global interface/class lookup table in a + space-efficient manner. This may cause the original + interfaceDispatchTable to be destroyed and replaced with one that + is shared with another class. */ +bool build(InterfaceDispatchTable * &interfaceDispatchTable) +{ + InterfaceDispatchTable *newTable = interfaceDispatchTable->build(); + if (newTable) { + interfaceDispatchTable = newTable; + return true; + } + return false; +} + +/* Use another interface lookup table as the basis for constructing this table. + This is used when inheriting interfaces from superclasses. */ +void InterfaceDispatchTable::inherit(InterfaceDispatchTable *table) +{ + if (!table) + return; + + InterfaceList *inheritedInterfaceList = table->interfaceList; + if (!inheritedInterfaceList) + return; + + assert (!inheritedInterfaceTable); + inheritedInterfaceTable = table; +} + + diff --git a/ef/Runtime/System/InterfaceDispatchTable.h b/ef/Runtime/System/InterfaceDispatchTable.h new file mode 100644 index 000000000000..39c441200bfc --- /dev/null +++ b/ef/Runtime/System/InterfaceDispatchTable.h @@ -0,0 +1,134 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#ifndef InterfaceDispatchTable_H +#define InterfaceDispatchTable_H + +/* Efficient mapping from {Class, Interface} to vtable offset */ + +#include "Vector.h" +#include "HashTable.h" + +/* A type used to hold the offset, in bytes, into a vtable */ +typedef Uint32 VTableOffset; + +struct InterfaceVIndexPair { + Uint32 interfaceNumber; // Unique serial number of interface + Uint32 baseVOffset; // Offset, in bytes, to first entry in interface's vtable +}; +typedef Vector InterfaceList; +typedef InterfaceList *InterfaceListPtr; + +struct InterfaceListKeyOps { + static bool equals(InterfaceList * userKey, InterfaceList * hashTableKey); + + static InterfaceList *copyKey(Pool &/*pool*/, InterfaceList* userKey) { + return userKey; + } + + static Uint32 hashCode(InterfaceList * userKey); +}; + +class InterfaceDispatchTable; +typedef InterfaceDispatchTable *InterfaceDispatchTablePtr; +typedef HashTable InterfaceSetHashTable; + +class InterfaceDispatchTable { +public: + /* Maximum number of simultaneously loaded interfaces in the entire VM. + If we exceed this limit, we throw an error during compilation. + This is only an enum because const class members suck in C++ */ + enum {maxInterfaces = 2048}; + + /* Arbitrary upper bound for global lookup table sizes. + If we blow out these limits, we throw an error during compilation. + This is only an enum because const members suck in C++ */ + enum {interfaceDispatchTableSize = 4096}; + enum {interfaceAssignabilityTableSize = 8192}; + +private: + + /* The system-wide table used for mapping {class,interface} to a sub-vtable */ + static VTableOffset VOffsetTable[interfaceDispatchTableSize]; + + /* Class-specific offset to add to interfaceNumber when accessing VIndexTable */ + Uint16 vShift; + + /* The system-wide table used for performing instanceof and checkcast + operations on interface types */ + static Uint16 assignabilityTable[interfaceAssignabilityTableSize]; + + /* Class-specific offset to add to interfaceNumber when accessing assignabilityTable */ + Uint16 aShift; + + /* Hashtable keyed by the set of interfaces that are implemented by a class */ + static InterfaceSetHashTable *hashTable; + + /* List of interface/VIndex pairs */ + InterfaceList *interfaceList; + + /* Internal helper functions */ + bool tryFitVOffset(Uint32 shift); + bool packIntoVOffsetTable(); + bool tryFitAssignability(Uint32 shift); + bool packIntoAssignabilityTable(); + void mergeInterfaceLists(); + + /* Unique number used for */ + Uint16 assignabilityColor; + + /* Counter used to assign unique values to assignability color, above */ + static Uint16 sColorCounter; + + InterfaceDispatchTable *inheritedInterfaceTable; + +public: + static void staticInit(Pool &pool); + + /* After building up the list of all implemented interfaces using + interfaceDispatchTable::add(), the build method is used to integrate + that list into the global interface/class lookup table in a + space-efficient manner. */ + InterfaceDispatchTable *build(); + + InterfaceDispatchTable(): vShift(0), aShift(0), interfaceList(NULL), + assignabilityColor(0), inheritedInterfaceTable(0) {} + + /* Add an interface to the set of interfaces that is implemented, + with a sub-vtable that begins at a byte offset of baseVOffset in + the enclosing vtable. */ + void add(Uint32 interfaceNumber, Uint32 baseVOffset); + + /* Same as above, but for an interface that has no methods. */ + void add(Uint32 interfaceNumber) {add(interfaceNumber, 0);} + + void inherit(InterfaceDispatchTable *inheritedTable); + + /* Return the table addresses to be stored in the Type object for a class. */ + VTableOffset *getVOffsetTableBaseAddress() {return &VOffsetTable[vShift];}; + Uint16 *getAssignableTableBaseAddress() {return &assignabilityTable[aShift];}; + + /* Return the value which must be found in an interface's assignment + table entry to indicate that an object is assignable + to that interface type. */ + Uint16 getAssignableMatchValue() const {return assignabilityColor;} +}; + +bool build(InterfaceDispatchTable * &interfaceDispatchTable); + + +#endif /* InterfaceDispatchTable_H */ diff --git a/ef/Runtime/System/JavaObject.cpp b/ef/Runtime/System/JavaObject.cpp new file mode 100644 index 000000000000..5aabb724ff90 --- /dev/null +++ b/ef/Runtime/System/JavaObject.cpp @@ -0,0 +1,1897 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#include "ClassWorld.h" +#include +#include "ClassCentral.h" +#include "FieldOrMethod.h" +#include "plstr.h" +#include "prprf.h" + +#include "JavaVM.h" + + +/* Counter used for setting the interfaceNumber member in + Interface's and in those Array's where the element type + is an interface. */ +static Uint32 sInterfaceCount; + +// Size of each TypeKind +const Int8 typeKindSizes[nTypeKinds] = +{ + 0, // tkVoid + 1, // tkBoolean + 1, // tkUByte + 1, // tkByte + 2, // tkChar + 2, // tkShort + 4, // tkInt + 8, // tkLong + 4, // tkFloat + 8, // tkDouble + sizeof(ptr), // tkObject + 4, // tkSpecial + sizeof(ptr), // tkArray + sizeof(ptr) // tkInterface +}; + +// lg2 of the size of each TypeKind +const Int8 lgTypeKindSizes[nTypeKinds] = +{ + -1, // tkVoid + 0, // tkBoolean + 0, // tkUByte + 0, // tkByte + 1, // tkChar + 1, // tkShort + 2, // tkInt + 3, // tkLong + 2, // tkFloat + 3, // tkDouble + 2, // tkObject FIXME - should be 3 on 64-bit machine + 2, // tkSpecial + 2, // tkArray FIXME - should be 3 on 64-bit machine + 2 // tkInterface FIXME - should be 3 on 64-bit machine +}; + +// Number of environment slots taken by each TypeKind +const Int8 typeKindNSlots[nTypeKinds] = +{ + 0, // tkVoid + 1, // tkBoolean + 1, // tkUByte + 1, // tkByte + 1, // tkChar + 1, // tkShort + 1, // tkInt + 2, // tkLong + 1, // tkFloat + 2, // tkDouble + 1, // tkObject + 1, // tkSpecial + 1, // tkArray + 1 // tkInterface +}; + + +// ---------------------------------------------------------------------------- +// Type + + +#ifdef DEBUG_LOG +// +// Print a reference to this Type for debugging purposes. +// Return the number of characters printed. +// +int Type::printRef(LogModuleObject &f) const +{ + const char *typeName; + + switch (typeKind) { + case tkVoid: + typeName = "void"; + break; + case tkBoolean: + typeName = "boolean"; + break; + case tkUByte: + typeName = "unsigned byte"; + break; + case tkByte: + typeName = "byte"; + break; + case tkChar: + typeName = "char"; + break; + case tkShort: + typeName = "short"; + break; + case tkInt: + typeName = "int"; + break; + case tkLong: + typeName = "long"; + break; + case tkFloat: + typeName = "float"; + break; + case tkDouble: + typeName = "double"; + break; + case tkObject: + case tkInterface: + return static_cast(this)->printRef(f); + case tkArray: + return static_cast(this)->printRef(f); + case tkSpecial: + typeName = "special"; + break; + default: + typeName = "????"; + } + return (UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("%s", typeName))); +} +#endif + +// Get the superclass of a Type, as defined by java.lang.Class.getSuperClass() +const Type *Type::getSuperClass() const +{ + if (typeKind == tkArray) + return static_cast(&Standard::get(cObject)); + else if (typeKind == tkInterface) + return NULL; + else + return superType; +} + +// Get the unique serial number that is assigned to interfaces +// and to arrays of interfaces. This serial number is used to perform +// runtime assignability checks. +Uint32 Type::getInterfaceNumber() const +{ + if (typeKind == tkArray) { + return asArray(*this).getInterfaceNumber(); + } else { + assert(typeKind == tkInterface); + return asInterface(*this).getInterfaceNumber(); + } +} + +const char *Type::getName() const +{ + switch (typeKind) { + case tkArray: + return asArray(*this).getName(); + + case tkInterface: + return asInterface(*this).getName(); + + case tkObject: + return asClass(*this).getName(); + + default: + return asPrimitiveType(*this).getName(); + } +} + + +// Returns the modifiers (access flags) for this class object. +Uint32 Type::getModifiers() const +{ + switch (typeKind) { + case tkObject: + case tkInterface: + return ((ClassOrInterface*)this)->getModifiers(); + + case tkArray: + // Modifier flags for an array are the same as the modifiers for its element type. + // XXX - Check this assumption for compatibility with Sun JDK + return asArray(*this).getElementType().getModifiers(); + + default: + // Primitive type modifier flags + // XXX - Check this assumption for compatibility with Sun JDK + return CR_ACC_PUBLIC | CR_ACC_FINAL | CR_ACC_ABSTRACT; + } +} + +// +// Return true if sub is a subtype of super. In other words, return true if +// an instance or variable of type sub can be assigned to a variable of type super. +// +bool implements(const Type &sub, const Type &super) +{ + // Every type is a subtype of itself. + if (&super == &sub) + return true; + + TypeKind superKind = super.typeKind; + TypeKind subKind = sub.typeKind; + + switch (subKind) { + case tkObject: + switch (superKind) { + // A class's supertypes can only be its superclasses or superinterfaces -- + // never primitive objects, arrays, or special objects. + case tkObject: + return asClass(sub).implements(asClass(super)); + case tkInterface: + return asClass(sub).implements(asInterface(super)); + default:; + } + break; + + case tkArray: + switch (superKind) { + // An array's supertypes can only be: + // the class Object, + // the interface Cloneable, or + // arrays whose element type is a supertype of this array's element type. + case tkObject: + return &super == &Standard::get(cObject); + case tkArray: + return implements(static_cast(&sub)->componentType, + static_cast(&super)->componentType); + case tkInterface: + return &super == &Standard::get(iCloneable); + default:; + } + break; + + case tkInterface: + switch (superKind) { + // An interface's supertypes can only be: + // the class Object, or + // the interface's superinterfaces. + case tkObject: + return &super == &Standard::get(cObject); + case tkInterface: + return asInterface(sub).implements(asInterface(super)); + default:; + } + break; + + default:; + } + + // There are no other nontrivial subtyping relationships. + return false; +} + + +// ---------------------------------------------------------------------------- +// PrimitiveType + +const PrimitiveType *PrimitiveType::primitiveTypes[nPrimitiveTypeKinds]; + +static const char primitiveTypeNames[nPrimitiveTypeKinds][8] = +{ + "void", // tkVoid + "boolean", // tkBoolean + "", // tkUByte (Not a real Java type) + "byte", // tkByte + "char", // tkChar + "short", // tkShort + "int", // tkInt + "long", // tkLong + "float", // tkFloat + "double" // tkDouble +}; + +// JVM-specified encodings for primitive types in signatures +static const char primitiveTypeEncodings[nPrimitiveTypeKinds] = +{ + 'V', // tkVoid + 'Z', // tkBoolean + '\0', // tkUByte (Not a real Java type) + 'B', // tkByte + 'C', // tkChar + 'S', // tkShort + 'I', // tkInt + 'J', // tkLong + 'F', // tkFloat + 'D' // tkDouble +}; + +// +// Initialize the table used by the obtain method. +// cPrimitiveType must have already been initialized. +// +void PrimitiveType::staticInit() +{ + for (TypeKind tk = tkVoid; tk < nPrimitiveTypeKinds; tk = (TypeKind)(tk+1)) + primitiveTypes[tk] = new PrimitiveType(Standard::get(cClass), tk); +} + +const PrimitiveType *PrimitiveType::getClass(const char *className) +{ + int i; + for (i = 0; i < nPrimitiveTypeKinds; i++) { + if (!PL_strcmp(primitiveTypeNames[i], className)) + return &obtain((TypeKind)i); + } + return NULL; +} + +const char *PrimitiveType::getName() const { + assert(isPrimitive()); + return primitiveTypeNames[(int)typeKind]; +} + +char PrimitiveType::getSignatureEncoding() const { + assert(isPrimitive()); + return primitiveTypeEncodings[(int)typeKind]; +} + +// ---------------------------------------------------------------------------- +// Array + + +const Array *Array::primitiveArrays[nPrimitiveTypeKinds]; + + +// +// Initialize a type for arrays. +// Do not call this constructor directly; use obtain or Type::getArrayType +// or Array::make instead. +// +Array::Array(const Type &componentType, const Type &superType, Uint32 nVTableSlots): + Type(Standard::get(cClass), + &superType, tkArray, componentType.final, nVTableSlots, 0), + componentType(componentType) +{ + assert(componentType.typeKind != tkVoid); + interfaceNumber = 0; + fullName = NULL; + + /* Assign each array of interfaces a unique serial number */ + if (getElementType().typeKind == tkInterface) + interfaceNumber = ++sInterfaceCount; +} + +// An array's name is just the name of it's element type followed by an appropriate number +// of pairs of braces. +const char *Array::getName() const { + if (fullName) + return fullName; + + int numDimensions, i; + const Type &element = getElementType(numDimensions); + char *name, *n; + + if (element.isPrimitive()) { + name = new char[numDimensions + 2]; + n = name; + for (i = 0; i < numDimensions; i++) + *n++ = '['; + *n++ = asPrimitiveType(element).getSignatureEncoding(); + } else { + const char *elementName = element.getName(); + // Leave room for an 'L' prefix and ';' suffix if we've got an object element type + name = new char[PL_strlen(elementName) + numDimensions + 3]; + n = name; + + for (i = 0; i < numDimensions; i++) + *n++ = '['; + + *n++ = 'L'; + while ((*n = *elementName) != 0) { + n++; + elementName++; + } + *n++ = ';'; + } + *n = 0; + + fullName = name; + return name; +} + +// +// Initialize a new Interface object that describes essential information such as +// inheritance relationships of objects belonging to a single Java interface. +// +// package is the package that defined this interface, name is the unqualified +// name of this interface, and interfaces is an array of nInterfaces elements +// that lists all interfaces from which this interface derives. +// +Interface::Interface(Package &package, const char *name, + Uint32 nInterfaces, Interface **interfaces, + ClassFileSummary *summary): + ClassOrInterface(Standard::get(cClass), tkInterface, NULL, false, 0, package, name, + nInterfaces, interfaces, + summary), interfaceNumber(++sInterfaceCount) +{superType = &Standard::get(cObject);} + +/* For every superinterface of this interface, obtain the Array object + that is the type of an array of such interfaces with dimensionality + given by numDimensions. Add that Array to the list of assignable types. + This is a helper function for buildAssignabilityTableForInterfaces(). */ +void Interface::addInterfaceArraysToAssignableTable(InterfaceDispatchTable *interfaceDispatchTable, + int numDimensions) +{ + int i; + Type *arrayType; + + /* Obtain the array-of-interfaces type and add it to the list + of assignable types */ + arrayType = this; + assert(numDimensions >= 1); + for (i = 0; i < numDimensions; i++) { + arrayType = const_cast(static_cast(&arrayType->getArrayType())); + } + interfaceDispatchTable->add(asArray(*arrayType).getInterfaceNumber()); +} + +// Setup the lookup tables so that we can perform instanceof and +// checkcast operations on arrays where the test type is +// either an array of interfaces or the Cloneable interface. +void Array::buildAssignabilityTableForInterfaces() +{ + interfaceDispatchTable = new InterfaceDispatchTable(); + + /* If this is an array of objects and those objects implement + one or more interfaces, obtain the type corresponding to + an array of those interfaces and add it to the list of + assignable types */ + + /* Only class and array instances can implement interfaces, and + only class instances can implement interfaces other than Cloneable. */ + int numDimensions; + const Type *elementType = &getElementType(numDimensions); + if (elementType->typeKind == tkObject) { + const Class &elementClass = asClass(*elementType); + + /* In addition to their direct superinterfaces, the elements of this + array implement all the interfaces implemented by their superclass. */ + if (elementType != &Standard::get(cObject)) { + const Array &superType = asArray(*getSuperType()); + interfaceDispatchTable->inherit(superType.interfaceDispatchTable); + } + + /* For every interface implemented by this Class, obtain the Array object + that is the type of an array of such interfaces. Add that Array to the + list of assignable types for an array of this Class. */ + for (Uint32 i = 0; i < elementClass.nInterfaces; i++) { + Interface *superInterface = elementClass.interfaces[i]; + superInterface->addInterfaceArraysToAssignableTable(interfaceDispatchTable, numDimensions); + } + } + + /* All arrays implement the Cloneable interface. */ + interfaceDispatchTable->add(Standard::get(iCloneable).getInterfaceNumber()); + + /* Check for interface table overflow */ + if (!build(interfaceDispatchTable)) + verifyError(VerifyError::resourceExhausted); + + /* Initialize the fields within the Type that are used by compiled code + for assignability checks */ + interfaceVIndexTable = 0; /* Arrays never implement interface methods */ + interfaceAssignableTable = interfaceDispatchTable->getAssignableTableBaseAddress(); + assignableMatchValue = interfaceDispatchTable->getAssignableMatchValue(); +} + +// +// Initialize a new Array object that describes essential information such as +// the type hierarchy. +// +// componentType is the type of elements in the array. It can itself be an array type. +// +Array &Array::make(const Type &componentType) +{ + const Type *superType; + + /* Obtain the supertype of the array */ + const Type *javaLangObject = static_cast(&Standard::get(cObject)); + if (isPrimitiveKind(componentType.typeKind) || (&componentType == javaLangObject)) { + /* The supertype of a primitive array or an array of Object is Object. */ + superType = javaLangObject; + } else { + /* The supertype of an array of non-primitive elements, where the + elements do not have type Object, is an array of the same + dimensionality of the element's supertype. */ + superType = static_cast(&componentType.getSuperType()->getArrayType()); + } + + /* Reserve one vtable slot for our class pointer, to implement instanceof + operations when the target type is neither an interface nor an array of + interfaces. */ + Uint32 nVTableSlots = 1; + const Type *super = superType; + while (super) { + nVTableSlots += super->nVTableSlots; + super = super->getSuperType(); + } + + /* The sizeof(Class) in the expression below is not a typo. VTables for + both Array and Class objects start at the same offset. */ + Int32 objSize = sizeof(Class) + nVTableSlots*sizeof(VTableEntry); + void *mem = malloc(objSize); + memset(mem, 0, objSize); // Set vtable entries to zero + Array *array = new(mem) Array(componentType, *superType, nVTableSlots); + + /* Construct the array's vtable. Start by copying our parent's vtable */ + Uint32 i; + for (i = 0; i < superType->nVTableSlots; i++) + array->setVTableEntry(i, (superType->getVTableEntry(i)).classOrCodePtr); + + /* The last vtable entry is a self-referential pointer, used for instanceof */ + array->setVTableEntry(i, array); + + /* Set up the tables that allow us to perform instanceof and checkcast + operations on this array when the target type is an array of interfaces */ + array->buildAssignabilityTableForInterfaces(); + + return *array; +} + +// Return the Type of an array's element (not the Type of +// its component). Also, return the dimensionality of the +// array in numDimensions. +const Type &Array::getElementType(int &numDimensions) const +{ + const Type *compType; + compType = &componentType; + numDimensions = 1; + while (compType && (compType->typeKind == tkArray)) { + compType = &(asArray(*compType).componentType); + numDimensions++; + } + return *compType; +} + +const Type &Array::getElementType() const +{ + int dummy; + return getElementType(dummy); +} + +#ifdef DEBUG_LOG +// +// Print a reference to this array for debugging purposes. +// Return the number of characters printed. +// +int Array::printRef(LogModuleObject &f) const +{ + int o = componentType.printRef(f); + return o + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("[]")); +} +#endif + + +// +// Initialize the table used by the obtain method. +// PrimitiveType::obtain must have already been initialized. +// +void Array::staticInit() +{ + primitiveArrays[tkVoid] = 0; // Can't have an array of type Void. + for (TypeKind tk = tkBoolean; tk < nPrimitiveTypeKinds; tk = (TypeKind)(tk+1)) + primitiveArrays[tk] = &PrimitiveType::obtain(tk).getArrayType(); +} + +#ifdef DEBUG +void Array::printValue(LogModuleObject &f, JavaArray *array, int maxRecursion, + Uint32 printFlags, const char *newlineString, + Vector *printedObjects) const +{ + assert(array->getType().typeKind == tkArray); + char *indentedNewlineString = NULL; + if (newlineString) { + indentedNewlineString = new char[strlen(newlineString) + 3]; + strcpy(indentedNewlineString, newlineString); + strcat(indentedNewlineString, " "); + } + + Uint8 *componentPtr = (Uint8*)array + arrayEltsOffset(componentType.typeKind); + + int componentSize = getTypeKindSize(componentType.typeKind); + + // Arbitrarily limit printed array size + int numElementsToPrint = array->length; + if (numElementsToPrint > 10) + numElementsToPrint = 10; + + bool printArrayIndices = printFlags & PRINT_ARRAY_INDICES; + + if (newlineString) + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("%s", newlineString)); + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("{")); + int elementNum; + for (elementNum = 0; elementNum < numElementsToPrint; elementNum++) { + if (newlineString) + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("%s ", newlineString)); + if (printArrayIndices) + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("[%2d] = ", elementNum)); + ::printValue(f, componentPtr, componentType, maxRecursion - 1, printFlags, + indentedNewlineString, printedObjects); + if (!newlineString && (elementNum != (numElementsToPrint - 1))) + UT_OBJECTLOG(f, PR_LOG_ALWAYS, (",")); + componentPtr += componentSize; + } + + if (numElementsToPrint < (Int32)array->length) + UT_OBJECTLOG(f, PR_LOG_ALWAYS, (" ...")); + if (newlineString) + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("%s", newlineString)); + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("}")); + + if (indentedNewlineString) + delete [] indentedNewlineString; +} +#endif + +//----------------------------------------------------- +// JavaArray +//------------------------------------------------------ +// Returns true if the array is an array of primitive elements +bool JavaArray::isPrimitive() +{ + return isPrimitiveKind(((Array *) type)->componentType.typeKind); +} + +void *JavaArray::getRaw(Int32 index) +{ + TypeKind tk = ((Array *) type)->componentType.typeKind; + Int32 size = getTypeKindSize(tk); + + return ((char *) this) + arrayEltsOffset(tk) + (index)*size; +} + +JavaObject *JavaArray::get(Int32 index) +{ + void *address = getRaw(index); + + if (isPrimitive()) + return &Class::makePrimitiveObject(static_cast(&getType())->componentType.typeKind, address); + else /* Array or object type */ + return (JavaObject *) address; +} + +#define ARRAY_GET_PRIMITIVE(typeTo, tkTo)\ + if (!isPrimitive()) \ + runtimeError(RuntimeError::illegalArgument);\ +\ + typeTo value;\ + void *address = getRaw(index);\ +\ + if (((Array *) type)->componentType.typeKind == tkTo)\ + return *(typeTo *) address;\ + else {\ + Field::widen(address, &value, ((Array *) type)->componentType.typeKind, tkTo);\ + return (typeTo) value;\ + } + +Int8 JavaArray::getBoolean(Int32 index) +{ + ARRAY_GET_PRIMITIVE(Int8, tkBoolean); +} + +char JavaArray::getByte(Int32 index) +{ + ARRAY_GET_PRIMITIVE(Int8, tkByte); +} + +Int16 JavaArray::getChar(Int32 index) +{ + ARRAY_GET_PRIMITIVE(Int16, tkChar); +} + +Int16 JavaArray::getShort(Int32 index) +{ + ARRAY_GET_PRIMITIVE(Int16, tkShort); +} + +Int32 JavaArray::getInt(Int32 index) +{ + ARRAY_GET_PRIMITIVE(Int32, tkInt); +} + +Int64 JavaArray::getLong(Int32 index) +{ + ARRAY_GET_PRIMITIVE(Int64, tkLong); +} + +Flt32 JavaArray::getFloat(Int32 index) +{ + ARRAY_GET_PRIMITIVE(Flt32, tkFloat); +} + +Flt64 JavaArray::getDouble(Int32 index) +{ + ARRAY_GET_PRIMITIVE(Flt64, tkDouble); +} + + +#define ARRAY_SET_PRIMITIVE(typeFrom, tkFrom) \ + if (!isPrimitive())\ + runtimeError(RuntimeError::illegalArgument);\ +\ + void *address = getRaw(index);\ +\ + if (((Array *) type)->componentType.typeKind == tkFrom)\ + *(typeFrom *) address = value;\ + else \ + Field::widen(&value, address, tkFrom, ((Array *) type)->componentType.typeKind) + +void JavaArray::set(Int32 index, JavaObject *value) +{ + void *address = getRaw(index); + + Int32 elementSize = getTypeKindSize(((Array *)type)->componentType.typeKind); + + /* If this is a primitive type, then it is encased in a Java Object; + * otherwise, it is the object itself + */ + if (isPrimitive()) { + TypeKind tk; + + if (!Standard::isPrimitiveWrapperClass(*static_cast(&value->getType()), &tk)) + runtimeError(RuntimeError::illegalArgument); + + memset(address, 0, elementSize); + + Int32 argumentSize = getTypeKindSize(tk); + memcpy(address, (char *)value+sizeof(JavaObject), argumentSize); + } else { + assert(elementSize == sizeof(JavaObject *)); + + // Ensure that the object is assignable + if (value && !((Array *)type)->componentType.isAssignableFrom(value->getType())) + runtimeError(RuntimeError::illegalArgument); + + *((JavaObject **) address) = value; + } + +} + +void JavaArray::setBoolean(Int32 index, Int8 value) +{ + ARRAY_SET_PRIMITIVE(Int8, tkBoolean); +} + + +void JavaArray::setByte(Int32 index, char value) +{ + ARRAY_SET_PRIMITIVE(Int8, tkByte); +} + +void JavaArray::setChar(Int32 index, Int16 value) +{ + ARRAY_SET_PRIMITIVE(Int16, tkChar); +} + +void JavaArray::setShort(Int32 index, Int16 value) +{ + ARRAY_SET_PRIMITIVE(Int16, tkShort); +} + +void JavaArray::setInt(Int32 index, Int32 value) +{ + ARRAY_SET_PRIMITIVE(Int32, tkInt); +} + +void JavaArray::setLong(Int32 index, Int64 value) +{ + ARRAY_SET_PRIMITIVE(Int64, tkLong); +} + +void JavaArray::setFloat(Int32 index, Flt32 value) +{ + ARRAY_SET_PRIMITIVE(Flt32, tkFloat); +} + +void JavaArray::setDouble(Int32 index, Flt64 value) +{ + ARRAY_SET_PRIMITIVE(Flt64, tkDouble); +} + + +// ---------------------------------------------------------------------------- +// ClassOrInterface +ClassCentral *ClassOrInterface::central; + +static inline bool isInterface(ClassFileSummary &summ) { + return ((summ.getAccessFlags() & CR_ACC_INTERFACE) != 0); +} + + +#ifdef DEBUG_LOG +// +// Print a reference to this class or interface for debugging purposes. +// Return the number of characters printed. +// +int ClassOrInterface::printRef(LogModuleObject &f) const +{ + int o = package.printRef(f); + if (o) + o += UT_OBJECTLOG(f, PR_LOG_ALWAYS, (".")); + return o + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("%s", name)); +} +#endif + + +// +// Generate the fully qualified name and the declaration name of the class. +// +void ClassOrInterface::getFullNames() const +{ + if (!summary) + runtimeError(RuntimeError::illegalAccess); + + // The 2 at the end comes from one extra dot, and the NULL character + Int32 fullNameLen = strlen(package.name) + strlen(name) + 2; + char *fullNameTemp = new char[fullNameLen+1]; + + if (*package.name) + PR_snprintf(fullNameTemp, fullNameLen, "%s.%s", package.name, name); + else + PR_snprintf(fullNameTemp, fullNameLen, "%s", name); + + const char *clOrIString; + if ((summary->getAccessFlags() & CR_ACC_INTERFACE)) + clOrIString = "interface "; + else + clOrIString = "class "; + + char *declNameTemp = new char[fullNameLen+strlen(clOrIString)+1]; + + sprintf(declNameTemp, "%s%s", clOrIString, fullNameTemp); + + StringPool &sp = central->getStringPool(); + fullName = sp.intern(fullNameTemp); + declName = sp.intern(declNameTemp); + + delete [] fullNameTemp; + delete [] declNameTemp; +} + +// Returns fully qualified name of the class/interface in the form +// "class " or "interface " +const char *ClassOrInterface::toString() const +{ + // XXX - really should be method on Type, not ClassOrInterface ? + if (declName) + return declName; + + getFullNames(); + return declName; +} + +// Given a fully qualified className, attempts to load and link the class +// and returns the corresponding Class object. The name could be of +// the form java/lang/Object or java.lang.Object. Makes a copy of the +// _className for further use. Throws a verify error if it could not +// load the class. +Class &Class::forName(const char *_className) +{ + // Make a copy of the string since we will be mutilating it + char *className = PL_strdup(_className); + + // Replace all dots with slashes + for (char *s = className; *s; s++) + if (*s == '.') *s = '/'; + + ClassFileSummary &summ = central->addClass(className); + return *static_cast(summ.getThisClass()); +} + +Uint32 Class::getPrimitiveValue(JavaObject &arg) +{ + assert(Standard::isPrimitiveWrapperClass(*static_cast(arg.type))); + + // This makes assumptions about the layout of the + // primitive classes -- it assumes that the first + // instance field is the value of the primitive + // type. But this is also the most efficient way + // to extract the value. + return *(Uint32 *) ((char *) &arg+sizeof(JavaObject)); +} + +// Creates an instance of the class if the class is instantiable. +// This method does *not* check that the a java class has access +// permissions to instantiate this class. That must be done by +// the caller of this method. +JavaObject &Class::newInstance() +{ + if (!summary || ::isInterface(*summary)) + runtimeError(RuntimeError::illegalAccess); + + // Cannot instantiate an abstract class + if (getModifiers() & CR_ACC_ABSTRACT) + runtimeError(RuntimeError::notInstantiable); + + // Run static initializers for this class if neccessary + if (!isInitialized()) + runStaticInitializers(); + + int32 memSize = sizeof(JavaObject)+summary->getObjSize(); + + void *mem = malloc(memSize); + memset(mem, 0, memSize); + + return *new (mem) JavaObject(*summary->getThisClass()); +} + +// Clones the object given by inObj. The implementation of clone here +// is shallow -- if any instance fields in the object are classes, +// the object references are cloned, but not the objects themselves. +// returns a pointer to the cloned object on success, NULL otherwise +JavaObject *Class::clone(JavaObject &inObj) const +{ + if (!summary || ::isInterface(*summary)) + runtimeError(RuntimeError::illegalAccess); + + /* The types must match in order to be able to clone */ + if (&inObj.getType() != (Type *) this) + return 0; + + int32 memSize = sizeof(JavaObject)+summary->getObjSize(); + + void *mem = malloc(memSize); + memcpy(mem, &inObj, memSize); + + return (JavaObject *) mem; +} + +// +// Make a JavaObject corresponding to a primitive type, whose +// raw bytes are located at *address +// +JavaObject &Class::makePrimitiveObject(TypeKind tk, void *address) +{ + assert(isPrimitiveKind(tk)); + + StandardClass sc; + switch (tk) { + case tkBoolean: + sc = cBoolean; + break; + case tkByte: + sc = cByte; + break; + case tkChar: + sc = cCharacter; + break; + case tkDouble: + sc = cDouble; + break; + case tkFloat: + sc = cFloat; + break; + case tkInt: + sc = cInteger; + break; + case tkLong: + sc = cLong; + break; + case tkShort: + sc = cShort; + break; + default: + runtimeError(RuntimeError::internal); + } + + JavaObject &inst = const_cast(&Standard::get(sc))->newInstance(); + int size = getTypeKindSize(tk); + + // FIX Assumes the offset of the "value" field in the class + memcpy((char *) &inst + sizeof(JavaObject), address, size); + return inst; +} + +// Returns true if the type represented by the specified Class parameter +// can be converted to the type represented by this class object. +bool Type::isAssignableFrom(const Type &from) const +{ + return implements(from, *this); +} + +// Returns the fully qualified name of the class; unlike toString(), +// does not prepend "class " in front of the name +const char *ClassOrInterface::getName() const +{ + if (fullName) + return fullName; + + getFullNames(); + return fullName; +} + + +// Returns the modifiers (access flags) for this class object. +Uint32 ClassOrInterface::getModifiers() const +{ + if (!summary) + runtimeError(RuntimeError::illegalAccess); + + return summary->getAccessFlags(); +} + + +// Returns the class loader object for this class. +// ClassLoader getClassLoader(); + + +// Returns summaries for the interfaces of this class. +// If this class object represents a class, returns an array containing +// objects representing the interfaces directly implemented by the class. +// If this Class object represents an interface, returns an array +// containing objects representing the direct superinterfaces of the +// interface. Returns number of array interfaces actually returned. +// This number could be zero, if the class is a primitive type or +// implements no interfaces. +Int32 ClassOrInterface::getInterfaces(Interface **&summaries) const +{ + // FIX Is this correct? All arrays implement cloneable + if (isArray()) + return 0; + + if (!summary) + runtimeError(RuntimeError::illegalAccess); + + summaries = const_cast(summary->getInterfaces()); + return summary->getInterfaceCount(); +} + +// If this class or interface is a member of another class, returns the +// class object representing the class of which it is a member. If this is +// not the case, returns NULL. Hmmm. Need to think about how to implement +// this. +// Class *getDeclaringClass(); + +// Returns an array containing class objects representing all the public +// classes and interfaces that are members of the class represented by this +// class object. Returns number of class objects returned. +Int32 ClassOrInterface::getClasses(Class **&summaries) +{ + if (!summary) + runtimeError(RuntimeError::illegalAccess); + + // Not currently implemented + trespass("Not implemented"); + summaries = 0; + return 0; +} + +// Returns an array containing information about the public fields of this +// object. Returns number of fields in object. +Int32 ClassOrInterface::getFields(const Field **&fields) +{ + if (!summary) + runtimeError(RuntimeError::illegalAccess); + + fields = (const Field **) summary->getPublicFields(); + return summary->getPublicFieldCount(); +} + +// Returns an array containing information about the public methods of +// this object. Returns number of fields in object. +Int32 ClassOrInterface::getMethods(const Method **&methods) +{ + if (!summary) + runtimeError(RuntimeError::illegalAccess); + + methods = (const Method **) summary->getPublicMethods(); + return summary->getPublicMethodCount(); +} + +// Returns an array containing information about the public constructors of +// this object. Returns number of constructors. +Int32 ClassOrInterface::getConstructors(const Constructor **&constructors) +{ + if (!summary) + runtimeError(RuntimeError::illegalAccess); + + constructors = (const Constructor **) summary->getPublicConstructors(); + return summary->getPublicConstructorCount(); +} + + +// Look up fields/methods/constructors. These methods search through +// publicly accessible fields/methods/constructors. + +// Return the Field object for a static/instance public field with the given +// name. +Field &ClassOrInterface::getField(const char *name) +{ + if (!summary) + runtimeError(RuntimeError::illegalAccess); + + Field *field = summary->getField(name); + + if (!field) + runtimeError(RuntimeError::illegalArgument); + + return *field; +} + +// Return the Method object for a static/instance public method with the +// given name. parameterTypes is an array of Type objects +// that represent the parameters of the desired method. +Method &ClassOrInterface::getMethod(const char *name, + const Type *parameterTypes[], + Int32 numParams) +{ + if (!summary) + runtimeError(RuntimeError::illegalAccess); + + Method *method = summary->getMethod(name, parameterTypes, numParams); + + if (!method) + runtimeError(RuntimeError::illegalAccess); + + return *method; +} + +// Look up a method based on its name and signature. This routine searches +// only in the current class, and does not search in superclasses. +// If publicOrProtected is true, only public and protected methods are searched; +// otherwise, all declared methods are examined. +Method *ClassOrInterface::getMethod(const char *name, const char *sig, + bool publicOrProtected) +{ + if (!summary) + runtimeError(RuntimeError::illegalAccess); + + Method *method = summary->getMethod(name, sig); + + if (!method) + return 0; + + if (publicOrProtected) + if (!(method->getModifiers() & CR_METHOD_PUBLIC) && + !(method->getModifiers() & CR_METHOD_PROTECTED)) + runtimeError(RuntimeError::illegalAccess); + + return method; +} + +// Return a public constructor that takes the given parameters. +// parameterTypes is an array of Type objects +// that represent the parameters of the desired constructor. +Constructor &ClassOrInterface::getConstructor(const Type *parameterTypes[], + Int32 numParams) +{ + if (!summary) + runtimeError(RuntimeError::illegalAccess); + + Constructor *constructor = summary->getConstructor(parameterTypes, numParams); + + if (!constructor) + runtimeError(RuntimeError::illegalAccess); + + return *constructor; + +} + + +// The following functions deal with *all* declared fields, methods, or +// constructors, be they public, protected, or private. +Int32 ClassOrInterface::getDeclaredClasses(Class **&summaries); + +// Return all fields declared by this class, public, protected or private. +Int32 ClassOrInterface::getDeclaredFields(const Field **&fields) +{ + if (!summary) + runtimeError(RuntimeError::illegalAccess); + + fields = (const Field **) summary->getFields(); + return summary->getFieldCount(); +} + +// Get all methods declared by this class, public, protected or private. +Int32 ClassOrInterface::getDeclaredMethods(const Method **&methods) +{ + if (!summary) + runtimeError(RuntimeError::illegalAccess); + + methods = (const Method **) summary->getDeclaredMethods(); + return summary->getDeclaredMethodCount(); +} + +// Get all constructors declared by this class. +Int32 ClassOrInterface::getDeclaredConstructors(const Constructor **&constructors) +{ + if (!summary) + runtimeError(RuntimeError::illegalAccess); + + constructors = (const Constructor **) summary->getConstructors(); + return summary->getConstructorCount(); +} + + +// Get the Field object corresponding to a declared field with the given name. +Field &ClassOrInterface::getDeclaredField(const char *name) +{ + if (!summary) + runtimeError(RuntimeError::illegalAccess); + + Field *field = summary->getDeclaredField(name); + + if (!field) + runtimeError(RuntimeError::illegalAccess); + + return *field; +} + +// Get the Method object corresponding to a declared method with the +// given name and signature. parameterTypes is an array of Type objects +// that represent the parameters of the desired method. +Method &ClassOrInterface::getDeclaredMethod(const char *name, + const Type *parameterTypes[], + Int32 numParams) +{ + if (!summary) + runtimeError(RuntimeError::illegalAccess); + + Method *method = summary->getDeclaredMethod(name, parameterTypes, numParams); + + if (!method) + runtimeError(RuntimeError::illegalAccess); + + return *method; +} + +// Get the Constructor object for a constructor that has the signature given +// by parameterTypes. parameterTypes is an array of Type objects +// that represent the parameters of the desired method. +Constructor &ClassOrInterface::getDeclaredConstructor(const Type *parameterTypes[], + Int32 numParams) +{ + if (!summary) + runtimeError(RuntimeError::illegalAccess); + + Constructor *constructor = summary->getDeclaredConstructor(parameterTypes, numParams); + + if (!constructor) + runtimeError(RuntimeError::illegalAccess); + + return *constructor; +} + + +// ---------------------------------------------------------------------------- +// Class + + +// +// Initialize the fields of a Class object. This constructor may only be called +// from within Class::make because the Class object must be specially allocated to +// allow room for its vtable. +// +inline Class::Class(Package &package, const char *name, const Class *parent, + Uint32 nInterfaces, Interface **interfaces, ClassFileSummary *summary, + bool final, Uint32 instanceSize, Uint32 nVTableSlots, + VTableOffset *interfaceVOffsetTable, Uint16 *interfaceAssignableTable): + ClassOrInterface(Standard::get(cClass), tkObject, parent, final, nVTableSlots, package, name, + nInterfaces, interfaces, summary, interfaceVOffsetTable, + interfaceAssignableTable), + instanceSize(instanceSize) { } + + +#ifdef _WIN32 + #pragma warning(disable: 4355) +#endif +// +// Initialize the fields of a special Class object. This constructor may only be called +// from within Class::makeSpecial because the Class object must be specially allocated to +// allow room for its vtable. +// +// Each special class object is located in the pkgInternal package, has no parent or interfaces, +// and is final. The first class object created should be the cClass special class, and for +// that class only isOwnClass should be true. Every other class object created relies on +// cClass already being set up. +// +// The Standard class should fix up the parents of the special classes it creates after it +// loads the Object class. +// +inline Class::Class(bool isOwnClass, const char *name, Uint32 instanceSize, Uint32 nVTableSlots): + ClassOrInterface(isOwnClass ? *this : Standard::get(cClass), + tkObject, NULL, true, nVTableSlots, pkgInternal, name, 0, 0, 0), + instanceSize(instanceSize) +{} +#ifdef _WIN32 + #pragma warning(default: 4355) +#endif + + +// +// Initialize a new Class object that describes essential information such as layout +// and inheritance relationships of objects of a single Java class. +// +// package is the package that defined this class. +// name is the unqualified name of this class. +// parent is the parent class or nil if this is the Class for the Object class. +// interfaces is an array of nInterfaces elements that lists all interfaces from which +// this class derives except that the interfaces array does not include interfaces +// from which the parent class derives. +// extraSize is the number of additional bytes taken by fields of this class and should +// be a multiple of 4. +// nExtraVTableSlots is the number of additional virtual methods that this class declares; +// it includes the one vtable slot used for class membership testing. +// +Class &Class::make(Package &package, const char *name, const Class *parent, Uint32 nInterfaces, Interface **interfaces, + ClassFileSummary *summary, + bool final, Uint32 extraSize, Uint32 nVTableSlots, + VTableOffset *interfaceVOffsetTable, + Uint16 *interfaceAssignableTable) +{ + if (parent) { + assert(!parent->final); + //extraSize += parent->instanceSize; + } + Int32 objSize = sizeof(Class) + nVTableSlots*sizeof(VTableEntry); + void *mem = malloc(objSize); + memset(mem, 0, objSize); // Set vtable entries to zero + return *new(mem) Class(package, name, parent, nInterfaces, + interfaces, + summary, + final, extraSize, nVTableSlots, + interfaceVOffsetTable, interfaceAssignableTable); + +} + + +// +// Initialize a new special Class object. This routine is only be called +// from within Standard to bootstrap a few special classes. +// +// Each special class object is located in the pkgInternal package, has no parent or interfaces, +// and is final. The first class object created should be the cClass special class, and for +// that class only isOwnClass should be true. Every other class object created relies on +// cClass already being set up. +// +// The Standard class should fix up the parents of the special classes it creates after it +// loads the Object class. +// +// name is the unqualified name of this class. +// instanceSize is the TOTAL number of bytes taken by instances of this class and +// should be a multiple of 4. +// nVTableSlots is the TOTAL number of virtual methods that this class declares, including +// superclasses and vtable slots used for class membership testing. +// +Class &Class::makeSpecial(bool isOwnClass, const char *name, Uint32 instanceSize, Uint32 nVTableSlots) +{ + void *mem = malloc(sizeof(Class) + nVTableSlots*sizeof(VTableEntry)); + return *new(mem) Class(isOwnClass, name, instanceSize, nVTableSlots); +} + + +// +// Fix up the parent for a class created with makeSpecial. This routine is only be called +// from within Standard to bootstrap a few special classes. +// +inline void Class::setParent(const Class &p) +{ + assert(!superType && p.nVTableSlots < nVTableSlots && p.instanceSize <= instanceSize); + superType = &p; +} + + +// +// Return true if this class implements class c. +// (ie "is subclass of") +// +bool Class::implements(const Class &c) const +{ + const Class *a = this; + do { + if (a == &c) + return true; + a = a->getParent(); + } while (a); + return false; +} + + +// +// Return true if this class implements interface i. +// +bool Class::implements(const Interface &i) const +{ + const Class *a = this; + do { + Uint32 n = a->nInterfaces; + Interface *const*intfs = a->interfaces; + while (n--) { + if ((*intfs)->implements(i)) + return true; + intfs++; + } + a = a->getParent(); + } while (a); + return false; +} + + + +static const char *forbiddenClasses[] = { + //"System", // references System.securityManager which has longs + "CharToByteConverter", // references System.getProperty, has finally + //"Math", // Has float and double + //"Float", + //"Double" +}; + +static const numForbiddenClasses = sizeof(forbiddenClasses)/sizeof(forbiddenClasses[0]); + +/* Return true if we should not execute the static initializer for this class. + * This is a temporary kludge to shut out classes whose static initializers + * reference long's and float's. Eventualy, once codegen catches up, this + * should go away. + */ +static bool forbidden(const char *className) +{ + for (int i = 0; i < numForbiddenClasses; i++) + if (!PL_strcmp(forbiddenClasses[i], className)) + return true; + + return false; +} + +void ClassOrInterface::runStaticInitializers() +{ + if (initialized) + return; + + /* Eventually, we also need to have an initializing, but this will do + * for now + */ + initialized = true; + + /* Don't compile initializers unless we're executing */ + if (VM::theVM.getCompileStage() != csGenInstructions || + VM::theVM.getNoInvoke()) + return; + + /* KLUDGE ALERT Because codegen currently does not do longs, floats and + * doubles, we disable static initializers for those classes that + * use longs, floats and doubles. This should go away once codegen + * catches up. + */ + if (forbidden(name)) + return; + + /* Let's initially do this the easy way. Linearly search through the + * method array for static initializers + */ + Int16 methodCount = summary->getMethodCount(); + const MethodInfo **methodInfos = summary->getMethodInfo(); + + extern StringPool sp; + + const char *clinitp = sp.get(""); + const char *sigp = sp.get("()V"); + + for (Int16 i = 0; i < methodCount; i++) { + if (methodInfos[i]->getName()->getUtfString() == clinitp && + methodInfos[i]->getDescriptor()->getUtfString() == sigp) { + Method &m = summary->getMethod(i); + + m.compile(); + m.invoke(0, 0, 0); + } + } + +} + +#ifdef DEBUG_LOG +void Class::printValue(LogModuleObject &f, JavaObject *obj, int maxRecursion, Uint32 printFlags, + const char *newlineString, + Vector *printedObjects) +{ + const Field **fields; + + char *indentedNewlineString = NULL; + if (newlineString) { + indentedNewlineString = new char[strlen(newlineString) + 3]; + strcpy(indentedNewlineString, newlineString); + strcat(indentedNewlineString, " "); + } + + if (newlineString) + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("%s", newlineString)); + + int numFields = getDeclaredFields(fields); + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("{")); + + int fieldNum; + bool fieldPrinted = false; + for (fieldNum = 0; fieldNum < numFields; fieldNum++) { + Uint8 *fieldPtr; + const Field *field = fields[fieldNum]; + int modifiers = field->getModifiers(); + + if (modifiers & CR_FIELD_STATIC) { + if (!(printFlags & PRINT_STATIC_FIELDS)) + continue; + fieldPtr = (Uint8*)addressFunction(field->getAddress()); + } else { + fieldPtr = (Uint8*)obj + field->getOffset(); + } + + if (newlineString) + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("%s", newlineString)); + else if (fieldPrinted) + UT_OBJECTLOG(f, PR_LOG_ALWAYS, (",")); + UT_OBJECTLOG(f, PR_LOG_ALWAYS, (" %s:", field->getName())); + + + ::printValue(f, fieldPtr, field->getType(), maxRecursion - 1, printFlags, + indentedNewlineString, printedObjects); + fieldPrinted = true; + } + + if (newlineString) + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("%s", newlineString)); + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("}")); + + if (indentedNewlineString) + delete [] indentedNewlineString; +} + +#endif + +// ---------------------------------------------------------------------------- +// Interface + +// +// Return true if this interface implements interface i. +// +bool Interface::implements(const Interface &i) const +{ + Uint32 n = nInterfaces; + Interface *const*intfs = interfaces; + if (this == &i) + return true; + while (n--) { + if ((*intfs)->implements(i)) + return true; + intfs++; + } + return false; +} + + +// ---------------------------------------------------------------------------- + +const Class *Standard::standardClasses[nStandardClasses]; +const Interface *Standard::standardInterfaces[nStandardInterfaces]; +const JavaObject *Standard::standardObjects[nStandardObjects]; + +static const char *const standardClassNames[nStandardClasses + 1 - firstOrdinaryStandardClass] = { + "java/lang/Throwable", // cThrowable + "java/lang/Exception", // cException + "java/lang/RuntimeException", // cRuntimeException + "java/lang/ArithmeticException", // cArithmeticException + "java/lang/ArrayStoreException", // cArrayStoreException + "java/lang/ClassCastException", // cClassCastException + "java/lang/IllegalMonitorStateException", // cIllegalMonitorStateException + "java/lang/ArrayIndexOutOfBoundsException", // cArrayIndexOutOfBoundsException + "java/lang/NegativeArraySizeException", // cNegativeArraySizeException + "java/lang/NullPointerException", // cNullPointerException + "java/lang/Error", // cError + "java/lang/ThreadDeath", // cThreadDeath + "java/lang/Boolean", // cBoolean + "java/lang/Byte", // cByte + "java/lang/Character", // cCharacter + "java/lang/Short", // cShort + "java/lang/Integer", // cInteger + "java/lang/Long", // cLong + "java/lang/Float", // cFloat + "java/lang/Double", // cDouble + "java/lang/String", // cString + "java/lang/InterruptedException" // cInterruptedException +}; + +static const char *const standardInterfaceNames[nStandardInterfaces] = { + "java/lang/Cloneable" // iCloneable +}; + +static const StandardClass standardObjectClasses[nStandardObjects] = { + cArithmeticException, // oArithmeticException + cArrayStoreException, // oArrayStoreException + cClassCastException, // oClassCastException + cIllegalMonitorStateException, // oIllegalMonitorStateException + cArrayIndexOutOfBoundsException,// oArrayIndexOutOfBoundsException + cNegativeArraySizeException, // oNegativeArraySizeException + cNullPointerException // oNullPointerException +}; + +// Total number of vtable entries of any object whose class is Class. +const nClassClassVTableEntries = 20; + + +// +// Initialize the standard classes and objects. +// This routine must be called before any of these are referenced. +// +void Standard::initStandardObjects(ClassCentral &c) +{ + ClassOrInterface::setCentral(&c); + + // Array vtables will get clobbered if this assertion fails. + assert(sizeof(Class) >= sizeof(Array)); + + // Initially, set standardClasses[cClass] to a special class so that we + // can safely load java/lang/Class. + standardClasses[cClass] = &Class::makeSpecial(true, "Class", sizeof(Class), nClassClassVTableEntries); + + // Set standardClasses[cField], standardClasses[cMethod], and + // standardClasses[cConstructor] + standardClasses[cField] = &Class::makeSpecial(false, "Field", + sizeof(Class), + nClassClassVTableEntries); + + standardClasses[cMethod] = &Class::makeSpecial(false, "Method", + sizeof(Class), + nClassClassVTableEntries); + + standardClasses[cConstructor] = &Class::makeSpecial(false, "Constructor", + sizeof(Class), + nClassClassVTableEntries); + + // XXX - Disabled until Waldemar tells us what these meta-classes are for + standardClasses[cPrimitiveType] = &Class::makeSpecial(false, "PrimitiveType", sizeof(PrimitiveType), nClassClassVTableEntries); + standardClasses[cPrimitiveArray] = &Class::makeSpecial(false, "PrimitiveArray", sizeof(Array), nClassClassVTableEntries); + standardClasses[cObjectArray] = &Class::makeSpecial(false, "ObjectArray", sizeof(Array), nClassClassVTableEntries); + standardClasses[cInterface] = &Class::makeSpecial(false, "Interface", sizeof(Interface), nClassClassVTableEntries); + + const Class &objectClass = asClass(*c.addClass("java/lang/Object").getThisClass()); + standardClasses[cObject] = &objectClass; + + uint i; + for (i = cObject + 1; i != firstOrdinaryStandardClass; i++) + const_cast(standardClasses[i])->setParent(objectClass); + + + // Now load java/lang/Class and patch standardClasses[cClass] to be the newly + // loaded class. This way all classes subsequently created will get + // java/lang/Class as the metaclass. + const Class &classClass = asClass(*c.addClass("java/lang/Class").getThisClass()); + standardClasses[cClass] = &classClass; + + // Load classes Field, Method and constructor. + // FIX Need to fix the metaclasses of fields and methods of these classes + // to point to Field, Method, or Constructor. + const Class &classField = asClass(*c.addClass("java/lang/reflect/Field").getThisClass()); + standardClasses[cField] = &classField; + + const Class &classMethod = asClass(*c.addClass("java/lang/reflect/Method").getThisClass()); + standardClasses[cMethod] = &classMethod; + + const Class &classConstructor = asClass(*c.addClass("java/lang/reflect/Constructor").getThisClass()); + standardClasses[cConstructor] = &classConstructor; + + // Fix up the metaclass of classClass and objectClass + const_cast(&objectClass)->type = &asType(classClass); + const_cast(&classClass)->type = &asType(classClass); + + PrimitiveType::staticInit(); + + const char *const* pName = standardClassNames; + for (; i != nStandardClasses; i++) + standardClasses[i] = &asClass(*c.addClass(*pName++).getThisClass()); + + pName = standardInterfaceNames; + for (i = 0; i != nStandardInterfaces; i++) + standardInterfaces[i] = &asInterface(*c.addClass(*pName++).getThisClass()); + + const StandardClass *pSC = standardObjectClasses; + for (i = 0; i != nStandardObjects; i++) + standardObjects[i] = new JavaObject(get(*pSC++)); + + Array::staticInit(); + + +} + +// Returns true if clazz represents one of the primitive classes: +// java/lang/Byte, Boolean, Character, Short, Integer, Long, Float +// and Double. If tkIn is non-null, returns the typeKind of the +// primitive class on success. +bool Standard::isPrimitiveWrapperClass(const Class &clazz, TypeKind *tkIn) +{ + TypeKind tk; + bool isWrapper = true; + + if (&clazz == &Standard::get(cInteger)) + tk = tkInt; + else if (&clazz == &Standard::get(cShort)) + tk = tkShort; + else if (&clazz == &Standard::get(cBoolean)) + tk = tkBoolean; + else if (&clazz == &Standard::get(cByte)) + tk = tkByte; + else if (&clazz == &Standard::get(cCharacter)) + tk = tkChar; + else if (&clazz == &Standard::get(cLong)) + tk = tkLong; + else if (&clazz == &Standard::get(cFloat)) + tk = tkFloat; + else if (&clazz == &Standard::get(cDouble)) + tk = tkDouble; + else + return false; + + if (tkIn) + *tkIn = tk; + + return true; +} + +// Returns true if clazz represents one of the Double-word +// primitive classes -- java/lang/Long or Double. +bool Standard::isDoubleWordPrimitiveWrapperClass(const Class &clazz) +{ + return (&clazz == &Standard::get(cLong) || + &clazz == &Standard::get(cDouble)); +} + + +#ifdef DEBUG + +void printValue(LogModuleObject &f, void *valPtr, const Type &superType, int maxRecursionLevel, + Uint32 printFlags, const char *newlineString, + Vector *printedObjects) + +{ + char *str = NULL; + JavaObject *obj = NULL; + + switch(superType.typeKind) { + + case tkByte: + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("0x%02x", *((Int32*)valPtr))); + break; + + case tkChar: + { + Uint16 charVal = *((Uint32*)valPtr); + if (charVal < 0x7f) + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("'%c'", charVal)); + else + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("0x%04x", charVal)); + } + break; + + case tkShort: + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("0x%04x", *((Int32*)valPtr))); + break; + + case tkInt: + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("%d", *((Int32*)valPtr))); + break; + + case tkInterface: + case tkObject: + case tkArray: + { + obj = *((JavaObject**)valPtr); + if (!obj) { + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("null")); + break; + } + const Type &objType = obj->getType(); + assert(implements(objType, superType)); + if (&objType == &asType(Standard::get(cString))) { + JavaString *javaString = &asJavaString(*obj); + str = javaString->convertUtf(); + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("\"%s\"", str)); + delete str; + break; + } + + if (maxRecursionLevel > 0) { + obj->printValue(f, maxRecursionLevel - 1, printFlags, newlineString, printedObjects); + } else { + if (printFlags & PRINT_OBJECT_TYPE) { + objType.printRef(f); + UT_OBJECTLOG(f, PR_LOG_ALWAYS, (" ")); + } + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("0x%010x", *((Uint32**)valPtr))); + } + } + break; + + case tkDouble: + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("%f", *((Flt64*)valPtr))); + break; + + case tkFloat: + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("%f", (Flt64)(*((Flt32*)valPtr)))); + break; + + case tkLong: + str = PR_smprintf("%lld", *((Uint64*)valPtr)); + if (!str) + return; + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("%s", str)); +#if 0 + PR_smprintf_free(str); // XXX - Should be PR_smprintf_free() when that function is implemented +#endif + break; + + case tkBoolean: + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("%s", *((Uint32*)valPtr) ? "true" : "false")); + break; + + default: + assert(0); + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("don't know yet")); + break; + } +} + +void JavaObject::printValue(LogModuleObject &f, int maxRecursion, Uint32 printFlags, + const char *newlineString, + Vector *printedObjects) +{ + bool deletePrintedObjects = false; + + // Prevent infinite loops due to circular object references + if (printedObjects) { + int i; + int numObjectsPrinted = printedObjects->size(); + for (i = 0; i < numObjectsPrinted; i++) { + if ((*printedObjects)[i] == this) { + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("$%d", i)); + return; + } + } + } else if (maxRecursion > 0) { + // Vector *printedObjects = new Vector; + deletePrintedObjects = true; + } + + // An object reference is either an Array or an Object. (An interface is a type, but + // you can never have an instance of an interface.) + switch(getType().typeKind) { + case tkObject: + { + Class *clazz = const_cast(&asClass(getType())); + clazz->printValue(f, this, maxRecursion, printFlags, newlineString, printedObjects); + } + break; + + case tkArray: + asArray(getType()).printValue(f, (JavaArray*)this, maxRecursion, printFlags, newlineString, printedObjects); + break; + + default: + assert(0); + } + + if (deletePrintedObjects) + delete printedObjects; +} + +UT_DEFINE_LOG_MODULE(JavaObjectDump); + +void dump(JavaObject *obj, int maxRecursion, Uint32 printFlags, const char *newlineString) +{ + Vector printedObjects; + obj->printValue(UT_LOG_MODULE(JavaObjectDump), maxRecursion, printFlags, newlineString, &printedObjects); +} + +#endif + + + + diff --git a/ef/Runtime/System/JavaObject.h b/ef/Runtime/System/JavaObject.h new file mode 100644 index 000000000000..682bb7c754c5 --- /dev/null +++ b/ef/Runtime/System/JavaObject.h @@ -0,0 +1,872 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#ifndef JAVAOBJECT_H +#define JAVAOBJECT_H + +#include "Fundamentals.h" +#include "InterfaceDispatchTable.h" +#include "LogModule.h" + +// A TypeKind describes the basic kind of a Java value. +// See also Value.h. + +enum TypeKind +{ // Size Primitive kind? Final? + tkVoid, // 0 yes yes + tkBoolean, // 1 yes yes + tkUByte, // 1 yes yes + tkByte, // 1 yes yes + tkChar, // 2 yes yes + tkShort, // 2 yes yes + tkInt, // 4 yes yes + tkLong, // 8 yes yes + tkFloat, // 4 yes yes + tkDouble, // 8 yes yes + tkObject, // 4 no sometimes // Java objects + tkSpecial, // 4 no yes // Internal, non-java objects; not used at this time + tkArray, // 4 no sometimes // Java arrays + tkInterface // 4 no no // Java interfaces +}; +const nPrimitiveTypeKinds = tkDouble + 1; +const nTypeKinds = tkInterface + 1; + +inline bool NS_EXTERN isPrimitiveKind(TypeKind tk) {return tk <= tkDouble;} +inline bool NS_EXTERN isNonVoidPrimitiveKind(TypeKind tk) {return tk >= tkBoolean && tk <= tkDouble;} +inline bool NS_EXTERN isDoublewordKind(TypeKind tk) {return tk == tkLong || tk == tkDouble;} +inline int NS_EXTERN getTypeKindSize(TypeKind tk); +inline int NS_EXTERN getLgTypeKindSize(TypeKind tk); +inline int NS_EXTERN nTypeKindSlots(TypeKind tk); +inline bool NS_EXTERN getTypeKindFromDescriptor(char c, TypeKind &tk); + +#ifdef DEBUG + +// Flags for dumping objects and arrays +#define PRINT_ARRAY_INDICES 0x01 +#define PRINT_OBJECT_TYPE 0x02 +#define PRINT_STATIC_FIELDS 0x04 +#define PRINT_DEFAULT_FLAGS PRINT_OBJECT_TYPE + +#endif + +// ---------------------------------------------------------------------------- + +struct Type; +struct Class; +struct Interface; +struct Package; + +struct Field; +struct Method; +struct Constructor; + +class ClassCentral; +class ClassFileSummary; + +// A JavaObject is the header of any Java object. +// It contains just one field -- a pointer to the object's type. +// An actual Java object's fields follow after the end of the JavaEnd structure. +struct NS_EXTERN JavaObject +{ + const Type* type; // Pointer to the object's type + Int32 state; // contains lock and gc state, and possibly hash id + explicit JavaObject(const Type &type): type(&type), state(0x3) {} +public: + inline const Type &getType() const { return *type; } + inline const Class &getClass() const; +#ifdef DEBUG + void printValue(LogModuleObject &f, + int maxRecursion = 0, + Uint32 printFlags = PRINT_DEFAULT_FLAGS, + const char *newlineString = NULL, + Vector *printedObjects = NULL); +#endif + +}; +const Int32 objectTypeOffset = 0; // Offset from object address to its type pointer word + +typedef JavaObject *obj; +typedef const JavaObject *cobj; + +inline ptr objToPtr(obj o) {return reinterpret_cast(o);} +inline cptr objToPtr(cobj o) {return reinterpret_cast(o);} + +inline obj ptrToObj(ptr o) {return reinterpret_cast(o);} +inline cobj ptrToObj(cptr o) {return reinterpret_cast(o);} + + +// ---------------------------------------------------------------------------- + +// A JavaArray is the header of any Java array. +// It contains only two field -- a pointer to the object's type and a +// number of elements. +// An actual Java array's elements follow after the end of the JavaArray structure. +struct NS_EXTERN JavaArray: JavaObject +{ + const Uint32 length; // Number of elements in this array + + JavaArray(const Type &type, Uint32 length): JavaObject(type), length(length) {} + + JavaObject *get(Int32 index); + Int8 getBoolean(Int32 index); + char getByte(Int32 index); + Int16 getChar(Int32 index); + Int16 getShort(Int32 index); + Int32 getInt(Int32 index); + Int64 getLong(Int32 index); + Flt32 getFloat(Int32 index); + Flt64 getDouble(Int32 index); + + void set(Int32 index, JavaObject *obj); + void setBoolean(Int32 index, Int8 value); + void setByte(Int32 index, char value); + void setChar(Int32 index, Int16 value); + void setShort(Int32 index, Int16 value); + void setInt(Int32 index, Int32 value); + void setLong(Int32 index, Int64 value); + void setFloat(Int32 index, Flt32 value); + void setDouble(Int32 index, Flt64 value); +private: + void *getRaw(Int32 index); + bool isPrimitive(); +}; + +// Offset from array address to its length word +const Int32 arrayLengthOffset = offsetof(JavaArray, length); + +// Offset from array address to its first element, equivalent to arrayEltsOffset(tkObject) +const Int32 arrayObjectEltsOffset = sizeof(JavaArray); + + +// ---------------------------------------------------------------------------- + +// A vtable contains two kinds of entries: +// Method pointers that point to code (either actual code or stubs that +// load the actual code); +// Class pointers that point to superclasses. +// +// The method pointers are used for dispatching methods inherited from +// superclasses. The Class pointers are used for quickly determining +// whether an object belongs to a particular class. +union VTableEntry +{ + void *codePtr; // Pointer to method + Class *classPtr; // Pointer to superclass + void *classOrCodePtr; // One of the above +}; + +struct Array; +class InterfaceDispatchTable; + +// A Type describes the contents of a Java object. +// It's also itself a special kind of Java object. +struct NS_EXTERN Type: JavaObject +{ + const TypeKind typeKind ENUM_8; // Kind of objects described here + const bool final BOOL_8; // True if this type cannot have any subtypes. Note that, by this + // definition, an array type is final if its element type is final. + const Uint32 nVTableSlots; // Number of vtable slots for this class; zero if there is no vtable + const VTableOffset *interfaceVIndexTable; // Table for mapping interface to first VIndex in interface's VTable + const Uint16 *interfaceAssignableTable; // Table for determining if instance is assignable to an interface type + Uint16 assignableMatchValue; // Used to compare with entry in interfaceAssignableTable + + private: + mutable const Array *arrayType; // Type of arrays whose components have this Type or null if none declared yet + + protected: // This is an abstract class + Type(const Type &metaType, const Type *superType, TypeKind typeKind, bool final, Uint32 nVTableSlots, + VTableOffset *interfaceVIndexTable = 0, Uint16 *interfaceAssignableTable = 0): + JavaObject(metaType), typeKind(typeKind), final(final), nVTableSlots(nVTableSlots), + interfaceVIndexTable(interfaceVIndexTable), + interfaceAssignableTable(interfaceAssignableTable), + arrayType(0), superType(superType) {} + + const Type *superType; + public: + const Array &getArrayType() const; + const Type *getSuperType() const {return superType;}; + const Type *getSuperClass() const; + + Uint32 getInterfaceNumber() const; + + VTableEntry &getVTableEntry(Uint32 vIndex) const; + void setVTableEntry(Uint32 vIndex, void *classOrCodePtr); + + // Returns true if the current class object describes an interface. + bool isInterface() const {return (typeKind == tkInterface);} + bool isArray() const {return (typeKind == tkArray);} + + // Returns true if this class describes a primitive type + bool isPrimitive() const {return isPrimitiveKind(typeKind); } + + // Returns true if the type represented by the specified Class parameter + // can be converted to the type represented by this class object. + bool isAssignableFrom(const Type &from) const; + + // Returns true if the object represented by obj is an instance of this class + bool isInstance(JavaObject &obj) const {return (&obj.getType() == this || + isAssignableFrom(obj.getType()));} + + // Returns the modifiers (access flags) for this class object. + Uint32 getModifiers() const; + + // Returns the fully qualified name of the class; unlike toString(), + // does not prepend "class " in front of the name + const char *getName() const; + + #ifdef DEBUG_LOG + int printRef(LogModuleObject &f) const; + #endif +}; + +inline Type &asType(JavaObject &o); + +bool implements(const Type &sub, const Type &super); + + +// A Type for void, boolean, ubyte, byte, char, short, int, long, float, or double. +struct NS_EXTERN PrimitiveType: Type +{ + private: + static const PrimitiveType *primitiveTypes[nPrimitiveTypeKinds]; + + // Only initPrimitiveTypes can construct PrimitiveType instances. + PrimitiveType(const Type &metaType, TypeKind typeKind): Type(metaType, NULL, typeKind, true, 0, 0) { } + + public: + static const PrimitiveType &obtain(TypeKind tk); + static const PrimitiveType *getClass(const char* className); + static void staticInit(); + const char *getName() const; + char getSignatureEncoding() const; +}; + +inline const PrimitiveType &asPrimitiveType(const Type &t) +{ + assert(isPrimitiveKind(t.typeKind)); + return *static_cast(&t); +} + + +// A Type for any array. +struct NS_EXTERN Array: Type +{ + const Type &componentType; // Type of components of this array + + private: + mutable const char *fullName; // Fully qualified name of the array + + // Unique serial number among all interfaces and arrays of interfaces + Uint32 interfaceNumber; + + InterfaceDispatchTable *interfaceDispatchTable; + + static const Array *primitiveArrays[nPrimitiveTypeKinds]; + explicit Array(const Type &componentType, const Type &superType, + Uint32 nVTableSlots); + void buildAssignabilityTableForInterfaces(); + + public: + static Array &make(const Type &componentType); + static const Array &obtain(TypeKind elementKind); + const Type &getElementType() const; + const Type &getElementType(int &numDimensions) const; + const Type &getComponentType() const {return componentType;}; + + // Used for arrays of interfaces + Uint32 getInterfaceNumber() const { + assert(getElementType().typeKind == tkInterface); + return interfaceNumber; + } + +#ifdef DEBUG + void printValue(LogModuleObject &f, JavaArray *array, + int maxRecursion = 0, + Uint32 printFlags = PRINT_DEFAULT_FLAGS, + const char *newlineString = NULL, + Vector *printedObjects = NULL) const; +#endif + + // Returns the fully qualified name of the class; unlike toString(), + // does not prepend "class " in front of the name + const char *getName() const; + + #ifdef DEBUG_LOG + int printRef(LogModuleObject &f) const; + #endif + + static void staticInit(); +}; + +inline const Array &asArray(const Type &t) { + assert(t.typeKind == tkArray); + return *static_cast(&t); +} + + +// ---------------------------------------------------------------------------- + + +// An abstract class that contains information common to Class and +// Interface objects. +struct NS_EXTERN ClassOrInterface: Type +{ + Package &package; // The package that defines this class or interface + const char * /*const*/ name; // Unqualified name of the class or interface (stored in the ClassWorld's pool) + private: + mutable const char *fullName; // Fully qualified name of the class or interface + mutable const char *declName; // Class declaration, as returned by toString() + public: + + const Uint32 nInterfaces; // Number of interfaces implemented directly by this class or interface + Interface **interfaces; // Array of nInterfaces interfaces implemented directly by this class or interface + + static ClassCentral *central; // Repository of loaded classes + ClassFileSummary *summary; // Class loader for this class, NULL if none + bool initialized; + + // Run all the static initializers of this class + void runStaticInitializers(); + + bool isInitialized() { return initialized; } + + protected: + ClassOrInterface(const Type &metaType, TypeKind typeKind, + const Class *parent, + bool final, + Uint32 nVTableSlots, Package &package, + const char *name, Uint32 nInterfaces, + Interface **interfaces, + ClassFileSummary *summary, + VTableOffset *interfaceVIndexTable = 0, + Uint16 *interfaceAssignableTable = 0); + + public: + #ifdef DEBUG_LOG + int printRef(LogModuleObject &f) const; + #endif + + // Set the value of the ClassCentral object. This should be done + // only once. + static void setCentral(ClassCentral *c) { central = c; } + + // Returns fully qualified name of the class/interface in the form + // "class " or "interface " + const char *toString() const; + + // Returns the fully qualified name of the class; unlike toString(), + // does not prepend "class " in front of the name + const char *getName() const; + + // Returns the modifiers (access flags) for this class object. + Uint32 getModifiers() const; + + // Returns the class loader object for this class. Need to think about + // this a little bit. + // ClassLoader getClassLoader() const; + + // Returns summaries for the interfaces of this class. + // If this class object represents a class, returns an array containing + // objects representing the interfaces directly implemented by the class. + // If this Class object represents an interface, returns an array + // containing objects representing the direct superinterfaces of the + // interface. Returns number of array interfaces actually returned. + // This number could be zero, if the class is a primitive type or + // implements no interfaces. + Int32 getInterfaces(Interface **&summaries) const; + + // If this class or interface is a member of another class, returns the + // class object representing the class of which it is a member. If this is + // not the case, returns NULL. Hmmm. Need to think about how to implement + // this. + // Class *getDeclaringClass(); + + // Returns an array containing class objects representing all the public + // classes and interfaces that are members of the class represented by this + // class object. Returns number of class objects returned. + Int32 getClasses(Class **&summaries); + + // Returns an array containing information about the public fields of this + // object. Returns number of fields in object. + Int32 getFields(const Field **&fields); + + // Returns an array containing information about the public methods of + // this object. Returns number of fields in object. + Int32 getMethods(const Method **&methods); + + // Returns an array containing information about the public constructors of + // this object. Returns number of constructors. + Int32 getConstructors(const Constructor **&constructors); + + // Look up fields/methods/constructors. These methods search through + // publicly accessible fields/methods/constructors. They throw a + // runtimeError on failure. + Field &getField(const char *name); + Method &getMethod(const char *name, const Type *parameterTypes[], + Int32 numParams); + + // Look up a method based on its name and signature. This routine searches + // only in the current class, and does not search in superclasses. + // If publicOrProtected is true, only public and protected methods are searched; + // otherwise, all declared methods are examined. If the method was not found, + // returns NULL. + Method *getMethod(const char *name, const char *sig, bool publicOrProtcted); + + Constructor &getConstructor(const Type *parameterTypes[], + Int32 numParams); + + // The following functions deal with *all* declared fields, methods, or + // constructors, be they public, protected, or private. + Int32 getDeclaredClasses(Class **&summaries); + Int32 getDeclaredFields(const Field **&fields); + Int32 getDeclaredMethods(const Method **&methods); + Int32 getDeclaredConstructors(const Constructor **&constructors); + + Field &getDeclaredField(const char *name); + Method &getDeclaredMethod(const char *name, const Type *parameterTypes[], + Int32 numParams); + + Constructor &getDeclaredConstructor(const Type *parameterTypes[], + Int32 numParams); + +private: + void getFullNames() const; +}; + + +// Runtime reflection information about a class, such as its inheritance +// hierarchy, fields and field layout, etc. +// A Class remains in memory as long as a class is alive. It does +// not keep track of a class's constant pool, etc. +struct NS_EXTERN Class: ClassOrInterface +{ + Uint32 instanceSize; // Size of instance objects in bytes + private: + + Class(Package &package, const char *name, const Class *parent, Uint32 nInterfaces, Interface **interfaces, + ClassFileSummary *summary, bool final, Uint32 instanceSize, Uint32 nVTableSlots, + VTableOffset *interfaceVOffsetTable, Uint16 *interfaceAssignableTable); + Class(bool isOwnClass, const char *name, Uint32 instanceSize, Uint32 nVTableSlots); + + public: + static Class &make(Package &package, const char *name, const Class *parent, Uint32 nInterfaces, Interface **interfaces, + ClassFileSummary *summary, bool final, Uint32 extraSize, Uint32 nExtraVTableSlots, + VTableOffset *interfaceVOffsetTable, + Uint16 *interfaceAssignableTable); + // Given a fully qualified className, attempts to load and link the class + // and returns the corresponding Class object. The name could be of + // the form java/lang/Object or java.lang.Object . + static Class &forName(const char *className); + + // Ensure that the object obj is a primitive class and + // return the raw primitive value corresponding to the class, + // converted to a Uint32. + static Uint32 getPrimitiveValue(JavaObject &obj); + + // Creates an instance of the class if the class is instantiable. + JavaObject &newInstance(); + + static JavaObject &makePrimitiveObject(TypeKind tk, void *address); + + JavaObject *clone(JavaObject &inObj) const; + + +#ifdef DEBUG + void printValue(LogModuleObject &f, JavaObject *obj, + int maxRecursion = 0, + Uint32 printFlags = PRINT_DEFAULT_FLAGS, + const char *newlineString = NULL, + Vector *printedObjects = NULL); +#endif + + private: + static Class &makeSpecial(bool isOwnClass, const char *name, Uint32 instanceSize, Uint32 nVTableSlots); + void setParent(const Class &p); + public: + + const Class *getParent() const; + bool implements(const Class &c) const; + bool implements(const Interface &i) const; + + friend class Standard; // Standard needs to call makeSpecial and explicitly set the parents of the first few classes created + // for bootstrapping reasons. +}; + +inline const Class &asClass(const Type &t); + +const Uint32 vTableOffset = sizeof(Class); // Offset from a Type to beginning of its vtable +inline Int32 vTableIndexToOffset(Uint32 vIndex) {return (Int32)(vTableOffset + vIndex*sizeof(VTableEntry));} + +struct NS_EXTERN Interface: ClassOrInterface +{ +private: + // Unique serial number among all interfaces and arrays of interfaces + Uint32 interfaceNumber; + +public: + Interface(Package &package, const char *name, Uint32 nInterfaces, + Interface **interfaces, + ClassFileSummary *summary); + + bool implements(const Interface &i) const; + + void addInterfaceArraysToAssignableTable(InterfaceDispatchTable *interfaceDispatchTable, + int numDimensions); + + Uint32 getInterfaceNumber() const {return interfaceNumber;}; +}; +inline const Interface &asInterface(const Type &t); + + +// ---------------------------------------------------------------------------- +// Standard objects + + +// Standard classes +enum StandardClass { + cNone, + cObject, // java.lang.Object + cPrimitiveType, // internal variant of java.lang.Class + cPrimitiveArray, // internal variant of java.lang.Class + cObjectArray, // internal variant of java.lang.Class + cClass, // internal variant of java.lang.Class + cInterface, // internal variant of java.lang.Class + cField, // internal variant of java.lang.Field + cMethod, // internal variant of java.lang.Method + cConstructor, // internal variant of java.lang.Constructor + cThrowable, // java.lang.Throwable + cException, // java.lang.Exception + cRuntimeException, // java.lang.RuntimeException + cArithmeticException, // java.lang.ArithmeticException + cArrayStoreException, // java.lang.ArrayStoreException + cClassCastException, // java.lang.ClassCastException + cIllegalMonitorStateException, // java.lang.illegalMonitorStateException + cArrayIndexOutOfBoundsException,// java.lang.ArrayIndexOutOfBoundsException + cNegativeArraySizeException, // java.lang.NegativeArraySizeException + cNullPointerException, // java.lang.NullPointerException + cError, // java.lang.Error + cThreadDeath, // java.lang.ThreadDeath + cBoolean, // java.lang.Boolean + cByte, // java.lang.Byte + cCharacter, // java.lang.Character + cShort, // java.lang.Short + cInteger, // java.lang.Integer + cLong, // java.lang.Long + cFloat, // java.lang.Float + cDouble, // java.lang.Double + cString, // java.lang.String + cInterruptedException // java.lang.InterruptedException +}; +const nStandardClasses = cString + 1; +const firstOrdinaryStandardClass = cThrowable; + +// Standard interfaces +enum StandardInterface { + iCloneable // java.lang.Cloneable +}; +const nStandardInterfaces = iCloneable + 1; + + +// Standard objects +enum StandardObject { + oArithmeticException, // new java.lang.ArithmeticException() + oArrayStoreException, // new java.lang.ArrayStoreException() + oClassCastException, // new java.lang.ClassCastException() + oIllegalMonitorStateException, // new java.lang.IllegalMonitorStateException + oArrayIndexOutOfBoundsException,// new java.lang.ArrayIndexOutOfBoundsException() + oNegativeArraySizeException, // new java.lang.NegativeArraySizeException() + oNullPointerException, // new java.lang.NullPointerException() + oInterruptedException // new java.lang.InterruptedException() +}; +const nStandardObjects = oNullPointerException + 1; + + +class NS_EXTERN Standard +{ + static const Class *standardClasses[nStandardClasses]; + static const Interface *standardInterfaces[nStandardInterfaces]; + static const JavaObject *standardObjects[nStandardObjects]; + +public: + static bool isPrimitiveWrapperClass(const Class &clazz, TypeKind *tk = 0); + static bool isDoubleWordPrimitiveWrapperClass(const Class &clazz); + static const Class &get(StandardClass sc) {assert(standardClasses[sc]); return *standardClasses[sc];} + static const Interface &get(StandardInterface si) {assert(standardInterfaces[si]); return *standardInterfaces[si];} + static const JavaObject &get(StandardObject so) {assert(standardObjects[so]); return *standardObjects[so];} + + static void initStandardObjects(ClassCentral &c); +}; + + +// --- INLINES ---------------------------------------------------------------- + +extern const NS_EXTERN Int8 typeKindSizes[nTypeKinds]; + +// +// Return the number of bytes taken by a value that has the given TypeKind. +// +inline int getTypeKindSize(TypeKind tk) +{ + assert((uint)tk < nTypeKinds); + return typeKindSizes[tk]; +} + + +extern const NS_EXTERN Int8 lgTypeKindSizes[nTypeKinds]; +// +// Return the base-2 logarithm of the number of bytes taken by a value +// that has the given TypeKind. +// +inline int getLgTypeKindSize(TypeKind tk) +{ + assert((uint)tk < nTypeKinds); + return lgTypeKindSizes[tk]; +} + + +extern const Int8 typeKindNSlots[nTypeKinds]; +// +// Return the number of environment slots taken by a value that has the +// given TypeKind. +// +inline int nTypeKindSlots(TypeKind tk) +{ + assert((uint)tk < nTypeKinds); + return typeKindNSlots[tk]; +} + + +// +// If c is the descriptor for a primitive type, sets tk to the +// typeKind of c and returns true. Else, returns false. +// +inline bool getTypeKindFromDescriptor(char c, TypeKind &tk) +{ + bool ret = true; + + switch (c) { + case 'B': + tk = tkByte; + break; + + case 'C': + tk = tkChar; + break; + + case 'D': + tk = tkDouble; + break; + + case 'F': + tk = tkFloat; + break; + + case 'I': + tk = tkInt; + break; + + case 'J': + tk = tkLong; + break; + + case 'S': + tk = tkShort; + break; + + case 'Z': + tk = tkBoolean; + break; + + default: + ret = false; + } + + return ret; +} + + +// ---------------------------------------------------------------------------- + + +// +// Return the type of arrays whose elements have this Type. +// +inline const Array &Type::getArrayType() const +{ + if (arrayType) + return *arrayType; + arrayType = &Array::make(*this); + return *arrayType; +} + + +// +// Assert that this JavaObject is really a Type and return that Type. +// +inline Type &asType(JavaObject &o) +{ + const Type *type = &o.getType(); + + assert(type && + (type == &Standard::get(cPrimitiveType) || + type == &Standard::get(cPrimitiveArray) || + type == &Standard::get(cObjectArray) || + type == &Standard::get(cClass) || + type == &Standard::get(cInterface))); + return *static_cast(&o); +} + +inline Type &asType(const Array &o) { + return *static_cast(const_cast(&o)); +} + +inline Type &asType(const Class &o) { + return *static_cast(const_cast(&o)); +} + +// +// Return the primitive type corresponding to the given TypeKind. +// +inline const PrimitiveType &PrimitiveType::obtain(TypeKind tk) +{ + assert(isPrimitiveKind(tk) && primitiveTypes[tk]); + return *primitiveTypes[tk]; +} + + + +// +// Return a PrimitiveArray corresponding to the given TypeKind. +// +inline const Array &Array::obtain(TypeKind elementKind) +{ + assert(isNonVoidPrimitiveKind(elementKind) && primitiveArrays[elementKind]); + return *primitiveArrays[elementKind]; +} + +// Return the offset from an array's address to its first element. +inline int arrayEltsOffset(TypeKind tk) +{ + assert((uint)tk < nTypeKinds); + int lgtks = lgTypeKindSizes[tk]; + + // Round up address so elements are aligned + return (((sizeof(JavaArray) + typeKindSizes[tk] - 1) >> lgtks) << lgtks); +} + +// ---------------------------------------------------------------------------- + + +// +// Assert that this Type is really a Class and return that Class. +// +inline const Class &asClass(const Type &t) +{ + assert(t.typeKind == tkObject); + return *static_cast(&t); +} + +inline const Class &JavaObject::getClass() const { + return asClass(getType()); +} + +// +// Assert that this Type is really an Interface and return that Interface. +// +inline const Interface &asInterface(const Type &t) +{ + assert(t.typeKind == tkInterface); + return *static_cast(&t); +} + +// +// Initialize a new ClassOrInterface object. metaType is the type of +// the ClassOrInterface object -- either cClass or cInterface. +// size is the size of instances of this class; size is zero if this is Interface +// instead of a Class. +// package is the package that defined this class or interface, name is the unqualified +// name of this class or interface, and interfaces is an array of nInterfaces elements +// that lists all interfaces from which this class or interface derives except that, +// if this is a Class, the interfaces array does not include interfaces from which +// the parent class derives. +// +inline ClassOrInterface::ClassOrInterface(const Type &metaType, + TypeKind typeKind, + const Class *parent, bool final, + Uint32 nVTableSlots, + Package &package, const char *name, + Uint32 nInterfaces, + Interface **interfaces, + ClassFileSummary *summary, + VTableOffset *interfaceVOffsetTable, + Uint16 *interfaceAssignableTable): + Type(metaType, &asType(*parent), typeKind, final, nVTableSlots, interfaceVOffsetTable, interfaceAssignableTable), + package(package), + name(name), + fullName(0), + declName(0), + nInterfaces(nInterfaces), + interfaces(interfaces), + summary(summary), + initialized(false) +{ } + +// +// Get this class's parent. Return nil if this class is Object. +// +inline const Class *Class::getParent() const +{ + // Make sure that we've set the parent already. + assert(superType || this == &Standard::get(cObject)); + return static_cast(getSuperClass()); +} + + +// +// Get the vtable entry at the given index. +// +inline VTableEntry &Type::getVTableEntry(Uint32 vIndex) const +{ + assert(vIndex < nVTableSlots); + assert((typeKind == tkObject) || (typeKind == tkArray)); + return *(VTableEntry *)((ptr)this + vTableIndexToOffset(vIndex)); +} + +// +// Set the vtable entry at the given index to point either to a Class or to a +// method's code. +// +inline void Type::setVTableEntry(Uint32 vIndex, void *classOrCodePtr) +{ + assert(vIndex < nVTableSlots); + assert((typeKind == tkObject) || (typeKind == tkArray)); + VTableEntry *vTableEntry = (VTableEntry *)((ptr)this + vTableIndexToOffset(vIndex)); + vTableEntry->classOrCodePtr = classOrCodePtr; +} + +#ifdef DEBUG +void printValue(LogModuleObject &f, void *valPtr, const Type &type, + int maxRecursionLevel = 0, + Uint32 printFlags = PRINT_DEFAULT_FLAGS, + const char *newlineString = NULL, + Vector *printedObjects = NULL); + +void dump(JavaObject *obj, int maxRecursion = 0, Uint32 printFlags = PRINT_DEFAULT_FLAGS, + const char *newlineString = "\n"); +#endif + +#endif diff --git a/ef/Runtime/System/JavaString.cpp b/ef/Runtime/System/JavaString.cpp new file mode 100644 index 000000000000..85f2fa3e510b --- /dev/null +++ b/ef/Runtime/System/JavaString.cpp @@ -0,0 +1,91 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#include "plstr.h" +#include "JavaString.h" +#include "ClassCentral.h" +#include "ClassFileSummary.h" + +static inline JavaArray *newCharArray(Uint32 length) +{ + void *mem = malloc(arrayEltsOffset(tkChar) + getTypeKindSize(tkChar)*length); + return (new (mem) JavaArray(Array::obtain(tkChar), length)); +} + + +/* Return the UTF representation of this string. This routine allocates + * enough memory for the conversion; this memory can be freed using + * JavaString::freeUtf() + */ +char *JavaString::convertUtf() +{ + /* XXX Fixme For now, we just copy the string over byte by byte... */ + const int16 *chars = getStr(); + char *copy = new char[count+1]; + + int32 i; + for (i = 0; i < count; i++) + copy[i] = (char) chars[i]; + + copy[i] = 0; + return copy; +} + +void JavaString::freeUtf(char *str) +{ + delete [] str; +} + +/* Create a new JavaString from a char array that represents the string in UTF-8 + * format. + */ +JavaString::JavaString(const char *str) : JavaObject(*strType) +{ + count = PL_strlen(str); + + offset = 0; + + /* Let's keep the string zero-terminated anyway */ + value = (JavaArray *) newCharArray(count+1); + int16 *chars = const_cast(getStr()); + + for (int32 i = 0; i < count; i++) + chars[i] = str[i]; + + chars[count] = 0; +} + +/* print a textual representation of this string */ +void JavaString::dump() +{ + const int16 *chars = getStr(); + + for (int16 i = 0; i < count; i++) + putchar(chars[i]); + + putchar('\n'); +} + +Type *JavaString::strType; + +void JavaString::staticInit() +{ + strType = &asType(Standard::get(cString)); +} + + + diff --git a/ef/Runtime/System/JavaString.h b/ef/Runtime/System/JavaString.h new file mode 100644 index 000000000000..978d8d61ea8b --- /dev/null +++ b/ef/Runtime/System/JavaString.h @@ -0,0 +1,63 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#ifndef _JAVA_STRING_H_ +#define _JAVA_STRING_H_ + +#include "JavaObject.h" + +class ClassCentral; + + +/* A String is a Java Object that holds an array of characters This is the C++ + * structure corresponding to java/lang/string. + */ +struct NS_EXTERN JavaString: JavaObject { +private: + JavaArray *value; /* Array of Java char's */ + Int32 offset; /* First index of the storage that is used */ + Int32 count; /* Number of characters in the string */ + Int64 serialVersionId; + + static Type *strType; /* Type: must be set to Java/lang/String::type */ + +public: + + static JavaString* make(const char* str) {return new JavaString(str); /* To change when we have a GC. */} + + JavaString(const char *str); + const int16 *getStr() { return (int16 *) ((char *) value+arrayEltsOffset(tkChar)); } + + /* Must be called before an instance of string is created */ + static void staticInit(); + + char *convertUtf(); + static void freeUtf(char *); + + // Return the size of the string + Int32 getLength() { return count; } + void dump(); +}; + +inline JavaString &asJavaString(JavaObject &obj) +{ + assert(&obj.getType() == &asType(Standard::get(cString))); + return *(JavaString*)&obj; +} + + +#endif /* _JAVA_STRING_H_ */ diff --git a/ef/Runtime/System/JavaVM.cpp b/ef/Runtime/System/JavaVM.cpp new file mode 100644 index 000000000000..3078ce55fb33 --- /dev/null +++ b/ef/Runtime/System/JavaVM.cpp @@ -0,0 +1,271 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#include "JavaVM.h" +#include "prprf.h" +#include "plstr.h" +#include "LogModule.h" +#include "Debugger.h" +#include "jvmdi.h" +#include "Thread.h" +#include "JniRuntime.h" + +Pool envPool; +ClassWorld world(envPool); +StringPool sp(envPool); +Pool debuggerPool; + +UT_DEFINE_LOG_MODULE(HiMom); +UT_DEFINE_LOG_MODULE(VM); + +VM VM::theVM; + +/* Initialize the VM. If initialize is true, attempts to run + * the static initializers to initialize the System class on + * start-up. + */ +void VM::staticInit(bool initialize) +{ + NativeMethodDispatcher::staticInit(); + InterfaceDispatchTable::staticInit(envPool); + Standard::initStandardObjects(central); + JavaString::staticInit(); + JNIInitialize(); + + /* Intern a few strings which we'll need */ + /* FIX-ME Why do we need them??? */ + sp.intern(""); + sp.intern("()V"); + + if (initialize) { + bool loadedSysLibrary; + + Monitor::staticInit(); + + /* Load package library */ + if (!(loadedSysLibrary = (NativeMethodDispatcher::loadLibrary("Package") != 0))) + UT_LOG(VM, PR_LOG_ALWAYS, ("\tCannot load package library!\n")); + + if (loadedSysLibrary) { + /* execute System::initializeSystemClass() to get us up and going */ + theVM.execute("java/lang/System", "initializeSystemClass", "()V", 0, 0); + } + + Thread::staticInit(); + } +} + +/* Set the class path used to search for class files */ +void VM::setClassPath(const char *classPath) +{ + central.setClassPath(classPath); +} + +/* Load a native library. libName is the canonical name of the library. + * This routine returns true on success, false on failure. + */ +bool VM::loadLibrary(const char *libName) +{ + return (NativeMethodDispatcher::loadLibrary(libName) != 0); +} + +const Class &VM::getStandardClass(StandardClass clz) +{ + return (Standard::get(clz)); +} + +/* Execute the method whose simple name is given by methodName and signature + * string is given by signature in the class given by className. + * If the method is not overloaded, signature can be nil. + * If invokeMethod is false, then just compile the method but do not + * execute it. + */ +void VM::execute(const char *className, + const char *methodName, + const char *signature, + JavaObject *args[], + Int32 nArgs) +{ + ClassFileSummary *cfs = ¢ral.addClass(className); + + if (compileStage < csPreprocess) + return; + + /* Search for specified method */ + Method *method; + + if (!methodName) { + methodName = sp.get("main"); + signature = sp.get("([Ljava/lang/String;)V"); + + if (!methodName || !signature) + return; + } else { + methodName = sp.get(methodName); + if (signature) + signature = sp.get(signature); + } + + if ((method = cfs->getMethod(methodName, signature)) != 0) { + // MethodDescriptor descriptor(*method); + + void *code; + code = method->compile(); + + if (debugger.getEnabled()) + JVMDI_SetBreakpoint((JNIEnv *) code, 0, 0, 0); + + if (!noInvoke) { + /* You can only jump to a static method */ + if ((method->getModifiers() & CR_METHOD_STATIC)) { + if (!PL_strcmp(methodName, "main")) { + const Type *type = (const Class *) central.addClass("java/lang/String").getThisClass(); + const Array &typeOfArray = type->getArrayType(); + void *mem = malloc(arrayObjectEltsOffset + getTypeKindSize(tkObject)*nArgs); + JavaArray *argsArray = new (mem) JavaArray(typeOfArray, nArgs); + + /* Copy args into the array */ + JavaObject **argsInArray = (JavaObject **) ((char *) mem+arrayObjectEltsOffset); + for (int32 i = 0; i < nArgs; i++) + argsInArray[i] = args[i]; + + args = new JavaObject*[1]; + args[0] = argsArray; + nArgs = 1; + } + //method->invoke(0, args, nArgs); + Thread::invoke(method,NULL,args,nArgs); + + } else + UT_LOG(VM, PR_LOG_ALWAYS, ("specified method is not static; cannot execute\n")); + } + + } else + UT_LOG(VM, PR_LOG_ALWAYS, ("Could not find method %s.\n", methodName)); + +} + +ClassCentral VM::central(envPool, world, sp, 0); +DebuggerState VM::debugger(debuggerPool); + +/* + * Compile and dump the methods in the file read into cfs. + * Run the compiler's stages + * up to and including the given stage. Use the envPool for temporary + * storage. + */ +void VM::compileMethods(const char *className) +{ + ClassFileSummary &cfs = central.addClass(className); + + uint nMethods = cfs.getMethodCount(); + const Method **methods = cfs.getMethods(); + + for (uint16 i =0; i < nMethods; i++) { + Method *method = const_cast(methods[i]); + + method->compile(); + } +} + + +/* Intern a string, expected to be in UTF8 format, and return a reference + * to the interned string object. + */ +JavaString &VM::intern(const char *str) +{ + const char *internedp = sp.intern(str); + return *sp.getStringObj(internedp); +} + +#ifdef DEBUG + +/* Copy breakPointsIn into breakpointsOut, allocating memory as neccessary */ +inline void VM::setBreakPoints(DebugDesc *breakPointsIn, Uint32 numBreakPointsIn, + DebugDesc *&breakPointsOut, Uint32 &numBreakPointsOut) +{ + if (breakPointsOut) + delete [] breakPointsOut; + + breakPointsOut = new DebugDesc[(numBreakPointsOut = numBreakPointsIn)]; + + for (Uint32 i = 0; i < numBreakPointsIn; i++) { + /* Replace slashes with dots, since the fully qualified class name is stored with dots + * as the separators + */ + for (char *cnameTemp = const_cast(breakPointsIn[i].className); *cnameTemp; cnameTemp++) + if (*cnameTemp == '/') *cnameTemp = '.'; + + breakPointsOut[i].className = sp.intern(breakPointsIn[i].className); + breakPointsOut[i].methodName = sp.intern(breakPointsIn[i].methodName); + + /* Replace all dots in the signature with slashes */ + for (char *bTemp = const_cast(breakPointsIn[i].sig); *bTemp; + bTemp++) + if (*bTemp == '.') *bTemp = '/'; + + breakPointsOut[i].sig = sp.intern(breakPointsIn[i].sig); + } + +} + + +/* Specify a list of methods to break into when compiling the method */ +void VM::setCompileBreakPoints(DebugDesc *breakPoints, Uint32 numBreakPoints) +{ + setBreakPoints(breakPoints, numBreakPoints, compileBreakPoints, nCompileBreakPoints); +} + +/* Specify a list of methods to break into when running the method */ +void VM::setExecBreakPoints(DebugDesc *breakPoints, Uint32 numBreakPoints) +{ + setBreakPoints(breakPoints, numBreakPoints, execBreakPoints, nExecBreakPoints); +} + +#endif + +/* Construct and return a fully qualified class-name + * from the input name, which is a fully qualified + * java class name. + * getUtfClassName("java.lang.String") = "java/lang/String" + */ +char *VM::getUtfClassName(const char *name) +{ + char *utfClassName = PL_strdup(name); + + for (char *t = utfClassName; *t; t++) + if (*t == '.') *t = '/'; + + return utfClassName; +} + +/* Free the name returned by getUtfClassName() */ +void VM::freeUtfClassName(char *name) +{ + free(name); +} + + +VM::~VM() +{ + if (execBreakPoints) + delete [] execBreakPoints; + + if (compileBreakPoints) + delete [] compileBreakPoints; +} + diff --git a/ef/Runtime/System/JavaVM.h b/ef/Runtime/System/JavaVM.h new file mode 100644 index 000000000000..6adf972e93f1 --- /dev/null +++ b/ef/Runtime/System/JavaVM.h @@ -0,0 +1,162 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#include "BytecodeGraph.h" +#include "ClassCentral.h" +#include "PrimitiveOptimizer.h" +#include "ErrorHandling.h" +#include "FieldOrMethod.h" +#include "NativeCodeCache.h" +#include "DebugUtils.h" +#include "NativeMethodDispatcher.h" +#include "JavaString.h" +#include "Debugger.h" + +#include "prprf.h" + +/* A structure to specify methods in debug breakpoints */ +struct NS_EXTERN DebugDesc { + const char *className; /* Fully qualified class name of the class */ + const char *methodName; /* Simple name of the method */ + const char *sig; /* Java signature string of the method */ +}; + +class NS_EXTERN VM { +public: + static VM theVM; + static DebuggerState debugger; + + VM() : compileBreakPoints(0), + nCompileBreakPoints(0), + execBreakPoints(0), + nExecBreakPoints(0), + compileStage(csGenInstructions), + noInvoke(false) {} + + ~VM(); + + static void staticInit(bool initialize = false); + + void execute(const char *className, const char *methodName, + const char *signature, + JavaObject *args[], + Int32 nArgs); + + void compileMethods(const char *className); + + static void setClassPath(const char *classPath = 0); + + static ClassCentral &getCentral() { return central; } + + static bool loadLibrary(const char *libName); + + static JavaString &intern(const char *str); + + static const Class &getStandardClass(StandardClass clz); + + static char *getUtfClassName(const char *name); + + static void freeUtfClassName(char *name); + + /* + * The following methods have been put in to support temporary debugging + * and will work only with the debug build of the VM + */ + void setCompileBreakPoints(DebugDesc *breakPoints, Uint32 numBreakPoints); + + /* + * Get the current list of compile breakpoints. Returns the number of + * compile breakpoints + */ + Uint32 getCompileBreakPoints(DebugDesc *&breakPoints) + { breakPoints = compileBreakPoints; return nCompileBreakPoints; } + + void setExecBreakPoints(DebugDesc *breakPoints, Uint32 numBreakPoints); + + /* + * Get the current list of execution breakpoints. Returns the number of + * execution breakpoints + */ + Uint32 getExecBreakPoints(DebugDesc *&breakPoints) + { breakPoints = execBreakPoints; return nExecBreakPoints; } + + /* Get and set the compile stage for all methods compiled */ + void setCompileStage(CompileStage stage) { compileStage = stage; } + CompileStage getCompileStage() { return compileStage; } + + /* get and set the verbosity of compilation */ + void setVerbose(bool ver) { verbose = ver; } + bool getVerbose() { return verbose; } + + void setNoInvoke(bool noinv) { noInvoke = noinv; } + bool getNoInvoke() { return noInvoke; } + + void setTraceAllMethods(bool b) { + assert(!b || inhibitBackpatching); + traceAllMethods = b; + } + bool getTraceAllMethods() { return traceAllMethods; } + + void setInhibitBackpatching(bool b) { inhibitBackpatching = b; } + bool getInhibitBackpatching() { return inhibitBackpatching; } + + void setEmitHTML(bool emit) { emitHTML = emit; } + bool getEmitHTML() { return emitHTML; } + + void setCatchHardwareExceptions(bool catchExc) { catchHardwareExceptions = catchExc; } + bool getCatchHardwareExceptions() { return catchHardwareExceptions; } + +private: +#ifdef DEBUG + void setBreakPoints(DebugDesc *breakPointsIn, Uint32 numBreakPointsIn, + DebugDesc *&breakPointsOut, Uint32 &numBreakPointsOut); +#endif + + static ClassCentral central; + + DebugDesc *compileBreakPoints; + Uint32 nCompileBreakPoints; + + DebugDesc *execBreakPoints; + Uint32 nExecBreakPoints; + + CompileStage compileStage; + bool verbose; + bool noInvoke; /* If true, do not invoke method */ + bool inhibitBackpatching; // If true, don't update vtables or + // call-sites when methods are compiled + bool traceAllMethods; + bool emitHTML; + + bool catchHardwareExceptions; // If true, catch all hardware exceptions and asserts +}; + + + +/* UtfClassName is a wrapper around VM::getUtfClassName(); */ +class UtfClassName { +public: + UtfClassName(const char *name) { + className = VM::getUtfClassName(name); + } + + ~UtfClassName() { VM::freeUtfClassName(className); } + operator char * () { return className; } + +private: + char *className; +}; diff --git a/ef/Runtime/System/Makefile b/ef/Runtime/System/Makefile new file mode 100644 index 000000000000..d8c465eb97b8 --- /dev/null +++ b/ef/Runtime/System/Makefile @@ -0,0 +1,79 @@ +#!gmake +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +####################################################################### +# (1) Directory specific info # +####################################################################### + +DEPTH = ../.. + +DIRS = md +SUBMODULES = $(DIRS) + +CPPSRCS = ClassWorld.cpp \ + FieldOrMethod.cpp \ + JavaObject.cpp \ + JavaString.cpp \ + Method.cpp \ + StackWalker.cpp \ + InterfaceDispatchTable.cpp \ + SysCallsRuntime.cpp \ + JavaVM.cpp \ + Monitor.cpp \ + Thread.cpp \ + $(NULL) + +LOCAL_EXPORTS = ClassWorld.h \ + InterfaceDispatchTable.h \ + JavaObject.h \ + FieldOrMethod.h \ + Exceptions.h \ + JavaString.h \ + Method.h \ + Monitor.h \ + StackWalker.h \ + SysCallsRuntime.h \ + Thread.h \ + JavaVM.h \ + Monitor.h \ + $(NULL) + +MODULE_NAME = EF + +####################################################################### +# (2) Include "component" configuration information. # +####################################################################### + +include $(DEPTH)/config/config.mk + +####################################################################### +# (3) Include "local" platform-dependent assignments (OPTIONAL). # +####################################################################### + + +####################################################################### +# (4) Execute "component" rules. (OPTIONAL) # +####################################################################### + +include $(DEPTH)/config/rules.mk + +####################################################################### +# (7) Execute "local" rules. (OPTIONAL). # +####################################################################### + + + diff --git a/ef/Runtime/System/Method.cpp b/ef/Runtime/System/Method.cpp new file mode 100644 index 000000000000..c165ab1be8ff --- /dev/null +++ b/ef/Runtime/System/Method.cpp @@ -0,0 +1,38 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#include "Method.h" + + +// ---------------------------------------------------------------------------- +// Signature + +// +// Return the number of Java environment slots that this signature's arguments +// would take. All types count as one slot except for long and double, which +// take two slots each. +// +uint Signature::nArgumentSlots() const +{ + assert(nArguments == 0 || argumentTypes); + uint nSlots = 0; + const Type **a = argumentTypes; + for (uint i = nArguments; i; i--) + nSlots += nTypeKindSlots((*a++)->typeKind); + return nSlots; +} + diff --git a/ef/Runtime/System/Method.h b/ef/Runtime/System/Method.h new file mode 100644 index 000000000000..1a1d35ef9969 --- /dev/null +++ b/ef/Runtime/System/Method.h @@ -0,0 +1,52 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#ifndef METHOD_H +#define METHOD_H + +#include "JavaObject.h" + +// Utility class for passing method signatures around. +// This struct is not related to the heavyweight Method class. +struct Signature +{ + uint nArguments; // Number of method arguments (including "this" if present) + const Type **argumentTypes; // Array of nArgument Types of arguments + const Type *resultType; // Type of result; the Void primitive type if no result + bool isStatic; // True if method has no "this" argument + + uint getNResults() const {return resultType->typeKind != tkVoid;} + uint nArgumentSlots() const; + uint nResultSlots() const; +}; + + +// --- INLINES ---------------------------------------------------------------- + + +// +// Return the number of Java environment slots that this signature's result +// would take. Void takes no slots, long and double take two slots, and all +// other types take one slot. +// +inline uint Signature::nResultSlots() const +{ + assert(resultType); + return nTypeKindSlots(resultType->typeKind); +} + +#endif diff --git a/ef/Runtime/System/Monitor.cpp b/ef/Runtime/System/Monitor.cpp new file mode 100644 index 000000000000..6efe5dff6c73 --- /dev/null +++ b/ef/Runtime/System/Monitor.cpp @@ -0,0 +1,744 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#include "Monitor.h" +#include "Exceptions.h" +#include "SysCallsRuntime.h" +#include "prprf.h" + +/* + Author: Bjorn Carlson (bjorn@netscape.com) + + This is the new implementation: + Each object has one state word in which we can place information + regarding the status of the lock. This might later be a word + shared with other parts of the system such as the gc. At this point, we are + assuming that we can use three bits. Hence; + + Obj: ------------ + | type | + ------------ + | hash/gc bb| + ------------ + + where the lock state is captured in the two bits 'bb'. + + The lock state is as follows: + case 01: + Obj is unlocked and the remaining 30 bits are used as a hash code (shifted by 2). + + case 11: + Obj is unlocked and the remaining 30 bits index an entry in the hash code + vector. If the code is 0, the object has not yet received its hash code + (strings are assigned a code lazily). + + case 00: + Obj is locked and the remaining 30 bits point to a stack frame entry containing + the old contents of the object. As a special case we use the word 0 for signalling + that the object is currently busy, which we use when updating its hash code. + + case 10: + Obj is locked, some thread is waiting, and the remaining 30 bits point to + the stack as above. + + For the specific algorithms for reading and writing hash codes, and locking and + unlocking monitors, see below. + + When a thread is created (from inside java.lang.Thread, or + externally), the initial function should be Thread::run, so that appropriate + initialization takes place. + + When a thread dies (is interrupted), I try to catch this in the calls to + NSPR which fails in such a case. At failure, I try to take the appropriate + action. A thread may die, however, waiting for I/O or hanging off some NSPR + lock outside our monitors. + + */ + +Monitors* monitors; + +inline bool Monitor::cmpAndSwap(Int32* w, Int32 ov, Int32 nv) +{ + bool r=false; +#ifdef _WIN32 + __asm { + mov eax,ov + mov ecx, nv + mov ebx, w + lock cmpxchg [ebx], ecx + sete r + } + return r; +#elif defined(__linux__) + __asm__ ("movl %0, %%eax" : /* no outputs */ : "g" (ov)); + __asm__ ("movl %0, %%ecx" : /* no outputs */ : "g" (nv)); + __asm__ ("movl %0, %%ebx" : /* no outputs */ : "g" (w)); + __asm__ ("lock; cmpxchg %%ecx, (%%ebx)" : /* no outputs */ : /* no outputs */); + __asm__ ("sete %0" : "=g" (r) : /* no outputs */); + return r; +#else + ov; + PR_fprintf(PR_STDOUT,"compare and swap NYI!!\n"); + *w = nv; + return (true); +#endif +} + +inline Int32 Monitor::pushStack() { // for now + return monitors->pushStack(); + // should be something like: + // __asm { + // mov ecx,v + // mov [esp]Context.lock,ecx + // } +} + +inline Int32 Monitor::popStack() { // for now + return monitors->popStack(); + // should be something like: + // __asm { + // mov eax,[esp]Context.lock + // } +} + +inline bool Monitor::inStack(Int32 v) { + return monitors->inStack(v); + // Use #ifdef HAVE_STACK_GROWING_UP + // and something like: + // p = beginning of current stack; + // __asm { + // cmp esp,v + // setb r1 + // mov ecx,p + // cmp ecx,v + // seta r2 + // mov eax,r1 + // and eax,r2 + // } +} + +void Monitor::staticInit() +{ + monitors = new Monitors(10); + threadInit(); +} + +void Monitor::destroy() +{ + delete monitors; +} + +inline void Monitor::threadInit() +{ + monitors->threadInit(); +} + +// locks the monitor part of object o. +/* the algorithm is as follows: + get a pointer to the state slot of the object, w, and the stack entry, sp, in which to + save the old value of *w. Now; + 1. if *w is 0, then the monitor is busy and we spin. + 2. if *w is unlocked (an odd number), then we optimistically save *w to sp, and + try to swap sp into w. If this succeeds, we now own the monitor. If it fails, we + loop back to 1. + 3. if *w is locked, we check if we own the lock, by checking if the pointer stored in + *w (v) points into our stack. If it does, we save 0 onto the stack, and return. If it + doesn't, we enqueue ourselves onto the suspension list of the monitor. For more on this, + see enqueue() (there is a special case when the lock is released while we are trying to + suspend, which is dealt with in enqueue()). The variable 'wl' is used for keeping the + waiting bit set when returning from enqueue, if we see that more threads are waiting when + we wake up. Hence, or:ing 'wl' with 'sp' will keep the bit set if needed. When we return + from enqueue() we loop back to 1. + */ +void Monitor::lock(JavaObject &o) +{ + Int32* w; + Int32 v,sp,wl=0; + +#ifdef DEBUG_ + PR_fprintf(PR_STDOUT,"\nT%x trying to lock %x\n",PR_GetCurrentThread(),&o); +#endif + w = &o.state; + sp = pushStack(); + while (true) { + v = *w; + if (v == 0) + continue; + if ((v&Unlocked) != 0) { // unlocked + // write to stack entry + *(Int32*)sp = v; + sp |= wl; + if (cmpAndSwap(w,v,sp)) + return; + continue; // try again + } + v &= ~LockMask; + if (inStack(v)) { // I own it + *(Int32*)sp = 0; + return; + } + wl = monitors->enqueue(o); + } +} + +// unlocking a monitor which we must own. +// The algorithm is: +/* + 1. Pop the stack entry corresponding to this lock. If 0, then return. + 2. Otherwise, check the state *w of the object to see if it is busy, and + if so, spin. Otherwise, we check to see if we own the lock. If not, an + exception is thrown. + 3. finally, we try to swap back top into w, comparing with the pointer v. If + this fails, it is either because the monitor is busy, or the waiting bit is set + (the waiting bit resides outside the bitpattern for the pointer, and hence masking + the pointer with ~LockMask, will remove the waiting bit from 'v'). Then, dequeue() + is called, which will resume a thread if one exists, and release the monitor. + */ +void Monitor::unlock(JavaObject &o) +{ + Int32* w; + Int32 v,top; + +#ifdef DEBUG_ + PR_fprintf(PR_STDOUT,"\nT%x unlocking %x\n",PR_GetCurrentThread(),&o); +#endif + w = &o.state; + top = popStack(); + if (top == 0) + return; + while (true) { + v = *w; + if (v == 0) + continue; + v &= ~LockMask; + if (!inStack(v)) { + sysThrowNamedException("java/lang/IllegalMonitorStateException"); // doesn't return + return; + } + if (!cmpAndSwap(w,v,top)) + monitors->dequeue(o,top); + return; + } +} + +// locks the monitor part of object o for wait():s sake. +// This is a replica of lock() but where we don't save to the stack (done +// previously since we used to own this lock), and we don't check if we own +// the monitor because we don't (having just been wakened inside wait()). +// For more, see wait(). +void Monitor::wlock(JavaObject &o, Int32 sp) +{ + Int32* w; + Int32 v,wl=0; + +#ifdef DEBUG_ + PR_fprintf(PR_STDOUT,"\nT%x trying to w-lock %x\n",PR_GetCurrentThread(),&o); +#endif + w = &o.state; + while (true) { + v = *w; + if (v == 0) + continue; + if ((v&Unlocked) != 0) { // unlocked + sp |= wl; + if (cmpAndSwap(w,v,sp)) + return; + continue; // try again + } + wl = monitors->enqueue(o); + } +} + +// waits for someone to notify o within 'tim'. If we don't own the monitor, +// an exception is thrown. +void Monitor::wait(JavaObject &o, Int64 tim) +{ + Int32* w; + Int32 v, t; + + if (tim < 0) { + sysThrowNamedException("java/lang/IllegalArgumentException"); + return; + } + t = (Int32)tim; + w = &o.state; + while (true) { + v = *w; + if (v == 0) + continue; + v &= ~LockMask; + if (!inStack(v)) { + sysThrowNamedException("java/lang/IllegalMonitorStateException"); + return; + } +#ifdef DEBUG + PR_fprintf(PR_STDOUT,"About to wait for %d\n",t); +#endif + monitors->wait(o,v,t); +#ifdef DEBUG + PR_fprintf(PR_STDOUT,"finished waiting\n"); +#endif + return; + } +} + +// notifies someone waiting on o +void Monitor::notify(JavaObject &o) +{ + Int32* w; + Int32 v; + + w = &o.state; + while (true) { + v = *w; + if (v == 0) + continue; + v &= ~LockMask; + if (!inStack(v)) { + sysThrowNamedException("java/lang/IllegalMonitorStateException"); + return; + } + monitors->notify(o); + return; + } +} + +// notifies everyone waiting on o +void Monitor::notifyAll(JavaObject &o) +{ + Int32* w; + Int32 v; + + w = &o.state; + while (true) { + v = *w; + if (v == 0) + continue; + v &= ~LockMask; + if (!inStack(v)) { + sysThrowNamedException("java/lang/IllegalMonitorStateException"); + return; + } + monitors->notifyAll(o); + return; + } +} + +// reading a hash code is done as follows: +/* + 1. get a pointer to the object state slot, w. + 2. spin, if the monitor is busy. + 3. if the monitor is locked by someone then; + 3.1 if someone else owns it, make the monitor busy, and + read from the other thread's stack entry or the object itself (if it was + released while we are trying to read it). Then restore w back to non-busy. + 3.2 if we own it, read from our stack. + 4. if the hash value of the object is extended, get the value from the table. + Otherwise, shift it appropriately, and return that value. + */ +Int32 Monitor::hashRead(JavaObject& obj) { + Int32* w; + Int32 v, ov; + + w = &obj.state; + while (true) { + v = *w; + if (v == 0) + continue; + if ((v&Unlocked) == 0) { // locked by someone + v &= ~LockMask; + if (!inStack(v)) { // some other thread + while ((ov = exchange(w,0)) == 0) // make it busy + ; + if ((ov&Unlocked) == 0) + v = *(Int32*)(ov & ~LockMask); + else + v = ov; + *w = ov; + } + else // current thread + v = *(Int32*)v; + } + if ((v&XHash) == 0) + return v>>KeyShift; + else + return monitors->hashGet(v); + } +} + +// writing a hash code is done as: +/* + 1. decide if we need to allocate an extended code, and if so, + allocate an entry optimistically. + 2. make the monitor busy. + 3. if the monitor is locked: + 3.1. if the value is still unset, update the stack entry with the new code. + 3.2 If set, deallocate the new code since we don't need it then. + 4. if unlocked, then update the old value. + 5. finally, write back the old value. + */ +void Monitor::hashWrite(JavaObject& obj, Int32 k) { + Int32* w; + Int32 ov, v; + + w = &obj.state; + if (k >= (1<hashAdd(k) | XHash; + else + k = (k<hashRemove(k); + } + else // unlocked + ov = k; + *w = ov; +} + +Int32 Monitor::hashCode(JavaObject& obj) { + Int32 v = hashRead(obj); + if (v == 0) { + v = monitors->nextHash(); + hashWrite(obj,v); + } + return v; +} + +// Monitors:: +template +Monitors::Monitors(int l) : pool(), cacheNext(0), taken(NULL), stateNext(1), hashNext(1), hashVecTop(0), hashVecSize(64) { + int i; + PRStatus stat; + + if (l > 10000) + sysThrowNamedException("java/lang/IllegalArgumentException"); + free = newList(l); + _lock = PR_NewLock(); + table = new PointerHashTable(pool); + for (i=0; i +Monitors::~Monitors() { + delete table; + PR_DestroyLock(_lock); +} + +template +M* Monitors::allocate(JavaObject& o) { + M* m; + if (free == NULL) + free = newList(10); + m = free; + m->init(o); + free = free->next; + m->next = taken; + m->prev = NULL; + if (taken != NULL) + taken->prev = m; + taken = m; + return m; +} + +template +void Monitors::deallocate(M* m) { + if (m->prev != NULL) + m->prev->next = m->next; + if (m->next != NULL) + m->next->prev = m->prev; + if (m == taken) + taken = m->next; + m->next = free; + free = m; +} + +template +M* Monitors::newList(int l) { + M* m; + M* m0; + assert(l>0); + m0 = m = new(pool) M; + for (int i=1; inext = new(pool) M; + m = m->next; + } + return m0; +} + +template +int Monitors::enqueue(JavaObject& o) { + M* m; + + // enqueue does ALL the deallocation of fat monitors, so that if a monitor + // is released in unlock()/dequeue() we deallocate it when waking up. + // we must deal with two cases: + // (i) we must suspend, and thus we might need to allocate a monitor object + // (ii) the object was just released, and we thus go back to lock() and try again + Int32* w = &o.state; + Int32 v = *w; + if (v!=0 && // not busy + (v&Monitor::Unlocked) == 0 && // still locked + Monitor::cmpAndSwap(w,v,v|Monitor::Waiting)) { // swap in waiting bit + lock(); // now allocate a fat monitor + if ((m = getObject(o)) == NULL) { + m = allocate(o); + addObject(o,m); + } + unlock(); +#ifdef DEBUG + PR_fprintf(PR_STDOUT,"\n T%x going to sleep on %x (%d)\n",PR_GetCurrentThread(),w,*w&Monitor::LockMask); +#endif + // puts current thread to sleep. Tries locking again at wakeup. + // suspend and resume are sticky, so that if the lock was released while we + // were trying to suspend, we return immediately (see MonitorObject::suspend()). + if (!m->suspend()) { // if failure, it was interrupted + if (m->empty()) { // no more state. Deallocate monitor + deallocate(m); + removeObject(o); + } + sysThrowNamedException("java/lang/InterruptedException"); + return 0; // never reached + } +#ifdef DEBUG + PR_fprintf(PR_STDOUT,"\n T%x waking up at %x (%d)\n",PR_GetCurrentThread(),w,*w&Monitor::LockMask); +#endif + v = 0; + if (m->empty()) { // no more state. Deallocate monitor + deallocate(m); + removeObject(o); + } + else if (m->isSuspended()) + v = Monitor::Waiting; // return waiting bit to lock() to preserve it + return v; + } + return 0; +} + +// dequeue looks for a fat monitor for o, and if one is found, it resumes it. +// This sticks, so that a concurrent suspend will return immediately if the resume +// beats it. Finally, the monitor is released by putting back the old value in, +// which was picked up from the stack ('top' in unlock()). +template +void Monitors::dequeue(JavaObject& o,Int32 v) { + M* m; + Int32 ov; + Int32* w = &o.state; + + do + ov = *w; + while (ov == 0 || !Monitor::cmpAndSwap(w,ov,v)); // release it + lock(); + if ((m = getObject(o)) != NULL) { + m->resume(); // wake a suspended thread + } + else if ((ov & Monitor::Waiting) != 0) { + // this is if enqueue() didn't make the lock() and suspend() before we got called + m = allocate(o); + addObject(o,m); + m->resume(); + } + unlock(); +} + +// wait() allocates a fat monitor if necessary. Then reads back the old +// value from the stack, releases the monitor, resumes a suspended thread, +// puts itself to sleep (which might return immediately if there is a pending +// resume). At wakeup, it tries to reacquire the lock, using the still valid stack pointer. +template +void Monitors::wait(JavaObject& o, Int32 sp, Int32 tim) { + M* m; + Int32 ov, v; + Int32* w; + + w = &o.state; + v = *(Int32*)sp; + do + ov = *w; + while (ov == 0 || !Monitor::cmpAndSwap(w,ov,v)); // release it + lock(); + if ((m = getObject(o)) == NULL) { + m = allocate(o); + addObject(o,m); + } + unlock(); + m->resume(); // resume a suspended thread + if (!m->wait(tim)) { // if failure, it was interrupted + if (m->empty()) { // no more state. Deallocate monitor + deallocate(m); + removeObject(o); + } + sysThrowNamedException("java/lang/InterruptedException"); + return; // never reached + } + Monitor::wlock(o,sp); +} + +template +void Monitors::notify(JavaObject& o) { + M* m; + + lock(); + if ((m = getObject(o)) == NULL) { + m = allocate(o); + addObject(o,m); + } + unlock(); + m->notify(); + return; +} + +template +void Monitors::notifyAll(JavaObject& o) { + M* m; + + lock(); + if ((m = getObject(o)) == NULL) { + m = allocate(o); + addObject(o,m); + } + unlock(); + m->notifyAll(); + return; +} + +template +void Monitors::addObject(JavaObject& o, M* m) { + Int32* w = &o.state; + keyCache[cacheNext] = &o.state; + valCache[cacheNext] = m; + cacheNext = (cacheNext+1)%cacheSize; + table->add(reinterpret_cast(w), m); +} + +template +M* Monitors::getObject(JavaObject& o) { + M* m; + int i; + Int32* w = &o.state; + + for (i=0; iget(reinterpret_cast(w),&m)) + return m; + else + return NULL; +} + +template +void Monitors::removeObject(JavaObject& o) { + int i; + Int32* w = &o.state; + + for (i=0; iremove(reinterpret_cast(w)); +} + +template +Int32 Monitors::hashGet(Int32 i) { + lock(); + Int32 k = hashVec[i>>Monitor::KeyShift]; + unlock(); + return k; +} + +template +Int32 Monitors::hashAdd(Int32 k) { + assert(k >= (1< 0; ) + hashVec[i] = oldVec[i]; + i = hashVecSize; + hashVecSize *= 2; + } + unlock(); + hashVec[i] = k; + return i< +void Monitors::hashRemove(Int32 i) { + lock(); + if ((i>>Monitor::KeyShift) == hashVecTop-1) + hashVecTop--; + unlock(); +} + +template +Int32 Monitors::nextHash() { + lock(); + int hN = hashNext++; + unlock(); + return hN; +} + +// These are only in here until we have the stack entries for monitors +// in place. +template +Int32 Monitors::pushStack() { + Int32* a = (Int32*)PR_GetThreadPrivate(thr_stack); + int i = (int)PR_GetThreadPrivate(thr_top); + + if (i==256) + return 0; + PR_SetThreadPrivate(thr_top,(void*)(i+1)); + return (Int32)&a[i]; +} + +template +Int32 Monitors::popStack() { + Int32* a = (Int32*)PR_GetThreadPrivate(thr_stack); + int i = (int)PR_GetThreadPrivate(thr_top); + PR_SetThreadPrivate(thr_top,(void*)(i-1)); + return a[i-1]; +} + +template +inline bool Monitors::inStack(Int32 sp) { // for now + Int32* a = (Int32*)PR_GetThreadPrivate(thr_stack); + return (Int32)&a[0] <= sp && sp < (Int32)&a[256]; +} diff --git a/ef/Runtime/System/Monitor.h b/ef/Runtime/System/Monitor.h new file mode 100644 index 000000000000..941f3257457e --- /dev/null +++ b/ef/Runtime/System/Monitor.h @@ -0,0 +1,326 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#ifndef _EF_MONITORS +#define _EF_MONITORS + +#include "JavaObject.h" +#include "HashTable.h" +#include "prtypes.h" +#include "pratom.h" +#include "prlock.h" +#include "prcvar.h" +#include "prthread.h" + +struct PointerKeyOps { + static bool equals(void* userKey, void* hashTableKey) { + return (userKey == hashTableKey); + } + + static void* copyKey(Pool &/*pool*/, void* userKey) { + return userKey; + } + + static Uint32 hashCode(void* userKey) { + return reinterpret_cast(userKey); + } +}; + +template +class PointerHashTable : public HashTable { +public: + PointerHashTable(Pool &p) : HashTable(p) { } +}; + +struct MonitorArgStruct { // for debugging + void (*f)(void*); + void* arg; +}; + +class NS_EXTERN Monitor { +public: + enum { + KeySize=30, + KeyShift=32-KeySize, + KeyMask=0xFFFFFFFC, // '1...1100' + LockMask=0x3, + XHash=0x2, + Waiting=0x2, // w-flag when object is locked + IHash=0x1, + Unlocked=0x1 + }; + + class Exception {}; + + static inline bool cmpAndSwap(Int32* w, Int32 ov, Int32 nv); + + static inline Int32 exchange(Int32* w, Int32 v) { + return (Int32)PR_AtomicSet((PRInt32*)w,(PRInt32)v); + } + + static inline bool inStack(Int32 v); + + static inline Int32 pushStack(); + + static inline Int32 popStack(); + + static void threadInit(); + + static void lock(JavaObject& o); + + static void unlock(JavaObject& o); + + static void wlock(JavaObject& o, Int32 sp); + + static void wait(JavaObject& o, Int64 tim); + + static inline void wait(JavaObject& o) { + wait(o, PR_INTERVAL_NO_TIMEOUT); + } + + static void notify(JavaObject& o); + + static void notifyAll(JavaObject& o); + + static void staticInit(); + + static void destroy(); + + static inline void run(void* arg) { // for debugging + MonitorArgStruct* mas = (MonitorArgStruct*)arg; +#if 0 + DWORD handler = (DWORD)NULL;//*win32HardwareThrow; + __asm + { + push handler + push fs:[0] + mov fs:[0],esp + } + threadInit(); + mas->f(mas->arg); + __asm { + mov eax,[esp] // old fs:[0] + mov fs:[0],eax + add esp,8 + } +#else + threadInit(); + mas->f(mas->arg); +#endif + } + + static void hashWrite(JavaObject& obj, Int32 k); + + static Int32 hashRead(JavaObject& obj); + + static Int32 hashCode(JavaObject& obj); +}; + +struct MonitorObject { + JavaObject* obj; + Int32 susp; + Int32 _wait; + PRLock* slock; + PRCondVar* svar; + PRLock* wlock; + PRCondVar* wvar; +public: + class Exception {}; + MonitorObject* next; + MonitorObject* prev; + + MonitorObject() : obj(NULL), susp(0), _wait(0), next(NULL), prev(NULL) { + slock = PR_NewLock(); svar = PR_NewCondVar(slock); + wlock = PR_NewLock(); wvar = PR_NewCondVar(wlock); + } + + ~MonitorObject() { + PR_DestroyLock(slock); PR_DestroyCondVar(svar); + PR_DestroyLock(wlock); PR_DestroyCondVar(wvar); + } + + inline void init(JavaObject& o) { + next=NULL; obj = &o; + susp = 0; _wait = 0; + } + + inline bool empty() { + return _wait == 0 && susp == 0; + } + + inline bool isSuspended() { + return susp > 0; + } + + inline bool suspend() + { + PRStatus stat; + PR_Lock(slock); + susp++; + if (susp<1) { + PR_Unlock(slock); + return true; + } + stat = PR_WaitCondVar(svar,PR_INTERVAL_NO_TIMEOUT); + if (stat == PR_FAILURE) { + susp--; + return false; + } + PR_Unlock(slock); + return true; + } + + inline void resume() + { + PRStatus stat; + PR_Lock(slock); + susp--; + stat = PR_NotifyCondVar(svar); + assert(stat != PR_FAILURE); + PR_Unlock(slock); + } + + inline bool wait(Int32 tim) + { + PRStatus stat; + PR_Lock(wlock); + _wait++; + if (_wait<1) { + PR_Unlock(wlock); + return true; + } + stat = PR_WaitCondVar(wvar,(tim == 0 ? PR_INTERVAL_NO_TIMEOUT : PR_MillisecondsToInterval(tim))); + if (stat == PR_FAILURE) { + _wait--; + return false; + } + PR_Unlock(wlock); + return true; + } + + inline void notify() + { + PRStatus stat; + PR_Lock(wlock); + _wait--; + stat = PR_NotifyCondVar(wvar); + assert(stat != PR_FAILURE); + PR_Unlock(wlock); + } + + inline void notifyAll() + { + PR_Lock(wlock); + _wait--; // Is this right? + PR_NotifyAllCondVar(wvar); + PR_Unlock(wlock); + } +}; + +template +class Monitors { +private: + PRUintn thr_stack; // temporary + PRUintn thr_top; // ditto + PRLock* _lock; + M* free; // for allocation + M* taken; // for deallocation and cleanup + M* newList(int l); + Pool pool; + PointerHashTable* table; + enum { cacheSize=4 }; // must be even!!! + Int32* keyCache[cacheSize]; + M* valCache[cacheSize]; + Int32* hashVec; + int cacheNext; + int stateNext; + int hashNext; + int hashVecTop; + int hashVecSize; + + inline Int32* threadVec() { + Int32* a; + a = new(pool) Int32[256]; + for (int i=0; i<256; i++) + a[i] = -1; + return a; + } + + inline void threadInit() { + PRStatus stat; + + stat = PR_SetThreadPrivate(thr_stack, (void *)threadVec()); + assert(stat != PR_FAILURE); + stat = PR_SetThreadPrivate(thr_top, (void *)0); + assert(stat != PR_FAILURE); + } + + friend void Monitor::threadInit(); + +public: + + class Exception {}; + + Monitors(int l); + + ~Monitors(); + + M* allocate(JavaObject& o); + + void deallocate(M* m); + + inline void lock() { + PR_Lock(_lock); + } + + inline void unlock() { + PR_Unlock(_lock); + } + + int enqueue(JavaObject& o); + + void dequeue(JavaObject& o, Int32 v); + + void wait(JavaObject& o, Int32 sp, Int32 tim); + + void notify(JavaObject& o); + + void notifyAll(JavaObject& o); + + M* getObject(JavaObject& o); + + void addObject(JavaObject& o, M* m); + + void removeObject(JavaObject& o); + + inline bool inStack(Int32 v); + + inline Int32 pushStack(); + + inline Int32 popStack(); + + Int32 hashGet(Int32 k); + + Int32 hashAdd(Int32 k); + + void hashRemove(Int32 k); + + Int32 nextHash(); +}; + +extern Monitors* monitors; +#endif diff --git a/ef/Runtime/System/StackWalker.cpp b/ef/Runtime/System/StackWalker.cpp new file mode 100644 index 000000000000..4e443f2cf423 --- /dev/null +++ b/ef/Runtime/System/StackWalker.cpp @@ -0,0 +1,238 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +// +// StackWalker.cpp +// +// Simon Holmes a Court +// Scott M. Silver +// + +// Routines for walking and printing out the stack. +// +// Interesting debug routines are listed at the end of this function + +#include "Fundamentals.h" +#include "StackWalker.h" + + +// Assembly guff to return the EBP +#ifdef _WIN32 +#define INLINE_GET_EBP(inEBPVariableName) __asm mov inEBPVariableName, ebp +#elif defined(LINUX) +#define INLINE_GET_EBP(inEBPVariableName) __asm__ ("movl %%ebp,%0" : "=g" (inEBPVariableName) : /* no inputs */) +#else +#define INLINE_GET_EBP(inEBPVariableName) inEBPVariableName = 0 +#endif + + +// Frame +// +// ACHTUNG ADVENTURER: Be careful of changing the inlining +// of this constructor, it assumes it is called on real frame down +// from the scope where the Frame object is. +Frame:: +Frame() +{ + Uint8 **foo; + INLINE_GET_EBP(foo); // inline assembly to grab our base pointer + pFrame = foo; + + // skip over the constructor frame and return the caller's frame + moveToPrevFrame(); +} + + +// moveToPrevFrame +// +// Set the cursor for this frame to the previous frame +void Frame:: +moveToPrevFrame() +{ + pMethodAddress = (Uint8*) *(pFrame + 1); + pFrame = (Uint8**) *pFrame; +} + +// Compute the number of stack frames on the stack +int Frame:: +getStackDepth() +{ + Frame frame; + int depth = -1; + do { + frame.moveToPrevFrame(); + depth++; + } while (frame.getBase()); + return depth; +} + +// getCallingJavaMethod +// +// Move the cursor of this frame to the closest Java frame and +// return the method corresponding to that frame +Method &Frame::getCallingJavaMethod() +{ + Method *m; + + do { + m = 0; + + while (!m) { + pMethodAddress = (Uint8*) *(pFrame + 1); + pFrame = (Uint8**) *pFrame; + m = getMethodForPC(pMethodAddress); + } + + } while ((m->getModifiers() & CR_METHOD_NATIVE)); + + return *m; +} + + +// getMethod +// +// get Method* or NULL associated with this Frame +Method* Frame:: +getMethod() +{ + return (getMethodForPC(pMethodAddress)); +} + + +// getCallerPC +// +// Return the address of the function that called the getCallerPC +extern Uint8* getCallerPC() +{ +#if defined(WIN32) || defined(LINUX) + Uint8** myEBP; + + INLINE_GET_EBP(myEBP); + + Uint8** calleeEBP = (Uint8**) *myEBP; // get the callee's EBP + Uint8* retAddress = (Uint8*) *(calleeEBP + 1); + return retAddress; +#else // WIN32 || LINUX + return 0; +#endif +} + + +// setCalleeReturnAddress +// +// change the return address of the callee's callee to the passed in pointer +// FIX-ME huh?? +extern void setCalleeReturnAddress(Uint8* retAddress) +{ +#ifdef WIN32 + Uint8** myEBP; + INLINE_GET_EBP(myEBP); // myEBP is the EBP of getCallerPC + Uint8** calleeEBP = (Uint8**) *myEBP; // get the callee's EBP + (Uint8*) *(calleeEBP + 1) = retAddress; +#else // non WIN32 + retAddress; + trespass("not implemented"); +#endif +} + +// getMethodForPC +// +// Return Method* or NULL associated with this PC +extern Method* getMethodForPC(void* inCurPC) +{ + CacheEntry* ce = NativeCodeCache::getCache().lookupByRange((Uint8*) inCurPC); + + return (ce ? ce->descriptor.method : 0); +} + + +#ifdef DEBUG_LOG +UT_DEFINE_LOG_MODULE(StackWalker); + +extern "C" +void NS_EXTERN stackWalker(void* inCurPC) +{ + UT_SET_LOG_LEVEL(StackWalker, PR_LOG_DEBUG); + + UT_LOG(StackWalker, PR_LOG_ALWAYS, ("\n\n_____________________Top of stack______________________\n")); + UT_LOG(StackWalker, PR_LOG_ALWAYS, ("%10s %10s\n", " Frame", "Return Addr")); + + if (inCurPC) + Frame::printOne(UT_LOG_MODULE(StackWalker), 0, inCurPC); + + Frame frame; + do + { + frame.print(UT_LOG_MODULE(StackWalker)); + frame.moveToPrevFrame(); + } + while (frame.hasPreviousFrame()); + + UT_LOG(StackWalker, PR_LOG_ALWAYS, ("____________________Bottom of Stack____________________\n\n")); +} + + +#include "prprf.h" + +void Frame:: +printWithArgs(LogModuleObject &f, Uint8* inFrame, Method* inMethod) +{ + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("%s(", inMethod->toString())); + + const Signature& ourSignature = inMethod->getSignature(); + Uint16 numArgs = ourSignature.nArguments; + const Type** ourArgs = ourSignature.argumentTypes; + + // calc arg size + Uint16 i; + Uint8* argListPtr = ((Uint8*) inFrame + 8); // just beyond first argument + + for(i = 0; i < numArgs; i++) + { + if (inFrame) + printValue(f, argListPtr, *ourArgs[i]); + else + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("")); + argListPtr += nTypeKindSlots(ourArgs[i]->typeKind) * 4; + if(i < (numArgs - 1)) + UT_OBJECTLOG(f, PR_LOG_ALWAYS, (", ")); + } + + UT_OBJECTLOG(f, PR_LOG_ALWAYS, (")")); +} + +void Frame:: +printOne(LogModuleObject &f, void* inFrame, void* inMethodAddress) +{ + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("0x%08x (0x%08x) ", inFrame, inMethodAddress)); + + Method* method = getMethodForPC(inMethodAddress); + + if(method) + printWithArgs(f, (Uint8*)inFrame, method); + else + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("anonymous")); + + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("\n")); +} + +void Frame:: +print(LogModuleObject &f) +{ + printOne(f, pFrame, pMethodAddress); +} +#endif diff --git a/ef/Runtime/System/StackWalker.h b/ef/Runtime/System/StackWalker.h new file mode 100644 index 000000000000..83add5f00344 --- /dev/null +++ b/ef/Runtime/System/StackWalker.h @@ -0,0 +1,63 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +// +// StackWalker.h +// +// Simon Holmes a Court + + +#ifndef _STACK_WALKER_ +#define _STACK_WALKER_ + +#include "Fundamentals.h" +#include "NativeCodeCache.h" +#include "LogModule.h" + +class NS_EXTERN Frame +{ +private: + Uint8** pFrame; // pointer to the EBP + Uint8* pMethodAddress; // holds an address within the method + +public: + Frame(); + void moveToPrevFrame(); + bool hasPreviousFrame() { return (pFrame != NULL && *pFrame != NULL); } + Uint8** getBase() { return pFrame; } + static int getStackDepth(); + + Method &getCallingJavaMethod(); + + // returns the Method associated with the frame, or NULL if there is not one + Method* getMethod(); + + #ifdef DEBUG + void print(LogModuleObject &f); + static void printWithArgs(LogModuleObject &f, Uint8* inFrame, Method* inMethod); + static void printOne(LogModuleObject &f, void*, void*); + #endif +}; + + +extern "C" void NS_EXTERN stackWalker(void*); +extern Uint8* getCallerPC(); +extern void setCalleeReturnAddress(Uint8* retAddress); +extern Method* getMethodForPC(void* inCurPC); + + +#endif // _STACK_WALKER_ diff --git a/ef/Runtime/System/SysCallsRuntime.cpp b/ef/Runtime/System/SysCallsRuntime.cpp new file mode 100644 index 000000000000..e236630fd2cd --- /dev/null +++ b/ef/Runtime/System/SysCallsRuntime.cpp @@ -0,0 +1,308 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#include "SysCalls.h" +#include "JavaObject.h" +#include +#include +#include "Monitor.h" +#include "Exceptions.h" + +#include "ErrorHandling.h" +#include "JavaVM.h" + +extern "C" { + +// +// Create a new object of the indicated size +// +SYSCALL_FUNC(void*) sysNew(const Class &inClass) +{ + return (&const_cast(&inClass)->newInstance()); +} + +// +// If test is true then throw a NegativeArraySizeException +// +inline void throwNegativeArraySizeExceptionIf(bool test) +{ + if (test) { + JavaObject& exception = const_cast(&Standard::get(cNegativeArraySizeException))->newInstance(); + sysThrow(exception); + } +} + +SYSCALL_FUNC(void *) sysNewPrimitiveArray(TypeKind tk, Int32 length) +{ + throwNegativeArraySizeExceptionIf(length < 0); + + void *mem = calloc(arrayEltsOffset(tk) + getTypeKindSize(tk)*length, 1); + return (new (mem) JavaArray(Array::obtain(tk), length)); +} + +// +// Create a new array of Java ints +// +SYSCALL_FUNC(void*) sysNewIntArray(Int32 length) +{ + return sysNewPrimitiveArray(tkInt, length); +} + +// +// Throw an Exception +// +#if !defined(_WIN32) && !defined(LINUX) + +SYSCALL_FUNC(void) sysThrow(const JavaObject& /* inObject */) +{ + trespass("\n *** Throw is unimplemented on this platform ***\n"); +} + +#endif + +// +// Create a new array of Java chars +// +SYSCALL_FUNC(void *) sysNewCharArray(Int32 length) +{ + return sysNewPrimitiveArray(tkChar, length); +} + +// +// Create a new array of Java bytes +// +SYSCALL_FUNC(void *) sysNewByteArray(Int32 length) +{ + return sysNewPrimitiveArray(tkByte, length); +} + +SYSCALL_FUNC(void) sysCheckArrayStore(const JavaArray *arr, const JavaObject *obj) +{ + /* Legal to assign a null reference to an array */ + if (!obj) + return; + + /* Make sure that the type of obj is the same as that of the component + * type of the array arr + */ + const Type *componentType = &(static_cast(&arr->getType()))->componentType; + const Type *objType = &obj->getType(); + bool ret; + + if (isPrimitiveKind(componentType->typeKind)) + ret = (componentType == objType); + else + ret = implements(*objType, *componentType); + + if (!ret) + sysThrowNamedException("java/lang/ArrayStoreException"); +} + +SYSCALL_FUNC(void) sysMonitorEnter(JavaObject *obj) +{ + if (obj == NULL) + sysThrowNamedException("java/lang/NullPointerException"); + Monitor::lock(*obj); +} + +SYSCALL_FUNC(void) sysMonitorExit(JavaObject * obj) +{ + if (obj == NULL) + sysThrowNamedException("java/lang/NullPointerException"); + Monitor::unlock(*obj); +} + +// +// Create a new array of Java booleans +// +SYSCALL_FUNC(void*) sysNewBooleanArray(Int32 length) +{ + return sysNewPrimitiveArray(tkBoolean, length); +} + +// +// Create a new array of Java shorts +// +SYSCALL_FUNC(void*) sysNewShortArray(Int32 length) +{ + return sysNewPrimitiveArray(tkShort, length); +} + +// +// Create a new array of Java longs +// +SYSCALL_FUNC(void*) sysNewLongArray(Int32 length) +{ + return sysNewPrimitiveArray(tkLong, length); +} + +SYSCALL_FUNC(void *) sysNewFloatArray(Int32 length) +{ + return sysNewPrimitiveArray(tkFloat, length); +} + +SYSCALL_FUNC(void *) sysNewDoubleArray(Int32 length) +{ + return sysNewPrimitiveArray(tkDouble, length); +} + +// +// Create a new array of Java objects +// +SYSCALL_FUNC(void *) sysNewObjectArray(const Type *type, Int32 length) +{ + throwNegativeArraySizeExceptionIf(length < 0); + const Array &typeOfArray = type->getArrayType(); + void *mem = calloc(arrayObjectEltsOffset + getTypeKindSize(tkObject)*length, 1); + return (new (mem) JavaArray(typeOfArray, length)); +} + +SYSCALL_FUNC(void *) sysNew2DArray(const Type *type, Int32 length1, Int32 length2) +{ + throwNegativeArraySizeExceptionIf(length1 < 0 || length2 < 0); + + const Array &arrayType = asArray(*type); + const Array &componentType = asArray(arrayType.componentType); + const Type &elementType = componentType.componentType; + + JavaArray* newArray = (JavaArray *) sysNewObjectArray(&componentType, length1); + + JavaArray** elements = (JavaArray **) ((char *) newArray+arrayObjectEltsOffset); + for (Int32 i = 0; i < length1; i++) + elements[i] = (JavaArray *) sysNewObjectArray(&elementType, length2); + + return (void*) newArray; +} + + +SYSCALL_FUNC(void*) sysNew3DArray(const Type *type, Int32 length1, Int32 length2, Int32 length3) +{ + throwNegativeArraySizeExceptionIf(length1 < 0 || length2 < 0 || length3 < 0); + + const Array &arrayType = asArray(*type); + const Array &componentType = asArray(arrayType.componentType); + const Array &componentComponentType = asArray(componentType.componentType); + const Type &elementType = componentComponentType.componentType; + + JavaArray* newArray = (JavaArray *) sysNewObjectArray(&componentType, length1); + + JavaArray** elements = (JavaArray **) (((char *) newArray)+arrayObjectEltsOffset); + for (Int32 i = 0; i < length1; i++) { + elements[i] = (JavaArray *) sysNewObjectArray(&componentComponentType, length2); + + JavaArray** elementElements = (JavaArray **) ((char *) (elements[i])+arrayObjectEltsOffset); + for (Int32 j = 0; j < length2; j++) + elementElements[j] = (JavaArray *) sysNewObjectArray(&elementType, length3); + } + + return (void*) newArray; +} + +SYSCALL_FUNC(void*) sysNewNDArray(const Type *type, JavaArray* lengthsArray) +{ + struct StackEntry { + JavaArray* array; + Int32 index; + }; + + Int32* lengths = (Int32*) ((char *) lengthsArray + arrayObjectEltsOffset); + Int32 nDimensions = lengthsArray->length; + + // FIX: replace this by mem from gc. + StackEntry* stack = (StackEntry*) calloc(sizeof(StackEntry),nDimensions); + StackEntry* stackPtr = stack; + + for (Uint8 i = 0; i < nDimensions; i++) + throwNegativeArraySizeExceptionIf(lengths[i] < 0); + + JavaArray* newArray = (JavaArray *) sysNewObjectArray(&asArray(*type).componentType, lengths[0]); + + // start the stack. + stackPtr->array = newArray; + stackPtr->index = 0; + + while (stackPtr >= stack) { + // get the current entry. + StackEntry& entry = *stackPtr; + + // depth of this entry. + Uint8 depth = stackPtr - stack; + JavaArray* array = entry.array; + Int32 index = entry.index++; + + if (index < lengths[depth]) { + // create element array[index]. + JavaArray** elements = (JavaArray**) ((char *) array+arrayObjectEltsOffset); + elements[index] = (JavaArray *) sysNewObjectArray(&asArray(array->getType()).componentType, lengths[depth + 1]); + + if (depth < (nDimensions - 2)) { + // push the new element and start over. + ++stackPtr; + stackPtr->index = 0; + stackPtr->array = elements[index]; + } + } else { + // we are done with this array. + --stackPtr; + } + } + return (void *) newArray; +} + +/* Throw an object of the type specified by fully qualified exception name */ +NS_EXTERN SYSCALL_FUNC(void) sysThrowNamedException(const char *exceptionName) +{ + const Class *clazz = static_cast(VM::getCentral().addClass(exceptionName).getThisClass()); + + /* Ensure that named class is a sub-class of java/lang/Exception */ +#ifdef DEBUG + const Class *excClazz = static_cast(VM::getCentral().addClass("java/lang/Exception").getThisClass()); + + assert(excClazz->isAssignableFrom(*clazz)); +#endif + + sysThrow(const_cast(clazz)->newInstance()); +} + + +/* Use the following from jitted code directly only if + * you're on a platform that does *not* need stubs + * to call native code + */ +#if !(defined _WIN32) && !(defined LINUX) +SYSCALL_FUNC(void) sysThrowNullPointerException() +{ + sysThrow(const_cast(&Standard::get(cNullPointerException))->newInstance()); +} + +SYSCALL_FUNC(void) sysThrowArrayIndexOutOfBoundsException() +{ + sysThrow(const_cast(&Standard::get(cArrayIndexOutOfBoundsException))->newInstance()); +} + +SYSCALL_FUNC(void) sysThrowClassCastException() +{ + sysThrow(const_cast(&Standard::get(cClassCastException))->newInstance()); +} + +static SYSCALL_FUNC(void) sysThrowIllegalMonitorStateException() +{ + sysThrow(const_cast(&Standard::get(cIllegalMonitorStateException))->newInstance()); +} + +#endif +} diff --git a/ef/Runtime/System/SysCallsRuntime.h b/ef/Runtime/System/SysCallsRuntime.h new file mode 100644 index 000000000000..9cfd9623ffd1 --- /dev/null +++ b/ef/Runtime/System/SysCallsRuntime.h @@ -0,0 +1,65 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#ifndef _SYSCALLS_RUNTIME_H_ +#define _SYSCALLS_RUNTIME_H_ + +#include "Fundamentals.h" + +#define SYSCALL_FUNC(inReturnType) NS_NATIVECALL(inReturnType) + +/* Implementation of sysCalls needed by the runtime. */ + +extern "C" { + +NS_EXTERN SYSCALL_FUNC(void) sysThrow(const JavaObject &inObject); + +NS_EXTERN SYSCALL_FUNC(void) sysCheckArrayStore(const JavaArray *arr, const JavaObject *obj); + +NS_EXTERN SYSCALL_FUNC(void) sysMonitorExit(JavaObject *obj); +NS_EXTERN SYSCALL_FUNC(void) sysMonitorEnter(JavaObject *obj); + +NS_EXTERN SYSCALL_FUNC(void*) sysNew(const Class &inClass); + +NS_EXTERN SYSCALL_FUNC(void*) sysNewNDArray(const Type *type, JavaArray* lengths); +NS_EXTERN SYSCALL_FUNC(void*) sysNew3DArray(const Type *type, Int32 length1, Int32 length2, Int32 length); +NS_EXTERN SYSCALL_FUNC(void*) sysNew2DArray(const Type *type, Int32 length1, Int32 length2); + +NS_EXTERN SYSCALL_FUNC(void*) sysNewByteArray(Int32 length); +NS_EXTERN SYSCALL_FUNC(void*) sysNewCharArray(Int32 length); +NS_EXTERN SYSCALL_FUNC(void*) sysNewIntArray(Int32 length); +NS_EXTERN SYSCALL_FUNC(void*) sysNewLongArray(Int32 length); +NS_EXTERN SYSCALL_FUNC(void*) sysNewShortArray(Int32 length); +NS_EXTERN SYSCALL_FUNC(void*) sysNewBooleanArray(Int32 length); +NS_EXTERN SYSCALL_FUNC(void*) sysNewDoubleArray(Int32 length); +NS_EXTERN SYSCALL_FUNC(void*) sysNewFloatArray(Int32 length); +NS_EXTERN SYSCALL_FUNC(void*) sysNewObjectArray(const Type *type, Int32 length); + +// The following are not called directly from primitives +NS_EXTERN SYSCALL_FUNC(void *) sysNewPrimitiveArray(TypeKind tk, Int32 length); + +NS_EXTERN SYSCALL_FUNC(void) sysThrowNullPointerException(); +NS_EXTERN SYSCALL_FUNC(void) sysThrowArrayIndexOutOfBoundsException(); +NS_EXTERN SYSCALL_FUNC(void) sysThrowClassCastException(); +NS_EXTERN SYSCALL_FUNC(void) sysThrowArrayStoreException(); + +NS_EXTERN SYSCALL_FUNC(void) sysThrowNamedException(const char *name); + +} + +#endif /* _SYSCALLS_RUNTIME_H_ */ diff --git a/ef/Runtime/System/Thread.cpp b/ef/Runtime/System/Thread.cpp new file mode 100644 index 000000000000..71a60f58d1d0 --- /dev/null +++ b/ef/Runtime/System/Thread.cpp @@ -0,0 +1,445 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +// Thread.cpp +// +// Bjorn Carlson + +#include "Thread.h" +#include "Exceptions.h" +#include "NativeCodeCache.h" +#include "prprf.h" +#include "SysCallsRuntime.h" + +#ifdef _WIN32 + +#include "md/x86/x86Win32Thread.h" + +#elif defined(__linux__) + +#include "x86LinuxThread.h" + +#else + +#define GetPassedException(E) + +void Thread::realHandle() {} + +void Thread::invoke(Method* m,JavaObject* obj,JavaObject* arr[],int sz) { + m->invoke(obj,arr,sz); +} + +void _suspendThread(HANDLE /*p*/) {} + +void _resumeThread(HANDLE /*p*/) {} + +bool _getThreadContext(HANDLE /*handle*/, ThreadContext& /*context*/) { return false; } + +void _setThreadContext(HANDLE /*handle*/, ThreadContext& /*context*/) {} + +Int32* _getFramePointer(ThreadContext& /*context*/) { return NULL; } + +void _setFramePointer(ThreadContext& /*context*/, Int32* /*v*/) {} + +Uint8* _getInstructionPointer(ThreadContext& /*context*/) { return NULL; } + +void _setInstructionPointer(ThreadContext& /*context*/, Uint8* /*v*/) {} + +#endif + +Pool* Thread::pool; +PointerHashTable* Thread::table; + +/* + We support threads in C++ as follows. Every instance of java.lang.Thread has a corresponding C++ peer. + The peer represent all the low-level information we need to implement the native calls for Java threads, + and is used to bridge between Java threads and native (NSPR/Win32/Solaris/...) threads. Most native + methods (see Thread.cpp in Packages/java/lang/) check if the C++ instance has been creates and if not + it is created on the fly (right now from Thread::pool). + + Every instance of java.lang.Thread has a property 'eetop' of type Int64 which is only used for native + access to the thread object. We store a pointer to the C++ peer in 'eetop'. Hence, all native methods + required by java.lang.Thread can pick up the peer using this field (see Thread.cpp in Packages/java/lang/). + + For every thread that we create, we keep a mapping between its identifier and the C++ object representing it. + This is added in Thread::run() (see below). +*/ + +/* + This is the static initializer for threads. It initializes the global structurs + used by the C++ methods in here, and creates a Java object, 'obj', of class java.lang.Thread + to represent the main thread in Java. It does this by setting up some of the properties + of java.lang.Thread objects for 'obj', and then calling the 'init' method of java.lang.Thread + on 'obj'. The Field and Method classes are used for reading and writing properties and + methods of 'obj'. Also, staticInit() adds a mapping between the current thread id and the + C++ peer of 'obj', named 'thr' below. Hence, current_thread() can use the thread + id to lookup both the C++ object and the Java object representing the current thread. + +*/ +void Thread::staticInit() { + pool = new Pool(); + table = new PointerHashTable(*pool); + // create an object representing the main thread. + Class& thrClass = Class::forName("java/lang/Thread"); + JavaObject& obj = thrClass.newInstance(); + Field& fl_daemon = thrClass.getDeclaredField("daemon"); + fl_daemon.setBoolean(&obj,false); + Field& fl_prio = thrClass.getDeclaredField("priority"); + //Field& fl_normprio = thrClass.getDeclaredField("NORM_PRIORITY"); + //fl_prio.setInt(&obj,fl_normprio.getInt(NULL)); + fl_prio.setInt(&obj,5); // NORM_PRIORITY + Class& tgClass = Class::forName("java/lang/ThreadGroup"); + const Type* typearr[1]; + JavaObject* objarr[1]; + JavaObject& tgobj = tgClass.getDeclaredConstructor(typearr,0).newInstance(objarr,0); + Field& fl_group = thrClass.getDeclaredField("group"); + fl_group.set(&obj,tgobj); + Thread* thr = new(*pool) Thread(&obj); + Field& fl_eetop = thrClass.getDeclaredField("eetop"); + fl_eetop.setLong(&obj,(Int64)thr); + thr->state = ALIVE; + thr->id = getCurrentThread(); + thr->realHandle(); + table->add(thr->id,thr); + const Type& ifc = Class::forName("java/lang/Runnable"); + const Type& strc = Class::forName("java/lang/String"); + const Type *typearr1[3] = {&tgClass,&ifc,&strc}; + Method& m = thrClass.getDeclaredMethod("init",typearr1,3); + JavaObject* objarr1[3] = {NULL,NULL,JavaString::make("")}; + invoke(&m,&obj,objarr1,3); +} + +// returns the current thread object using the peer pointer +JavaObject* Thread::currentThread() { + Thread* thr; + if (table->get(getCurrentThread(),&thr)) + return thr->peer; + else + return NULL; +} + +void Thread::yield() { + PR_Sleep(PR_INTERVAL_NO_WAIT); +} + +void Thread::sleep(Int64 i) { + Int32 j = (Int32)i; +#ifdef DEBUG + PR_fprintf(PR_STDOUT,"About to sleep for %d\n",j); +#endif + PR_Sleep(PR_MillisecondsToInterval(j)); +#ifdef DEBUG + PR_fprintf(PR_STDOUT,"Waking up from sleep (%d)\n",j); +#endif +} + +// this is called if a thread throws an uncaught exception. It calls back to +// java.lang.ThreadGroup.uncaughtException() to give the thread group a chance to cleanup. +void +uncaughtException() { + JavaObject* exc = NULL; + Thread* thr; + + GetPassedException(exc); + Thread::table->get(Thread::getCurrentThread(),&thr); + if (thr->state == Thread::CLEANUP) // recursive invocation + return; + thr->state = Thread::CLEANUP; + // call thr->peer->group->uncaughtException(thr->peer,exc); + Class& thrClass = Class::forName("java/lang/Thread"); + Class& throwClass = Class::forName("java/lang/Throwable"); + const Type* typearr[2] = {&thrClass,&throwClass}; + Class& tgClass = Class::forName("java/lang/ThreadGroup"); + Method& m = tgClass.getDeclaredMethod("uncaughtException",typearr,2); + JavaObject* objarr[2] = {thr->peer,exc}; + Field& fl_group = thrClass.getDeclaredField("group"); + JavaObject& tg = fl_group.get(thr->peer); + m.invoke(&tg,objarr,2); +} + +// entry point for threads where a callback through Method::invoke() is made to the Java peer's +// run method. First we check that we haven't been killed or suspended already. Then, a call to +// Monitor::threadInit() sets up thread local data used by the monitors. Finally, the callback is +// made. This call will *always* return, whether an exception happened or not. +void Thread::run(void* arg) { + Thread* thr = (Thread*)arg; + thr->lock(); + thr->id = getCurrentThread(); + thr->realHandle(); + table->add(thr->id,thr); + while (thr->state == SUSPENDED) { // someone has suspended us + thr->unlock(); + _suspendThread(thr->handle); + thr->lock(); + } + if (thr->state > SUSPENDED) { + thr->unlock(); + sysThrowNamedException("java/lang/ThreadDeath"); + return; + } + thr->state = ALIVE; + Monitor::threadInit(); + // call run through thr->peer + const Type *typearr[1]; + Class* c = const_cast(&thr->peer->getClass()); + Method& m = c->getMethod("run",typearr,0); + JavaObject* objarr[1]; + thr->unlock(); + invoke(&m,thr->peer,objarr,0); + table->remove(thr->id); + thr->lock(); + if (thr->state < KILLED) + thr->state = KILLED; + thr->unlock(); + // recycle thr if not in pool. + return; +} + +void Thread::start() { + PRThread* thr = PR_CreateThread(PR_USER_THREAD,run,(void*)this, + PR_PRIORITY_NORMAL,PR_GLOBAL_THREAD, + PR_UNJOINABLE_THREAD,0); // Later use join. + assert(thr != NULL); + PR_Sleep(PR_INTERVAL_NO_WAIT); + //PR_Sleep(PR_MillisecondsToInterval(100)); + PR_SetThreadPriority(thr, prio); +} + +// stops by: +// if already killed, do nothing. +// otherwise, set the state and call _stop() if the thread has been started. +void Thread::stop(JavaObject* obj) { + if (obj == NULL) { + sysThrowNamedException("java/lang/NullPointerException"); + return; + } + lock(); + int ostate = state; + if (state >= KILLED) { + unlock(); + return; + } + state = KILLED; + unlock(); + if (ostate == ALIVE) + _stop(obj); +} + +void Thread::interrupt() { + lock(); + int ostate = state; + if (state >= INTERRUPTED) { + unlock(); + return; + } + state = INTERRUPTED; + unlock(); + if (ostate == ALIVE) + _stop(&const_cast(&Standard::get(cInterruptedException))->newInstance()); +} + +bool Thread::isInterrupted(Uint32 /*f*/) { + int ostate; + lock(); + ostate = state; + //if (f == 1) + // state = ALIVE; + unlock(); + return ostate == INTERRUPTED; +} + +bool Thread::isAlive() { + return state == ALIVE || state == SUSPENDED; +} + +void Thread::setPriority(Int32 p) { + switch (p) { + case 1: + case 2: + case 3: + prio = PR_PRIORITY_LOW; + break; + case 4: + case 5: + case 6: + case 7: + prio = PR_PRIORITY_NORMAL; + break; + case 8: + case 9: + case 10: + prio = PR_PRIORITY_HIGH; + break; + default: + return; + } +} + +// suspends thread by: +// if not running return. +// Otherwise, suspend the thread. +void Thread::suspend() { + lock(); + if (state > ALIVE) { + unlock(); + return; + } + state = SUSPENDED; + unlock(); +#ifndef __linux__ + if (handle != NULL) +#else + if (handle != 0) +#endif + _suspendThread(handle); +} + +void Thread::resume() { + lock(); + if (state != SUSPENDED) { + unlock(); + return; + } + state = ALIVE; + +#ifndef __linux__ + if (handle != NULL) +#else + if (handle != 0) +#endif + _resumeThread(handle); + unlock(); +} + +// counts by following EBP until 0 is reached. +// First the thread is suspended. +Int32 Thread::countStackFrames() { + ThreadContext context; + Int32* frame; + Int32 i = 0; +#ifndef __linux__ + if (handle == NULL) +#else + if (handle == 0) +#endif + return 0; + if (id != getCurrentThread()) + _suspendThread(handle); + if (!_getThreadContext(handle,context)) { + _resumeThread(handle); + return -1; // error + } + frame = _getFramePointer(context); + while (frame != NULL) { + i++; + frame = (Int32*)*frame; + } + _resumeThread(handle); + return i; +} + +// support for killing a thread T +// This is what needs to happen: +// 1. Suspend all threads or just T +// 2. copy the code of the current function of T (found through the saved eip) +// 3. find the asynchronous checkpoints, and smash them with 'int 3'. +// 4. add thread local data to the dying thread for the exception handling +// 5. Set 'eip' of T to point to the instruction in the new code corresponding +// to the old position. Resume T. +// When the async. exception is thrown at runtime, free the code copy, and +// throw a Java exception corresponding to the exception that was provided +// by kill/stop (default: java.lang.ThreadDeath). +// If an exception is thrown before the breakpoint is hit and which is not caught by +// the local exception handler, before repeating the search a level up, free the +// current code copy, make a copy as before of the receiving function (if one +// exists), insert breakpoints, update the receiver's exception table, +// and throw the exception. Again, the above must be repeated if another exception +// is thrown before a breakpoint is hit (puh!). +// How do we detect whether we should throw normally or not? +// By checking whether the current function is in the cache? +// By checking some thread local data? +// In any way, we will use thread local data to carry state from the asynchronous/hardware +// exceptions into the throw routines. + +// for now we simplify as follows: +/* + First, suspend the thread to be killed. + Then, scan its stack to find the innermost return address which points to jitted code. Smash this + return address to point to an illegal instruction, followed by a pointer to the exception + being provided for the stopped thread. The illegal instruction will generate a hardware exception + when the thread is resumed, which will initiate the exception handling. + */ +void Thread::_stop(JavaObject* exc) +{ + Int32 *frame, *ret=NULL; + ThreadContext context; + Uint8* ip; + +#ifndef __linux__ + if (handle == NULL) +#else + if (handle == 0) +#endif + return; + if (id != getCurrentThread()) + _suspendThread(handle); + NativeCodeCache& ca = NativeCodeCache::getCache(); + if (_getThreadContext(handle,context)) { + frame = _getFramePointer(context); + ip = _getInstructionPointer(context); + CacheEntry* ce = ca.lookupByRange(ip); + while (ce == NULL && frame != NULL) { // scan to find innermost jit fram. + ret = frame+1; + ip = (Uint8*)*ret; + frame = (Int32*)*frame; + ce = ca.lookupByRange(ip); + } + if (ce != NULL) { // REPLACE +#if defined(XP_PC) || defined(LINUX) + ip = new(*pool) Uint8[10]; + ip[0] = 0xf; // 0x0f0b is an illegal instruction + ip[1] = 0xb; + if (ret == NULL) { + *(Int32*)(ip+2) = (Int32)_getInstructionPointer(context); + _setInstructionPointer(context,ip); + } + else { + *(Int32*)(ip+2) = *ret; + *ret = (Int32)ip; // new return address is illegal instruction + } + *(Int32*)(ip+6) = (Int32)exc; // picked up by the code for illegal instructions in the hw-exception handler +#else + exc; // force use of exc to make compiler happy +#endif + _setThreadContext(handle,context); + } + } + if (id != NULL) + PR_Interrupt((PRThread*)id); + _resumeThread(handle); +} + +// later use something like the following in the above instead: +/* + if (ce != NULL) { // REPLACE + Uint8* newcode = ce->asynchVersion(ca.mPool,ip); + context.Eip = (DWORD)newcode; + if (!SetThreadContext(handle,&context)) + assert(false); + cache = new(*pool) ExceptionTableCache(ce->eTable,newcode,exc); + } +*/ diff --git a/ef/Runtime/System/Thread.h b/ef/Runtime/System/Thread.h new file mode 100644 index 000000000000..be2ea6b9687d --- /dev/null +++ b/ef/Runtime/System/Thread.h @@ -0,0 +1,128 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#ifndef _Thread +#define _Thread +#include "Monitor.h" +#include "JavaObject.h" +#include "FieldOrMethod.h" + +#ifdef _WIN32 + +typedef CONTEXT ThreadContext; + +#elif defined (__linux__) + +#include + +typedef pid_t HANDLE; +typedef pt_regs ThreadContext; + +#else + +typedef void* HANDLE; +typedef int ThreadContext; + +#endif + + +void _suspendThread(HANDLE p); + +void _resumeThread(HANDLE p); + +bool _getThreadContext(HANDLE handle, ThreadContext& context); + +void _setThreadContext(HANDLE handle, ThreadContext& context); + +Int32* _getFramePointer(ThreadContext& context); + +void _setFramePointer(ThreadContext& context, Int32* v); + +Uint8* _getInstructionPointer(ThreadContext& context); + +void _setInstructionPointer(ThreadContext& context, Uint8* v); + +class NS_EXTERN Thread { + enum { DEFAULT, ALIVE, SUSPENDED, INTERRUPTED, KILLED, CLEANUP }; + static PointerHashTable* table; + PRLock* _lock; + PRThreadPriority prio; // NSPR priority + void* id; // NSPR + HANDLE handle; // Win32 + JavaObject* peer; // Java instance of thread + int state; // used for suspend/resume/interrupt + static void run(void*); // C++ version of java.lang.Thread.run() + void realHandle(); + void _stop(JavaObject* exc); // implements asynchronous stop +public: + static Pool* pool; + struct JavaThread : JavaObject { // shadow structure. See java_lang_Thread.h + JavaObject* name; + Int32 priority; + JavaObject* threadQ; + Int64 eetop; + Uint32 single_step; + Uint32 daemon; + Uint32 stillborn; + JavaObject* target; + JavaObject* group; + JavaObject* inheritedAccessControlContext; + + // dummy constructor, never used (only used for casting) + JavaThread(const Type& type) : JavaObject(type) { } + }; + Thread(JavaObject* o) : state(DEFAULT), peer(o), id(NULL), handle(NULL), prio(PR_PRIORITY_NORMAL) { + _lock = PR_NewLock(); + } + ~Thread() { + PR_DestroyLock(_lock); + } + inline void lock() { + PR_Lock(_lock); + } + inline void unlock() { + PR_Unlock(_lock); + } + static void* getCurrentThread() { + return (void*)PR_GetCurrentThread(); + } + Int32 getStatus() { + return state; + } + static void staticInit(); + static JavaObject* currentThread(); + static void yield(); + static void sleep(Int64 i); + static void exit() { + // clean up + ::exit(0); + } + void start(); + void stop(JavaObject* exc); + void interrupt(); + bool isInterrupted(Uint32 f); + bool isAlive(); + Int32 countStackFrames(); + void setPriority(Int32 p); + void suspend(); + void resume(); + static void invoke(Method* m,JavaObject* obj,JavaObject* arr[],int sz); + friend void uncaughtException(); +}; + +#endif + diff --git a/ef/Runtime/System/md/FieldOrMethod_md.h b/ef/Runtime/System/md/FieldOrMethod_md.h new file mode 100644 index 000000000000..a37cc9584f39 --- /dev/null +++ b/ef/Runtime/System/md/FieldOrMethod_md.h @@ -0,0 +1,48 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#ifndef _FIELD_OR_METHOD_MD_H_ +#define _FIELD_OR_METHOD_MD_H_ + +#if defined(XP_PC) || defined(LINUX) +#define PC_ONLY(x) x +#else +#define PC_ONLY(x) +#endif + +#if defined(XP_PC) +# define prepareArg(i, arg) _asm { push arg } // Prepare the ith argument +# define callFunc(func) _asm { call func } // Call function func +# define getReturnValue(ret) _asm {mov ret, eax} // Put return value into ret +#elif defined(LINUX) +# define prepareArg(i, arg) __asm__ ("pushl %0" : /* no outputs */ : "g" (arg)) // Prepare the ith argument +# define callFunc(func) __asm__ ("call *%0" : /* no outputs */ : "r" (func)) // Call function func +# define getReturnValue(ret) __asm__ ("movl %%eax,%0" : "=g" (ret) : /* no inputs */) // Put return value into ret +#elif defined(GENERATE_FOR_PPC) +# ifdef XP_MAC +# define prepareArg(i, arg) +# define callFunc(func) +# define getReturnValue(ret) ret = 0 +# else +# define prepareArg(i, arg) +# define callFunc(func) +# define getReturnValue(ret) ret = 0 +# endif +#endif + + +#endif /* _FIELD_OR_METHOD_MD_H_ */ diff --git a/ef/Runtime/System/md/Makefile b/ef/Runtime/System/md/Makefile new file mode 100644 index 000000000000..278e3863a0f7 --- /dev/null +++ b/ef/Runtime/System/md/Makefile @@ -0,0 +1,55 @@ +#!gmake +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +####################################################################### +# (1) Directory specific info # +####################################################################### + +DEPTH = ../../.. + +DIRS = x86 +SUBMODULES = $(DIRS) + +LOCAL_EXPORTS = FieldOrMethod_md.h \ + $(NULL) + +MODULE_NAME = EF + +####################################################################### +# (2) Include "component" configuration information. # +####################################################################### + +include $(DEPTH)/config/config.mk + +####################################################################### +# (3) Include "local" platform-dependent assignments (OPTIONAL). # +####################################################################### + + + +####################################################################### +# (4) Execute "component" rules. (OPTIONAL) # +####################################################################### + +include $(DEPTH)/config/rules.mk + +####################################################################### +# (7) Execute "local" rules. (OPTIONAL). # +####################################################################### + + + diff --git a/ef/Runtime/System/md/x86/Makefile b/ef/Runtime/System/md/x86/Makefile new file mode 100644 index 000000000000..06abb3800e2c --- /dev/null +++ b/ef/Runtime/System/md/x86/Makefile @@ -0,0 +1,58 @@ +#!gmake +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +####################################################################### +# (1) Directory specific info # +####################################################################### + +DEPTH = ../../../.. + +CPPSRCS = x86ExceptionHandler.cpp \ + x86SysCallsRuntime.cpp \ + $(NULL) + +LOCAL_MD_EXPORTS_x86 = x86SysCallsRuntime.h \ + x86Win32ExceptionHandler.h \ + $(NULL) + +MODULE_NAME = EF + +####################################################################### +# (2) Include "component" configuration information. # +####################################################################### + +include $(DEPTH)/config/config.mk + +####################################################################### +# (3) Include "local" platform-dependent assignments (OPTIONAL). # +####################################################################### + +include config.mk + + +####################################################################### +# (4) Execute "component" rules. (OPTIONAL) # +####################################################################### + +include $(DEPTH)/config/rules.mk + +####################################################################### +# (7) Execute "local" rules. (OPTIONAL). # +####################################################################### + + + diff --git a/ef/Runtime/System/md/x86/Win32ExceptionHandler.cpp b/ef/Runtime/System/md/x86/Win32ExceptionHandler.cpp new file mode 100644 index 000000000000..fe3f13955822 --- /dev/null +++ b/ef/Runtime/System/md/x86/Win32ExceptionHandler.cpp @@ -0,0 +1,326 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +// +// Win32ExceptionHandler.cpp +// +// Win32 Specific Exception Handling +// +// simon +// bjorn + + +#ifdef _WIN32 + +#include "Fundamentals.h" +#include "SysCalls.h" +#include "prprf.h" +#include "ExceptionTable.h" +#include "NativeCodeCache.h" +#include "LogModule.h" + +#include "x86Win32ExceptionHandler.h" + +// declarations +extern "C" SYSCALL_FUNC(void) x86SoftwareExceptionHandler(Uint32 EBP, Uint32 EDI, Uint32 ESI, Uint32 EBX, const JavaObject& inObject); +extern "C" SYSCALL_FUNC(JavaObject&) x86NewExceptionInstance(StandardClass classKind); + + +//-------------------------------------------------------------------------------- +// set up the stack with the saved registers +__declspec(naked) SYSCALL_FUNC(void) sysThrow (const JavaObject& inObject) +{ + _asm + { + // make a new stack frame + push ebp + mov ebp,esp + + // marshall arguments + push [ebp + 8] // inObject + push ebx + push esi + push edi + push ebp + + call x86SoftwareExceptionHandler + // never returns + } +} + +Uint8* findExceptionHandler(Context* context); + +// x86JumpToHandler +// In: the current frame context +extern "C" +__declspec(naked) SYSCALL_FUNC(void) x86JumpToHandler(const JavaObject* inObject, Uint8* handler, Uint32 EBX, Uint32 ESI, Uint32 EDI, Uint32* EBP, Uint32* ESP) +{ + _asm + { +/* + restore when regalloc is fixed + + pop eax // return address + pop eax // argument for the catch handler + pop ecx // handler + pop ebx + pop esi + pop edi + pop ebp + pop esp + jmp ecx +*/ + // FIX (hack to work around reg alloc bug) + pop eax // return address + pop ecx // argument for the catch handler + pop eax // handler + pop ebx + pop esi + pop edi + pop ebp + pop esp + jmp eax + } +} + +//-------------------------------------------------------------------------------- +__declspec(naked) SYSCALL_FUNC(void) sysThrowNullPointerException() +{ + _asm + { + push cNullPointerException // Push the kind of class + call x86NewExceptionInstance // Create a new object + pop ecx + push eax + push ecx + jmp sysThrow + } +} + +__declspec(naked) SYSCALL_FUNC(void) sysThrowClassCastException() +{ + _asm + { + push cClassCastException // Push the kind of class + call x86NewExceptionInstance // Create a new object + pop ecx + push eax + push ecx + jmp sysThrow + } +} + +__declspec(naked) SYSCALL_FUNC(void) sysThrowArrayIndexOutOfBoundsException() +{ + _asm + { + push cArrayIndexOutOfBoundsException // Push the kind of class + call x86NewExceptionInstance // Create a new object + pop ecx + push eax + push ecx + jmp sysThrow + } +} + +__declspec(naked) SYSCALL_FUNC(void) sysThrowArrayStoreException() +{ + _asm + { + push cArrayStoreException // Push the kind of class + call x86NewExceptionInstance // Create a new object + pop ecx + push eax + push ecx + jmp sysThrow + } +} + +//-------------------------------------------------------------------------------- +// Function: win32SetHandler +// In: the current frame context +void win32SetHandler(Context* context, Uint8* handler, struct _CONTEXT *ContextRecord) +{ +/* + // restore when regalloc is fixed + + ContextRecord->Eip = (DWORD)handler; + ContextRecord->Ebx = (DWORD)context->EBX; + ContextRecord->Esi = (DWORD)context->ESI; + ContextRecord->Edi = (DWORD)context->EDI; + ContextRecord->Esp = (DWORD)context->restoreESP; + ContextRecord->Eax = (DWORD)context->object; + ContextRecord->Ebp = (DWORD)context->sourceEBP; +*/ + // FIX (hack to work around reg alloc bug) + ContextRecord->Eip = (DWORD)handler; + ContextRecord->Ebx = (DWORD)context->EBX; + ContextRecord->Esi = (DWORD)context->ESI; + ContextRecord->Edi = (DWORD)context->EDI; + ContextRecord->Esp = (DWORD)context->restoreESP; + ContextRecord->Ecx = (DWORD)context->object; + ContextRecord->Ebp = (DWORD)context->sourceEBP; +} + +//-------------------------------------------------------------------------------- +// Hardware Exception Handling + +// Stack: +/* + +-------------------------------+ + | return address | + ========+===============================+======== + Source | EBP link | <- ContextRecord.Ebp + (JITed Java) +-------------------------------+ + | Local Store | + +-------------------------------+ + | Saved Non-volatiles | + | eg. EDI | + | ESI | + | EBX | + faulting instruction +-------------------------------+ <- ContextRecord.Esp + (= ContextRecord.Eip) +*/ + +void win32HardwareExceptionHandler(JavaObject* exc, CONTEXT* ContextRecord) +{ + // create a context object on the stack, and save registers + Context context; + + context.EBX = ContextRecord->Ebx; + context.ESI = ContextRecord->Esi; + context.EDI = ContextRecord->Edi; + + context.object = exc; + + // get top EBP + context.sucessorEBP = NULL; + context.sourceEBP = (Uint32*)ContextRecord->Ebp; + context.sourceAddress = (Uint8*)ContextRecord->Eip; + + // cache entries + context.sourceCE = NativeCodeCache::getCache().lookupByRange((Uint8*)context.sourceAddress); // sourceCE could be == NULL + context.successorCE = NULL; // no information yet + + // calculate the ESP if we were to proceed directly to the catch + context.restoreESP = reinterpret_cast(ContextRecord->Esp); + + // call the exception handler + Uint8* handler = findExceptionHandler(&context); + + // Assuming that we received an exception that was not a breakpoint. + // Then it matters if the current thread has been stopped (indicated + // by ec, i.e. if ec == NULL then the normal case applies. + // If stopped, we must free the current code copy, and make a new + // copy (asynchronous one) of the catching function (pHandler). + win32SetHandler(&context, handler, ContextRecord); +} + +// Breakpoint and hardware exceptions +// 1. install an exception handler, which determines the fault and +// invokes the handler lookup (equivalent to throw()). The handler +// should be installed when the thread is created (see Monitor::run()). +// 2. conditioning some exceptions, e.g. breakpoints, which under normal +// circumstances should be caught by the debugger, but when used for asynchronous +// exceptions, should be dealt with differently. + +// This function is used to print the arguments to the assert function of the +// harness code. For example, if there is a call from the test-suite such as: +// QT.assert(b, "A2"); +// the function below will print to standard output the value of 'b' and the string +// "A2", *if* sajava was run with: +// -be suntest/quicktest/runtime/QuickTest assert (ZLjava/lang/String;)V +// It is a kludge, but it is useful while debugging since the printout helps you +// navigate through the source code of the test. + +#ifdef DEBUG_LOG +void +printAssertFrame(Int32* esp) +{ + PR_fprintf(PR_STDOUT,"Arg 1: %x\n",*(esp+2)); + PR_fprintf(PR_STDOUT,"Arg 2: %x\n",*(esp+3)); + JavaString* js = (JavaString*)*(esp+3); + js->dump(); +} +#endif // DEBUG_LOG + +#if LANG_TURKISH != 0x1f +#error Turkey has fucked us. +#endif + +EXCEPTION_DISPOSITION __cdecl +win32HardwareThrow( EXCEPTION_RECORD* ExceptionRecord, + void* EstablisherFrame, + CONTEXT* ContextRecord, + void* DispatcherContext) +{ + Uint8*ip=NULL; + + // In Win32, an exception handler is called twice, when the exception wasn't handled. + // The flags are set the second time around, hence, by checking them we know if we + // should simply ignore the call or not. + if (ExceptionRecord->ExceptionFlags & LANG_TURKISH) + return ExceptionContinueSearch; + + switch (ExceptionRecord->ExceptionCode) + { + case STATUS_INTEGER_DIVIDE_BY_ZERO: + win32HardwareExceptionHandler(&x86NewExceptionInstance(cArithmeticException),ContextRecord); + return ExceptionContinueExecution; + + case STATUS_BREAKPOINT: +#ifdef DEBUG +// Use this instead when checking asserts. +// printAssertFrame((Int32*)ContextRecord->Esp); +// ContextRecord->Eip++; +// return ExceptionContinueExecution; +#endif + return ExceptionContinueSearch; + + case STATUS_ILLEGAL_INSTRUCTION: // these are used for now to do asynchronous exceptions + ip = (Uint8*)ContextRecord->Eip; + ContextRecord->Eip = *(DWORD*)(ip+2); + win32HardwareExceptionHandler((JavaObject*)*(DWORD*)(ip+6),ContextRecord); + return ExceptionContinueExecution; + + case STATUS_ACCESS_VIOLATION: + return ExceptionContinueSearch; + + default: + PR_fprintf(PR_STDOUT,"I am not here am I %d??\n",ExceptionRecord->ExceptionCode); + return ExceptionContinueSearch; + } +} + +// This fellow might be called if the the above handler doesn't catch the exception. +// The 'might' depends on whether the '-ce' option was set as a command line option. +// All it does is to exit the process. +EXCEPTION_DISPOSITION __cdecl +win32HardwareThrowExit(struct _EXCEPTION_RECORD *ExceptionRecord, + void * EstablisherFrame, + CONTEXT *ContextRecord, + void * DispatcherContext) +{ + PR_fprintf(PR_STDOUT,"STATUS:EXCEPTION.\n"); + PR_fprintf(PR_STDOUT,"Exception %d\n",ExceptionRecord->ExceptionCode); + PR_fprintf(PR_STDOUT,"At 0x%x\n",ContextRecord->Eip); + PR_fprintf(PR_STDOUT,"Exception flags %d\n",ExceptionRecord->ExceptionFlags); + _exit(-1); + return ExceptionContinueSearch; // never reached +} + +#endif // _WIN32 diff --git a/ef/Runtime/System/md/x86/config.mk b/ef/Runtime/System/md/x86/config.mk new file mode 100644 index 000000000000..30faa7dfeeed --- /dev/null +++ b/ef/Runtime/System/md/x86/config.mk @@ -0,0 +1,35 @@ +# +# CONFIDENTIAL AND PROPRIETARY SOURCE CODE OF +# NETSCAPE COMMUNICATIONS CORPORATION +# Copyright (C) 1996 Netscape Communications Corporation. All Rights +# Reserved. Use of this Source Code is subject to the terms of the +# applicable license agreement from Netscape Communications Corporation. +# The copyright notice(s) in this Source Code does not indicate actual or +# intended publication of this Source Code. +# + +ifeq ($(OS_ARCH),Linux) +ASFILES = x86LinuxException.s \ + x86LinuxInvokeNative.s \ + $(NULL) + +CPPSRCS += x86LinuxThread.cpp \ + $(NULL) + +LOCAL_MD_EXPORTS_x86 += x86LinuxThread.h \ + $(NULL) + +endif + +ifeq ($(OS_ARCH),WINNT) +CPPSRCS += Win32ExceptionHandler.cpp \ + x86Win32InvokeNative.cpp \ + x86Win32Thread.cpp \ + $(NULL) + +LOCAL_MD_EXPORTS_x86 += x86Win32Thread.h \ + $(NULL) +endif + + + diff --git a/ef/Runtime/System/md/x86/x86ExceptionHandler.cpp b/ef/Runtime/System/md/x86/x86ExceptionHandler.cpp new file mode 100644 index 000000000000..41bc39f652c7 --- /dev/null +++ b/ef/Runtime/System/md/x86/x86ExceptionHandler.cpp @@ -0,0 +1,442 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +// x86Win32_Exception.cpp +// +// simon +// bjorn + +#if defined(_WIN32) || defined(LINUX) + +#include "SysCalls.h" +#include "prprf.h" +#include "x86Win32ExceptionHandler.h" +#include "ExceptionTable.h" +#include "NativeCodeCache.h" +#include "LogModule.h" + +UT_DEFINE_LOG_MODULE(Win32ExceptionHandler); +UT_DEFINE_LOG_MODULE(ExceptionRegs); + +extern "C" SYSCALL_FUNC(void) x86JumpToHandler(const JavaObject* inObject, Uint8* handler, Uint32 EBX, Uint32 ESI, Uint32 EDI, Uint32* EBP, Uint32* ESP); +extern "C" SYSCALL_FUNC(void) x86SoftwareExceptionHandler(Uint32 EBP, Uint32 EDI, Uint32 ESI, Uint32 EBX, const JavaObject& inObject); + +//-------------------------------------------------------------------------------- +/* + +-------------------------------+ + | return address | + ========+===============================+======== + Source | EBP link | <- sourceEBP + (JITed Java) +-------------------------------+ + | Local Store | + +-------------------------------+ + | Saved Non-volatiles | + | eg. EDI | + | ESI | + | EBX | + +-------------------------------+ + | thrown object | + +-------------------------------+ <- initial restoreESP + | return address | + ========+===============================+======== + sysThrow | EBP link | <- sucessorEBP + (native) +-------------------------------+ + | arguments | + ========+===============================+======== + x86SoftwareExceptionHandler | EBP link | + (native) +-------------------------------+ + | Saved Non-volatiles | + | (variable) | + +-------------------------------+ + | 'context' structure | + +-------------------------------+ +*/ + +//-------------------------------------------------------------------------------- +#ifdef DEBUG_LOG +void printRegs(LogModuleObject &f, Context* context); +void printExceptionBegin(LogModuleObject &f, Context* context); +#endif + +#ifdef DEBUG +void checkForNativeStub(Context* context); +#endif + +Uint8* findExceptionHandler(Context* context); + +//-------------------------------------------------------------------------------- +extern "C" SYSCALL_FUNC(JavaObject&) x86NewExceptionInstance(StandardClass classKind) +{ + assert(classKind == cNullPointerException || + classKind == cArrayIndexOutOfBoundsException || + classKind == cClassCastException || + classKind == cArithmeticException); + return const_cast(&Standard::get(classKind))->newInstance(); +} + + +//-------------------------------------------------------------------------------- +// LINUX specific -- FIX make another file for this +#ifdef LINUX + +extern "C" +{ + Uint32 exceptionClass[] = { + cNullPointerException, + cArrayIndexOutOfBoundsException, + cClassCastException, + cArrayStoreException, + }; +} + +#endif + +//-------------------------------------------------------------------------------- +// Function: x86SoftwareExceptionHandler +// +// called by sysThrow +extern "C" SYSCALL_FUNC(void) x86SoftwareExceptionHandler(Uint32 inEBP, Uint32 inEDI, Uint32 inESI, Uint32 inEBX, const JavaObject& inObject) +{ + Context context; // create a context object on the stack + + context.EDI = inEDI; + context.ESI = inESI; + context.EBX = inEBX; + context.object = (JavaObject*) &inObject; + + // get other EBPs + context.sucessorEBP = (Uint32*) inEBP; + context.sourceEBP = *((Uint32**)context.sucessorEBP); + + // The source address will point to the instruction to return to, NOT the instruction that + // generated the exception. The return address is often (always?) in a different control node, so + // it may have a different exception table. + // The byte before the return address will be part of the call instruction that got us here. + context.sourceAddress = (Uint8*)(context.sucessorEBP[1]) - 1; + + // cache entries + context.sourceCE = NativeCodeCache::getCache().lookupByRange((Uint8*)context.sourceAddress); + context.successorCE = NULL; // no information yet + + // calculate the ESP if we were to proceed directly to the catch + // EBP + 4 (return address) + 4 (argument) + 4 (point to last object on stack == saved regs) + context.restoreESP = (Uint32*) ((Uint8*)context.sucessorEBP + 12); + + // now that the context struct is filled we can print debugging information + DEBUG_LOG_ONLY(printExceptionBegin(UT_LOG_MODULE(Win32ExceptionHandler), &context)); + + // find the exception handler + Uint8* handler = findExceptionHandler(&context); + + // jump to it + UT_LOG(ExceptionRegs, PR_LOG_DEBUG, ("Exit: ")); + DEBUG_LOG_ONLY(printRegs(UT_LOG_MODULE(ExceptionRegs), &context)); + UT_LOG(Win32ExceptionHandler, PR_LOG_DEBUG, ("\n===============================\n\n")); + assert(handler); + x86JumpToHandler(context.object, handler, context.EBX, context.ESI, context.EDI, context.sourceEBP, context.restoreESP); +} + +// Function: x86PopStackFrame +// In: the current frame context +// Out: true if a frame was popped, and false if bottom of stack was reached +bool x86PopStackFrame(Context* context) +{ + assert(context); + assert(context->sourceEBP); + + // check that we can unwind + Uint32* newSourceEBP = *(Uint32**)(context->sourceEBP); + + // FIX for now when we get the EBP points to NULL we are at the bottom of the stack + // As a temporary measure, die and display the error + if(newSourceEBP == NULL) + { + DEBUG_LOG_ONLY(PR_fprintf(PR_STDOUT,"\n*** Unhandled Exception Error: %s\n", context->object->getClass().getName())); + return false; + } + + // roll back to point to previous frame + context->sucessorEBP = context->sourceEBP; + context->sourceEBP = newSourceEBP; + context->sourceAddress = (Uint8*)(context->sucessorEBP[1]) - 1; // move back a byte to ensure we're in correct control node + + context->successorCE = context->sourceCE; + context->sourceCE = NativeCodeCache::getCache().lookupByRange(context->sourceAddress); + + // Restore Registers + // The callee saves a set of registers EDI, ESI, EBX. To restore to the current 'source' frame we need + // to restore the set of registers saved from our callee (the 'successor' frame). + // + // We know nothing about the register save policies of native methods. To ensure proper register + // restoration we include a dummy stack frame below all native frames that has stored all three + // callee-save registers. + // + // Whenever we see a native method we should restore the registers assuming that the first three locations + // after EBP are the callee-save values. The first native method will probably load garbage into the registers + // but the last fake frame that we have inserted will properly restore them all. + // EBX, ESI and EDI are restored from the successor frame + // + // remember that sourceCE and successorCE can be null + Uint32 numRegs; // number of registers to restore + Uint32* restoreReg; // address of first restore location + + if(context->successorCE) + { + // successor is java frame; restore regs as per saved policy + StackFrameInfo& successorPolicy = context->successorCE->policy; + restoreReg = (Uint32*) ((Uint8*)(context->sucessorEBP) - successorPolicy.getCalleeSavedBeginOffset()); + numRegs = successorPolicy.getNumSavedGPRWords(); + } + else + { + // successor is native frame; restore all regs from just below EBP + restoreReg = (Uint32*) ((Uint8*)(context->sucessorEBP) - 4); + numRegs = 3; + } + + if(numRegs > 2) + context->EDI = *restoreReg--; + if(numRegs > 1) + context->ESI = *restoreReg--; + if(numRegs > 0) + context->EBX = *restoreReg--; + + // Calculate the restore ESP + if(context->sourceCE) + { + // source frame is java frame; restore ESP to correct position + StackFrameInfo& sourcePolicy = context->sourceCE->policy; + context->restoreESP = (Uint32*) ((Uint8*)(context->sourceEBP) - (Uint8*)(sourcePolicy.getStackPointerOffset())); + } + else + { + // source frame is native; cannot restore ESP, so we set it to NULL as a sentinel + context->restoreESP = NULL; + } + + DEBUG_LOG_ONLY(printContext(UT_LOG_MODULE(Win32ExceptionHandler), context)); + DEBUG_ONLY(checkForNativeStub(context)); + return true; +} + +//-------------------------------------------------------------------------------- +#ifdef DEBUG + +extern void* compileStubReEntryPoint; + +// Function: isGuardFrame +// Purpose: determines whether the source frame is a native method / syscall guard frame +bool isGuardFrame(Context* context, bool printIdentifier = false) +{ + Uint32 retAddress = (Uint32)(context->sucessorEBP[1]); + int i; + + // check unrolled-loop stubs for return address + extern void* sysInvokeNativeStubs[1024]; + for(i = 0; i < 6; i++) + if( ((Uint32)(sysInvokeNativeStubs[i]) + 9 + 5 * i) == retAddress) + { + if(printIdentifier) + UT_LOG(Win32ExceptionHandler, PR_LOG_DEBUG, ("Guard Frame (made by sysInvokeNative%d())\n", i)); + return true; + } + // check other stubs + for(i = 6; i < 256; i++) + if( ((Uint32)(sysInvokeNativeStubs[i]) + 23) == retAddress) + { + if(printIdentifier) + UT_LOG(Win32ExceptionHandler, PR_LOG_DEBUG, ("Guard Frame (made by sysInvokeNative(%d))\n", i)); + return true; + } + + // check for staticCompileStub + if((Uint32)compileStubReEntryPoint == retAddress) + { + if(printIdentifier) + UT_LOG(Win32ExceptionHandler, PR_LOG_DEBUG, ("Guard Frame (staticCompileStub)\n")); + DEBUG_LOG_ONLY(PR_fprintf(PR_STDOUT,"WARNING: exception unwinding past a static compile stub\n")); + return true; + } + + // if we are here then we are not a guard frame + return false; +} + +#include "StackWalker.h" + +// Function: checkForNativeStub +// Purpose: if the current frame is a non-Java frame called by a Java method, check that +// the frame is a guard frame +void checkForNativeStub(Context* context) +{ + // checks + // take a peek back at the previous frame + Uint8* prevAddress = (Uint8*)(context->sourceEBP[1]) - 1; + assert(prevAddress); + CacheEntry* prevCacheEntry = NativeCodeCache::getCache().lookupByRange(prevAddress); + + bool sourceIsJITCode = context->sourceCE && context->sourceCE->eTable; + bool previousIsJITCode = prevCacheEntry && prevCacheEntry->eTable; + + if((!sourceIsJITCode && previousIsJITCode) && !isGuardFrame(context)) + { + // this is not a GUARD-JAVA interface, but the guard was missing + stackWalker((void*) 0); + trespass("\nFATAL ERROR: missing guard frame\n"); + } +} +#endif + +#ifdef DEBUG_LOG + +// Function: printExceptionBegin +// Purpose: call this when the context record has been filled to print out the origin and type of exception +void printExceptionBegin(LogModuleObject &f, Context* context) +{ + // print debugging information + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("\n===============================\nEXCEPTION\n")); + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("Source: ")); + if(context->sourceCE) + { + const char* methodName = context->sourceCE->descriptor.method->getName(); + const char* className = context->sourceCE->descriptor.method->getDeclaringClass()->getName(); + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("java method '%s'\n", methodName)); + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("Class: %s\n", className)); + } + else + { + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("a syscall or native method\n")); + } + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("Object: '%s' (object = 0x%p)\n", context->object->getClass().getName(), context->object)); + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("Return: 0x%p\n", context->sucessorEBP[1])); + UT_OBJECTLOG(UT_LOG_MODULE(ExceptionRegs), PR_LOG_ALWAYS, ("Entry: ")); + printRegs(UT_LOG_MODULE(ExceptionRegs), context); +} + +// Function: printRegs +// Purpose: print the state of the registers being restored by the exception handler +void printRegs(LogModuleObject &f, Context* context) +{ + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("EBX %8x ESI %8x EDI %8x\n", context->EBX, context->ESI, context->EDI)); +} + +// Function: printContext +// Purpose: dump the state of the exception handler context to the log module +void printContext(LogModuleObject &f, Context* context) +{ + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("\n-------------------------------\n")); + + // print the method + if(context->sourceCE) + { + const char* methodName = context->sourceCE->descriptor.method->getName(); + const char* className = context->sourceCE->descriptor.method->getDeclaringClass()->getName(); + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("Method: %s\n", methodName)); + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("Class: %s\n", className)); + + StackFrameInfo& policy = context->sourceCE->policy; + policy.print(f); + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("Regs: ")); + printRegs(f, context); + + ExceptionTable* eTable = context->sourceCE->eTable; + if(eTable && eTable->getNumberofEntries() > 0) + { + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("Exception Table\n")); + eTable->printShort(f); + } + } + else if(!isGuardFrame(context, true)) // isGuardFrame(..., true) prints reference if guard frame found + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("Method: anonymous\n")); + + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("Return: 0x%p\n", context->sucessorEBP[1])); +} +#endif // DEBUG_LOG + +//-------------------------------------------------------------------------------- +// this function assumes that the source frame was set up by Thread::invoke(), and +// that it should look like: +/* + +-----------------------+ + | old EBP | <- real sourceEBP + |-----------------------| + | &uncaughtException | + |-----------------------| + | NULL | <- sourceEBP as on entry to uncaughtExitPoint + |-----------------------| + | 4 arguments to invoke | + | ... | + |-----------------------| + | return address | <- restoreESP + |-----------------------| + */ +static Uint8* uncaughtExceptionExit(Context* context) +{ + Uint8* ip = *(Uint8**)(context->sourceEBP+1); // uncaughtException() + context->restoreESP = context->sourceEBP-5; // 4 arguments plus the return address + context->sourceEBP = *(Uint32**)(context->sourceEBP+2); // old ebp + assert(ip); + return ip; +} + +//-------------------------------------------------------------------------------- +// findExceptionHandler +// +Uint8* findExceptionHandler(Context* context) +{ + // look for a handler for the object + // unwind repeatedly until found + ExceptionTableEntry* ete; + + while (1) + { + // every jit'd method has an eTable + // native frames don't have a sourceCE + if(context->sourceCE) + { + // jit frame + assert(context->sourceCE->eTable); + ete = context->sourceCE->eTable->findCatchHandler(context->sourceAddress, *(context->object)); + } + else + { + // native frame + ete = NULL; + } + + if (ete) // ete != null iff there has been an exception match + break; + + if (!x86PopStackFrame(context)) // when popStack() fails, we are faced with an uncaught exception + { + Uint8* uncaughtHandler = uncaughtExceptionExit(context); + UT_LOG(Win32ExceptionHandler, PR_LOG_DEBUG, ("\n-------------------------------\n")); + UT_LOG(Win32ExceptionHandler, PR_LOG_DEBUG, ("Uncaught Exception -- jumping to handler at 0x%p\n", uncaughtHandler)); + return uncaughtHandler; + } + } + + Uint8* pHandler = context->sourceCE->eTable->getStart()+ete->pHandler; + assert(pHandler); + UT_LOG(Win32ExceptionHandler, PR_LOG_DEBUG, ("\n-------------------------------\n")); + UT_LOG(Win32ExceptionHandler, PR_LOG_DEBUG, ("Matched to catch handler at %p\n\n", pHandler)); + assert(context->restoreESP != NULL); // restore ESP must not be null, could mean that we are trying to return to a native method, NYI + return pHandler; +} + +//-------------------------------------------------------------------------------- +#endif // _WIN32 || LINUX diff --git a/ef/Runtime/System/md/x86/x86LinuxException.s b/ef/Runtime/System/md/x86/x86LinuxException.s new file mode 100644 index 000000000000..017b8352c29e --- /dev/null +++ b/ef/Runtime/System/md/x86/x86LinuxException.s @@ -0,0 +1,105 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + + .globl sysThrow + .align 4 +sysThrow: + push %ebp + mov %esp,%ebp + push 8(%ebp) + push %ebx + push %esi + push %edi + push %ebp + + call x86SoftwareExceptionHandler + +/** + restore when regalloc is fixed + + .globl x86JumpToHandler + .align 4 +x86JumpToHandler: + popl %eax + popl %eax + popl %ecx + popl %ebx + popl %esi + popl %edi + popl %ebp + popl %esp + jmp *%ecx + + // FIX (hack to work around reg alloc bug) +**/ + .globl x86JumpToHandler + .align 4 +x86JumpToHandler: + popl %eax + popl %ecx + popl %eax + popl %ebx + popl %esi + popl %edi + popl %ebp + popl %esp + jmp *%eax + + .globl sysThrowClassCastException + .align 4 +sysThrowClassCastException: + mov $exceptionClass, %eax + push 8(%eax) + call x86NewExceptionInstance + popl %ecx + pushl %eax + pushl %ecx + jmp sysThrow; + + .globl sysThrowNullPointerException + .align 4 +sysThrowNullPointerException: + mov $exceptionClass, %eax + push (%eax) + call x86NewExceptionInstance + popl %ecx + pushl %eax + pushl %ecx + jmp sysThrow; + + .globl sysThrowArrayIndexOutOfBoundsException + .align 4 +sysThrowArrayIndexOutOfBoundsException: + mov $exceptionClass, %eax + push 4(%eax) + call x86NewExceptionInstance + popl %ecx + pushl %eax + pushl %ecx + jmp sysThrow; + + .globl sysThrowArrayStoreException + .align 4 +sysThrowArrayStoreException: + mov $exceptionClass, %eax + push 12(%eax) + call x86NewExceptionInstance + popl %ecx + pushl %eax + pushl %ecx + jmp sysThrow; diff --git a/ef/Runtime/System/md/x86/x86LinuxInvokeNative.s b/ef/Runtime/System/md/x86/x86LinuxInvokeNative.s new file mode 100644 index 000000000000..eb737cf7e4df --- /dev/null +++ b/ef/Runtime/System/md/x86/x86LinuxInvokeNative.s @@ -0,0 +1,255 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +/* + * + * A per function stub should look like this (N is the number of incoming arguments) + * + * functionStub: + * push $function + * jmp sysInvokeNative##N + */ + +#include + +.file "x86LinuxInvokeNative.S" + +#define sysInvokeNative(N); \ +STATIC_ENTRY(CAT(sysInvokeNative,N)); \ + popl %eax; /* pop the function adress */ \ + \ + pushl %ebp; /************************************/ \ + movl %esp,%ebp; /* */ \ + pushl %edi; /* PROLOG */ \ + pushl %esi; /* */ \ + pushl %ebx; /************************************/ \ + \ + movl $N,%edx; /* %edx = nArgs */ \ + \ +SYMBOL_NAME_LABEL(CAT(top,N)); \ + \ + leal (16+4*N)(%esp),%ecx; /* %ecx = %esp + 16 + 4 * nArgs */ \ + pushl (%ecx); /* push original argument */ \ + decl %edx; /* nArgs -= 1 */ \ + jne SYMBOL_NAME(CAT(top,N)); /* loop over */ \ + call *%eax; /* call the native function */ \ + \ + movl %ebp,%esp; /********************************** */ \ + popl %ebp; /* EPILOG */ \ + ret $(4*N); /************************************/ \ +END_ENTRY(CAT(sysInvokeNative,N)) + +TEXT_SEGMENT + +STATIC_ENTRY(sysInvokeNative0) + popl %eax + pushl %ebp + movl %esp,%ebp + pushl %edi + pushl %esi + pushl %ebx + call *%eax + movl %ebp,%esp + popl %ebp + ret +END_ENTRY(sysInvokeNative0) + +STATIC_ENTRY(sysInvokeNative1) + popl %eax + pushl %ebp + movl %esp,%ebp + pushl %edi + pushl %esi + pushl %ebx + movl 20(%esp),%ecx + pushl %ecx + call *%eax + movl %ebp,%esp + popl %ebp + ret $4 +END_ENTRY(sysInvokeNative1) + +STATIC_ENTRY(sysInvokeNative2) + popl %eax + pushl %ebp + movl %esp,%ebp + pushl %edi + pushl %esi + pushl %ebx + movl 24(%esp),%ecx + pushl %ecx + movl 24(%esp),%ecx + pushl %ecx + call *%eax + movl %ebp,%esp + popl %ebp + ret $8 +END_ENTRY(sysInvokeNative2) + +STATIC_ENTRY(sysInvokeNative3) + popl %eax + pushl %ebp + movl %esp,%ebp + pushl %edi + pushl %esi + pushl %ebx + movl 28(%esp),%ecx + pushl %ecx + movl 28(%esp),%ecx + pushl %ecx + movl 28(%esp),%ecx + pushl %ecx + call *%eax + movl %ebp,%esp + popl %ebp + ret $12 +END_ENTRY(sysInvokeNative3) + +STATIC_ENTRY(sysInvokeNative4) + popl %eax + pushl %ebp + movl %esp,%ebp + pushl %edi + pushl %esi + pushl %ebx + movl 32(%esp),%ecx + pushl %ecx + movl 32(%esp),%ecx + pushl %ecx + movl 32(%esp),%ecx + pushl %ecx + movl 32(%esp),%ecx + pushl %ecx + call *%eax + movl %ebp,%esp + popl %ebp + ret $16 +END_ENTRY(sysInvokeNative4) + +STATIC_ENTRY(sysInvokeNative5) + popl %eax + pushl %ebp + movl %esp,%ebp + pushl %edi + pushl %esi + pushl %ebx + movl 36(%esp),%ecx + pushl %ecx + movl 36(%esp),%ecx + pushl %ecx + movl 36(%esp),%ecx + pushl %ecx + movl 36(%esp),%ecx + pushl %ecx + movl 36(%esp),%ecx + pushl %ecx + call *%eax + movl %ebp,%esp + popl %ebp + ret $20 +END_ENTRY(sysInvokeNative5) + +sysInvokeNative(6); sysInvokeNative(7); sysInvokeNative(8); sysInvokeNative(9); sysInvokeNative(10); +sysInvokeNative(11); sysInvokeNative(12); sysInvokeNative(13); sysInvokeNative(14); sysInvokeNative(15); +sysInvokeNative(16); sysInvokeNative(17); sysInvokeNative(18); sysInvokeNative(19); sysInvokeNative(20); +sysInvokeNative(21); sysInvokeNative(22); sysInvokeNative(23); sysInvokeNative(24); sysInvokeNative(25); +sysInvokeNative(26); sysInvokeNative(27); sysInvokeNative(28); sysInvokeNative(29); sysInvokeNative(30); +sysInvokeNative(31); sysInvokeNative(32); sysInvokeNative(33); sysInvokeNative(34); sysInvokeNative(35); +sysInvokeNative(36); sysInvokeNative(37); sysInvokeNative(38); sysInvokeNative(39); sysInvokeNative(40); +sysInvokeNative(41); sysInvokeNative(42); sysInvokeNative(43); sysInvokeNative(44); sysInvokeNative(45); +sysInvokeNative(46); sysInvokeNative(47); sysInvokeNative(48); sysInvokeNative(49); sysInvokeNative(50); +sysInvokeNative(51); sysInvokeNative(52); sysInvokeNative(53); sysInvokeNative(54); sysInvokeNative(55); +sysInvokeNative(56); sysInvokeNative(57); sysInvokeNative(58); sysInvokeNative(59); sysInvokeNative(60); +sysInvokeNative(61); sysInvokeNative(62); sysInvokeNative(63); sysInvokeNative(64); sysInvokeNative(65); +sysInvokeNative(66); sysInvokeNative(67); sysInvokeNative(68); sysInvokeNative(69); sysInvokeNative(70); +sysInvokeNative(71); sysInvokeNative(72); sysInvokeNative(73); sysInvokeNative(74); sysInvokeNative(75); +sysInvokeNative(76); sysInvokeNative(77); sysInvokeNative(78); sysInvokeNative(79); sysInvokeNative(80); +sysInvokeNative(81); sysInvokeNative(82); sysInvokeNative(83); sysInvokeNative(84); sysInvokeNative(85); +sysInvokeNative(86); sysInvokeNative(87); sysInvokeNative(88); sysInvokeNative(89); sysInvokeNative(90); +sysInvokeNative(91); sysInvokeNative(92); sysInvokeNative(93); sysInvokeNative(94); sysInvokeNative(95); +sysInvokeNative(96); sysInvokeNative(97); sysInvokeNative(98); sysInvokeNative(99); sysInvokeNative(100); +sysInvokeNative(101); sysInvokeNative(102); sysInvokeNative(103); sysInvokeNative(104); sysInvokeNative(105); +sysInvokeNative(106); sysInvokeNative(107); sysInvokeNative(108); sysInvokeNative(109); sysInvokeNative(110); +sysInvokeNative(111); sysInvokeNative(112); sysInvokeNative(113); sysInvokeNative(114); sysInvokeNative(115); +sysInvokeNative(116); sysInvokeNative(117); sysInvokeNative(118); sysInvokeNative(119); sysInvokeNative(120); +sysInvokeNative(121); sysInvokeNative(122); sysInvokeNative(123); sysInvokeNative(124); sysInvokeNative(125); +sysInvokeNative(126); sysInvokeNative(127); sysInvokeNative(128); sysInvokeNative(129); sysInvokeNative(130); +sysInvokeNative(131); sysInvokeNative(132); sysInvokeNative(133); sysInvokeNative(134); sysInvokeNative(135); +sysInvokeNative(136); sysInvokeNative(137); sysInvokeNative(138); sysInvokeNative(139); sysInvokeNative(140); +sysInvokeNative(141); sysInvokeNative(142); sysInvokeNative(143); sysInvokeNative(144); sysInvokeNative(145); +sysInvokeNative(146); sysInvokeNative(147); sysInvokeNative(148); sysInvokeNative(149); sysInvokeNative(150); +sysInvokeNative(151); sysInvokeNative(152); sysInvokeNative(153); sysInvokeNative(154); sysInvokeNative(155); +sysInvokeNative(156); sysInvokeNative(157); sysInvokeNative(158); sysInvokeNative(159); sysInvokeNative(160); +sysInvokeNative(161); sysInvokeNative(162); sysInvokeNative(163); sysInvokeNative(164); sysInvokeNative(165); +sysInvokeNative(166); sysInvokeNative(167); sysInvokeNative(168); sysInvokeNative(169); sysInvokeNative(170); +sysInvokeNative(171); sysInvokeNative(172); sysInvokeNative(173); sysInvokeNative(174); sysInvokeNative(175); +sysInvokeNative(176); sysInvokeNative(177); sysInvokeNative(178); sysInvokeNative(179); sysInvokeNative(180); +sysInvokeNative(181); sysInvokeNative(182); sysInvokeNative(183); sysInvokeNative(184); sysInvokeNative(185); +sysInvokeNative(186); sysInvokeNative(187); sysInvokeNative(188); sysInvokeNative(189); sysInvokeNative(190); +sysInvokeNative(191); sysInvokeNative(192); sysInvokeNative(193); sysInvokeNative(194); sysInvokeNative(195); +sysInvokeNative(196); sysInvokeNative(197); sysInvokeNative(198); sysInvokeNative(199); sysInvokeNative(200); +sysInvokeNative(201); sysInvokeNative(202); sysInvokeNative(203); sysInvokeNative(204); sysInvokeNative(205); +sysInvokeNative(206); sysInvokeNative(207); sysInvokeNative(208); sysInvokeNative(209); sysInvokeNative(210); +sysInvokeNative(211); sysInvokeNative(212); sysInvokeNative(213); sysInvokeNative(214); sysInvokeNative(215); +sysInvokeNative(216); sysInvokeNative(217); sysInvokeNative(218); sysInvokeNative(219); sysInvokeNative(220); +sysInvokeNative(221); sysInvokeNative(222); sysInvokeNative(223); sysInvokeNative(224); sysInvokeNative(225); +sysInvokeNative(226); sysInvokeNative(227); sysInvokeNative(228); sysInvokeNative(229); sysInvokeNative(230); +sysInvokeNative(231); sysInvokeNative(232); sysInvokeNative(233); sysInvokeNative(234); sysInvokeNative(235); +sysInvokeNative(236); sysInvokeNative(237); sysInvokeNative(238); sysInvokeNative(239); sysInvokeNative(240); +sysInvokeNative(241); sysInvokeNative(242); sysInvokeNative(243); sysInvokeNative(244); sysInvokeNative(245); +sysInvokeNative(246); sysInvokeNative(247); sysInvokeNative(248); sysInvokeNative(249); sysInvokeNative(250); +sysInvokeNative(251); sysInvokeNative(252); sysInvokeNative(253); sysInvokeNative(254); sysInvokeNative(255); + +DATA_SEGMENT + +#define STUB(N) .long SYMBOL_NAME(CAT(sysInvokeNative,N)) + +GLOBAL_ENTRY(sysInvokeNativeStubs) + STUB(0); STUB(1); STUB(2); STUB(3); STUB(4); STUB(5); STUB(6); STUB(7); + STUB(8); STUB(9); STUB(10); STUB(11); STUB(12); STUB(13); STUB(14); STUB(15); + STUB(16); STUB(17); STUB(18); STUB(19); STUB(20); STUB(21); STUB(22); STUB(23); + STUB(24); STUB(25); STUB(26); STUB(27); STUB(28); STUB(29); STUB(30); STUB(31); + STUB(32); STUB(33); STUB(34); STUB(35); STUB(36); STUB(37); STUB(38); STUB(39); + STUB(40); STUB(41); STUB(42); STUB(43); STUB(44); STUB(45); STUB(46); STUB(47); + STUB(48); STUB(49); STUB(50); STUB(51); STUB(52); STUB(53); STUB(54); STUB(55); + STUB(56); STUB(57); STUB(58); STUB(59); STUB(60); STUB(61); STUB(62); STUB(63); + STUB(64); STUB(65); STUB(66); STUB(67); STUB(68); STUB(69); STUB(70); STUB(71); + STUB(72); STUB(73); STUB(74); STUB(75); STUB(76); STUB(77); STUB(78); STUB(79); + STUB(80); STUB(81); STUB(82); STUB(83); STUB(84); STUB(85); STUB(86); STUB(87); + STUB(88); STUB(89); STUB(90); STUB(91); STUB(92); STUB(93); STUB(94); STUB(95); + STUB(96); STUB(97); STUB(98); STUB(99); STUB(100); STUB(101); STUB(102); STUB(103); + STUB(104); STUB(105); STUB(106); STUB(107); STUB(108); STUB(109); STUB(110); STUB(111); + STUB(112); STUB(113); STUB(114); STUB(115); STUB(116); STUB(117); STUB(118); STUB(119); + STUB(120); STUB(121); STUB(122); STUB(123); STUB(124); STUB(125); STUB(126); STUB(127); + STUB(128); STUB(129); STUB(130); STUB(131); STUB(132); STUB(133); STUB(134); STUB(135); + STUB(136); STUB(137); STUB(138); STUB(139); STUB(140); STUB(141); STUB(142); STUB(143); + STUB(144); STUB(145); STUB(146); STUB(147); STUB(148); STUB(149); STUB(150); STUB(151); + STUB(152); STUB(153); STUB(154); STUB(155); STUB(156); STUB(157); STUB(158); STUB(159); + STUB(160); STUB(161); STUB(162); STUB(163); STUB(164); STUB(165); STUB(166); STUB(167); + STUB(168); STUB(169); STUB(170); STUB(171); STUB(172); STUB(173); STUB(174); STUB(175); + STUB(176); STUB(177); STUB(178); STUB(179); STUB(180); STUB(181); STUB(182); STUB(183); + STUB(184); STUB(185); STUB(186); STUB(187); STUB(188); STUB(189); STUB(190); STUB(191); + STUB(192); STUB(193); STUB(194); STUB(195); STUB(196); STUB(197); STUB(198); STUB(199); + STUB(200); STUB(201); STUB(202); STUB(203); STUB(204); STUB(205); STUB(206); STUB(207); + STUB(208); STUB(209); STUB(210); STUB(211); STUB(212); STUB(213); STUB(214); STUB(215); + STUB(216); STUB(217); STUB(218); STUB(219); STUB(220); STUB(221); STUB(222); STUB(223); + STUB(224); STUB(225); STUB(226); STUB(227); STUB(228); STUB(229); STUB(230); STUB(231); + STUB(232); STUB(233); STUB(234); STUB(235); STUB(236); STUB(237); STUB(238); STUB(239); + STUB(240); STUB(241); STUB(242); STUB(243); STUB(244); STUB(245); STUB(246); STUB(247); + STUB(248); STUB(249); STUB(250); STUB(251); STUB(252); STUB(253); STUB(254); STUB(255); + .size sysInvokeNativeStubs,1024 diff --git a/ef/Runtime/System/md/x86/x86LinuxThread.cpp b/ef/Runtime/System/md/x86/x86LinuxThread.cpp new file mode 100644 index 000000000000..81af12bbec6a --- /dev/null +++ b/ef/Runtime/System/md/x86/x86LinuxThread.cpp @@ -0,0 +1,162 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#include +#include +#include +#include +#ifdef _REENTRANT +#include +#endif +#include +#include +#include "Thread.h" +#include "NativeCodeCache.h" +#include "Exceptions.h" + +// Supend the thread specified by the pid +void _suspendThread(HANDLE handle) +{ +#ifdef _REENTRANT + if (pthread_kill(handle, SIGKILL) == -1) { + assert(0); + } +#endif +} + +// Resume the thread specified by the pid +void _resumeThread(HANDLE handle) +{ +#ifdef _REENTRANT + if (pthread_kill(handle, SIGCONT) == -1) { + assert(0); + } +#endif +} + +// Gets the thread context via ptrace +bool +_getThreadContext(HANDLE handle, ThreadContext& context) +{ + if (ptrace(PTRACE_ATTACH, handle, NULL, NULL) == -1) + assert(0); + if (ptrace(PTRACE_PEEKUSR, handle, offsetof(struct user, regs), &context) + == -1) + assert(0); + + return true; +} + +// Sets the thread context via ptrace +void +_setThreadContext(HANDLE handle, ThreadContext &context) +{ + if (ptrace(PTRACE_ATTACH, handle, NULL, NULL) == -1) + assert(0); + if (ptrace(PTRACE_POKEUSR, handle, offsetof(struct user, regs), &context) + == -1) + assert(0); +} + +Int32* +_getFramePointer(ThreadContext& context) +{ + return (Int32 *) context.ebp; +} + +void _setFramePointer(ThreadContext& context, Int32* v) +{ + context.ebp = (long) v; +} + +Uint8* +_getInstructionPointer(ThreadContext &context) +{ + return (Uint8*)context.eip; +} + +void +_setInstructionPointer(ThreadContext& context, Uint8 *v) +{ + context.eip = (long) v; +} + +void Thread::realHandle() +{ + // sets up the OS handles + HANDLE thr = getpid(); +} + +/* + Special invoke for threads. + + We prepare the stack for a newborn thread as follows. First we push + the hardware exception handler (as {previous handler, new handler}), + and set fs:[0] to point to this structure. This will make win32 call + new handler when a hardware exception fires (/0, *NULL, or illegal + instruction). + + Second, we push EBP as it it is upon entry to this routine, followed + by a pointer to uncaughtException, followed by the sentinel + NULL. Then we prepare to call __invoke() which corresponds to + Method::invoke() by pushing the arguments in reverse order. Now, + regardless whether invoke() returns normally or through an uncaught + exception, we will return to the line 'add esp,24' which is where we + clean up afterwards. + + For the entry set-up to uncaughtException() see + uncaughtExceptionExit() in x86Win32ExceptionHandler.cpp in + Runtime/System/md/x86. +*/ + +// called by Thread::invoke() and is only used to avoid assuming a calling +// convention for C++ methods. +static void +__invoke(Method* m, JavaObject* obj, JavaObject* arr[], int sz) +{ + m->invoke(obj,arr,sz); +} + +void +Thread::invoke(Method* m, JavaObject* obj, JavaObject* arr[], int sz) +{ +/* + DWORD w32 = (DWORD)win32HardwareThrow; + DWORD uE = (DWORD)uncaughtException; + __asm { + push w32 + push fs:[0] + mov fs:[0],esp + push ebp + push uE + push NULL + mov ecx,esp + push sz + push arr + push obj + push m + mov ebp,ecx + call __invoke + add esp,24 // pop 4 arguments, NULL, and uncaughtException + pop ebp + pop ecx + mov fs:[0],ecx + pop ecx // pop win32HardwareThrow + } +*/ + m->invoke(obj,arr,sz); +} diff --git a/ef/Runtime/System/md/x86/x86LinuxThread.h b/ef/Runtime/System/md/x86/x86LinuxThread.h new file mode 100644 index 000000000000..c7d71a129232 --- /dev/null +++ b/ef/Runtime/System/md/x86/x86LinuxThread.h @@ -0,0 +1,27 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#ifndef _X86_LINUX_THREAD_H_ +#define _X86_LINUX_THREAD_H_ + +#include "ExceptionTable.h" +#include "Monitor.h" +#include "FieldOrMethod.h" + +#define GetPassedException(E) __asm__("mov %%ecx, %0" : : "g"(E)) + +#endif // _X86_LINUX_THREAD_H_ diff --git a/ef/Runtime/System/md/x86/x86SysCallsRuntime.cpp b/ef/Runtime/System/md/x86/x86SysCallsRuntime.cpp new file mode 100644 index 000000000000..2819ba700e38 --- /dev/null +++ b/ef/Runtime/System/md/x86/x86SysCallsRuntime.cpp @@ -0,0 +1,72 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +// +// x86SysCallsRuntime.cpp +// +// simon + +#include "JavaObject.h" +#include "SysCallsRuntime.h" + +extern void* sysInvokeNativeStubs[1024]; + +// Assembly glue macro +#if defined(_WIN32) + +#define guardedSysCall(target, numArgWords) \ +__declspec(naked) SYSCALL_FUNC(void) guarded##target() \ +{ \ + __asm \ + { \ + __asm push OFFSET target \ + __asm jmp [sysInvokeNativeStubs + 4 * numArgWords] \ + } \ +} + +#else +//#error You need to make some inline assembly equivalent to the above +#define guardedSysCall(target, numArgWords) +#endif + +extern "C" { + +// Make Guard Stubs for the all SysCalls that can throw exceptions +// NB: SysThrow is already guarded +// form: guardedSysCall(actual destination, number of words for parameters) +guardedSysCall(sysCheckArrayStore, 2) + +guardedSysCall(sysMonitorEnter, 1) +guardedSysCall(sysMonitorExit, 1) + +guardedSysCall(sysNewNDArray, 2) +guardedSysCall(sysNew2DArray, 3) +guardedSysCall(sysNew3DArray, 4) + +guardedSysCall(sysNew, 1) + +guardedSysCall(sysNewByteArray, 1) +guardedSysCall(sysNewBooleanArray, 1) +guardedSysCall(sysNewShortArray, 1) +guardedSysCall(sysNewCharArray, 1) +guardedSysCall(sysNewIntArray, 1) +guardedSysCall(sysNewLongArray, 1) +guardedSysCall(sysNewFloatArray, 1) +guardedSysCall(sysNewDoubleArray, 1) +guardedSysCall(sysNewObjectArray, 2) + +} diff --git a/ef/Runtime/System/md/x86/x86SysCallsRuntime.h b/ef/Runtime/System/md/x86/x86SysCallsRuntime.h new file mode 100644 index 000000000000..b8fe95ff804e --- /dev/null +++ b/ef/Runtime/System/md/x86/x86SysCallsRuntime.h @@ -0,0 +1,54 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +// +// x86SysCallsRuntime.h +// +// simon + +#ifndef _X86_SYSCALLS_RUNTIME_H_ +#define _X86_SYSCALLS_RUNTIME_H_ + + +#include "Fundamentals.h" +#include "SysCallsRuntime.h" + +extern "C" +{ + NS_EXTERN SYSCALL_FUNC(void) guardedsysCheckArrayStore(); + + NS_EXTERN SYSCALL_FUNC(void) guardedsysMonitorEnter(); + NS_EXTERN SYSCALL_FUNC(void) guardedsysMonitorExit(); + + NS_EXTERN SYSCALL_FUNC(void) guardedsysNew(); + + NS_EXTERN SYSCALL_FUNC(void) guardedsysNewNDArray(); + NS_EXTERN SYSCALL_FUNC(void) guardedsysNew3DArray(); + NS_EXTERN SYSCALL_FUNC(void) guardedsysNew2DArray(); + + NS_EXTERN SYSCALL_FUNC(void) guardedsysNewByteArray(); + NS_EXTERN SYSCALL_FUNC(void) guardedsysNewCharArray(); + NS_EXTERN SYSCALL_FUNC(void) guardedsysNewIntArray(); + NS_EXTERN SYSCALL_FUNC(void) guardedsysNewLongArray(); + NS_EXTERN SYSCALL_FUNC(void) guardedsysNewShortArray(); + NS_EXTERN SYSCALL_FUNC(void) guardedsysNewBooleanArray(); + NS_EXTERN SYSCALL_FUNC(void) guardedsysNewDoubleArray(); + NS_EXTERN SYSCALL_FUNC(void) guardedsysNewFloatArray(); + NS_EXTERN SYSCALL_FUNC(void) guardedsysNewObjectArray(); +} + +#endif // _X86_SYSCALLS_RUNTIME_H_ diff --git a/ef/Runtime/System/md/x86/x86Win32ExceptionHandler.h b/ef/Runtime/System/md/x86/x86Win32ExceptionHandler.h new file mode 100644 index 000000000000..73c736959a5b --- /dev/null +++ b/ef/Runtime/System/md/x86/x86Win32ExceptionHandler.h @@ -0,0 +1,80 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +// x86Win32_Exception.cpp +// +// simon + +#if defined(_WIN32) || defined(LINUX) + +#ifndef _X86WIN32_EXCEPTION_H_ +#define _X86WIN32_EXCEPTION_H_ + +#include + +#include "SysCallsRuntime.h" +#include "Fundamentals.h" +#include "LogModule.h" + +struct JavaObject; +struct CacheEntry; + +extern void* sysInvokeNativeStubs[]; + + +//-------------------------------------------------------------------------------- +// Do not mess with ordering! +struct Context +{ + // save registers + Uint32 EBX; + Uint32 ESI; + Uint32 EDI; + + Uint32* sourceEBP; + Uint32* sucessorEBP; + + Uint8* sourceAddress; + + Uint32* restoreESP; // where ESP should be set if returning back to this frame + + CacheEntry* sourceCE; + CacheEntry* successorCE; + + JavaObject* object; +}; + +#ifndef LINUX +NS_EXTERN EXCEPTION_DISPOSITION win32HardwareThrow(struct _EXCEPTION_RECORD *ExceptionRecord, + void * EstablisherFrame, + struct _CONTEXT *ContextRecord, + void * DispatcherContext); +NS_EXTERN EXCEPTION_DISPOSITION win32HardwareThrowExit(struct _EXCEPTION_RECORD *ExceptionRecord, + void * EstablisherFrame, + struct _CONTEXT *ContextRecord, + void * DispatcherContext); +#endif + +#ifdef DEBUG +void printContext(LogModuleObject &f, Context* context); +#endif // DEBUG + + +//-------------------------------------------------------------------------------- + +#endif // _X86WIN32_EXCEPTION_H_ +#endif // _WIN32 diff --git a/ef/Runtime/System/md/x86/x86Win32InvokeNative.cpp b/ef/Runtime/System/md/x86/x86Win32InvokeNative.cpp new file mode 100644 index 000000000000..544d191baf57 --- /dev/null +++ b/ef/Runtime/System/md/x86/x86Win32InvokeNative.cpp @@ -0,0 +1,503 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +// +// +// A per function stub should look like this (N is the number of incoming arguments) +// +// functionStub: +// push $function +// jmp sysInvokeNative##N +// +// WARNING 1 -- the sysInvokeNative method must be defined with 'static' identifiers, otherwise +// MSDev will fill the sysInvokeNativeStubs table with pointers to a jump vector, rather than +// pointers to the real thing. +// +// WARNING 2 -- a check in x86Win32ExceptionHandler.cpp makes the following assumption +// For sysInvokeNativeN() where 0 <= N < 6 +// the address to return after the call is methodStart + 9 + 5N +// For sysInvokeNative(N) where 6 <= N < 256 +// the address to return after the call is methodStart + 23 +// +// If the sysInvokeNative methods change, the exception handler's check must also be changed +// + +#if defined(WIN32) + +#include "Fundamentals.h" + +#define sysInvokeNative(N) \ +static __declspec(naked) NS_NATIVECALL(void) sysInvokeNative##N() \ +{ \ + __asm { \ + __asm pop eax /* pop the function adress */ \ + \ + __asm push ebp /************************************/ \ + __asm mov ebp,esp /* */ \ + __asm push edi /* PROLOG */ \ + __asm push esi /* */ \ + __asm push ebx /************************************/ \ + \ + __asm mov edx,N /* %edx = nArgs */ \ +__asm loopHeader: \ + __asm lea ecx,[esp+16+4*N] /* %ecx = %esp + 16 + 4 * nArgs */ \ + __asm push [ecx] /* push original argument */ \ + __asm dec edx /* nArgs -= 1 */ \ + __asm jne loopHeader /* loop over */ \ + __asm call eax /* call the native function */ \ + \ + __asm mov esp,ebp /********************************** */ \ + __asm pop ebp /* EPILOG */ \ + __asm ret (4*N) /************************************/ \ + } \ +} + + +static __declspec(naked) NS_NATIVECALL(void) sysInvokeNative0() +{ + __asm { + pop eax + + push ebp + mov ebp,esp + push edi + push esi + push ebx + + call eax + + mov esp,ebp + pop ebp + ret + } +} + +static __declspec(naked) NS_NATIVECALL(void) sysInvokeNative1() +{ + __asm { + pop eax + + push ebp + mov ebp,esp + push edi + push esi + push ebx + + mov ecx,[esp+20] + push ecx + call eax + + mov esp,ebp + pop ebp + ret 4 + } +} + +static __declspec(naked) NS_NATIVECALL(void) sysInvokeNative2() +{ + __asm { + pop eax + + push ebp + mov ebp,esp + push edi + push esi + push ebx + + mov ecx,[esp+24] + push ecx + mov ecx,[esp+24] + push ecx + call eax + + mov esp,ebp + pop ebp + ret 8 + } +} + +static __declspec(naked) NS_NATIVECALL(void) sysInvokeNative3() +{ + __asm { + pop eax + + push ebp + mov ebp,esp + push edi + push esi + push ebx + + mov ecx,[esp+28] + push ecx + mov ecx,[esp+28] + push ecx + mov ecx,[esp+28] + push ecx + call eax + + mov esp,ebp + pop ebp + ret 12 + } +} + +static __declspec(naked) NS_NATIVECALL(void) sysInvokeNative4() +{ + __asm { + pop eax + + push ebp + mov ebp,esp + push edi + push esi + push ebx + + mov ecx,[esp+32] + push ecx + mov ecx,[esp+32] + push ecx + mov ecx,[esp+32] + push ecx + mov ecx,[esp+32] + push ecx + call eax + + mov esp,ebp + pop ebp + ret 16 + } +} + +static __declspec(naked) NS_NATIVECALL(void) sysInvokeNative5() +{ + __asm { + pop eax + + push ebp + mov ebp,esp + push edi + push esi + push ebx + + mov ecx,[esp+36] + push ecx + mov ecx,[esp+36] + push ecx + mov ecx,[esp+36] + push ecx + mov ecx,[esp+36] + push ecx + mov ecx,[esp+36] + push ecx + call eax + + mov esp,ebp + pop ebp + ret 20 + } +} + +sysInvokeNative(6) +sysInvokeNative(7) +sysInvokeNative(8) +sysInvokeNative(9) +sysInvokeNative(10) +sysInvokeNative(11) +sysInvokeNative(12) +sysInvokeNative(13) +sysInvokeNative(14) +sysInvokeNative(15) +sysInvokeNative(16) +sysInvokeNative(17) +sysInvokeNative(18) +sysInvokeNative(19) +sysInvokeNative(20) +sysInvokeNative(21) +sysInvokeNative(22) +sysInvokeNative(23) +sysInvokeNative(24) +sysInvokeNative(25) +sysInvokeNative(26) +sysInvokeNative(27) +sysInvokeNative(28) +sysInvokeNative(29) +sysInvokeNative(30) +sysInvokeNative(31) +sysInvokeNative(32) +sysInvokeNative(33) +sysInvokeNative(34) +sysInvokeNative(35) +sysInvokeNative(36) +sysInvokeNative(37) +sysInvokeNative(38) +sysInvokeNative(39) +sysInvokeNative(40) +sysInvokeNative(41) +sysInvokeNative(42) +sysInvokeNative(43) +sysInvokeNative(44) +sysInvokeNative(45) +sysInvokeNative(46) +sysInvokeNative(47) +sysInvokeNative(48) +sysInvokeNative(49) +sysInvokeNative(50) +sysInvokeNative(51) +sysInvokeNative(52) +sysInvokeNative(53) +sysInvokeNative(54) +sysInvokeNative(55) +sysInvokeNative(56) +sysInvokeNative(57) +sysInvokeNative(58) +sysInvokeNative(59) +sysInvokeNative(60) +sysInvokeNative(61) +sysInvokeNative(62) +sysInvokeNative(63) +sysInvokeNative(64) +sysInvokeNative(65) +sysInvokeNative(66) +sysInvokeNative(67) +sysInvokeNative(68) +sysInvokeNative(69) +sysInvokeNative(70) +sysInvokeNative(71) +sysInvokeNative(72) +sysInvokeNative(73) +sysInvokeNative(74) +sysInvokeNative(75) +sysInvokeNative(76) +sysInvokeNative(77) +sysInvokeNative(78) +sysInvokeNative(79) +sysInvokeNative(80) +sysInvokeNative(81) +sysInvokeNative(82) +sysInvokeNative(83) +sysInvokeNative(84) +sysInvokeNative(85) +sysInvokeNative(86) +sysInvokeNative(87) +sysInvokeNative(88) +sysInvokeNative(89) +sysInvokeNative(90) +sysInvokeNative(91) +sysInvokeNative(92) +sysInvokeNative(93) +sysInvokeNative(94) +sysInvokeNative(95) +sysInvokeNative(96) +sysInvokeNative(97) +sysInvokeNative(98) +sysInvokeNative(99) +sysInvokeNative(100) +sysInvokeNative(101) +sysInvokeNative(102) +sysInvokeNative(103) +sysInvokeNative(104) +sysInvokeNative(105) +sysInvokeNative(106) +sysInvokeNative(107) +sysInvokeNative(108) +sysInvokeNative(109) +sysInvokeNative(110) +sysInvokeNative(111) +sysInvokeNative(112) +sysInvokeNative(113) +sysInvokeNative(114) +sysInvokeNative(115) +sysInvokeNative(116) +sysInvokeNative(117) +sysInvokeNative(118) +sysInvokeNative(119) +sysInvokeNative(120) +sysInvokeNative(121) +sysInvokeNative(122) +sysInvokeNative(123) +sysInvokeNative(124) +sysInvokeNative(125) +sysInvokeNative(126) +sysInvokeNative(127) +sysInvokeNative(128) +sysInvokeNative(129) +sysInvokeNative(130) +sysInvokeNative(131) +sysInvokeNative(132) +sysInvokeNative(133) +sysInvokeNative(134) +sysInvokeNative(135) +sysInvokeNative(136) +sysInvokeNative(137) +sysInvokeNative(138) +sysInvokeNative(139) +sysInvokeNative(140) +sysInvokeNative(141) +sysInvokeNative(142) +sysInvokeNative(143) +sysInvokeNative(144) +sysInvokeNative(145) +sysInvokeNative(146) +sysInvokeNative(147) +sysInvokeNative(148) +sysInvokeNative(149) +sysInvokeNative(150) +sysInvokeNative(151) +sysInvokeNative(152) +sysInvokeNative(153) +sysInvokeNative(154) +sysInvokeNative(155) +sysInvokeNative(156) +sysInvokeNative(157) +sysInvokeNative(158) +sysInvokeNative(159) +sysInvokeNative(160) +sysInvokeNative(161) +sysInvokeNative(162) +sysInvokeNative(163) +sysInvokeNative(164) +sysInvokeNative(165) +sysInvokeNative(166) +sysInvokeNative(167) +sysInvokeNative(168) +sysInvokeNative(169) +sysInvokeNative(170) +sysInvokeNative(171) +sysInvokeNative(172) +sysInvokeNative(173) +sysInvokeNative(174) +sysInvokeNative(175) +sysInvokeNative(176) +sysInvokeNative(177) +sysInvokeNative(178) +sysInvokeNative(179) +sysInvokeNative(180) +sysInvokeNative(181) +sysInvokeNative(182) +sysInvokeNative(183) +sysInvokeNative(184) +sysInvokeNative(185) +sysInvokeNative(186) +sysInvokeNative(187) +sysInvokeNative(188) +sysInvokeNative(189) +sysInvokeNative(190) +sysInvokeNative(191) +sysInvokeNative(192) +sysInvokeNative(193) +sysInvokeNative(194) +sysInvokeNative(195) +sysInvokeNative(196) +sysInvokeNative(197) +sysInvokeNative(198) +sysInvokeNative(199) +sysInvokeNative(200) +sysInvokeNative(201) +sysInvokeNative(202) +sysInvokeNative(203) +sysInvokeNative(204) +sysInvokeNative(205) +sysInvokeNative(206) +sysInvokeNative(207) +sysInvokeNative(208) +sysInvokeNative(209) +sysInvokeNative(210) +sysInvokeNative(211) +sysInvokeNative(212) +sysInvokeNative(213) +sysInvokeNative(214) +sysInvokeNative(215) +sysInvokeNative(216) +sysInvokeNative(217) +sysInvokeNative(218) +sysInvokeNative(219) +sysInvokeNative(220) +sysInvokeNative(221) +sysInvokeNative(222) +sysInvokeNative(223) +sysInvokeNative(224) +sysInvokeNative(225) +sysInvokeNative(226) +sysInvokeNative(227) +sysInvokeNative(228) +sysInvokeNative(229) +sysInvokeNative(230) +sysInvokeNative(231) +sysInvokeNative(232) +sysInvokeNative(233) +sysInvokeNative(234) +sysInvokeNative(235) +sysInvokeNative(236) +sysInvokeNative(237) +sysInvokeNative(238) +sysInvokeNative(239) +sysInvokeNative(240) +sysInvokeNative(241) +sysInvokeNative(242) +sysInvokeNative(243) +sysInvokeNative(244) +sysInvokeNative(245) +sysInvokeNative(246) +sysInvokeNative(247) +sysInvokeNative(248) +sysInvokeNative(249) +sysInvokeNative(250) +sysInvokeNative(251) +sysInvokeNative(252) +sysInvokeNative(253) +sysInvokeNative(254) +sysInvokeNative(255) + +#define STUB(N) sysInvokeNative##N + +void* sysInvokeNativeStubs[1024] = { + STUB(0), STUB(1), STUB(2), STUB(3), STUB(4), STUB(5), STUB(6), STUB(7), + STUB(8), STUB(9), STUB(10), STUB(11), STUB(12), STUB(13), STUB(14), STUB(15), + STUB(16), STUB(17), STUB(18), STUB(19), STUB(20), STUB(21), STUB(22), STUB(23), + STUB(24), STUB(25), STUB(26), STUB(27), STUB(28), STUB(29), STUB(30), STUB(31), + STUB(32), STUB(33), STUB(34), STUB(35), STUB(36), STUB(37), STUB(38), STUB(39), + STUB(40), STUB(41), STUB(42), STUB(43), STUB(44), STUB(45), STUB(46), STUB(47), + STUB(48), STUB(49), STUB(50), STUB(51), STUB(52), STUB(53), STUB(54), STUB(55), + STUB(56), STUB(57), STUB(58), STUB(59), STUB(60), STUB(61), STUB(62), STUB(63), + STUB(64), STUB(65), STUB(66), STUB(67), STUB(68), STUB(69), STUB(70), STUB(71), + STUB(72), STUB(73), STUB(74), STUB(75), STUB(76), STUB(77), STUB(78), STUB(79), + STUB(80), STUB(81), STUB(82), STUB(83), STUB(84), STUB(85), STUB(86), STUB(87), + STUB(88), STUB(89), STUB(90), STUB(91), STUB(92), STUB(93), STUB(94), STUB(95), + STUB(96), STUB(97), STUB(98), STUB(99), STUB(100), STUB(101), STUB(102), STUB(103), + STUB(104), STUB(105), STUB(106), STUB(107), STUB(108), STUB(109), STUB(110), STUB(111), + STUB(112), STUB(113), STUB(114), STUB(115), STUB(116), STUB(117), STUB(118), STUB(119), + STUB(120), STUB(121), STUB(122), STUB(123), STUB(124), STUB(125), STUB(126), STUB(127), + STUB(128), STUB(129), STUB(130), STUB(131), STUB(132), STUB(133), STUB(134), STUB(135), + STUB(136), STUB(137), STUB(138), STUB(139), STUB(140), STUB(141), STUB(142), STUB(143), + STUB(144), STUB(145), STUB(146), STUB(147), STUB(148), STUB(149), STUB(150), STUB(151), + STUB(152), STUB(153), STUB(154), STUB(155), STUB(156), STUB(157), STUB(158), STUB(159), + STUB(160), STUB(161), STUB(162), STUB(163), STUB(164), STUB(165), STUB(166), STUB(167), + STUB(168), STUB(169), STUB(170), STUB(171), STUB(172), STUB(173), STUB(174), STUB(175), + STUB(176), STUB(177), STUB(178), STUB(179), STUB(180), STUB(181), STUB(182), STUB(183), + STUB(184), STUB(185), STUB(186), STUB(187), STUB(188), STUB(189), STUB(190), STUB(191), + STUB(192), STUB(193), STUB(194), STUB(195), STUB(196), STUB(197), STUB(198), STUB(199), + STUB(200), STUB(201), STUB(202), STUB(203), STUB(204), STUB(205), STUB(206), STUB(207), + STUB(208), STUB(209), STUB(210), STUB(211), STUB(212), STUB(213), STUB(214), STUB(215), + STUB(216), STUB(217), STUB(218), STUB(219), STUB(220), STUB(221), STUB(222), STUB(223), + STUB(224), STUB(225), STUB(226), STUB(227), STUB(228), STUB(229), STUB(230), STUB(231), + STUB(232), STUB(233), STUB(234), STUB(235), STUB(236), STUB(237), STUB(238), STUB(239), + STUB(240), STUB(241), STUB(242), STUB(243), STUB(244), STUB(245), STUB(246), STUB(247), + STUB(248), STUB(249), STUB(250), STUB(251), STUB(252), STUB(253), STUB(254), STUB(255), +}; + +#endif // WIN32 diff --git a/ef/Runtime/System/md/x86/x86Win32Thread.cpp b/ef/Runtime/System/md/x86/x86Win32Thread.cpp new file mode 100644 index 000000000000..62cb6ef39ebb --- /dev/null +++ b/ef/Runtime/System/md/x86/x86Win32Thread.cpp @@ -0,0 +1,111 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#include "Thread.h" + +#include "Exceptions.h" +#include "NativeCodeCache.h" +#include "prprf.h" + +void _suspendThread(HANDLE handle) { + DWORD dw = SuspendThread(handle); + assert(dw != 0xFFFFFFFF); +} + +void _resumeThread(HANDLE handle) { + ResumeThread(handle); +} + +bool _getThreadContext(HANDLE handle, ThreadContext& context) { + context.ContextFlags = CONTEXT_CONTROL; + return (GetThreadContext(handle,&context) != 0); +} + +void _setThreadContext(HANDLE handle, ThreadContext& context) { + if (!SetThreadContext(handle,&context)) + assert(false); +} + +Int32* _getFramePointer(ThreadContext& context) { + return (Int32*)context.Ebp; +} + +void _setFramePointer(ThreadContext& context, Int32* v) { + context.Ebp = (DWORD)v; +} + +Uint8* _getInstructionPointer(ThreadContext& context) { + return (Uint8*)context.Eip; +} + +void _setInstructionPointer(ThreadContext& context, Uint8* v) { + context.Eip = (DWORD)v; +} + +void Thread::realHandle() { // sets up the OS handles + HANDLE thr = GetCurrentThread(); + HANDLE p = GetCurrentProcess(); + if (!DuplicateHandle(p,thr,p,&handle,THREAD_ALL_ACCESS,FALSE,0)) + sysThrowNamedException("java/lang/ThreadDeathException"); +} + +/* Special invoke for threads. + + We prepare the stack for a newborn thread as follows. + First we push the hardware exception handler (as {previous handler, new handler}), + and set fs:[0] to point to this structure. This will make win32 call new handler when + a hardware exception fires (/0, *NULL, or illegal instruction). + + Second, we push EBP as it it is upon entry to this routine, followed by a pointer to uncaughtException, + followed by the sentinel NULL. Then we prepare to call __invoke() which corresponds to Method::invoke() + by pushing the arguments in reverse order. Now, regardless whether invoke() returns normally or through + an uncaught exception, we will return to the line 'add esp,24' which is where we clean up afterwards. + + For the entry set-up to uncaughtException() see uncaughtExceptionExit() in x86Win32ExceptionHandler.cpp in + Runtime/System/md/x86. + */ +// called by Thread::invoke() and is only used to avoid assuming a calling convention for C++ methods. +static void __cdecl +__invoke(Method* m, JavaObject* obj, JavaObject* arr[], int sz) { + m->invoke(obj,arr,sz); +} + +void +Thread::invoke(Method* m, JavaObject* obj, JavaObject* arr[], int sz) { + DWORD w32 = (DWORD)win32HardwareThrow; + DWORD uE = (DWORD)uncaughtException; + __asm { + push w32 + push fs:[0] + mov fs:[0],esp + push ebp + push uE + push NULL + mov ecx,esp + push sz + push arr + push obj + push m + mov ebp,ecx + call __invoke + add esp,24 // pop 4 arguments, NULL, and uncaughtException + pop ebp + pop ecx + mov fs:[0],ecx + pop ecx // pop win32HardwareThrow + } +} diff --git a/ef/Runtime/System/md/x86/x86Win32Thread.h b/ef/Runtime/System/md/x86/x86Win32Thread.h new file mode 100644 index 000000000000..8583f581a301 --- /dev/null +++ b/ef/Runtime/System/md/x86/x86Win32Thread.h @@ -0,0 +1,31 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#ifndef _Win32Thread +#define _Win32Thread + +#define GetPassedException(E) __asm { mov E,ecx } + +void Thread::realHandle(); +void Thread::invoke(Method* m,JavaObject* obj,JavaObject* arr[],int sz); + +#endif // _Win32Thread + + + + + diff --git a/ef/Tools/Burg/.cvsignore b/ef/Tools/Burg/.cvsignore new file mode 100644 index 000000000000..0b765aa7a2e2 --- /dev/null +++ b/ef/Tools/Burg/.cvsignore @@ -0,0 +1,2 @@ +*tab.c +*tab.h diff --git a/ef/Tools/Burg/Makefile b/ef/Tools/Burg/Makefile new file mode 100644 index 000000000000..0857f2539c27 --- /dev/null +++ b/ef/Tools/Burg/Makefile @@ -0,0 +1,48 @@ +#!gmake +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +####################################################################### +# (1) Include manifest file # +####################################################################### + +include manifest.mn + +####################################################################### +# (2) Include "component" configuration information. # +####################################################################### + +include $(DEPTH)/config/config.mk + +####################################################################### +# (3) Include "local" platform-dependent assignments (OPTIONAL). # +####################################################################### + + + +####################################################################### +# (4) Execute "component" rules. (OPTIONAL) # +####################################################################### + +include $(DEPTH)/config/rules.mk + +####################################################################### +# (7) Execute "local" rules. (OPTIONAL). # +####################################################################### + +include rules.mk + + diff --git a/ef/Tools/Burg/macbuild/BURGPPCDebug.prj b/ef/Tools/Burg/macbuild/BURGPPCDebug.prj new file mode 100644 index 000000000000..8403ff84f297 Binary files /dev/null and b/ef/Tools/Burg/macbuild/BURGPPCDebug.prj differ diff --git a/ef/Tools/Burg/manifest.mn b/ef/Tools/Burg/manifest.mn new file mode 100644 index 000000000000..da2bfb59c0b8 --- /dev/null +++ b/ef/Tools/Burg/manifest.mn @@ -0,0 +1,44 @@ +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +DEPTH = ../.. + + +CSRCS = be.c \ + burs.c \ + closure.c \ + delta.c \ + fe.c \ + item.c \ + lex.c \ + list.c \ + main.c \ + map.c \ + nonterminal.c \ + operator.c \ + pattern.c \ + plank.c \ + queue.c \ + rule.c \ + string.c \ + symtab.c \ + table.c \ + trim.c \ + zalloc.c \ + y.tab.c \ + $(NULL) + +PROGRAM = burg diff --git a/ef/Tools/Burg/rules.mk b/ef/Tools/Burg/rules.mk new file mode 100644 index 000000000000..cc0cfba377b6 --- /dev/null +++ b/ef/Tools/Burg/rules.mk @@ -0,0 +1,31 @@ +# +# Rules to generate y.tab.h and y.tab.c +# +# Redefine this rule because of the warnings. !!!! +$(OBJDIR)/y.tab.$(OBJ_SUFFIX): y.tab.c + @$(MAKE_OBJDIR) +ifeq ($(OS_ARCH), WINNT) + $(CC) -Fo$@ -c $(CFLAGS) $< +else + $(CC) -o $@ -c $(CFLAGS) $< +endif + +# +# Extra dependencies. +# +lex.c: y.tab.h + +y.tab.c y.tab.h: gram.y + $(YACC) $(YACC_FLAGS) -d $< + +# +# Extra cleaning. +# + +clobber:: + rm -f y.tab.c y.tab.h + +realclean clobber_all:: + rm -f y.tab.c y.tab.h + +export:: $(PROGRAM) \ No newline at end of file diff --git a/ef/Tools/Disass/Disass.c b/ef/Tools/Disass/Disass.c new file mode 100644 index 000000000000..5bf1a2f33e20 --- /dev/null +++ b/ef/Tools/Disass/Disass.c @@ -0,0 +1,131 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#include +#include +#include +#include +#include "Disass.h" +#include "VM.h" +#include "XDisAsm.h" + +Uint32 knownStub[] = +{ + 0x55076A50, 0x04246C8D, 0x6A535756, 0x73E85500, + 0x89FFFFFB, 0x64500445, 0x000035FF, 0xC7640000, + 0x00000005, 0xFFFFFF00, 0x0875FFFF, 0x000023E8, + 0x058F6400, 0x00000000, 0x840FC00B, 0x0002C832, + 0x3FE8F08B, 0x8BFFFFFB, 0x5F5B5BC6, 0x59595D5E, + 0x1860FF58, 0x57565553 +}; +const Uint32 knownStubSize = sizeof(knownStub); + +DWORD __cdecl +RNIGetCompatibleVersion() +{ + return RNIVER; +} + +static long printMethod(struct HDisass *pThis, MethodBlock* method) +{ + Uint8* code; + Uint8* limit; + Uint8* start; + CodeCacheEntry* codeCache; + + code = method->code; + + // If the code is not yet compiled then the first instruction + // to be executed will be a call to the compile stub. + if (code[0] == CALL_OPCODE) { + Int32 offset; + Uint8* staticCompileStub; + Uint8* newCompileStub; + + staticCompileStub = &code[5] + *(Int32 *) &code[1]; + + if (memcmp(staticCompileStub, knownStub, knownStubSize) != 0) { + fprintf(stderr, "Unknown stub for this method"); + return Disass_UNKNOWN_STUB; + } + + newCompileStub = (Uint8 *) malloc(knownStubSize); + memcpy(newCompileStub, staticCompileStub, knownStubSize); + + // Replace the call offsets. + offset = *(Int32 *) &staticCompileStub[15]; + *(Int32 *) &newCompileStub[15] = offset + (staticCompileStub - newCompileStub); + + offset = *(Int32 *) &staticCompileStub[45]; + *(Int32 *) &newCompileStub[45] = offset + (staticCompileStub - newCompileStub); + + offset = *(Int32 *) &staticCompileStub[67]; + *(Int32 *) &newCompileStub[67] = offset + (staticCompileStub - newCompileStub); + + // Put a return at the end of the code instead of the jump code. + newCompileStub[81] = RETURN_OPCODE; + + _asm { + call stub + jmp end + stub: + push method + jmp newCompileStub + end: + } + + code = method->code; + } + + codeCache = (CodeCacheEntry *) (code - sizeof(CodeCacheEntry)); + limit = ((Uint8 *) codeCache) + codeCache->length + 4; + + start = code; + while ((code < limit) && (0 != *(Uint32 *) code)) { + fprintf(stdout, "%p:\t", code - start); + fprintf(stdout, "%s\n", disasmx86(code - start, &code, limit + 1, kDisAsmFlag32BitSegments)); + } + + return Disass_SUCCESS; +} + +__declspec(dllexport) long __cdecl +Disass_disassemble(struct HDisass *pThis, struct Hjava_lang_String *jClassName, struct Hjava_lang_String *jMethodName, + struct Hjava_lang_String *jSignature) +{ + ClassClass* classclass; + MethodBlock* method; + + char cClassName[1024]; + char cMethodName[1024]; + char cSignature[1024]; + + javaString2CString(jClassName, cClassName, 1024); + javaString2CString(jMethodName, cMethodName, 1024); + javaString2CString(jSignature, cSignature, 1024); + + classclass = FindClassEx(cClassName, FINDCLASSEX_IGNORECASE); + if (classclass == NULL) + return Disass_CLASS_NOT_FOUND; + + method = (MethodBlock*) Class_GetMethod(classclass, cMethodName, cSignature); + if (method == NULL) + return Disass_METHOD_NOT_FOUND; + + return printMethod(pThis, method); +} + diff --git a/ef/Tools/Disass/Disass.def b/ef/Tools/Disass/Disass.def new file mode 100644 index 000000000000..1e2eb536397d --- /dev/null +++ b/ef/Tools/Disass/Disass.def @@ -0,0 +1,4 @@ +LIBRARY DISASS + +EXPORTS + RNIGetCompatibleVersion diff --git a/ef/Tools/Disass/Disass.dsp b/ef/Tools/Disass/Disass.dsp new file mode 100644 index 000000000000..af927e532874 --- /dev/null +++ b/ef/Tools/Disass/Disass.dsp @@ -0,0 +1,156 @@ +# Microsoft Developer Studio Project File - Name="Disass" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 5.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=Disass - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "Disass.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "Disass.mak" CFG="Disass - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "Disass - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "Disass - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "Disass - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386 + +!ELSEIF "$(CFG)" == "Disass - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c +# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "$(JAVASDK)\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib $(JAVASDK)\lib\i386\msjava.lib /nologo /subsystem:windows /dll /debug /machine:I386 /out:"Disass.dll" /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "Disass - Win32 Release" +# Name "Disass - Win32 Debug" +# Begin Source File + +SOURCE=.\Disass.c +# End Source File +# Begin Source File + +SOURCE=.\Disass.class + +!IF "$(CFG)" == "Disass - Win32 Release" + +!ELSEIF "$(CFG)" == "Disass - Win32 Debug" + +# Begin Custom Build - Generate Disass.h +InputPath=.\Disass.class + +"Disass.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + $(JAVASDK)\bin\msjavah -o Disass.h Disass + +# End Custom Build + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\Disass.def +# End Source File +# Begin Source File + +SOURCE=.\Disass.h +# End Source File +# Begin Source File + +SOURCE=.\Disass.java + +!IF "$(CFG)" == "Disass - Win32 Release" + +!ELSEIF "$(CFG)" == "Disass - Win32 Debug" + +# Begin Custom Build - Compile Disass.class +InputPath=.\Disass.java +InputName=Disass + +"Disass.class" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + $(JAVASDK)\bin\jvc $(InputName) + +# End Custom Build + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\VM.h +# End Source File +# Begin Source File + +SOURCE=.\XDisAsm.c +# End Source File +# Begin Source File + +SOURCE=.\XDisAsm.h +# End Source File +# Begin Source File + +SOURCE=.\XDisAsmTable.c +# End Source File +# End Target +# End Project diff --git a/ef/Tools/Disass/Disass.dsw b/ef/Tools/Disass/Disass.dsw new file mode 100644 index 000000000000..ac23b19e5438 --- /dev/null +++ b/ef/Tools/Disass/Disass.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 5.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "Disass"=.\Disass.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/ef/Tools/Disass/Disass.java b/ef/Tools/Disass/Disass.java new file mode 100644 index 000000000000..38b8bed71ff8 --- /dev/null +++ b/ef/Tools/Disass/Disass.java @@ -0,0 +1,68 @@ +/* -*- Mode: Java; 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +public class Disass +{ + final static int SUCCESS = 0; + final static int UNKNOWN_STUB = 1; + final static int METHOD_NOT_FOUND = 2; + final static int CLASS_NOT_FOUND = 3; + + public native int disassemble(String className, String methodName, String signature); + + Disass() + { + System.loadLibrary("Disass"); + } + + public static void main(String argv[]) + { + if (argv.length != 3) { + System.out.println("usage: Disass "); + return; + } + + Disass disass = new Disass(); + + switch (disass.disassemble(argv[0], argv[1], argv[2])) { + case SUCCESS: + break; + + case UNKNOWN_STUB: + System.out.println("Was unable to compile the method (unknown compile stub)"); + break; + + case METHOD_NOT_FOUND: + System.out.println("Found the class " + argv[0] + " but cannot find the method " + + argv[1] + argv[2] + "."); + break; + + case CLASS_NOT_FOUND: + System.out.println("Cannot find the class " + argv[0] + "."); + break; + } + } + + public void test(int a) + { + int j = 0; + + for (int i = 0; i < 100; i++) { + j += i; + } + } +} diff --git a/ef/Tools/Disass/Disass.opt b/ef/Tools/Disass/Disass.opt new file mode 100644 index 000000000000..3599f1b0124b --- /dev/null +++ b/ef/Tools/Disass/Disass.opt @@ -0,0 +1 @@ +ÐÏࡱ \ No newline at end of file diff --git a/ef/Tools/Disass/README b/ef/Tools/Disass/README new file mode 100644 index 000000000000..d506b2ffda9e --- /dev/null +++ b/ef/Tools/Disass/README @@ -0,0 +1,6 @@ +The following files were deleted from this directory because they +were subject to the GPL license: + + XDisAsm.c + XDisAsm.h + XDisAsmTable.c diff --git a/ef/Tools/Disass/VM.h b/ef/Tools/Disass/VM.h new file mode 100644 index 000000000000..81b86f76814d --- /dev/null +++ b/ef/Tools/Disass/VM.h @@ -0,0 +1,43 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#ifndef _VM_H_ +#define _VM_H_ + +typedef unsigned int Uint32; +typedef signed int Int32; +typedef unsigned char Uint8; +typedef signed char Int8; + +typedef struct MethodBlock_t +{ + Uint32 pad[6]; + Uint8* code; +} MethodBlock; + +typedef struct CodeCacheEntry_t +{ + Uint32 pad1[2]; + Uint32 length; + Uint32 pad2[2]; + MethodBlock* methodBlock; +} CodeCacheEntry; + +const Uint32 CALL_OPCODE = 0xE8; +const Uint32 RETURN_OPCODE = 0xC3; + +#endif /* _VM_H_ */ diff --git a/ef/Tools/JavaH/HeaderGenerator.cpp b/ef/Tools/JavaH/HeaderGenerator.cpp new file mode 100644 index 000000000000..bf537a03cb17 --- /dev/null +++ b/ef/Tools/JavaH/HeaderGenerator.cpp @@ -0,0 +1,312 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#include "HeaderGenerator.h" +#include "plstr.h" +#include "prprf.h" + +#include "CUtils.h" +#include "StringUtils.h" +#include "Pool.h" +#include "FieldOrMethod.h" + +#ifdef USE_PR_IO +#define PR_fprintf fprintf +#define PR_Write fwrite +#define PRFileDesc FILE +#endif + +HeaderGenerator::HeaderGenerator(ClassCentral ¢ral) : central(central) +{ + /* Default directory to write stuff into is the current directory */ + headerDir = PL_strdup("."); + tempDir = PL_strdup("/tmp"); +} + +HeaderGenerator::~HeaderGenerator() +{ + //free(headerDir); + //free(tempDir); +} + + +void HeaderGenerator::setClassPath(const char *classPath) +{ + central.setClassPath(classPath); +} + + +void HeaderGenerator::setOutputDir(const char *dir) +{ + //free(headerDir); + + headerDir = (dir) ? PL_strdup(dir) : PL_strdup("."); +} + +void HeaderGenerator::setTempDir(const char *dir) +{ + //free(tempDir); + + tempDir = (dir) ? PL_strdup(dir) : PL_strdup("/tmp"); +} + + +bool HeaderGenerator::writeFile(const char *className) +{ + ClassFileSummary *summ; + + try { + summ = ¢ral.addClass(className); + } catch (VerifyError err) { +#ifdef DEBUG + printf("VerifyError loading class %s: %d\n", className, err.cause); +#endif + return false; + } + + TemporaryStringCopy copy(className); + char *cname = copy; + + /* Replace slashes in the className with underscores */ + mangleClassName(cname, '/'); + + /* The 2 at the end is for the NULL character and an extra slash at the + * end of the directory name + */ + uint32 fileLen = strlen(headerDir)+strlen(className)+sizeof(".h")+5; + + TemporaryBuffer buffer(fileLen); + char *fileName = buffer; + + PR_snprintf(fileName, fileLen, "%s/%s.h", headerDir, cname); + +#ifndef USE_PR_IO + FileDesc desc(fileName, (PR_WRONLY | PR_CREATE_FILE), 00644); + PRFileDesc *fp = desc; +#else + FILE *fp = fopen(fileName, "w"); +#endif + + if (!fp) + return false; + + writeHeader(cname, fp); + + bool ret = genHeaderFile(*summ, fp); + + if (!ret) + return false; + + writeFooter(cname, fp); + +#ifndef USE_PR_IO + desc.close(); +#else + fclose (fp); +#endif + + /* Write the headers for our parent objects if they exist */ + if (needParents()) { + const char *parentName = getParentName(*summ->getReader()); + + if (parentName && !writeFile(parentName)) + return false; + } + + return ret; +} + +void HeaderGenerator::writeHeader(const char *cname, PRFileDesc *fp) +{ + PR_fprintf(fp, "#ifndef _%s_H_\n#define _%s_H_\n\n", cname, cname); +} + + +void HeaderGenerator::writeFooter(const char *cname, PRFileDesc *fp) +{ + PR_fprintf(fp, "#endif /* _%s_H_ */\n", cname); +} + +char *HeaderGenerator::getMangledName(const Type &type, bool asArray) +{ + switch (type.typeKind) { + case tkChar: + return (asArray) ? PL_strdup("char") : PL_strdup("int32 /* char */"); + break; + + case tkShort: + return (asArray) ? PL_strdup("int16") : PL_strdup("int32 /* short */"); + break; + + case tkInt: + return PL_strdup("int32"); + break; + + case tkByte: + return (asArray) ? PL_strdup("uint8") : PL_strdup("uint32 /* byte */"); + break; + + case tkBoolean: + return (asArray) ? PL_strdup("char") : PL_strdup("uint32 /* bool */"); + break; + + case tkLong: + return PL_strdup("int64"); + break; + + case tkFloat: + return PL_strdup("Flt32"); + break; + + case tkDouble: + return PL_strdup("Flt64"); + break; + + case tkVoid: + return PL_strdup("void"); + break; + + case tkObject: + case tkInterface: { + Class &clazz = *const_cast(static_cast(&type)); + TemporaryStringCopy copy(clazz.getName()); + char *nameCopy = copy; + mangleClassName(nameCopy, '.'); + int32 objNameLen = strlen(nameCopy)+ 1 + sizeof("Java_"); + char *objName = (char *) malloc(objNameLen); + PR_snprintf(objName, objNameLen, "Java_%s", nameCopy); + return objName; + } + + case tkArray: { + const Array &atype = *static_cast(&type); + char *elementString = getMangledName(atype.componentType, true); + assert(elementString); + int32 len = sizeof("ArrayOf_")+strlen(elementString)+1; + char *arrayStr = (char *) malloc(len); + PR_snprintf(arrayStr, len, "ArrayOf_%s", elementString); + + // NSPR needs to provide a way to free strings that it allocates +#ifdef DEBUG + free(elementString); +#endif + + return arrayStr; + } + + default: + return 0; + } +} + + +char *HeaderGenerator::getArgString(const Type &type) +{ + switch (type.typeKind) { + case tkObject: /* For objects, we always pass a pointer to the object */ + case tkInterface: + case tkArray: { + char *objArg = getMangledName(type); + assert(objArg); + objArg = (char *) realloc(objArg, strlen(objArg)+3); + PL_strcat(objArg, " *"); + return objArg; + } + + + default: + return getMangledName(type); + } + +} + + +void HeaderGenerator::addMangledName(ClassFileSummary &summ, + const Type &type, StringPool &sp) +{ + Type *ourType = summ.getThisClass(); + + /* No need to generate forward declarators for ourselves */ + if (ourType == &type) + return; + + /* XXX Note here that we still generate forward declarations for + * references to our parent types. These are infrequent, but still + * redundant. But they'll compile, so I'll come back some other day + * and filter them out -- kini + */ + + char *mangledObjName = 0; + mangledObjName = getMangledName(type); + + if (!mangledObjName) + verifyError(VerifyError::noClassDefFound); + + sp.intern(mangledObjName); + free((void *) mangledObjName); +} + + +void HeaderGenerator::genForwards(ClassFileSummary &summ, + StringPool &sp) +{ + /* So as not to generate duplicate forward declarations, we'll go + * through the fields and methods and put all object and array names into + * a StringPool, which we will use later to generate the actual + * forward declarations. + */ + + /* Go through the fields */ + const Field **fields = summ.getFields(); + uint32 fieldCount = summ.getFieldCount(); + + uint32 i; + for (i = 0; i < fieldCount; i++) { + const Type &type = fields[i]->getType(); + + if (type.typeKind == tkObject || type.typeKind == tkInterface || + type.typeKind == tkArray) + addMangledName(summ, type, sp); + } + + const Method **methods = summ.getMethods(); + uint32 methodCount = summ.getMethodCount(); + + for (i = 0; i < methodCount; i++) { + Method *m = (Method *) methods[i]; + const Signature &sig = m->getSignature(); + + if ((m->getModifiers() & CR_METHOD_NATIVE)) { + /* Generate forward declarators for the return type, if neccessary */ + if (sig.resultType->typeKind == tkObject || + sig.resultType->typeKind == tkInterface || + sig.resultType->typeKind == tkArray) + addMangledName(summ, *sig.resultType, sp); + + for (uint32 j = 0; j < sig.nArguments; j++) + if (sig.argumentTypes[j]->typeKind == tkObject || + sig.argumentTypes[j]->typeKind == tkInterface || + sig.argumentTypes[j]->typeKind == tkArray) + addMangledName(summ, *sig.argumentTypes[j], sp); + } + } + +} + + + + diff --git a/ef/Tools/JavaH/HeaderGenerator.h b/ef/Tools/JavaH/HeaderGenerator.h new file mode 100644 index 000000000000..3f5415543619 --- /dev/null +++ b/ef/Tools/JavaH/HeaderGenerator.h @@ -0,0 +1,175 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#ifndef _HEADER_GENERATOR_H_ +#define _HEADER_GENERATOR_H_ + +#include "ClassCentral.h" +#include "prio.h" + +/* A HeaderGenerator class generates C/C++ style headers from a + * java class file. It will generate stubs for native methods + * in the class, and depending on the kind of mechanism used, + * might also generate C structures to access the fields of the class. + * HeaderGenerator is an abstract class; headers for specific native-method + * dispatch mechanisms are generated by sub-classes of this class. + */ +class HeaderGenerator { +public: + /* Initialize a header generator. classPath, if non-zero, is a path to + * search for classes. If classPath is zero, the environment variable + * CLASSPATH is used to determine the class path. + */ + HeaderGenerator(ClassCentral ¢ral); + + virtual ~HeaderGenerator(); + + /* Set the class path to the given string classPath. classPath is a + * colon-separated list of canonical (Unix-like) pathnames which are + * searched for classes. The new path will completely replace the + * existing path. + */ + void setClassPath(const char *classPath); + + /* Set the directory where the header files are to be written. dir is a + * canonical pathname representing the directory. + */ + void setOutputDir(const char *dir); + + /* Set the temporary directory to store temporary information. */ + void setTempDir(const char *dir); + + /* Set the name of the output header file. */ + void setOutputFile(const char *fileName); + + /* Generate the header for the given fully-qualified className. Returns + * true on success, false on failure. + */ + bool writeFile(const char *className); + +protected: + /* Returns true if the header-generation process requires a traversal of + * the parent classes of the class, false otherwise. + */ + virtual bool needParents() { return false; } + + /* This routine will examine the class for fields and/or + * native methods and generate the C/C++ header. This routine can assume + * that it does not have to generate the headers and footers of the header + * file..it will be done by the caller. This routine should also not close + * the file -- that will also be done by the caller. + */ +#ifndef USE_PR_IO + virtual bool genHeaderFile(ClassFileSummary &summ, PRFileDesc *fp) = 0; +#else + virtual bool genHeaderFile(ClassFileSummary &summ, FILE *fp) = 0; +#endif + + /* Write the header and footer information for amn already open + * header file whose mangled class name is given by mangledClassName. + */ +#ifndef USE_PR_IO + virtual void writeHeader(const char *mangledClassName, PRFileDesc *fp); + virtual void writeFooter(const char *mangledClassName, PRFileDesc *fp); +#else + virtual void writeHeader(const char *mangledClassName, FILE *fp); + virtual void writeFooter(const char *mangledClassName, FILE *fp); +#endif + + /* Mangles the given fullyQualifiedClassName and returns the + * mangled name. Modifies fullyQualifiedClassName; also + * assumed that it holds enough memory for the mangling. + */ + virtual char *mangleClassName(char *fullyQualifiedClassName, + char separator) { + for (char *s = fullyQualifiedClassName; *s; s++) + if (*s == separator) *s = '_'; + + return fullyQualifiedClassName; + } + + /* Return a string that is the C++ representation of the given type, as + * used as arguments to C++ functions and return types. + * Sub-classes might want to re-define this if they want to return + * different representations. This routine allocates memory (using malloc) + * for the string that it generates; it is the responsibility of the + * caller to free this memory (using free()). + */ + virtual char *getArgString(const Type &type); + + /* Given a Java entity whose type is Type, generate a mangled class name. + * This routine allocates memory using malloc():it is the responsibility + * of the caller to free this memory (using free()). + * If asArray is true, returns a string that is equivalent to the + * exact representation of the type. If asArray is false, this method + * might return a string that corresponds to this type's layout in + * memory (for example, char's and short's are 4-byte aligned in objects + * but are packed in arrays). + */ + virtual char *getMangledName(const Type &type, bool asArray = false); + + /* return the name of the parent of the class whose information + * is contained in reader. + */ + const char *getParentName(const ClassFileReader &reader) { + ConstantClass *parentClass = reader.getSuperClass(); + + if (!parentClass) + return 0; + + return parentClass->getUtf()->getUtfString(); + } + + /* This routine generates forward declarations for all objects + * referenced in the fields and methods of the class whose representation + * in memory is summ. The mangled names of all the objects that forward + * declarations should be generated for are stored in the StringPool. + * This routine does not generate the forward declarations themselves - + * that is done as appropriate by a sub-class of HeaderGenerator. + */ + virtual void genForwards(ClassFileSummary &summ, StringPool &sp); + + /* Add the mangled name corresponding to type, whose typeKind should + * be tkArray or tkObject, to the stringpool sp. summ contains information + * about the current class (the class for which forward declarations are + * being generated. + * + */ + void addMangledName(ClassFileSummary &summ, + const Type &type, StringPool &sp); + + /* Absolute or relative canonical pathname of the directory where the + * headers are written. + */ + char *headerDir; + + /* Absolute or relative canonical pathname of the temporary directory */ + char *tempDir; + +private: + /* A repository to hold all our classes */ + ClassCentral ¢ral; + +}; + + +#endif /* _HEADER_GENERATOR_H_ */ + + + + + diff --git a/ef/Tools/JavaH/JNIHeaderGenerator.cpp b/ef/Tools/JavaH/JNIHeaderGenerator.cpp new file mode 100644 index 000000000000..b2cc76c9b139 --- /dev/null +++ b/ef/Tools/JavaH/JNIHeaderGenerator.cpp @@ -0,0 +1,224 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#include "JNIHeaderGenerator.h" +#include "prprf.h" +#include "plstr.h" +#include "CUtils.h" +#include "StringUtils.h" +#include "JavaObject.h" +#include "FieldOrMethod.h" +#include "JNIManglers.h" + +#ifdef USE_PR_IO +#define PR_fprintf fprintf +#define PR_Write fwrite +#define PRFileDesc FILE +#endif + +bool JNIHeaderGenerator::genHeaderFile(ClassFileSummary &summ, + PRFileDesc *fp) +{ + const ClassFileReader &reader = *summ.getReader(); + const char *className = reader.getThisClass()->getUtf()->getUtfString(); + + PR_fprintf(fp, "/* This file is machine-generated. Do not edit!! */\n"); + + PR_fprintf(fp, "\n/* Header for class %s */\n\n", className); + + PR_fprintf(fp, "#include \n\n"); + + /* Go through each native method and generate a declaration for it */ + const Method **methods = summ.getMethods(); + Uint32 methodCount = summ.getMethodCount(); + + JNIShortMangler mangler; + + /* extern "C" the generated method headers */ + PR_fprintf(fp, "#ifdef __cplusplus\n"); + PR_fprintf(fp, "extern \"C\" {\n"); + PR_fprintf(fp, "#endif\n"); + + for (Uint32 i = 0; i < methodCount; i++) { + Method *m = (Method *) methods[i]; + const Signature &sig = m->getSignature(); + + if ((m->getModifiers() & CR_METHOD_NATIVE)) { + /* Generate the return type */ + char *retString = getArgString(*sig.resultType); + const char *methodName = m->getName(); + const char *signature = const_cast(m)->getSignatureString(); + + if (!retString) + return false; + + int32 len = PL_strlen(methodName) + PL_strlen(className)*2 + + PL_strlen(signature)*2 + sizeof("Java___"); + + TemporaryBuffer copy(len); + char *mangledMethodName = copy; + + if (!mangler.mangle(className, methodName, signature, + mangledMethodName, len)) + continue; + + PR_fprintf(fp, "\n/*\n"); + PR_fprintf(fp, " * Class : %s\n", className); + PR_fprintf(fp, " * Method : %s\n", methodName); + PR_fprintf(fp, " * Signature : %s\n", signature); + PR_fprintf(fp, " */\n"); + + PR_fprintf(fp, "JNIEXPORT JNICALL(%s)\n%s(", + retString, mangledMethodName); + + // Kills the release build since NSPR needs to give us a clean way to + // free strings that it allocates +#ifdef DEBUG + //free(retString); +#endif + + /* The first argument is always a (JNIEnv *) */ + PR_fprintf(fp, "JNIEnv *"); + + /* For static methods, the second argument is a jclass */ + if (m->getModifiers() & CR_METHOD_STATIC) + PR_fprintf(fp, ", jclass"); + + for (uint32 j = 0; j < sig.nArguments; j++) { + char *typeString = getArgString(*sig.argumentTypes[j]); + + if (!typeString) + return false; + + PR_fprintf(fp, ", %s", typeString); + + // Currently does not work with the release build since NSPR needs to + // give us a clean way of freeing strings that it allocates +#ifdef DEBUG + //free(typeString); +#endif + + } + + PR_fprintf(fp, ");\n\n"); + } + } + + PR_fprintf(fp, "#ifdef __cplusplus\n"); + PR_fprintf(fp, "}\n"); /* Matches the extern "C" declaration generated earlier */ + PR_fprintf(fp, "#endif \n\n"); /* Matches the #ifdef __cplusplus */ + + return true; +} + + +char *JNIHeaderGenerator::getArgString(const Type &type) +{ + switch (type.typeKind) { + case tkChar: + return PL_strdup("jchar"); + break; + + case tkShort: + return PL_strdup("jshort"); + break; + + case tkInt: + return PL_strdup("jint"); + break; + + case tkByte: + return PL_strdup("jbyte"); + break; + + case tkBoolean: + return PL_strdup("jbool"); + break; + + case tkLong: + return PL_strdup("jlong"); + break; + + case tkFloat: + return PL_strdup("jfloat"); + break; + + case tkDouble: + return PL_strdup("jdouble"); + break; + + case tkVoid: + return PL_strdup("void"); + break; + + case tkObject: { + const Class &clazz = *static_cast(&type); + + /* Special-case certain objects XXX Need to do throwable here */ + if (!PL_strcmp(clazz.getName(), "java.lang.String")) + return PL_strdup("jstring"); + else + return PL_strdup("jobject"); + } + + case tkInterface: + return PL_strdup("jobject"); + + case tkArray: { + const Array &atype = *static_cast(&type); + + switch (atype.componentType.typeKind) { + case tkChar: + return PL_strdup("jcharArray"); + + case tkShort: + return PL_strdup("jshortArray"); + + case tkInt: + return PL_strdup("jintArray"); + + case tkByte: + return PL_strdup("jbyteArray"); + + case tkBoolean: + return PL_strdup("jboolArray"); + + case tkLong: + return PL_strdup("jlongArray"); + + case tkFloat: + return PL_strdup("jfloatArray"); + + case tkDouble: + return PL_strdup("jdoubleArray"); + + case tkObject: + case tkInterface: + case tkArray: + return PL_strdup("jobjectArray"); + + default: + return 0; + } + break; + } + + default: + return 0; + } + +} diff --git a/ef/Tools/JavaH/JNIHeaderGenerator.h b/ef/Tools/JavaH/JNIHeaderGenerator.h new file mode 100644 index 000000000000..3e9288b1c5e9 --- /dev/null +++ b/ef/Tools/JavaH/JNIHeaderGenerator.h @@ -0,0 +1,62 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#ifndef _JNI_HEADER_GENERATOR_H_ +#define _JNI_HEADER_GENERATOR_H_ + +#include "HeaderGenerator.h" + +/* Header generator for JNI-style internal native methods. + * Almost identical to the sun header generator, except that + * it generates method declarations of the form + * + * JNIEXPORT JNICALL(returnType) foo() + * + * rather than + * + * JNIEXPORT returnType JNICALL foo() + * + * as generated by Sun. We will need to generate the first form + * in order to support x86 Unices like Linux. + */ +class JNIHeaderGenerator : public HeaderGenerator { +public: + JNIHeaderGenerator(ClassCentral ¢ral) : + HeaderGenerator(central) { } + + virtual ~JNIHeaderGenerator() { } + + /* Return a string that is the C++ representation of the given type, as + * used as arguments to C++ functions and return types. + * Sub-classes might want to re-define this if they want to return + * different representations. This routine allocates memory (using malloc) + * for the string that it generates; it is the responsibility of the + * caller to free this memory (using free()). + */ + virtual char *getArgString(const Type &type); + +protected: + virtual bool needParents() { return false; } +#ifndef USE_PR_IO + virtual bool genHeaderFile(ClassFileSummary &summ, PRFileDesc *fp); +#else + virtual bool genHeaderFile(ClassFileSummary &summ, FILE *fp); +#endif +private: +}; + +#endif /* _JNI_HEADER_GENERATOR_H_ */ diff --git a/ef/Tools/JavaH/Makefile b/ef/Tools/JavaH/Makefile new file mode 100644 index 000000000000..aeb07c8772a1 --- /dev/null +++ b/ef/Tools/JavaH/Makefile @@ -0,0 +1,49 @@ +#!gmake +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +####################################################################### +# (1) Include manifest file # +####################################################################### + +include manifest.mn + +####################################################################### +# (2) Include "component" configuration information. # +####################################################################### + +include $(DEPTH)/config/config.mk + +####################################################################### +# (3) Include "local" platform-dependent assignments (OPTIONAL). # +####################################################################### + +include config.mk + + +####################################################################### +# (4) Execute "component" rules. (OPTIONAL) # +####################################################################### + +include $(DEPTH)/config/rules.mk + +####################################################################### +# (7) Execute "local" rules. (OPTIONAL). # +####################################################################### + + +include rules.mk + diff --git a/ef/Tools/JavaH/NetscapeHeaderGenerator.cpp b/ef/Tools/JavaH/NetscapeHeaderGenerator.cpp new file mode 100644 index 000000000000..918cb9e57beb --- /dev/null +++ b/ef/Tools/JavaH/NetscapeHeaderGenerator.cpp @@ -0,0 +1,207 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#include "NetscapeHeaderGenerator.h" +#include "prprf.h" +#include "plstr.h" +#include "CUtils.h" +#include "StringUtils.h" +#include "JavaObject.h" +#include "FieldOrMethod.h" +#include "NetscapeManglers.h" + +#ifdef USE_PR_IO +#define PR_fprintf fprintf +#define PR_Write fwrite +#define PRFileDesc FILE +#endif + +bool NetscapeHeaderGenerator::genHeaderFile(ClassFileSummary &summ, + PRFileDesc *fp) +{ + const ClassFileReader &reader = *summ.getReader(); + const char *className = reader.getThisClass()->getUtf()->getUtfString(); + + PR_fprintf(fp, "/* This file is machine-generated. Do not edit!! */\n"); + + PR_fprintf(fp, "\n/* Header for class %s */\n\n", className); + + PR_fprintf(fp, "#include \"prtypes.h\"\n"); + PR_fprintf(fp, "#include \"NativeDefs.h\"\n"); + + /* If we have a parent, put in a #include so that we can access the + * parent's struct as well + */ + const char *constParentName = getParentName(reader); + char *parentCName = 0; + + if (constParentName) { + TemporaryStringCopy pcopy(constParentName); + char *parentName = pcopy; + int32 parentLen = PL_strlen(parentName)+sizeof("Java_")+1; + + parentCName = (char *) malloc(parentLen+1); + + PL_strcpy(parentCName, mangleClassName(parentName, '/')); + + PR_fprintf(fp, "#include \"%s.h\"\n", parentCName); + } + + PR_fprintf(fp, "\n\n"); + + /* Generate forward declarations */ + Pool p; + StringPool sp(p); + genForwards(summ, sp); + + /* Now get all the keys in the string pool */ + Vector &vec = sp; + + for (uint32 index = 0; index < vec.size(); index++) + PR_fprintf(fp, "struct %s;\n", vec[index]); + + PR_fprintf(fp, "\n\n"); + + TemporaryStringCopy copy(className); + char *mangledClassName = mangleClassName((char *) copy, '/'); + + if (parentCName) { + PR_fprintf(fp, "struct Java_%s : Java_%s {\n", mangledClassName, + parentCName); + PR_fprintf(fp, "\tJava_%s(const Type &type) : Java_%s(type) { }\n", + mangledClassName, parentCName); + free(parentCName); + } else { + PR_fprintf(fp, "struct Java_%s : JavaObject {\n", mangledClassName); + PR_fprintf(fp, "\tJava_%s(const Type &type) : JavaObject(type) { }\n", + mangledClassName); + } + + + /* Go through each field and generate it's type */ + const Field **fields = summ.getFields(); + uint32 fieldCount = summ.getFieldCount(); + + uint32 i; + for (i = 0; i < fieldCount; i++) { + const char *fieldName = fields[i]->getName(); + const Type &type = fields[i]->getType(); + + + const char *typeStr = getArgString(type); + + if (!typeStr) + return false; + + if (fields[i]->getModifiers() & CR_FIELD_STATIC) + PR_fprintf(fp, "\t// static %s %s; \n", typeStr, fieldName); + else + PR_fprintf(fp, "\t%s %s;\n", typeStr, fieldName); + + // Currently kills the release build since NSPR needs to give us a + // clean way of freeing strings that it allocates +#ifdef DEBUG + //free((void *) typeStr); /* getArgString() uses malloc to allocate */ +#endif + + } + + PR_fprintf(fp, "};\n\n"); + + /* Generate a declaration for the array type corresponding to this class */ + PR_fprintf(fp, "ARRAY_OF(Java_%s);\n", mangledClassName); + + /* Now go through each native method and generate a declaration for it */ + const Method **methods = summ.getMethods(); + uint32 methodCount = summ.getMethodCount(); + + NetscapeShortMangler mangler; + + /* extern "C" the generated method headers */ + PR_fprintf(fp, "extern \"C\" {\n"); + + for (i = 0; i < methodCount; i++) { + Method *m = (Method *) methods[i]; + const Signature &sig = m->getSignature(); + + if ((m->getModifiers() & CR_METHOD_NATIVE)) { + /* Generate the return type */ + char *retString = getArgString(*sig.resultType); + const char *methodName = m->getName(); + const char *signature = const_cast(m)->getSignatureString(); + + if (!retString) + return false; + + int32 len = PL_strlen(methodName) + PL_strlen(className)*2 + + PL_strlen(signature)*2 + sizeof("Netscape_Java___"); + + TemporaryBuffer copy(len); + char *mangledMethodName = copy; + + if (!mangler.mangle(className, methodName, signature, + mangledMethodName, len)) + continue; + + PR_fprintf(fp, "\n/*\n"); + PR_fprintf(fp, " * Class : %s\n", className); + PR_fprintf(fp, " * Method : %s\n", methodName); + PR_fprintf(fp, " * Signature : %s\n", signature); + PR_fprintf(fp, " */\n"); + + PR_fprintf(fp, "NS_EXPORT NS_NATIVECALL(%s)\n%s(", + retString, mangledMethodName); + + // Kills the release build since NSPR needs to give us a clean way to + // free strings that it allocates +#ifdef DEBUG + //free(retString); +#endif + + for (uint32 j = 0; j < sig.nArguments; j++) { + char *typeString = getArgString(*sig.argumentTypes[j]); + + if (!typeString) + return false; + + if (j == 0) + PR_fprintf(fp, "%s", typeString); + else + PR_fprintf(fp, ", %s", typeString); + + // Currently does not work with the release build since NSPR needs to + // give us a clean way of freeing strings that it allocates +#ifdef DEBUG + //free(typeString); +#endif + + } + + PR_fprintf(fp, ");\n\n"); + } + } + + /* Matches the extern "C" declaration generated earlier */ + PR_fprintf(fp, "}\n"); + return true; +} + + + + + + diff --git a/ef/Tools/JavaH/NetscapeHeaderGenerator.h b/ef/Tools/JavaH/NetscapeHeaderGenerator.h new file mode 100644 index 000000000000..ba66bbd3b1a5 --- /dev/null +++ b/ef/Tools/JavaH/NetscapeHeaderGenerator.h @@ -0,0 +1,78 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#ifndef _NETSCAPE_HEADER_GENERATOR_H_ +#define _NETSCAPE_HEADER_GENERATOR_H_ + +#include "HeaderGenerator.h" + +/* Header generator for Electrical-fire style internal + * native methods. Internal native methods are of the form + * NS_ where the mangledMethodName is + * the method name of the Java method mangled exactly as + * specified by the JNI. Internal structures corresponding to + * Java objects are all sub-classes of JavaObject; the name of + * the struct corresponding to a class whose fully qualified name + * is Java_, with underscore characters ('_') replacing the + * slashes ('/') in the fully-qualified name. + * The signature of the method is exactly as in the Java class, with the + * following differences: + * - All Class types are replaced by a sub-class of JavaObject. + * - All array types are replaced by a sub-class of JavaArray. + * + * For example, consider the Java Class foo: + * + * class Foo extends String { + * String str; + * int i; + * char j; + * long k; + * + * public native void bar(String s, int i, int j); + * }; + * + * will generate: + * + * #include "java_lang_String.h" + * struct Java_Foo : Java_java_lang_String { + * Java_java_lang_String *str; + * int32 i; + * int32 j; + * int64 k; + * }; + * + * void NS_Java_Foo_bar(Java_Foo *obj, Java_java_lang_string *str, + * int32 i, int32 j); + */ +class NetscapeHeaderGenerator : public HeaderGenerator { +public: + NetscapeHeaderGenerator(ClassCentral ¢ral) : + HeaderGenerator(central) { } + + virtual ~NetscapeHeaderGenerator() { } + +protected: + virtual bool needParents() { return true; } +#ifndef USE_PR_IO + virtual bool genHeaderFile(ClassFileSummary &summ, PRFileDesc *fp); +#else + virtual bool genHeaderFile(ClassFileSummary &summ, FILE *fp); +#endif +private: +}; + +#endif /* _NETSCAPE_HEADER_GENERATOR_H_ */ diff --git a/ef/Tools/JavaH/config.mk b/ef/Tools/JavaH/config.mk new file mode 100644 index 000000000000..8bcec531364c --- /dev/null +++ b/ef/Tools/JavaH/config.mk @@ -0,0 +1,31 @@ +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +CFLAGS += -DIMPORTING_VM_FILES +LDFLAGS += $(EF_LIBS) $(NSPR_LIBS) + +ifneq ($(OS_ARCH),WINNT) +LDFLAGS += -lm +endif + + + + + + + + + diff --git a/ef/Tools/JavaH/main.cpp b/ef/Tools/JavaH/main.cpp new file mode 100644 index 000000000000..0c2ec41c8aab --- /dev/null +++ b/ef/Tools/JavaH/main.cpp @@ -0,0 +1,187 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#include "NetscapeHeaderGenerator.h" +#include "JNIHeaderGenerator.h" +#include "JavaVM.h" + +#include "prprf.h" +#include "plstr.h" + + +/* argv[1] -- fully qualified className */ + +void printUsage() +{ + PR_fprintf(PR_STDERR, "Usage: javah [-v] [-options] classes...\n"); + PR_fprintf(PR_STDERR, "\n"); + PR_fprintf(PR_STDERR, "where options include:\n"); + + PR_fprintf(PR_STDERR, " -help print out this message\n"); + PR_fprintf(PR_STDERR, " -o specify the output file name\n"); + PR_fprintf(PR_STDERR, " -d specify the output directory\n"); + PR_fprintf(PR_STDERR, " -jni create a JNI-style header file\n"); + PR_fprintf(PR_STDERR, " -ns create Netscape-style header files (default)\n"); + PR_fprintf(PR_STDERR, " -td specify the temporary directory\n"); + PR_fprintf(PR_STDERR, " -trace adding tracing information to stubs file\n"); + PR_fprintf(PR_STDERR, " -v verbose operation\n"); + PR_fprintf(PR_STDERR, " -classpath \n"); + PR_fprintf(PR_STDERR, " -version print out the build version\n"); +} + +enum HeaderMode { + headerModeInvalid = 0, + headerModeJNI, + headerModeNetscape, + headerModeJRI +}; + + +/* Parse command-line options and return an initialized HeaderGenerator + * class. On success, set className to the className to generate headers + * for. + */ +HeaderGenerator *parseOptions(int argc, char **argv, ClassCentral ¢ral, + char **&classNames, int32 &numClasses) +{ + struct Options { + HeaderGenerator *generator; + bool verbose; + const char *classPath; + const char *tempDir; + const char *outputDir; + HeaderMode mode; + + Options() : generator(0), verbose(false), classPath(0), tempDir(0), + outputDir(0), mode(headerModeNetscape) { } + }; + + Options options; + + numClasses = 0; + + if (argc < 1) { + PR_fprintf(PR_STDERR, "javah: Class name expected\n"); + return 0; + } + + for (int i = 1; i < argc; i++) { + if (!PL_strcmp(argv[i], "-d")) + options.outputDir = argv[++i]; + else if (!PL_strcmp(argv[i], "-td")) + options.tempDir = argv[++i]; + else if (!PL_strcmp(argv[i], "-v")) + options.verbose = true; + else if (!PL_strcmp(argv[i], "-h") || !PL_strcmp(argv[i], "-help")) { + printUsage(); + return 0; + } else if (!PL_strcmp(argv[i], "-classpath")) + options.classPath = argv[++i]; + else if (!PL_strcmp(argv[i], "-jni")) + options.mode = headerModeJNI; + else if (!PL_strcmp(argv[i], "-jri")) + options.mode = headerModeJRI; + else if (!PL_strcmp(argv[i], "-ns")) + options.mode = headerModeNetscape; + else if (!PL_strcmp(argv[i], "-stubs")) { + PR_fprintf(PR_STDERR, + "javah does not support the -stubs option since neither\n" + "JNI nor Netscape's native method dispatch require stubs\n"); + return 0; + } else if (!PL_strcmp(argv[i], "-trace")) { + PR_fprintf(PR_STDERR, + "javah does not support the -trace option since neither\n" + "JNI nor Netscape's native method dispatch require stubs\n"); + return 0; + } else if (*argv[i] == '-') { + PR_fprintf(PR_STDERR, "javah warning: Unknown option %s\n", argv[i]); + continue; + } else { /* This must be the first of a list of class names */ + numClasses = argc-i; + classNames = new char *[numClasses]; + + for (int index = i, j = 0; index < argc; index++, j++) + classNames[j] = VM::getUtfClassName(argv[index]); + + break; + } + + } + + central.setClassPath(options.classPath); + + VM::staticInit(); + + HeaderGenerator *generator = 0; + switch (options.mode) { + case headerModeNetscape: + generator = new NetscapeHeaderGenerator(central); + break; + + case headerModeJNI: + generator = new JNIHeaderGenerator(central); + break; + + default: + break; + } + + if (!generator) + return 0; + + generator->setOutputDir(options.outputDir); + generator->setTempDir(options.tempDir); + + return generator; +} + +int main(int argc, char **argv) +{ + try { + char **classNames; + int32 numClasses; + + HeaderGenerator *generator = parseOptions(argc, argv, + VM::getCentral(), + classNames, numClasses); + + if (!generator) + return 1; + + for (int32 i = 0; i < numClasses; i++) { + VM::theVM.setCompileStage(csRead); + VM::theVM.setNoInvoke(true); + VM::theVM.setVerbose(false); + + VM::theVM.execute(classNames[i], 0, 0, 0, 0); + generator->writeFile(classNames[i]); + } + + } catch (VerifyError err) { + PR_fprintf(PR_STDERR, "Error loading class file: %d\n", err.cause); + return 1; + } + + return 0; +} + +#ifdef __GNUC__ +/* for gcc with -fhandle-exceptions */ +void terminate() {} +#endif + + diff --git a/ef/Tools/JavaH/manifest.mn b/ef/Tools/JavaH/manifest.mn new file mode 100644 index 000000000000..b93d2de6b3d1 --- /dev/null +++ b/ef/Tools/JavaH/manifest.mn @@ -0,0 +1,30 @@ +# +# CONFIDENTIAL AND PROPRIETARY SOURCE CODE OF +# NETSCAPE COMMUNICATIONS CORPORATION +# Copyright (C) 1996 Netscape Communications Corporation. All Rights +# Reserved. Use of this Source Code is subject to the terms of the +# applicable license agreement from Netscape Communications Corporation. +# The copyright notice(s) in this Source Code does not indicate actual or +# intended publication of this Source Code. +# +DEPTH = ../.. + +CPPSRCS = HeaderGenerator.cpp \ + JNIHeaderGenerator.cpp \ + NetscapeHeaderGenerator.cpp \ + main.cpp \ + $(NULL) + +PROGRAM = javah + + + + + + + + + + + + diff --git a/ef/Tools/JavaH/rules.mk b/ef/Tools/JavaH/rules.mk new file mode 100644 index 000000000000..6c0b049e804e --- /dev/null +++ b/ef/Tools/JavaH/rules.mk @@ -0,0 +1,25 @@ +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +libs:: $(PROGRAM) + +$(PROGRAM) : $(EF_LIB_FILES) + + + + + + diff --git a/ef/Tools/Macintosh/GetMOZ_SRC.pl b/ef/Tools/Macintosh/GetMOZ_SRC.pl new file mode 100644 index 000000000000..709684fcc87b --- /dev/null +++ b/ef/Tools/Macintosh/GetMOZ_SRC.pl @@ -0,0 +1,25 @@ +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +use Cwd; + +$x = cwd(); +$x =~ /(.*):ns/; +print $1; + + + + diff --git a/ef/Tools/Macintosh/SetupMOZ_SRC.mpws b/ef/Tools/Macintosh/SetupMOZ_SRC.mpws new file mode 100644 index 000000000000..db7b48c40403 --- /dev/null +++ b/ef/Tools/Macintosh/SetupMOZ_SRC.mpws @@ -0,0 +1,36 @@ +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +# SetupMOZ_SRC.mpws +# +# Scott M. Silver +# +# Sets the environment variable MOZ_SRC used throughout +# the MPW scripts which build autogenerated stuff +# +# The working directory when this script is executed +# must be somwhere in your tree at ns or below. +# (This autmatically happens when using the CWPro2 IDE) +# +# This should be at the top of the link order so that +# it gets executed before all other scripts which reference +# MOZ_SRC + + +# GetMOZ_SRC.pl is currently broken + +# set MOZ_SRC "`{PERL} :::::Tools:Macintosh:GetMOZ_SRC.pl`" +# export MOZ_SRC diff --git a/ef/Tools/Makefile b/ef/Tools/Makefile new file mode 100644 index 000000000000..d317e44fd43f --- /dev/null +++ b/ef/Tools/Makefile @@ -0,0 +1,47 @@ +#!gmake +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +####################################################################### +# (1) Include manifest file # +####################################################################### + +include manifest.mn + +####################################################################### +# (2) Include "component" configuration information. # +####################################################################### + +include $(DEPTH)/config/config.mk + +####################################################################### +# (3) Include "local" platform-dependent assignments (OPTIONAL). # +####################################################################### + + + +####################################################################### +# (4) Execute "component" rules. (OPTIONAL) # +####################################################################### + +include $(DEPTH)/config/rules.mk + +####################################################################### +# (7) Execute "local" rules. (OPTIONAL). # +####################################################################### + + + diff --git a/ef/Tools/Monitor/Breakpoints.cpp b/ef/Tools/Monitor/Breakpoints.cpp new file mode 100644 index 000000000000..f6b01b82b491 --- /dev/null +++ b/ef/Tools/Monitor/Breakpoints.cpp @@ -0,0 +1,101 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +// Breakpoint.cpp +// +// Scott M. Silver + +#include "Breakpoints.h" +#include "Debugee.h" +#include +#include +#include "Win32Util.h" + + +Vector BreakpointManager::sBreakpoints; + +Breakpoint& BreakpointManager:: +newBreakpoint(DebugeeProcess& inProcess, void* inWhere, bool inGlobal, bool inEnabled) +{ + Breakpoint* newBp = new Breakpoint(*(inProcess.getMainThread()), inWhere, inGlobal, inEnabled); + sBreakpoints.append(newBp); + + return (*newBp); +} + +Breakpoint& BreakpointManager:: +newBreakpoint(DebugeeThread& inThread, void* inWhere, bool inGlobal, bool inEnabled) +{ + Breakpoint* newBp = new Breakpoint(inThread, inWhere, inGlobal, inEnabled); + sBreakpoints.append(newBp); + + return (*newBp); +} + + +Breakpoint* BreakpointManager:: +findBreakpoint(void* inAddress) +{ + Breakpoint** curBreakpoint; + + for(curBreakpoint = sBreakpoints.begin(); curBreakpoint < sBreakpoints.end(); curBreakpoint++) + if ((*curBreakpoint)->mAddress == inAddress) + return *curBreakpoint; + + return (NULL); +} + +void Breakpoint:: +replace() +{ + BYTE expectedDebugger; + + + if (!mThread.getProcess().readMemory(mAddress, &expectedDebugger, 1)) + { + showLastError(); + assert(false); + } + + assert(expectedDebugger == 0xcc); + + if (!mThread.getProcess().writeMemory(mAddress, &mReplacedCode, 1)) + { + showLastError(); + assert(false); + } +} + +void Breakpoint:: +set() +{ + if (!mThread.getProcess().readMemory(mAddress, &mReplacedCode, 1)) + { + showLastError(); + assert(false); + } + + BYTE debugger = 0xcc; + + if (!mThread.getProcess().writeMemory(mAddress, &debugger, 1)) + { + showLastError(); + assert(false); + } +} + + diff --git a/ef/Tools/Monitor/Breakpoints.h b/ef/Tools/Monitor/Breakpoints.h new file mode 100644 index 000000000000..138d44837000 --- /dev/null +++ b/ef/Tools/Monitor/Breakpoints.h @@ -0,0 +1,65 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +// Breakpoint.h +// +// Scott M. Silver + +#include +#include "Vector.h" + +class DebugeeThread; +class DebugeeProcess; +class Breakpoint; + +class BreakpointManager +{ + static Vector sBreakpoints; + +public: + static Breakpoint& newBreakpoint(DebugeeProcess& inProcess, void* inWhere, bool inGlobal = false, bool inEnabled = true); + static Breakpoint& newBreakpoint(DebugeeThread& inThread, void* inWhere, bool inGlobal = false, bool inEnabled = true); + static Breakpoint* findBreakpoint(void* inAddress); + static Vector& getBreakpoints() { return (sBreakpoints); } +}; + +class Breakpoint +{ + friend class BreakpointManager; + + void* mAddress; + BYTE mReplacedCode; + bool mEnabled; + bool mGlobal; + DebugeeThread& mThread; + + Breakpoint(DebugeeThread& inThread, void* inWhere, bool inGlobal = false, bool inEnabled = true) : + mAddress(inWhere), + mEnabled(inEnabled), + mGlobal(inGlobal), + mThread(inThread) { } +public: + bool getEnabled() const { return (mEnabled); } + void setEnabled(bool inEnabled) { mEnabled = inEnabled; } + DebugeeThread& getThread() const { return (mThread); } + + BYTE getReplaced() { assert(mEnabled); return (mReplacedCode); } + void replace(); + void set(); +}; + +Breakpoint* findFreeBreakpoint(); diff --git a/ef/Tools/Monitor/CatchAssert.cpp b/ef/Tools/Monitor/CatchAssert.cpp new file mode 100644 index 000000000000..b6ca8c744c3e --- /dev/null +++ b/ef/Tools/Monitor/CatchAssert.cpp @@ -0,0 +1,39 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#include +#include +#include "CatchAssert.h" +#include "CatchAssert_md.h" + +/* + * catchAssert + * + * This function replaces the existing assert function. + * If the catchHardwareExceptions flag is true, then we just + * print the assert to stdout. If the flag is false, then + * we call the regular assert function for each platform. + * + */ + +NS_EXTERN void __cdecl catchAssert(void *exp, void *filename, unsigned linenumber) +{ + assert(0); + +} + + diff --git a/ef/Tools/Monitor/CommandLine.cpp b/ef/Tools/Monitor/CommandLine.cpp new file mode 100644 index 000000000000..72a9fe5a8308 --- /dev/null +++ b/ef/Tools/Monitor/CommandLine.cpp @@ -0,0 +1,332 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +// CommandLine.cpp +// +// Scot M. Silver +// + +/* fileman.c -- A tiny application which demonstrates how to use the + GNU Readline library. This application interactively allows users + to manipulate files and their modes. */ + +#include +#include +#include + +extern "C" +{ +#include "readline.h" +#include "history.h" +} + +#include "Commands.h" + +bool gCommandLineLoopActive = false; + +const char * +completeCommand(char* inText, int inState); + +const int kMonitorMajorVersion = 0; +const int kMonitorMinorVersion = 1; + +void version(char*) +{ + printf( "Furmon - v%d.%d\n" + "Copyright 1997-8 Netscape Communications Corp.\n" + "All Rights Reserved\n" + "\n" + "Readline Library property of FSF\n", kMonitorMajorVersion, kMonitorMinorVersion); +} + +bool gEndCommandLine; + + +// Commands understood +struct MonitorCommand +{ + const char* mName; // name + void (*mFunc)(char*); // function which implements this + const char* mHelp; // help string + + // list of all commands available + static MonitorCommand mAllCommands[]; + + static MonitorCommand* find(const char* inKeyString) { return(findFrom(mAllCommands, inKeyString, strlen(inKeyString))); } + static MonitorCommand* findFrom(MonitorCommand* inLastCommand, const char* inKeyString, int inMaxLen = 0); + + void execute(char* inArguments) { (*mFunc)(inArguments); } + +}; + +void help(char*); + +MonitorCommand MonitorCommand::mAllCommands[] = +{ + { "help", help, "Print out this message" }, + { "?", help, "Print out this message" }, + { "version", version, "Print version information" }, + { "step-in", stepIn, "Step into" }, + { "si", stepIn, "Step into" }, + { "step-over", stepOver, "Step over" }, + { "so", stepOver, "Step over" }, + { "q", quit, "Quit" }, + { "continue", go, "Resume current thread"}, + { "go", go, "Resume current thread"}, + { "il", disassemble, "Disassemble"}, + { "disass", disassemble, "Disassemble"}, + { "br", breakExecution, "Set an execution breakpoint"}, + { "bre", breakExecution, "Set an execution breakpoint"}, + { "run", run, "Run an application"}, + { "allthreads", printThreads, "Print all threads that were or are"}, + { "thread", printThisThread, "Print current thread"}, + { "sc", printThreadStack, "Print current thread stack"}, + { "where", printThreadStack, "Print current thread stack"}, + { "rc", runClass, "Run main method of a given class"}, + { "swt", switchThread, "Switch to thread id"}, + { "cv", connectToVM, "Force reconnection to VM"}, + { "reg", printIntegerRegs, "Print integer registers"}, + { "allreg", printAllRegs, "Print all registers"}, + { "kill", kill, "Kill currently running program"} +}; + +void help(char*) +{ + MonitorCommand* lastCommand = MonitorCommand::mAllCommands + sizeof(MonitorCommand::mAllCommands) / sizeof(MonitorCommand); + MonitorCommand* firstCommand = MonitorCommand::mAllCommands; + MonitorCommand* curCommand; + + for (curCommand = firstCommand; curCommand < lastCommand; curCommand++) + printf("%-10s %.40s\n", curCommand->mName, curCommand->mHelp); +} + + +MonitorCommand* MonitorCommand:: +findFrom(MonitorCommand* inCommand, const char* inKeyString, int inMaxLen) +{ + MonitorCommand* lastCommand = mAllCommands + sizeof(mAllCommands) / sizeof(MonitorCommand); + MonitorCommand* firstCommand = inCommand ? inCommand : mAllCommands; + MonitorCommand* curCommand; + + for (curCommand = firstCommand; curCommand < lastCommand; curCommand++) + { + if (inMaxLen) + { + if (!strncmp(inKeyString, curCommand->mName, inMaxLen)) + return (curCommand); + } + else + { + if (!strcmp(inKeyString, curCommand->mName)) + return (curCommand); + } + } + + return (NULL); +} + + +int +valid_argument (char*, char*arg); + +void +initialize_readline (); + +void +stripwhite(char* string); + +void +execute_line(char* line); + +extern "C" char ** +fileman_completion(char* text, int start, int end); + + +/* The name of this program, as taken from argv[0]. */ +char *progname; + + +int +commandLineLoop(int argc, char**argv) +{ + initialize_readline (); + + progname = argv[0]; + + version(NULL); + char* lastLine = NULL; + + gCommandLineLoopActive = true; + + /* Loop reading and executing lines until the user quits. */ + while (!gEndCommandLine) + { + char *line; + + line = readline("> "); + + if (!line) + gEndCommandLine = true; /* Encountered EOF at top level. */ + else + { + /* Remove leading and trailing whitespace from the line. + Then, if there is anything left, add it to the history list + and execute it. */ + stripwhite (line); + + // try to hang on to the lastLine, if the user enters an empty + // line then do the last command + if (*line) + { + add_history(line); + execute_line(line); + if (lastLine) + free(lastLine); + lastLine = strdup(line); + + } + else if (lastLine) + { + add_history(lastLine); + execute_line(lastLine); + } + } + + if (line) + free (line); + } + + return 0; +} + +/* Execute a command line. */ +void +execute_line(char* line) +{ + int i; + MonitorCommand *command; + char *word; + + /* Isolate the command word. */ + i = 0; + while (line[i] && !whitespace (line[i])) + i++; + + word = line; + + // FIX-ME this is destructive and this will fuck us + // when we want to evaluate expressions + if (line[i]) + line[i++] = '\0'; + + command = MonitorCommand::find(word); + + if (!command) + { + unhandledCommandLine(line); + return; + } + + // skip to next non-whitespace character to find argument + while (whitespace (line[i])) + i++; + + word = line + i; + + // Call the function + command->execute(word); +} + + +/* Strip whitespace from the start and end of STRING. */ +void +stripwhite (char* string) +{ + register int i = 0; + + while (whitespace (string[i])) + i++; + + if (i) + strcpy (string, string + i); + + i = strlen (string) - 1; + + while (i > 0 && whitespace (string[i])) + i--; + + string[++i] = '\0'; +} + +/* **************************************************************** */ +/* */ +/* Interface to Readline Completion */ +/* */ +/* **************************************************************** */ + +/* Tell the GNU Readline library how to complete. We want to try to complete + on command names if this is the first word in the line, or on filenames + if not. */ +void +initialize_readline () +{ + /* Allow conditional parsing of the ~/.inputrc file. */ + rl_readline_name = "Furmon"; + + /* Tell the completer that we want a crack first. */ + rl_attempted_completion_function = fileman_completion; +} + +/* Attempt to complete on the contents of TEXT. START and END show the + region of TEXT that contains the word to complete. We can use the + entire line in case we want to do some simple parsing. Return the + array of matches, or NULL if there aren't any. */ +extern char * +command_generator (char* text, int state); + + +char ** +fileman_completion (char* text, int start, int end) +{ + char **matches; + matches = NULL; + + /* If this word is at the start of the line, then it is a command + to complete. Otherwise it is the name of a file in the current + directory. */ + if (start == 0) + matches = completion_matches (text, completeCommand); + + return (matches); +} + +MonitorCommand* gLastCommand = NULL; + +/* Generator function for command completion. STATE lets us know whether + to start from scratch; without any state (i.e. STATE == 0), then we + start at the top of the list. */ +const char * +completeCommand(char* inText, int inState) +{ + if (!inState) + gLastCommand = NULL; + + gLastCommand = MonitorCommand::findFrom(gLastCommand ? gLastCommand + 1 : NULL, inText, strlen(inText)); + + return (gLastCommand ? gLastCommand->mName : NULL); +} + diff --git a/ef/Tools/Monitor/CommandLine.h b/ef/Tools/Monitor/CommandLine.h new file mode 100644 index 000000000000..6468055b6c44 --- /dev/null +++ b/ef/Tools/Monitor/CommandLine.h @@ -0,0 +1,23 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +// CommandLine.h +// +// Scott M. Silver + +int +commandLineLoop(int argc, char** argv); diff --git a/ef/Tools/Monitor/Commands.cpp b/ef/Tools/Monitor/Commands.cpp new file mode 100644 index 000000000000..d386b171b97a --- /dev/null +++ b/ef/Tools/Monitor/Commands.cpp @@ -0,0 +1,307 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +// Commands.cpp +// +// Scott M. Silver +// + +#include +#include "Commands.h" +#include "Debugee.h" +#include "DataOutput.h" +#include "Symbols.h" +#include "MonitorExpression.h" +#include "Breakpoints.h" +#include "DebuggerChannel.h" +#include "Win32Util.h" +#include "XDisAsm.h" + +extern DebugeeThread* gCurThread; +extern DebugeeProcess* gProcess; +extern bool gEndCommandLine; + +#define CHECK_HAVE_PROCESS(inProcess) \ + if (!inProcess) \ + { \ + printf("No process started\n"); \ + return; \ + } + +void +quit(char*) +{ + if (gProcess) + gProcess->kill(); + + gEndCommandLine = true; +} + + +void +kill(char*) +{ + CHECK_HAVE_PROCESS(gProcess); + + gProcess->kill(); + gProcess = NULL; +} + +void +stepIn(char*) +{ + CHECK_HAVE_PROCESS(gProcess); + + gCurThread->singleStep(); +} + + +void +stepOver(char*) +{ + CHECK_HAVE_PROCESS(gProcess); + + // set thread breakpoint on instruction after call + unsigned char data[32]; + unsigned char* ip; + + ip = (unsigned char*) gCurThread->getIP(); + if (!gProcess->readMemory(ip, &data, 32, NULL)) + showLastError(); + + if (data[0] == 0xe8 || data[0] == 0xff || data[0] == 0x9a) + { + unsigned char* tempStart; + unsigned char* nextInstruction; + + tempStart = data; + nextInstruction = ip + x86InstructionLength(0, (char**)&tempStart, (char*) data + 32, kDisAsmFlag32BitSegments); + BreakpointManager::newBreakpoint(*gCurThread, nextInstruction).set(); + gCurThread->resume(); + } + else + gCurThread->singleStep(); +} + + +void +go(char *) +{ + CHECK_HAVE_PROCESS(gProcess); + if (gCurThread != NULL) + gCurThread->resume(); + else + printf("no thread, use swt\n"); +} + + +void +disassemble(char *inExpression) +{ + CHECK_HAVE_PROCESS(gProcess); + void *address; + static void* sLastAddress = NULL; + + if (*inExpression != '\0') + address = evaluateExpression(*gCurThread, inExpression); + else if (sLastAddress) + address = sLastAddress; + else + address = gCurThread->getIP(); + + sLastAddress = disassembleN(*gProcess, (char*) address, 10); +} + + +void +unhandledCommandLine(char *inLine) +{ + CHECK_HAVE_PROCESS(gProcess); + + PrintableValue value; + + if (lookupSymbol(*gCurThread, inLine, value)) + { + printf("'%s' = ", inLine); + printf(value.fmtString, value.value); + putchar('\n'); + } +} + +void* gArg; + +void +breakpointCompileLoadAction(const char* inMethodName, void* inAddress, void* inArgument) +{ + DebugeeThread* thread = (DebugeeThread*) inArgument; + + BreakpointManager::newBreakpoint(*thread, inAddress).set(); +} + +void +deferredCompileLoadHandler(const char* inMethodName, void* inAddress) +{ + printf("deferred notification at %p: %s\n", inAddress, inMethodName); + if (gArg) + breakpointCompileLoadAction(inMethodName, inAddress, gArg); +} + +void +addDeferredCompileLoadAction(const char* inMethodName, void* inArgument) +{ + DebuggerClientChannel* channel = gProcess->getChannel(); + + if (channel) + { + gArg = inArgument; + channel->setCompileOrLoadMethodHandler(deferredCompileLoadHandler); + channel->requestNotifyOnMethodCompileLoad(inMethodName); + } +} + + +// expressions limited now +void +breakExecution(char *inExpression) +{ + CHECK_HAVE_PROCESS(gProcess); + + void* address = evaluateExpression(*gCurThread, inExpression); + + if (address) + BreakpointManager::newBreakpoint(*gCurThread, address).set(); + else + { + const char* methodName; + if ((methodName = extractMethodFromExpression(inExpression))) + addDeferredCompileLoadAction(methodName, gCurThread); + else + printf("error %s unknown\n", methodName); + } +} + + +void +runClass(char* inClassName) +{ + CHECK_HAVE_PROCESS(gProcess); + + if (gProcess->getChannel()) + gProcess->getChannel()->requestRunClass("javasoft/sqe/tests/api/java/lang/System/SystemTests10"); +} + + +void +run(char*) +{ + HANDLE debugThreadH; + const char* testApp = "e:\\trees\\ef1\\ns\\electricalfire\\Driver\\StandAloneJava\\winbuild\\electric\\sajava.exe"; + + if (gProcess) + printf("already running process\n"); + else + gProcess = DebugeeProcess::createDebugeeProcess(testApp, ::GetCurrentThreadId(), debugThreadH); +} + + +void +switchThread(char *inExpression) +{ + CHECK_HAVE_PROCESS(gProcess); + + DebugeeThread* thread = gProcess->idToThread((DWORD) evaluateExpression(*gCurThread, inExpression)); + if (thread) + gCurThread = thread; +} + + +extern "C" void +stack(DWORD id) +{ + DebugeeThread* thread = gProcess->idToThread(id); + if (thread) + printThreadStack(*thread); +} + +void +printThreads(char*) +{ + CHECK_HAVE_PROCESS(gProcess); + + printThreads(*gProcess); +} + + +void +printThisThread(char*) +{ + CHECK_HAVE_PROCESS(gProcess); + + if (gCurThread) + { + gCurThread->print(); + printf("\n"); + } +} + + +void +printThreadStack(char*) +{ + CHECK_HAVE_PROCESS(gProcess); + + if (gCurThread) + printThreadStack(*gCurThread); +} + + +void +connectToVM(char*) +{ + CHECK_HAVE_PROCESS(gProcess); + + if (!gProcess->getChannel(true)) + printf("couldn't connect to VM\n"); +} + + +void printFPRegs(char*) +{ + CHECK_HAVE_PROCESS(gProcess); + + +} + + +void printIntegerRegs(char*) +{ + CHECK_HAVE_PROCESS(gProcess); + printIntegerRegs(*gCurThread); + +} +void printAllRegs(char*) +{ + CHECK_HAVE_PROCESS(gProcess); + +} + + +void dumpMemory(char*) +{ + +} + diff --git a/ef/Tools/Monitor/Commands.h b/ef/Tools/Monitor/Commands.h new file mode 100644 index 000000000000..4b864b7b8486 --- /dev/null +++ b/ef/Tools/Monitor/Commands.h @@ -0,0 +1,42 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +// Commands.h +// +// Scott M. Silver + + +void stepIn(char*); +void stepOver(char*); +void go(char*); +void disassemble(char*); +void quit(char*); +void unhandledCommandLine(char*); +void breakExecution(char*); +void run(char*); +void printThreads(char*); +void printThisThread(char*); +void printThreadStack(char*); +void runClass(char*); +void switchThread(char*); +void connectToVM(char*); +void printIntegerRegs(char*); +void printFPRegs(char*); +void printIntegerRegs(char*); +void printAllRegs(char*); +void dumpMemory(char*); +void kill(char*); diff --git a/ef/Tools/Monitor/DataOutput.cpp b/ef/Tools/Monitor/DataOutput.cpp new file mode 100644 index 000000000000..b321ed60db51 --- /dev/null +++ b/ef/Tools/Monitor/DataOutput.cpp @@ -0,0 +1,283 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +// DataOutput.cpp +// +// Scott M. Silver + + +#include +#include +#include +#include +#include "Debugee.h" +#include "XDisAsm.h" +#include "Win32Util.h" +#include "DataOutput.h" +#include "DebuggerChannel.h" +#include "Breakpoints.h" + +void* disassembleToString(DebugeeProcess& inProcess, void* inStart, const char* inOutputBuffer); +void* printOneInstruction(DebugeeProcess& inProcess, void* inStart); + +extern bool gCommandLineLoopActive; +extern "C" rl_clear_screen(); +extern DebugeeThread* gCurThread; + + +void +disassembleBytes(DebugeeProcess& inProcess, const char* inStart, int /*length*/) +{ + printOneInstruction(inProcess, (void*) inStart); + putchar('\n'); +} + + +void* +disassembleToString(DebugeeProcess& inProcess, void* inStart, char* outOutputBuffer) +{ + unsigned char data[32]; + if (!inProcess.readMemory(inStart, &data, 32, NULL)) + showLastError(); + + // if the current pc is the site of breakpoint + // we replace the breakpoint instruction with + // the replaced instruction + Breakpoint* bp = BreakpointManager::findBreakpoint(inStart); + if (bp) + data[0] = bp->getReplaced(); + + unsigned char* tempStart = data; + + if (data[0] == 0xe8 || data[0] == 0xe9) + { + // call/jmp with 32 bit offset relative to pc from end of the instruction + char symbol[512]; + DWORD offset; + void* address = (void*) ((Uint8*) inStart + *((Int32*) (data + 1)) + 5); // 5 is length of instruction + if (inProcess.getSymbol(address, symbol, sizeof(symbol), offset)) + { + sprintf(outOutputBuffer, "%s\t %s + %d; %p", (data[0] == 0xe8) ? "call" : "jmp", symbol, offset, address); + goto FinishDisassembling; + } + // else false through and do the normal thing + } + + // regular instruction + char* str; + str = disasmx86(0, (char**) &tempStart, (char*)data + 32, kDisAsmFlag32BitSegments); + strcpy(outOutputBuffer, str); + +FinishDisassembling: + tempStart = data; + return ((void*) ((char*) inStart + x86InstructionLength(0, (char**)&tempStart, (char*) data + 32, kDisAsmFlag32BitSegments))); +} + + +DebugeeProcess::SymbolKind +printMethodName(DebugeeProcess& inProcess, const void* inMethodAddress) +{ + char symbol[512]; + DWORD offset; + DebugeeProcess::SymbolKind kind; + + if ((kind = inProcess.getSymbol(inMethodAddress, symbol, sizeof(symbol), offset)) != DebugeeProcess::kNil) + printf("%s + %d", symbol, offset); + + return (kind); +} + + +void* +printOneInstruction(DebugeeProcess& inProcess, void* inStart) +{ + void* nextPC; + char buffer[1024]; + + nextPC = disassembleToString(inProcess, inStart, buffer); + printf("%.8x: %s", inStart, buffer); + return (nextPC); +} + + +void* +disassembleN(DebugeeProcess& inProcess, const char* inStart, int inInstructions) +{ + int curInstruction; + void* curPC = (void*) inStart; + + if (printMethodName(inProcess, inStart)); + putchar('\n'); + + for (curInstruction = 0; curInstruction < inInstructions; curInstruction++) + { + curPC = printOneInstruction(inProcess, curPC); + printf("\n"); + } + + return (curPC); +} + + +void beginOutput() +{ + if (gCommandLineLoopActive) + putchar('\n'); +} + + +void endOutput() +{ + if (gCommandLineLoopActive) + rl_clear_screen(); +} + + +void +printThreads(DebugeeProcess& inProcess) +{ + Vector threads = inProcess.getThreads(); + + printf(" %4s%5s%10s(%5s)%9s %s\n", "id", "hndl", "state", "cnt", "eip", "symbol"); + + DebugeeThread** curThread; + + for(curThread = threads.begin(); curThread < threads.end(); curThread++) + { + if (gCurThread == *curThread) + printf("*"); + else + printf(" "); + + (*curThread)->print(); + printf("\n"); + } +} + + +void +printThreadStack(DebugeeThread& inThread) +{ + STACKFRAME stackFrame; + CONTEXT context; + + ::ZeroMemory(&stackFrame, sizeof(stackFrame)); + + inThread.getContext(CONTEXT_FULL | CONTEXT_FLOATING_POINT | CONTEXT_DEBUG_REGISTERS, context); + stackFrame.AddrPC.Offset = context.Eip; + stackFrame.AddrPC.Mode = AddrModeFlat; + + stackFrame.AddrStack.Offset = context.Esp; + stackFrame.AddrStack.Mode = AddrModeFlat; + + stackFrame.AddrFrame.Offset = context.Ebp; + stackFrame.AddrFrame.Mode = AddrModeFlat; + + DebugeeProcess::SymbolKind state; + + for (;;) + { + if (stackFrame.AddrPC.Offset == 0) + break; + + state = printMethodName(inThread.getProcess(), (void*) stackFrame.AddrPC.Offset); + + if (state == DebugeeProcess::kJava) + { + printf("\n"); + inThread.getProcess().readMemory(((DWORD*)stackFrame.AddrFrame.Offset + 1), &stackFrame.AddrPC.Offset, 4); + inThread.getProcess().readMemory((void*) stackFrame.AddrFrame.Offset, &stackFrame.AddrFrame.Offset, 4); + stackFrame.AddrStack.Offset = stackFrame.AddrFrame.Offset; + } + else if (state == DebugeeProcess::kNative) + { + printf("\n"); + if (!::StackWalk(IMAGE_FILE_MACHINE_I386, + inThread.getProcess().getProcessHandle(), + inThread.getThreadHandle(), + &stackFrame, + NULL, + NULL, + SymFunctionTableAccess, + SymGetModuleBase, + NULL)) + { + inThread.getProcess().readMemory(((DWORD*)stackFrame.AddrFrame.Offset + 1), &stackFrame.AddrPC.Offset, 4); + inThread.getProcess().readMemory((void*) stackFrame.AddrFrame.Offset, &stackFrame.AddrFrame.Offset, 4); + stackFrame.AddrStack.Offset = stackFrame.AddrFrame.Offset; + } + + } + else + { + // try one more native frame + if (::StackWalk(IMAGE_FILE_MACHINE_I386, + inThread.getProcess().getProcessHandle(), + inThread.getThreadHandle(), + &stackFrame, + NULL, + NULL, + SymFunctionTableAccess, + SymGetModuleBase, + NULL)) + state = printMethodName(inThread.getProcess(), (void*) stackFrame.AddrPC.Offset); + else + { + printf("\n"); + break; + } + } + } +// showLastError(); +} + + +void +printIntegerRegs(DebugeeThread& inThread) +{ + CONTEXT context; + gCurThread->getContext(CONTEXT_INTEGER | CONTEXT_CONTROL, context); + + printf( "EDI=%8p ESI=%8p EBX=%8p EDX=%8p\n" + "ECX=%8p EAX=%8p EBP=%8p ESP=%8p\n" + "EIP=%8p\n", context.Edi, context.Esi, + context.Ebx, context.Edx, context.Ecx, + context.Eax, context.Ebp, context.Esp, + context.Eip); +} + + +void +printFlags(DebugeeThread& inThread) +{ + CONTEXT context; + gCurThread->getContext(CONTEXT_CONTROL, context); + const char* flagString = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"; + const char* cp = flagString; + + while (context.EFlags) + { + if (context.EFlags & 1) + putchar(*cp); + else + putchar(*cp - 32); + + cp++; + context.EFlags >>= 1; + } +} + diff --git a/ef/Tools/Monitor/DataOutput.h b/ef/Tools/Monitor/DataOutput.h new file mode 100644 index 000000000000..560540007fbe --- /dev/null +++ b/ef/Tools/Monitor/DataOutput.h @@ -0,0 +1,33 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +// DataOutput.h +// +// Scott M. Silver + +#include "Debugee.h" + + +void disassembleBytes(DebugeeProcess& inProcess, const char* start, int length); +void* disassembleN(DebugeeProcess& inProcess, const char* inStart, int inInstructions); +void beginOutput(); +void endOutput(); +DebugeeProcess::SymbolKind printMethodName(DebugeeProcess& inProcess, const void* inMethodAddress); +void printThreads(DebugeeProcess& inProcess); +void printThreadStack(DebugeeThread& inThread); +void printFlags(DebugeeThread& inThread); +void printIntegerRegs(DebugeeThread& inThread); diff --git a/ef/Tools/Monitor/Debugee.cpp b/ef/Tools/Monitor/Debugee.cpp new file mode 100644 index 000000000000..c13cd909839b --- /dev/null +++ b/ef/Tools/Monitor/Debugee.cpp @@ -0,0 +1,664 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +// Debugee.cpp +// +// Scott M. Silver + +#include +#include "Debugee.h" +#include +#include +#include "Win32Util.h" +#include "DataOutput.h" +#include "Breakpoints.h" +#include "DebuggerChannel.h" +#include "ImageHlp.h" +#include "prthread.h" + +extern DebugeeThread* gCurThread; +extern DebugeeProcess* gProcess; + +void startupDebugee(LPTSTR lpszFileName, LPTSTR lpszTitle, PROCESS_INFORMATION* outProcessInfo); + +DebugeeProcess:: +DebugeeProcess(DEBUG_EVENT* inNewProcessEvent) : + mCreateProcessInfo(inNewProcessEvent->u.CreateProcessInfo), + mProcessH(inNewProcessEvent->u.CreateProcessInfo.hProcess), + mDebuggerChannel(0) + +{ + assert(inNewProcessEvent->dwDebugEventCode == CREATE_PROCESS_DEBUG_EVENT); + + BOOL success = ::SymInitialize(mProcessH, NULL, FALSE); + assert(success); + + addThread(new DebugeeThread(mCreateProcessInfo.hThread, inNewProcessEvent->dwThreadId, *this, false)); + printf("CREATE_PROCESS_DEBUG_EVENT\n"); +} + + +void DebugeeProcess:: +kill() +{ + ::TerminateProcess(mProcessH, 0); + setDebuggerThreadID(0); // since we are not reloading libDebuggerChannel, we need to + // reset the debugger thread ID to zero, so we don't mistakenly + // suspend the wrong thread +} + + +void DebugeeProcess:: +handleModuleLoad(HANDLE inFileH, void* inBaseOfImage) +{ + if (!::SymLoadModule(mProcessH, inFileH, NULL, NULL, (DWORD) inBaseOfImage, 0)) + showLastError(); +} + + +DebugeeThread* DebugeeProcess:: +idToThread(DWORD inThreadID) +{ + DebugeeThread** curThread; + + for (curThread = mThreads.begin(); curThread < mThreads.end(); curThread++) + if ((*curThread)->getThreadID() == inThreadID) + return (*curThread); + + return (NULL); +} + + +// subsequent calls will fail if the first +// time we could not connect to the ef process +DebuggerClientChannel* DebugeeProcess:: +getChannel(bool inForce) +{ + if (!mDebuggerChannel || (inForce && mDebuggerChannel == (DebuggerClientChannel*) this)) + { + mDebuggerChannel = DebuggerClientChannel::createClient(); + + if (mDebuggerChannel) + return (mDebuggerChannel); + else + { + mDebuggerChannel = (DebuggerClientChannel*) this; + return (NULL); + } + } + else if (mDebuggerChannel == (DebuggerClientChannel*) this) + return (NULL); + else + return (mDebuggerChannel); + +} + +BOOL DebugeeProcess:: +writeMemory(void* inDest, void* inSrc, DWORD inSrcLen, DWORD* outBytesWritten) +{ + return (::WriteProcessMemory(mProcessH, inDest, inSrc, inSrcLen, outBytesWritten)); +} + + +BOOL DebugeeProcess:: +readMemory(const void* inSrc, void* inDest, DWORD inDestLen, DWORD* outBytesRead) +{ + return (::ReadProcessMemory(mProcessH, inSrc, inDest, inDestLen, outBytesRead)); +} + + +// this only returns the the debugee process starts up and is ready +// for use. the debugee process is suspended, etc +DebugeeProcess* DebugeeProcess:: +createDebugeeProcess(const char* inFullPath, DWORD inDebugEventHandlerID, HANDLE& outDebugThreadH) +{ + DebugeeProcess::DebugStartupInfo startupInfo; + + startupInfo.fullPath = inFullPath; + startupInfo.debugeeProcessCreated = ::CreateEvent(NULL, FALSE, FALSE, NULL); + startupInfo.debugEventHandlerID = inDebugEventHandlerID; + startupInfo.newDebugeeProcess = NULL; + + PR_CreateThread(PR_USER_THREAD, + &debugEventThread, + &startupInfo, + PR_PRIORITY_NORMAL, + PR_GLOBAL_THREAD, + PR_JOINABLE_THREAD, + 0); + + // now wait until the process actually starts up + ::WaitForSingleObject(startupInfo.debugeeProcessCreated, INFINITE); + + // need to get to first instruction + startupInfo.newDebugeeProcess->getMainThread()->singleStep(); + + return (startupInfo.newDebugeeProcess); +} + + + +void +startupDebugee(LPTSTR lpszFileName, LPTSTR lpszTitle, PROCESS_INFORMATION* outProcessInfo) +{ + // why does this retard not just assign to the structs, instead + // of having pointers?? + STARTUPINFO StartupInfo; + LPSTARTUPINFO lpStartupInfo = &StartupInfo; + char* args = "-debug -html -sys -classpath \"\\trees\\ef1\\ns\\dist\\classes\\classes.zip:\\trees\\ef1\\ns\\dist\\classes\\tests.zip:\\trees\\ef1\\ns\\dist\\classes\\t1.zip\" javasoft/sqe/tests/api/java/lang/System/SystemTests10"; + char* commandLine = new char[strlen(lpszFileName) + strlen(args) + 2]; + + sprintf(commandLine, "%s %s", lpszFileName, args); + + lpStartupInfo->cb = sizeof(STARTUPINFO); + lpStartupInfo->lpDesktop = NULL; + lpStartupInfo->lpTitle = lpszTitle; + lpStartupInfo->dwX = 0; + lpStartupInfo->dwY = 0; + lpStartupInfo->dwXSize = 0; + lpStartupInfo->dwYSize = 0; + lpStartupInfo->dwFlags = (DWORD) NULL; + lpStartupInfo->wShowWindow = SW_SHOWDEFAULT; + + outProcessInfo->hProcess = NULL; + + // create the Debuggee process instead + if( !::CreateProcess( + NULL, + commandLine, //lpszFileName, + (LPSECURITY_ATTRIBUTES) NULL, + (LPSECURITY_ATTRIBUTES) NULL, + TRUE, + DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS | CREATE_NEW_CONSOLE | CREATE_NEW_PROCESS_GROUP, + (LPVOID) NULL, + (LPTSTR) NULL, + lpStartupInfo, outProcessInfo)) + { + showLastError(); + exit(-1); + } + + delete commandLine; +} + +void DebugeeProcess:: +debugEventThread(void* inStartupInfo) +{ + bool fFinished = false; + DEBUG_EVENT debugEvent; + PROCESS_INFORMATION processInformation; + DebugeeProcess::DebugStartupInfo* startupInfo = (DebugeeProcess::DebugStartupInfo*) inStartupInfo; + DebugeeProcess* thisProcess = NULL; + DebugeeThread* thread; + bool didSuspend; + + // start debugee + startupDebugee((char*) startupInfo->fullPath, (char*) startupInfo->fullPath, &processInformation); + + // debug event processing loop + for(;;) + { + didSuspend = false; + + // wait for debug events + if(!WaitForDebugEvent(&debugEvent, INFINITE)) + { + showLastError(); + fFinished = true; + break; + } + + // our strategy is to suspend all (relevant) + // threads, continue the debug event -- so all threads + // continue so we can continue grabbing symbols, etc + if (thisProcess) + { + thisProcess->suspendAll(); + didSuspend = true; + thread = thisProcess->idToThread(debugEvent.dwThreadId); // can be null if CREATE_THREAD_EVENT + + if (!::ContinueDebugEvent(debugEvent.dwProcessId, debugEvent.dwThreadId, DBG_CONTINUE)) + showLastError(); + } + + beginOutput(); + + switch(debugEvent.dwDebugEventCode) + { + // exception occured + case EXCEPTION_DEBUG_EVENT: + // figure out which type of exception + switch(debugEvent.u.Exception.ExceptionRecord.ExceptionCode) + { + // hardware exceptions + case EXCEPTION_ACCESS_VIOLATION: + thread->suspend(); + disassembleN(thread->getProcess(), (char*) thread->getIP(), 10); + printThreadStack(*thread); + thread->print(); + ::ContinueDebugEvent(debugEvent.dwProcessId, debugEvent.dwThreadId, DBG_CONTINUE); + + printf("EXCEPTION_ACCESS_VIOLATION\n"); + break; + case EXCEPTION_DATATYPE_MISALIGNMENT: + printf("EXCEPTION_ACCESS_VIOLATION\n"); + break; + case EXCEPTION_BREAKPOINT: + printf("EXCEPTION_BREAKPOINT\n"); + // so we need an extra continue for breakpoints?? +// ::ContinueDebugEvent(debugEvent.dwProcessId, debugEvent.dwThreadId, DBG_CONTINUE); + + thread->suspend(); + thisProcess->handleBreakpoint(debugEvent, thread); + + break; + case EXCEPTION_SINGLE_STEP: + printf("EXCEPTION_SINGLE_STEP\n"); + thread->suspend(); + thisProcess->handleSingleStep(debugEvent, thread); + break; + case EXCEPTION_ARRAY_BOUNDS_EXCEEDED: + printf("EXCEPTION_ARRAY_BOUNDS_EXCEEDED\n"); + break; + case EXCEPTION_FLT_DENORMAL_OPERAND: + printf("EXCEPTION_FLT_DENORMAL_OPERAND\n"); + break; + case EXCEPTION_FLT_DIVIDE_BY_ZERO: + printf("EXCEPTION_FLT_DIVIDE_BY_ZERO\n"); + break; + case EXCEPTION_FLT_INEXACT_RESULT: + printf("EXCEPTION_FLT_INEXACT_RESULT\n"); + break; + case EXCEPTION_FLT_INVALID_OPERATION: + printf("EXCEPTION_FLT_INVALID_OPERATION\n"); + break; + case EXCEPTION_FLT_OVERFLOW: + printf("EXCEPTION_FLT_OVERFLOW\n"); + break; + case EXCEPTION_FLT_STACK_CHECK: + printf("EXCEPTION_FLT_STACK_CHECK\n"); + break; + case EXCEPTION_FLT_UNDERFLOW: + printf("EXCEPTION_FLT_UNDERFLOW\n"); + break; + case EXCEPTION_INT_DIVIDE_BY_ZERO: + printf("EXCEPTION_INT_DIVIDE_BY_ZERO\n"); + break; + case EXCEPTION_INT_OVERFLOW: + printf("EXCEPTION_INT_OVERFLOW\n"); + break; + case EXCEPTION_PRIV_INSTRUCTION: + printf("EXCEPTION_PRIV_INSTRUCTION\n"); + break; + case EXCEPTION_IN_PAGE_ERROR: + printf("EXCEPTION_IN_PAGE_ERROR\n"); + break; + // Debug exceptions + case DBG_TERMINATE_THREAD: + printf("DBG_TERMINATE_THREAD\n"); + break; + case DBG_TERMINATE_PROCESS: + printf("DBG_TERMINATE_PROCESS\n"); + break; + case DBG_CONTROL_C: + printf("DBG_CONTROL_C\n"); + break; + case DBG_CONTROL_BREAK: + printf("DBG_CONTROL_BREAK\n"); + break; + // RPC exceptions (some) + case RPC_S_UNKNOWN_IF: + printf("RPC_S_UNKNOWN_IF\n"); + break; + case RPC_S_SERVER_UNAVAILABLE: + printf("RPC_S_SERVER_UNAVAILABLE\n"); + break; + default: + printf("unhandled event\n"); + break; + } + + if(1) + { + ; + } + else + { + if(debugEvent.u.Exception.dwFirstChance != 0) + ; + else + ; + } + break; + case CREATE_THREAD_DEBUG_EVENT: + { + printf("CREATE_THREAD_DEBUG_EVENT\n"); + bool suspendable = (getDebuggerThreadID() != 0 && debugEvent.dwThreadId != getDebuggerThreadID()); // if we have a debugger thread ID then this thread is suspendable + + thisProcess->addThread(thread = new DebugeeThread(debugEvent.u.CreateThread.hThread, debugEvent.dwThreadId, *thisProcess, suspendable)); + } + break; + + case CREATE_PROCESS_DEBUG_EVENT: + assert(startupInfo->newDebugeeProcess == NULL); // can only get here once + thisProcess = startupInfo->newDebugeeProcess = new DebugeeProcess(&debugEvent); + gCurThread = thisProcess->getMainThread(); + thisProcess->handleModuleLoad(debugEvent.u.CreateProcessInfo.hFile, debugEvent.u.CreateProcessInfo.lpBaseOfImage); + gCurThread->suspend(); + ::SetEvent(startupInfo->debugeeProcessCreated); + ::ContinueDebugEvent(debugEvent.dwProcessId, debugEvent.dwThreadId, DBG_CONTINUE); + break; + + case EXIT_THREAD_DEBUG_EVENT: + printf("EXIT_THREAD_DEBUG_EVENT\n"); + break; + + case EXIT_PROCESS_DEBUG_EVENT: + fFinished = true; + printf("EXIT_PROCESS_DEBUG_EVENT\n"); + break; + + case LOAD_DLL_DEBUG_EVENT: + char dllName[512]; + retrieveModuleName(dllName, debugEvent.u.LoadDll.hFile); + printf("Dll Load: %s\n", dllName); + thisProcess->handleModuleLoad(debugEvent.u.LoadDll.hFile, debugEvent.u.LoadDll.lpBaseOfDll); + break; + + case UNLOAD_DLL_DEBUG_EVENT: + printf("UNLOAD_DLL_DEBUG_EVENT\n"); + break; + + case OUTPUT_DEBUG_STRING_EVENT: + printf("OUTPUT_DEBUG_STRING_EVENT\n"); + break; + + case RIP_EVENT: + printf("RIP_EVENT\n"); + break; + + default: + printf("unhandled event\n"); + break; + } + + if (didSuspend) + thisProcess->resumeAll(); + + endOutput(); + + // default action, just continue + if(fFinished) + break; + } + + gProcess = NULL; + + // decrement active process count + ::ExitThread(TRUE); + +// return(TRUE); +} + + +BOOL DebugeeThread:: +getContext(DWORD inContextFlags, CONTEXT& outContext) +{ + outContext.ContextFlags = inContextFlags; + + return (::GetThreadContext(mThreadH, &outContext)); +} + + +BOOL DebugeeThread:: +setContext(DWORD inContextFlags, CONTEXT& ioContext) +{ + ioContext.ContextFlags = inContextFlags; + + return (::SetThreadContext(mThreadH, &ioContext)); +} + + +bool DebugeeProcess:: +handleSingleStep(const DEBUG_EVENT& inDebugEvent, DebugeeThread* inThread) +{ + disassembleBytes(*this, (char*) inDebugEvent.u.Exception.ExceptionRecord.ExceptionAddress, 32); + + // reset out of single step mode + CONTEXT threadContext; + + // clear trap bit + inThread->getContext(CONTEXT_CONTROL, threadContext); + threadContext.EFlags &= ~0x100; + inThread->setContext(CONTEXT_CONTROL, threadContext); + + inThread->handleSingleStep(); + + return (true); +} + + +bool DebugeeProcess:: +handleBreakpoint(const DEBUG_EVENT& inDebugEvent, DebugeeThread* inThread) +{ + CONTEXT threadContext; + + inThread->getContext(CONTEXT_CONTROL, threadContext); + // now set back the ip to the beginning of the debug statement + // if we are at one of our breakpoints, the resume will handle skipping + // over this + if (BreakpointManager::findBreakpoint((void*) inDebugEvent.u.Exception.ExceptionRecord.ExceptionAddress)) + { + threadContext.Eip = (DWORD) inDebugEvent.u.Exception.ExceptionRecord.ExceptionAddress; + inThread->setContext(CONTEXT_CONTROL, threadContext); + } + + return (true); +} + + +// return true if we really did single step +void DebugeeThread:: +singleStep() +{ + if (!mSuspendable) + return; + + // set into single step mode + CONTEXT threadContext; + + getContext(CONTEXT_CONTROL, threadContext); + + // set trap bit + threadContext.EFlags |= 0x100; + setContext(CONTEXT_CONTROL, threadContext); + + resume(true); +} + + +void DebugeeProcess:: +suspendAll() +{ + DebugeeThread** curThread; + + for(curThread = mThreads.begin(); curThread < mThreads.end(); curThread++) + (*curThread)->suspend(); +} + +void DebugeeProcess:: +resumeAll() +{ + DebugeeThread** curThread; + + for(curThread = mThreads.begin(); curThread < mThreads.end(); curThread++) + (*curThread)->resume(); +} + + +DebugeeProcess::SymbolKind DebugeeProcess:: +getSymbol(const void* inPC, char* outName, DWORD inBufLen, DWORD& outOffset) +{ + DebugeeProcess::SymbolKind kind = kNil; + char* symbolName; + + // will deadlock getting a symbol when the debugger thread or + // main/io thread is suspended. + assert( getDebuggerThreadID() && + !threadSuspendCount(idToThread(getDebuggerThreadID())->getThreadHandle()) && + !threadSuspendCount(getMainThread()->getThreadHandle())); + + // IMAGEHLP is silly and wants the data to go at the end of the struct + IMAGEHLP_SYMBOL* symbol = (IMAGEHLP_SYMBOL*) malloc(sizeof(IMAGEHLP_SYMBOL) + inBufLen); + symbol->MaxNameLength = inBufLen; + + if (::SymGetSymFromAddr(mProcessH, (DWORD) inPC, &outOffset, symbol)) + { + strcpy(outName, symbol->Name); // copy to user's buffer + free(symbol); + kind = kNative; + } + else if (getChannel()) + { +// return (kind); + if ((symbolName = getChannel()->requestAddressToMethod(inPC, (Int32&) outOffset))) + { + strncpy(outName, symbolName, inBufLen); // copy to user's buffer + delete [] symbolName; + kind = kJava; + } + } + + return (kind); +} + + +void* DebugeeProcess:: +getAddress(const char* inMethodName) +{ + void* address = NULL; + + if (getChannel()) + address = getChannel()->requestMethodToAddress(inMethodName); + + return (address); +} + + +void DebugeeThread:: +handleSingleStep() +{ + if (mBp) + { + mBp->set(); // reset this breakpoint + mBp = NULL; + if (mStaySuspended) + suspend(); // this will up our suspend count, so we won't get resumed in + // the next statement + mProcess.resumeAll(); // resume (put back state) of other threads + } +} + + +DWORD DebugeeThread:: +suspend() +{ + if (!mSuspendable) + return 0; + + // no suspending the debugger thread or main thread + assert(getDebuggerThreadID() != mThreadID); + assert(mProcess.getMainThread() != this); + + return (::SuspendThread(mThreadH)); +} + + +DWORD DebugeeThread:: +resume(bool inSingleStepping) +{ + if (!mSuspendable) + return 0; + + CONTEXT threadContext; + + getContext(CONTEXT_CONTROL, threadContext); + + // if this thread would be resumed by our resuming it + // major race condition between when we check to see if we'll be resuming + // and the actual resume + // if we have a breakpoint at this instruction + // suspend all threads + // put this thread into single step mode + // push a pending to-do for the single step for this thread + // (ie put back the breakpoint) + Breakpoint* bp; + if ((threadSuspendCount(mThreadH) == 1) && (bp = BreakpointManager::findBreakpoint((void*) threadContext.Eip))) + { + mProcess.suspendAll(); + ::ResumeThread(mThreadH); // we shouldn't be suspended twice + bp->replace(); + threadContext.EFlags |= 0x100; // single step mode + setContext(CONTEXT_CONTROL, threadContext); + pushSingleStepAction(bp, inSingleStepping); + } + + return (::ResumeThread(mThreadH)); // now really resume this threac +} + + +void* DebugeeThread:: +getIP() +{ + CONTEXT threadContext; + + getContext(CONTEXT_CONTROL, threadContext); + return ((void*) threadContext.Eip); +} + + +void* DebugeeThread:: +getSP() +{ + CONTEXT threadContext; + + getContext(CONTEXT_CONTROL, threadContext); + return ((void*) threadContext.Esp); +} + + +void DebugeeThread:: +print() +{ + CONTEXT threadContext; + + getContext(CONTEXT_CONTROL, threadContext); + DWORD suspendCount = threadSuspendCount(mThreadH); + char symbol[512]; + char* printSymbol; + + + DWORD offset; + printSymbol = (mProcess.getSymbol((void*) threadContext.Eip, symbol, sizeof(symbol), offset)) ? symbol : ""; + + printf("%4.4x%5.4x%10s(%5d)%9.8p %s", getThreadID(), mThreadH, (suspendCount >= 0) ? "suspended" : "running", suspendCount, threadContext.Eip, printSymbol); + + if (getDebuggerThreadID() == mThreadID) + printf("[debugger]"); + else if (mProcess.getMainThread() == this) + printf("[main-i/o]"); +} diff --git a/ef/Tools/Monitor/Debugee.h b/ef/Tools/Monitor/Debugee.h new file mode 100644 index 000000000000..6c8846811121 --- /dev/null +++ b/ef/Tools/Monitor/Debugee.h @@ -0,0 +1,125 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +// Debugee.h + +#ifndef _H_DEBUGEE +#define _H_DEBUGEE + +#include +#include "Vector.h" + +class DebugeeProcess; +class Breakpoint; + +class DebugeeThread +{ + friend DebugeeProcess; + +public: + DebugeeThread(HANDLE inThreadH, DWORD inThreadID, DebugeeProcess& inProcess, bool inSuspendable) : + mThreadH(inThreadH), + mProcess(inProcess), + mThreadID(inThreadID), + mBp(0), + mSuspendable(inSuspendable) { } + + DWORD resume(bool inSingleStepping = false); + DWORD suspend(); + void singleStep(); + + DWORD getThreadID() const { return mThreadID; } + HANDLE getThreadHandle() const { return mThreadH; } + DebugeeProcess& getProcess() const { return mProcess; } + void* getIP(); + void* getSP(); + + BOOL getContext(DWORD inContextFlags, CONTEXT& outContext); + BOOL setContext(DWORD inContextFlags, CONTEXT& ioContext); + + void print(); + +private: + void handleSingleStep(); + void pushSingleStepAction(Breakpoint* inBp, bool inStaySuspended) { assert(!mBp); mBp = inBp; mStaySuspended = inStaySuspended; } + + bool mSuspendable; + bool mStaySuspended; + Breakpoint* mBp; + DWORD mThreadID; + DebugeeProcess& mProcess; + HANDLE mThreadH; +}; + +class DebuggerClientChannel; + +class DebugeeProcess +{ + Vector mThreads; + CREATE_PROCESS_DEBUG_INFO mCreateProcessInfo; + HANDLE mProcessH; + HANDLE mHandledEvent; + DebuggerClientChannel* mDebuggerChannel; + +public: + enum SymbolKind + { + kNil = 0, + kNative, + kJava + }; + // use this to create a debugee process + static DebugeeProcess* createDebugeeProcess(const char* inFullPath, DWORD inDebugEventHandlerID, HANDLE& outDebugThreadH); + + BOOL writeMemory(void* inDebugeeDest, void* inSrc, DWORD inSrcLen, DWORD* outBytesWritten = NULL); + BOOL readMemory(const void* inDebugeeSrc, void* inDest, DWORD inDestLen, DWORD* outBytesRead = NULL); + + DebugeeThread* handleToThread(HANDLE inHandle); + DebugeeThread* idToThread(DWORD inThreadID); + + void kill(); + void suspendAll(); // increment suspend count on all threads + void resumeAll(); // decrement suspend count on all threads + + DebuggerClientChannel* getChannel(bool inForce = false); + Vector& getThreads() { return mThreads; } + SymbolKind getSymbol(const void* inPC, char* outName, DWORD inBufLen, DWORD& outOffset); + void* getAddress(const char* inSymbol); + HANDLE getProcessHandle() { return mProcessH; } + DebugeeThread* getMainThread() { return mThreads[0]; } + + +private: + bool handleSingleStep(const DEBUG_EVENT& inDebugEvent, DebugeeThread* inThread); + bool handleBreakpoint(const DEBUG_EVENT& inDebugEvent, DebugeeThread* inThread); + void addThread(DebugeeThread* inNewThread) { mThreads.append(inNewThread); } + void handleModuleLoad(HANDLE inFileH, void* inBaseOfImage); + + // Bootstrapping stuff (get the debugger thread going, startup up the debugee, etc) + struct DebugStartupInfo + { + const char* fullPath; // in + DWORD debugEventHandlerID; // in + HANDLE debugeeProcessCreated; // io event flag protecting next field + DebugeeProcess* newDebugeeProcess; // out new object + }; + + static void debugEventThread(void* inDebugStartupInfo); + DebugeeProcess(DEBUG_EVENT* inNewProcessEvent); +}; + +#endif // _H_DEBUGEE diff --git a/ef/Tools/Monitor/Makefile b/ef/Tools/Monitor/Makefile new file mode 100644 index 000000000000..e8c10f28a90b --- /dev/null +++ b/ef/Tools/Monitor/Makefile @@ -0,0 +1,47 @@ +#!gmake +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +####################################################################### +# (1) Include manifest file # +####################################################################### + +include manifest.mn + +####################################################################### +# (2) Include "component" configuration information. # +####################################################################### + +include $(DEPTH)/config/config.mk + +####################################################################### +# (3) Include "local" platform-dependent assignments (OPTIONAL). # +####################################################################### + +include config.mk + + +####################################################################### +# (4) Execute "component" rules. (OPTIONAL) # +####################################################################### + +include $(DEPTH)/config/rules.mk + +####################################################################### +# (7) Execute "local" rules. (OPTIONAL). # +####################################################################### + +include rules.mk \ No newline at end of file diff --git a/ef/Tools/Monitor/MonitorExpression.cpp b/ef/Tools/Monitor/MonitorExpression.cpp new file mode 100644 index 000000000000..e45bed7f3799 --- /dev/null +++ b/ef/Tools/Monitor/MonitorExpression.cpp @@ -0,0 +1,48 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +// MonitorExpression.cpp +// +// Scott M. Silver + +#include +#include "MonitorExpression.h" +#include +#include "Symbols.h" +#include "Fundamentals.h" + +// for now only handle numbers or registers + +const char* +extractMethodFromExpression(const char* inString) +{ + return (inString); +} + + +void* +evaluateExpression(DebugeeThread& inThread, const char* inString) +{ + + PrintableValue pv; + + if (lookupSymbol(inThread, inString, pv)) + return (pv.value); + else + return (0); // bail +} + diff --git a/ef/Tools/Monitor/MonitorExpression.h b/ef/Tools/Monitor/MonitorExpression.h new file mode 100644 index 000000000000..3a8d266a41c9 --- /dev/null +++ b/ef/Tools/Monitor/MonitorExpression.h @@ -0,0 +1,25 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +// MonitorExpression.h +// +// + +class DebugeeThread; + +void* evaluateExpression(DebugeeThread& inThread, const char* inString); +const char* extractMethodFromExpression(const char* inString); diff --git a/ef/Tools/Monitor/Symbols.cpp b/ef/Tools/Monitor/Symbols.cpp new file mode 100644 index 000000000000..a7ebd6978ee8 --- /dev/null +++ b/ef/Tools/Monitor/Symbols.cpp @@ -0,0 +1,144 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +// Symbols.cpp +// +// Scott M. Silver +// + +#include +#include +#include +#include "Debugee.h" +#include +#include "Symbols.h" + +bool lookupLiteral(const char* inSymbol, PrintableValue& outValue); +bool lookupRegister(DebugeeThread& inThread, const char* inSymbol, PrintableValue& outValue); + +// the mother of all symbol lookups +// this searches through all known ways +// of figuring out what the hell a symbol is +bool +lookupSymbol(DebugeeThread& inThread, const char* inSymbol, PrintableValue& outValue) +{ + if (lookupLiteral(inSymbol, outValue)) + return(true); + + if (lookupRegister(inThread, inSymbol, outValue)) + return (true); + + void *address; + + if ((address = inThread.getProcess().getAddress(inSymbol))) + { + outValue.fmtString = "%p"; + outValue.value = address; + return (true); + } + + return (false); +} + + +bool +lookupLiteral(const char* inString, PrintableValue& outValue) +{ + const char* lc = inString + strlen(inString); // point to 0 + Int32 value; + char* endp; + + if (*inString == '\0') + return (false); + + if (*inString == '#') + { + value = strtol(inString + 1, &endp, 10); + if (endp == lc) + { + outValue.value = (void*) value; + outValue.fmtString = "#%d"; + return (true); + } + } + else if (*inString == '$') + { + value = strtol(inString + 1, &endp, 16); + if (endp == lc) + { + outValue.value = (void*) value; + outValue.fmtString = "0x%x"; + return (true); + } + } + else + { + value = strtol(inString, &endp, 16); + if (endp == lc) + { + outValue.value = (void*) value; + outValue.fmtString = "0x%x"; + return (true); + } + } + + return (false); +} + +bool +lookupRegister(DebugeeThread& inThread, const char* inSymbol, PrintableValue& outValue) +{ + char* symbol = strdup(inSymbol); + char* cp = symbol; + + assert(symbol); + + // lowercase the string + while(*cp) + *cp++ = tolower(*cp); + + outValue.fmtString = "%.8X"; + + bool found = true; + CONTEXT context; + + assert(inThread.getContext(CONTEXT_INTEGER | CONTEXT_CONTROL, context)); + + if (!strcmp("edi", symbol)) + outValue.value = (void*) context.Edi; + else if (!strcmp("esi", symbol)) + outValue.value = (void*) context.Esi; + else if (!strcmp("ebx", symbol)) + outValue.value = (void*) context.Ebx; + else if (!strcmp("edx", symbol)) + outValue.value = (void*) context.Edx; + else if (!strcmp("ecx", symbol)) + outValue.value = (void*) context.Ecx; + else if (!strcmp("eax", symbol)) + outValue.value = (void*) context.Eax; + else if (!strcmp("ebp", symbol)) + outValue.value = (void*) context.Ebp; + else if (!strcmp("eip", symbol)) + outValue.value = (void*) context.Eip; + else if (!strcmp("esp", symbol)) + outValue.value = (void*) context.Esp; + else + found = false; + + free(symbol); + return (found); +} diff --git a/ef/Tools/Monitor/Symbols.h b/ef/Tools/Monitor/Symbols.h new file mode 100644 index 000000000000..d7be56a2de69 --- /dev/null +++ b/ef/Tools/Monitor/Symbols.h @@ -0,0 +1,29 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +// Symbols.cpp +// +// Scott M. Silver +// + +struct PrintableValue +{ + const char* fmtString; + void* value; +}; + +bool lookupSymbol(DebugeeThread& inThread, const char* inSymbol, PrintableValue& outValue); diff --git a/ef/Tools/Monitor/Test/test.cpp b/ef/Tools/Monitor/Test/test.cpp new file mode 100644 index 000000000000..b438eeeff2de --- /dev/null +++ b/ef/Tools/Monitor/Test/test.cpp @@ -0,0 +1,24 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#include + +void main() +{ + printf("scott\n"); + _asm int 3 +} diff --git a/ef/Tools/Monitor/Test/winbuild/testapp.dsp b/ef/Tools/Monitor/Test/winbuild/testapp.dsp new file mode 100644 index 000000000000..6325f47087f2 --- /dev/null +++ b/ef/Tools/Monitor/Test/winbuild/testapp.dsp @@ -0,0 +1,88 @@ +# Microsoft Developer Studio Project File - Name="testapp" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 5.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=testapp - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "testapp.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "testapp.mak" CFG="testapp - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "testapp - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "testapp - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "testapp - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "testapp - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "testapp - Win32 Release" +# Name "testapp - Win32 Debug" +# Begin Source File + +SOURCE=.\test.cpp +# End Source File +# End Target +# End Project diff --git a/ef/Tools/Monitor/Test/winbuild/testapp.dsw b/ef/Tools/Monitor/Test/winbuild/testapp.dsw new file mode 100644 index 000000000000..bf51671ec8a5 --- /dev/null +++ b/ef/Tools/Monitor/Test/winbuild/testapp.dsw @@ -0,0 +1,41 @@ +Microsoft Developer Studio Workspace File, Format Version 5.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "furmon"=..\furmon\furmon.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "testapp"=.\testapp.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/ef/Tools/Monitor/Win32Util.cpp b/ef/Tools/Monitor/Win32Util.cpp new file mode 100644 index 000000000000..082a7fd91afb --- /dev/null +++ b/ef/Tools/Monitor/Win32Util.cpp @@ -0,0 +1,139 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +// Win32Util.cpp +// +// Scott M. Silver + +#include "Win32Util.h" +#include + +void +showLastError() +{ + // if we fail put of one of those sweet Win32 dialogs + char* lpMsgBuf; + + ::FormatMessage( + FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, + NULL, + GetLastError(), + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language + (LPTSTR) &lpMsgBuf, + 0, + NULL); + ::MessageBox( NULL, lpMsgBuf, "GetLastError", MB_OK|MB_ICONINFORMATION ); +} + + +/* retrieve name of module from module's open file handle */ +void retrieveModuleName ( + char *lpszModule, + HANDLE hFile) +{ + HANDLE hMapFile; + LPVOID lpFile; + char *lpszName; + int nSections; + ULONG VAExportDir; + int i=0; + int ImageHdrOffset; + PIMAGE_SECTION_HEADER psh; + PIMAGE_FILE_HEADER pfh; + PIMAGE_OPTIONAL_HEADER poh; + PIMAGE_EXPORT_DIRECTORY ped; + + + /* memory map handle to DLL for easy access */ + hMapFile = CreateFileMapping (hFile, + (LPSECURITY_ATTRIBUTES)NULL, + PAGE_READONLY, + 0, + 0, + NULL); + + /* map view of entire file */ + lpFile = MapViewOfFile (hMapFile, FILE_MAP_READ, 0, 0, 0); + + /* if DOS based file */ + if (*((USHORT *)lpFile) == IMAGE_DOS_SIGNATURE) + { + /* file image header offset exists after DOS header and nt signature */ + ImageHdrOffset = (int)((ULONG *)lpFile)[15] + sizeof (ULONG); + if (*((ULONG *)((char *)lpFile + ImageHdrOffset - sizeof (ULONG))) != + IMAGE_NT_SIGNATURE) + { + strcpy (lpszModule, "Error, no IMAGE_NT_SIGNATURE"); + goto EXIT; + } + } + + pfh = (PIMAGE_FILE_HEADER)((char *)lpFile + ImageHdrOffset); + + /* if optional header exists and exports directory exists proceed */ + if (pfh->SizeOfOptionalHeader) + { + /* locate virtual address for Export Image Directory in OptionalHeader */ + poh = (PIMAGE_OPTIONAL_HEADER)((char *)pfh + sizeof (IMAGE_FILE_HEADER)); + VAExportDir = poh->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress; + + /* locate section where export virtual address is located */ + psh = (PIMAGE_SECTION_HEADER)((char *)poh + pfh->SizeOfOptionalHeader); + nSections = pfh->NumberOfSections; + while (i++VirtualAddress <= VAExportDir && + psh->VirtualAddress + psh->SizeOfRawData > VAExportDir) + break; + psh++; + } + + /* locate export image directory */ + if (i < nSections) + ped = (PIMAGE_EXPORT_DIRECTORY)((char *)lpFile + + (VAExportDir - psh->VirtualAddress) + psh->PointerToRawData); + else + { + strcpy (lpszModule, "IMAGE_EXPORT_DIRECTORY not found"); + goto EXIT; + } + + /* read name from export directory */ + lpszName = (char *)lpFile + ped->Name + (psh->PointerToRawData - psh->VirtualAddress); + strcpy (lpszModule, lpszName); + } + + else + strcpy (lpszModule, "Error, no IMAGE_OPTIONAL_HEADER"); + +EXIT: + /* clean up before exiting */ + UnmapViewOfFile (lpFile); + CloseHandle (hMapFile); +} + + +DWORD +threadSuspendCount(HANDLE inThreadH) +{ + DWORD suspendCount; + + suspendCount = ::SuspendThread(inThreadH); + ::ResumeThread(inThreadH); + + return (suspendCount); +} diff --git a/ef/Tools/Monitor/Win32Util.h b/ef/Tools/Monitor/Win32Util.h new file mode 100644 index 000000000000..0f70a3250a0a --- /dev/null +++ b/ef/Tools/Monitor/Win32Util.h @@ -0,0 +1,23 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +// Win32Util.h +#include + +void showLastError(); +void retrieveModuleName(char* lpszMoudle, HANDLE hFile); +DWORD threadSuspendCount(HANDLE inThreadH); diff --git a/ef/Tools/Monitor/config.mk b/ef/Tools/Monitor/config.mk new file mode 100644 index 000000000000..a7f66634a6d7 --- /dev/null +++ b/ef/Tools/Monitor/config.mk @@ -0,0 +1,28 @@ +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +ifeq ($(OS_ARCH), WINNT) +LDFLAGS += user32.lib kernel32.lib imagehlp.lib +#$(DIST)/lib/Readline.lib $(DIST)/lib/DebuggerChannel.lib $(DIST)/lib/DisassembleX86.lib $(NSPR_LIBS) +endif + + + + + + + + diff --git a/ef/Tools/Monitor/main.cpp b/ef/Tools/Monitor/main.cpp new file mode 100644 index 000000000000..474c56ababf6 --- /dev/null +++ b/ef/Tools/Monitor/main.cpp @@ -0,0 +1,139 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +// main.cpp +// +// Scott M. Silver +// + +#include +#include +#include +#include "Debugee.h" +#include "CommandLine.h" +#include "prthread.h" + +#include "XDisAsm.h" + +class Breakpoint; + +DWORD WINAPI debugEventThread(void *); +void startupDebugee(LPTSTR lpszFileName, LPTSTR lpszTitle, PROCESS_INFORMATION* outProcessInfo); +void disassembleBytes(char* start, int length); +void showLastError(); + +HANDLE hMessageEvent; +DWORD gDebugEventHandlerID; +HANDLE gQueueEventFlag; +HANDLE hVictimProcess; + + +DebugeeThread* gCurThread; +DebugeeProcess* gProcess; + +enum +{ + kDebugTheadMessage = WM_USER + +}; + + + + +enum DebugEventKind +{ + dkBreakpoint +}; + +struct DebugEvent +{ + DebugEvent(DebugEventKind inEventKind, const DEBUG_EVENT& inPlatformEvent, HANDLE inThreadH) : + mEventKind(inEventKind), + mPlatformEvent(inPlatformEvent), + mThreadH(inThreadH) { } + + DebugEventKind mEventKind; + DEBUG_EVENT mPlatformEvent; + HANDLE mThreadH; + +}; + +void +postDebuggerEvent(DebugEvent* inEvent) +{ + ::PostThreadMessage(gDebugEventHandlerID, kDebugTheadMessage, (WPARAM) inEvent, NULL); + ::WaitForSingleObject(gQueueEventFlag, INFINITE); +} + +inline int +instructionLength(DebugeeProcess* inProcess, char* start, int length) +{ + char data[32]; + assert(::ReadProcessMemory(hVictimProcess, start, &data, 32, NULL)); + + char* tempStart = data; + + return (x86InstructionLength(0, &tempStart, data + length, kDisAsmFlag32BitSegments)); +} + +void realMain(void*); + +struct MainArgs +{ + int argc; + char **argv; +}; + +int main(int argc, char** argv) +{ + PRThread* thread; + MainArgs mainArgs = {argc, argv}; + + thread = PR_CreateThread(PR_USER_THREAD, + realMain, + &mainArgs, + PR_PRIORITY_NORMAL, + PR_GLOBAL_THREAD, + PR_JOINABLE_THREAD, + 0); + + PR_JoinThread(thread); + return (0); +} + +void realMain(void* inArgument) +{ + MainArgs* args = (MainArgs*) inArgument; + + const char* testApp = "sajava.exe"; + //"e:\\trees\\ef1\\ns\\electricalfire\\Tools\\Monitor\\Test\\winbuild\\Debug\\testapp.exe"; + printf("Furmon - v0.0.1\n"); + + HANDLE debugThreadH; + + gProcess = DebugeeProcess::createDebugeeProcess(testApp, ::GetCurrentThreadId(), debugThreadH); + + commandLineLoop(args->argc, args->argv); + +// ::WaitForSingleObject(debugThreadH, INFINITE); +} + + + + + + diff --git a/ef/Tools/Monitor/manifest.mn b/ef/Tools/Monitor/manifest.mn new file mode 100644 index 000000000000..ddde4a6aa478 --- /dev/null +++ b/ef/Tools/Monitor/manifest.mn @@ -0,0 +1,49 @@ +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +DEPTH = ../.. + +CPPSRCS = Breakpoints.cpp \ + CommandLine.cpp \ + Commands.cpp \ + DataOutput.cpp \ + Debugee.cpp \ + main.cpp \ + MonitorExpression.cpp \ + Symbols.cpp \ + Win32Util.cpp \ + CatchAssert.cpp \ + $(NULL) + +LIBRARIES = Readline \ + DebuggerChannel \ + DisassembleX86 \ + libnspr21 \ + $(NULL) + +PROGRAM = furmon + + + + + + + + + + + + diff --git a/ef/Tools/Monitor/rules.mk b/ef/Tools/Monitor/rules.mk new file mode 100644 index 000000000000..5ce0c954e417 --- /dev/null +++ b/ef/Tools/Monitor/rules.mk @@ -0,0 +1,24 @@ +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. +# +libs:: $(PROGRAM) + + + + + + + diff --git a/ef/Tools/Monitor/winbuild/furmon.dsp b/ef/Tools/Monitor/winbuild/furmon.dsp new file mode 100644 index 000000000000..df4b88715d8c --- /dev/null +++ b/ef/Tools/Monitor/winbuild/furmon.dsp @@ -0,0 +1,177 @@ +# Microsoft Developer Studio Project File - Name="furmon" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 5.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=furmon - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "furmon.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "furmon.mak" CFG="furmon - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "furmon - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "furmon - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "furmon - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "furmon - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I "../../../Debugger/Communication" /I "../../../Utilities/Readline" /I "../../../Utilities/Disassemblers/x86" /I "../../../Utilities/General" /I "../../../../dist/WINNT4.0_DBG.OBJ/include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR /YX /FD /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 ../../../../dist/WINNT4.0_DBG.OBJ/lib/libnspr21.lib ../../../../dist/WINNT4.0_DBG.OBJ/lib/libDebuggerChannel.lib ../../../../dist/WINNT4.0_DBG.OBJ/lib/Readline.lib kernel32.lib user32.lib imagehlp.lib /nologo /subsystem:console /debug /machine:I386 /out:"../../../../dist/WINNT4.0_DBG.OBJ/bin/furmon.exe" /pdbtype:sept +# SUBTRACT LINK32 /pdb:none + +!ENDIF + +# Begin Target + +# Name "furmon - Win32 Release" +# Name "furmon - Win32 Debug" +# Begin Group "Utilities" + +# PROP Default_Filter "" +# Begin Group "Disassembler" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Utilities\Disassemblers\x86\XDisAsm.c +# End Source File +# Begin Source File + +SOURCE=..\..\..\Utilities\Disassemblers\x86\XDisAsm.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Utilities\Disassemblers\x86\XDisAsmTable.c +# End Source File +# End Group +# End Group +# Begin Source File + +SOURCE=..\Breakpoints.cpp +# End Source File +# Begin Source File + +SOURCE=..\Breakpoints.h +# End Source File +# Begin Source File + +SOURCE=..\CommandLine.cpp +# End Source File +# Begin Source File + +SOURCE=..\CommandLine.h +# End Source File +# Begin Source File + +SOURCE=..\Commands.cpp +# End Source File +# Begin Source File + +SOURCE=..\Commands.h +# End Source File +# Begin Source File + +SOURCE=..\DataOutput.cpp +# End Source File +# Begin Source File + +SOURCE=..\DataOutput.h +# End Source File +# Begin Source File + +SOURCE=..\Debugee.cpp +# End Source File +# Begin Source File + +SOURCE=..\Debugee.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Debugger\Communication\DebuggerChannel.h +# End Source File +# Begin Source File + +SOURCE=..\main.cpp +# End Source File +# Begin Source File + +SOURCE=..\MonitorExpression.cpp +# End Source File +# Begin Source File + +SOURCE=..\MonitorExpression.h +# End Source File +# Begin Source File + +SOURCE=..\Symbols.cpp +# End Source File +# Begin Source File + +SOURCE=..\Symbols.h +# End Source File +# Begin Source File + +SOURCE=..\Win32Util.cpp +# End Source File +# Begin Source File + +SOURCE=..\Win32Util.h +# End Source File +# End Target +# End Project diff --git a/ef/Tools/Monitor/winbuild/furmon.dsw b/ef/Tools/Monitor/winbuild/furmon.dsw new file mode 100644 index 000000000000..96d3bb1879c8 --- /dev/null +++ b/ef/Tools/Monitor/winbuild/furmon.dsw @@ -0,0 +1,44 @@ +Microsoft Developer Studio Workspace File, Format Version 5.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "ReadLine"=..\..\..\Utilities\Readline\winbuild\ReadLine.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "furmon"=.\furmon.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name ReadLine + End Project Dependency +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/ef/Tools/Nad/Makefile b/ef/Tools/Nad/Makefile new file mode 100644 index 000000000000..6b3e44815298 --- /dev/null +++ b/ef/Tools/Nad/Makefile @@ -0,0 +1,20 @@ +#!gmake +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +DEPTH = ../.. + +include $(DEPTH)/config/rules.mk diff --git a/ef/Tools/Nad/NADGrammar/NADGrammar.c b/ef/Tools/Nad/NADGrammar/NADGrammar.c new file mode 100644 index 000000000000..93207ef02626 --- /dev/null +++ b/ef/Tools/Nad/NADGrammar/NADGrammar.c @@ -0,0 +1,117 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +/* + NADGrammar.c + + Scott M. Silver +*/ + +#ifdef NADGRAMMAR_APP +/* Macintosh cruft for setting stdin */ +#include +#endif + +#include +#include +#include "NADOutput.h" +#include +#include + +extern int lineno; +extern FILE* yyout; + +char* gEmitterName = "PPCEmitter"; +int gNextRuleNumber; +int gFirstRuleNumber; +extern int yyparse(); + +/* + [emittername] [emitterfile] [burg rule file] [first burg rule num] + PPCEmitter PPCEmitterRules PPC.burg 4 +*/ + +main(int argc, char** argv) +{ + extern int yydebug; + extern int gDebugLevel; + +// yydebug = 0; + gDebugLevel = 0; /* set to 1 for interesting results */ + +#ifdef NADGRAMMAR_APP + /* Macintosh cruft for setting stdin */ + argc = ccommand(&argv); +#endif + + if (argc < 4) + { + fprintf(stderr, "Atleast 3 arguments expected, got %d\n" + "Usage:\n" + "NADGrammar EmitterObjectName GlueFilePrefix BurgRulesFile\n" + " is the input NAD file\n" + " is the output of the implementation file\n" + "example\n" + " NADGrammar PPCEmitter PPCEmitterGlue PPCSpecificRules > PPCEmitterImpl.cpp\n" + , argc); + + return -1; + } + gEmitterName = argv[1]; + gNextRuleNumber = 1; + + fprintGeneratedHeader(stdout, gEmitterName); + + yyparse(); + + { + char* rulesFn = argv[3]; + char* implFn = (char*) malloc(strlen(argv[2]) + 1 + 4); /* + ".cpp" */ + char* headerFn = (char*) malloc(strlen(argv[2]) + 1 + 2); /* + ".h" */ + sprintf(implFn, "%s.cpp", argv[2]); + sprintf(headerFn, "%s.h", argv[2]); + assert(rulesFn && implFn && headerFn); + + { + FILE* rulesFp = fopen(rulesFn, "w"); + FILE* emImplFp = fopen(implFn, "w"); + FILE* emHeaderFp = fopen(headerFn, "w"); + + assert(rulesFp && emImplFp && emHeaderFp); + + fprintGeneratedHeader(emImplFp, implFn); + fprintGeneratedHeader(emHeaderFp, headerFn); + fprintRules(rulesFp, emImplFp, emHeaderFp); + } + } + + return 0; +} + +int +yyerror(); + +extern char* yytext; + +int +yyerror() +{ + fprintf(stderr, "%s", yytext); + fprintf(stderr, "Parse error line: %d\n", lineno); + exit(-1); + return (-1); +} diff --git a/ef/Tools/Nad/NADGrammar/NADGrammar.l b/ef/Tools/Nad/NADGrammar/NADGrammar.l new file mode 100644 index 000000000000..a3171b824f07 --- /dev/null +++ b/ef/Tools/Nad/NADGrammar/NADGrammar.l @@ -0,0 +1,60 @@ +%{ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#include "NADGrammarTypes.h" +#include "NADGrammar.tab.h" +#include +#include +int lineno = 1; +int leaveblock; +int yylex(void); +int isatty(int); +int fileno(FILE*); +%} + +%s PERCENT_BRACE +%s COMMANDS +%s STUFF_MODE + +%% +%{ + BEGIN COMMANDS; +%} +#[ ]*line.* { ECHO; return LINEDIRECTIVE; } +\<- { return DERIVES; } +cost { return COST; } +[0-9]+ { yylval.cost = atoi(yytext); return NUMBER; } +[ \t] ; /* ignore whitespace */ +\n?\r { lineno++; } /* ignore end of lines */ +[A-Za-z][A-Za-z0-9_]* { yylval.string = strdup(yytext); return STRING; } +. { return yytext[0]; } +"%{" { leaveblock = 0; BEGIN(PERCENT_BRACE);} +"%}" { BEGIN(COMMANDS); return CODEBLOCK;} +. { ECHO; } +\n?\r { + lineno++; + ECHO; + if (leaveblock == 1) + BEGIN COMMANDS; + } +%% + +yywrap() +{ + return 1; +} \ No newline at end of file diff --git a/ef/Tools/Nad/NADGrammar/NADGrammar.y b/ef/Tools/Nad/NADGrammar/NADGrammar.y new file mode 100644 index 000000000000..c2bff7789422 --- /dev/null +++ b/ef/Tools/Nad/NADGrammar/NADGrammar.y @@ -0,0 +1,136 @@ +%{ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#include "NADGrammarTypes.h" +#include "NADOutput.h" +#include +#include +#ifdef WIN32 +#include +int yylex(void); +int yyerror(); +#endif +int gDebugLevel = 0; +#define kParseDebug 1 +#define DPRINTF(inLevel, inParenthesizedString) if (gDebugLevel >= (inLevel)) printf inParenthesizedString +#ifdef __MWERKS__ +#pragma require_prototypes off +#endif +%} + +%union { + int cost; + char* string; + ParamList* paramList; + Prototype* prototype; + Parameter* parameter; + ParameterType* paramType; +} + +%token STRING NUMBER COST DERIVES CODEBLOCK LINEDIRECTIVE + +%type ParameterList +%type PrototypeDescriptor +%type ParameterDescriptor +%type CostDescriptor +%type ParameterType +%type CompoundParameterType +%type CodeSection +%type InCompoundParameter + +%token STRING +%token NUMBER + +%% +Line: LINEDIRECTIVE + | Statement + | Line + | /* epsilon */ + ; + +Statement: Line PrototypeDescriptor CostDescriptor CodeSection { + DPRINTF(kParseDebug, ("got Rule\n")); + addRule(makeRule($2, $3, $4)); + echoEmitDefinitionFooter(); + } + ; + +CodeSection: CODEBLOCK { $$ = 1; } + | /* epsilon */ { printf("thisPrimitive;"); $$ = 0; } + ; + +PrototypeDescriptor: STRING DERIVES STRING '(' ParameterList ')' { + DPRINTF(kParseDebug, ("got Prototype\n")); + $$ = makePrototype($5, $1, $3); + echoEmitDefinitionHeader($$); + } + ; + +ParameterList: ParameterDescriptor ',' ParameterDescriptor { + DPRINTF(kParseDebug, ("got ParameterList2\n")); + $$ = makeParamList($1, $3); + } + | ParameterDescriptor { + DPRINTF(kParseDebug, ("got ParameterList1\n")); + $$ = makeParamList($1, NULL); + } + | /* epsilon */ { + DPRINTF(kParseDebug, ("got ParameterList1\n")); + $$ = makeParamList(NULL, NULL); + } + ; + +CostDescriptor: COST '(' NUMBER ')' { + DPRINTF(kParseDebug, ("cost = %d\n", $3)); + $$ = $3; + } + | /* epsilon */ { + DPRINTF(kParseDebug, ("default cost 0\n")); + $$ = 0; + } + ; + +ParameterDescriptor: ParameterType STRING { + DPRINTF(kParseDebug, ("got ParameterDescriptor2\n")); + $$ = makeParameter($1, $2); + } + | ParameterType { + DPRINTF(kParseDebug, ("got ParameterDescriptor1\n")); + $$ = makeParameter($1, NULL); + } + ; + +ParameterType: CompoundParameterType '[' NUMBER ']' { $$ = makeParameterType($1, $3); } + | CompoundParameterType { $$ = makeParameterType($1, 0); } + ; + +CompoundParameterType: STRING '(' InCompoundParameter ')' { $$ = myParenStrCat($1, $3); } + | STRING { $$ = $1; } + ; + +InCompoundParameter: STRING ',' STRING { $$ = myCommaStrCat($1, $3); } + | STRING { $$ = $1; } + | CompoundParameterType { $$ = $1; } + ; +%% + +#ifdef __MWERKS__ +#pragma require_prototypes reset +#endif + + diff --git a/ef/Tools/Nad/NADGrammar/NADGrammarTypes.c b/ef/Tools/Nad/NADGrammar/NADGrammarTypes.c new file mode 100644 index 000000000000..ed9a4e130ead --- /dev/null +++ b/ef/Tools/Nad/NADGrammar/NADGrammarTypes.c @@ -0,0 +1,186 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +/* + NADGrammarTypes.c + + Scott M. Silver +*/ + +#include "NADGrammarTypes.h" +#include +#include +#include +#include + + +/* + makes + "inStr1, inStr2" +*/ +extern char* +myCommaStrCat(const char* inStr1, const char* inStr2) +{ + size_t len = strlen(inStr1) + strlen(inStr2); + char* rv; + + rv = (char*) malloc(len + 1 + 2); /* plus 2 for ", " */ + assert(rv); + + sprintf(rv, "%s, %s", inStr1, inStr2); + + return (rv); +} + + +/* + makes + "inStr1(inStr2)" + +*/ +extern char* +myParenStrCat(const char* inStr1, const char* inStr2) +{ + size_t len = strlen(inStr1) + strlen(inStr2); + char* rv; + + rv = (char*) malloc(len + 1 + 2); /* plus 2 for two parentheses */ + assert(rv); + + sprintf(rv, "%s(%s)", inStr1, inStr2); + + return (rv); +} + + +/* + assume we do NOT have to make copies of any passed in arguments +*/ +extern ParameterType* +makeParameterType(char* inTypeStr, int inStartOffset) +{ + ParameterType* rv; + + assert(inTypeStr); + rv = (ParameterType*) malloc(sizeof(ParameterType)); + assert(rv); + + rv->name = inTypeStr; + rv->start = inStartOffset; + + return (rv); +} + +/* + assume we do NOT have to make copies of any passed in arguments +*/ +extern Parameter* +makeParameter(ParameterType* inType, char* inNameStr) +{ + Parameter* rv; + + assert(inType); + rv = (Parameter*) malloc(sizeof(Parameter)); + assert(rv); + + rv->type = inType; + rv->name = inNameStr; + + return (rv); +} + + +/* + assume we do NOT have to make copies of any passed in arguments +*/ +extern ParamList* +makeParamList(Parameter* inParam1, Parameter* inParam2) +{ + ParamList* rv; + + rv = (ParamList*) malloc(sizeof(ParamList)); + assert(rv); + + rv->param1 = inParam1; + rv->param2 = inParam2; + + return (rv); +} + +/* + assume we do NOT have to make copies of any passed in arguments +*/ +extern Prototype* +makePrototype(ParamList* inParamList, char* inReturnVal, char* inPrimitive) +{ + Prototype* rv; + + rv = (Prototype*) malloc(sizeof(Prototype)); + assert(rv); + + rv->paramList = inParamList; + rv->returnVal = inReturnVal; + rv->primitive = inPrimitive; + + return (rv); +} + + +/* + assume we do NOT have to make copies of any passed in arguments +*/ +extern Rule* +makeRule(Prototype* inPrototype, int inCost, int inHasCode) +{ + Rule* rv; + + rv = (Rule*) malloc(sizeof(Rule)); + assert(rv); + + rv->prototype = inPrototype; + rv->cost = inCost; + rv->hasCode = inHasCode; + + return (rv); +} + + +/* this limit is arbitrary */ +#define kMaximumRules 1000 +Rule* gRules[kMaximumRules]; +Rule** gNextRule = gRules; + +extern void +addRule(Rule* inRule) +{ + assert (gNextRule < gRules + kMaximumRules); + *gNextRule++ = inRule; +} + +#ifdef __MWERKS__ +char* +strdup(const char* inString) +{ + char* rv; + + assert(inString); + rv = (char*) malloc(strlen(inString) + 1); + assert(rv); + + return strcpy(rv, inString); +} +#endif diff --git a/ef/Tools/Nad/NADGrammar/NADGrammarTypes.h b/ef/Tools/Nad/NADGrammar/NADGrammarTypes.h new file mode 100644 index 000000000000..7fa1b4301c5f --- /dev/null +++ b/ef/Tools/Nad/NADGrammar/NADGrammarTypes.h @@ -0,0 +1,72 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +/* + NADGrammarTypes.h + + Scott M. Silver +*/ + +#ifndef NADGRAMMARTYPES_H +#define NADGRAMMARTYPES_H + +typedef struct +{ + char* name; /* name of type */ + int start; /* beginning at which offset */ +} ParameterType; + +typedef struct +{ + ParameterType* type; /* must be non-NULL */ + char* name; /* can be NULL */ +} Parameter; + +typedef struct +{ + Parameter* param1; /* can be NULL */ + Parameter* param2; /* can be NULL */ +} ParamList; + +typedef struct +{ + ParamList* paramList; /* must be non-NULL */ + char* returnVal; /* must be non-NULL */ + char* primitive; /* must be non-NULL */ +} Prototype; + +typedef struct +{ + Prototype* prototype; /* must be non-NULL */ + int cost; + int hasCode; +} Rule; + +extern ParameterType* makeParameterType(char* inTypeStr, int inStartOffset); +extern Parameter* makeParameter(ParameterType* inParamType, char* inNameStr); +extern ParamList* makeParamList(Parameter* inParam1, Parameter* inParam2); +extern Prototype* makePrototype(ParamList* inParamList, char* inReturnVal, char* inPrimitive); +extern Rule* makeRule(Prototype* inPrototype, int inCost, int inHasCode); +extern void addRule(Rule* inNewRule); +extern char* myParenStrCat(const char* inStr1, const char* inStr2); +extern char* myCommaStrCat(const char* inStr1, const char* inStr2); + +#ifdef __MWERKS__ +char* strdup(const char* inString); +#endif + +#endif /* NADGRAMMARTYPES_H */ diff --git a/ef/Tools/Nad/NADGrammar/NADOutput.c b/ef/Tools/Nad/NADGrammar/NADOutput.c new file mode 100644 index 000000000000..c66d272dd354 --- /dev/null +++ b/ef/Tools/Nad/NADGrammar/NADOutput.c @@ -0,0 +1,223 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +/* + NADOutput.c + + Scott M. Silver +*/ + +#include +#include +#ifndef WIN32 +#include +#endif +#include +#include "NADOutput.h" +#include "NADGrammarTypes.h" +#include +#include + +extern FILE* yyout; +extern char* gEmitterName; + +static void echoYYOut(const char* inFormat, ...); +static void fprintBurgRule(FILE* inFile, Rule* inRule, int inRuleNo); +static void fprintCase(FILE* infile, Rule* inRule, int inRuleNo); +static void fprintCaseBegin(FILE* inFile); +static void fprintCaseEnd(FILE* inFile); +static void fprintDeclaration(FILE* inFile, Rule* inRule, int inRuleNo); +static void fprintRuleHeader(FILE* inFile, Prototype* inPrototype, int inRuleNo, int inDefinition); + + +extern int gNextRuleNumber; /* next rule number */ + +void +echoEmitDefinitionHeader(Prototype* inPrototype) +{ + fprintRuleHeader(yyout, inPrototype, gNextRuleNumber++, 1); + echoYYOut("\n{"); +} + +void +echoEmitDefinitionFooter() +{ + echoYYOut("}\n"); +} + +/* + fprintBurgRule + + Recreate the actual "BURG" style rule +*/ +extern Rule** gRules; +extern Rule** gNextRule; +extern int gFirstRuleNumber; + +void fprintRules(FILE* inBurgFile, FILE* inEmitterFile, FILE* inEmitterHeaderFile) +{ + Rule** curRule; + int ruleNo; + + ruleNo = gFirstRuleNumber; + fprintCaseBegin(inEmitterFile); + curRule = (Rule**)&gRules; /* maybe I just don't understand C */ + for (; curRule < gNextRule; curRule++, ruleNo++) + { + fprintBurgRule(inBurgFile, *curRule, ruleNo); + fprintCase(inEmitterFile, *curRule, ruleNo); + fprintDeclaration(inEmitterHeaderFile, *curRule, ruleNo); + } + fprintCaseEnd(inEmitterFile); +} + +void +fprintBurgRule(FILE* inFile, Rule* inRule, int inRuleNo) +{ + Prototype* prototype = inRule->prototype; + fprintf(inFile, "%s: %s", prototype->returnVal, prototype->primitive); + if (prototype->paramList->param1) + { + fprintf(inFile, "(%s", prototype->paramList->param1->type->name); + + if (prototype->paramList->param2) + fprintf(inFile, ", %s)", prototype->paramList->param2->type->name); + else + fprintf(inFile, ")"); + } + else + assert(!prototype->paramList->param2); /* must have param1 */ + + fprintf(inFile, " = %d (%d);\n", inRuleNo, inRule->cost); +} + +void +fprintCaseBegin(FILE* inFile) +{ + fprintf(inFile, "void %s::\n" + "emitPrimitive(Primitive& inPrimitive, int inRule)\n" + "{\n" + "\tswitch (inRule)\n" + "\t{\n", gEmitterName); +} + + +void +fprintCaseEnd(FILE* inFile) +{ + fprintf(inFile, "\t}\n\n" + "}\n"); +} + +void +fprintCase(FILE* inFile, Rule* inRule, int inRuleNo) +{ + Prototype* prototype = inRule->prototype; + int curInput; + + if (inRule->hasCode) + { + if (inRule->prototype->paramList->param1) + curInput = inRule->prototype->paramList->param1->type->start; + else + curInput = 0; + + fprintf(inFile, "\t\tcase%4d: ", inRuleNo); + fprintf(inFile, "\t\t\temitRule%d(inPrimitive", inRuleNo); + if (prototype->paramList->param1) + fprintf(inFile, ", inPrimitive.nthInputVariable(%d)", curInput++); + + if (prototype->paramList->param2) + fprintf(inFile, ", inPrimitive.nthInputVariable(%d)", curInput++); + + fprintf(inFile, "); break;\n"); + } +} + + +void +fprintDeclaration(FILE* inFile, Rule* inRule, int inRuleNo) +{ + Prototype* prototype = inRule->prototype; + + fprintf(inFile, "\t"); + fprintRuleHeader(inFile, prototype, inRuleNo, 0); + fprintf(inFile, ";\n"); +} + +void +fprintRuleHeader(FILE* inFile, Prototype* inPrototype, int inRuleNo, int inDefinition) +{ + int unused = 0; + + if (inDefinition) + fprintf(inFile, "void %s::\n", gEmitterName); + else + fprintf(inFile, "void\t"); + + fprintf(inFile, "emitRule%d(Primitive& thisPrimitive", inRuleNo); + + if (inPrototype->paramList->param1) + { + fprintf(inFile, ", "); + if (inPrototype->paramList->param1->name) + fprintf(inFile, "DataNode& %s", inPrototype->paramList->param1->name); + else + fprintf(inFile, "DataNode& /*inUnused%d*/", unused++); + } + + if (inPrototype->paramList->param2) + { + fprintf(inFile, ", "); + if (inPrototype->paramList->param2->name) + fprintf(inFile, "DataNode& %s", inPrototype->paramList->param2->name); + else + fprintf(inFile, "DataNode& /*inUnused%d*/", unused++); + } + fprintf(inFile, ")"); +} + +void +fprintGeneratedHeader(FILE* inFile, const char* inFileName) +{ + time_t currentTime; + + time(¤tTime); + fprintf(inFile, "// %s\n" + "//\n" + "// Generated File. Do not edit.\n" + "//\n" + "// %s\n", inFileName, ctime(¤tTime)); +} + + +/* + echoYYOut + + Print stuff to stdout +*/ +static void +echoYYOut(const char* inFormat, ...) +{ + va_list ap; + + va_start(ap, inFormat); + vfprintf(yyout, inFormat, ap); +} + + + diff --git a/ef/Tools/Nad/NADGrammar/NADOutput.h b/ef/Tools/Nad/NADGrammar/NADOutput.h new file mode 100644 index 000000000000..ddac257b3188 --- /dev/null +++ b/ef/Tools/Nad/NADGrammar/NADOutput.h @@ -0,0 +1,30 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +/* + NADOutput.h + + Scott M. Silver +*/ + +#include +#include "NADGrammarTypes.h" + +extern void echoEmitDefinitionHeader(Prototype* inPrototype); +extern void echoEmitDefinitionFooter(); +extern void fprintRules(FILE* inBurgFile, FILE* inEmitterFile, FILE* inEmitterHeaderFile); +extern void fprintGeneratedHeader(FILE* inFile, const char* inFileName); diff --git a/ef/Tools/Nad/NADGrammar/alloca.c b/ef/Tools/Nad/NADGrammar/alloca.c new file mode 100644 index 000000000000..95f082ce3ab7 --- /dev/null +++ b/ef/Tools/Nad/NADGrammar/alloca.c @@ -0,0 +1,489 @@ +/* alloca.c -- allocate automatically reclaimed memory + (Mostly) portable public-domain implementation -- D A Gwyn + + This implementation of the PWB library alloca function, + which is used to allocate space off the run-time stack so + that it is automatically reclaimed upon procedure exit, + was inspired by discussions with J. Q. Johnson of Cornell. + J.Otto Tennant contributed the Cray support. + + There are some preprocessor constants that can + be defined when compiling for your specific system, for + improved efficiency; however, the defaults should be okay. + + The general concept of this implementation is to keep + track of all alloca-allocated blocks, and reclaim any + that are found to be deeper in the stack than the current + invocation. This heuristic does not reclaim storage as + soon as it becomes invalid, but it will do so eventually. + + As a special case, alloca(0) reclaims storage without + allocating any. It is a good idea to use alloca(0) in + your main control loop, etc. to force garbage collection. */ + +#ifdef WIN32 +void free(void*); +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +/* If compiling with GCC 2, this file's not needed. */ +#if !defined (__GNUC__) || __GNUC__ < 2 + +/* If someone has defined alloca as a macro, + there must be some other way alloca is supposed to work. */ +#ifndef alloca + +#ifdef emacs +#ifdef static +/* actually, only want this if static is defined as "" + -- this is for usg, in which emacs must undefine static + in order to make unexec workable + */ +#ifndef STACK_DIRECTION +you +lose +-- must know STACK_DIRECTION at compile-time +#endif /* STACK_DIRECTION undefined */ +#endif /* static */ +#endif /* emacs */ + +/* If your stack is a linked list of frames, you have to + provide an "address metric" ADDRESS_FUNCTION macro. */ + +#if defined (CRAY) && defined (CRAY_STACKSEG_END) +long i00afunc (); +#define ADDRESS_FUNCTION(arg) (char *) i00afunc (&(arg)) +#else +#define ADDRESS_FUNCTION(arg) &(arg) +#endif + +#if __STDC__ +typedef void *pointer; +#else +typedef char *pointer; +#endif + +#define NULL 0 + +/* Different portions of Emacs need to call different versions of + malloc. The Emacs executable needs alloca to call xmalloc, because + ordinary malloc isn't protected from input signals. On the other + hand, the utilities in lib-src need alloca to call malloc; some of + them are very simple, and don't have an xmalloc routine. + + Non-Emacs programs expect this to call use xmalloc. + + Callers below should use malloc. */ + +#if !defined(emacs) && !defined(__MWERKS__) &&!defined(WIN32) +#define malloc xmalloc +#endif +extern pointer malloc (); + +/* Define STACK_DIRECTION if you know the direction of stack + growth for your system; otherwise it will be automatically + deduced at run-time. + + STACK_DIRECTION > 0 => grows toward higher addresses + STACK_DIRECTION < 0 => grows toward lower addresses + STACK_DIRECTION = 0 => direction of growth unknown */ + +#ifndef STACK_DIRECTION +#define STACK_DIRECTION 0 /* Direction unknown. */ +#endif + +#if STACK_DIRECTION != 0 + +#define STACK_DIR STACK_DIRECTION /* Known at compile-time. */ + +#else /* STACK_DIRECTION == 0; need run-time code. */ + +static int stack_dir; /* 1 or -1 once known. */ +#define STACK_DIR stack_dir + +static void +find_stack_direction () +{ + static char *addr = NULL; /* Address of first `dummy', once known. */ + auto char dummy; /* To get stack address. */ + + if (addr == NULL) + { /* Initial entry. */ + addr = ADDRESS_FUNCTION (dummy); + + find_stack_direction (); /* Recurse once. */ + } + else + { + /* Second entry. */ + if (ADDRESS_FUNCTION (dummy) > addr) + stack_dir = 1; /* Stack grew upward. */ + else + stack_dir = -1; /* Stack grew downward. */ + } +} + +#endif /* STACK_DIRECTION == 0 */ + +/* An "alloca header" is used to: + (a) chain together all alloca'ed blocks; + (b) keep track of stack depth. + + It is very important that sizeof(header) agree with malloc + alignment chunk size. The following default should work okay. */ + +#ifndef ALIGN_SIZE +#define ALIGN_SIZE sizeof(double) +#endif + +typedef union hdr +{ + char align[ALIGN_SIZE]; /* To force sizeof(header). */ + struct + { + union hdr *next; /* For chaining headers. */ + char *deep; /* For stack depth measure. */ + } h; +} header; + +static header *last_alloca_header = NULL; /* -> last alloca header. */ + +/* Return a pointer to at least SIZE bytes of storage, + which will be automatically reclaimed upon exit from + the procedure that called alloca. Originally, this space + was supposed to be taken from the current stack frame of the + caller, but that method cannot be made to work for some + implementations of C, for example under Gould's UTX/32. */ + +#ifdef __MWERKS__ +#include +#include "alloca.h" +#endif + +pointer +alloca (size) + unsigned size; +{ + auto char probe; /* Probes stack depth: */ + register char *depth = ADDRESS_FUNCTION (probe); + +#if STACK_DIRECTION == 0 + if (STACK_DIR == 0) /* Unknown growth direction. */ + find_stack_direction (); +#endif + + /* Reclaim garbage, defined as all alloca'd storage that + was allocated from deeper in the stack than currently. */ + + { + register header *hp; /* Traverses linked list. */ + + for (hp = last_alloca_header; hp != NULL;) + if ((STACK_DIR > 0 && hp->h.deep > depth) + || (STACK_DIR < 0 && hp->h.deep < depth)) + { + register header *np = hp->h.next; + + free ((pointer) hp); /* Collect garbage. */ + + hp = np; /* -> next header. */ + } + else + break; /* Rest are not deeper. */ + + last_alloca_header = hp; /* -> last valid storage. */ + } + + if (size == 0) + return NULL; /* No allocation required. */ + + /* Allocate combined header + user data storage. */ + + { + register pointer new = malloc (sizeof (header) + size); + /* Address of header. */ + + ((header *) new)->h.next = last_alloca_header; + ((header *) new)->h.deep = depth; + + last_alloca_header = (header *) new; + + /* User storage begins just after header. */ + + return (pointer) ((char *) new + sizeof (header)); + } +} + +#if defined (CRAY) && defined (CRAY_STACKSEG_END) + +#ifdef DEBUG_I00AFUNC +#include +#endif + +#ifndef CRAY_STACK +#define CRAY_STACK +#ifndef CRAY2 +/* Stack structures for CRAY-1, CRAY X-MP, and CRAY Y-MP */ +struct stack_control_header + { + long shgrow:32; /* Number of times stack has grown. */ + long shaseg:32; /* Size of increments to stack. */ + long shhwm:32; /* High water mark of stack. */ + long shsize:32; /* Current size of stack (all segments). */ + }; + +/* The stack segment linkage control information occurs at + the high-address end of a stack segment. (The stack + grows from low addresses to high addresses.) The initial + part of the stack segment linkage control information is + 0200 (octal) words. This provides for register storage + for the routine which overflows the stack. */ + +struct stack_segment_linkage + { + long ss[0200]; /* 0200 overflow words. */ + long sssize:32; /* Number of words in this segment. */ + long ssbase:32; /* Offset to stack base. */ + long:32; + long sspseg:32; /* Offset to linkage control of previous + segment of stack. */ + long:32; + long sstcpt:32; /* Pointer to task common address block. */ + long sscsnm; /* Private control structure number for + microtasking. */ + long ssusr1; /* Reserved for user. */ + long ssusr2; /* Reserved for user. */ + long sstpid; /* Process ID for pid based multi-tasking. */ + long ssgvup; /* Pointer to multitasking thread giveup. */ + long sscray[7]; /* Reserved for Cray Research. */ + long ssa0; + long ssa1; + long ssa2; + long ssa3; + long ssa4; + long ssa5; + long ssa6; + long ssa7; + long sss0; + long sss1; + long sss2; + long sss3; + long sss4; + long sss5; + long sss6; + long sss7; + }; + +#else /* CRAY2 */ +/* The following structure defines the vector of words + returned by the STKSTAT library routine. */ +struct stk_stat + { + long now; /* Current total stack size. */ + long maxc; /* Amount of contiguous space which would + be required to satisfy the maximum + stack demand to date. */ + long high_water; /* Stack high-water mark. */ + long overflows; /* Number of stack overflow ($STKOFEN) calls. */ + long hits; /* Number of internal buffer hits. */ + long extends; /* Number of block extensions. */ + long stko_mallocs; /* Block allocations by $STKOFEN. */ + long underflows; /* Number of stack underflow calls ($STKRETN). */ + long stko_free; /* Number of deallocations by $STKRETN. */ + long stkm_free; /* Number of deallocations by $STKMRET. */ + long segments; /* Current number of stack segments. */ + long maxs; /* Maximum number of stack segments so far. */ + long pad_size; /* Stack pad size. */ + long current_address; /* Current stack segment address. */ + long current_size; /* Current stack segment size. This + number is actually corrupted by STKSTAT to + include the fifteen word trailer area. */ + long initial_address; /* Address of initial segment. */ + long initial_size; /* Size of initial segment. */ + }; + +/* The following structure describes the data structure which trails + any stack segment. I think that the description in 'asdef' is + out of date. I only describe the parts that I am sure about. */ + +struct stk_trailer + { + long this_address; /* Address of this block. */ + long this_size; /* Size of this block (does not include + this trailer). */ + long unknown2; + long unknown3; + long link; /* Address of trailer block of previous + segment. */ + long unknown5; + long unknown6; + long unknown7; + long unknown8; + long unknown9; + long unknown10; + long unknown11; + long unknown12; + long unknown13; + long unknown14; + }; + +#endif /* CRAY2 */ +#endif /* not CRAY_STACK */ + +#ifdef CRAY2 +/* Determine a "stack measure" for an arbitrary ADDRESS. + I doubt that "lint" will like this much. */ + +static long +i00afunc (long *address) +{ + struct stk_stat status; + struct stk_trailer *trailer; + long *block, size; + long result = 0; + + /* We want to iterate through all of the segments. The first + step is to get the stack status structure. We could do this + more quickly and more directly, perhaps, by referencing the + $LM00 common block, but I know that this works. */ + + STKSTAT (&status); + + /* Set up the iteration. */ + + trailer = (struct stk_trailer *) (status.current_address + + status.current_size + - 15); + + /* There must be at least one stack segment. Therefore it is + a fatal error if "trailer" is null. */ + + if (trailer == 0) + abort (); + + /* Discard segments that do not contain our argument address. */ + + while (trailer != 0) + { + block = (long *) trailer->this_address; + size = trailer->this_size; + if (block == 0 || size == 0) + abort (); + trailer = (struct stk_trailer *) trailer->link; + if ((block <= address) && (address < (block + size))) + break; + } + + /* Set the result to the offset in this segment and add the sizes + of all predecessor segments. */ + + result = address - block; + + if (trailer == 0) + { + return result; + } + + do + { + if (trailer->this_size <= 0) + abort (); + result += trailer->this_size; + trailer = (struct stk_trailer *) trailer->link; + } + while (trailer != 0); + + /* We are done. Note that if you present a bogus address (one + not in any segment), you will get a different number back, formed + from subtracting the address of the first block. This is probably + not what you want. */ + + return (result); +} + +#else /* not CRAY2 */ +/* Stack address function for a CRAY-1, CRAY X-MP, or CRAY Y-MP. + Determine the number of the cell within the stack, + given the address of the cell. The purpose of this + routine is to linearize, in some sense, stack addresses + for alloca. */ + +static long +i00afunc (long address) +{ + long stkl = 0; + + long size, pseg, this_segment, stack; + long result = 0; + + struct stack_segment_linkage *ssptr; + + /* Register B67 contains the address of the end of the + current stack segment. If you (as a subprogram) store + your registers on the stack and find that you are past + the contents of B67, you have overflowed the segment. + + B67 also points to the stack segment linkage control + area, which is what we are really interested in. */ + + stkl = CRAY_STACKSEG_END (); + ssptr = (struct stack_segment_linkage *) stkl; + + /* If one subtracts 'size' from the end of the segment, + one has the address of the first word of the segment. + + If this is not the first segment, 'pseg' will be + nonzero. */ + + pseg = ssptr->sspseg; + size = ssptr->sssize; + + this_segment = stkl - size; + + /* It is possible that calling this routine itself caused + a stack overflow. Discard stack segments which do not + contain the target address. */ + + while (!(this_segment <= address && address <= stkl)) + { +#ifdef DEBUG_I00AFUNC + fprintf (stderr, "%011o %011o %011o\n", this_segment, address, stkl); +#endif + if (pseg == 0) + break; + stkl = stkl - pseg; + ssptr = (struct stack_segment_linkage *) stkl; + size = ssptr->sssize; + pseg = ssptr->sspseg; + this_segment = stkl - size; + } + + result = address - this_segment; + + /* If you subtract pseg from the current end of the stack, + you get the address of the previous stack segment's end. + This seems a little convoluted to me, but I'll bet you save + a cycle somewhere. */ + + while (pseg != 0) + { +#ifdef DEBUG_I00AFUNC + fprintf (stderr, "%011o %011o\n", pseg, size); +#endif + stkl = stkl - pseg; + ssptr = (struct stack_segment_linkage *) stkl; + size = ssptr->sssize; + pseg = ssptr->sspseg; + result += size; + } + return (result); +} + +#endif /* not CRAY2 */ +#endif /* CRAY */ + +#endif /* no alloca */ +#endif /* not GCC version 2 */ diff --git a/ef/Tools/Nad/NADGrammar/alloca.h b/ef/Tools/Nad/NADGrammar/alloca.h new file mode 100644 index 000000000000..32b94746acf5 --- /dev/null +++ b/ef/Tools/Nad/NADGrammar/alloca.h @@ -0,0 +1,27 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +/* + alloca.h + + Scott M. Silver +*/ + +#ifdef __MWERKS__ +pointer +alloca (unsigned size); +#endif diff --git a/ef/Tools/Nad/NADGrammar/macbuild/NADGrammarAppPrefix.h b/ef/Tools/Nad/NADGrammar/macbuild/NADGrammarAppPrefix.h new file mode 100644 index 000000000000..c20054a9cd19 --- /dev/null +++ b/ef/Tools/Nad/NADGrammar/macbuild/NADGrammarAppPrefix.h @@ -0,0 +1,8 @@ +/* + + + NADGrammarAppPrefix.h +*/ + + +#define NADGRAMMAR_APP \ No newline at end of file diff --git a/ef/Tools/Nad/NADGrammar/macbuild/NadGrammar.prj2 b/ef/Tools/Nad/NADGrammar/macbuild/NadGrammar.prj2 new file mode 100644 index 000000000000..e7e68da06d91 Binary files /dev/null and b/ef/Tools/Nad/NADGrammar/macbuild/NadGrammar.prj2 differ diff --git a/ef/Tools/Nad/NADGrammar/winbuild/.cvsignore b/ef/Tools/Nad/NADGrammar/winbuild/.cvsignore new file mode 100644 index 000000000000..35fc3a4ff7c3 --- /dev/null +++ b/ef/Tools/Nad/NADGrammar/winbuild/.cvsignore @@ -0,0 +1,3 @@ +Debug +Release +*.plg diff --git a/ef/Tools/Nad/NADGrammar/winbuild/NADGrammar.dsp b/ef/Tools/Nad/NADGrammar/winbuild/NADGrammar.dsp new file mode 100644 index 000000000000..572d8ad0365c --- /dev/null +++ b/ef/Tools/Nad/NADGrammar/winbuild/NADGrammar.dsp @@ -0,0 +1,257 @@ +# Microsoft Developer Studio Project File - Name="NADGrammar" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 5.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=NADGrammar - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "NADGrammar.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "NADGrammar.mak" CFG="NADGrammar - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "NADGrammar - Win32 Release" (based on\ + "Win32 (x86) Console Application") +!MESSAGE "NADGrammar - Win32 Debug" (based on\ + "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "NADGrammar - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I ".." /I "..\..\..\Debugger ..\..\..\Exports ..\..\..\Exports\md" /I "..\..\..\Exports ..\..\..\Exports\md" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "NADGrammar - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /ML /W3 /Gm /GX /Zi /Od /I ".." /I "..\..\..\Debugger" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR /YX /FD /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 winmm.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /nodefaultlib:"MSVCRT.lib" /pdbtype:sept +# SUBTRACT LINK32 /pdb:none /nodefaultlib + +!ENDIF + +# Begin Target + +# Name "NADGrammar - Win32 Release" +# Name "NADGrammar - Win32 Debug" +# Begin Group "Generated Files (Debug)" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\Debug\lex.yy.c + +!IF "$(CFG)" == "NADGrammar - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "NADGrammar - Win32 Debug" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\Debug\nadgrammar.tab.c + +!IF "$(CFG)" == "NADGrammar - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "NADGrammar - Win32 Debug" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\Debug\nadgrammar.tab.h + +!IF "$(CFG)" == "NADGrammar - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "NADGrammar - Win32 Debug" + +!ENDIF + +# End Source File +# End Group +# Begin Group "Generated Files (Release)" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\Release\lex.yy.c + +!IF "$(CFG)" == "NADGrammar - Win32 Release" + +!ELSEIF "$(CFG)" == "NADGrammar - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\Release\nadgrammar.tab.c + +!IF "$(CFG)" == "NADGrammar - Win32 Release" + +!ELSEIF "$(CFG)" == "NADGrammar - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\Release\nadgrammar.tab.h + +!IF "$(CFG)" == "NADGrammar - Win32 Release" + +!ELSEIF "$(CFG)" == "NADGrammar - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# End Group +# Begin Source File + +SOURCE=..\alloca.c +# End Source File +# Begin Source File + +SOURCE=..\NADGrammar.c +# End Source File +# Begin Source File + +SOURCE=..\NADGrammar.l + +!IF "$(CFG)" == "NADGrammar - Win32 Release" + +# Begin Custom Build - Flex'ing my muscles +OutDir=.\Release +InputPath=..\NADGrammar.l + +"$(OutDir)\lex.yy.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + $(NSTOOLS)\bin\flex -t $(InputPath) > $(OutDir)\lex.yy.c + +# End Custom Build + +!ELSEIF "$(CFG)" == "NADGrammar - Win32 Debug" + +# Begin Custom Build - flex +OutDir=.\Debug +InputPath=..\NADGrammar.l + +"$(OutDir)\lex.yy.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + $(MOZ_TOOLS)\bin\flex -t $(InputPath) > $(OutDir)\lex.yy.c + +# End Custom Build + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\NADGrammar.y + +!IF "$(CFG)" == "NADGrammar - Win32 Release" + +# Begin Custom Build - Bison me +OutDir=.\Release +InputPath=..\NADGrammar.y + +"$(OutDir)\NADGrammar.tab.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + $(NSTOOLS)\bin\bison.exe --defines $(InputPath) --output\ + $(OutDir)\NADGrammar.tab.c + +# End Custom Build + +!ELSEIF "$(CFG)" == "NADGrammar - Win32 Debug" + +# Begin Custom Build - bison me +OutDir=.\Debug +InputPath=..\NADGrammar.y + +"$(OutDir)\NADGrammar.tab.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + $(MOZ_TOOLS)\bin\bison.exe --defines $(InputPath) --output\ + $(OutDir)\NADGrammar.tab.c + +# End Custom Build + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\NADGrammarTypes.c +# End Source File +# Begin Source File + +SOURCE=..\NADGrammarTypes.h +# End Source File +# Begin Source File + +SOURCE=..\NADOutput.c +# End Source File +# Begin Source File + +SOURCE=..\NADOutput.h +# End Source File +# End Target +# End Project diff --git a/ef/Tools/Nad/NADGrammar/winbuild/NADGrammar.dsw b/ef/Tools/Nad/NADGrammar/winbuild/NADGrammar.dsw new file mode 100644 index 000000000000..591a1d302898 --- /dev/null +++ b/ef/Tools/Nad/NADGrammar/winbuild/NADGrammar.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 5.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "NADGrammar"=.\NADGrammar.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/ef/Tools/Nad/PrepareBurg.pl b/ef/Tools/Nad/PrepareBurg.pl new file mode 100644 index 000000000000..61fd41f2de78 --- /dev/null +++ b/ef/Tools/Nad/PrepareBurg.pl @@ -0,0 +1,118 @@ +#!/usr/local/bin/perl +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. +# + +# PrepareBurg.pl +# +# Assembles a BURG rule file from different inputs +# +# Usage: +# perl PrepareBurg.pl +# input primitive operations description +# < input (stdin) machine specific BURG style rules +# > output (stdout) +# + +use PrimOp; + +# rules in BURG must be >= 1 +# terminals in BURG must be >= 1 + +# grab the arguments +($PrimitiveOperationsSourceFN) = @ARGV; + +PrimOp::readPrimitiveOperations($PrimitiveOperationsSourceFN); + +# cruft at top +print "%{\n"; +print q!#include "Burg.h"!; +print "\n%}\n"; + +# start symbol +# we use a false one so we can have multiple start symbols +print "%start xxxGeneratedStartSymbol\n"; + +# **** BEGIN %term section + +# input is gPrimitiveInfo +# output is @ts, a list of terminals and there numbers (assumed to start +# at 1 (skipping poNone) and continuing on. +# convert a primitive info into a list of terminal names +# skip first terminal which is poNone (because we should never see that primitive +# and BURG can't handle terminals <= 0 +$gTermNo = 1; +foreach $x (@PrimOp::gPrimitiveInfo[$gTermNo..$#PrimOp::gPrimitiveInfo]) { + if ($x->[$nameIndex] ne "") { + print "%term $x->[$nameIndex] = $gTermNo\n"; + $gTermNo++; + } +} + +# **** BEGIN rules section +print "%%\n"; + +# Open the file containing the BurgRules and just print them +# to stdout +$gCurRule = 1; +while () { + $gMachineSpecificRules[$gCurRule++] = $_; +} + +print "Vint: coReg_I = ", $gCurRule++, " (0);\n", + "Vlong: coReg_L = ", $gCurRule++, " (0);\n", + "Vfloat: coReg_F = ", $gCurRule++, " (0);\n", + "Vdouble: coReg_D = ", $gCurRule++, " (0);\n", + "Vptr: coReg_A = ", $gCurRule++, " (0);\n", + "Vcond: coReg_C = ", $gCurRule++, " (0);\n", + "Store: coReg_M = ", $gCurRule++, " (0);\n", + "Cint: coReg_I = ", $gCurRule++, " (0);\n", + "Clong: coReg_L = ", $gCurRule++, " (0);\n", + "Cfloat: coReg_F = ", $gCurRule++, " (0);\n", + "Cdouble: coReg_D = ", $gCurRule++, " (0);\n", + "Cptr: coReg_A = ", $gCurRule++, " (0);\n", + "Tuple: coReg_T = ", $gCurRule++, " (0);\n", + "Vint: poArg_I = ", $gCurRule++, " (0);\n", + "Vlong: poArg_L = ", $gCurRule++, " (0);\n", + "Vfloat: poArg_F = ", $gCurRule++, " (0);\n", + "Vdouble: poArg_D = ", $gCurRule++, " (0);\n", + "Vptr: poArg_A = ", $gCurRule++, " (0);\n", + "Store: poArg_M = ", $gCurRule++, " (0);\n", + "Result: poResult_M(Store) = ", $gCurRule++, " (0);\n", + "Store: poProj_M = ", $gCurRule++, " (0);\n", + "Vint: poProj_I = ", $gCurRule++, " (0);\n", + "Vptr: poProj_A = ", $gCurRule++, " (0);\n", + "Vptr: poConst_M = ", $gCurRule++, " (0);\n"; + +# now print out the start symbols +# start symbols are anonymous rules +@gStartSymbols = qw(Control Result Exception Store Vcond Vint Vlong Vfloat Vdouble Vptr Cint Clong Cfloat Cdouble Cptr Tuple); +foreach $x (@gStartSymbols) { + print "xxxGeneratedStartSymbol:\t$x \t = $gCurRule (0);\n"; + $gCurRule++; +} + +# now print out those rules +$gCurRule = 1; +foreach $x (@gMachineSpecificRules[$gCurRule..$#gMachineSpecificRules]) { + print $x; + $gCurRule++; +} + +# end grammar section +print "%%\n"; + +1; diff --git a/ef/Tools/Nad/nad.pl b/ef/Tools/Nad/nad.pl new file mode 100644 index 000000000000..1f112a28e85c --- /dev/null +++ b/ef/Tools/Nad/nad.pl @@ -0,0 +1,706 @@ +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. +# + +# +# nad.pl +# +# Takes a nad file (Netscape Architecture Definition) and +# produces a header with the Terminals and Named rules in it +# and prints the BURG specification to stdout. +# +# Usage: +# perl nad.pl > +# + +# rules in BURG must be >= 1 +# terminals in BURG must be >= 1 + +# Fields of a $gPrimitiveInfo structure +$nameIndex = 0; +$categoryIndex = 1; +$usageIndex = 2; +$commentIndex = 3; + +# DataNode flag numbers +$dnIsReal = 0; +$dnCanRaiseException = 1; +$dnIsRoot = 2; + +# Special kinds +$voidKind = "vkVoid"; +$shortOrigin = "aoVariable"; + +# grab the arguments +($NadFile, $PrimitiveOperationsSourceFN, $PrimitiveOperationsEnumFN, $DataNodeTemplateFN, $BurgHeaderFN) = @ARGV; + +#print STDERR "$PrimitiveOperationsSourceFN\n"; + +# read PrimitiveOperation infos +open PrimitiveOperationsSourceFN or die "Couldn't open $PrimitiveOperationsSourceFN: $!\n"; +$readingStage = 0; +while () +{ + if ($readingStage == 0) { + if (/^\s*((?:\/\/.*)?\n)$/) { + push @headerLines,$1; + } else { + $readingStage = 1; + } + } + if ($readingStage == 1) { + if (/^\s*ARG-ORIGIN\s+'(.)'\s+(\w+)\s*;\s*\n$/) { + $argOrigins{$1} = $2; + } elsif (/^\s*ARG-KIND\s+'(.)'\s+(\w+)\s*;\s*\n$/) { + $argKinds{$1} = $2; + } elsif (/^\s*SHORT-ARG\s+'(.)'\s+(\w+)\s*;\s*\n$/) { + $shortArgs{$1} = $2; + } elsif (!/^\s*(\/\/.*)?\n$/) { + $readingStage = 2; + } + } + if ($readingStage == 2) { + die "Bad line: $_\n" unless m/^(?:\s*{(\w+),\s*(\w+),\s*"([^"\s]*)"})?(?:\s*(\/\/.*))?\n?$/; + # print STDERR "--->$1***$2***$3***$4\n"; + #($name, $category, $usage, $comment) = ($1, $2, $3, $4); + push @gPrimitiveInfo, [$1, $2, $3, $4]; + } +} +close PrimitiveOperationsSourceFN; + +$argOrigins = ""; +$argKinds = ""; +$shortArgs = ""; +foreach (keys %argOrigins) {$argOrigins .= $_;} +foreach (keys %argKinds) {$argKinds .= $_;} +foreach (keys %shortArgs) {$shortArgs .= $_;} +#print STDERR "argOrigins = \"$argOrigins\"\n"; +#print STDERR "argKinds = \"$argKinds\"\n"; +#print STDERR "shortArgs = \"$shortArgs\"\n"; + +$maxArgOriginNameLength = maxStringLength(values %argOrigins); +$maxValueKindNameLength = maxStringLength(values %argKinds, values %shortArgs); +$maxPrimitiveNameLength = maxStringLength(map $_->[$nameIndex], @gPrimitiveInfo); +$maxCategoryNameLength = maxStringLength(map $_->[$categoryIndex], @gPrimitiveInfo); + +# do DataNodeTemplates +unlink ($DataNodeTemplateFN) or break; +outputNodeTemplates($DataNodeTemplateFN, \@gPrimitiveInfo); + +# do PrimitiveOperations enum +unlink ($PrimitiveOperationsEnumFN) or break; +$gLastPrimEnumName = outputEnumFromListX("PrimitiveOperation", $PrimitiveOperationsEnumFN, 0, \@gPrimitiveInfo, \&primInfoToEnumDescriptor); +open FILE, ">>$PrimitiveOperationsEnumFN" or die "Couldn't open $PrimitiveOperationsEnumFN: $!\n"; +print FILE "\nconst nPrimitiveOperations = $gLastPrimEnumName + 1;\n"; +close FILE; + +# now handle the BURG section of the file +open NadFile or die "Couldn't open $NadFile: $!\n"; +while () +{ + if (/%(.*)/) + { + $section = $1; + + if ($section eq "terminals") + { + #print STDERR "processing terminals...\n"; + while() + { + if (/%/) + { + last; + } + else + { + chop; + $ts[++$#ts] = $_; + } + } + } + elsif($section eq "startsymbols") + { + #print STDERR "processing startsymbols...\n"; + while() + { + if (/%/) + { + last; + } + else + { + chop; + $sss[++$#sss] = $_; + } + } + } + elsif($section eq "top") + { + #print STDERR "processing top...\n"; + while() + { + if (/%/) + { + last; + } + else + { + $top[++$#top] = $_; + } + } + } + elsif($section eq "nonterm_header") + { + #print STDERR "processing nonterm_header...\n"; + while() + { + if (/%/) + { + last; + } + else + { + $BurgHeaderFN[++$#header] = $_; + } + } + } + elsif($section eq "grammar") + { + #print STDERR "processing grammar...\n"; + while() + { + if (/%/) + { + last; + } + else + { + chop; + $old = $_; + if (!s/\/\/.*//) + { + $_ = $old; + if (s/\w//) + { + $_ = $old; + ($rules[++$#rules], $costs[++$#costs], $rulenames[++$#rulenames]) = split(/\$/, $_); + $costs[$#costs] =~ s/\s//g; + $rulenames[$#rulenames] =~ s/\s//g; + } + } + } + } + + + } + } +} + +# Do NamedRules enum file +unlink ($BurgHeaderFN) or break; +outputEnumFromListX("NamedRules", $BurgHeaderFN, 1, \@rulenames, \&ruleNameToEnumDescriptor); + +# print out cruft at top +print "%{\n"; +foreach $x (@top) +{ + print $x; +} +print "%}\n"; + +# print out start symbol +# we use a false one so we can have multiple start symbols +print "%start xxxGeneratedStartSymbol\n"; + +# print terminals +$termno = 1; +foreach $x (@primoperations) +{ + $_ = $x; + if (s/\w+//) + { + print "%term $x = $termno\n"; + $termno++; + } +} + +# convert a primitive info into a list of terminal names +# skip first terminal which is pkNone +@ts = (); +foreach $x (@gPrimitiveInfo[1..$#gPrimitiveInfo]) +{ + push @ts, $x->[$nameIndex]; +} + +# print out "%term BLAHBLAH = number" +foreach $x (@ts) +{ + $_ = $x; + if (s/\w+//) + { + print "%term $x = $termno\n"; + $termno++; + } +} + +# start counting anonruleno's at the number rules + number of start symbols +$anonruleno = $#rules +1 + $#sss + 1; +print "%%\n"; + + +# now print out the start symbols +# start symbols are anonymous rules +foreach $x (@sss) +{ + print "xxxGeneratedStartSymbol:\t$x \t = $anonruleno (0);\n"; + $anonruleno++; +} + + +# now print out the rules +# if it is a named rule we store it away in +# an array of named rules so we can print the enum out later +# named rules start at 0 anonymous rules pick up where sss's left of +$namedruleno = 1; +$i = 0; +foreach $x (@rules) +{ + #print STDERR "$i rulename: ***$rulenames[$i]*** ***$costs[$i]***\n"; + + if ($rulenames[$i] eq "") + { + # this is an anonymous rule + #print STDERR "anon\n"; + + print "$x\t = $anonruleno ($costs[$i]);\n"; + $anonruleno++; + } + else + { + print "$x\t = $namedruleno ($costs[$i]);\n"; + $namedrules[++$#namedrules] = $rulenames[$i]; + $namedruleno++; + } + + $i = $i + 1; +} + +print "%%\n"; + + +# primInfoToEnumDescriptor +# +# Convert a primInfo to a ($enumname, $enumcomment) list +sub primInfoToEnumDescriptor +{ + my ($primInfo) = @_; + return ($$primInfo[$nameIndex], $$primInfo[$commentIndex]); +} + +# primInfoToEnumDescriptor +# +# Convert a namedrule (a string) to a ($enumname, $enumcomment) list +sub ruleNameToEnumDescriptor +{ + my ($name) = @_; + return ($name, ""); +} + + +# outputGeneratedHeader +# +# Output header of generated file. +sub outputGeneratedHeader +{ + my ($fh, $filename) = @_; + + $_ = $filename; + + if (!(s/.*:([^:]+)\Z/$1/)) + { + s/(.*)/$1/; + } + + $filename = $1; + + print $fh "//\n// $filename\n//\n// Generated file\n// DO NOT EDIT\n//\n\n"; +} + + +# outputEnumFromListX +# +# in +# name: name of this enum, will be printed as a comment above +# fileName: file name which to append this enum +# enumBase: value of first enum (usually either 0 or 1) +# items: list of items +# convertFunc: function that transforms an item into a (enumname, enumcomment) list +# +# out +# the file $fileName with the appended enum +# returns the last enum output +# +sub outputEnumFromListX +{ + my ($name, $fileName, $enumBase, $items, $convertFunc) = @_; + my $i; + my $lastEnum; + my $lastName; + + for ($i = $#$items; $i >= 0; $i--) + { + my ($name, $comment) = &$convertFunc($$items[$i]); + if ($name ne "") + { + $lastEnum = $i; + $lastName = $name; + last; + } + } + #($hi, $crap) = &$convertFunc($$items[$lastEnum]); + #print STDERR "----> $lastEnum, $hi <---\n"; + + open FILE, ">>$fileName" or die "Couldn't open $fileName: $!\n"; + + outputGeneratedHeader(\*FILE, $fileName); + print FILE "enum $name\n"; + print FILE "{\n"; + + my $enumCount = $enumBase; # used so we don't count spaces, but still go through the whole array + for ($i = 0; $i <= $#$items; $i++) + { + # print previous item's comma and comment + # if it has a name, then we print out the enum name, else we just print the comment + my ($name, $comment) = &$convertFunc($$items[$i]); + + if ($name ne "") + { + printf FILE "\t%-20s\t%s\n", "$name = $enumCount" . ($i == $lastEnum ? "" : ","), $comment; + $enumCount++; + } + elsif ($comment eq "") + {printf FILE "\n";} + else + {printf FILE "\t%-20s\t%s\n", "", $comment;} + } + print FILE "};\n"; + close FILE; + + return $lastName; +} + +sub getResult +{ + my ($expression) = @_; + + #print STDERR "getResult: $expression\n"; + $_ = $expression; + if (s/(.*)?->(.*)/$1 $2/) + { + #print STDERR "getResult -- lhs -- : $1\n"; + #print STDERR "getResult -- rhs -- : $2\n"; + return $2; + } +} + +sub getArgs +{ + my ($expression) = @_; + my @returnVal; + #print STDERR "return val is $#returnVal\n"; + + $_ = $expression; + if (s/(.*)?->(.*)//) + { + $lhs = $1; + #print STDERR "$lhs XXXX $2\n"; + $_ = $lhs; + + while (s/\b([A-Za-z\(\)]+)//) + { + #print STDERR "$1 foo \n"; + $returnVal[++$#returnVal] = $1; + } + } + + #print STDERR "return val is $#returnVal\n"; + return @returnVal; +} + + +# +# Given a list of strings, return the length of the longest one. +# +sub maxStringLength +{ + my $max = 0; + foreach (@_) + {$max = length if $max < length;} + return $max; +} + + +# +# Ensure that the usage string has the proper format. +# Return the outputs and inputs strings. +# +sub verifyUsage +{ + my ($usage) = @_; + return ("", "") if $usage eq ""; + my $flags = 0; + die "Bad usage string: $usage\n" unless $usage =~ /^([^:]*):([^:]*)$/; + my ($outputs, $inputs) = ($1, $2); + #print STDERR "'$usage' -> '$outputs', '$inputs'\n"; + die "Bad usage string: $usage\n" unless + $outputs =~ /^E?(|[Z$shortArgs]|[$argOrigins][$argKinds])$/o and + $inputs ne "*" and $inputs =~ /^(Z|([$argOrigins][$argKinds\@]|[$shortArgs])*\*?)$/o; + return ($outputs, $inputs); +} + + +# +# Decode a single argument, possibly with a wildcard. +# +# Return four values: +# the argument's origin, +# the argument's valueKind, and +# true if the valueKind is a wildcard (either '@' or '_'). +# +sub decodeArg +{ + my ($arg) = @_; + my $origin = $shortOrigin; + my $kind = $voidKind; + my $wildcard = 0; + if (defined($shortArgs{$arg})) { + $kind = $shortArgs{$arg}; + } elsif ($arg =~ /^([$argOrigins])([$argKinds])$/) { + $origin = $argOrigins{$1}; + $kind = $argKinds{$2}; + } elsif ($arg =~ /^([$argOrigins])[\@_]$/) { + $origin = $argOrigins{$1}; + $wildcard = 1; + } else { + die "Internal error\n"; + } + return ($origin, $kind, $wildcard); +} + + +# +# Convert an inputs string returned from verifyUsage into a string that contains the +# input constraints only and is appropriate as a C++ identifier name. +# Wildcard '@' symbols are converted into '_' symbols. +# +# Return two values: +# the constraint string, +# true if the last input is repeated. +# +sub inputsToConstraintString +{ + my ($inputs) = @_; + $inputs = "" if $inputs eq "Z"; + die "Internal error\n" unless $inputs =~ /^([^\*]*)(\*?)$/; + my $constraints = $1; + my $repeat = $2 ne ""; + $constraints =~ tr/\@/_/; + return ($constraints, $repeat); +} + + +# +# Convert a constraint string returned from inputsToConstraintString into an array +# of single-argument strings and return that array. +# +sub decodeConstraintString +{ + my ($constraints) = @_; + my @args = (); + while ($constraints ne "") { + die "Internal error\n" unless $constraints =~ /^([$argOrigins][$argKinds\_]|[$shortArgs])(.*)$/o; + push @args, $1; + $constraints = $2; + }; + return @args; +} + + +# +# Convert an outputs string returned from verifyUsage into a ValueKind constant. +# Null outputs get vkVoid. +# +sub outputsToKind +{ + my ($outputs) = @_; + if ($outputs =~ /([$shortArgs]|[$argOrigins][$argKinds])/) { + my ($origin, $kind, $wildcard) = decodeArg($1); + die "Bad output: $outputs\n" if $wildcard || ($origin ne $shortOrigin); + return $kind; + } else { + return $voidKind; + } +} + + +# +# Convert a usage string (without quotes) to a hexadecimal string representing the desired flags value +# +sub usageToFlags +{ + my ($usage) = @_; + my $flags = 0; + $flags |= 1<<$dnIsReal if $usage ne ""; + $flags |= 1<<$dnCanRaiseException | 1<<$dnIsRoot if $usage =~ /E/; + $flags |= 1<<$dnIsRoot if $usage =~ /Z/; + return sprintf "0x%.4X", $flags; +} + + +# +# in +# arrayName: name of this array +# namesName: name of array of enum names +# fileName: file name which to append this enum +# names: list of names +# +# out +# the file $fileName with the appended definitions +# +sub outputNodeTemplates +{ + my ($fileName, $primInfos) = @_; + my $i; + my $str; + my $lastEnum; + my %constraintStrings; + + # find out where to place the comma + for ($i = $#$primInfos; $i >= 0; $i--) + { + if ($primInfos->[$i][$nameIndex] ne "") + { + $lastEnum = $i; + last; + } + } + + open FILE, ">>$fileName" or die "Couldn't open $fileName: $!\n"; + + outputGeneratedHeader(\*FILE, $fileName); + print FILE "#include \"Primitives.h\"\n\n"; + print FILE @headerLines; + + print FILE "\nconst DataNode::Template DataNode::templates[nPrimitiveOperations] = \n"; + print FILE "{\n"; + my $formatString = "\t{%-".($maxPrimitiveNameLength+2)."s". + "%-".($maxCategoryNameLength+2)."s". + "%-".($maxValueKindNameLength+2)."s". + "%-8s\t%s\n"; + my $commentFormatString = "\t%-".(1 + $maxPrimitiveNameLength+2 + $maxCategoryNameLength+2 + $maxValueKindNameLength+2 + 8)."s\t%s\n"; + for ($i = 0; $i <= $#$primInfos; $i++) + { + my ($name, $category, $usage, $comment) = + ($primInfos->[$i][$nameIndex], $primInfos->[$i][$categoryIndex], $primInfos->[$i][$usageIndex], $primInfos->[$i][$commentIndex]); + + # If it has a name, then we print out the template, else we just print the comment. + if ($name ne "") { + my ($outputs, $inputs) = verifyUsage($usage); + printf FILE $formatString, + "$name,", + "$category,", + outputsToKind($outputs).",", + usageToFlags($usage)."}".($i == $lastEnum ? "" : ","), + $comment; + my ($constraintString, $repeat) = inputsToConstraintString($inputs); + $constraintStrings{$constraintString} = 1; + } elsif ($comment eq "") + {printf FILE "\n";} + else + {printf FILE $commentFormatString, "", $comment;} + } + print FILE "};\n\n\n"; + + print FILE "#ifdef DEBUG\n"; + # Print definitions for all of the constraint strings, printing each unique one only once. + my @constraintStrings = sort keys %constraintStrings; + my $maxConstraintNameLength = length("constraint") + maxStringLength(@constraintStrings); + foreach $str (@constraintStrings) { + if ($str ne "") { + my @constraints = decodeConstraintString($str); + printf FILE "static const DataNode::InputConstraint %-".($maxConstraintNameLength+3)."s= {", + "constraint$str\[]"; + my @constraint; + while (defined($constraint = shift @constraints)) { + my ($origin, $kind, $wildcard) = decodeArg($constraint); + printf FILE "{%-".($maxValueKindNameLength+2)."s", "$kind,"; + print FILE "DataNode::"; + if (@constraints) + {printf FILE "%-".($maxArgOriginNameLength+3)."s", "$origin},";} + else + {print FILE "$origin}";} + } + print FILE "};\n"; + } + } + print FILE "\n\n"; + + print FILE "const DataNode::InputConstraintPattern DataNode::inputConstraintPatterns[nPrimitiveOperations] = \n"; + print FILE "{\n"; + $formatString = "\t{%-".($maxConstraintNameLength+2)."s%d, %-7s // %-${maxPrimitiveNameLength}s\t%s\n"; + $commentFormatString = "\t%-".(1 + $maxConstraintNameLength+2 + 16 + $maxPrimitiveNameLength)."s\t%s\n"; + for ($i = 0; $i <= $#$primInfos; $i++) + { + my ($name, $usage, $comment) = + ($primInfos->[$i][$nameIndex], $primInfos->[$i][$usageIndex], $primInfos->[$i][$commentIndex]); + + # If it has a name, then we print out the input pattern, else we just print the comment. + if ($name ne "") { + my ($outputs, $inputs) = verifyUsage($usage); + my ($constraintString, $repeat) = inputsToConstraintString($inputs); + printf FILE $formatString, + ($constraintString eq "" ? "0" : "constraint$constraintString").",", + scalar decodeConstraintString($constraintString), + ($repeat ? "true" : "false")."}".($i == $lastEnum ? "" : ","), + $name, $comment; + $constraintStrings{$constraintString} = 1; + } elsif ($comment eq "") + {printf FILE "\n";} + else + {printf FILE $commentFormatString, "", $comment;} + } + print FILE "};\n#endif\n\n\n"; + + print FILE "#ifdef DEBUG_LOG\n"; + print FILE "static const char primitiveOperationNames[nPrimitiveOperations][16] = \n"; + print FILE "{\n"; + for ($i = 0; $i <= $#$primInfos; $i++) + { + my $name = $primInfos->[$i][$nameIndex]; + + # If it has a name, then we print out the name. + if ($name ne "") + { + $nameStr = $name; + $nameStr = $1 if $name =~ /^[pc]o(\w+)$/; + printf FILE "\t%-".($maxPrimitiveNameLength+1)."s\t// %s\n", + "\"$nameStr\"" . ($i == $lastEnum ? "" : ","), $name; + } + } + print FILE "};\n#endif\n\n"; + + close FILE; +} diff --git a/ef/Tools/PerlAssemblyConverter/assembly.pl b/ef/Tools/PerlAssemblyConverter/assembly.pl new file mode 100644 index 000000000000..10b435017537 --- /dev/null +++ b/ef/Tools/PerlAssemblyConverter/assembly.pl @@ -0,0 +1,449 @@ +#/* +# Christian Bennett +# +# Purpose: +# For use in a Make system when generating the at&t assembly syntax file (for gnu software) from some the +# Intel standard assembly syntax file. +# +# +# Expandability: +# This program is ready to be hooked into a make system. The design for this script +# is based on the assumption there is just an assembly file with no distinct header or +# footer information. This was not designed to parse through a C++ file and find the inlined +# assembly. Quite simply it takes an Intel asm instruction and outputs the AT&T version. If +# there is a line it does not recognize, it outputs it as is. +# So if there is distinct headers and footers per compiler you may have to modify the linux +# output slightly, or modify this code slightly. +# +# Use: +# The IO in this file is done through standard in and standard out. READ: cat the input +# and redirect the output to a file. Or do whatever means necessary. So for testing I did something +# like: cat sampleInput.asm perl assembly.pl > linuxTranslation.pl +# +# +# KEY: in comments: ws = whitespcae, pws = possible white space (read: there may be ws here). + + +# Here is a hash for identifying registers. Querying the hash will return TRUE if, the query contains a +# register. Else will return null. If there are additional registers that may be used, add them in a +# similar fasion. +#*/ + +%registers = ( + "eax" => 1, + "ebx" => 1, + "ecx" => 1, + "edx" => 1, + "esi" => 1, + "edi" => 1, + "eip" => 1, + "esp" => 1, + "ebp" => 1, + "efl" => 1, + ); + + + +LINE: while ($line = <>) { + + if($line eq "\n"){ #goto next line if endline + print "\n"; + next LINE; + } + + + +#/*----------------Interpretation of instructions-------------- +### The Different Cases Handled +# +# Each case takes a string. It then parses the string and grabs arguments and parameters. +# It then formats the instruction and args for AT&T assembly syntax. +# +# Formating preserves c++ style comments. +# +# 1) instruction = insn reg, int +# This case grabs the three words, and makes sure the second is a reg, and the third a integer +# +# 2) insn reg, reg2 +# This case grabs the three words, and check if the 2nd and 3rd parameters are valid registers. +# +# 3) insn reg, [reg + offet] (where offset is an integer) +# This case grabs 5 items: inst, reg, reg, sign, offset. +# +# 4) insn int +# This case grabs the instruction, then grabs an int. +# +# 5) insn location (e.g. call FOO) +# insn reg +# +# 6) inverse of case 3: insn [reg + offset], reg +# +# 7) insn reg, [reg2 + FOO * 4] //note FOO may be a register. +# +# 8) insn [reg + FOO*4], reg2 +# +# 9) insn reg, [reg2] +# +# 10) insn [reg], reg2 +# +# 11) insn reg, [reg2 + reg3] +# +# 12) insn [reg + reg2], reg3 +# +# 13) insn reg, [reg2 + reg3 + offset] +# +# 14) insn [reg + reg2 + offset], reg4 +# +# 15) insn reg, [reg2 + reg3*offset + someintOffset] +# +# 16) insn [reg1 + reg2*offset + someintOffset], reg3 +# +# +# +#*/ + + if($line =~ m@(^//.*)@){ #if a line is a comment, + print $1, "\n"; #send to the output stream. + next LINE; + } + + +#/* CASE 1 -- insn reg, int --> insnl %reg, int +# This statment is a regexp looking for: a word, whitespace, alphaNum chars, possible space +# an integer (digit), possible whitespace, possible comment. +# It then to makes sure the second word it absorbed was a register by using the hash feature. +# If entered, 'next' gotos the next iteration of the while loop. +#*/ + + if($line =~ m@(\w+)\s+([a-zA-Z]+),\s*(\d+)\s*(/*.*)@ && $registers{$2}){ + print $1, "l %", $2, ", ", $3; + print " ", $4, "\n"; + next LINE; + } + + + +#/* CASE 2 -- insn reg, reg2 --> insnl %reg2, %reg +# This statment is a regexp looking for: a word, whitespace, a word, possible space +# alphanum chars, possible whitespace, possible comments. +# It then to makes sure the second and third words absorbed were registers by +# using the hash feature. +# If entered, 'next' gotos the next iteration of the while loop. +#*/ + + + if(($line =~ m@(\w+)\s+(\w+),\s*([a-zA-Z]+)\s*(/*.*)@) + && $registers{$2} && $registers{$3}){ + print $1, "l %", $3, ", %", $2; + print " ", $4, "\n"; + next LINE; + } + + + +#/* CASE 3-- insn reg, [reg2+offset] --> insnl offset(%reg2), %reg +# This statment is a regexp looking for: a word, whitespace, alphanum chars, possible space +# [ char, alphanum chars, possible whitespace, + or -, possible whitespace, ] char, +# possible comments. It then to makes sure the second and third words absorbed were +# actually registers by using the hash feature. +# If entered, 'next' gotos the next iteration of the while loop. +#*/ + + + if($line =~ m@(\w+)\s+([a-zA-Z]+),\s*\[([a-zA-Z]+)\s*([\+\-])\s*(\d+)\s*]\s*(/*.*)@ + && $registers{$2} && $registers{$3}){ + + if($4 eq "\+"){ + print $1, "l ", $5, "(%", $3, "), %", $2; #if + + } + else{ + print $1, "l -", $5, "(%", $3, "), %", $2; #if - + } + + print " ", $6, "\n"; + next LINE; + } + +#/* CASE 4 -- insn int --> insnl $int, or ret int +# This statment is a regexp looking for: a word, whitespace, digits, possible space +# possible comments. It then to makes sure the second word absorbed was +# actually a register by using the hash feature. +# Also makes sure there are no '['s in the string. +# If entered, 'next' gotos the next iteration of the while loop. +#*/ + + if($line =~ m@(\w+)\s+(\d+)\s*(/*.*)@ && !$registers{$2} && !($line =~ /\[/)){ + $temp = $1; + if($1 eq "ret"){ + print $temp, " \$", $2; + } + else{ + print $temp, "l \$", $2; + } + print " ", $3, "\n"; + next LINE; + } + + +#/* CASE 5 insn LOCATION or insn reg --> either insn *%reg or insnl %LOCATION +# This statment is a regexp looking for: a word, whitespace, alphanum chars, possible space +# possible comments. It tests to exclude strings with '[' in them. +# If entered, 'next' gotos the next iteration of the while loop. +#*/ + + if($line =~ m@(\w+)\s+([a-zA-Z]+)\s*(/*.*)@ && !($line =~ /\[/)){ + $temp = $1; + $temp2 = $2; + + if((($registers{$2}) && (($temp eq "call") || ($temp eq "jmp")))){ + print $temp, " *\%", $temp2; + } + elsif($registers{$2}){ + print $temp, "l \%", $temp2; + + } + else{ + print $, " ", $2; + } + + print " ", $3, "\n"; + next LINE; + } + +#/* CASE 6 insn [reg + offset], reg2 -- > insnl %reg2, offset(%reg) +# This statment is a regexp looking for: a word, whitespace, alphanum chars, possible space +# + or - char, possible whitespace, possible whitespace, digits, ws,], ws, alphanum chars, ws, +# possible comments. It then to makes sure the second and fifth words absorbed were +# actually registers by using the hash feature. +# If entered, 'next' gotos the next iteration of the while loop. +#*/ + + if($line =~ m@(\w+)\s+\[([a-zA-Z]+)\s*([+-])\s*(\d+)\s*\]\s*,\s*([a-zA-Z]+)\s*(/*.*)@ && + $registers{$2} && $registers{$5}){ + + + if($3 eq "\+"){ + print $1, "l ", $5, ", ", $4, "(", $2, ")"; #if + + } + else{ + print $1, "l ", $5, ", -", $4, "(", $2, ")"; #if - + } + + print " ", $6, "\n"; + next LINE; + } + + +# CASE 7 : insn reg, [reg2 + FOO*int] --> insnl %reg2(FOO*int), %reg +# E.G. : add eax, [ecx + FOO*4] --> addl %ecx(FOO*4), %eax + + if($line =~ m@(\w+)\s+([a-zA-Z]+),\s*\[([a-zA-Z]+)\s*([\+\-])\s*([a-zA-Z]+)\*(\d+)\s*]\s*(/*.*)@ + && $registers{$2} && $registers{$3}){ + + if($registers{$5}){ #if FOO is a register + if($4 eq "\+"){ + print $1, "l %", $3, "(%", $5, "*", $6, "), %", $2; #if + + } + else{ + print $1, "l %", $3, "(-%", $5, "*", $6, "), %", $2; #if - + } + } + else{ + if($4 eq "\+"){ + print $1, "l %", $3, "(", $5, "*", $6, "), %", $2; + } + else{ + print $1, "l %", $3, "(-", $5, "*", $6, "), %", $2; + } + } + print " ", $7, "\n"; + next LINE; + } + + + +# case 8: insn [reg1 + FOO*int], reg2 --> insnl %reg2, %reg1(%FOO*int) if foo is a reg +# --> insnl %reg2, %reg1(FOO*int) if foo is not a register +# This code first checks to see if foo is a register. If foo is a register, it switches on whether +# or not there was a plus or minus symbol used. The rest is formatting to make the case mentioned above +# have the right output. +# + if($line =~ m@(\w+)\s+\[([a-zA-Z]+)\s*([+-])\s*(\w+)\s*\*\s*(\d+)\s*\]\s*,\s*(\w+.*)\s*(/*.*)@ + && $registers{$2} && $registers{$5}){ + + if($registers{$5}){ #if FOO is a register + if($4 eq "\+"){ + print $1, "l %", $6, ", %", $2, "(%", $4, "*", $5, ")"; #if + + } + else{ + print $1, "l %", $6, ", %", $2, "(-%", $4, "*", $5, ")"; #if - + } + } + else{ #if FOO is not a register + if($4 eq "\+"){ + print $1, "l %", $6, ", %", $2, "(", $4, "*", $5, ")"; + } + else{ + print $1, "l %", $6, ", %", $2, "(-", $4, "*", $5, ")"; + } + } + print " ", $7, "\n"; + next LINE; + } + +# case 9: insn reg, [reg2] --> insn (%reg2), %reg +# This code looks for and write the input and output described above. +# The only error checking is the identical matching of the input (with ws as a variant), and +# to make sure the args are valid registers. +# The rest is formatting to make the case mentioned above have the right output. + + if($line =~ m@(\w+)\s+(\w+),\s*\[(\w+)\]\s*(/*.*)@ && $registers{$2} && $registers{$3}){ + + print $1, "l (%", $3, "), %", $2; + print " ", $4, "\n"; + next LINE; + + } + + +# Case 10: insn [reg], reg2 --> insn %reg2, (%reg) +# Just the reverse of the previous case. See case 9. + if($line =~ m@(\w+)\s+\[(\w+)\],\s*(\w+)\s*(/*.*)@ && $registers{$2} && $registers{$3}){ #*/ + + print $1, "l %", $3, ", (%", $2, ")"; + print " ", $4, "\n"; + next LINE; + } + + + +# case 11: insn reg, [reg2 + reg3] --> insnl (%reg2, %reg3), %reg +# +# This looks for the input matching the description above. If found it then formats it match the output described. +# Error checking is in the formatting and making sure appropriate args are valid registers. +# If entered, goto LINE to iterate through the next line. + + + if($line =~ m@(\w+)\s+(\w+),\s*\[\s*([a-zA-Z]+)\s*([/+/-])\s*([a-zA-Z]+)\s*\]\s*(/*.*)@ && $registers{$2} #*/ + && $registers{$3} && $registers{$5}){ + + if($4 eq "\+"){ + print $1, "l (%", $3, ",%", $5, "), ", $2; + } + else{ + # does subtraction work?? + } + + print " ", $6, "\n"; + next LINE; + } + + +# case 12: insn [reg + reg2], reg3 (reverse of case 11) --> insnl %reg3, (%reg, %reg2) +# See case 11 for details. + + if($line =~ m@(\w+)\s+\[\s*([a-zA-Z]+)\s*([+-])\s*([a-zA-Z]+)\s*\],\s*([a-zA-Z]+)\s*(/*.*)@){ + + if($3 eq "\+"){ + + print $1, "l %", $5, ", (%", $2, ",%", $4, ")"; + } + print " ", $6, "\n"; + next LINE; + } + +# case 13: insn reg, [reg2 + reg3 + int] --> insnl (%reg2, %reg3, int), %reg +# The following code takes the above +# +# + + if($line =~ m@(\w+)\s+(\w+),\s*\[\s*([a-zA-Z]+)\s*([/+/-])\s*([a-zA-Z]+)\s*\+\s*(\d+)\s*\]\s*(/*.*)@ #*/ + && $registers{$2} && $registers{$3} && $registers{$5}){ + + if($4 eq "\+"){ + print $1, "l (%", $3, ",%", $5, ",", $6, "), ", $2; + } + else{ + # does subtraction work?? + } + + print " ", $7, "\n"; + next LINE; + } + + +# case 14: insn [reg + reg2 + int], reg3 (reverse of case 13) --> insnl %reg3, (%reg, %reg2, int) +# +# The regular expression parses for (in this order): word, ws, '[', pws, Chars, pws, + or -, +# pws, chars, pws, +, pws, int, pws, ']', ',',pws, chars, pws, possible comments +# +# Grabs and puts items in temp vars $1-$7 respectively: insn, reg, sign, reg, int, reg, comment +# + + if($line =~ m@(\w+)\s+\[\s*([a-zA-Z]+)\s*([+-])\s*([a-zA-Z]+)\s*\+\s*(\d*)\s*\],\s*([a-zA-Z]+)\s*(/*.*)@){ + + if($3 eq "\+"){ + + print $1, "l %", $6, ", (%", $2, ",%", $4, ",", $5, ")"; + } + print " ", $7, "\n"; + next LINE; + } + + +# case 15: insn reg, [reg2 + reg3*4 + int] --> insn (%reg2,%reg3*4,int), reg +# +# The regular expression parses for (in this order): word, ws, word, ',', pws, '[' +# pws, chars, pws, + or -, pws, chars, pws, '*', int, pws, +, pws, int, pws, ']', pws, +# possible comments. +# +# Grabs and puts items temp vars $1-$8 respectively: insn, reg, reg2, reg3, int, + or -, int, comment +# + + if($line =~ m@(\w+)\s+(\w+),\s*\[\s*([a-zA-Z]+)\s*([/+/-])\s*([a-zA-Z]+)\s*\*\s*(\d+)\s*\+\s*(\d+)\s*\]\s*(/*.*)@ + && $registers{$2} && $registers{$3} && $registers{$5}){ + + + if($4 eq "\+"){ + print $1, "l ", $6, "(%", $3, ",%", $5, ",", $7, "), %", $2; + } + else{ + # does subtraction work?? + } + + print " ", $8, "\n"; + next LINE; + } + + +# case 16: insn [reg + reg2*4 + int], reg3 (reverse of case 12) --> insn %reg3, (%reg,%reg2*4,int) +# The regular expression parses for (in this order): word, ws, '[', possible ws, chars, poss ws, +# + or -, possible ws, chars, pws, '*', int, pws, '+', pws, int, pws, ']', pws, chars, pws +# then looks for possible comments. +# +# Grabs and puts items temp vars $1-$8 respectively: insn, reg, reg2, int, + or -, int, reg3, comment +# +# + + if($line =~ m@(\w+)\s+\[\s*([a-zA-Z]+)\s*([+-])\s*([a-zA-Z]+)\s*\*\s*(\d*)\s*\+\s*(\d*)\s*\],\s*([a-zA-Z]+)\s*(/*.*)@ + && $registers{$2} && $registers{$4} && $registers{$7}){ + + + if($3 eq "\+"){ + + print $1, "l %", $7, ", ", $5, "(%", $2, ",%", $4, ",", $6, ")"; + } + print " ", $8, "\n"; + next LINE; + + } + + +# ELSE just output the line as is... + + if($line =~ /\s*(.+)/){ + print $1, "\n"; + } +} + + diff --git a/ef/Tools/PrimitiveOperations/MakePrimOp.pl b/ef/Tools/PrimitiveOperations/MakePrimOp.pl new file mode 100644 index 000000000000..ff2575a2abc9 --- /dev/null +++ b/ef/Tools/PrimitiveOperations/MakePrimOp.pl @@ -0,0 +1,38 @@ +#!/usr/local/bin/perl +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +# +# MakePrimOp.pl +# +# Scott M. Silver +# +# Parses PrimitiveOperations file. +# + +use PrimOp; + +# Usage: +# perl PrepareBurg.pl +# input primitive operations description +# output +# output + +($PrimitiveOperationsSourceFN, $PrimitiveOperationsEnumFN, $DataNodeTemplateFN) = @ARGV; + +PrimOp::readPrimitiveOperations($PrimitiveOperationsSourceFN); +PrimOp::createPrimitiveOperationsCpp($DataNodeTemplateFN); +PrimOp::createPrimitiveOperationsH($PrimitiveOperationsEnumFN); diff --git a/ef/Tools/PrimitiveOperations/PrimOp.pm b/ef/Tools/PrimitiveOperations/PrimOp.pm new file mode 100644 index 000000000000..560444e62dce --- /dev/null +++ b/ef/Tools/PrimitiveOperations/PrimOp.pm @@ -0,0 +1,513 @@ +#!/usr/local/bin/perl +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +# PrimOp.pl +# +# Waldemar Horwat +# Scott M. Silver +# +# Parses PrimitiveOperations file. +# + +package PrimOp; + +# Fields of a $gPrimitiveInfo structure +$nameIndex = 0; +$categoryIndex = 1; +$usageIndex = 2; +$commentIndex = 3; + +# DataNode flag numbers +$dnIsReal = 0; +$dnCanRaiseException = 1; +$dnIsRoot = 2; + +# Special kinds +$voidKind = "vkVoid"; +$shortOrigin = "aoVariable"; + +sub readPrimitiveOperations { + my ($fileName) = @_; + + # read PrimitiveOperation infos + open PRIMOPS, "$fileName" or die "Couldn't open $fileName: $!\n"; + $readingStage = 0; + while () + { + if ($readingStage == 0) { + if (/^\s*((?:\/\/.*)?\n)$/) { + push @headerLines,$1; + } else { + $readingStage = 1; + } + } + if ($readingStage == 1) { + if (/^\s*ARG-ORIGIN\s+'(.)'\s+(\w+)\s*;\s*\n$/) { + $argOrigins{$1} = $2; + } elsif (/^\s*ARG-KIND\s+'(.)'\s+(\w+)\s*;\s*\n$/) { + $argKinds{$1} = $2; + } elsif (/^\s*SHORT-ARG\s+'(.)'\s+(\w+)\s*;\s*\n$/) { + $shortArgs{$1} = $2; + } elsif (!/^\s*(\/\/.*)?\n$/) { + $readingStage = 2; + } + } + if ($readingStage == 2) { + die "Bad line: $_\n" unless m/^(?:\s*{(\w+),\s*(\w+),\s*"([^"\s]*)"})?(?:\s*(\/\/.*))?\n?$/; + # print STDERR "--->$1***$2***$3***$4\n"; + #($name, $category, $usage, $comment) = ($1, $2, $3, $4); + push @gPrimitiveInfo, [$1, $2, $3, $4]; + } + } + close PRIMOPS; + + $argOrigins = ""; + $argKinds = ""; + $shortArgs = ""; + foreach (keys %argOrigins) {$argOrigins .= $_;} + foreach (keys %argKinds) {$argKinds .= $_;} + foreach (keys %shortArgs) {$shortArgs .= $_;} + #print STDERR "argOrigins = \"$argOrigins\"\n"; + #print STDERR "argKinds = \"$argKinds\"\n"; + #print STDERR "shortArgs = \"$shortArgs\"\n"; + + $maxArgOriginNameLength = maxStringLength(values %argOrigins); + $maxValueKindNameLength = maxStringLength(values %argKinds, values %shortArgs); + $maxPrimitiveNameLength = maxStringLength(map $_->[$nameIndex], @gPrimitiveInfo); + $maxCategoryNameLength = maxStringLength(map $_->[$categoryIndex], @gPrimitiveInfo); +} + +sub createPrimitiveOperationsCpp { + my ($PrimitiveOperationsCpp) = @_; + + unlink ($PrimitiveOperationsCpp) or break; + outputNodeTemplates($PrimitiveOperationsCpp, \@gPrimitiveInfo); +} + +sub createPrimitiveOperationsH { + my ($PrimitiveOperationsH) = @_; + + unlink ($PrimitiveOperationsH) or break; + $gLastPrimEnumName = outputEnumFromListX("PrimitiveOperation", $PrimitiveOperationsH, 0, \@gPrimitiveInfo, \&primInfoToEnumDescriptor); + open FILE, ">>$PrimitiveOperationsH" or die "Couldn't open $PrimitiveOperationsEnumFN: $!\n"; + print FILE "\nconst nPrimitiveOperations = $gLastPrimEnumName + 1;\n"; + close FILE; +} + + +# primInfoToEnumDescriptor +# +# Convert a primInfo to a ($enumname, $enumcomment) list +sub primInfoToEnumDescriptor { + my ($primInfo) = @_; + return ($$primInfo[$nameIndex], $$primInfo[$commentIndex]); +} + +# primInfoToEnumDescriptor +# +# Convert a namedrule (a string) to a ($enumname, $enumcomment) list +sub ruleNameToEnumDescriptor { + my ($name) = @_; + return ($name, ""); +} + + +# outputGeneratedHeader +# +# Output header of generated file. +sub outputGeneratedHeader +{ + my ($fh, $filename) = @_; + + $_ = $filename; + + if (!(s/.*:([^:]+)\Z/$1/)) { + s/(.*)/$1/; + } + + $filename = $1; + + print $fh "//\n// $filename\n//\n// Generated file\n// DO NOT EDIT\n//\n\n"; +} + + +# outputEnumFromListX +# +# in +# name: name of this enum, will be printed as a comment above +# fileName: file name which to append this enum +# enumBase: value of first enum (usually either 0 or 1) +# items: list of items +# convertFunc: function that transforms an item into a (enumname, enumcomment) list +# +# out +# the file $fileName with the appended enum +# returns the last enum output +# +sub outputEnumFromListX +{ + my ($name, $fileName, $enumBase, $items, $convertFunc) = @_; + my $i; + my $lastEnum; + my $lastName; + + for ($i = $#$items; $i >= 0; $i--) + { + my ($name, $comment) = &$convertFunc($$items[$i]); + if ($name ne "") + { + $lastEnum = $i; + $lastName = $name; + last; + } + } + #($hi, $crap) = &$convertFunc($$items[$lastEnum]); + #print STDERR "----> $lastEnum, $hi <---\n"; + + open FILE, ">>$fileName" or die "Couldn't open $fileName: $!\n"; + + outputGeneratedHeader(\*FILE, $fileName); + print FILE "enum $name\n"; + print FILE "{\n"; + + my $enumCount = $enumBase; # used so we don't count spaces, but still go through the whole array + for ($i = 0; $i <= $#$items; $i++) + { + # print previous item's comma and comment + # if it has a name, then we print out the enum name, else we just print the comment + my ($name, $comment) = &$convertFunc($$items[$i]); + + if ($name ne "") + { + printf FILE "\t%-20s\t%s\n", "$name = $enumCount" . ($i == $lastEnum ? "" : ","), $comment; + $enumCount++; + } + elsif ($comment eq "") + {printf FILE "\n";} + else + {printf FILE "\t%-20s\t%s\n", "", $comment;} + } + print FILE "};\n"; + close FILE; + + return $lastName; +} + +sub getResult +{ + my ($expression) = @_; + + #print STDERR "getResult: $expression\n"; + $_ = $expression; + if (s/(.*)?->(.*)/$1 $2/) + { + #print STDERR "getResult -- lhs -- : $1\n"; + #print STDERR "getResult -- rhs -- : $2\n"; + return $2; + } +} + +sub getArgs +{ + my ($expression) = @_; + my @returnVal; + #print STDERR "return val is $#returnVal\n"; + + $_ = $expression; + if (s/(.*)?->(.*)//) + { + $lhs = $1; + #print STDERR "$lhs XXXX $2\n"; + $_ = $lhs; + + while (s/\b([A-Za-z\(\)]+)//) + { + #print STDERR "$1 foo \n"; + $returnVal[++$#returnVal] = $1; + } + } + + #print STDERR "return val is $#returnVal\n"; + return @returnVal; +} + + +# +# Given a list of strings, return the length of the longest one. +# +sub maxStringLength +{ + my $max = 0; + foreach (@_) + {$max = length if $max < length;} + return $max; +} + + +# +# Ensure that the usage string has the proper format. +# Return the outputs and inputs strings. +# +sub verifyUsage +{ + my ($usage) = @_; + return ("", "") if $usage eq ""; + my $flags = 0; + die "Bad usage string: $usage\n" unless $usage =~ /^([^:]*):([^:]*)$/; + my ($outputs, $inputs) = ($1, $2); + #print STDERR "'$usage' -> '$outputs', '$inputs'\n"; + die "Bad usage string: $usage\n" unless + $outputs =~ /^E?(|[Z$shortArgs]|[$argOrigins][$argKinds])$/o and + $inputs ne "*" and $inputs =~ /^(Z|([$argOrigins][$argKinds\@]|[$shortArgs])*\*?)$/o; + return ($outputs, $inputs); +} + + +# +# Decode a single argument, possibly with a wildcard. +# +# Return four values: +# the argument's origin, +# the argument's valueKind, and +# true if the valueKind is a wildcard (either '@' or '_'). +# +sub decodeArg +{ + my ($arg) = @_; + my $origin = $shortOrigin; + my $kind = $voidKind; + my $wildcard = 0; + if (defined($shortArgs{$arg})) { + $kind = $shortArgs{$arg}; + } elsif ($arg =~ /^([$argOrigins])([$argKinds])$/) { + $origin = $argOrigins{$1}; + $kind = $argKinds{$2}; + } elsif ($arg =~ /^([$argOrigins])[\@_]$/) { + $origin = $argOrigins{$1}; + $wildcard = 1; + } else { + die "Internal error\n"; + } + return ($origin, $kind, $wildcard); +} + + +# +# Convert an inputs string returned from verifyUsage into a string that contains the +# input constraints only and is appropriate as a C++ identifier name. +# Wildcard '@' symbols are converted into '_' symbols. +# +# Return two values: +# the constraint string, +# true if the last input is repeated. +# +sub inputsToConstraintString +{ + my ($inputs) = @_; + $inputs = "" if $inputs eq "Z"; + die "Internal error\n" unless $inputs =~ /^([^\*]*)(\*?)$/; + my $constraints = $1; + my $repeat = $2 ne ""; + $constraints =~ tr/\@/_/; + return ($constraints, $repeat); +} + + +# +# Convert a constraint string returned from inputsToConstraintString into an array +# of single-argument strings and return that array. +# +sub decodeConstraintString +{ + my ($constraints) = @_; + my @args = (); + while ($constraints ne "") { + die "Internal error\n" unless $constraints =~ /^([$argOrigins][$argKinds\_]|[$shortArgs])(.*)$/o; + push @args, $1; + $constraints = $2; + }; + return @args; +} + + +# +# Convert an outputs string returned from verifyUsage into a ValueKind constant. +# Null outputs get vkVoid. +# +sub outputsToKind +{ + my ($outputs) = @_; + if ($outputs =~ /([$shortArgs]|[$argOrigins][$argKinds])/) { + my ($origin, $kind, $wildcard) = decodeArg($1); + die "Bad output: $outputs\n" if $wildcard || ($origin ne $shortOrigin); + return $kind; + } else { + return $voidKind; + } +} + + +# +# Convert a usage string (without quotes) to a hexadecimal string representing the desired flags value +# +sub usageToFlags +{ + my ($usage) = @_; + my $flags = 0; + $flags |= 1<<$dnIsReal if $usage ne ""; + $flags |= 1<<$dnCanRaiseException | 1<<$dnIsRoot if $usage =~ /E/; + $flags |= 1<<$dnIsRoot if $usage =~ /Z/; + return sprintf "0x%.4X", $flags; +} + + +# +# in +# arrayName: name of this array +# namesName: name of array of enum names +# fileName: file name which to append this enum +# names: list of names +# +# out +# the file $fileName with the appended definitions +# +sub outputNodeTemplates +{ + my ($fileName, $primInfos) = @_; + my $i; + my $str; + my $lastEnum; + my %constraintStrings; + + # find out where to place the comma + for ($i = $#$primInfos; $i >= 0; $i--) + { + if ($primInfos->[$i][$nameIndex] ne "") + { + $lastEnum = $i; + last; + } + } + + open FILE, ">>$fileName" or die "Couldn't open $fileName: $!\n"; + + outputGeneratedHeader(\*FILE, $fileName); + print FILE "#include \"Primitives.h\"\n\n"; + print FILE @headerLines; + + print FILE "\nconst DataNode::Template DataNode::templates[nPrimitiveOperations] = \n"; + print FILE "{\n"; + my $formatString = "\t{%-".($maxPrimitiveNameLength+2)."s". + "%-".($maxCategoryNameLength+2)."s". + "%-".($maxValueKindNameLength+2)."s". + "%-8s\t%s\n"; + my $commentFormatString = "\t%-".(1 + $maxPrimitiveNameLength+2 + $maxCategoryNameLength+2 + $maxValueKindNameLength+2 + 8)."s\t%s\n"; + for ($i = 0; $i <= $#$primInfos; $i++) + { + my ($name, $category, $usage, $comment) = + ($primInfos->[$i][$nameIndex], $primInfos->[$i][$categoryIndex], $primInfos->[$i][$usageIndex], $primInfos->[$i][$commentIndex]); + + # If it has a name, then we print out the template, else we just print the comment. + if ($name ne "") { + my ($outputs, $inputs) = verifyUsage($usage); + printf FILE $formatString, + "$name,", + "$category,", + outputsToKind($outputs).",", + usageToFlags($usage)."}".($i == $lastEnum ? "" : ","), + $comment; + my ($constraintString, $repeat) = inputsToConstraintString($inputs); + $constraintStrings{$constraintString} = 1; + } elsif ($comment eq "") + {printf FILE "\n";} + else + {printf FILE $commentFormatString, "", $comment;} + } + print FILE "};\n\n\n"; + + print FILE "#ifdef DEBUG\n"; + # Print definitions for all of the constraint strings, printing each unique one only once. + my @constraintStrings = sort keys %constraintStrings; + my $maxConstraintNameLength = length("constraint") + maxStringLength(@constraintStrings); + foreach $str (@constraintStrings) { + if ($str ne "") { + my @constraints = decodeConstraintString($str); + printf FILE "static const DataNode::InputConstraint %-".($maxConstraintNameLength+3)."s= {", + "constraint$str\[]"; + my @constraint; + while (defined($constraint = shift @constraints)) { + my ($origin, $kind, $wildcard) = decodeArg($constraint); + printf FILE "{%-".($maxValueKindNameLength+2)."s", "$kind,"; + print FILE "DataNode::"; + if (@constraints) + {printf FILE "%-".($maxArgOriginNameLength+3)."s", "$origin},";} + else + {print FILE "$origin}";} + } + print FILE "};\n"; + } + } + print FILE "\n\n"; + + print FILE "const DataNode::InputConstraintPattern DataNode::inputConstraintPatterns[nPrimitiveOperations] = \n"; + print FILE "{\n"; + $formatString = "\t{%-".($maxConstraintNameLength+2)."s%d, %-7s // %-${maxPrimitiveNameLength}s\t%s\n"; + $commentFormatString = "\t%-".(1 + $maxConstraintNameLength+2 + 16 + $maxPrimitiveNameLength)."s\t%s\n"; + for ($i = 0; $i <= $#$primInfos; $i++) + { + my ($name, $usage, $comment) = + ($primInfos->[$i][$nameIndex], $primInfos->[$i][$usageIndex], $primInfos->[$i][$commentIndex]); + + # If it has a name, then we print out the input pattern, else we just print the comment. + if ($name ne "") { + my ($outputs, $inputs) = verifyUsage($usage); + my ($constraintString, $repeat) = inputsToConstraintString($inputs); + printf FILE $formatString, + ($constraintString eq "" ? "0" : "constraint$constraintString").",", + scalar decodeConstraintString($constraintString), + ($repeat ? "true" : "false")."}".($i == $lastEnum ? "" : ","), + $name, $comment; + $constraintStrings{$constraintString} = 1; + } elsif ($comment eq "") + {printf FILE "\n";} + else + {printf FILE $commentFormatString, "", $comment;} + } + print FILE "};\n#endif\n\n\n"; + + print FILE "#ifdef DEBUG_LOG\n"; + print FILE "static const char primitiveOperationNames[nPrimitiveOperations][16] = \n"; + print FILE "{\n"; + for ($i = 0; $i <= $#$primInfos; $i++) + { + my $name = $primInfos->[$i][$nameIndex]; + + # If it has a name, then we print out the name. + if ($name ne "") + { + $nameStr = $name; + $nameStr = $1 if $name =~ /^[pc]o(\w+)$/; + printf FILE "\t%-".($maxPrimitiveNameLength+1)."s\t// %s\n", + "\"$nameStr\"" . ($i == $lastEnum ? "" : ","), $name; + } + } + print FILE "};\n#endif\n\n"; + + close FILE; +} + +1; diff --git a/ef/Tools/UtilityTest/TreeTest.cpp b/ef/Tools/UtilityTest/TreeTest.cpp new file mode 100644 index 000000000000..f8c9770747f7 --- /dev/null +++ b/ef/Tools/UtilityTest/TreeTest.cpp @@ -0,0 +1,404 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +// +// A test program for the Tree classes +// + +#include +#include "TreeTest.h" +#include "DebugUtils.h" + + +// +// Return a pseudo-random number between 0 and range-1, inclusive. +// This is not a good pseudo-random number generator (it has biases), +// but it will do fine for generating tests. +// range should be relatively small -- less than 1000 or so. +// +Uint32 random(Uint16 range) +{ + static Uint32 seed = 1; + + seed *= 0x10003; + return (seed>>16) % range; +} + + +// ---------------------------------------------------------------------------- +// TreeHarness + + +// +// Initialize the TreeHarness, which contains both a SortedTree and a +// rep value that is a bitmap that is supposed to match the contents of +// the tree. +// +TreeHarness::TreeHarness(): rep(0) +{ + for (Uint32 i = nNodes; i--;) + nodes[i].key.n = i; +} + + +// +// Return a random node number of a node present in the tree or nNodes +// if the tree is empty. +// +Uint32 TreeHarness::randomPresent() const +{ + Uint32 limit = tree.getNNodes(); + if (limit) { + Uint32 i = random(limit); + for (Uint32 j = 0; j != nNodes; j++) + if (present(j)) + if (i) + i--; + else + return j; + trespass("Error in randomPresent"); + } + return nNodes; +} + + +// +// Remove all elements from the tree. +// +void TreeHarness::testClear() +{ + Uint32 n; + while ((n = randomPresent()) != nNodes) + testRemove(n); + assert(rep == 0); +} + + +// +// Test the find method on element n, which may or may not be in the tree. +// +void TreeHarness::testFind(Uint32 n) const +{ + TestNode *node = tree.find(TestKey(n)); + if (present(n)) + assert(node == nodes + n); + else + assert(!node); +} + + +// +// Test the findAfter method on element n, which may or may not be in the tree. +// Return the number of the lowest element in the set that is greater than or +// equal to n, or nNodes if there is no such element. +// +Uint32 TreeHarness::testFindAfter(Uint32 n) const +{ + TestNode *node = tree.findAfter(TestKey(n)); + Uint32 i = n; + while (i != nNodes && !present(i)) + i++; + if (i != nNodes) + assert(node == nodes + i); + else + assert(!node); + return i; +} + + +// +// Test the findBefore method on element n, which may or may not be in the tree. +// Return the number of the greatest element in the set that is less than or +// equal to n, or nNodes if there is no such element. +// +Uint32 TreeHarness::testFindBefore(Uint32 n) const +{ + TestNode *node = tree.findBefore(TestKey(n)); + Uint32 i = n; + while (i != 0 && !present(i)) + i--; + if (present(i)) { + assert(node == nodes + i); + return i; + } else { + assert(!node); + return nNodes; + } +} + + +// +// Test the three-argument find method on element n, which may or may not be +// in the tree. If element n is not in the tree, add it. +// +void TreeHarness::testFindAttach(Uint32 n) +{ + TestNode *where; + bool right; + TestNode *node = tree.find(TestKey(n), where, right); + if (!node) + tree.attach(nodes[n], where, right); + + if (present(n)) + assert(node == nodes + n); + else { + assert(!node); + add(n); + } +} + + +// +// Test the insert method on element n, which is not currently in the tree. +// +void TreeHarness::testInsert(Uint32 n) +{ + assert(!present(n)); + tree.insert(nodes[n]); + add(n); +} + + +// +// Test the insertAfter method on element n, which is not currently in the tree, +// and location where, which is a valid argument to insertAfter for this n. +// If where==nNodes, then insertAfter's where is set to nil. +// +void TreeHarness::testInsertAfter(Uint32 n, Uint32 where) +{ + assert(!present(n) && (where == nNodes || present(where))); + tree.insertAfter(nodes[n], where == nNodes ? 0 : nodes + where); + add(n); +} + + +// +// Test the insertBefore method on element n, which is not currently in the tree, +// and location where, which is a valid argument to insertBefore for this n. +// If where==nNodes, then insertBefore's where is set to nil. +// +void TreeHarness::testInsertBefore(Uint32 n, Uint32 where) +{ + assert(!present(n) && (where == nNodes || present(where))); + tree.insertBefore(nodes[n], where == nNodes ? 0 : nodes + where); + add(n); +} + + +// +// Test the remove method on element n, which is currently in the tree. +// +void TreeHarness::testRemove(Uint32 n) +{ + assert(present(n)); + tree.remove(nodes[n]); + remove(n); +} + + +// +// Test the remove substitute on element newN, which is not currently in the tree +// (unless newN==oldN) and element oldN, which is currently in the tree. The caller +// guarantees that the combination of newN and oldN is legal. +// +void TreeHarness::testSubstitute(Uint32 newN, Uint32 oldN) +{ + assert(newN == oldN || !present(newN) && present(oldN)); + tree.substitute(nodes[newN], nodes[oldN]); + remove(oldN); + add(newN); +} + + +// +// Make sure that the contents of the tree and rep match. +// +void TreeHarness::verify() const +{ + tree.verify(); + + // Make sure that there is a one-to-one correspondence between the tree nodes + // and the bits set in rep. + Uint32 r = rep; + for (TestNode *p = tree.firstNode(); p; p = p->next()) { + Uint32 n = p->key.n; + assert(r & 1<isRed() ? "(" : "["); + printSubtree(node->getChild(false)); + printf(" %d ", node->key.n); + printSubtree(node->getChild(true)); + printf(node->isRed() ? ")" : "]"); + } else + printf("-"); +} + +// +// Print the current state of the TreeHarness. +// +void TreeHarness::print() const +{ + printSubtree(tree.getRoot()); + printf("\n"); +} + + +// ---------------------------------------------------------------------------- + + +// +// Test the implementation of SortedTree. Assert if problems are found. +// +void testTrees() +{ + printf("Testing SortedTree...\n"); + TreeHarness h; + + for (Uint32 i = 0; i != 10000; i++) { + Uint32 n = h.randomNode(); + Uint32 m; + Uint32 c = 0; + + switch (random(21)) { + case 0: // Clear the tree (but do it infrequently) + if (random(5) != 2) + continue; + if (printProgress) + c = printf("Clear"); + h.testClear(); + break; + + case 1: // Test finding an element + case 2: + if (printProgress) + c = printf("Find %d", n); + h.testFind(n); + break; + + case 3: // Test findAfter + case 4: + if (printProgress) + c = printf("FindAfter %d", n); + h.testFindAfter(n); + break; + + case 5: // Test findBefore + case 6: + if (printProgress) + c = printf("FindBefore %d", n); + h.testFindBefore(n); + break; + + case 7: // Test findAttach + case 8: + if (printProgress) + c = printf("Find+Attach %d", n); + h.testFindAttach(n); + break; + + case 9: // Test insert + case 10: + if (h.present(n)) + continue; + if (printProgress) + c = printf("Insert %d", n); + h.testInsert(n); + break; + + case 11: // Test insertAfter + case 12: + if (h.present(n)) + continue; + m = h.testFindBefore(n); + if (printProgress) + if (m == h.nNodes) + c = printf("Insert %d after nil", n); + else + c = printf("Insert %d after %d", n, m); + h.testInsertAfter(n, m); + break; + + case 13: // Test insertBefore + case 14: + if (h.present(n)) + continue; + m = h.testFindAfter(n); + if (printProgress) + if (m == h.nNodes) + c = printf("Insert %d before nil", n); + else + c = printf("Insert %d before %d", n, m); + h.testInsertBefore(n, m); + break; + + case 15: // Test remove + case 16: + case 17: + n = h.randomPresent(); + if (n == h.nNodes) + continue; + if (printProgress) + c = printf("Remove %d", n); + h.testRemove(n); + break; + + case 18: // Test substitute + case 19: + n = h.randomPresent(); + m = n^1; + if (n == h.nNodes || m >= h.nNodes || h.present(m)) + continue; + if (printProgress) + c = printf("Substitute %d for %d", m, n); + h.testSubstitute(m, n); + break; + + case 20: // Test self-substitute + n = h.randomPresent(); + if (n == h.nNodes) + continue; + if (printProgress) + c = printf("Substitute %d for %d", n, n); + h.testSubstitute(n, n); + break; + + default: + trespass("Bad case"); + } + + h.verify(); + if (printProgress) { + printSpaces(stdout, 32 - c); + h.print(); + } + } + h.testClear(); + h.verify(); + printf("Done testing SortedTree.\n"); +} diff --git a/ef/Tools/UtilityTest/TreeTest.h b/ef/Tools/UtilityTest/TreeTest.h new file mode 100644 index 000000000000..6c28ebc89bac --- /dev/null +++ b/ef/Tools/UtilityTest/TreeTest.h @@ -0,0 +1,94 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#ifndef TREETEST_H +#define TREETEST_H + +#include "Tree.h" + + +const bool printProgress = true; // Set to print the progress of each test + +Uint32 random(Uint16 range); + + +// --- PRIVATE ---------------------------------------------------------------- + +class TreeHarness +{ + // We could have used Uint32 directly instead of struct TestKey, but + // this way we can check that the Tree templates do not expect any methods + // other than operator< to apply to keys. + struct TestKey + { + Uint32 n; // Number of the node that contains this key + + explicit TestKey(Uint32 n): n(n) {} + + bool operator<(const TestKey &key2) const {return n < key2.n;} + }; + + struct TestNode: TreeNode + { + TestKey key; + + TestNode(): key(0) {} + + const TestKey &getKey() const {return key;} + }; + + public: + static const nNodes = 32; + + private: + SortedTree tree; + Uint32 rep; // Bitmap of what should be in the tree + TestNode nodes[nNodes]; + + public: + TreeHarness(); + + static inline Uint32 randomNode() {return random(nNodes);} + inline bool present(Uint32 n) const {return rep>>n & 1;} + inline void add(Uint32 n) {rep |= 1< +#include "TreeTest.h" + + +#ifndef DEBUG + #error "DEBUG must be set here" +#endif + +int main() +{ + printf("Utility test program\n"); + testTrees(); + printf("Finished successfully.\n"); + return 0; +} diff --git a/ef/Tools/manifest.mn b/ef/Tools/manifest.mn new file mode 100644 index 000000000000..13664961a950 --- /dev/null +++ b/ef/Tools/manifest.mn @@ -0,0 +1,30 @@ +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. +DEPTH = .. + +DIRS = Burg JavaH + + + + + + + + + + + + diff --git a/ef/Utilities/Disassemblers/Makefile b/ef/Utilities/Disassemblers/Makefile new file mode 100644 index 000000000000..a316400b5267 --- /dev/null +++ b/ef/Utilities/Disassemblers/Makefile @@ -0,0 +1,49 @@ +#!gmake +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +####################################################################### +# (1) Directory specific info # +####################################################################### + +DEPTH = ../.. + +DIRS = x86 + +####################################################################### +# (2) Include "component" configuration information. # +####################################################################### + +include $(DEPTH)/config/config.mk + +####################################################################### +# (3) Include "local" platform-dependent assignments (OPTIONAL). # +####################################################################### + + + +####################################################################### +# (4) Execute "component" rules. (OPTIONAL) # +####################################################################### + +include $(DEPTH)/config/rules.mk + +####################################################################### +# (7) Execute "local" rules. (OPTIONAL). # +####################################################################### + + + diff --git a/ef/Utilities/Disassemblers/x86/Makefile b/ef/Utilities/Disassemblers/x86/Makefile new file mode 100644 index 000000000000..5de9688c06b5 --- /dev/null +++ b/ef/Utilities/Disassemblers/x86/Makefile @@ -0,0 +1,62 @@ +#!gmake +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +####################################################################### +# (1) Directory specific stuff # +####################################################################### + +DEPTH = ../../.. + +LIBRARY_NAME = DisassembleX86 + +CSRCS = XDisAsm.c \ + XDisAsmTable.c \ + $(NULL) + +LOCAL_MD_EXPORTS_x86 = XDisAsm.h \ + $(NULL) + +####################################################################### +# (2) Include "component" configuration information. # +####################################################################### + +include $(DEPTH)/config/config.mk + +####################################################################### +# (3) Include "local" platform-dependent assignments (OPTIONAL). # +####################################################################### + + +####################################################################### +# (4) Execute "component" rules. (OPTIONAL) # +####################################################################### + +include $(DEPTH)/config/rules.mk + +####################################################################### +# (7) Execute "local" rules. (OPTIONAL). # +####################################################################### + +# must make library first +# since the dll has no exported symbols +# no .lib will be created and since +# this piece of shit insists on making +# the fucking shared library lets make it +# happy +libs:: $(LIBRARY) $(SHARED_LIBRARY) + + diff --git a/ef/Utilities/Disassemblers/x86/XDisAsm.c b/ef/Utilities/Disassemblers/x86/XDisAsm.c new file mode 100644 index 000000000000..32f1c14cf578 --- /dev/null +++ b/ef/Utilities/Disassemblers/x86/XDisAsm.c @@ -0,0 +1,27 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#include "prlog.h" +#include "XDisAsm.h" + +char* disasmx86(long offset, char** startByte, char *limitByte, unsigned long flags ) +{ + /* IMPLEMENT: replace GPL'ed code */ + PR_ASSERT(0); + return NULL; +} diff --git a/ef/Utilities/Disassemblers/x86/XDisAsm.h b/ef/Utilities/Disassemblers/x86/XDisAsm.h new file mode 100644 index 000000000000..4b254ddadd11 --- /dev/null +++ b/ef/Utilities/Disassemblers/x86/XDisAsm.h @@ -0,0 +1,36 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +enum +{ + kDisAsmFlag32BitSegments = 0x0001 +}; + +#ifdef __cplusplus +extern "C" { +#endif + +char* disasmx86(long offset, char** startByte, char *limitByte, unsigned long flags ); +int x86InstructionLength(long offset, char** startByte, char *limitByte, unsigned long flags); + +#ifdef __cplusplus +} +#endif + + + diff --git a/ef/Utilities/General/CUtils.cpp b/ef/Utilities/General/CUtils.cpp new file mode 100644 index 000000000000..592a1b507dc0 --- /dev/null +++ b/ef/Utilities/General/CUtils.cpp @@ -0,0 +1,91 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#include "CUtils.h" + +#ifndef NO_NSPR +#include "plstr.h" +#endif + +#include + +char *Strtok::get(const char *pattern) +{ + char *start; + char *curr; + + for (start = string, curr = string; *curr; curr++) +#ifdef NO_NSPR + if (strchr(pattern, *curr)) +#else + if (PL_strchr(pattern, *curr)) +#endif + break; + + if (*curr) { + *curr = 0; + string = curr+1; + } else + string = curr; + + return (*start) ? start : 0; +} + + +char *dupString(const char *str, Pool &pool) +{ + if (!str) + return 0; + +#ifdef NO_NSPR + char *dup = new (pool) char[strlen(str)+1]; + strcpy(dup, str); +#else + char *dup = new (pool) char[PL_strlen(str)+1]; + PL_strcpy(dup, str); +#endif + + return dup; +} + +char *append(char *&s, Uint32 &strSize, const char *t) +{ +#ifdef NO_NSPR + Uint32 slen = strlen(s); + Uint32 tlen = strlen(t); +#else + Uint32 slen = PL_strlen(s); + Uint32 tlen = PL_strlen(t); +#endif + + if (slen+tlen+1 > strSize) { + strSize += tlen+256; + char *temp = new char[strSize]; +#ifdef NO_NSPR + strcpy(temp, s); +#else + PL_strcpy(temp, s); +#endif + delete [] s; + s = temp; + } + + strcat(s, t); + return s; +} + diff --git a/ef/Utilities/General/CUtils.h b/ef/Utilities/General/CUtils.h new file mode 100644 index 000000000000..93e273065a77 --- /dev/null +++ b/ef/Utilities/General/CUtils.h @@ -0,0 +1,85 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#ifndef _C_UTILS_H_ +#define _C_UTILS_H_ + +#include "Pool.h" + +/* This file is intended to be a repository for C/C++ utils that + * are reimplemented because the standard C routines are unsuitable + * for some reason (not thread-safe, not available on all platforms) + * and NSPR does not have them. + */ + +/* Performs the work done by the standard C routine strtok; like + * strtok, it mangles the original string. Use it as follows: + * const char *stringToBeBrokenUp; + * Strtok tok(stringToBeBrokenUp); + * for (const char *token = tok.get(pattern); token; + * token = tok.get(pattern)) + * use tok; + */ +class Strtok { +public: + /* string is a sequence of zero or more text tokens separated + * by spans of one or more characters in a pattern string. + */ + Strtok(char *string) : string(string) { } + + /* returns a pointer to the first character of the next + * "token" in the string separated by one of the characters + * in pattern, NULL if there are no nore tokens. + */ + char *get(const char *pattern); + +private: + /* The candidate string */ + char *string; + +}; + +/* duplicate the string, using the Pool provided to alloc memory */ +char *dupString(const char *str, Pool &pool); + +/* Append t to s, whose initial size (not length) is strSize. Grows s if + * necessary; on success, returns the updated s and sets strSize to + * the new size of the string. + */ +char *append(char *&s, Uint32 &strSize, const char *t); + +/* Class that houses a file descriptor and closes the file on exit */ +#include "prio.h" + +class FileDesc { +private: + PRFileDesc *fp; + +public: + FileDesc(const char *fileName, PRWord flags, PRWord mode) { + fp = PR_Open(fileName, flags, mode); + } + + void close() { if (fp) PR_Close(fp); fp = 0; } + ~FileDesc() { close(); } + + operator PRFileDesc * (void) { return fp; } +}; + +#endif /* _C_UTILS_H_ */ + diff --git a/ef/Utilities/General/CatchAssert.cpp b/ef/Utilities/General/CatchAssert.cpp new file mode 100644 index 000000000000..3bd9039b390f --- /dev/null +++ b/ef/Utilities/General/CatchAssert.cpp @@ -0,0 +1,55 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#include +#include +#include "CatchAssert.h" +#include "CatchAssert_md.h" +#include "JavaVM.h" + +#ifdef _WIN32 +/* + * catchAssert + * + * This function replaces the existing assert function. + * If the catchHardwareExceptions flag is true, then we just + * print the assert to stdout. If the flag is false, then + * we call the regular assert function for each platform. + * + */ +NS_EXTERN void __cdecl catchAssert(void *exp, void *filename, unsigned linenumber) { + + if (VM::theVM.getCatchHardwareExceptions()) { + + /* Print the assert. */ + printf("STATUS:ASSERTION.\n"); + printf("File: %s\n", filename); + printf("Linenumber: %i\n", linenumber); + + exit(1); + + } else { + + /* Call the regular assert. */ + throwAssert(exp, filename, linenumber); + + } + +} +#endif + diff --git a/ef/Utilities/General/CatchAssert.h b/ef/Utilities/General/CatchAssert.h new file mode 100644 index 000000000000..3bfb626f436d --- /dev/null +++ b/ef/Utilities/General/CatchAssert.h @@ -0,0 +1,53 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#include "Exports.h" + +#ifndef XP_PC +#include +#else + +/* Define __cdeck for non MS compilers. */ +#if ( !defined(_MSC_VER) && !defined(__cdecl) ) +# define __cdecl +#endif + + +/* Use the catchAssert instead of the regular assert. */ +#undef assert + +/* If the build target is optimized, don't include assert. */ +#ifdef NDEBUG + +# define assert(exp) ((void)0) + +#else + +/* + * Define an assert function that doesn't have a dialog pop-up, + * which would require user intervention. + * + */ +NS_EXTERN void __cdecl catchAssert(void *, void *, unsigned); + +# define assert(exp) (void)( (exp) || (catchAssert(#exp, __FILE__, __LINE__), 0) ) + +# endif /* NDEBUG */ + +#endif //XP_MAC + diff --git a/ef/Utilities/General/CheckedUnion.h b/ef/Utilities/General/CheckedUnion.h new file mode 100644 index 000000000000..9c6837553ed5 --- /dev/null +++ b/ef/Utilities/General/CheckedUnion.h @@ -0,0 +1,226 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#ifndef CHECKEDUNION_H +#define CHECKEDUNION_H + +// +// Use the CheckedUnion2 macro to create a checked union of two structures T1 and T2 +// with the following features: +// +// 1. In DEBUG versions the union remembers which of the structures in it, if any, +// is currently valid. +// 2. The structures T1 and T2 can have constructors. +// 3. Methods are provided to explicitly construct a T1 or T2 inside the union. +// +// +// To use a CheckedUnion2, do the following: +// +// Declare the structures T1 and T2 and the checked union as follows: +// +// struct Foo { ... }; +// struct Bar { ... }; +// CheckedUnion2(Foo, Bar) cu; +// +// To construct a Foo inside the checked union, call the following, replacing the ... +// with arguments to Foo's constructor. Constructing a Bar is analogous. +// +// new(cu.initFoo()) Foo(...); +// +// To get a reference to the Foo inside the checked union, call the following. In DEBUG +// versions it will raise an assert if the checked union does not currently contain a Foo. +// Getting a reference to a Bar is analogous. +// +// cu.getFoo() +// +// To erase the union's knowledge of the structure it contains, call the following. This +// is a no-op in non-DEBUG versions. +// +// cu.clear(); +// +// Caution: T1 and T2 should not have destructors; the checked union does not call them. +// T1 and T2 should not have elements that require more than pointer alignment. +// + +#define UncheckedUnion2(T1, T2) \ +union UncheckedUnion_##T1##_##T2 \ +{ \ + private: \ + void *aligner; /* Unused field to ensure that the union is properly aligned */ \ + char f##T1[sizeof(T1)]; /* Fields of T1 */ \ + char f##T2[sizeof(T2)]; /* Fields of T2 */ \ + \ + public: \ + void *init##T1() {return f##T1;} \ + void *init##T2() {return f##T2;} \ + void clear() {} \ + \ + const T1 &get##T1() const {return *static_cast(static_cast(f##T1));} \ + T1 &get##T1() {return *static_cast(static_cast(f##T1));} \ + const T2 &get##T2() const {return *static_cast(static_cast(f##T2));} \ + T2 &get##T2() {return *static_cast(static_cast(f##T2));} \ +} + +#define CheckedUnion2DEBUG(T1, T2) \ +class CheckedUnion_##T1##_##T2 \ +{ \ + T1 *p##T1; /* Pointer to T1 (to simplify looking at T1 in a debugger) or nil if none */ \ + T2 *p##T2; /* Pointer to T2 (to simplify looking at T2 in a debugger) or nil if none */ \ + UncheckedUnion2(T1, T2) u; \ + \ + public: \ + CheckedUnion_##T1##_##T2() {p##T1 = 0; p##T2 = 0;} \ + void *init##T1() {p##T1 = &u.get##T1(); p##T2 = 0; return u.init##T1();} \ + void *init##T2() {p##T1 = 0; p##T2 = &u.get##T2(); return u.init##T2();} \ + void clear() {p##T1 = 0; p##T2 = 0;} \ + \ + const T1 &get##T1() const {assert(p##T1); return u.get##T1();} \ + T1 &get##T1() {assert(p##T1); return u.get##T1();} \ + const T2 &get##T2() const {assert(p##T2); return u.get##T2();} \ + T2 &get##T2() {assert(p##T2); return u.get##T2();} \ +} + +#ifdef DEBUG + #define CheckedUnion2(T1, T2) CheckedUnion2DEBUG(T1, T2) +#else + #define CheckedUnion2(T1, T2) UncheckedUnion2(T1, T2) +#endif + + +// +// CheckedUnion3 is analogous to CheckedUnion2, but with three alternatives. +// + +#define UncheckedUnion3(T1, T2, T3) \ +union UncheckedUnion_##T1##_##T2##_##T3 \ +{ \ + private: \ + void *aligner; /* Unused field to ensure that the union is properly aligned */ \ + char f##T1[sizeof(T1)]; /* Fields of T1 */ \ + char f##T2[sizeof(T2)]; /* Fields of T2 */ \ + char f##T3[sizeof(T3)]; /* Fields of T3 */ \ + \ + public: \ + void *init##T1() {return f##T1;} \ + void *init##T2() {return f##T2;} \ + void *init##T3() {return f##T3;} \ + void clear() {} \ + \ + const T1 &get##T1() const {return *static_cast(static_cast(f##T1));} \ + T1 &get##T1() {return *static_cast(static_cast(f##T1));} \ + const T2 &get##T2() const {return *static_cast(static_cast(f##T2));} \ + T2 &get##T2() {return *static_cast(static_cast(f##T2));} \ + const T3 &get##T3() const {return *static_cast(static_cast(f##T3));} \ + T3 &get##T3() {return *static_cast(static_cast(f##T3));} \ +} + +#define CheckedUnion3DEBUG(T1, T2, T3) \ +class CheckedUnion_##T1##_##T2##_##T3 \ +{ \ + T1 *p##T1; /* Pointer to T1 (to simplify looking at T1 in a debugger) or nil if none */ \ + T2 *p##T2; /* Pointer to T2 (to simplify looking at T2 in a debugger) or nil if none */ \ + T3 *p##T3; /* Pointer to T3 (to simplify looking at T3 in a debugger) or nil if none */ \ + UncheckedUnion3(T1, T2, T3) u; \ + \ + public: \ + CheckedUnion_##T1##_##T2##_##T3() {p##T1 = 0; p##T2 = 0; p##T3 = 0;} \ + void *init##T1() {p##T1 = &u.get##T1(); p##T2 = 0; p##T3 = 0; return u.init##T1();} \ + void *init##T2() {p##T1 = 0; p##T2 = &u.get##T2(); p##T3 = 0; return u.init##T2();} \ + void *init##T3() {p##T1 = 0; p##T2 = 0; p##T3 = &u.get##T3(); return u.init##T3();} \ + void clear() {p##T1 = 0; p##T2 = 0; p##T3 = 0;} \ + \ + const T1 &get##T1() const {assert(p##T1); return u.get##T1();} \ + T1 &get##T1() {assert(p##T1); return u.get##T1();} \ + const T2 &get##T2() const {assert(p##T2); return u.get##T2();} \ + T2 &get##T2() {assert(p##T2); return u.get##T2();} \ + const T3 &get##T3() const {assert(p##T3); return u.get##T3();} \ + T3 &get##T3() {assert(p##T3); return u.get##T3();} \ +} + +#ifdef DEBUG + #define CheckedUnion3(T1, T2, T3) CheckedUnion3DEBUG(T1, T2, T3) +#else + #define CheckedUnion3(T1, T2, T3) UncheckedUnion3(T1, T2, T3) +#endif + + +// +// CheckedUnion4 is analogous to CheckedUnion2, but with four alternatives. +// + +#define UncheckedUnion4(T1, T2, T3, T4) \ +union UncheckedUnion_##T1##_##T2##_##T3##_##T4 \ +{ \ + private: \ + void *aligner; /* Unused field to ensure that the union is properly aligned */ \ + char f##T1[sizeof(T1)]; /* Fields of T1 */ \ + char f##T2[sizeof(T2)]; /* Fields of T2 */ \ + char f##T3[sizeof(T3)]; /* Fields of T3 */ \ + char f##T4[sizeof(T4)]; /* Fields of T4 */ \ + \ + public: \ + void *init##T1() {return f##T1;} \ + void *init##T2() {return f##T2;} \ + void *init##T3() {return f##T3;} \ + void *init##T4() {return f##T4;} \ + void clear() {} \ + \ + const T1 &get##T1() const {return *static_cast(static_cast(f##T1));} \ + T1 &get##T1() {return *static_cast(static_cast(f##T1));} \ + const T2 &get##T2() const {return *static_cast(static_cast(f##T2));} \ + T2 &get##T2() {return *static_cast(static_cast(f##T2));} \ + const T3 &get##T3() const {return *static_cast(static_cast(f##T3));} \ + T3 &get##T3() {return *static_cast(static_cast(f##T3));} \ + const T4 &get##T4() const {return *static_cast(static_cast(f##T4));} \ + T4 &get##T4() {return *static_cast(static_cast(f##T4));} \ +} + +#define CheckedUnion4DEBUG(T1, T2, T3, T4) \ +class CheckedUnion_##T1##_##T2##_##T3##_##T4 \ +{ \ + T1 *p##T1; /* Pointer to T1 (to simplify looking at T1 in a debugger) or nil if none */ \ + T2 *p##T2; /* Pointer to T2 (to simplify looking at T2 in a debugger) or nil if none */ \ + T3 *p##T3; /* Pointer to T3 (to simplify looking at T3 in a debugger) or nil if none */ \ + T4 *p##T4; /* Pointer to T4 (to simplify looking at T4 in a debugger) or nil if none */ \ + UncheckedUnion4(T1, T2, T3, T4) u; \ + \ + public: \ + CheckedUnion_##T1##_##T2##_##T3##_##T4() {p##T1 = 0; p##T2 = 0; p##T3 = 0; p##T4 = 0;} \ + void *init##T1() {p##T1 = &u.get##T1(); p##T2 = 0; p##T3 = 0; p##T4 = 0; return u.init##T1();} \ + void *init##T2() {p##T1 = 0; p##T2 = &u.get##T2(); p##T3 = 0; p##T4 = 0; return u.init##T2();} \ + void *init##T3() {p##T1 = 0; p##T2 = 0; p##T3 = &u.get##T3(); p##T4 = 0; return u.init##T3();} \ + void *init##T4() {p##T1 = 0; p##T2 = 0; p##T3 = 0; p##T4 = &u.get##T4(); return u.init##T4();} \ + void clear() {p##T1 = 0; p##T2 = 0; p##T3 = 0; p##T4 = 0;} \ + \ + const T1 &get##T1() const {assert(p##T1); return u.get##T1();} \ + T1 &get##T1() {assert(p##T1); return u.get##T1();} \ + const T2 &get##T2() const {assert(p##T2); return u.get##T2();} \ + T2 &get##T2() {assert(p##T2); return u.get##T2();} \ + const T3 &get##T3() const {assert(p##T3); return u.get##T3();} \ + T3 &get##T3() {assert(p##T3); return u.get##T3();} \ + const T4 &get##T4() const {assert(p##T4); return u.get##T4();} \ + T4 &get##T4() {assert(p##T4); return u.get##T4();} \ +} + +#ifdef DEBUG + #define CheckedUnion4(T1, T2, T3, T4) CheckedUnion4DEBUG(T1, T2, T3, T4) +#else + #define CheckedUnion4(T1, T2, T3, T4) UncheckedUnion4(T1, T2, T3, T4) +#endif + +#endif diff --git a/ef/Utilities/General/DebugUtils.cpp b/ef/Utilities/General/DebugUtils.cpp new file mode 100644 index 000000000000..68cb14149a1f --- /dev/null +++ b/ef/Utilities/General/DebugUtils.cpp @@ -0,0 +1,83 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#include "DebugUtils.h" + +#ifdef DEBUG_LOG +// +// Print nSpaces spaces on the output stream f. +// +void printSpaces(LogModuleObject &f, int nSpaces) +{ + while (nSpaces > 0) { + UT_OBJECTLOG(f, PR_LOG_ALWAYS, (" ")); + nSpaces--; + } +} + + +// +// Tab margin spaces over from the beginning of a line. +// f must be at the beginning of a line. This differs +// from printSpaces in that it could output tabs instead of +// or in addition to spaces. +// +void printMargin(LogModuleObject &f, int margin) +{ + if (tabWidth > 1) + while (margin >= tabWidth) { + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("\t")); + margin -= tabWidth; + } + printSpaces(f, margin); +} + + +// +// Print the unsigned Int64 for debugging purposes. +// Return the number of characters printed. +// +int printUInt64(LogModuleObject &f, Uint64 l) +{ + char digits[21]; + digits[21] = '\0'; + char *firstDigit = digits + 21; + do { + Uint64 q = l / 10; + *--firstDigit = (char)(l - q*10) + '0'; + l = q; + } while (l != 0); + return UT_OBJECTLOG(f, PR_LOG_ALWAYS, (firstDigit)); +} + + +// +// Print the signed Int64 for debugging purposes. +// Return the number of characters printed. +// +int printInt64(LogModuleObject &f, Int64 l) +{ + int a = 0; + if (l < 0) { + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("-")); + a = 1; + l = -l; + } + return a + printUInt64(f, l); +} +#endif diff --git a/ef/Utilities/General/DebugUtils.h b/ef/Utilities/General/DebugUtils.h new file mode 100644 index 000000000000..6b578e538ff9 --- /dev/null +++ b/ef/Utilities/General/DebugUtils.h @@ -0,0 +1,35 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#ifndef DEBUGUTILS_H +#define DEBUGUTILS_H + +#include "Fundamentals.h" +#include "LogModule.h" + +#ifdef DEBUG_LOG + +const tabWidth = 0; // Width of tabs in output stream; 0 means no tabs + +void printSpaces(LogModuleObject &f, int nSpaces); +void printMargin(LogModuleObject &f, int margin); +int printUInt64(LogModuleObject &f, Uint64 l); +int printInt64(LogModuleObject &f, Int64 l); + +#endif +#endif diff --git a/ef/Utilities/General/DoublyLinkedList.h b/ef/Utilities/General/DoublyLinkedList.h new file mode 100644 index 000000000000..6440a539e0b4 --- /dev/null +++ b/ef/Utilities/General/DoublyLinkedList.h @@ -0,0 +1,427 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#ifndef DOUBLYLINKEDLIST_H +#define DOUBLYLINKEDLIST_H + +#include "Fundamentals.h" + +// --- PRIVATE ---------------------------------------------------------------- + +struct DoublyLinkedNode +{ + DoublyLinkedNode *next; // Link to next node (in DEBUG versions nil if not explicitly set) + DoublyLinkedNode *prev; // Link to previous node (in DEBUG versions nil if not explicitly set) + + void remove(); + void substitute(DoublyLinkedNode &src); + void insertAfter(DoublyLinkedNode &loc); + void insertBefore(DoublyLinkedNode &loc); + + #ifdef DEBUG + void init() {next = 0; prev = 0;} + bool isLinked() const {return next && prev;} + bool isUnlinked() const {return !next && !prev;} + #else + void init() {} + #endif +}; + + +class DoublyLinkedRoot +{ + protected: + DoublyLinkedNode root; + + private: + DoublyLinkedRoot(const DoublyLinkedRoot &); // Copying forbidden + void operator=(const DoublyLinkedRoot &); // Copying forbidden + public: + DoublyLinkedRoot() {root.next = &root; root.prev = &root;} + + void init() {root.next = &root; root.prev = &root;} + bool empty() const {return root.next == &root;} + + protected: + void removeFirstNode(); +}; + + +// --- PUBLIC ----------------------------------------------------------------- + + +// Derive doubly-linked list nodes from this class. N is the node class, which should +// be a subclass of this class. +template +class DoublyLinkedEntry: public DoublyLinkedNode +{ + #ifdef DEBUG + DoublyLinkedEntry(const DoublyLinkedEntry &); // Copying forbidden + void operator=(const DoublyLinkedEntry &); // Copying forbidden + public: + DoublyLinkedEntry() {init();} + #endif + public: + + // DoublyLinkedNode administration + static N &linkOwner(DoublyLinkedNode &l) {return *static_cast(&l);} + DoublyLinkedNode &getLinks() {return *this;} +}; + + +// Use this class for doubly-linked list containers. N is the node class, which should +// inherit from DoublyLinkedEntry. +template +class DoublyLinkedList: public DoublyLinkedRoot +{ + public: + typedef DoublyLinkedNode *iterator; + + // To iterate forward through a DoublyLinkedList dl, use: + // for (DoublyLinkedList::iterator i = dl.begin(); !dl.done(i); i = dl.advance(i)) + // ... dl.get(i) ... + iterator begin() const {return root.next;} + iterator end() const {return root.prev;} + NONDEBUG_ONLY(static) iterator location(N &node) {assert(exists(node)); return &node.getLinks();} + static N &get(iterator i) {return N::linkOwner(*i);} + static iterator advance(iterator i) {return i->next;} + static iterator retreat(iterator i) {return i->prev;} + bool done(iterator i) const {return i == &root;} + #ifdef DEBUG + bool validIterator(iterator i) const; + #endif + + Uint32 length() const; + bool lengthIs(Uint32 n) const; + N &first() const {assert(!empty()); return get(root.next);} + N &last() const {assert(!empty()); return get(root.prev);} + bool exists(N &node) const; + Uint32 index(N &node) const; + + void addFirst(N &node); + void addLast(N &node); + NONDEBUG_ONLY(static) void insertBefore(N &node, iterator i); + NONDEBUG_ONLY(static) void insertAfter(N &node, iterator i); + void removeFirst(); + void removeLast(); + void clear(); + void move(DoublyLinkedList &src); +}; + + +template +class SortedDoublyLinkedList: public DoublyLinkedList +{ + public: + explicit SortedDoublyLinkedList(int (*compare)(const N *elem1, const N *elem2)): compareFunc(compare) {} + void insert(N &node); + bool isInList(N &node); + + private: + int (*const compareFunc)(const N*, const N*); // Comparison function returns 1 for >, -1 for <, and 0 for ==. +}; + + +// --- INLINES ---------------------------------------------------------------- + + +// +// Unlink this node from the list into which it is linked. +// +inline void DoublyLinkedNode::remove() +{ + assert(isLinked() && next != this); + DoublyLinkedNode *n = next; + DoublyLinkedNode *p = prev; + n->prev = p; + p->next = n; + init(); +} + + +// +// Insert this node after node loc in a doubly-linked list. +// Node loc must be already linked into a list, while +// this node should not be already linked into any list. +// +inline void DoublyLinkedNode::insertAfter(DoublyLinkedNode &loc) +{ + assert(isUnlinked() && loc.isLinked()); + next = loc.next; + prev = &loc; + loc.next->prev = this; + loc.next = this; +} + + +// +// Insert this node before node loc in a doubly-linked list. +// Node loc must be already linked into a list, while +// this node should not be already linked into any list. +// +inline void DoublyLinkedNode::insertBefore(DoublyLinkedNode &loc) +{ + assert(isUnlinked() && loc.isLinked()); + next = &loc; + prev = loc.prev; + loc.prev->next = this; + loc.prev = this; +} + + +// +// Unlink src from the list into which it is linked and link this node in src's +// place. src must not be the list's root (unless called from the move method below). +// +inline void DoublyLinkedNode::substitute(DoublyLinkedNode &src) +{ + assert(isUnlinked() && src.isLinked()); + DoublyLinkedNode *n = src.next; + DoublyLinkedNode *p = src.prev; + assert(n != &src && p != &src && n != this && p != this && n->prev == &src && p->next == &src); + next = n; + prev = p; + n->prev = this; + p->next = this; + src.init(); +} + + +// +// Return the number of nodes (not including the root) in the doubly-linked list. +// +template +Uint32 DoublyLinkedList::length() const +{ + Uint32 n = 0; + for (iterator i = begin(); !done(i); i = advance(i)) + n++; + return n; +} + + +// +// Return true if the number of nodes (not including the root) in the doubly-linked list +// is equal to n. This is often faster than "length() == n" because if n is small it can +// stop iterating through the list as soon as it exceeds n. +// +template +bool DoublyLinkedList::lengthIs(Uint32 n) const +{ + for (iterator i = begin(); !done(i); i = advance(i)) + if (n-- == 0) + return false; + return n == 0; +} + + +#ifdef DEBUG +// +// Return true if the iterator points somewhere within this doubly-linked list +// (including its root). +// +template +bool DoublyLinkedList::validIterator(DoublyLinkedNode* i) const +{ + iterator j; + for (j = begin(); !done(j); j = advance(j)) + if (i == j) + return true; + return i == j; +} +#endif + + +// +// Return true if node is in the list and false otherwise. +// +template +bool DoublyLinkedList::exists(N &node) const +{ + for (iterator current = this->begin(); !done(current); current = advance(current)) + if (&node == &this->get(current)) + return true; + return false; +} + + +// +// Return the zero-based index of node in the list or this->length() if +// the node is not in the list. +// +template +Uint32 DoublyLinkedList::index(N &node) const +{ + Uint32 index = 0; + for (iterator current = this->begin(); !done(current) && &node != &this->get(current); current = advance(current)) + index++; + return index; +} + + +// +// Insert node into the doubly-linked list at its beginning. +// The node should not be already linked into any list. +// +template +inline void DoublyLinkedList::addFirst(N &node) +{ + node.getLinks().insertAfter(root); +} + + +// +// Insert node into the doubly-linked list at its end. +// The node should not be already linked into any list. +// +template +inline void DoublyLinkedList::addLast(N &node) +{ + node.getLinks().insertBefore(root); +} + + +// +// Insert node into the doubly-linked list before iterator i. +// The node should not be already linked into any list. +// +template +inline void DoublyLinkedList::insertBefore(N &node, DoublyLinkedNode* i) +{ + assert(validIterator(i)); + node.getLinks().insertBefore(*i); +} + + +// +// Insert node into the doubly-linked list after iterator i. +// The node should not be already linked into any list. +// +template +inline void DoublyLinkedList::insertAfter(N &node, DoublyLinkedNode* i) +{ + assert(validIterator(i)); + node.getLinks().insertAfter(*i); +} + + +// +// Remove the first node, if any, from this doubly-linked list. +// +template +inline void DoublyLinkedList::removeFirst() +{ + if (!empty()) + root.next->remove(); +} + + +// +// Remove the last node, if any, from this doubly-linked list. +// +template +inline void DoublyLinkedList::removeLast() +{ + if (!empty()) + root.prev->remove(); +} + + +// +// Remove all nodes from this doubly-linked list. +// +template +inline void DoublyLinkedList::clear() +{ + while (!empty()) + root.next->remove(); +} + + +// +// Destructively move the src DoublyLinkedList to this DoublyLinkedList. +// The src DoublyLinkedList will subsequently be empty. This DoublyLinkedList +// must be empty prior to this call. +// +template +void DoublyLinkedList::move(DoublyLinkedList &src) +{ + assert(empty() && &src != this); + + if (!src.empty()) { + root.init(); // Avoid assert inside substitute. + root.substitute(src.root); + src.init(); + } +} + + +// +// Uses the specified compare function to search for node. +// Returns true if node is in the list and false otherwise. +// +template +bool SortedDoublyLinkedList::isInList(N &node) +{ + iterator current = this->begin(); + for (; !done(current) && (compareFunc(&node, &(this->get(current))) == 1); + current = advance(current)) + {} // do nothing in body + + if (done(current)) + return false; + else + return (compareFunc(&node, &(this->get(current))) == 0); +} + + +// +// Inserts node into the sorted list unless it already exists in the list. +// +template +void SortedDoublyLinkedList::insert(N &node) +{ + // loop will terminate with current pointing to the spot where we wish to insert node. + // last will be the node before the desired spot. If the element is already in the list then + // current will point to it. + iterator current = this->begin(); + iterator last = current; + for(; !done(current) && (compareFunc(&node, &(this->get(current))) == 1); + current = advance(current)) + last = current; + + if(this->done(current)) // special case add to end of list + addLast(node); + else if(compareFunc(&node, &(this->get(current))) != 0) // Do not insert if element is in the list already + { // might want this to be users responsibilities + if (current == this->begin()) + addFirst(node); + else + { + // add to list between last and current + DoublyLinkedNode& beforeNode = this->get(last).getLinks(); + DoublyLinkedNode& afterNode = this->get(current).getLinks(); + beforeNode.next = &(node.getLinks()); + node.getLinks().prev = &beforeNode; + afterNode.prev = &(node.getLinks()); + node.getLinks().next = &afterNode; + } + } +} + +#endif diff --git a/ef/Utilities/General/Exports.h b/ef/Utilities/General/Exports.h new file mode 100644 index 000000000000..60f64255100c --- /dev/null +++ b/ef/Utilities/General/Exports.h @@ -0,0 +1,42 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +/* + * Export definitions. + */ + +#ifdef XP_PC + #define NS_NATIVECALL(inReturnType) inReturnType __stdcall + #define NS_EXPORT __declspec(dllexport) + + #ifdef IMPORTING_VM_FILES /* Defined by all modules that import Vm header files */ + #define NS_EXTERN __declspec(dllimport) + #else + #define NS_EXTERN __declspec(dllexport) + #endif + + #pragma warning(disable: 4251) +#elif defined(LINUX) + #define NS_NATIVECALL(inReturnType) __attribute__((stdcall)) inReturnType + #define NS_EXPORT + #define NS_EXTERN +#else + #define NS_NATIVECALL(inReturnType) inReturnType + #define NS_EXPORT + #define NS_EXTERN +#endif diff --git a/ef/Utilities/General/FastBitMatrix.cpp b/ef/Utilities/General/FastBitMatrix.cpp new file mode 100644 index 000000000000..32fff71ca187 --- /dev/null +++ b/ef/Utilities/General/FastBitMatrix.cpp @@ -0,0 +1,135 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#include "FastBitMatrix.h" +#include "FastBitSet.h" +#include "prlog.h" + +bool +operator == (const FastBitMatrix& x, const FastBitMatrix& y) +{ + if ((x.nCols != y.nCols) || (x.nRows != y.nRows)) + return false; + + PRUint32 nCols = x.nCols; + PRUint32 nRows = x.nRows; + for (PRUint32 r = 0; r < nRows; r++) + { + FastBitSet xRow(x.getRow(r), nCols); + FastBitSet yRow(y.getRow(r), nCols); + + if (xRow != yRow) + return false; + } + return true; +} + +void FastBitMatrix:: +reserve(PRUint32 r, PRUint32 c) +{ + PRUint32 nWordsOnARow = FBS_ROUNDED_WORDS(c); + nRows = r; + nCols = c; + + if ((nWordsOnARow & (nWordsOnARow - 1)) == 0) + { + PR_FLOOR_LOG2(rowShift, nWordsOnARow); + } + else + { + PR_FLOOR_LOG2(rowShift, nWordsOnARow); + rowShift++; + } + + assert(rowShift < 32); + + nWords = r << rowShift; + if (pool != NULL) + words = new(*pool) PRUint32[nWords]; + else + words = new PRUint32[nWords]; +} + +void FastBitMatrix:: +reserveOrUpdate(PRUint32 r, PRUint32 c) +{ + PRUint32 nWordsOnARow = FBS_ROUNDED_WORDS(c); + PRUint32 neededWords; + nRows = r; + nCols = c; + + if ((nWordsOnARow & (nWordsOnARow - 1)) == 0) + { + PR_FLOOR_LOG2(rowShift, nWordsOnARow); + } + else + { + PR_FLOOR_LOG2(rowShift, nWordsOnARow); + rowShift++; + } + assert(rowShift < 32); + neededWords = r << rowShift; + if (nWords < neededWords) + { + if ((words != NULL) && (pool == NULL)) delete words; + nWords = neededWords; + if (pool != NULL) + words = new(*pool) PRUint32[nWords]; + else + words = new PRUint32[nWords]; + } +} + +void FastBitMatrix:: +copy(PRUint32* src) +{ + PRUint32 *ptr = words; + PRUint32* limit = &words[nRows << rowShift]; + while (ptr < limit) *ptr++ = *src++; +} + +#ifdef DEBUG_LOG +void FastBitMatrix:: +printPretty(FILE* f) +{ + fprintf(f, "[\n"); + for (PRUint32 i = 0; i < nRows; i++) + { + fprintf(stdout, " "); + FastBitSet row(&words[i << rowShift], nCols); + row.printPretty(f); + } + fprintf(stdout, "]\n"); +} + +void FastBitMatrix:: +printDiff(FILE *f, const FastBitMatrix& x) +{ + PR_ASSERT((x.nCols == nCols) && (x.nRows == nRows)); + + fprintf(f, "[\n"); + for (PRUint32 i = 0; i < nRows; i++) + { + fprintf(stdout, " "); + FastBitSet row(&words[i << rowShift], nCols); + FastBitSet xRow(&x.words[i << rowShift], nCols); + row.printDiff(f, xRow); + } + fprintf(stdout, "]\n"); +} +#endif diff --git a/ef/Utilities/General/FastBitMatrix.h b/ef/Utilities/General/FastBitMatrix.h new file mode 100644 index 000000000000..f322351b7689 --- /dev/null +++ b/ef/Utilities/General/FastBitMatrix.h @@ -0,0 +1,228 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#ifndef _FAST_BITMATRIX_H_ +#define _FAST_BITMATRIX_H_ + +#include "Fundamentals.h" +#include "FastBitSet.h" +#include "Pool.h" +#include "prbit.h" + +class FastBitMatrix +{ +private: + Pool* pool; + PRUint32* words; + PRUint32 nWords; + PRUint32 nCols; + PRUint32 nRows; + PRUint8 rowShift; + + + void reserve(PRUint32 r, PRUint32 c); + void reserveOrUpdate(PRUint32 r, PRUint32 c); + + void copy(PRUint32* src); + +public: + FastBitMatrix() : pool(NULL), words(0), nWords(0), nCols(0), nRows(0), rowShift(0) {} + FastBitMatrix(Pool& p) : pool(&p), words(0), nWords(0), nCols(0), nRows(0), rowShift(0) {} + FastBitMatrix(PRUint32 r, PRUint32 c) : pool(NULL), words(0), nWords(0) {sizeToAndClear(r, c);} + FastBitMatrix(Pool& p, PRUint32 r, PRUint32 c) : pool(&p), words(0), nWords(0) {sizeToAndClear(r, c);} + inline FastBitMatrix(const FastBitMatrix& m); + ~FastBitMatrix() {if ((words != NULL) && (pool == NULL)) delete words;} + + inline FastBitMatrix& operator = (const FastBitMatrix& m); + friend bool operator == (const FastBitMatrix& x, const FastBitMatrix& y); + inline friend bool operator != (const FastBitMatrix& x, const FastBitMatrix& y); + + inline void sizeTo(PRUint32 r, PRUint32 c) {reserveOrUpdate(r, c);} + inline void sizeToAndClear(PRUint32 r, PRUint32 c) {sizeTo(r, c); clear();} + + inline void set(PRUint32 r, PRUint32 c); + inline void setRow(PRUint32 r); + inline void set(); + + inline void clear(PRUint32 r, PRUint32 c); + inline void clearRow(PRUint32 r); + inline void clear(); + + inline bool test(PRUint32 r, PRUint32 c) const; + inline bool test(PRUint32 r, PRUint32* bits) const; + + inline PRUint32* getRow(PRUint32 r) {return &words[r << rowShift];} + inline PRUint32* getRow(PRUint32 r) const {return &words[r << rowShift];} + inline void orRow(PRUint32 r, FastBitSet& set); + inline void andRow(PRUint32 r, FastBitSet& set); + + inline void andRows(PRUint32 r, PRUint32 d); + inline void orRows(PRUint32 r, PRUint32 d); + inline void copyRows(PRUint32 r, PRUint32 d); + inline bool compareRows(PRUint32 r, PRUint32 d); + +#ifdef DEBUG_LOG + void printPretty(FILE *f); + void printDiff(FILE *f, const FastBitMatrix& x); +#endif +}; + +inline bool FastBitMatrix::compareRows(PRUint32 s, PRUint32 d) +{ + register PRUint32* src = &words[s << rowShift]; + register PRUint32* dst = &words[d << rowShift]; + register PRUint32* limit = &src[FBS_ROUNDED_WORDS(nCols)]; + + while (src < limit) + if (*src++ != *dst++) + return false; + return true; +} + +inline void FastBitMatrix::copyRows(PRUint32 s, PRUint32 d) +{ + register PRUint32* src = &words[s << rowShift]; + register PRUint32* dst = &words[d << rowShift]; + register PRUint32* limit = &src[FBS_ROUNDED_WORDS(nCols)]; + + while (src < limit) + *dst++ = *src++; +} + +inline void FastBitMatrix::andRows(PRUint32 s, PRUint32 d) +{ + register PRUint32* src = &words[s << rowShift]; + register PRUint32* dst = &words[d << rowShift]; + register PRUint32* limit = &src[FBS_ROUNDED_WORDS(nCols)]; + + while (src < limit) + *dst++ &= *src++; +} + +inline void FastBitMatrix::orRows(PRUint32 s, PRUint32 d) +{ + register PRUint32* src = &words[s << rowShift]; + register PRUint32* dst = &words[d << rowShift]; + register PRUint32* limit = &src[FBS_ROUNDED_WORDS(nCols)]; + + while (src < limit) + *dst++ |= *src++; +} + +inline void FastBitMatrix::orRow(PRUint32 r, FastBitSet& set) +{ + register PRUint32* ptr = &words[r << rowShift]; + register PRUint32* src = set.getWords(); + register int size = FBS_ROUNDED_WORDS(nCols) - 1; + do ptr[size] |= src[size]; while (--size >= 0); +} + +inline void FastBitMatrix::andRow(PRUint32 r, FastBitSet& set) +{ + register PRUint32* ptr = &words[r << rowShift]; + register PRUint32* src = set.getWords(); + register int size = FBS_ROUNDED_WORDS(nCols) - 1; + do ptr[size] &= src[size]; while (--size >= 0); +} + +inline void FastBitMatrix::set(PRUint32 r, PRUint32 c) +{ + register PRUint8 shift = c & 31; + register PRUint32 mask = (1 << shift); + words[(r << rowShift) + (c >> 5)] |= mask; +} + +inline void FastBitMatrix::setRow(PRUint32 r) +{ + register PRUint32* ptr = &words[r << rowShift]; + register int size = FBS_ROUNDED_WORDS(nCols) - 1; + do ptr[size] = ~0; while (--size >= 0); +} + +inline void FastBitMatrix::set() +{ + register PRUint32* ptr = words; + register PRUint32 val = ~0; + register int size = nWords-1; + do ptr[size] = val; while (--size >= 0); +} + +inline void FastBitMatrix::clear(PRUint32 r, PRUint32 c) +{ + register PRUint8 shift = c & 31; + register PRUint32 mask = (1 << shift); + mask = ~mask; + words[(r << rowShift) + (c >> 5)] &= mask; +} + +inline void FastBitMatrix::clearRow(PRUint32 r) +{ + register PRUint32* ptr = &words[r << rowShift]; + register int size = FBS_ROUNDED_WORDS(nCols) - 1; + do ptr[size] = 0; while (--size >= 0); +} + +inline void FastBitMatrix::clear() +{ + register PRUint32* ptr = words; + register PRUint32 val = 0; + register int size = nWords-1; + do ptr[size] = val; while (--size >= 0); +} + +inline bool FastBitMatrix::test(PRUint32 r, PRUint32 c) const +{ + register PRUint8 shift = c & 31; + register PRUint32 mask = (1 << shift); + if ((words[(r << rowShift) + (c >> 5)] & mask) > 0) + return true; + else + return false; +} + +inline bool FastBitMatrix::test(PRUint32 r, PRUint32* bits) const +{ + register PRUint32* row = &words[r << rowShift]; + register int size = FBS_ROUNDED_WORDS(nCols) - 1; + + do if (row[size] & bits[size]) return true; while (--size >= 0); + return false; +} + +inline FastBitMatrix& FastBitMatrix:: +operator = (const FastBitMatrix& m) +{ + reserveOrUpdate(m.nRows, m.nCols); + copy(m.words); + return (*this); +} + +inline FastBitMatrix:: +FastBitMatrix(const FastBitMatrix& m) : pool(m.pool), words(0), nWords(0) +{ + reserve(m.nRows, m.nCols); + copy(m.words); +} + +inline bool +operator != (const FastBitMatrix& x, const FastBitMatrix& y) +{ + return !(x==y); +} + +#endif /* _FAST_BITMATRIX_H_ */ diff --git a/ef/Utilities/General/FastBitSet.cpp b/ef/Utilities/General/FastBitSet.cpp new file mode 100644 index 000000000000..7656dd5b915d --- /dev/null +++ b/ef/Utilities/General/FastBitSet.cpp @@ -0,0 +1,447 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#include "FastBitSet.h" +#ifdef WIN32 +#include "Value.h" // for leastSigBit +#endif + +static PRUint32 nBit[16] = {0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4}; + +static PRUint32 endMasks[32] = +{ + 0x00000001, 0x00000003, 0x00000007, 0x0000000f, + 0x0000001f, 0x0000003f, 0x0000007f, 0x000000ff, + 0x000001ff, 0x000003ff, 0x000007ff, 0x00000fff, + 0x00001fff, 0x00003fff, 0x00007fff, 0x0000ffff, + 0x0001ffff, 0x0003ffff, 0x0007ffff, 0x000fffff, + 0x001fffff, 0x003fffff, 0x007fffff, 0x00ffffff, + 0x01ffffff, 0x03ffffff, 0x07ffffff, 0x0fffffff, + 0x1fffffff, 0x3fffffff, 0x7fffffff, 0xffffffff +}; + +static PRUint32 beginMasks[32] = +{ + 0xffffffff, 0xfffffffe, 0xfffffffc, 0xfffffff8, + 0xfffffff0, 0xffffffe0, 0xffffffc0, 0xffffff80, + 0xffffff00, 0xfffffe00, 0xfffffc00, 0xfffff800, + 0xfffff000, 0xffffe000, 0xffffc000, 0xffff8000, + 0xffff0000, 0xfffe0000, 0xfffc0000, 0xfff80000, + 0xfff00000, 0xffe00000, 0xffc00000, 0xff800000, + 0xff000000, 0xfe000000, 0xfc000000, 0xf8000000, + 0xf0000000, 0xe0000000, 0xc0000000, 0x80000000 +}; + + +#if defined(WIN32) + +PRInt32 FastBitSet:: +nextOne(PRInt32 pos) const +{ + ++pos; + register PRUint32 index = pos >> 5; + if (index >= nWords) + return -1; + register PRUint32 offset = pos & 31; + register PRUint32* ptr = &words[index]; + register PRUint32* limit = &words[nWords]; + + PRUint32 word = *ptr++ >> offset; + if (word != 0) + return leastSigBit(word) + (index << 5) + offset; + + for (++index; ptr < limit; ++index) + { + word = *ptr++; + + if (word != 0) + return leastSigBit(word) + (index << 5); + } + return -1; +} + +#elif 0 + +PRInt32 FastBitSet:: +nextOne(PRInt32 pos) const +{ + ++pos; + register PRUint32 index = pos >> 5; + if (index >= nWords) + return -1; + register PRUint32 offset = pos & 31; + register PRUint32* ptr = &words[index]; + register PRUint32* limit = &words[nWords]; + + PRUint32 word = *ptr++ >> offset; + if (word != 0) + { + register PRInt32 pos; + __asm__("bsf %1,%0\n" : "=r" (pos) : "r" (word)); + return pos + (index << 5) + offset; + } + + for (++index; ptr < limit; ++index) + { + word = *ptr++; + + if (word != 0) + { + register PRInt32 pos; + __asm__("bsf %1,%0\n" : "=r" (pos) : "r" (word)); + return pos + (index << 5); + } + } + return -1; +} + +#elif 1 + +PRInt32 FastBitSet:: +nextOne(PRInt32 pos) const +{ + ++pos; + register PRUint32 index = pos >> 5; + if (index >= nWords) + return -1; + register PRUint32 offset = pos & 31; + register PRUint32* ptr = &words[index]; + + PRUint32 word = *ptr++ >> offset; + if (word != 0) + { + while ((word & 1) == 0) + { + offset++; + word >>= 1; + } + return (index << 5) + offset; + } + + register PRUint32* limit = &words[nWords]; + + for (++index; ptr < limit; ++index) + { + word = *ptr++; + if (word != 0) + { + offset = 0; + while ((word & 1) == 0) + { + offset++; + word >>= 1; + } + return (index << 5) + offset; + } + } + return -1; +} + +#else + +PRInt32 FastBitSet:: +nextOne(PRInt32 pos) const +{ + ++pos; + register PRUint32 index = pos >> 5; + if (index >= nWords) + return -1; + register PRUint32 offset = pos & 31; + register PRUint32* ptr = &words[index]; + register PRUint32* limit = &words[nWords]; + + PRUint32 word = *ptr++ >> offset; + for (; offset < 32 && word != 0; offset++) + { + if (word & 1) + return (index << 5) + offset; + word >>= 1; + } + for (++index; ptr < limit; ++index) + { + word = *ptr++; + for (offset = 0; offset < 32 && word != 0; ++offset) + { + if (word & 1) + return (index << 5) + offset; + word >>= 1; + } + } + return -1; +} +#endif + +PRInt32 FastBitSet:: +nextZero(PRInt32 pos) const +{ + ++pos; + register PRUint32 index = pos >> 5; + if (index >= nWords) + return -1; + register PRUint32 offset = pos & 31; + register PRUint32* ptr = &words[index]; + register PRUint32* limit = &words[nWords]; + + PRUint32 word = *ptr++ >> offset; + for (; offset < 32 && word != PRUint32(~0); offset++) + { + if ((word & 1) == 0) + return (index << 5) + offset; + word >>= 1; + } + for (++index; ptr < limit; ++index) + { + word = *ptr++; + for (offset = 0; offset < 32 && word != PRUint32(~0); ++offset) + { + if ((word & 1) == 0) + return (index << 5) + offset; + word >>= 1; + } + } + return -1; +} + +PRInt32 FastBitSet:: +previousOne(PRInt32 pos) const +{ + if (pos == 0) + return -1; + + --pos; + register PRUint32 index = pos >> 5; + if (index >= nWords) + return -1; + register PRUint32 offset = pos & 31; + register PRUint32* ptr = &words[index]; + + PRUint32 word = *ptr-- << (31 - offset); + if (word != 0) + { + while ((word & 0x80000000) == 0) + { + offset--; + word <<= 1; + } + return (index << 5) + offset; + } + + register PRUint32* limit = &words[0]; + + for (--index; ptr >= limit; --index) + { + word = *ptr--; + if (word != 0) + { + offset = 31; + while ((word & 0x80000000) == 0) + { + offset--; + word <<= 1; + } + return (index << 5) + offset; + } + } + return -1; +} + +PRUint32 FastBitSet:: +countOnes() +{ + register PRUint32* ptr = words; + register int size = nWords-1; + register PRUint32 counter = 0; + + do + { + register PRUint32 word = ptr[size]; + if (word != 0) + { + counter += nBit[word & 0xf]; word >>= 4; + counter += nBit[word & 0xf]; word >>= 4; + counter += nBit[word & 0xf]; word >>= 4; + counter += nBit[word & 0xf]; word >>= 4; + counter += nBit[word & 0xf]; word >>= 4; + counter += nBit[word & 0xf]; word >>= 4; + counter += nBit[word & 0xf]; word >>= 4; + counter += nBit[word & 0xf]; + } + } + while (--size >= 0); + return counter; +} + +PRUint32 FastBitSet:: +countOnes(PRUint32 from, PRUint32 to) +{ + register PRUint32* ptr = &words[from >> 5]; + register PRUint32* limit = &words[to >> 5]; + register PRUint32 counter = 0; + + if (ptr == limit) + { + PRUint32 word = (*ptr & endMasks[to & 31]) >> (from & 31); + while (word != PRUint32(0)) + { + if (word & 1) + counter++; + word >>= 1; + } + } + else + { + PRUint32 word = *ptr++ >> (from & 31); + while (word != PRUint32(0)) + { + if (word & 1) + counter++; + word >>= 1; + } + while (ptr < limit) + { + word = *ptr++; + if (word != 0) + { + counter += nBit[word & 0xf]; word >>= 4; + counter += nBit[word & 0xf]; word >>= 4; + counter += nBit[word & 0xf]; word >>= 4; + counter += nBit[word & 0xf]; word >>= 4; + counter += nBit[word & 0xf]; word >>= 4; + counter += nBit[word & 0xf]; word >>= 4; + counter += nBit[word & 0xf]; word >>= 4; + counter += nBit[word & 0xf]; + } + } + word = *ptr & endMasks[to & 31]; + while (word != PRUint32(0)) + { + if (word & 1) + counter++; + word >>= 1; + } + } + + return counter; +} + +bool FastBitSet:: +setAndTest(const FastBitSet& x) +{ + register PRUint32* ptr = words; + register int size = nWords-1; + register PRUint32* src = &x.words[size]; + bool ret = false; + + do + { + register PRUint32 old = ptr[size]; + register PRUint32 modified = old | *src--; + if (old != modified) + ret = true; + ptr[size] = modified; + } + while (--size >= 0); + return ret; +} + +void FastBitSet:: +set(PRUint32 from, PRUint32 to) +{ + register PRUint32* begin = &words[from >> 5]; + register PRUint32* end = &words[to >> 5]; + + PRUint32 beginMask = beginMasks[from & 31]; + PRUint32 endMask = endMasks[to & 31]; + + if (begin == end) + { + *begin |= (beginMask & endMask); + } + else + { + register PRUint32 val = ~0; + *begin++ |= beginMask; + while (begin < end) + *begin++ = val; + *end |= endMask; + } +} + +void FastBitSet:: +clear(PRUint32 from, PRUint32 to) +{ + register PRUint32* begin = &words[from >> 5]; + register PRUint32* end = &words[to >> 5]; + + PRUint32 beginMask = ~beginMasks[from & 31]; + PRUint32 endMask = ~endMasks[to & 31]; + + if (begin == end) + { + *begin &= beginMask | endMask; + } + else + { + register PRUint32 val = 0; + *begin++ &= beginMask; + while (begin < end) + *begin++ = val; + *end &= endMask; + } +} + +#ifdef DEBUG_LOG +void FastBitSet:: +printPrettyOnes(FILE *f) +{ + fprintf(f, "[ "); + for (PRInt32 i = firstOne(); i != -1; i = nextOne(i)) + fprintf(f, "%d ", i); + fprintf(f, "]\n"); +} + +void FastBitSet:: +printPrettyZeros(FILE *f) +{ + fprintf(f, "[ "); + for (PRInt32 i = firstZero(); i != -1; i = nextZero(i)) + fprintf(f, "%d ", i); + fprintf(f, "]\n"); +} + +void FastBitSet:: +printPretty(FILE *f) +{ + fprintf(f, "["); + for (PRUint32 i = 0; i < nBits; i++) + fprintf(f, test(i) ? "1" : "0"); + fprintf(f, "]\n"); +} + +void FastBitSet:: +printDiff(FILE *f, const FastBitSet& x) +{ + fprintf(f, "["); + for (PRUint32 i = 0; i < nBits; i++) + if (test(i) != x.test(i)) + fprintf(f, test(i) ? "-" : "+"); + else + fprintf(f, test(i) ? "1" : "0"); + fprintf(f, "]\n"); +} +#endif diff --git a/ef/Utilities/General/FastBitSet.h b/ef/Utilities/General/FastBitSet.h new file mode 100644 index 000000000000..65ffbcfd4946 --- /dev/null +++ b/ef/Utilities/General/FastBitSet.h @@ -0,0 +1,223 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#ifndef _FAST_BITSET_H_ +#define _FAST_BITSET_H_ + +#include "Fundamentals.h" +#include "Pool.h" + +#define FBS_ROUNDED_WORDS(x) (((x) + 31) >> 5) + +class FastBitSet +{ +private: + Pool* pool; + PRUint32* words; + PRUint32 nWords; + PRUint32 nBits; + bool wordsAreMine; + + inline void reserve(PRUint32 n); + inline void copy(PRUint32* src, PRUint32 size); + +public: + FastBitSet() : pool(NULL), words(0), nWords(0), nBits(0), wordsAreMine(false) {} + FastBitSet(Pool& p) : pool(&p), words(0), nWords(0), nBits(0), wordsAreMine(false) {} + FastBitSet(PRUint32 n) : pool(NULL), words(0), nWords(0), nBits(n), wordsAreMine(false) {sizeToAndClear(n);} + FastBitSet(Pool& p, PRUint32 n) : pool(&p), words(0), nWords(0), nBits(n), wordsAreMine(false) {sizeToAndClear(n);} + FastBitSet(PRUint32* ptr, PRUint32 n) : pool(NULL), words(ptr), nWords(FBS_ROUNDED_WORDS(n)), nBits(n), wordsAreMine(false) {} + FastBitSet(const FastBitSet& x) : pool(x.pool), words(0), nWords(x.nWords), nBits(x.nBits), wordsAreMine(false) {sizeTo(x.nBits); copy(x.words, x.nWords);} + ~FastBitSet() {if (words && wordsAreMine) delete words;} + + inline PRUint32* getWords() {return words;} + + inline void copyFrom(const FastBitSet& x) {copy(x.words, x.nWords);} + inline void operator = (const FastBitSet& x) {sizeTo(x.nBits); copy(x.words, x.nWords);} + inline FastBitSet& operator |= (const FastBitSet& x); + inline FastBitSet& operator &= (const FastBitSet& x); + inline FastBitSet& operator -= (const FastBitSet& x); + inline friend bool operator == (const FastBitSet& x, const FastBitSet& y); + inline friend bool operator != (const FastBitSet& x, const FastBitSet& y); + + inline void sizeTo(PRUint32 n) {PR_ASSERT(n); nBits = n; if (nWords < FBS_ROUNDED_WORDS(n)) reserve(n);} + inline void sizeTo(Pool& p, PRUint32 n) {PR_ASSERT(n); pool = &p; nBits = n; if (nWords < FBS_ROUNDED_WORDS(n)) reserve(n);} + inline void sizeToAndClear(PRUint32 n) {PR_ASSERT(n); sizeTo(n); clear();} + inline void sizeToAndClear(Pool& p, PRUint32 n) {PR_ASSERT(n); sizeTo(p, n); clear();} + + inline bool empty(); + + inline void clear(); + inline void clear(PRUint32 n); + void clear(PRUint32 from, PRUint32 to); + + inline void set(); + inline void set(PRUint32 n); + void set(PRUint32 from, PRUint32 to); + + bool setAndTest(const FastBitSet& x); + + inline bool test(PRUint32 n) const; + + inline PRInt32 firstOne() const {return nextOne(-1);} + PRInt32 nextOne(PRInt32 pos) const; + inline PRInt32 lastOne() const {return previousOne(nBits);} + PRInt32 previousOne(PRInt32 pos) const; + + inline PRInt32 firstZero() const {return nextZero(-1);} + PRInt32 nextZero(PRInt32 pos) const; + + PRUint32 countOnes(); + PRUint32 countOnes(PRUint32 from, PRUint32 to); + inline PRUint32 countZeros() {return nBits - countOnes();} + +#ifdef DEBUG_LOG + void printPretty(FILE *f); + void printDiff(FILE *f, const FastBitSet& x); + void printPrettyOnes(FILE *f); + void printPrettyZeros(FILE *f); +#endif +}; + +inline bool +operator == (const FastBitSet& x, const FastBitSet& y) +{ + register PRUint32* xWords = x.words; + register PRUint32* yWords = y.words; + register int size = x.nWords-1; + + do if (xWords[size] != yWords[size]) return false; while (--size >= 0); + return true; +} + +inline bool +operator != (const FastBitSet& x, const FastBitSet& y) +{ + return !(x==y); +} + +inline FastBitSet& FastBitSet::operator |= (const FastBitSet& x) +{ + register PRUint32* xWords = words; + register PRUint32* yWords = x.words; + register int size = nWords - 1; + do xWords[size] |= yWords[size]; while (--size >= 0); + return *this; +} + +inline FastBitSet& FastBitSet::operator &= (const FastBitSet& x) +{ + register PRUint32* xWords = words; + register PRUint32* yWords = x.words; + register int size = nWords - 1; + do xWords[size] &= yWords[size]; while (--size >= 0); + return *this; +} + +inline FastBitSet& FastBitSet::operator -= (const FastBitSet& x) +{ + register PRUint32* xWords = words; + register PRUint32* yWords = x.words; + register int size = nWords - 1; + do xWords[size] &= ~yWords[size]; while (--size >= 0); + return *this; +} + +inline bool FastBitSet::test(PRUint32 n) const +{ + register PRUint8 shift = n & 31; + register PRUint32 mask = (1 << shift); + if ((words[n >> 5] & mask) > 0) + return true; + else + return false; +} + +inline void FastBitSet::set(PRUint32 n) +{ + register PRUint8 shift = n & 31; + register PRUint32 mask = (1 << shift); + words[n >> 5] |= mask; +} + +inline void FastBitSet::clear(PRUint32 n) +{ + register PRUint8 shift = n & 31; + register PRUint32 mask = (1 << shift); + mask = ~mask; + words[n >> 5] &= mask; +} + +inline bool FastBitSet::empty() +{ + register PRUint32* ptr = words; + register int size = nWords-1; + do + if (ptr[size] != 0) + return false; + while (--size >= 0); + + return true; +} + +inline void FastBitSet::set() +{ + register PRUint32* ptr = words; + register PRUint32 val = ~0; + register int size = nWords-1; + do ptr[size] = val; while (--size >= 0); +} + +inline void FastBitSet::clear() +{ + register PRUint32* ptr = words; + register PRUint32 val = 0; + register int size = nWords-1; + do ptr[size] = val; while (--size >= 0); +} + +inline void FastBitSet::reserve(PRUint32 n) +{ + if (words && wordsAreMine) delete words; + nWords = FBS_ROUNDED_WORDS(n); + if (pool != NULL) + { + words = new(*pool) PRUint32[nWords]; + wordsAreMine = false; + } + else + { + words = new PRUint32[nWords]; + wordsAreMine = true; + } +} + +inline void FastBitSet:: +copy(PRUint32* src, PRUint32 size) +{ + PR_ASSERT(size <= nWords); + register PRUint32* ptr = words; + register int len = size-1; + src = &src[len]; + do ptr[len] = *src--; while (--len >= 0); + if (size < nWords) + do ptr[size] = 0; while (++size < nWords); +} + + +#endif /* _FAST_BITSET_H_ */ diff --git a/ef/Utilities/General/FastHashTable.h b/ef/Utilities/General/FastHashTable.h new file mode 100644 index 000000000000..c8233c9ac7e0 --- /dev/null +++ b/ef/Utilities/General/FastHashTable.h @@ -0,0 +1,48 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#ifndef _FAST_HASH_TABLE_H_ +#define _FAST_HASH_TABLE_H_ + +#include "HashTable.h" + +/* A faster version of class Hashtable, which makes the assumption that + * all keys are interned somewhere, ie., that there is only one copy + * of each unique string in the universe. + */ + +/* Operations on HashTable keys, when keys are interned strings */ +struct InternedStringKeyOps { + static bool equals(const char * userKey, const char * hashTableKey) { + return (userKey == hashTableKey); + } + + static char *copyKey(Pool &/*pool*/, const char * userKey) { + return const_cast(userKey); + } + + static Uint32 hashCode(const char * userKey) { + return reinterpret_cast(userKey); + } +}; + +template class FastHashTable : public HashTable { +public: + FastHashTable(Pool &p) : HashTable(p) { } +}; + +#endif /* _FAST_HASH_TABLE_H_ */ diff --git a/ef/Utilities/General/Fifo.h b/ef/Utilities/General/Fifo.h new file mode 100644 index 000000000000..e4ac6248a2de --- /dev/null +++ b/ef/Utilities/General/Fifo.h @@ -0,0 +1,71 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#ifndef _FIFO_H_ +#define _FIFO_H_ + +#include "Fundamentals.h" + +template +class Fifo +{ +private: + N* begin; + N* limit; + N* first; + N* last; + +public: + Fifo(Uint32 size) {begin = first = last = new N[size]; limit = &begin[size];} + ~Fifo() {delete begin;} + + N& get(); // get at first element inserted. + void put(N n); // append an element. + bool empty() const {return (last == first);} // is the fifo empty ? + Uint32 count() const; // number of elements in the fifo. +}; + +template inline N& +Fifo::get() +{ + assert(last != first); + N* pos = first++; + if (first == limit) + first = begin; + return *pos; +} + +template inline void +Fifo::put(N n) +{ + *last++ = n; + if (last == limit) + last = begin; + assert(last != first); +} + +template inline Uint32 +Fifo::count() const +{ + if (last >= first) + return Uint32(last - first); + else + return Uint32(limit - first) + Uint32(last - begin); +} + +#endif /* _FIFO_H_ */ diff --git a/ef/Utilities/General/FloatUtils.cpp b/ef/Utilities/General/FloatUtils.cpp new file mode 100644 index 000000000000..691ea4ba3e3c --- /dev/null +++ b/ef/Utilities/General/FloatUtils.cpp @@ -0,0 +1,201 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#include "FloatUtils.h" +#include // For fmod() + +#ifdef WIN32 +#include +Flt32 floatPositiveInfinity; +Flt64 doublePositiveInfinity; +Flt32 floatNegativeInfinity; +Flt64 doubleNegativeInfinity; +Flt32 floatNegativeZero; +Flt64 doubleNegativeZero; +Flt32 floatNaN; +Flt64 doubleNaN; + +struct DummyInit +{ + DummyInit(Flt32 fZero, Flt64 dZero); +}; + +DummyInit dummyFloatInit(0.0f, 0.0); + +DummyInit::DummyInit(Flt32, Flt64) +{ + floatPositiveInfinity = std::numeric_limits::infinity(); + doublePositiveInfinity = std::numeric_limits::infinity(); + floatNegativeInfinity = -std::numeric_limits::infinity(); + doubleNegativeInfinity = -std::numeric_limits::infinity(); + floatNegativeZero = -1.0f/floatPositiveInfinity; + doubleNegativeZero = -1.0/doublePositiveInfinity; + floatNaN = std::numeric_limits::quiet_NaN(); + doubleNaN = std::numeric_limits::quiet_NaN(); +} + +#elif defined __GNUC__ +Flt32 floatPositiveInfinity; +Flt64 doublePositiveInfinity; +Flt32 floatNegativeInfinity; +Flt64 doubleNegativeInfinity; +Flt32 floatNaN; +Flt64 doubleNaN; + +struct DummyInit +{ + DummyInit(Flt32 fZero, Flt64 dZero); +}; + +DummyInit dummyFloatInit(0.0f, 0.0); + +DummyInit::DummyInit(Flt32 fZero, Flt64 dZero) +{ + floatPositiveInfinity = 1.0f/fZero; + doublePositiveInfinity = 1.0/dZero; + floatNegativeInfinity = -1.0f/fZero; + doubleNegativeInfinity = -1.0/dZero; + floatNaN = fZero/fZero; + doubleNaN = dZero/dZero; +} +#endif + +// Wrapper around fmod() is necessary because some implementations doesn't +// handle infinities properly, e.g. MSVC. +double javaFMod(double dividend, double divisor) { + if (isNaN(dividend) || isNaN(divisor) || isInfinite(dividend) || (divisor == 0.0)) + return doubleNaN; + + if ((dividend == 0.0) || isInfinite(divisor)) + return dividend; + + return fmod(dividend, divisor); +} + +Int32 flt64ToInt32(Flt64 d) +{ + if (isNaN(d)) + return 0; + if (d >= (Flt64)(Int32)0x7fffffff) + return 0x7fffffff; + if (d <= (Flt64)(Int32)0x80000000) + return 0x80000000; + return (Int32)d; +} + +Int64 flt64ToInt64(Flt64 d) +{ + if (isNaN(d)) + return CONST64(0); + if (d >= (Flt64)CONST64(0x7fffffffffffffff)) + return CONST64(0x7fffffffffffffff); + if (d <= (Flt64)CONST64(0x8000000000000000)) + return CONST64(0x8000000000000000); + return (Int64)d; +} + +#ifdef DEBUG +template +void testFloat(T myNaN, T myNegZero, T myPosInf, T myNegInf) +{ + T plusZero = 0.0; + T minusZero = myNegZero; + T plusOne = 1.0; + T plusInf = plusOne/plusZero; + T minusInf = plusOne/minusZero; + T nan = plusInf + minusInf; + + assert(plusZero == minusZero); + assert(plusZero != plusOne); + assert(plusInf > 0.0); + assert(minusInf < 0.0); + assert(!(nan == 0.0)); + assert(!(nan == nan)); + assert(!(nan < nan)); + assert(!(nan > nan)); + assert(!(myNaN == 0.0)); + assert(!(myNaN == myNaN)); + assert(!(myNaN < myNaN)); + assert(!(myNaN > myNaN)); + assert(plusInf == myPosInf); + assert(minusInf == myNegInf); + + assert(isPositiveZero(plusZero)); + assert(!isNegativeZero(plusZero)); + assert(!isNaN(plusZero)); + assert(!isPositiveZero(minusZero)); + assert(isNegativeZero(minusZero)); + assert(!isNaN(minusZero)); + assert(!isPositiveZero(plusOne)); + assert(!isNegativeZero(plusOne)); + assert(!isNaN(plusOne)); + assert(!isPositiveZero(plusInf)); + assert(!isNegativeZero(plusInf)); + assert(!isNaN(plusInf)); + assert(!isPositiveZero(minusInf)); + assert(!isNegativeZero(minusInf)); + assert(!isNaN(minusInf)); + assert(!isPositiveZero(nan)); + assert(!isNegativeZero(nan)); + assert(isNaN(nan)); + assert(!isPositiveZero(myNaN)); + assert(!isNegativeZero(myNaN)); + assert(isNaN(myNaN)); + + assert(isPositiveZero(plusZero + minusZero)); + assert(!isNegativeZero(plusZero + minusZero)); + assert(!isNaN(plusZero + minusZero)); +} + + +static bool testGt(double a, double b) +{ + return a>b; +} + +static bool testGe(double a, double b) +{ + return a>=b; +} + +static bool testLt(double a, double b) +{ + return a doubleNaN)); + assert(!(doubleNaN >= doubleNaN)); + assert(doubleNaN != doubleNaN); + testFloat(floatNaN, floatNegativeZero, floatPositiveInfinity, floatNegativeInfinity); + testFloat(doubleNaN, doubleNegativeZero, doublePositiveInfinity, doubleNegativeInfinity); +} +#endif diff --git a/ef/Utilities/General/FloatUtils.h b/ef/Utilities/General/FloatUtils.h new file mode 100644 index 000000000000..5ef9ee4e8f2c --- /dev/null +++ b/ef/Utilities/General/FloatUtils.h @@ -0,0 +1,121 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#ifndef FLOATUTILS_H +#define FLOATUTILS_H + +#include "Fundamentals.h" + +// Wrapper around fmod() is necessary because some implementations doesn't +// handle infinities properly, e.g. MSVC. +double javaFMod(double dividend, double divisor); + +// Simple queries on IEEE floating-point values. +// It's amazing that the standard C headers don't have these operations +// standardized... + +#ifdef WIN32 + // Microsoft's compiler is quite buggy when it comes to handling floating + // point zeros and NaNs, so we need workarounds here... + extern Flt32 floatPositiveInfinity; + extern Flt64 doublePositiveInfinity; + extern Flt32 floatNegativeInfinity; + extern Flt64 doubleNegativeInfinity; + extern Flt32 floatNegativeZero; + extern Flt64 doubleNegativeZero; + extern Flt32 floatNaN; + extern Flt64 doubleNaN; +#elif defined __GNUC__ + // GCC is also broken when it comes to immediate floating point expressions. + extern Flt32 floatPositiveInfinity; + extern Flt64 doublePositiveInfinity; + extern Flt32 floatNegativeInfinity; + extern Flt64 doubleNegativeInfinity; + const Flt32 floatNegativeZero = -0.0f; + const Flt64 doubleNegativeZero = -0.0; + extern Flt32 floatNaN; + extern Flt64 doubleNaN; +#else + const Flt32 floatPositiveInfinity = 1.0f/0.0f; + const Flt64 doublePositiveInfinity = 1.0/0.0; + const Flt32 floatNegativeInfinity = -1.0f/0.0f; + const Flt64 doubleNegativeInfinity = -1.0/0.0; + const Flt32 floatNegativeZero = -0.0f; + const Flt64 doubleNegativeZero = -0.0; + const Flt32 floatNaN = 0.0f/0.0f; + const Flt64 doubleNaN = 0.0/0.0; +#endif + +inline bool isPositiveZero(Flt32 x); +inline bool isPositiveZero(Flt64 x); +inline bool isNegativeZero(Flt32 x); +inline bool isNegativeZero(Flt64 x); +inline bool isNaN(Flt32 x); +inline bool isNaN(Flt64 x); + +DEBUG_ONLY(void testFloatUtils();) + +// Conversions between integral and floating point types +// These may need to be defined specially on platforms that handle rounding +// or out-of-range values weirdly. + +// Rounds to nearest when result is inexact. +inline Flt32 int32ToFlt32(Int32 i) {return (Flt32)i;} +inline Flt64 int32ToFlt64(Int32 i) {return (Flt64)i;} +inline Flt32 int64ToFlt32(Int64 l) {return (Flt32)l;} +inline Flt64 int64ToFlt64(Int64 l) {return (Flt64)l;} + +// Ordinary values round towards zero. +// NaN becomes zero. +// -inf or values below -2^31 (or -2^63) become -2^31 (or -2^63). +// +inf or values above 2^31-1 (or 2^63-1) become 2^31-1 (or 2^63-1). +extern Int32 flt64ToInt32(Flt64 d); +extern Int64 flt64ToInt64(Flt64 d); +inline Int32 flt32ToInt32(Flt32 f) {return flt64ToInt32((Flt64)f);} +inline Int64 flt32ToInt64(Flt32 f) {return flt64ToInt64((Flt64)f);} + + + +// --- INLINES ---------------------------------------------------------------- + + +inline bool isPositiveZero(Flt32 x) + {return *(Uint32 *)&x == 0x00000000;} + +inline bool isPositiveZero(Flt64 x) + {return *(Uint64 *)&x == CONST64(0x0000000000000000);} + +inline bool isNegativeZero(Flt32 x) + {return *(Uint32 *)&x == 0x80000000;} + +inline bool isNegativeZero(Flt64 x) + {return *(Uint64 *)&x == CONST64(0x8000000000000000);} + +inline bool isNaN(Flt32 x) + {return (~(*(Uint32 *)&x) & 0x7fc00000) == 0;} + +inline bool isNaN(Flt64 x) + {return (~(*(Uint64 *)&x) & CONST64(0x7ff8000000000000)) == 0;} + +inline bool isInfinite(Flt32 v) + {return v == floatPositiveInfinity || v == floatNegativeInfinity;} + +inline bool isInfinite(Flt64 v) + {return v == doublePositiveInfinity || v == doubleNegativeInfinity;} + +#endif diff --git a/ef/Utilities/General/Fundamentals.h b/ef/Utilities/General/Fundamentals.h new file mode 100644 index 000000000000..cf4faedd1fa7 --- /dev/null +++ b/ef/Utilities/General/Fundamentals.h @@ -0,0 +1,246 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#ifndef FUNDAMENTALS_H +#define FUNDAMENTALS_H + +#include +#include "Exports.h" +#include "CatchAssert.h" + +#include "prlong.h" +#include "prlog.h" + +#if defined(DEBUG) || defined(DEBUG_LOG) + #include +#endif + +#ifndef USE_GENERATEDFILES +#define USE_GENERATEDFILES 1 +#endif + +#ifdef NO_NSPR +#include "Nonspr.h" +#endif + + +// Turn this on to have the internal addr values be two-word structures that permit +// relocations of the generated code's references to objects. +#ifndef BATCH_COMPILATION + #define BATCH_COMPILATION 1 +#endif + +// DEBUG_LOG controls whether we compile in the routines to disassemble and dump +// internal compiler state to a file or stdout. These are useful even in nondebug +// builds but should not be present in release builds. +#if defined(DEBUG) && !defined(DEBUG_LOG) + #define DEBUG_LOG +#endif + + +// ---------------------------------------------------------------------------- +// Compiler idiosyncrasies + +// Metrowerks doesn't recognize the typename keyword yet. +#ifdef __MWERKS__ + #define typename +#endif + +// MANUAL_TEMPLATES means we instantiate all templates manually. +#ifdef __GNUC__ + #define MANUAL_TEMPLATES +#endif + +// +// Compilers align bools and enums inside structures differently. +// Some are nice enough to allocate only as many bytes as needed; +// others always store these as entire words. On the latter we need to use +// bit fields to persuade them to store these as bytes or halfwords. +// We don't use bit fields on the former because: +// 1. Some compilers generate much less efficient code for bit fields, +// 2. Some compilers (esp. Metrowerks) generate buggy code for bit fields. +// +// Use ENUM_8 after an 8-bit enum field declaration in a structure +// Use ENUM_16 after a 16-bit enum field declaration in a structure +// Use BOOL_8 after an 8-bit bool field declaration in a structure +// Use CHAR_8 after a char field declaration (if it should be packed with one of the above) +// Use SHORT_16 after a short field declaration (if it should be packed with one of the above) +// +// The last two macros are only necessary when packing a char or a short in the same +// word as a bool or enum; some compilers don't put fields with bit widths in the +// same word as fields without bit widths. +// +#if defined __MWERKS__ || defined WIN32 + #define ENUM_8 + #define ENUM_16 + #define BOOL_8 + #define CHAR_8 + #define SHORT_16 +#else + #define ENUM_8 :8 + #define ENUM_16 :16 + #define BOOL_8 :8 + #define CHAR_8 :8 + #define SHORT_16 :16 +#endif + + +// Use the following to make 64-bit integer constants +#ifdef WIN32 + #define CONST64(val) val ## i64 +#else + #define CONST64(val) val ## LL +#endif + + +// ---------------------------------------------------------------------------- +// Universal types + +#ifdef __GNUC__ + typedef unsigned int uint; +#endif +typedef char *ptr; +typedef const char *cptr; + +typedef PRInt8 Int8; +typedef PRUint8 Uint8; +typedef PRInt16 Int16; +typedef PRUint16 Uint16; +typedef PRInt32 Int32; +typedef PRUint32 Uint32; +typedef PRInt64 Int64; +typedef PRUint64 Uint64; + +typedef float Flt32; // 32-bit IEEE floating point +typedef PRFloat64 Flt64; // 64-bit IEEE floating point + +// ---------------------------------------------------------------------------- +// Debugging + +// Use DEBUG_ONLY around function arguments that are only used in debug builds. +// This avoids unused variable warnings in nondebug builds. +#ifdef DEBUG + #define DEBUG_ONLY(arg) arg + #define NONDEBUG_ONLY(arg) +#else + #define DEBUG_ONLY(arg) + #define NONDEBUG_ONLY(arg) arg +#endif + +#ifdef DEBUG_LOG + #define DEBUG_LOG_ONLY(arg) arg +#else + #define DEBUG_LOG_ONLY(arg) +#endif + +#ifdef DEBUG + #define trespass(string) { fprintf(stderr, "%s", string); assert(false); } +#else + #define trespass(string) assert(!string) +#endif + +// ---------------------------------------------------------------------------- +// Tiny pieces of STL +// These can be replaced by the real STL if it happens to be available +// (but make sure that the real STL has these as inlines!). + +#ifndef STL +template +inline Out copy(In srcBegin, In srcEnd, Out dst) +{ + while (srcBegin != srcEnd) { + *dst = *srcBegin; + ++srcBegin; + ++dst; + } + return dst; +} + +template +inline void fill(Out first, Out last, T value) +{ + while (first != last) + *first++ = value; +} + +template +inline void fill_n(Out first, Uint32 n, T value) +{ + while (n--) + *first++ = value; +} +#endif + + +// ---------------------------------------------------------------------------- +// Non-STL useful templates + +template +inline Out move(In srcBegin, In srcEnd, Out dst) +{ + while (srcBegin != srcEnd) { + dst->move(*srcBegin); + ++srcBegin; + ++dst; + } + return dst; +} + + +// An abstract base class for representing closures of functions with no arguments. +template +struct Function0 +{ + virtual Result operator()() = 0; +}; + +// An abstract base class for representing closures of functions with one argument. +template +struct Function1 +{ + virtual Result operator()(Arg arg) = 0; +}; + +// An abstract base class for representing closures of functions with two arguments. +template +struct Function2 +{ + virtual Result operator()(Arg1 arg1, Arg2 arg2) = 0; +}; + +// An abstract base class for representing closures of functions with three arguments. +template +struct Function3 +{ + virtual Result operator()(Arg1 arg1, Arg2 arg2, Arg3 arg3) = 0; +}; + + +// ---------------------------------------------------------------------------- +// Pooled memory allocation + +inline void *operator new(size_t, void* ptr) {return ptr;} + +class Pool; + +NS_EXTERN void *operator new(size_t size, Pool &pool); +#if !defined __MWERKS__ && !defined WIN32 + NS_EXTERN void *operator new[](size_t size, Pool &pool); + NS_EXTERN void *operator new[](size_t size); +#endif +#endif diff --git a/ef/Utilities/General/GraphUtils.h b/ef/Utilities/General/GraphUtils.h new file mode 100644 index 000000000000..67fc9e42cb9b --- /dev/null +++ b/ef/Utilities/General/GraphUtils.h @@ -0,0 +1,342 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#ifndef GRAPHUTILS_H +#define GRAPHUTILS_H + +#include "Fundamentals.h" + +template +struct SearchStackEntry +{ + Successor *next; // Next child to be searched at this level of the graph + Successor *limit; // Last child+1 to be searched at this level of the graph +}; + + +// +// Search and mark all reachable nodes of the directed graph with the given root. +// The graph must have no more than maxNNodes nodes reachable from the root. +// The stack argument must be a preallocated temporary array of maxNNodes entries of +// type SearchStackEntry. +// +// The NodeRef class is a way to refer to nodes in the graph (NodeRefs may be +// pointers to nodes, node indices, etc.). +// The SearchParams is a helper class that graphSimpleSearch uses to access the +// contents of graph nodes. SearchParams must support the following types and +// methods (static or dynamic): +// +// typedef Successor; +// typedef NodeRef; +// +// Successor *getSuccessorsBegin(NodeRef n); +// Successor *getSuccessorsEnd(NodeRef n); +// Return the bounds of an array of Successors of node n. +// +// NodeRef getNodeRef(Successor &s); +// Return the node to which the Successor s refers. +// +// bool isMarked(NodeRef n); +// void setMarked(NodeRef n); +// Each node in the graph is either marked or unmarked. +// All nodes should be in the unmarked state when graphSimpleSearch is called; +// graphSimpleSearch will not traverse any marked nodes it encounters. The +// setMarked method changes the state of a node to marked. Every node +// reachable from the root will be marked when graphSimpleSearch exits. +// setMarked is only called on unmarked nodes. +// +template +void graphSimpleSearch(SearchParams &searchParams, Successor root, Uint32 DEBUG_ONLY(maxNNodes), SearchStackEntry *stack) +{ + #ifdef DEBUG + SearchStackEntry *stackEnd = stack + maxNNodes; + #endif + + SearchStackEntry *sp = stack; + + // Prepare to visit the root. + Successor *n = &root; + Successor *l = &root + 1; + + while (true) { + if (n == l) { + // We're done with all successors between n and l, so pop up one level. + // Finish when we've marked the root. + if (sp == stack) + break; + --sp; + n = sp->next; + l = sp->limit; + + } else { + // We still have to visit more successors between n and l. Mark the + // next successor and advance n. + typename SearchParams::NodeRef node = searchParams.getNodeRef(*n++); + if (!searchParams.isMarked(node)) { + // Mark the successor, saving the current place on the stack. + searchParams.setMarked(node); + assert(sp < stackEnd); + sp->next = n; + sp->limit = l; + sp++; + n = searchParams.getSuccessorsBegin(node); + l = searchParams.getSuccessorsEnd(node); + } + } + } +} + + +// +// Search, mark, and count all reachable nodes of the directed graph with +// the given root (which may be null). The graph must have no more than +// maxNNodes nodes reachable from the root. The stack argument must be a +// preallocated temporary array of maxNNodes entries of type +// SearchStackEntry. +// +// This function returns the number of nodes reached, including the root. +// +// The NodeRef class is a way to refer to nodes in the graph (NodeRefs may be +// pointers to nodes, node indices, etc.). +// The SearchParams is a helper class that graphSearch uses to access the +// contents of graph nodes. SearchParams must support the following types and +// methods (static or dynamic): +// +// typedef Successor; +// typedef NodeRef; +// +// Successor *getSuccessorsBegin(NodeRef n); +// Successor *getSuccessorsEnd(NodeRef n); +// Return the bounds of an array of Successors of node n. +// +// bool isNull(Successor &s); +// Returns true if n is null. +// +// NodeRef getNodeRef(Successor &s); +// Return the node to which the Successor s refers. +// +// bool isMarked(NodeRef n); +// void setMarked(NodeRef n); +// Each node in the graph is either marked or unmarked. +// All nodes should be in the unmarked state when graphSearch is called; +// graphSearch will not traverse any marked nodes it encounters. The +// setMarked method changes the state of a node to marked. Every node +// reachable from the root will be marked when graphSearch exits. +// setMarked is only called on unmarked nodes. +// +// void notePredecessor(NodeRef n); +// This method is called on node n once for each time n is a successor +// of any node or the root. The SearchParams class may use this method to +// count predecessors of node n. +// +template +Uint32 graphSearch(SearchParams &searchParams, Successor &root, Uint32 DEBUG_ONLY(maxNNodes), SearchStackEntry *stack) +{ + #ifdef DEBUG + SearchStackEntry *stackEnd = stack + maxNNodes; + #endif + + Uint32 nNodes = 0; + if (!searchParams.isNull(root)) { + SearchStackEntry *sp = stack; + + // Prepare to visit the root. + Successor *n = &root; + Successor *l = &root + 1; + + while (true) { + if (n == l) { + // We're done with all successors between n and l, so pop up one level. + // Finish when we've marked the root. + if (sp == stack) + break; + --sp; + n = sp->next; + l = sp->limit; + + } else { + // We still have to visit more successors between n and l. Mark the + // next successor and advance n. + typename SearchParams::NodeRef node = searchParams.getNodeRef(*n++); + searchParams.notePredecessor(node); + if (!searchParams.isMarked(node)) { + // Mark the successor, saving the current place on the stack. + nNodes++; + searchParams.setMarked(node); + assert(sp < stackEnd); + sp->next = n; + sp->limit = l; + sp++; + n = searchParams.getSuccessorsBegin(node); + l = searchParams.getSuccessorsEnd(node); + } + } + } + } + assert(nNodes <= maxNNodes); + return nNodes; +} + + +// +// A specialized version of graphSearch for graphs with a designated end node. +// The end node must have no successors. There may be other nodes with no successors. +// Unlike all other nodes, which must be reachable from the root, the end node does +// not have to be reachable from the root; if it's not reachable, it will have no +// predecessors. +// +// The end node may be the root node, in which case the graph consists of exactly +// one node. +// +// graphSearchWithEnd guarantees that the end node will be marked and counted, +// even if it is not reachable from the root. +// +template +Uint32 graphSearchWithEnd(SearchParams &searchParams, Successor &root, Successor &end, + Uint32 maxNNodes, SearchStackEntry *stack) +{ + assert(!searchParams.isNull(end)); + typename SearchParams::NodeRef endNode = searchParams.getNodeRef(end); + assert(searchParams.getSuccessorsBegin(endNode) == searchParams.getSuccessorsEnd(endNode)); + searchParams.setMarked(endNode); + return 1 + graphSearch(searchParams, root, maxNNodes, stack); +} + + +// +// Perform a depth-first search of the directed graph with the given root +// (which may be null). This search will assign a unique integer between 0 +// and nNodes-1 to each node in the graph according to the graph's depth- +// first ordering (see [ASU86], page 661). The graph must have exactly nNodes +// nodes reachable from the root. The stack argument must be a preallocated +// temporary array of nNodes entries of type SearchStackEntry. +// +// The NodeRef class is a way to refer to nodes in the graph (NodeRefs may be +// pointers to nodes, node indices, etc.). +// The DFSParams is a helper class that depthFirstSearch uses to access the +// contents of graph nodes. DFSParams must support the following types and +// methods (static or dynamic): +// +// typedef Successor; +// typedef NodeRef; +// +// Successor *getSuccessorsBegin(NodeRef n); +// Successor *getSuccessorsEnd(NodeRef n); +// Return the bounds of an array of Successors of node n. +// +// bool isNull(Successor &s); +// Returns true if n is null. +// +// NodeRef getNodeRef(Successor &s); +// Return the node to which the Successor s refers. +// +// bool isUnvisited(NodeRef n); +// bool isNumbered(NodeRef n); +// void setVisited(NodeRef n); +// void setNumbered(NodeRef n, Int32 i); +// Each node in the graph is in one of three states: +// unvisited, visited, or numbered. +// All nodes should be in the unvisited state when depthFirstSearch is +// called. The setVisited and setNumbered methods change the state of +// a node to visited or numbered; i is the node's depth-first ordering +// index. Every node will be numbered when depthFirstSearch exits. +// setVisited is only called on an unvisited node. setNumbered is only +// called on an unvisited or visited node. +// isUnvisited and isNumbered query the current state of a node. +// +// void noteIncomingBackwardEdge(NodeRef n); +// This method is called on node n once for each time n is the target +// of any backward edge. The DFSParams class may use this method to +// determine if the graph contains cycles and which nodes are cycle +// headers. +// +template +void depthFirstSearch(DFSParams &dfsParams, Successor &root, Uint32 nNodes, SearchStackEntry *stack) +{ + #ifdef DEBUG + SearchStackEntry *stackEnd = stack + nNodes; + #endif + + if (!dfsParams.isNull(root)) { + SearchStackEntry *sp = stack; + + // Prepare to visit the root. + Successor *n = &root; + Successor *l = &root + 1; + + while (true) { + if (n == l) { + // We're done with all successors between n and l, so number the + // source node (which is on the stack) and pop up one level. + // Finish when we've marked the root. + if (sp == stack) + break; + --sp; + n = sp->next; + l = sp->limit; + dfsParams.setNumbered(dfsParams.getNodeRef(n[-1]), --nNodes); + + } else { + // We still have to visit more successors between n and l. Visit the + // next successor and advance n. + typename DFSParams::NodeRef node = dfsParams.getNodeRef(*n++); + if (dfsParams.isUnvisited(node)) { + // Visit the successor, saving the current place on the stack. + dfsParams.setVisited(node); + assert(sp < stackEnd); + sp->next = n; + sp->limit = l; + sp++; + n = dfsParams.getSuccessorsBegin(node); + l = dfsParams.getSuccessorsEnd(node); + } else + // We have a cycle if we ever encounter a successor that has been visited + // but not yet numbered. + if (!dfsParams.isNumbered(node)) + dfsParams.noteIncomingBackwardEdge(node); + } + } + } + assert(nNodes == 0); +} + + +// +// A specialized version of depthFirstSearch for graphs with a designated end node. +// The end node must have no successors. There may be other nodes with no successors. +// Unlike all other nodes, which must be reachable from the root, the end node does +// not have to be reachable from the root; if it's not reachable, it will have no +// predecessors. +// +// The end node may be the root node, in which case the graph consists of exactly +// one node. +// +// depthFirstSearchWithEnd guarantees that the end node will be assigned the number nNodes-1. +// +template +void depthFirstSearchWithEnd(DFSParams &dfsParams, Successor &root, Successor &end, + Uint32 nNodes, SearchStackEntry *stack) +{ + assert(!dfsParams.isNull(end)); + typename DFSParams::NodeRef endNode = dfsParams.getNodeRef(end); + assert(dfsParams.getSuccessorsBegin(endNode) == dfsParams.getSuccessorsEnd(endNode)); + dfsParams.setNumbered(endNode, --nNodes); + depthFirstSearch(dfsParams, root, nNodes, stack); +} + +#endif diff --git a/ef/Utilities/General/HashTable.h b/ef/Utilities/General/HashTable.h new file mode 100644 index 000000000000..896a1a3878fe --- /dev/null +++ b/ef/Utilities/General/HashTable.h @@ -0,0 +1,260 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#ifndef _HASH_TABLE_ +#define _HASH_TABLE_ + +#include // for strdup, strcmp + +#include "Fundamentals.h" +#include "DoublyLinkedList.h" +#include "Pool.h" +#include "Vector.h" + +#define _NBUCKETS_ 128 + +/* Operations on HashTable keys, when the keys are (non-interned) strings */ +struct StringKeyOps { + static bool equals(const char * userKey, const char * hashTableKey) { + return (strcmp(userKey, hashTableKey) == 0); + } + + static char *copyKey(Pool &pool, const char * userKey) { + char *hashTableKey = new (pool) char[strlen(userKey)+1]; + strcpy(hashTableKey, userKey); + return hashTableKey; + } + + static Uint32 hashCode(const char * userKey) { + const char *ptr; + Uint32 hashCode; + + for (hashCode = 0, ptr = userKey; *ptr != '\0'; ptr++) { + hashCode = (hashCode * 7) + *ptr; + } + return hashCode; + } +}; + +typedef const char * DefaultKeyClass; + +template +struct HashTableEntry : public DoublyLinkedEntry > { + HashTableEntry(KEY k, N val):key(k),value(val) {}; + KEY key; + N value; +}; + +template +class HashTable { +protected: + /* Adds key and returns pointer to interned version of the key */ + KEY add(KEY key, const N &value, int hashIndex); + + /* if found, returns the interned version of the key, NULL otherwise. + * Returns hash index of bucket(key) via hashIndex, and + * if value is non-null, returns matched value on success + */ + KEY get(KEY key, N *value, int &hashIndex) const; + + /* If found, sets the value corresponding to given key to N. Does + * nothing if an entry corresponding to key was not found. + */ + void set(KEY key, N *value, int hashIndex); + + /* Function that will compare user's key to key in hash-table. + * equals returns true if the userKey is "equal" to hashTableKey, + * false otherwise. + */ + + Uint32 hashIndexOf(KEY key) const; + + DoublyLinkedList > buckets[_NBUCKETS_]; + Pool &pool; /* Pool used to allocate hash-table entries */ + +private: + HashTable(const HashTable&); // Copying forbidden + void operator=(const HashTable&); // Copying forbidden + +public: + explicit HashTable(Pool &p): pool(p) {} + + void add(KEY key, const N &value) { + (void) add(key, value, hashIndexOf(key)); + } + + bool exists(KEY key) { + int hashIndex; + + return (get(key, (N *) 0, hashIndex) != 0); + } + + /* return true if key is valid, and corresponding data; + * else return false + */ + bool get(KEY key, N *data) { + int hashIndex; + return (get(key, data, hashIndex) != 0); + } + + N &operator[](KEY key) const; + + // Vector& operator ()(); + operator Vector& () const; + + // Get all entries matching given key and append them into vector. + // Return number of matching entries found. + Int32 getAll(KEY key, Vector &vector) const; + + void remove(KEY key); +}; + +// Implementation +template +Uint32 HashTable::hashIndexOf(KEY key) const +{ + Uint32 hashCode = KEYOPS::hashCode(key); + hashCode = hashCode ^ (hashCode >> 16); + hashCode = hashCode ^ (hashCode >> 8); + return (hashCode % _NBUCKETS_); +} + +template +KEY HashTable::add(KEY key, + const N& value, + int hashIndex) +{ + HashTableEntry *newEntry = + new (pool) HashTableEntry(KEYOPS::copyKey(pool, key), value); + buckets[hashIndex].addLast(*newEntry); + return newEntry->key; +} + +template +KEY HashTable::get(KEY key, + N *data, + int &hashIndex) const +{ + hashIndex = hashIndexOf(key); + const DoublyLinkedList >& list = buckets[hashIndex]; + + for (DoublyLinkedNode *i = list.begin(); !list.done(i); + i = list.advance(i)) { + KEY candidateKey = list.get(i).key; + + if (KEYOPS::equals(candidateKey, key)) { + if (data) + *data = list.get(i).value; + return candidateKey; + } + } + + return 0; +} + +template +void HashTable::set(KEY key, + N *data, + int hashIndex) +{ + hashIndex = hashIndexOf(key); + DoublyLinkedList >& list = buckets[hashIndex]; + + for (DoublyLinkedNode *i = list.begin(); !list.done(i); + i = list.advance(i)) { + KEY candidateKey = list.get(i).key; + + if (KEYOPS::equals(candidateKey, key)) { + if (data) + list.get(i).value = *data; + + break; + } + } + +} + +template +Int32 HashTable::getAll(KEY key, + Vector &vector) const +{ + Int32 hashIndex = hashIndexOf(key); + Int32 numMatches = 0; + const DoublyLinkedList >& list = buckets[hashIndex]; + + for (DoublyLinkedNode *i = list.begin(); !list.done(i); + i = list.advance(i)) { + KEY candidateKey = list.get(i).key; + + if (KEYOPS::equals(candidateKey, key)) { + vector.append(list.get(i).value); + numMatches++; + } + } + + return numMatches; +} + +template +N& HashTable::operator[](KEY key) const +{ + const DoublyLinkedList >& list = buckets[hashIndexOf(key)]; + for (DoublyLinkedNode *i = list.begin(); !list.done(i); + i = list.advance(i)) { + if (KEYOPS::equals(list.get(i).key, key)) + return list.get(i).value; + } + // should never get here. + return list.get(list.begin()).value; +} + +//template Vector &HashTable::operator()() +template +HashTable::operator Vector& () const +{ + Vector *vector = new Vector; + + for (Uint32 i = 0; i < _NBUCKETS_; i++) { + const DoublyLinkedList >& list = buckets[i]; + if (!list.empty()) + for (DoublyLinkedNode *j = list.begin(); !list.done(j); + j = list.advance(j)) { + vector->append(list.get(j).value); + } + } + + return *vector; +} + +template +void HashTable::remove(KEY key) +{ + DoublyLinkedList >& list = buckets[hashIndexOf(key)]; + for (DoublyLinkedNode *i = list.begin(); !list.done(i); + i = list.advance(i)) { + if (KEYOPS::equals(list.get(i).key, key)) { + list.get(i).remove();; + return; + } + } +} + + +#endif + + diff --git a/ef/Utilities/General/InterestingEvents.cpp b/ef/Utilities/General/InterestingEvents.cpp new file mode 100644 index 000000000000..efa5a392ae1f --- /dev/null +++ b/ef/Utilities/General/InterestingEvents.cpp @@ -0,0 +1,31 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#include "InterestingEvents.h" + +void EventBroadcaster:: +broadcastEvent(BroadcastEventKind inKind, void* inArgument) +{ + EventListener** curListener; + + for(curListener = mListeners.begin(); curListener < mListeners.end(); curListener++) + (*curListener)->listenToMessage(inKind, inArgument); +} + +EventBroadcaster* gCompileBroadcaster; +EventBroadcaster* gCompileOrLoadBroadcaster; diff --git a/ef/Utilities/General/InterestingEvents.h b/ef/Utilities/General/InterestingEvents.h new file mode 100644 index 000000000000..188663be4a8c --- /dev/null +++ b/ef/Utilities/General/InterestingEvents.h @@ -0,0 +1,161 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +// InterestingEvents.h +// +// Scott M. Silver + +// Getting notifed for and broadcasting interesting events in the +// system. + +#ifndef _H_INTERESTINGEVENTS +#define _H_INTERESTINGEVENTS + +#include "Vector.h" +#include "Fundamentals.h" + +// Creating a new simple listener. +// +// First declare the event handler. +// name, the global event broadcaster you want (listed below) +// +// DECLARE_SIMPLE_EVENT_HANDLER(PrintCompilingMessage, gCompileBroadcaster) +// +// Now define the event handler +// name, parameter name for the MessageKind, and parameter name for the void* argument +// +// DEFINE_SIMPLE_EVENT_HANDLER(PrintCompilingMessage, inKind, inArgument) +// { +// inKind; inArgument; // unused parameters +// +// printf("We're compiling something\n"); +// } +// +// What is passed is defined by each broadcaster. (documented below) +// + +// Creating a new broadcaster +// +// add below +// extern EventBroadcaster* gMyBroadcaster; // (notice the *) +// +// add to InterestingEvents.cpp (or maybe in your file) +// EventBroadcaster* gMyBroadcaster; +// +// For more compilcated listeners subclass EventListener +// and override the listenToMessage method. + +enum BroadcastEventKind +{ + kBroacastCompile, + kEndCompileOrLoad +}; + +// EventBroadcaster +// +// Maintains a vector of EventListeners (which currently cannot) +// be removed. Each event listener is broadcast a message. +// +// Because of static-initializer ordering not crossing file +// boundaries we pass in a pointer to the broadcaster in each +// public function, which checks to see that the broadcaster +// was initialized. + +class EventListener; +class EventBroadcaster +{ + Vector mListeners; + void addListener(EventListener& inListener) { mListeners.append(&inListener); } + void removeListener(EventListener& /*inListener*/) { } + void broadcastEvent(BroadcastEventKind inKind, void* inArgument); + + static EventBroadcaster& checkAllocated(EventBroadcaster*& ioBroadcaster) + { + if (!ioBroadcaster) + ioBroadcaster = new EventBroadcaster(); + + return *ioBroadcaster; + } + +public: + static void addListener(EventBroadcaster*& ioBroadcaster, EventListener& inListener) + { + checkAllocated(ioBroadcaster).addListener(inListener); + } + + static void broadcastEvent(EventBroadcaster*& ioBroadcaster, BroadcastEventKind inKind, void* inArgument) + { + checkAllocated(ioBroadcaster).broadcastEvent(inKind, inArgument); + } + + static void removeListener(EventBroadcaster*& ioBroadcaster, EventListener& inListener) + { + checkAllocated(ioBroadcaster).removeListener(inListener); + } +}; + + +// EventListener +// +// For listenToMessage is called each time a message is broadcast +// +class NS_EXTERN EventListener +{ + DEBUG_ONLY(Vector mBroadcasters); + +public: + EventListener(EventBroadcaster*& ioBroadcaster) + { + ioBroadcaster->addListener(ioBroadcaster, *this); + } + + + ~EventListener() { } + + virtual void listenToMessage(BroadcastEventKind inKind, void* inArgument) = 0; +}; + + +// Add new declarations of new broadcasters here. +extern EventBroadcaster* gCompileBroadcaster; +extern EventBroadcaster* gCompileOrLoadBroadcaster; + +// Some helper macros described above +#define SIMPLE_EVENT_HANDLER_CLASS_NAME(inName) \ + inName##Listener + +#define DECLARE_SIMPLE_EVENT_HANDLER(inName, inBroadcaster) \ + class SIMPLE_EVENT_HANDLER_CLASS_NAME(inName) : \ + public EventListener \ + { \ + public: \ + SIMPLE_EVENT_HANDLER_CLASS_NAME(inName)(EventBroadcaster*& ioListener) : \ + EventListener(ioListener) {} \ + \ + void listenToMessage(BroadcastEventKind inKind, void* inArgument); \ + private: \ + static SIMPLE_EVENT_HANDLER_CLASS_NAME(inName) s##inName##Listener; \ + }; \ + \ + SIMPLE_EVENT_HANDLER_CLASS_NAME(inName) SIMPLE_EVENT_HANDLER_CLASS_NAME(inName)::s##inName##Listener(inBroadcaster); + +#define DEFINE_SIMPLE_EVENT_HANDLER(inName, inMessageKindParamName, inArgumentParamName) \ + void SIMPLE_EVENT_HANDLER_CLASS_NAME(inName):: \ + listenToMessage(BroadcastEventKind inMessageKindParamName, void* inArgumentParamName) + +#endif // _H_INTERESTINGEVENTS diff --git a/ef/Utilities/General/JavaBytecodes.cpp b/ef/Utilities/General/JavaBytecodes.cpp new file mode 100644 index 000000000000..a484e9f33aeb --- /dev/null +++ b/ef/Utilities/General/JavaBytecodes.cpp @@ -0,0 +1,1133 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#include "JavaBytecodes.h" +#include "MemoryAccess.h" +#include "ConstantPool.h" +#include "Attributes.h" +#include "DebugUtils.h" + +// Kinds and sizes of normal bytecodes +const BytecodeControlInfo normalBytecodeControlInfos[256] = +{ + {BytecodeControlInfo::bckNormal, 1}, // 00 nop + {BytecodeControlInfo::bckNormal, 1}, // 01 aconst_null + {BytecodeControlInfo::bckNormal, 1}, // 02 iconst_m1 + {BytecodeControlInfo::bckNormal, 1}, // 03 iconst_0 + {BytecodeControlInfo::bckNormal, 1}, // 04 iconst_1 + {BytecodeControlInfo::bckNormal, 1}, // 05 iconst_2 + {BytecodeControlInfo::bckNormal, 1}, // 06 iconst_3 + {BytecodeControlInfo::bckNormal, 1}, // 07 iconst_4 + {BytecodeControlInfo::bckNormal, 1}, // 08 iconst_5 + {BytecodeControlInfo::bckNormal, 1}, // 09 lconst_0 + {BytecodeControlInfo::bckNormal, 1}, // 0A lconst_1 + {BytecodeControlInfo::bckNormal, 1}, // 0B fconst_0 + {BytecodeControlInfo::bckNormal, 1}, // 0C fconst_1 + {BytecodeControlInfo::bckNormal, 1}, // 0D fconst_2 + {BytecodeControlInfo::bckNormal, 1}, // 0E dconst_0 + {BytecodeControlInfo::bckNormal, 1}, // 0F dconst_1 + {BytecodeControlInfo::bckNormal, 2}, // 10 cc bipush c + {BytecodeControlInfo::bckNormal, 3}, // 11 cccc sipush c + {BytecodeControlInfo::bckNormal, 2}, // 12 ii ldc i + {BytecodeControlInfo::bckNormal, 3}, // 13 iiii ldc_w i + {BytecodeControlInfo::bckNormal, 3}, // 14 iiii ldc2_w i + {BytecodeControlInfo::bckNormal, 2}, // 15 vv iload v + {BytecodeControlInfo::bckNormal, 2}, // 16 vv lload v + {BytecodeControlInfo::bckNormal, 2}, // 17 vv fload v + {BytecodeControlInfo::bckNormal, 2}, // 18 vv dload v + {BytecodeControlInfo::bckNormal, 2}, // 19 vv aload v + {BytecodeControlInfo::bckNormal, 1}, // 1A iload_0 + {BytecodeControlInfo::bckNormal, 1}, // 1B iload_1 + {BytecodeControlInfo::bckNormal, 1}, // 1C iload_2 + {BytecodeControlInfo::bckNormal, 1}, // 1D iload_3 + {BytecodeControlInfo::bckNormal, 1}, // 1E lload_0 + {BytecodeControlInfo::bckNormal, 1}, // 1F lload_1 + {BytecodeControlInfo::bckNormal, 1}, // 20 lload_2 + {BytecodeControlInfo::bckNormal, 1}, // 21 lload_3 + {BytecodeControlInfo::bckNormal, 1}, // 22 fload_0 + {BytecodeControlInfo::bckNormal, 1}, // 23 fload_1 + {BytecodeControlInfo::bckNormal, 1}, // 24 fload_2 + {BytecodeControlInfo::bckNormal, 1}, // 25 fload_3 + {BytecodeControlInfo::bckNormal, 1}, // 26 dload_0 + {BytecodeControlInfo::bckNormal, 1}, // 27 dload_1 + {BytecodeControlInfo::bckNormal, 1}, // 28 dload_2 + {BytecodeControlInfo::bckNormal, 1}, // 29 dload_3 + {BytecodeControlInfo::bckNormal, 1}, // 2A aload_0 + {BytecodeControlInfo::bckNormal, 1}, // 2B aload_1 + {BytecodeControlInfo::bckNormal, 1}, // 2C aload_2 + {BytecodeControlInfo::bckNormal, 1}, // 2D aload_3 + {BytecodeControlInfo::bckExc, 1}, // 2E iaload + {BytecodeControlInfo::bckExc, 1}, // 2F laload + {BytecodeControlInfo::bckExc, 1}, // 30 faload + {BytecodeControlInfo::bckExc, 1}, // 31 daload + {BytecodeControlInfo::bckExc, 1}, // 32 aaload + {BytecodeControlInfo::bckExc, 1}, // 33 baload + {BytecodeControlInfo::bckExc, 1}, // 34 caload + {BytecodeControlInfo::bckExc, 1}, // 35 saload + {BytecodeControlInfo::bckNormal, 2}, // 36 vv istore v + {BytecodeControlInfo::bckNormal, 2}, // 37 vv lstore v + {BytecodeControlInfo::bckNormal, 2}, // 38 vv fstore v + {BytecodeControlInfo::bckNormal, 2}, // 39 vv dstore v + {BytecodeControlInfo::bckNormal, 2}, // 3A vv astore v + {BytecodeControlInfo::bckNormal, 1}, // 3B istore_0 + {BytecodeControlInfo::bckNormal, 1}, // 3C istore_1 + {BytecodeControlInfo::bckNormal, 1}, // 3D istore_2 + {BytecodeControlInfo::bckNormal, 1}, // 3E istore_3 + {BytecodeControlInfo::bckNormal, 1}, // 3F lstore_0 + {BytecodeControlInfo::bckNormal, 1}, // 40 lstore_1 + {BytecodeControlInfo::bckNormal, 1}, // 41 lstore_2 + {BytecodeControlInfo::bckNormal, 1}, // 42 lstore_3 + {BytecodeControlInfo::bckNormal, 1}, // 43 fstore_0 + {BytecodeControlInfo::bckNormal, 1}, // 44 fstore_1 + {BytecodeControlInfo::bckNormal, 1}, // 45 fstore_2 + {BytecodeControlInfo::bckNormal, 1}, // 46 fstore_3 + {BytecodeControlInfo::bckNormal, 1}, // 47 dstore_0 + {BytecodeControlInfo::bckNormal, 1}, // 48 dstore_1 + {BytecodeControlInfo::bckNormal, 1}, // 49 dstore_2 + {BytecodeControlInfo::bckNormal, 1}, // 4A dstore_3 + {BytecodeControlInfo::bckNormal, 1}, // 4B astore_0 + {BytecodeControlInfo::bckNormal, 1}, // 4C astore_1 + {BytecodeControlInfo::bckNormal, 1}, // 4D astore_2 + {BytecodeControlInfo::bckNormal, 1}, // 4E astore_3 + {BytecodeControlInfo::bckExc, 1}, // 4F iastore + {BytecodeControlInfo::bckExc, 1}, // 50 lastore + {BytecodeControlInfo::bckExc, 1}, // 51 fastore + {BytecodeControlInfo::bckExc, 1}, // 52 dastore + {BytecodeControlInfo::bckExc, 1}, // 53 aastore + {BytecodeControlInfo::bckExc, 1}, // 54 bastore + {BytecodeControlInfo::bckExc, 1}, // 55 castore + {BytecodeControlInfo::bckExc, 1}, // 56 sastore + {BytecodeControlInfo::bckNormal, 1}, // 57 pop + {BytecodeControlInfo::bckNormal, 1}, // 58 pop2 + {BytecodeControlInfo::bckNormal, 1}, // 59 dup + {BytecodeControlInfo::bckNormal, 1}, // 5A dup_x1 + {BytecodeControlInfo::bckNormal, 1}, // 5B dup_x2 + {BytecodeControlInfo::bckNormal, 1}, // 5C dup2 + {BytecodeControlInfo::bckNormal, 1}, // 5D dup2_x1 + {BytecodeControlInfo::bckNormal, 1}, // 5E dup2_x2 + {BytecodeControlInfo::bckNormal, 1}, // 5F swap + {BytecodeControlInfo::bckNormal, 1}, // 60 iadd + {BytecodeControlInfo::bckNormal, 1}, // 61 ladd + {BytecodeControlInfo::bckNormal, 1}, // 62 fadd + {BytecodeControlInfo::bckNormal, 1}, // 63 dadd + {BytecodeControlInfo::bckNormal, 1}, // 64 isub + {BytecodeControlInfo::bckNormal, 1}, // 65 lsub + {BytecodeControlInfo::bckNormal, 1}, // 66 fsub + {BytecodeControlInfo::bckNormal, 1}, // 67 dsub + {BytecodeControlInfo::bckNormal, 1}, // 68 imul + {BytecodeControlInfo::bckNormal, 1}, // 69 lmul + {BytecodeControlInfo::bckNormal, 1}, // 6A fmul + {BytecodeControlInfo::bckNormal, 1}, // 6B dmul + {BytecodeControlInfo::bckExc, 1}, // 6C idiv + {BytecodeControlInfo::bckExc, 1}, // 6D ldiv + {BytecodeControlInfo::bckNormal, 1}, // 6E fdiv + {BytecodeControlInfo::bckNormal, 1}, // 6F ddiv + {BytecodeControlInfo::bckExc, 1}, // 70 irem + {BytecodeControlInfo::bckExc, 1}, // 71 lrem + {BytecodeControlInfo::bckNormal, 1}, // 72 frem + {BytecodeControlInfo::bckNormal, 1}, // 73 drem + {BytecodeControlInfo::bckNormal, 1}, // 74 ineg + {BytecodeControlInfo::bckNormal, 1}, // 75 lneg + {BytecodeControlInfo::bckNormal, 1}, // 76 fneg + {BytecodeControlInfo::bckNormal, 1}, // 77 dneg + {BytecodeControlInfo::bckNormal, 1}, // 78 ishl + {BytecodeControlInfo::bckNormal, 1}, // 79 lshl + {BytecodeControlInfo::bckNormal, 1}, // 7A ishr + {BytecodeControlInfo::bckNormal, 1}, // 7B lshr + {BytecodeControlInfo::bckNormal, 1}, // 7C iushr + {BytecodeControlInfo::bckNormal, 1}, // 7D lushr + {BytecodeControlInfo::bckNormal, 1}, // 7E iand + {BytecodeControlInfo::bckNormal, 1}, // 7F land + {BytecodeControlInfo::bckNormal, 1}, // 80 ior + {BytecodeControlInfo::bckNormal, 1}, // 81 lor + {BytecodeControlInfo::bckNormal, 1}, // 82 ixor + {BytecodeControlInfo::bckNormal, 1}, // 83 lxor + {BytecodeControlInfo::bckNormal, 3}, // 84 vv cc iinc v,c + {BytecodeControlInfo::bckNormal, 1}, // 85 i2l + {BytecodeControlInfo::bckNormal, 1}, // 86 i2f + {BytecodeControlInfo::bckNormal, 1}, // 87 i2d + {BytecodeControlInfo::bckNormal, 1}, // 88 l2i + {BytecodeControlInfo::bckNormal, 1}, // 89 l2f + {BytecodeControlInfo::bckNormal, 1}, // 8A l2d + {BytecodeControlInfo::bckNormal, 1}, // 8B f2i + {BytecodeControlInfo::bckNormal, 1}, // 8C f2l + {BytecodeControlInfo::bckNormal, 1}, // 8D f2d + {BytecodeControlInfo::bckNormal, 1}, // 8E d2i + {BytecodeControlInfo::bckNormal, 1}, // 8F d2l + {BytecodeControlInfo::bckNormal, 1}, // 90 d2f + {BytecodeControlInfo::bckNormal, 1}, // 91 i2b + {BytecodeControlInfo::bckNormal, 1}, // 92 i2c + {BytecodeControlInfo::bckNormal, 1}, // 93 i2s + {BytecodeControlInfo::bckNormal, 1}, // 94 lcmp + {BytecodeControlInfo::bckNormal, 1}, // 95 fcmpl + {BytecodeControlInfo::bckNormal, 1}, // 96 fcmpg + {BytecodeControlInfo::bckNormal, 1}, // 97 dcmpl + {BytecodeControlInfo::bckNormal, 1}, // 98 dcmpg + {BytecodeControlInfo::bckIf, 3}, // 99 dddd ifeq + {BytecodeControlInfo::bckIf, 3}, // 9A dddd ifne + {BytecodeControlInfo::bckIf, 3}, // 9B dddd iflt + {BytecodeControlInfo::bckIf, 3}, // 9C dddd ifge + {BytecodeControlInfo::bckIf, 3}, // 9D dddd ifgt + {BytecodeControlInfo::bckIf, 3}, // 9E dddd ifle + {BytecodeControlInfo::bckIf, 3}, // 9F dddd if_icmpeq + {BytecodeControlInfo::bckIf, 3}, // A0 dddd if_icmpne + {BytecodeControlInfo::bckIf, 3}, // A1 dddd if_icmplt + {BytecodeControlInfo::bckIf, 3}, // A2 dddd if_icmpge + {BytecodeControlInfo::bckIf, 3}, // A3 dddd if_icmpgt + {BytecodeControlInfo::bckIf, 3}, // A4 dddd if_icmple + {BytecodeControlInfo::bckIf, 3}, // A5 dddd if_acmpeq + {BytecodeControlInfo::bckIf, 3}, // A6 dddd if_acmpne + {BytecodeControlInfo::bckGoto, 3}, // A7 dddd goto + {BytecodeControlInfo::bckJsr, 3}, // A8 dddd jsr + {BytecodeControlInfo::bckRet, 2}, // A9 vv ret v + {BytecodeControlInfo::bckTableSwitch, 1}, // AA ... tableswitch + {BytecodeControlInfo::bckLookupSwitch, 1}, // AB ... lookupswitch + {BytecodeControlInfo::bckReturn, 1}, // AC ireturn + {BytecodeControlInfo::bckReturn, 1}, // AD lreturn + {BytecodeControlInfo::bckReturn, 1}, // AE freturn + {BytecodeControlInfo::bckReturn, 1}, // AF dreturn + {BytecodeControlInfo::bckReturn, 1}, // B0 areturn + {BytecodeControlInfo::bckReturn, 1}, // B1 return + {BytecodeControlInfo::bckNormal, 3}, // B2 iiii getstatic + {BytecodeControlInfo::bckNormal, 3}, // B3 iiii putstatic + {BytecodeControlInfo::bckExc, 3}, // B4 iiii getfield + {BytecodeControlInfo::bckExc, 3}, // B5 iiii putfield + {BytecodeControlInfo::bckExc, 3}, // B6 iiii invokevirtual + {BytecodeControlInfo::bckExc, 3}, // B7 iiii invokespecial + {BytecodeControlInfo::bckExc, 3}, // B8 iiii invokestatic + {BytecodeControlInfo::bckExc, 5}, // B9 iiii nn00 invokeinterface + {BytecodeControlInfo::bckIllegal, 1}, // BA unused + {BytecodeControlInfo::bckExc, 3}, // BB iiii new + {BytecodeControlInfo::bckExc, 2}, // BC tt newarray + {BytecodeControlInfo::bckExc, 3}, // BD iiii anewarray + {BytecodeControlInfo::bckExc, 1}, // BE arraylength + {BytecodeControlInfo::bckThrow, 1}, // BF athrow + {BytecodeControlInfo::bckExc, 3}, // C0 iiii checkcast + {BytecodeControlInfo::bckNormal, 3}, // C1 iiii instanceof + {BytecodeControlInfo::bckExc, 1}, // C2 monitorenter + {BytecodeControlInfo::bckExc, 1}, // C3 monitorexit + {BytecodeControlInfo::bckNormal, 0}, // C4 ... wide + {BytecodeControlInfo::bckExc, 4}, // C5 iiii nn multianewarray + {BytecodeControlInfo::bckIf, 3}, // C6 dddd ifnull + {BytecodeControlInfo::bckIf, 3}, // C7 dddd ifnonnull + {BytecodeControlInfo::bckGoto_W, 5}, // C8 dddddddd goto_w + {BytecodeControlInfo::bckJsr_W, 5}, // C9 dddddddd jsr_w + {BytecodeControlInfo::bckExc, 1}, // CA breakpoint + {BytecodeControlInfo::bckIllegal, 1}, // CB unused + {BytecodeControlInfo::bckIllegal, 1}, // CC unused + {BytecodeControlInfo::bckIllegal, 1}, // CD unused + {BytecodeControlInfo::bckIllegal, 1}, // CE unused + {BytecodeControlInfo::bckIllegal, 1}, // CF unused + {BytecodeControlInfo::bckIllegal, 1}, // D0 unused + {BytecodeControlInfo::bckIllegal, 1}, // D1 unused + {BytecodeControlInfo::bckIllegal, 1}, // D2 unused + {BytecodeControlInfo::bckIllegal, 1}, // D3 unused + {BytecodeControlInfo::bckIllegal, 1}, // D4 unused + {BytecodeControlInfo::bckIllegal, 1}, // D5 unused + {BytecodeControlInfo::bckIllegal, 1}, // D6 unused + {BytecodeControlInfo::bckIllegal, 1}, // D7 unused + {BytecodeControlInfo::bckIllegal, 1}, // D8 unused + {BytecodeControlInfo::bckIllegal, 1}, // D9 unused + {BytecodeControlInfo::bckIllegal, 1}, // DA unused + {BytecodeControlInfo::bckIllegal, 1}, // DB unused + {BytecodeControlInfo::bckIllegal, 1}, // DC unused + {BytecodeControlInfo::bckIllegal, 1}, // DD unused + {BytecodeControlInfo::bckIllegal, 1}, // DE unused + {BytecodeControlInfo::bckIllegal, 1}, // DF unused + {BytecodeControlInfo::bckIllegal, 1}, // E0 unused + {BytecodeControlInfo::bckIllegal, 1}, // E1 unused + {BytecodeControlInfo::bckIllegal, 1}, // E2 unused + {BytecodeControlInfo::bckIllegal, 1}, // E3 unused + {BytecodeControlInfo::bckIllegal, 1}, // E4 unused + {BytecodeControlInfo::bckIllegal, 1}, // E5 unused + {BytecodeControlInfo::bckIllegal, 1}, // E6 unused + {BytecodeControlInfo::bckIllegal, 1}, // E7 unused + {BytecodeControlInfo::bckIllegal, 1}, // E8 unused + {BytecodeControlInfo::bckIllegal, 1}, // E9 unused + {BytecodeControlInfo::bckIllegal, 1}, // EA unused + {BytecodeControlInfo::bckIllegal, 1}, // EB unused + {BytecodeControlInfo::bckIllegal, 1}, // EC unused + {BytecodeControlInfo::bckIllegal, 1}, // ED unused + {BytecodeControlInfo::bckIllegal, 1}, // EE unused + {BytecodeControlInfo::bckIllegal, 1}, // EF unused + {BytecodeControlInfo::bckIllegal, 1}, // F0 unused + {BytecodeControlInfo::bckIllegal, 1}, // F1 unused + {BytecodeControlInfo::bckIllegal, 1}, // F2 unused + {BytecodeControlInfo::bckIllegal, 1}, // F3 unused + {BytecodeControlInfo::bckIllegal, 1}, // F4 unused + {BytecodeControlInfo::bckIllegal, 1}, // F5 unused + {BytecodeControlInfo::bckIllegal, 1}, // F6 unused + {BytecodeControlInfo::bckIllegal, 1}, // F7 unused + {BytecodeControlInfo::bckIllegal, 1}, // F8 unused + {BytecodeControlInfo::bckIllegal, 1}, // F9 unused + {BytecodeControlInfo::bckIllegal, 1}, // FA unused + {BytecodeControlInfo::bckIllegal, 1}, // FB unused + {BytecodeControlInfo::bckIllegal, 1}, // FC unused + {BytecodeControlInfo::bckIllegal, 1}, // FD unused + {BytecodeControlInfo::bckIllegal, 1}, // FE unused + {BytecodeControlInfo::bckIllegal, 1} // FF unused +}; + +// Kinds and sizes of wide bytecodes +const BytecodeControlInfo wideBytecodeControlInfos[256] = +{ + {BytecodeControlInfo::bckIllegal, 2}, // C4 00 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 01 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 02 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 03 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 04 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 05 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 06 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 07 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 08 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 09 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 0A wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 0B wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 0C wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 0D wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 0E wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 0F wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 10 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 11 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 12 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 13 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 14 wide unused + {BytecodeControlInfo::bckNormal, 4}, // C4 15 vvvv wide iload v + {BytecodeControlInfo::bckNormal, 4}, // C4 16 vvvv wide lload v + {BytecodeControlInfo::bckNormal, 4}, // C4 17 vvvv wide fload v + {BytecodeControlInfo::bckNormal, 4}, // C4 18 vvvv wide dload v + {BytecodeControlInfo::bckNormal, 4}, // C4 19 vvvv wide aload v + {BytecodeControlInfo::bckIllegal, 2}, // C4 1A wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 1B wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 1C wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 1D wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 1E wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 1F wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 20 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 21 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 22 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 23 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 24 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 25 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 26 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 27 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 28 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 29 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 2A wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 2B wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 2C wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 2D wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 2E wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 2F wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 30 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 31 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 32 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 33 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 34 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 35 wide unused + {BytecodeControlInfo::bckNormal, 4}, // C4 36 vvvv wide istore v + {BytecodeControlInfo::bckNormal, 4}, // C4 37 vvvv wide lstore v + {BytecodeControlInfo::bckNormal, 4}, // C4 38 vvvv wide fstore v + {BytecodeControlInfo::bckNormal, 4}, // C4 39 vvvv wide dstore v + {BytecodeControlInfo::bckNormal, 4}, // C4 3A vvvv wide astore v + {BytecodeControlInfo::bckIllegal, 2}, // C4 3B wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 3C wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 3D wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 3E wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 3F wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 40 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 41 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 42 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 43 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 44 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 45 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 46 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 47 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 48 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 49 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 4A wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 4B wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 4C wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 4D wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 4E wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 4F wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 50 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 51 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 52 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 53 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 54 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 55 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 56 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 57 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 58 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 59 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 5A wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 5B wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 5C wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 5D wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 5E wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 5F wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 60 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 61 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 62 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 63 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 64 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 65 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 66 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 67 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 68 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 69 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 6A wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 6B wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 6C wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 6D wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 6E wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 6F wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 70 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 71 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 72 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 73 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 74 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 75 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 76 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 77 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 78 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 79 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 7A wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 7B wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 7C wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 7D wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 7E wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 7F wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 80 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 81 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 82 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 83 wide unused + {BytecodeControlInfo::bckNormal, 6}, // C4 84 vvvv cccc wide iinc v,c + {BytecodeControlInfo::bckIllegal, 2}, // C4 85 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 86 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 87 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 88 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 89 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 8A wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 8B wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 8C wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 8D wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 8E wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 8F wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 90 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 91 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 92 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 93 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 94 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 95 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 96 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 97 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 98 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 99 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 9A wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 9B wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 9C wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 9D wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 9E wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 9F wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 A0 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 A1 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 A2 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 A3 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 A4 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 A5 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 A6 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 A7 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 A8 wide unused + {BytecodeControlInfo::bckRet_W, 4}, // C4 A9 vvvv wide ret v + {BytecodeControlInfo::bckIllegal, 2}, // C4 AA wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 AB wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 AC wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 AD wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 AE wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 AF wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 B0 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 B1 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 B2 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 B3 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 B4 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 B5 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 B6 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 B7 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 B8 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 B9 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 BA wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 BB wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 BC wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 BD wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 BE wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 BF wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 C0 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 C1 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 C2 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 C3 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 C4 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 C5 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 C6 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 C7 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 C8 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 C9 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 CA wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 CB wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 CC wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 CD wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 CE wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 CF wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 D0 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 D1 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 D2 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 D3 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 D4 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 D5 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 D6 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 D7 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 D8 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 D9 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 DA wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 DB wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 DC wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 DD wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 DE wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 DF wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 E0 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 E1 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 E2 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 E3 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 E4 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 E5 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 E6 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 E7 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 E8 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 E9 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 EA wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 EB wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 EC wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 ED wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 EE wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 EF wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 F0 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 F1 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 F2 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 F3 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 F4 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 F5 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 F6 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 F7 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 F8 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 F9 wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 FA wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 FB wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 FC wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 FD wide unused + {BytecodeControlInfo::bckIllegal, 2}, // C4 FE wide unused + {BytecodeControlInfo::bckIllegal, 2} // C4 FF wide unused +}; + + +// ---------------------------------------------------------------------------- + + +#ifdef DEBUG_LOG +struct BytecodeDisasmInfo +{ + enum ArgFormat // Formats of arguments + { + afNone, // No arguments + afSByte, // One signed byte + afSHalf, // One signed halfword + afByteConstIndex, // One unsigned byte constant table index + afHalfConstIndex, // One unsigned halfword constant table index + afVar, // One unsigned byte (or halfword if wide) local variable index + afIInc, // Arguments for iinc or wide iinc + afDisp, // One signed halfword branch displacement + afWideDisp, // One signed word branch displacement + afTableSwitch, // Arguments for tableswitch + afLookupSwitch, // Arguments for lookupswitch + afInvokeInterface, // Arguments for invokeinterface + afNewArray, // Argument for newarray + afMultiANewArray, // Argument for multianewarray + afWide, // Wide instruction prefix + afIllegal // Any bytecode that's not defined by the Java spec + }; + + ArgFormat format; // Kind of bytecode + char name[16]; // Name of bytecode +}; + + +// Disassembly table for normal bytecodes +static BytecodeDisasmInfo bytecodeDisasmInfos[256] = +{ + {BytecodeDisasmInfo::afNone, "nop"}, // 00 nop + {BytecodeDisasmInfo::afNone, "aconst_null"}, // 01 aconst_null + {BytecodeDisasmInfo::afNone, "iconst_m1"}, // 02 iconst_m1 + {BytecodeDisasmInfo::afNone, "iconst_0"}, // 03 iconst_0 + {BytecodeDisasmInfo::afNone, "iconst_1"}, // 04 iconst_1 + {BytecodeDisasmInfo::afNone, "iconst_2"}, // 05 iconst_2 + {BytecodeDisasmInfo::afNone, "iconst_3"}, // 06 iconst_3 + {BytecodeDisasmInfo::afNone, "iconst_4"}, // 07 iconst_4 + {BytecodeDisasmInfo::afNone, "iconst_5"}, // 08 iconst_5 + {BytecodeDisasmInfo::afNone, "lconst_0"}, // 09 lconst_0 + {BytecodeDisasmInfo::afNone, "lconst_1"}, // 0A lconst_1 + {BytecodeDisasmInfo::afNone, "fconst_0"}, // 0B fconst_0 + {BytecodeDisasmInfo::afNone, "fconst_1"}, // 0C fconst_1 + {BytecodeDisasmInfo::afNone, "fconst_2"}, // 0D fconst_2 + {BytecodeDisasmInfo::afNone, "dconst_0"}, // 0E dconst_0 + {BytecodeDisasmInfo::afNone, "dconst_1"}, // 0F dconst_1 + {BytecodeDisasmInfo::afSByte, "bipush"}, // 10 cc bipush c + {BytecodeDisasmInfo::afSHalf, "sipush"}, // 11 cccc sipush c + {BytecodeDisasmInfo::afByteConstIndex, "ldc"}, // 12 ii ldc i + {BytecodeDisasmInfo::afHalfConstIndex, "ldc_w"}, // 13 iiii ldc_w i + {BytecodeDisasmInfo::afHalfConstIndex, "ldc2_w"}, // 14 iiii ldc2_w i + {BytecodeDisasmInfo::afVar, "iload"}, // 15 vv iload v + {BytecodeDisasmInfo::afVar, "lload"}, // 16 vv lload v + {BytecodeDisasmInfo::afVar, "fload"}, // 17 vv fload v + {BytecodeDisasmInfo::afVar, "dload"}, // 18 vv dload v + {BytecodeDisasmInfo::afVar, "aload"}, // 19 vv aload v + {BytecodeDisasmInfo::afNone, "iload_0"}, // 1A iload_0 + {BytecodeDisasmInfo::afNone, "iload_1"}, // 1B iload_1 + {BytecodeDisasmInfo::afNone, "iload_2"}, // 1C iload_2 + {BytecodeDisasmInfo::afNone, "iload_3"}, // 1D iload_3 + {BytecodeDisasmInfo::afNone, "lload_0"}, // 1E lload_0 + {BytecodeDisasmInfo::afNone, "lload_1"}, // 1F lload_1 + {BytecodeDisasmInfo::afNone, "lload_2"}, // 20 lload_2 + {BytecodeDisasmInfo::afNone, "lload_3"}, // 21 lload_3 + {BytecodeDisasmInfo::afNone, "fload_0"}, // 22 fload_0 + {BytecodeDisasmInfo::afNone, "fload_1"}, // 23 fload_1 + {BytecodeDisasmInfo::afNone, "fload_2"}, // 24 fload_2 + {BytecodeDisasmInfo::afNone, "fload_3"}, // 25 fload_3 + {BytecodeDisasmInfo::afNone, "dload_0"}, // 26 dload_0 + {BytecodeDisasmInfo::afNone, "dload_1"}, // 27 dload_1 + {BytecodeDisasmInfo::afNone, "dload_2"}, // 28 dload_2 + {BytecodeDisasmInfo::afNone, "dload_3"}, // 29 dload_3 + {BytecodeDisasmInfo::afNone, "aload_0"}, // 2A aload_0 + {BytecodeDisasmInfo::afNone, "aload_1"}, // 2B aload_1 + {BytecodeDisasmInfo::afNone, "aload_2"}, // 2C aload_2 + {BytecodeDisasmInfo::afNone, "aload_3"}, // 2D aload_3 + {BytecodeDisasmInfo::afNone, "iaload"}, // 2E iaload + {BytecodeDisasmInfo::afNone, "laload"}, // 2F laload + {BytecodeDisasmInfo::afNone, "faload"}, // 30 faload + {BytecodeDisasmInfo::afNone, "daload"}, // 31 daload + {BytecodeDisasmInfo::afNone, "aaload"}, // 32 aaload + {BytecodeDisasmInfo::afNone, "baload"}, // 33 baload + {BytecodeDisasmInfo::afNone, "caload"}, // 34 caload + {BytecodeDisasmInfo::afNone, "saload"}, // 35 saload + {BytecodeDisasmInfo::afVar, "istore"}, // 36 vv istore v + {BytecodeDisasmInfo::afVar, "lstore"}, // 37 vv lstore v + {BytecodeDisasmInfo::afVar, "fstore"}, // 38 vv fstore v + {BytecodeDisasmInfo::afVar, "dstore"}, // 39 vv dstore v + {BytecodeDisasmInfo::afVar, "astore"}, // 3A vv astore v + {BytecodeDisasmInfo::afNone, "istore_0"}, // 3B istore_0 + {BytecodeDisasmInfo::afNone, "istore_1"}, // 3C istore_1 + {BytecodeDisasmInfo::afNone, "istore_2"}, // 3D istore_2 + {BytecodeDisasmInfo::afNone, "istore_3"}, // 3E istore_3 + {BytecodeDisasmInfo::afNone, "lstore_0"}, // 3F lstore_0 + {BytecodeDisasmInfo::afNone, "lstore_1"}, // 40 lstore_1 + {BytecodeDisasmInfo::afNone, "lstore_2"}, // 41 lstore_2 + {BytecodeDisasmInfo::afNone, "lstore_3"}, // 42 lstore_3 + {BytecodeDisasmInfo::afNone, "fstore_0"}, // 43 fstore_0 + {BytecodeDisasmInfo::afNone, "fstore_1"}, // 44 fstore_1 + {BytecodeDisasmInfo::afNone, "fstore_2"}, // 45 fstore_2 + {BytecodeDisasmInfo::afNone, "fstore_3"}, // 46 fstore_3 + {BytecodeDisasmInfo::afNone, "dstore_0"}, // 47 dstore_0 + {BytecodeDisasmInfo::afNone, "dstore_1"}, // 48 dstore_1 + {BytecodeDisasmInfo::afNone, "dstore_2"}, // 49 dstore_2 + {BytecodeDisasmInfo::afNone, "dstore_3"}, // 4A dstore_3 + {BytecodeDisasmInfo::afNone, "astore_0"}, // 4B astore_0 + {BytecodeDisasmInfo::afNone, "astore_1"}, // 4C astore_1 + {BytecodeDisasmInfo::afNone, "astore_2"}, // 4D astore_2 + {BytecodeDisasmInfo::afNone, "astore_3"}, // 4E astore_3 + {BytecodeDisasmInfo::afNone, "iastore"}, // 4F iastore + {BytecodeDisasmInfo::afNone, "lastore"}, // 50 lastore + {BytecodeDisasmInfo::afNone, "fastore"}, // 51 fastore + {BytecodeDisasmInfo::afNone, "dastore"}, // 52 dastore + {BytecodeDisasmInfo::afNone, "aastore"}, // 53 aastore + {BytecodeDisasmInfo::afNone, "bastore"}, // 54 bastore + {BytecodeDisasmInfo::afNone, "castore"}, // 55 castore + {BytecodeDisasmInfo::afNone, "sastore"}, // 56 sastore + {BytecodeDisasmInfo::afNone, "pop"}, // 57 pop + {BytecodeDisasmInfo::afNone, "pop2"}, // 58 pop2 + {BytecodeDisasmInfo::afNone, "dup"}, // 59 dup + {BytecodeDisasmInfo::afNone, "dup_x1"}, // 5A dup_x1 + {BytecodeDisasmInfo::afNone, "dup_x2"}, // 5B dup_x2 + {BytecodeDisasmInfo::afNone, "dup2"}, // 5C dup2 + {BytecodeDisasmInfo::afNone, "dup2_x1"}, // 5D dup2_x1 + {BytecodeDisasmInfo::afNone, "dup2_x2"}, // 5E dup2_x2 + {BytecodeDisasmInfo::afNone, "swap"}, // 5F swap + {BytecodeDisasmInfo::afNone, "iadd"}, // 60 iadd + {BytecodeDisasmInfo::afNone, "ladd"}, // 61 ladd + {BytecodeDisasmInfo::afNone, "fadd"}, // 62 fadd + {BytecodeDisasmInfo::afNone, "dadd"}, // 63 dadd + {BytecodeDisasmInfo::afNone, "isub"}, // 64 isub + {BytecodeDisasmInfo::afNone, "lsub"}, // 65 lsub + {BytecodeDisasmInfo::afNone, "fsub"}, // 66 fsub + {BytecodeDisasmInfo::afNone, "dsub"}, // 67 dsub + {BytecodeDisasmInfo::afNone, "imul"}, // 68 imul + {BytecodeDisasmInfo::afNone, "lmul"}, // 69 lmul + {BytecodeDisasmInfo::afNone, "fmul"}, // 6A fmul + {BytecodeDisasmInfo::afNone, "dmul"}, // 6B dmul + {BytecodeDisasmInfo::afNone, "idiv"}, // 6C idiv + {BytecodeDisasmInfo::afNone, "ldiv"}, // 6D ldiv + {BytecodeDisasmInfo::afNone, "fdiv"}, // 6E fdiv + {BytecodeDisasmInfo::afNone, "ddiv"}, // 6F ddiv + {BytecodeDisasmInfo::afNone, "irem"}, // 70 irem + {BytecodeDisasmInfo::afNone, "lrem"}, // 71 lrem + {BytecodeDisasmInfo::afNone, "frem"}, // 72 frem + {BytecodeDisasmInfo::afNone, "drem"}, // 73 drem + {BytecodeDisasmInfo::afNone, "ineg"}, // 74 ineg + {BytecodeDisasmInfo::afNone, "lneg"}, // 75 lneg + {BytecodeDisasmInfo::afNone, "fneg"}, // 76 fneg + {BytecodeDisasmInfo::afNone, "dneg"}, // 77 dneg + {BytecodeDisasmInfo::afNone, "ishl"}, // 78 ishl + {BytecodeDisasmInfo::afNone, "lshl"}, // 79 lshl + {BytecodeDisasmInfo::afNone, "ishr"}, // 7A ishr + {BytecodeDisasmInfo::afNone, "lshr"}, // 7B lshr + {BytecodeDisasmInfo::afNone, "iushr"}, // 7C iushr + {BytecodeDisasmInfo::afNone, "lushr"}, // 7D lushr + {BytecodeDisasmInfo::afNone, "iand"}, // 7E iand + {BytecodeDisasmInfo::afNone, "land"}, // 7F land + {BytecodeDisasmInfo::afNone, "ior"}, // 80 ior + {BytecodeDisasmInfo::afNone, "lor"}, // 81 lor + {BytecodeDisasmInfo::afNone, "ixor"}, // 82 ixor + {BytecodeDisasmInfo::afNone, "lxor"}, // 83 lxor + {BytecodeDisasmInfo::afIInc, "iinc"}, // 84 vv cc iinc v,c + {BytecodeDisasmInfo::afNone, "i2l"}, // 85 i2l + {BytecodeDisasmInfo::afNone, "i2f"}, // 86 i2f + {BytecodeDisasmInfo::afNone, "i2d"}, // 87 i2d + {BytecodeDisasmInfo::afNone, "l2i"}, // 88 l2i + {BytecodeDisasmInfo::afNone, "l2f"}, // 89 l2f + {BytecodeDisasmInfo::afNone, "l2d"}, // 8A l2d + {BytecodeDisasmInfo::afNone, "f2i"}, // 8B f2i + {BytecodeDisasmInfo::afNone, "f2l"}, // 8C f2l + {BytecodeDisasmInfo::afNone, "f2d"}, // 8D f2d + {BytecodeDisasmInfo::afNone, "d2i"}, // 8E d2i + {BytecodeDisasmInfo::afNone, "d2l"}, // 8F d2l + {BytecodeDisasmInfo::afNone, "d2f"}, // 90 d2f + {BytecodeDisasmInfo::afNone, "i2b"}, // 91 i2b + {BytecodeDisasmInfo::afNone, "i2c"}, // 92 i2c + {BytecodeDisasmInfo::afNone, "i2s"}, // 93 i2s + {BytecodeDisasmInfo::afNone, "lcmp"}, // 94 lcmp + {BytecodeDisasmInfo::afNone, "fcmpl"}, // 95 fcmpl + {BytecodeDisasmInfo::afNone, "fcmpg"}, // 96 fcmpg + {BytecodeDisasmInfo::afNone, "dcmpl"}, // 97 dcmpl + {BytecodeDisasmInfo::afNone, "dcmpg"}, // 98 dcmpg + {BytecodeDisasmInfo::afDisp, "ifeq"}, // 99 dddd ifeq + {BytecodeDisasmInfo::afDisp, "ifne"}, // 9A dddd ifne + {BytecodeDisasmInfo::afDisp, "iflt"}, // 9B dddd iflt + {BytecodeDisasmInfo::afDisp, "ifge"}, // 9C dddd ifge + {BytecodeDisasmInfo::afDisp, "ifgt"}, // 9D dddd ifgt + {BytecodeDisasmInfo::afDisp, "ifle"}, // 9E dddd ifle + {BytecodeDisasmInfo::afDisp, "if_icmpeq"}, // 9F dddd if_icmpeq + {BytecodeDisasmInfo::afDisp, "if_icmpne"}, // A0 dddd if_icmpne + {BytecodeDisasmInfo::afDisp, "if_icmplt"}, // A1 dddd if_icmplt + {BytecodeDisasmInfo::afDisp, "if_icmpge"}, // A2 dddd if_icmpge + {BytecodeDisasmInfo::afDisp, "if_icmpgt"}, // A3 dddd if_icmpgt + {BytecodeDisasmInfo::afDisp, "if_icmple"}, // A4 dddd if_icmple + {BytecodeDisasmInfo::afDisp, "if_acmpeq"}, // A5 dddd if_acmpeq + {BytecodeDisasmInfo::afDisp, "if_acmpne"}, // A6 dddd if_acmpne + {BytecodeDisasmInfo::afDisp, "goto"}, // A7 dddd goto + {BytecodeDisasmInfo::afDisp, "jsr"}, // A8 dddd jsr + {BytecodeDisasmInfo::afVar, "ret"}, // A9 vv ret v + {BytecodeDisasmInfo::afTableSwitch, "tableswitch"}, // AA ... tableswitch + {BytecodeDisasmInfo::afLookupSwitch, "lookupswitch"}, // AB ... lookupswitch + {BytecodeDisasmInfo::afNone, "ireturn"}, // AC ireturn + {BytecodeDisasmInfo::afNone, "lreturn"}, // AD lreturn + {BytecodeDisasmInfo::afNone, "freturn"}, // AE freturn + {BytecodeDisasmInfo::afNone, "dreturn"}, // AF dreturn + {BytecodeDisasmInfo::afNone, "areturn"}, // B0 areturn + {BytecodeDisasmInfo::afNone, "return"}, // B1 return + {BytecodeDisasmInfo::afHalfConstIndex, "getstatic"}, // B2 iiii getstatic + {BytecodeDisasmInfo::afHalfConstIndex, "putstatic"}, // B3 iiii putstatic + {BytecodeDisasmInfo::afHalfConstIndex, "getfield"}, // B4 iiii getfield + {BytecodeDisasmInfo::afHalfConstIndex, "putfield"}, // B5 iiii putfield + {BytecodeDisasmInfo::afHalfConstIndex, "invokevirtual"}, // B6 iiii invokevirtual + {BytecodeDisasmInfo::afHalfConstIndex, "invokespecial"}, // B7 iiii invokespecial + {BytecodeDisasmInfo::afHalfConstIndex, "invokestatic"}, // B8 iiii invokestatic + {BytecodeDisasmInfo::afInvokeInterface, "invokeinterface"}, // B9 iiii nn00 invokeinterface + {BytecodeDisasmInfo::afIllegal, "????"}, // BA unused + {BytecodeDisasmInfo::afHalfConstIndex, "new"}, // BB iiii new + {BytecodeDisasmInfo::afNewArray, "newarray"}, // BC tt newarray + {BytecodeDisasmInfo::afHalfConstIndex, "anewarray"}, // BD iiii anewarray + {BytecodeDisasmInfo::afNone, "arraylength"}, // BE arraylength + {BytecodeDisasmInfo::afNone, "athrow"}, // BF athrow + {BytecodeDisasmInfo::afHalfConstIndex, "checkcast"}, // C0 iiii checkcast + {BytecodeDisasmInfo::afHalfConstIndex, "instanceof"}, // C1 iiii instanceof + {BytecodeDisasmInfo::afNone, "monitorenter"}, // C2 monitorenter + {BytecodeDisasmInfo::afNone, "monitorexit"}, // C3 monitorexit + {BytecodeDisasmInfo::afWide, "wide"}, // C4 ... wide + {BytecodeDisasmInfo::afMultiANewArray, "multianewarray"}, // C5 iiii nn multianewarray + {BytecodeDisasmInfo::afDisp, "ifnull"}, // C6 dddd ifnull + {BytecodeDisasmInfo::afDisp, "ifnonnull"}, // C7 dddd ifnonnull + {BytecodeDisasmInfo::afWideDisp, "goto_w"}, // C8 dddddddd goto_w + {BytecodeDisasmInfo::afWideDisp, "jsr_w"}, // C9 dddddddd jsr_w + {BytecodeDisasmInfo::afNone, "breakpoint"}, // CA breakpoint + {BytecodeDisasmInfo::afIllegal, "????"}, // CB unused + {BytecodeDisasmInfo::afIllegal, "????"}, // CC unused + {BytecodeDisasmInfo::afIllegal, "????"}, // CD unused + {BytecodeDisasmInfo::afIllegal, "????"}, // CE unused + {BytecodeDisasmInfo::afIllegal, "????"}, // CF unused + {BytecodeDisasmInfo::afIllegal, "????"}, // D0 unused + {BytecodeDisasmInfo::afIllegal, "????"}, // D1 unused + {BytecodeDisasmInfo::afIllegal, "????"}, // D2 unused + {BytecodeDisasmInfo::afIllegal, "????"}, // D3 unused + {BytecodeDisasmInfo::afIllegal, "????"}, // D4 unused + {BytecodeDisasmInfo::afIllegal, "????"}, // D5 unused + {BytecodeDisasmInfo::afIllegal, "????"}, // D6 unused + {BytecodeDisasmInfo::afIllegal, "????"}, // D7 unused + {BytecodeDisasmInfo::afIllegal, "????"}, // D8 unused + {BytecodeDisasmInfo::afIllegal, "????"}, // D9 unused + {BytecodeDisasmInfo::afIllegal, "????"}, // DA unused + {BytecodeDisasmInfo::afIllegal, "????"}, // DB unused + {BytecodeDisasmInfo::afIllegal, "????"}, // DC unused + {BytecodeDisasmInfo::afIllegal, "????"}, // DD unused + {BytecodeDisasmInfo::afIllegal, "????"}, // DE unused + {BytecodeDisasmInfo::afIllegal, "????"}, // DF unused + {BytecodeDisasmInfo::afIllegal, "????"}, // E0 unused + {BytecodeDisasmInfo::afIllegal, "????"}, // E1 unused + {BytecodeDisasmInfo::afIllegal, "????"}, // E2 unused + {BytecodeDisasmInfo::afIllegal, "????"}, // E3 unused + {BytecodeDisasmInfo::afIllegal, "????"}, // E4 unused + {BytecodeDisasmInfo::afIllegal, "????"}, // E5 unused + {BytecodeDisasmInfo::afIllegal, "????"}, // E6 unused + {BytecodeDisasmInfo::afIllegal, "????"}, // E7 unused + {BytecodeDisasmInfo::afIllegal, "????"}, // E8 unused + {BytecodeDisasmInfo::afIllegal, "????"}, // E9 unused + {BytecodeDisasmInfo::afIllegal, "????"}, // EA unused + {BytecodeDisasmInfo::afIllegal, "????"}, // EB unused + {BytecodeDisasmInfo::afIllegal, "????"}, // EC unused + {BytecodeDisasmInfo::afIllegal, "????"}, // ED unused + {BytecodeDisasmInfo::afIllegal, "????"}, // EE unused + {BytecodeDisasmInfo::afIllegal, "????"}, // EF unused + {BytecodeDisasmInfo::afIllegal, "????"}, // F0 unused + {BytecodeDisasmInfo::afIllegal, "????"}, // F1 unused + {BytecodeDisasmInfo::afIllegal, "????"}, // F2 unused + {BytecodeDisasmInfo::afIllegal, "????"}, // F3 unused + {BytecodeDisasmInfo::afIllegal, "????"}, // F4 unused + {BytecodeDisasmInfo::afIllegal, "????"}, // F5 unused + {BytecodeDisasmInfo::afIllegal, "????"}, // F6 unused + {BytecodeDisasmInfo::afIllegal, "????"}, // F7 unused + {BytecodeDisasmInfo::afIllegal, "????"}, // F8 unused + {BytecodeDisasmInfo::afIllegal, "????"}, // F9 unused + {BytecodeDisasmInfo::afIllegal, "????"}, // FA unused + {BytecodeDisasmInfo::afIllegal, "????"}, // FB unused + {BytecodeDisasmInfo::afIllegal, "????"}, // FC unused + {BytecodeDisasmInfo::afIllegal, "????"}, // FD unused + {BytecodeDisasmInfo::afIllegal, "????"}, // FE unused + {BytecodeDisasmInfo::afIllegal, "????"} // FF unused +}; + + +// +// If c is non-nil, disassemble the constant pool index symbolically using the information +// in c. If c is nil, print the index preceded by an '@' sign. +// +static void printConstantPoolIndex(LogModuleObject &f, Uint32 index, const ConstantPool *c) +{ + if (c) + c->printItem(f, index); + else + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("@%u", index)); +} + + +// +// Disassemble the alignment bytes and default target for a tableswitch +// or lookupswitch instruction and print them on the output stream f. +// origin is the address of the first bytecode in the function (and must +// be word-aligned). bc is base+1. The base and the instruction's first +// byte has already been printed on f. +// Return the address of the npairs or lowbyte word. +// +static const bytecode *disasmAlignAndDefault(LogModuleObject &f, const bytecode *bc, const bytecode *base, + const bytecode *origin, const char *name, int margin) +{ + int nPadBytes = -(int)bc & 3; + for (int i = 0; i != 3; i++) + if (i < nPadBytes) { + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("%.2X ", *(Uint8 *)bc)); + bc++; + } else + UT_OBJECTLOG(f, PR_LOG_ALWAYS, (" ")); + UT_OBJECTLOG(f, PR_LOG_ALWAYS, (" %s\n", name)); + + printMargin(f, margin); + Int32 d = readBigSWord(bc); + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("%.4X: %.8X default -> 0x%.4X\n", bc - origin, d, d + (base - origin))); + bc += 4; + printMargin(f, margin); + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("%.4X: ", bc - origin)); + return bc; +} + + +// +// Disassemble a single Java tableswitch bytecode starting at base and print it +// on the output stream f. origin is the address of the first bytecode in +// the function (and must be word-aligned). bc is base+1. The base and the +// instruction's first byte has already been printed on f. +// Return the address of the next bytecode. +// +static const bytecode *disasmTableSwitch(LogModuleObject &f, const bytecode *bc, const bytecode *base, const bytecode *origin, int margin) +{ + bc = disasmAlignAndDefault(f, bc, base, origin, "tableswitch", margin); + Int32 low = readBigSWord(bc); + bc += 4; + Int32 high = readBigSWord(bc); + bc += 4; + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("%.8X %.8X", low, high)); + if (low <= high) + while (true) { + Int32 d = readBigSWord(bc); + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("\n")); + printMargin(f, margin); + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("%.4X: %.8X %d -> 0x%.4X", bc - origin, d, low, d + (base - origin))); + bc += 4; + if (low == high) + break; + low++; + } + return bc; +} + + +// +// Disassemble a single Java lookupswitch bytecode starting at base and print it +// on the output stream f. origin is the address of the first bytecode in +// the function (and must be word-aligned). bc is base+1. The base and the +// instruction's first byte has already been printed on f. +// Return the address of the next bytecode. +// +static const bytecode *disasmLookupSwitch(LogModuleObject &f, const bytecode *bc, const bytecode *base, const bytecode *origin, int margin) +{ + bc = disasmAlignAndDefault(f, bc, base, origin, "lookupswitch", margin); + Int32 nPairs = readBigSWord(bc); + bc += 4; + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("%.8X", nPairs)); + while (nPairs > 0) { + Int32 match = readBigSWord(bc); + Int32 d = readBigSWord(bc + 4); + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("\n")); + printMargin(f, margin); + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("%.4X: %.8X %.8X %d -> 0x%.4X", bc - origin, match, d, match, d + (base - origin))); + bc += 8; + nPairs--; + } + return bc; +} + + +// +// Disassemble a single Java bytecode starting at bc and print it as a complete +// line on the output stream f. origin is the address of the first bytecode in +// the function (and must be word-aligned). +// If c is non-nil, disassemble constant pool indices symbolically using the information +// in c. +// Return the address of the next bytecode. +// +const bytecode *disassembleBytecode(LogModuleObject &f, const bytecode *bc, const bytecode *origin, + const ConstantPool *c, int margin) +{ + assert(((size_t)origin & 3) == 0); // Make sure that origin is word-aligned. + + const bytecode *base = bc; + bytecode b = *bc++; + printMargin(f, margin); + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("%.4X: %.2X ", base - origin, b)); + const BytecodeDisasmInfo &bdi = bytecodeDisasmInfos[b]; + Int32 i; + Uint32 u; + Uint32 n; + const char *s; + + switch (bdi.format) { + + case BytecodeDisasmInfo::afSByte: + i = *(Int8 *)bc; + bc++; + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("%.2X %s %d", i & 0xFF, bdi.name, i)); + break; + + case BytecodeDisasmInfo::afSHalf: + i = readBigSHalfwordUnaligned(bc); + bc += 2; + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("%.4X %s %d", i & 0xFFFF, bdi.name, i)); + break; + + case BytecodeDisasmInfo::afByteConstIndex: + u = *(Uint8 *)bc; + bc++; + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("%.2X %s ", u, bdi.name)); + printConstantPoolIndex(f, u, c); + break; + + case BytecodeDisasmInfo::afHalfConstIndex: + u = readBigUHalfwordUnaligned(bc); + bc += 2; + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("%.4X %s ", u, bdi.name)); + printConstantPoolIndex(f, u, c); + break; + + case BytecodeDisasmInfo::afVar: + u = *(Uint8 *)bc; + bc++; + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("%.2X %s %u", u, bdi.name, u)); + break; + + case BytecodeDisasmInfo::afIInc: + u = *(Uint8 *)bc; + bc++; + i = *(Int8 *)bc; + bc++; + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("%.2X %.2X %s %u,%d", u, i & 0xFF, bdi.name, u, i)); + break; + + case BytecodeDisasmInfo::afDisp: + i = readBigSHalfwordUnaligned(bc); + bc += 2; + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("%.4X %s 0x%.4X", i & 0xFFFF, bdi.name, i + (base - origin))); + break; + + case BytecodeDisasmInfo::afWideDisp: + i = readBigSWordUnaligned(bc); + bc += 4; + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("%.8X %s 0x%.4X", i, bdi.name, i + (base - origin))); + break; + + case BytecodeDisasmInfo::afTableSwitch: + bc = disasmTableSwitch(f, bc, base, origin, margin); + break; + + case BytecodeDisasmInfo::afLookupSwitch: + bc = disasmLookupSwitch(f, bc, base, origin, margin); + break; + + case BytecodeDisasmInfo::afInvokeInterface: + u = readBigUHalfwordUnaligned(bc); + bc += 2; + n = *(Uint8 *)bc; + bc++; + i = *(Uint8 *)bc; + bc++; + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("%.4X %.2X %.2X %s ", u, n, i, bdi.name)); + printConstantPoolIndex(f, u, c); + UT_OBJECTLOG(f, PR_LOG_ALWAYS, (", %d", n)); + break; + + case BytecodeDisasmInfo::afNewArray: + u = *(Uint8 *)bc; + bc++; + switch (u) { + case 4: s = "T_BOOLEAN"; break; + case 5: s = "T_CHAR"; break; + case 6: s = "T_FLOAT"; break; + case 7: s = "T_DOUBLE"; break; + case 8: s = "T_BYTE"; break; + case 9: s = "T_SHORT"; break; + case 10: s = "T_INT"; break; + case 11: s = "T_LONG"; break; + default: s = "????"; + } + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("%.2X %s %s", u, bdi.name, s)); + break; + + case BytecodeDisasmInfo::afMultiANewArray: + u = readBigUHalfwordUnaligned(bc); + bc += 2; + n = *(Uint8 *)bc; + bc++; + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("%.4X %.2X %s ", u, n, bdi.name)); + printConstantPoolIndex(f, u, c); + UT_OBJECTLOG(f, PR_LOG_ALWAYS, (", %d", n)); + break; + + case BytecodeDisasmInfo::afWide: + { + b = *bc++; + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("%.2X ", b)); + const BytecodeDisasmInfo &bdi = bytecodeDisasmInfos[b]; + switch (bdi.format) { + case BytecodeDisasmInfo::afVar: + u = readBigUHalfwordUnaligned(bc); + bc += 2; + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("%.4X wide %s %d", u, bdi.name, u)); + break; + case BytecodeDisasmInfo::afIInc: + u = readBigUHalfwordUnaligned(bc); + bc += 2; + i = readBigSHalfwordUnaligned(bc); + bc += 2; + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("%.2X %.2X wide %s %u,%d", u, i & 0xFFFF, bdi.name, u, i)); + break; + default: + UT_OBJECTLOG(f, PR_LOG_ALWAYS, (" wide ????")); + } + } + break; + + default: + UT_OBJECTLOG(f, PR_LOG_ALWAYS, (" %s", bdi.name)); + } + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("\n")); + return bc; +} + + +// +// Disassemble Java bytecodes starting from begin (inclusive) up to end (exclusive) +// and print them as complete lines on the output stream f. origin is the address +// of the first bytecode in the function (and must be word-aligned). +// If c is non-nil, disassemble constant pool indices symbolically using the information +// in c. +// +void disassembleBytecodes(LogModuleObject &f, const bytecode *begin, const bytecode *end, const bytecode *origin, + const ConstantPool *c, int margin) +{ + while (begin < end) + begin = disassembleBytecode(f, begin, origin, c, margin); + assert(begin == end); +} + + +// +// Disassemble nExceptionEntries exception entries starting at exceptionEntries +// and print them on the output stream f. +// If c is non-nil, disassemble constant pool indices symbolically using the information +// in c. +// +void disassembleExceptions(LogModuleObject &f, Uint32 nExceptionEntries, const ExceptionItem *exceptionEntries, + const ConstantPool *c, int margin) +{ + if (nExceptionEntries) { + printMargin(f, margin); + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("Exception handlers:\n")); + while (nExceptionEntries--) { + printMargin(f, margin + 4); + UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("%.4X-%.4X, ", exceptionEntries->startPc, exceptionEntries->endPc)); + printConstantPoolIndex(f, exceptionEntries->catchType, c); + UT_OBJECTLOG(f, PR_LOG_ALWAYS, (" -> %.4X\n", exceptionEntries->handlerPc)); + exceptionEntries++; + } + } +} +#endif diff --git a/ef/Utilities/General/JavaBytecodes.h b/ef/Utilities/General/JavaBytecodes.h new file mode 100644 index 000000000000..c30398b33289 --- /dev/null +++ b/ef/Utilities/General/JavaBytecodes.h @@ -0,0 +1,311 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#ifndef JAVABYTECODES_H +#define JAVABYTECODES_H + +#include "Fundamentals.h" +#include "LogModule.h" + +typedef unsigned char bytecode; + +enum BytecodeOpcode +{ + bcNop, + bcAConst_Null, + bcIConst_m1, + bcIConst_0, + bcIConst_1, + bcIConst_2, + bcIConst_3, + bcIConst_4, + bcIConst_5, + bcLConst_0, + bcLConst_1, + bcFConst_0, + bcFConst_1, + bcFConst_2, + bcDConst_0, + bcDConst_1, + bcBIPush, + bcSIPush, + bcLdc, + bcLdc_W, + bcLdc2_W, + bcILoad, + bcLLoad, + bcFLoad, + bcDLoad, + bcALoad, + bcILoad_0, + bcILoad_1, + bcILoad_2, + bcILoad_3, + bcLLoad_0, + bcLLoad_1, + bcLLoad_2, + bcLLoad_3, + bcFLoad_0, + bcFLoad_1, + bcFLoad_2, + bcFLoad_3, + bcDLoad_0, + bcDLoad_1, + bcDLoad_2, + bcDLoad_3, + bcALoad_0, + bcALoad_1, + bcALoad_2, + bcALoad_3, + bcIALoad, + bcLALoad, + bcFALoad, + bcDALoad, + bcAALoad, + bcBALoad, + bcCALoad, + bcSALoad, + bcIStore, + bcLStore, + bcFStore, + bcDStore, + bcAStore, + bcIStore_0, + bcIStore_1, + bcIStore_2, + bcIStore_3, + bcLStore_0, + bcLStore_1, + bcLStore_2, + bcLStore_3, + bcFStore_0, + bcFStore_1, + bcFStore_2, + bcFStore_3, + bcDStore_0, + bcDStore_1, + bcDStore_2, + bcDStore_3, + bcAStore_0, + bcAStore_1, + bcAStore_2, + bcAStore_3, + bcIAStore, + bcLAStore, + bcFAStore, + bcDAStore, + bcAAStore, + bcBAStore, + bcCAStore, + bcSAStore, + bcPop, + bcPop2, + bcDup, + bcDup_x1, + bcDup_x2, + bcDup2, + bcDup2_x1, + bcDup2_x2, + bcSwap, + bcIAdd, + bcLAdd, + bcFAdd, + bcDAdd, + bcISub, + bcLSub, + bcFSub, + bcDSub, + bcIMul, + bcLMul, + bcFMul, + bcDMul, + bcIDiv, + bcLDiv, + bcFDiv, + bcDDiv, + bcIRem, + bcLRem, + bcFRem, + bcDRem, + bcINeg, + bcLNeg, + bcFNeg, + bcDNeg, + bcIShl, + bcLShl, + bcIShr, + bcLShr, + bcIUShr, + bcLUShr, + bcIAnd, + bcLAnd, + bcIOr, + bcLOr, + bcIXor, + bcLXor, + bcIInc, + bcI2L, + bcI2F, + bcI2D, + bcL2I, + bcL2F, + bcL2D, + bcF2I, + bcF2L, + bcF2D, + bcD2I, + bcD2L, + bcD2F, + bcInt2Byte, + bcInt2Char, + bcInt2Short, + bcLCmp, + bcFCmpL, + bcFCmpG, + bcDCmpL, + bcDCmpG, + bcIfEq, + bcIfNe, + bcIfLt, + bcIfGe, + bcIfGt, + bcIfLe, + bcIf_ICmpEq, + bcIf_ICmpNe, + bcIf_ICmpLt, + bcIf_ICmpGe, + bcIf_ICmpGt, + bcIf_ICmpLe, + bcIf_ACmpEq, + bcIf_ACmpNe, + bcGoto, + bcJsr, + bcRet, + bcTableSwitch, + bcLookupSwitch, + bcIReturn, + bcLReturn, + bcFReturn, + bcDReturn, + bcAReturn, + bcReturn, + bcGetStatic, + bcPutStatic, + bcGetField, + bcPutField, + bcInvokeVirtual, + bcInvokeSpecial, + bcInvokeStatic, + bcInvokeInterface, + bc_unused_, + bcNew, + bcNewArray, + bcANewArray, + bcArrayLength, + bcAThrow, + bcCheckCast, + bcInstanceOf, + bcMonitorEnter, + bcMonitorExit, + bcWide, + bcMultiANewArray, + bcIfNull, + bcIfNonnull, + bcGoto_W, + bcJsr_W, + bcBreakpoint +}; + + +// Types for newarray bytecode +enum NewArrayType +{ + natBoolean = 4, + natChar, + natFloat, + natDouble, + natByte, + natShort, + natInt, + natLong +}; +const uint natMin = natBoolean; +const uint natLimit = natLong + 1; + + +struct BytecodeControlInfo +{ + enum Kind // Categories of bytecodes + { + bckNormal, // Any bytecode that can't branch anywhere + bckThrow, // A bytecode that always causes an exception + bckExc, // A bytecode that can cause an exception + bckGoto, // bcGoto + bckGoto_W, // bcGoto_W + bckIf, // Any of the if bytecodes + bckTableSwitch, // bcTableSwitch + bckLookupSwitch, // bcLookupSwitch + bckReturn, // Any of the return bytecodes + bckJsr, // bcJsr + bckJsr_W, // bcJsr_W + bckRet, // bcRet + bckRet_W, // wide bcRet + bckIllegal // Any bytecode that's not defined by the Java spec + }; + + Kind kind ENUM_8; // Kind of bytecode + Uint8 size; // Size of bytecode in bytes + // (1 for bcTableSwitch, bcLookupSwitch, and illegal; 2 for wide illegal) +}; + +extern const BytecodeControlInfo normalBytecodeControlInfos[256]; +extern const BytecodeControlInfo wideBytecodeControlInfos[256]; +const BytecodeControlInfo &getBytecodeControlInfo(const bytecode *bc); + + +#ifdef DEBUG_LOG +class ConstantPool; +struct ExceptionItem; + +const bytecode *disassembleBytecode(LogModuleObject &f, const bytecode *bc, const bytecode *origin, const ConstantPool *c, int margin); +void disassembleBytecodes(LogModuleObject &f, const bytecode *begin, const bytecode *end, const bytecode *origin, const ConstantPool *c, + int margin); +void disassembleExceptions(LogModuleObject &f, Uint32 nExceptionEntries, const ExceptionItem *exceptionEntries, const ConstantPool *c, + int margin); +#endif + + +// --- INLINES ---------------------------------------------------------------- + + +// +// Return the BytecodeControlInfo corresponding to the bytecode instruction that +// starts at the given address. The kind and size fields of the BytecodeControlInfo +// will be correct except for the tableswitch and lookupswitch instructions, for +// which the size will be 1. +// +inline const BytecodeControlInfo &getBytecodeControlInfo(const bytecode *bc) +{ + bytecode b = bc[0]; + if (b != bcWide) + return normalBytecodeControlInfos[b]; + else + return wideBytecodeControlInfos[bc[1]]; +} + +#endif diff --git a/ef/Utilities/General/LogModule.cpp b/ef/Utilities/General/LogModule.cpp new file mode 100644 index 000000000000..f756c6806028 --- /dev/null +++ b/ef/Utilities/General/LogModule.cpp @@ -0,0 +1,127 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +// LogModule.cpp +// +// Scott M. Silver +// + + +#include +#include +#include +#include "prthread.h" +#include "prprf.h" +#include "LogModule.h" + +#ifdef LOGMODULE_CLASS_IS_DEFINED + +#define DEFAULT_LOG_FILENAME "ef.log" + +// Default log file, if no module-specific files defined +static FILE* defaultLogFile = NULL; + +LogModuleObject *LogModuleObject::allLogModules = NULL; + +LogModuleObject:: +LogModuleObject(const char* inModuleName, PRLogModuleOptions inOptions) +{ + name = strdup(inModuleName); + level = PR_LOG_NONE; + options = inOptions; + file = NULL; + + // Add this module to the chain of all logging modules + next = allLogModules; + allLogModules = this; +} + +LogModuleObject:: +~LogModuleObject() +{ + if (name) + free((void*)name); + if (file) + fclose(file); +} + +FILE *LogModuleObject:: +getFile() const +{ + if (file) + return file; + if (!defaultLogFile) + defaultLogFile = fopen(DEFAULT_LOG_FILENAME, "w"); + return defaultLogFile; +} + +size_t LogModuleObject:: +logPrint(const char* inFormat, ...) const +{ + char *msg; + size_t num_chars; + PRThread *me; + + va_list ap; + + va_start(ap, inFormat); + + if (options & PR_LOG_OPTION_SHOW_THREAD_ID) { + char *format; + + me = PR_GetCurrentThread(); + format = PR_smprintf("[%p]: %s", me, inFormat); + if (!format) + return 0; + msg = PR_vsmprintf(format, ap); + PR_smprintf_free(format); + } else { + msg = PR_vsmprintf(inFormat, ap); + } + + if (!msg) + return 0; + + num_chars = strlen(msg); + + FILE *f = getFile(); + PR_ASSERT(f); + if (!f) + return 0; + + fputs(msg, f); + if (options & PR_LOG_OPTION_ADD_NEWLINE) + fputs("\n", f); + + PR_smprintf_free(msg); + + return num_chars; +} + +bool LogModuleObject:: +setLogFile(const char* inFileName) +{ + if (file) + fclose(file); + file = fopen(inFileName, "w"); + return (file != NULL); +} +#endif + + + diff --git a/ef/Utilities/General/LogModule.h b/ef/Utilities/General/LogModule.h new file mode 100644 index 000000000000..2a6dfc848717 --- /dev/null +++ b/ef/Utilities/General/LogModule.h @@ -0,0 +1,154 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +// LogModule.h +// +// Scott M. Silver +// + +// PRLogModuleInfo wrapper + +// Usage: +// +// UT_DEFINE_MODULE(MyNewModuleName); // notice no quotes +// +// void test() +// { +// UT_LOG(MyNewModuleName, PR_LOG_ALWAYS, ("%s", "Hello World")); +// } +// +// This will do the appropriate logging to a module named "MyNewModuleName" +// as defined in "prlog.h". See "prlog.h" for how to turn on this +// LogModule (as in make its output visible to the user). +// +// If you wish to share a particular module across file boundaries +// use the UT_LOG_MODULE macro in a ".cpp" file, and then use +// the UT_EXTERN_LOG_MODULE macro in a header (or a ".cpp" file) to +// share the module. +// +// Theoretically adding the appropriate decorator for dll exportation +// is possible too, but has not been tested. +// +// If you wish to pass around a LogModule, you need to +// make your function take a LogModuleObject as a parameter, and then +// use the UT_OBJECTLOG function instead of UT_LOG to log some data. +// For example: +// +// UT_DEFINE_MODULE(MyNewModuleName); +// +// void main() +// { +// test2(UT_LOG_MODULE(MyNewModuleName); +// } +// +// void test2(LogModuleObject inModuleObject) +// { +// UT_OBJECTLOG(inModuleObject, PR_LOG_ALWAYS, ("%s", "Hello World")); +// } +// +// All the UT* stuff in _this_ file disappears when PR_LOGGING is not defined +// The actual LogModule objects are created as global objects named +// g__MyNewModuleName. +// +// UT = Utility + +#ifndef _H_LOGMODULE +#define _H_LOGMODULE + +#include "prlog.h" +#include "Exports.h" + +#define PR_LOG_OPTION_NIL 0x0000 +#define PR_LOG_OPTION_SHOW_THREAD_ID 0x0001 +#define PR_LOG_OPTION_ADD_NEWLINE 0x0002 +#define PR_LOG_OPTION_DEFAULT (PR_LOG_OPTION_SHOW_THREAD_ID | PR_LOG_OPTION_ADD_NEWLINE) +typedef PRUint16 PRLogModuleOptions; + +#ifdef PR_LOGGING + +// Don't use this class directly, use the UT_* macros below +#define LOGMODULE_CLASS_IS_DEFINED + +class NS_EXTERN LogModuleObject +{ + const char * name; + PRLogModuleLevel level; + PRLogModuleOptions options; + FILE * file; + LogModuleObject* next; + + static LogModuleObject *allLogModules; + +public: + LogModuleObject(const char* inModuleName, + PRLogModuleOptions inOptions = PR_LOG_OPTION_DEFAULT); + ~LogModuleObject(); + + bool setLogFile(const char* inFileName); + size_t logPrint(const char* inFormat, ...) const; + void setLogLevel(PRLogModuleLevel inLevel) { level = inLevel; } + void setOptions(PRLogModuleOptions inOptions) { options = inOptions; } + PRLogModuleLevel getLogLevel() {return level;} + const char *getName() { return name; } + LogModuleObject* getNext() { return next; } + static LogModuleObject* getAllLogModules() { return allLogModules; } + FILE * getFile() const; +}; + +#define UT_DEFINE_LOG_MODULE(inModuleName) LogModuleObject g__##inModuleName(#inModuleName) +#define UT_LOG(inModule, inLevel, inArgs) UT_OBJECTLOG(g__##inModule, inLevel, inArgs) +#define UT_EXTERN_LOG_MODULE(inModuleName) extern LogModuleObject g__##inModuleName +#define UT_OBJECTLOG(inModuleObject, inLevel, inArgs) \ + (UT_LOG_TEST(inModuleObject, inLevel) ? inModuleObject.logPrint inArgs : 0) +#define UT_LOG_MODULE(inModule) g__##inModule +#define UT_SET_LOG_LEVEL(inModuleName, inLevel) g__##inModuleName.setLogLevel(inLevel) +#define UT_GET_LOG_NAME(inModuleName) g__##inModuleName.getName() +#define UT_LOG_TEST(inModule, inLevel) ((inModule).getLogLevel() >= (inLevel)) +#else + +typedef int LogModuleObject; // this needs to stay around because it might be + // passed as a parameter + +#define UT_DEFINE_LOG_MODULE(inModule) +#define UT_LOG(inModule, inLevel, inArgs) 0 +#define UT_EXTERN_LOG_MODULE(inModule) +#define UT_OBJECTLOG(inModuleObject, inLevel, inArgs) 0 +#define UT_SET_LOG_LEVEL(inModuleName, inLevel) +#define UT_GET_LOG_NAME(inModuleName) +#define UT_LOG_TEST(inModule, inLevel) 0 + +// since LogModule is an int when PR_LOGGING is off, we pass a 0 +const int g__Garbage39393 = 0; +#define UT_LOG_MODULE(inModule) g__Garbage39393 + + +#endif // PR_LOGGING + +#endif // _H_LOGMODULE + + + + + + + + + + + + diff --git a/ef/Utilities/General/Makefile b/ef/Utilities/General/Makefile new file mode 100644 index 000000000000..46f4a5945a4f --- /dev/null +++ b/ef/Utilities/General/Makefile @@ -0,0 +1,93 @@ +#!gmake +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +####################################################################### +# (1) Directory specific info # +####################################################################### + +DEPTH = ../.. + +MODULE_NAME = EF + +DIRS = md + +CPPSRCS = CUtils.cpp \ + DebugUtils.cpp \ + FastBitMatrix.cpp \ + FastBitSet.cpp \ + FloatUtils.cpp \ + InterestingEvents.cpp \ + LogModule.cpp \ + JavaBytecodes.cpp \ + Pool.cpp \ + Tree.cpp \ + $(NULL) + +LOCAL_EXPORTS = CUtils.h \ + CatchAssert.h \ + CheckedUnion.h \ + DebugUtils.h \ + DoublyLinkedList.h \ + Exports.h \ + FastBitMatrix.h \ + FastBitSet.h \ + FastHashTable.h \ + Fifo.h \ + FloatUtils.h \ + Fundamentals.h \ + GraphUtils.h \ + HashTable.h \ + InterestingEvents.h \ + JavaBytecodes.h \ + LogModule.h \ + MemoryAccess.h \ + Multiset.h \ + NewFastBitMatrix.h \ + NewFastBitSet.h \ + Nonspr.h \ + Pool.h \ + StringUtils.h \ + Tree.h \ + Vector.h \ + $(NULL) + +####################################################################### +# (2) Include "component" configuration information. # +####################################################################### + +include $(DEPTH)/config/config.mk + +####################################################################### +# (3) Include "local" platform-dependent assignments (OPTIONAL). # +####################################################################### + +ifeq ($(OS_ARCH),WINNT) +CPPSRCS += CatchAssert.cpp +endif + +####################################################################### +# (4) Execute "component" rules. (OPTIONAL) # +####################################################################### + +include $(DEPTH)/config/rules.mk + +####################################################################### +# (7) Execute "local" rules. (OPTIONAL). # +####################################################################### + + + diff --git a/ef/Utilities/General/MemOps.h b/ef/Utilities/General/MemOps.h new file mode 100644 index 000000000000..9d14a015b998 --- /dev/null +++ b/ef/Utilities/General/MemOps.h @@ -0,0 +1,143 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#ifndef _MEMORY_H_ +#define _MEMORY_H_ + +#include "Fundamentals.h" + +//////////////////////////////////////////////////////////////////////////////// + +#include + +class MallocMemoryOps { +public: + static void* alloc(Uint32 size) { + return ::calloc(1, size); + } + + static void free(void* p) { + ::free(p); + } +}; + +//////////////////////////////////////////////////////////////////////////////// +#if 0 +#include "Pool.h" + +class PoolMemoryOps { +public: + PoolMemoryOps(Pool &pool) : pool(pool) {} + + static void* alloc(Uint32 size) { + return pool.allocate(size); + } + + static void free(void* p) { + // no-op for pools + } + +protected: + Pool &pool; +}; + +//////////////////////////////////////////////////////////////////////////////// + +#include "plarena.h" + +class ArenaMemoryOps { +public: + ArenaMemoryOps(PLArena &arena) : arena(arena) {} + + static void* alloc(Uint32 size) { + void* p; + PL_ARENA_ALLOCATE(p, &arena, size); + return p; + } + + static void free(void* p) { + // no-op for arenas + } + +protected: + PLArena &arena; +}; +#endif // 0 +//////////////////////////////////////////////////////////////////////////////// + +#include "smobj.h" + +class SMMallocMemoryOps { +public: + static void* alloc(Uint32 size) { + return SM_Malloc(size); + } + + static void free(void* p) { + SM_Free(p); + } +}; + +//////////////////////////////////////////////////////////////////////////////// + +class GCObjectArrayMemoryOps { +public: + static void* alloc(Uint32 size) { + return SM_AllocArray(&objectArrayClass, size / sizeof(void*)); + } + + static void free(void* p) { + // no-op for gc + } + + static void init() { + SM_InitObjectClass(&genericObjectClass, NULL, sizeof(SMObjectClass), + 0, 0, 0); + SM_InitArrayClass(&objectArrayClass, NULL, (SMClass*)&genericObjectClass); + } + +protected: + static SMObjectClass genericObjectClass; + static SMArrayClass objectArrayClass; +}; + +//////////////////////////////////////////////////////////////////////////////// + +class GCByteArrayMemoryOps { +public: + static void* alloc(Uint32 size) { + return SM_AllocArray(&byteArrayClass, size); + } + + static void free(void* p) { + // no-op for gc + } + + static void init() { + SM_InitPrimClass(&byteClass, NULL, SMClassKind_ByteClass); + SM_InitArrayClass(&byteArrayClass, NULL, (SMClass*)&byteClass); + } + +protected: + static SMPrimClass byteClass; + static SMArrayClass byteArrayClass; +}; + +//////////////////////////////////////////////////////////////////////////////// + +#endif // _MEMORY_H_ diff --git a/ef/Utilities/General/MemoryAccess.h b/ef/Utilities/General/MemoryAccess.h new file mode 100644 index 000000000000..19bf30f68651 --- /dev/null +++ b/ef/Utilities/General/MemoryAccess.h @@ -0,0 +1,193 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#ifndef MEMORYACCESS_H +#define MEMORYACCESS_H + +// Aligned big-endian memory access +inline Uint16 readBigUHalfword(const void *p); +inline Int16 readBigSHalfword(const void *p); +inline Uint32 readBigUWord(const void *p); +inline Int32 readBigSWord(const void *p); + +inline void writeBigHalfword(void *p, Int16 v); +inline void writeBigWord(void *p, Int32 v); + +// Unaligned big-endian memory access +inline Uint16 readBigUHalfwordUnaligned(const void *p); +inline Int16 readBigSHalfwordUnaligned(const void *p); +inline Uint32 readBigUWordUnaligned(const void *p); +inline Int32 readBigSWordUnaligned(const void *p); + +inline void writeBigHalfwordUnaligned(void *p, Int16 v); +inline void writeBigWordUnaligned(void *p, Int32 v); + +// Aligned little-endian memory access +inline Uint16 readLittleUHalfword(const void *p); +inline Int16 readLittleSHalfword(const void *p); +inline Uint32 readLittleUWord(const void *p); +inline Int32 readLittleSWord(const void *p); + +inline void writeLittleHalfword(void *p, Int16 v); +inline void writeLittleWord(void *p, Int32 v); + +// Unaligned little-endian memory access +inline Uint16 readLittleUHalfwordUnaligned(const void *p); +inline Int16 readLittleSHalfwordUnaligned(const void *p); +inline Uint32 readLittleUWordUnaligned(const void *p); +inline Int32 readLittleSWordUnaligned(const void *p); + +inline void writeLittleHalfwordUnaligned(void *p, Int16 v); +inline void writeLittleWordUnaligned(void *p, Int32 v); + + +// --- INLINES ---------------------------------------------------------------- + + +#ifdef IS_BIG_ENDIAN + inline Uint16 readBigUHalfword(const void *p) {return *static_cast(p);} + inline Int16 readBigSHalfword(const void *p) {return *static_cast(p);} + inline Uint32 readBigUWord(const void *p) {return *static_cast(p);} + inline Int32 readBigSWord(const void *p) {return *static_cast(p);} + + inline void writeBigHalfword(void *p, Int16 v) {*static_cast(p) = v;} + inline void writeBigWord(void *p, Int32 v) {*static_cast(p) = v;} + + #ifdef MISALIGNED_MEMORY_ACCESS_OK + inline Uint16 readBigUHalfwordUnaligned(const void *p) {return *static_cast(p);} + inline Int16 readBigSHalfwordUnaligned(const void *p) {return *static_cast(p);} + inline Uint32 readBigUWordUnaligned(const void *p) {return *static_cast(p);} + inline Int32 readBigSWordUnaligned(const void *p) {return *static_cast(p);} + + inline void writeBigHalfwordUnaligned(void *p, Int16 v) {*static_cast(p) = v;} + inline void writeBigWordUnaligned(void *p, Int32 v) {*static_cast(p) = v;} + + #else + inline Uint16 readBigUHalfwordUnaligned(const void *p) + {const Uint8 *q = static_cast(p); return q[0]<<8 | q[1];} + inline Int16 readBigSHalfwordUnaligned(const void *p) + {const Uint8 *q = static_cast(p); return q[0]<<8 | q[1];} + inline Uint32 readBigUWordUnaligned(const void *p) + {const Uint8 *q = static_cast(p); return q[0]<<24 | q[1]<<16 | q[2]<<8 | q[3];} + inline Int32 readBigSWordUnaligned(const void *p) + {const Uint8 *q = static_cast(p); return q[0]<<24 | q[1]<<16 | q[2]<<8 | q[3];} + + inline void writeBigHalfwordUnaligned(void *p, Int16 v) + {Uint8 *q = static_cast(p); q[0] = (Uint8)(v>>8); q[1] = (Uint8)v;} + inline void writeBigWordUnaligned(void *p, Int32 v) + {Uint8 *q = static_cast(p); + q[0] = (Uint8)(v>>24); q[1] = (Uint8)(v>>16); q[2] = (Uint8)(v>>8); q[3] = (Uint8)v;} + #endif + + inline Uint16 readLittleUHalfword(const void *p) + {const Uint8 *q = static_cast(p); return q[0] | q[1]<<8;} + inline Int16 readLittleSHalfword(const void *p) + {const Uint8 *q = static_cast(p); return q[0] | q[1]<<8;} + inline Uint32 readLittleUWord(const void *p) + {const Uint8 *q = static_cast(p); return q[0] | q[1]<<8 | q[2]<<16 | q[3]<<24;} + inline Int32 readLittleSWord(const void *p) + {const Uint8 *q = static_cast(p); return q[0] | q[1]<<8 | q[2]<<16 | q[3]<<24;} + + inline void writeLittleHalfword(void *p, Int16 v) + {Uint8 *q = static_cast(p); q[0] = (Uint8)v; q[1] = (Uint8)(v>>8);} + inline void writeLittleWord(void *p, Int32 v) + {Uint8 *q = static_cast(p); + q[0] = (Uint8)v; q[1] = (Uint8)(v>>8); q[2] = (Uint8)(v>>16); q[3] = (Uint8)(v>>24);} + + inline Uint16 readLittleUHalfwordUnaligned(const void *p) + {const Uint8 *q = static_cast(p); return q[0] | q[1]<<8;} + inline Int16 readLittleSHalfwordUnaligned(const void *p) + {const Uint8 *q = static_cast(p); return q[0] | q[1]<<8;} + inline Uint32 readLittleUWordUnaligned(const void *p) + {const Uint8 *q = static_cast(p); return q[0] | q[1]<<8 | q[2]<<16 | q[3]<<24;} + inline Int32 readLittleSWordUnaligned(const void *p) + {const Uint8 *q = static_cast(p); return q[0] | q[1]<<8 | q[2]<<16 | q[3]<<24;} + + inline void writeLittleHalfwordUnaligned(void *p, Int16 v) + {Uint8 *q = static_cast(p); q[0] = (Uint8)v; q[1] = (Uint8)(v>>8);} + inline void writeLittleWordUnaligned(void *p, Int32 v) + {Uint8 *q = static_cast(p); + q[0] = (Uint8)v; q[1] = (Uint8)(v>>8); q[2] = (Uint8)(v>>16); q[3] = (Uint8)(v>>24);} + +#else /* !IS_BIG_ENDIAN */ + + inline Uint16 readBigUHalfword(const void *p) + {const Uint8 *q = static_cast(p); return q[0]<<8 | q[1];} + inline Int16 readBigSHalfword(const void *p) + {const Uint8 *q = static_cast(p); return q[0]<<8 | q[1];} + inline Uint32 readBigUWord(const void *p) + {const Uint8 *q = static_cast(p); return q[0]<<24 | q[1]<<16 | q[2]<<8 | q[3];} + inline Int32 readBigSWord(const void *p) + {const Uint8 *q = static_cast(p); return q[0]<<24 | q[1]<<16 | q[2]<<8 | q[3];} + + inline void writeBigHalfword(void *p, Int16 v) + {Uint8 *q = static_cast(p); q[0] = (Uint8)(v>>8); q[1] = (Uint8)v;} + inline void writeBigWord(void *p, Int32 v) + {Uint8 *q = static_cast(p); + q[0] = (Uint8)(v>>24); q[1] = (Uint8)(v>>16); q[2] = (Uint8)(v>>8); q[3] = (Uint8)v;} + + inline Uint16 readBigUHalfwordUnaligned(const void *p) + {const Uint8 *q = static_cast(p); return q[0]<<8 | q[1];} + inline Int16 readBigSHalfwordUnaligned(const void *p) + {const Uint8 *q = static_cast(p); return q[0]<<8 | q[1];} + inline Uint32 readBigUWordUnaligned(const void *p) + {const Uint8 *q = static_cast(p); return q[0]<<24 | q[1]<<16 | q[2]<<8 | q[3];} + inline Int32 readBigSWordUnaligned(const void *p) + {const Uint8 *q = static_cast(p); return q[0]<<24 | q[1]<<16 | q[2]<<8 | q[3];} + + inline void writeBigHalfwordUnaligned(void *p, Int16 v) + {Uint8 *q = static_cast(p); q[0] = (Uint8)(v>>8); q[1] = (Uint8)v;} + inline void writeBigWordUnaligned(void *p, Int32 v) + {Uint8 *q = static_cast(p); + q[0] = (Uint8)(v>>24); q[1] = (Uint8)(v>>16); q[2] = (Uint8)(v>>8); q[3] = (Uint8)v;} + + inline Uint16 readLittleUHalfword(const void *p) {return *static_cast(p);} + inline Int16 readLittleSHalfword(const void *p) {return *static_cast(p);} + inline Uint32 readLittleUWord(const void *p) {return *static_cast(p);} + inline Int32 readLittleSWord(const void *p) {return *static_cast(p);} + + inline void writeLittleHalfword(void *p, Int16 v) {*static_cast(p) = v;} + inline void writeLittleWord(void *p, Int32 v) {*static_cast(p) = v;} + + #ifdef MISALIGNED_MEMORY_ACCESS_OK + inline Uint16 readLittleUHalfwordUnaligned(const void *p) {return *static_cast(p);} + inline Int16 readLittleSHalfwordUnaligned(const void *p) {return *static_cast(p);} + inline Uint32 readLittleUWordUnaligned(const void *p) {return *static_cast(p);} + inline Int32 readLittleSWordUnaligned(const void *p) {return *static_cast(p);} + + inline void writeLittleHalfwordUnaligned(void *p, Int16 v) {*static_cast(p) = v;} + inline void writeLittleWordUnaligned(void *p, Int32 v) {*static_cast(p) = v;} + + #else + inline Uint16 readLittleUHalfwordUnaligned(const void *p) + {const Uint8 *q = static_cast(p); return q[0] | q[1]<<8;} + inline Int16 readLittleSHalfwordUnaligned(const void *p) + {const Uint8 *q = static_cast(p); return q[0] | q[1]<<8;} + inline Uint32 readLittleUWordUnaligned(const void *p) + {const Uint8 *q = static_cast(p); return q[0] | q[1]<<8 | q[2]<<16 | q[3]<<24;} + inline Int32 readLittleSWordUnaligned(const void *p) + {const Uint8 *q = static_cast(p); return q[0] | q[1]<<8 | q[2]<<16 | q[3]<<24;} + + inline void writeLittleHalfwordUnaligned(void *p, Int16 v) + {Uint8 *q = static_cast(p); q[0] = (Uint8)v; q[1] = (Uint8)(v>>8);} + inline void writeLittleWordUnaligned(void *p, Int32 v) + {Uint8 *q = static_cast(p); + q[0] = (Uint8)v; q[1] = (Uint8)(v>>8); q[2] = (Uint8)(v>>16); q[3] = (Uint8)(v>>24);} + #endif +#endif /* IS_BIG_ENDIAN */ +#endif diff --git a/ef/Utilities/General/Multiset.h b/ef/Utilities/General/Multiset.h new file mode 100644 index 000000000000..7333d166101c --- /dev/null +++ b/ef/Utilities/General/Multiset.h @@ -0,0 +1,218 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#ifndef MULTISET_H +#define MULTISET_H + +#include "Fundamentals.h" + +// +// A multiset (i.e. set that can contain the same element more than once) +// with elements of class Elt. Class Elt must provide the following operations: +// +// Copy constructor +// operator== and operator!= +// +// Elt equality must be reflexive (every Elt is equal to itself), symmetric +// (if a==b then b==a), and transitive. +// +// +template +class SimpleMultiset +{ + struct Node + { + Node *next; + Uint32 count; + Elt element; + + Node(Elt element, Uint32 count): count(count), element(element) {} + }; + + Pool &pool; + Node *nodes; + Uint32 nNodes; + + public: + explicit SimpleMultiset(Pool &pool): pool(pool), nodes(0), nNodes(0) {} + SimpleMultiset(const SimpleMultiset &src): pool(src.pool) {copy(src);} + void operator=(const SimpleMultiset &src) {copy(src);} + void move(SimpleMultiset &src); + void clear() {nodes = 0; nNodes = 0;} + + private: + void copy(const SimpleMultiset &src); + public: + + bool empty() const {return !nodes;} + bool operator==(const SimpleMultiset &s) const; + bool operator!=(const SimpleMultiset &s) const {return !operator==(s);} + + Uint32 find(Elt element) const; + Uint32 add(Elt element); + Uint32 remove(Elt element); + + #ifdef DEBUG + void verify() const; + #endif +}; + + +// +// Destructively move the src SimpleMultiset to this SimpleMultiset, leaving the +// src SimpleMultiset empty. +// +template +inline void SimpleMultiset::move(SimpleMultiset &src) +{ + assert(&pool == &src.pool); + nodes = src.nodes; + nNodes = src.nNodes; + src.clear(); + #ifdef DEBUG + verify(); + #endif +} + + +// +// Assign a copy of the src SimpleMultiset to this SimpleMultiset, whose previous +// contents are destroyed. +// +template +inline void SimpleMultiset::copy(const SimpleMultiset &src) +{ + if (&src != this) { + nNodes = src.nNodes; + Node **link = &nodes; + for (const Node *srcNode = src.nodes; srcNode; srcNode = srcNode->next) { + Node *dstNode = new Node(srcNode.element, srcNode.count); + *link = dstNode; + link = &dstNode->next; + } + *link = 0; + } + #ifdef DEBUG + verify(); + #endif +} + + +// +// Return true if this multiset contains the same elements with the same multiplicities +// as multiset s. +// +template +bool SimpleMultiset::operator==(const SimpleMultiset &s) const +{ + if (nNodes != s.nNodes) + return false; + for (const Node *n = nodes; n; n = n->next) + if (s.find(n->element) != n->count) + return false; + return true; +} + + +// +// Return the number of times the element is present in the multiset. This number +// is zero if the element is not present. +// +template +Uint32 SimpleMultiset::find(Elt element) const +{ + for (const Node *n = nodes; n; n = n->next) + if (n->element == element) + return n->count; + return 0; +} + + +// +// Add the element to the multiset. An element can be present multiple times in the +// same multiset. Return the number of times the element was present in the multiset +// before this latest addition. +// +template +Uint32 SimpleMultiset::add(Elt element) +{ + const Node *n; + for (n = nodes; n; n = n->next) + if (n->element == element) + return n->count++; + n = new(pool) Node(element, 1); + n->next = nodes; + nodes = n; + nNodes++; + #ifdef DEBUG + verify(); + #endif + return 0; +} + + +// +// Remove one instance of the element to the multiset. An element can be present +// multiple times in the same multiset. Return the number of times the element was +// present in the multiset before this latest removal. If the element was not +// present at all in the multiset before this removal, do nothing and return 0. +// +template +Uint32 SimpleMultiset::remove(Elt element) +{ + const Node **prev; + const Node *n; + for (prev = &nodes; (n = *prev) != 0; prev = &n->next) + if (n->element == element) { + Uint32 count = n->count--; + if (count == 1) { + *prev = n->next; + nNodes--; + } + #ifdef DEBUG + verify(); + #endif + return count; + } + return 0; +} + + +#ifdef DEBUG +// +// Verify that the multiset is internally consistent. Assert if anything wrong is found. +// +template +void SimpleMultiset::verify() const +{ + // Check nNodes. + Uint32 i = 0; + const Node *n; + for (n = nodes; n; n = n->next) + i++; + assert(i == nNodes); + + // Check that all elements are unique and none has a count of zero. + for (n = nodes; n; n = n->next) { + assert(n->count != 0); + for (const Node *m = n->next; m; m = m->next) + assert(m->element != n->element); + } +} +#endif +#endif diff --git a/ef/Utilities/General/NewFastBitMatrix.cpp b/ef/Utilities/General/NewFastBitMatrix.cpp new file mode 100644 index 000000000000..21fd95498605 --- /dev/null +++ b/ef/Utilities/General/NewFastBitMatrix.cpp @@ -0,0 +1,335 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#include "Fundamentals.h" +#include "FastBitMatrix.h" +#include "FastBitSet.h" +#include "Pool.h" +#include "prbit.h" // for PR_CEILING_LOG2 + + +// +// Resize the matrix. Allocate the words from the given pool. +// +void FastBitMatrix::sizeTo(Pool& pool, Uint32 nRows, Uint32 nCols) +{ + PR_ASSERT(nRows && nCols); + + Uint32 rowSizeInWords = (nCols + 31) >> 5; + this->rowSizeInWords = rowSizeInWords; + Uint8 shift; + + PR_CEILING_LOG2(shift, rowSizeInWords); + + if (shift) // The biggest square matrix we can allocate is Matrix(0x7ffe0,0x7ffe0) (524256). + PR_ASSERT((nRows & ~((1 << (32 - shift)) - 1)) == 0); // Overflow should send a signal (or exception). + + Uint32 newSizeInWords = nRows << shift; + if (newSizeInWords > sizeInWords) { + sizeInWords = newSizeInWords; + bits = new(pool) Uint32[sizeInWords]; + } + rowShift = shift; +#ifdef DEBUG_LOG + this->nCols = nCols; +#endif /* DEBUG_LOG */ +} + +// +// And rows src1 & src2 to row dst +// +void FastBitMatrix::andRows(Uint32 src1, Uint32 src2, Uint32 dst) +{ + PR_ASSERT(sizeInWords); + + Uint32* srcPtr1 = &bits[getRowOffset(src1)]; + Uint32* srcPtr2 = &bits[getRowOffset(src2)]; + Uint32* dstPtr = &bits[getRowOffset(dst)]; + Uint32* limit = &dstPtr[rowSizeInWords]; + + while (dstPtr < limit) + *dstPtr++ = *srcPtr1++ & *srcPtr2++; +} + +// +// And rows src1 & src2 to row dst +// +void FastBitMatrix::andRows(Uint32 src, const FastBitSet& x, Uint32 dst) +{ + PR_ASSERT(sizeInWords && (rowSizeInWords == x.sizeInWords)); + + Uint32* srcPtr1 = &bits[getRowOffset(src)]; + Uint32* srcPtr2 = x.bits; + Uint32* dstPtr = &bits[getRowOffset(dst)]; + Uint32* limit = &srcPtr2[x.sizeInWords]; + + while (srcPtr2 < limit) + *dstPtr++ = *srcPtr1++ & *srcPtr2++; +} + +// +// Or rows src1 & src2 to row dst +// +void FastBitMatrix::orRows(Uint32 src1, Uint32 src2, Uint32 dst) +{ + PR_ASSERT(sizeInWords); + + Uint32* srcPtr1 = &bits[getRowOffset(src1)]; + Uint32* srcPtr2 = &bits[getRowOffset(src2)]; + Uint32* dstPtr = &bits[getRowOffset(dst)]; + Uint32* limit = &dstPtr[rowSizeInWords]; + + while (dstPtr < limit) + *dstPtr++ = *srcPtr1++ | *srcPtr2++; +} + +// +// Or rows src1 & src2 to row dst +// +void FastBitMatrix::orRows(Uint32 src, const FastBitSet& x, Uint32 dst) +{ + PR_ASSERT(sizeInWords && (rowSizeInWords == x.sizeInWords)); + + Uint32* srcPtr1 = &bits[getRowOffset(src)]; + Uint32* srcPtr2 = x.bits; + Uint32* dstPtr = &bits[getRowOffset(dst)]; + Uint32* limit = &srcPtr2[x.sizeInWords]; + + while (srcPtr2 < limit) + *dstPtr++ = *srcPtr1++ | *srcPtr2++; +} + +// +// Compare the rows x and y. Return true if they are equal. +// +bool FastBitMatrix::compareRows(Uint32 x, Uint32 y) const +{ + PR_ASSERT(sizeInWords); + + Uint32* ptr1 = &bits[getRowOffset(x)]; + Uint32* ptr2 = &bits[getRowOffset(y)]; + Uint32* limit = &ptr1[rowSizeInWords]; + + while (ptr1 < limit) + if (*ptr1++ != *ptr2++) + return false; + return true; +} + +// +// Copy the row src to the row dst. +// +void FastBitMatrix::copyRows(Uint32 src, Uint32 dst) +{ + PR_ASSERT(sizeInWords); + + Uint32* srcPtr = &bits[getRowOffset(src)]; + Uint32* dstPtr = &bits[getRowOffset(dst)]; + Uint32* limit = &srcPtr[rowSizeInWords]; + + while (srcPtr < limit) + *dstPtr++ = *srcPtr++; +} + +// +// Copy the bitset x to the row dst. +// +void FastBitMatrix::copyRows(const FastBitSet& x, Uint32 dst) +{ + PR_ASSERT(sizeInWords && x.sizeInWords == rowSizeInWords); + + Uint32* srcPtr = x.bits; + Uint32* dstPtr = &bits[getRowOffset(dst)]; + Uint32* limit = &srcPtr[x.sizeInWords]; + + while (srcPtr < limit) + *dstPtr++ = *srcPtr++; +} + +// +// Copy the row x to the bitset x. +// +void FastBitMatrix::copyRows(Uint32 src, FastBitSet& x) +{ + PR_ASSERT(sizeInWords && x.sizeInWords == rowSizeInWords); + + Uint32* srcPtr = &bits[getRowOffset(src)]; + Uint32* dstPtr = x.bits; + Uint32* limit = &dstPtr[x.sizeInWords]; + + while (dstPtr < limit) + *dstPtr++ = *srcPtr++; +} + +// +// Clear the row +// +void FastBitMatrix::clear(Uint32 row) +{ + PR_ASSERT(sizeInWords); + + Uint32* ptr = &bits[getRowOffset(row)]; + Int32 count = rowSizeInWords - 1; + register Uint32 zeros = Uint32(0); + + do + ptr[count] = zeros; + while(--count >= 0); +} + +// +// Set the row +// +void FastBitMatrix::set(Uint32 row) +{ + PR_ASSERT(sizeInWords); + + Uint32* ptr = &bits[getRowOffset(row)]; + Int32 count = rowSizeInWords - 1; + register Uint32 ones = Uint32(~0); + + do + ptr[count] = ones; + while(--count >= 0); +} + + +// +// Arithmetic operators. +// + +#define FastBitMatrixOperation(x, op, val) \ +PR_ASSERT(sizeInWords && sizeInWords == x.sizeInWords); \ + Int32 nRows = (sizeInWords >> rowShift) - 1; \ + do { \ + Int32 count = rowSizeInWords - 1; \ + Uint32* dst = &bits[getRowOffset(nRows)]; \ + Uint32* src = &x.bits[x.getRowOffset(nRows)]; \ + do { \ + Uint32 word = src[count]; \ + if (word != val) \ + dst[count] op word; \ + } while(--count >= 0); \ + } while(--nRows >= 0); + +FastBitMatrix& FastBitMatrix::operator |= (const FastBitMatrix& x) +{ + FastBitMatrixOperation(x, |=, 0); + return *this; +} + +FastBitMatrix& FastBitMatrix::operator &= (const FastBitMatrix& x) +{ + FastBitMatrixOperation(x, &=, Uint32(~0)); + return *this; +} + +FastBitMatrix& FastBitMatrix::operator ^= (const FastBitMatrix& x) +{ + FastBitMatrixOperation(x, ^=, 0); + return *this; +} + +FastBitMatrix& FastBitMatrix::operator -= (const FastBitMatrix& x) +{ + FastBitMatrixOperation(x, &= ~, 0); + return *this; +} + +#undef FastBitMatrixOperation + +// +// Return true if the 2 matrix are equals. +// +bool operator == (const FastBitMatrix& x, const FastBitMatrix& y) +{ + Uint32 nRows = x.sizeInWords >> x.rowShift; + + if ((y.sizeInWords >> y.rowShift) != nRows) + return false; + + Uint32* ptr1 = x.bits; + Uint32* ptr2 = y.bits; + Uint32* limit = &ptr1[x.sizeInWords]; + + while (ptr1 < limit) + if (*ptr1++ != *ptr2++) + return false; + + return true; +} + +// +// Copy the bits from the bitmatrix x. +// +FastBitMatrix& FastBitMatrix::operator = (const FastBitMatrix& x) +{ + Uint32 nRows = x.sizeInWords >> x.rowShift; + + PR_ASSERT((nRows == (sizeInWords >> rowShift)) && (rowSizeInWords == x.rowSizeInWords)); + + Uint32* src = x.bits; + Uint32* dst = bits; + Uint32* limit = &dst[sizeInWords]; + + while (dst < limit) + *dst++ = *src++; + + rowSizeInWords = x.rowSizeInWords; + rowShift = x.rowShift; + + return *this; +} + +#ifdef DEBUG_LOG +// +// Print the matrix. +// +void FastBitMatrix::printPretty(FILE* f) const +{ + PR_ASSERT(sizeInWords); + + fprintf(f, "[\n"); + Uint32 nRows = sizeInWords >> rowShift; + for (Uint32 i = 0; i < nRows; i++) { + fprintf(f, " "); + FastBitSet row(&bits[getRowOffset(i)], nCols); + row.printPretty(f); + } + fprintf(f, "]\n"); +} + +// +// Print the diffs. +// +void FastBitMatrix::printDiff(FILE *f, const FastBitMatrix& x) const +{ + Uint32 nRows = sizeInWords >> rowShift; + PR_ASSERT((x.nCols == nCols) && (nRows == (x.sizeInWords >> x.rowShift))); + + fprintf(f, "[\n"); + for (Uint32 i = 0; i < nRows; i++) { + fprintf(f, " "); + FastBitSet row(&bits[i << rowShift], nCols); + FastBitSet xRow(&x.bits[i << rowShift], nCols); + row.printDiff(f, xRow); + } + fprintf(f, "]\n"); +} + +#endif /* DEBUG_LOG */ diff --git a/ef/Utilities/General/NewFastBitMatrix.h b/ef/Utilities/General/NewFastBitMatrix.h new file mode 100644 index 000000000000..97332ae8d918 --- /dev/null +++ b/ef/Utilities/General/NewFastBitMatrix.h @@ -0,0 +1,183 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#ifndef _FAST_BITMATRIX_H_ +#define _FAST_BITMATRIX_H_ + +#include "Fundamentals.h" +#include "Pool.h" + +class FastBitSet; + +// ---------------------------------------------------------------------------- +// FastBitMatrix +// +// !!!! A FastBitMatrix cannot have a null number of rows nor a null +// !!!! number of column. +// + +class FastBitMatrix +{ +private: + + Uint32* bits; // Array of words to store the bits. + Uint32 sizeInWords; // Number of words allocated. + Uint8 rowShift; // A row is (1 << shift) words wide. + Uint32 rowSizeInWords; // Number of used words in a row. +#ifdef DEBUG_LOG + Uint32 nCols; // Number of column in this matrix. +#endif + + + FastBitMatrix(const FastBitMatrix&); // No copy constructor. + + // Return the offset to the first word on this row. + Uint32 getRowOffset(Uint32 row) const {return row << rowShift;} + // Return the offset to word containing column from the begining of the row. + Uint32 getWordOffsetFromBeginOfRow(Uint32 column) const {return column >> 5;} + // Return the offset of the word containing (row, column). + Uint32 getWordOffset(Uint32 row, Uint32 column) const {return getRowOffset(row) + getWordOffsetFromBeginOfRow(column);} + // Return the offset of the bit a column from the begining of the word containing column. + Uint32 getBitOffset(Uint32 column) const {return column & 31;} + +public: + // This is not a valid bitmatrix. The method sizeTo must be called before any + // use of this instance. + FastBitMatrix() : sizeInWords(0), rowShift(0) {} + + // Allocate a new matrix. + inline FastBitMatrix(Pool& pool, Uint32 nRows, Uint32 nCols); + + // Resize the matrix. + void sizeTo(Pool& pool, Uint32 nRows, Uint32 nCols); + // Resize the matrix and clear all bits. + inline void sizeToAndClear(Pool& pool, Uint32 nRows, Uint32 nCols); + + // Return a pointer to the row bits. + inline Uint32* getRowBits(Uint32 row) const {return &bits[getRowOffset(row)];} + + // Clear all the bits in the matrix. + inline void clear(); + // Clear the bit at (row, column). + void clear(Uint32 row, Uint32 column) {PR_ASSERT(sizeInWords); bits[getWordOffset(row, column)] &= ~(1<>getBitOffset(column))&1;} + + // And rows src1 & src2 to row dst + void andRows(Uint32 src1, Uint32 src2, Uint32 dst); + // And row src & the bitset x to row dst + void andRows(Uint32 src, const FastBitSet& x, Uint32 dst); + // Or rows src1 & src2 to row dst + void orRows(Uint32 src1, Uint32 src2, Uint32 dst); + // Or row src & the bitset x to row dst + void orRows(Uint32 src, const FastBitSet& x, Uint32 dst); + // Copy row src to row dst. + void copyRows(Uint32 src, Uint32 dst); + // Copy the bitset x to the row dst. + void copyRows(const FastBitSet& x, Uint32 dst); + // Copy the row x to the bitset x. + void copyRows(Uint32 src, FastBitSet& x); + // Compare the rows x and y. + bool compareRows(Uint32 x, Uint32 y) const; + + // Arithmetic operators. + FastBitMatrix& operator |= (const FastBitMatrix& x); + FastBitMatrix& operator &= (const FastBitMatrix& x); + FastBitMatrix& operator ^= (const FastBitMatrix& x); + FastBitMatrix& operator -= (const FastBitMatrix& x); + + // Comparison operators. + friend bool operator == (const FastBitMatrix& x, const FastBitMatrix& y); + friend bool operator != (const FastBitMatrix& x, const FastBitMatrix& y) {return !(x == y);} + + // Copy operator. + FastBitMatrix& operator = (const FastBitMatrix& x); + +#ifdef DEBUG_LOG + // Print the matrix. + void printPretty(FILE* f) const; + // Print the diffs with the given matrix. + void printDiff(FILE* f, const FastBitMatrix& x) const; +#endif /* DEBUG_LOG */ +}; + +// ---------------------------------------------------------------------------- +// Inlines + + +// +// Set all the bits in the matrix. +// +inline void FastBitMatrix::set() +{ + PR_ASSERT(sizeInWords); + + Uint32* ptr = bits; + Int32 count = sizeInWords - 1; + register Uint32 ones = Uint32(~0); + + do + ptr[count] = ones; + while(--count >= 0); +} + +// +// Clear all the bits in the matrix. +// +inline void FastBitMatrix::clear() +{ + PR_ASSERT(sizeInWords); + + Uint32* ptr = bits; + Int32 count = sizeInWords - 1; + register Uint32 zeros = Uint32(0); + + do + ptr[count] = zeros; + while(--count >= 0); +} + +// +// Resize the matrix and clear all the bits. +// +inline void FastBitMatrix::sizeToAndClear(Pool& pool, Uint32 nRows, Uint32 nCols) +{ + sizeTo(pool, nRows, nCols); + clear(); +} + +// +// Resize the new matrix and clear its content. +// +inline FastBitMatrix::FastBitMatrix(Pool& pool, Uint32 nRows, Uint32 nCols) : sizeInWords(0) +{ + PR_ASSERT(nRows && nCols); + sizeToAndClear(pool, nRows, nCols); +} + + +#endif /* _FAST_BITMATRIX_H_ */ + diff --git a/ef/Utilities/General/NewFastBitSet.cpp b/ef/Utilities/General/NewFastBitSet.cpp new file mode 100644 index 000000000000..a7afdb46bf58 --- /dev/null +++ b/ef/Utilities/General/NewFastBitSet.cpp @@ -0,0 +1,366 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#include "Fundamentals.h" +#include "FastBitSet.h" +#include "Pool.h" + +// +// Resize the bitset to sizeInBits. All the bits present in the bitset will be lost. +// The bitset will be unitialized. A call to clear() or set() is needed after sizeTo() !!! +// +void FastBitSet::sizeTo(Pool& pool, Uint32 sizeInBits) +{ + PR_ASSERT(sizeInBits); + + Uint32 newSizeInWords = getNumberOfWords(sizeInBits); + if (newSizeInWords > sizeInWords) { + sizeInWords = newSizeInWords; + bits = new(pool) Uint32[newSizeInWords]; + } +#ifdef DEBUG_LOG + this->sizeInBits = sizeInBits; +#endif /* DEBUG_LOG */ +} + + +// +// Set the bits (in this bitset) that are defined in x and return true if this bitset changed. +// +bool FastBitSet::set(const FastBitSet& x) +{ + PR_ASSERT(sizeInWords == x.sizeInWords); + + bool differ = false; + Uint32* dst = bits; + Uint32* src = x.bits; + Int32 count = sizeInWords - 1; + + do { + Uint32 oldWord = dst[count]; + Uint32 newWord = oldWord | src[count]; + differ |= (newWord != oldWord); + dst[count] = newWord; + } while(--count >= 0); + + return differ; +} + +// +// Arithmetic operators. +// + +#define FastBitSetOperation(x, op) \ + PR_ASSERT(sizeInWords && sizeInWords == x.sizeInWords); \ + Uint32* dst = bits; \ + Uint32* src = x.bits; \ + Int32 count = sizeInWords < x.sizeInWords ? sizeInWords - 1 : x.sizeInWords - 1; \ + do { \ + dst[count] op src[count]; \ + } while(--count >= 0); + + +FastBitSet& FastBitSet::operator |= (const FastBitSet& x) +{ + FastBitSetOperation(x, |=); + return *this; +} + +FastBitSet& FastBitSet::operator &= (const FastBitSet& x) +{ + FastBitSetOperation(x, &=); + return *this; +} + +FastBitSet& FastBitSet::operator ^= (const FastBitSet& x) +{ + FastBitSetOperation(x, ^=); + return *this; +} + +FastBitSet& FastBitSet::operator -= (const FastBitSet& x) +{ + FastBitSetOperation(x, &= ~); + return *this; +} + +// +// Copy operator. +// +FastBitSet& FastBitSet::operator = (const FastBitSet& x) +{ + FastBitSetOperation(x, = ); + return *this; +} + +#undef FastBitSetOperation + +// +// Comparison operator. +// +bool operator == (const FastBitSet& x, const FastBitSet& y) +{ + PR_ASSERT(x.sizeInWords == y.sizeInWords); + + Uint32* srcX = x.bits; + Uint32* srcY = y.bits; + Uint32* limitX = &srcX[x.sizeInWords]; + + while (srcX < limitX) + if (*srcX++ != *srcY++) + return false; + + return true; +} + +// +// Return the next '1' bit just after pos or -1 if not found. +// +Int32 FastBitSet::nextOne(Int32 pos) const +{ + PR_ASSERT(sizeInWords); + + ++pos; // Skip this bit. + + Uint32 wordOffset = getWordOffset(pos); + if (wordOffset < sizeInWords) { + Uint32* ptr = &bits[wordOffset]; + Uint8 bitOffset = getBitOffset(pos); + Uint32 word = *ptr++ >> bitOffset; + if (word != 0) { + while ((word & 3) == 0) { + bitOffset+=2; + word >>= 2; + } + if ((word & 1) == 0) + bitOffset++; + + return (wordOffset << 5) + bitOffset; + } + + Uint32* limit = &bits[sizeInWords]; + for (++wordOffset; ptr < limit; ++wordOffset) { + word = *ptr++; + if (word != 0) { + bitOffset = 0; + while ((word & 3) == 0) { + bitOffset+=2; + word >>= 2; + } + if ((word & 1) == 0) + bitOffset++; + + return (wordOffset << 5) + bitOffset; + } + } + } + return -1; +} + +// +// Return the '1' bit just before pos or -1 if not found. +// +Int32 FastBitSet::previousOne(Int32 pos) const +{ + PR_ASSERT(sizeInWords); + + --pos; // Skip this bit. + + Uint32 wordOffset = getWordOffset(pos); + if (wordOffset < sizeInWords) { + Uint32* ptr = &bits[wordOffset]; + Uint8 bitOffset = getBitOffset(pos); + Uint32 word = *ptr-- << (31 - bitOffset); + if (word != 0) { + while ((word & 0x80000000) == 0) { + bitOffset--; + word <<= 1; + } + return (wordOffset << 5) + bitOffset; + } + + Uint32* limit = bits; + for (--wordOffset; ptr >= limit; --wordOffset) { + word = *ptr--; + if (word != 0) { + bitOffset = 31; + while ((word & 0x80000000) == 0) { + bitOffset--; + word <<= 1; + } + + return (wordOffset << 5) + bitOffset; + } + } + } + return -1; +} + +// +// Return the next '0' bit just after pos or -1 if not found. +// +Int32 FastBitSet::nextZero(Int32 pos) const +{ + PR_ASSERT(sizeInWords); + + ++pos; // Skip this bit. + + Uint32 wordOffset = getWordOffset(pos); + if (wordOffset < sizeInWords) { + Uint32* ptr = &bits[wordOffset]; + Uint8 bitOffset = getBitOffset(pos); + Uint32 word = *ptr++ >> bitOffset; + if (word != Uint32(~0)) { + while (word & 1) { + bitOffset++; + word >>= 1; + } + return (wordOffset << 5) + bitOffset; + } + + Uint32* limit = &bits[sizeInWords]; + for (++wordOffset; ptr < limit; ++wordOffset) { + word = *ptr++; + if (word != Uint32(~0)) { + bitOffset = 0; + while (word & 1) { + bitOffset++; + word >>= 1; + } + return (wordOffset << 5) + bitOffset; + } + } + } + return -1; +} + +// +// Return the '0' bit just before pos or -1 if not found. +// +Int32 FastBitSet::previousZero(Int32 pos) const +{ + PR_ASSERT(sizeInWords); + + --pos; // Skip this bit. + + Uint32 wordOffset = getWordOffset(pos); + if (wordOffset < sizeInWords) { + Uint32* ptr = &bits[wordOffset]; + Uint8 bitOffset = getBitOffset(pos); + Uint8 shift = (31 - bitOffset); + Uint32 word = *ptr-- << shift; + if (word != (Uint32(~0) << shift)) { + while (word & 0x80000000) { + bitOffset--; + word <<= 1; + } + return (wordOffset << 5) + bitOffset; + } + + Uint32* limit = bits; + for (--wordOffset; ptr >= limit; --wordOffset) { + word = *ptr--; + if (word != Uint32(~0)) { + bitOffset = 31; + while (word & 0x80000000) { + bitOffset--; + word <<= 1; + } + + return (wordOffset << 5) + bitOffset; + } + } + } + return -1; +} + +// +// Set the bits from position 'from' to position 'to'. +// +void FastBitSet::set(Uint32 from, Uint32 to) +{ + Uint32* ptr = &bits[getWordOffset(from)]; + Uint32* limit = &bits[getWordOffset(to)]; + Uint32 beginMask = ~((1 << getBitOffset(from)) - 1); // 11..(32 - from) times..1100..from times..00 + Uint32 endMask = (2 << getBitOffset(to)) - 1; // 00..(32 - to) times..0011..to times..11 + + if (ptr == limit) { + *ptr |= (beginMask & endMask); + } else { + register Uint32 val = ~0; + *ptr++ |= beginMask; + while (ptr < limit) + *ptr++ = val; + *limit |= endMask; + } +} + +#ifdef DEBUG_LOG +// +// Print the bitset. +// +void FastBitSet::printPretty(FILE* f) const +{ + PR_ASSERT(sizeInWords); + + fprintf(f, "["); + for (PRUint32 bit = 0; bit < sizeInBits; bit++) + fprintf(f, test(bit) ? "1" : "0"); + fprintf(f, "]\n"); +} + +// +// Print the difference between this bitset and the given biset. +// +void FastBitSet::printDiff(FILE *f, const FastBitSet& x) const +{ + fprintf(f, "["); + for (Uint32 i = 0; i < sizeInBits; i++) + if (test(i) != x.test(i)) + fprintf(f, test(i) ? "-" : "+"); + else + fprintf(f, test(i) ? "1" : "0"); + fprintf(f, "]\n"); +} + +// +// Print all the '1' bits. +// +void FastBitSet::printPrettyOnes(FILE* f) const +{ + PR_ASSERT(sizeInWords); + + fprintf(f, "[ "); + for (Int32 bit = firstOne(); !done(bit); bit = nextOne(bit)) + fprintf(f, "%d ", bit); + fprintf(f, "]\n"); +} + +// +// Print all the '0' bits. +// +void FastBitSet::printPrettyZeros(FILE* f) const +{ + PR_ASSERT(sizeInWords); + + fprintf(f, "[ "); + for (Int32 bit = firstZero(); !done(bit); bit = nextZero(bit)) + fprintf(f, "%d ", bit); + fprintf(f, "]\n"); +} +#endif /* DEBUG_LOG */ diff --git a/ef/Utilities/General/NewFastBitSet.h b/ef/Utilities/General/NewFastBitSet.h new file mode 100644 index 000000000000..ec44f1c40d28 --- /dev/null +++ b/ef/Utilities/General/NewFastBitSet.h @@ -0,0 +1,230 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#ifndef _FAST_BITSET_H_ +#define _FAST_BITSET_H_ + +#include "Fundamentals.h" +#include "Pool.h" + +// ---------------------------------------------------------------------------- +// FastBitSet +// +// !!!! A FastBitSet cannot have a null number bits. +// + +class FastBitSet +{ + friend class FastBitMatrix; // The bit matrix will need to access bits & sizeInWord. +private: + + Uint32* bits; // Array of words to store the bits. + Uint32 sizeInWords; // Number of words allocated. +#ifdef DEBUG_LOG + Uint32 sizeInBits; // Number of bits (only used in printPretty*()). +#endif /* DEBUG_LOG */ + + Uint32 getNumberOfWords(Uint32 numberOfBits) const {return (numberOfBits + 31) >> 5;} + Uint32 getWordOffset(Uint32 bitPos) const {return bitPos >> 5;} + Uint8 getBitOffset(Uint32 bitPos) const {return bitPos & 31;} + + FastBitSet(const FastBitSet&); // No Copy constructor. + +public: + // This is not a valid bitset. The method sizeTo must be called before any + // use of this instance. + FastBitSet() : sizeInWords(0) {} + + // Instanciate and allocate the bits. + inline FastBitSet(Pool& pool, Uint32 sizeInBits); + // This FastBitSet gets its bits from memory. + inline FastBitSet(Uint32* bits, Uint32 sizeInBits); + // This FastBitSet copy its bits from memory.. + inline FastBitSet(Pool& pool, Uint32* bits, Uint32 sizeInBits); + + // Resize the bitset to sizeInBits. + void sizeTo(Pool& pool, Uint32 sizeInBits); + // Resize the bitset and clear all the bits. + inline void sizeToAndClear(Pool& pool, Uint32 sizeInBits); + + // Set all the bits in this bitset. + inline void set(); + // Set the bit at pos. + inline void set(Uint32 pos) {PR_ASSERT(sizeInWords); bits[getWordOffset(pos)] |= (1<>getBitOffset(pos))&1;} + // Count the number of bits at '1'. + inline Uint32 countOnes(); + // Count the number of bits at '0'. + inline Uint32 countZeros(); + + // Return the '1' bit just after pos or -1 if not found. + Int32 nextOne(Int32 pos) const; + // Return the '1' bit just before pos or -1 if not found. + Int32 previousOne(Int32 pos) const; + // Return the first '1' bit in the bitset or -1 if not found. + inline Int32 firstOne() const {return nextOne(-1);} + // Return the last '1' bit in the bitset or -1 if not found. + inline Int32 lastOne() const {return previousOne(sizeInWords << 5);} + // Return the '0' bit just after pos or -1 if not found. + Int32 nextZero(Int32 pos) const; + // Return the '0' bit just before pos or -1 if not found. + Int32 previousZero(Int32 pos) const; + // Return the first '0' bit in the bitset or -1 if not found. + inline Int32 firstZero() const {return nextZero(-1);} + // Return the last '1' bit in the bitset or -1 if not found. + inline Int32 lastZero() const {return previousZero(sizeInWords << 5);} + // Return true if at the end of the BitSet. + inline bool done(Int32 pos) const {return pos == -1;} + + + // Return true if the bitset is empty. + inline bool empty() {return done(firstOne());} + + // Arithmetic operators. + FastBitSet& operator |= (const FastBitSet& x); + FastBitSet& operator &= (const FastBitSet& x); + FastBitSet& operator ^= (const FastBitSet& x); + FastBitSet& operator -= (const FastBitSet& x); + + // Comparison operators. + friend bool operator == (const FastBitSet& x, const FastBitSet& y); + friend bool operator != (const FastBitSet& x, const FastBitSet& y) {return !(x == y);} + + // Copy operator. + FastBitSet& operator = (const FastBitSet& x); + +#ifdef DEBUG_LOG + // Print the bitset. + void printPretty(FILE* f) const; + // Print the diffs with the given bitset. + void printDiff(FILE* f, const FastBitSet& x) const; + // Print all the '1' bits. + void printPrettyOnes(FILE* f) const; + // Print all the '0' bits. + void printPrettyZeros(FILE* f) const; +#endif +}; + +// ---------------------------------------------------------------------------- +// Inlines. + +// +// Set all the bits in this bitset. +// +inline void FastBitSet::set() +{ + PR_ASSERT(sizeInWords); + + Uint32* ptr = bits; + Int32 count = sizeInWords - 1; + register Uint32 ones = Uint32(~0); + + do { + ptr[count] = ones; + } while(--count >= 0); +} + +// +// Clear all the bits in this bitset. +// +inline void FastBitSet::clear() +{ + PR_ASSERT(sizeInWords); + + Uint32* ptr = bits; + Int32 count = sizeInWords - 1; + register Uint32 zeros = Uint32(0); + + do { + ptr[count] = zeros; + } while(--count >= 0); +} + +// +// Count the number of bits at '1'. +// +inline Uint32 FastBitSet::countOnes() +{ + Uint32 counter = 0; + for (Int32 i = firstOne(); !done(i); i = nextOne(i)) + counter++; + + return counter; +} + + +// +// Count the number of bits at '0'. +// +inline Uint32 FastBitSet::countZeros() +{ + Uint32 counter = 0; + for (Int32 i = firstZero(); !done(i); i = nextZero(i)) + counter++; + + return counter; +} + +inline void FastBitSet::sizeToAndClear(Pool& pool, Uint32 sizeInBits) +{ + sizeTo(pool, sizeInBits); + clear(); +} + +inline FastBitSet::FastBitSet(Pool& pool, Uint32 sizeInBits) : + sizeInWords(0) +{ + sizeToAndClear(pool, sizeInBits); +} + +inline FastBitSet::FastBitSet(Pool& pool, Uint32* bits, Uint32 sizeInBits) : + sizeInWords(0) +{ + sizeTo(pool, sizeInBits); + PR_ASSERT(sizeInWords); + Int32 count = sizeInWords - 1; + Uint32* dst = bits; + do { + dst[count] = bits[count]; + } while (--count >= 0); +} + + + +inline FastBitSet::FastBitSet(Uint32* bits, Uint32 sizeInBits) : + bits(bits), sizeInWords(getNumberOfWords(sizeInBits)) +{ +#ifdef DEBUG_LOG + this->sizeInBits = sizeInBits; +#endif /* DEBUG_LOG */ +} + +#endif /* _FAST_BITSET_H_ */ diff --git a/ef/Utilities/General/Nonspr.cpp b/ef/Utilities/General/Nonspr.cpp new file mode 100644 index 000000000000..f51aebd56501 --- /dev/null +++ b/ef/Utilities/General/Nonspr.cpp @@ -0,0 +1,944 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#include +#include + +#include + +#include "prio.h" +#include "plstr.h" + +#include "Nonspr.h" + +extern "C" { + +struct PRFileDesc { + FILE *fp; +}; + +/* Implementation of select NSPR routines for platforms that NSPR does + * not currently support, or does not build on. Hopefully, this will + * go away as NSPR progresses. + */ +PRStatus PR_GetFileInfo(const char *fn, PRFileInfo *info) +{ + struct stat sb; + PRInt64 s, s2us; + PRInt32 rv; + + rv = stat(fn, &sb); + if (rv < 0) + return PR_FAILURE; + else if (info) { + if (S_IFREG & sb.st_mode) + info->type = PR_FILE_FILE ; + else if (S_IFDIR & sb.st_mode) + info->type = PR_FILE_DIRECTORY; + else + info->type = PR_FILE_OTHER; + + info->size = sb.st_size; + LL_I2L(s, sb.st_mtime); + LL_I2L(s2us, PR_USEC_PER_SEC); + LL_MUL(s, s, s2us); + info->modifyTime = s; + LL_I2L(s, sb.st_ctime); + LL_MUL(s, s, s2us); + info->creationTime = s; + } + return PR_SUCCESS; +} + +PRFileDesc *PR_Open(const char *name, PRWord flags, PRWord) +{ + PRFileDesc *desc = (PRFileDesc *) malloc(sizeof(PRFileDesc)); + + if (!desc) + return 0; + + const char *readMode; + switch (flags) { + case PR_RDONLY: + readMode = "rb"; + break; + + case PR_WRONLY: + readMode = "wb"; + break; + + case PR_RDWR: + readMode = "rw"; + break; + + case PR_APPEND: + readMode = "wa"; + break; + + default: + return 0; + } + + if (!(desc->fp = fopen(name, readMode))) { + free(desc); + return 0; + } + + return desc; +} + +PRStatus PR_Close(PRFileDesc *desc) +{ + if (desc->fp) + fclose(desc->fp); + + free(desc); + return PR_SUCCESS; +} + +PRInt32 PR_Read(PRFileDesc *fd, void *buf, PRInt32 amount) +{ + return fread(buf, 1, amount, fd->fp); +} + +PRInt32 PR_Write(PRFileDesc *fd, const void *buf, PRInt32 amount) +{ + return fwrite(buf, 1, amount, fd->fp); +} + +PRInt32 PR_Seek(PRFileDesc *fd, PRInt32 offset, + PRSeekWhence prWhence) +{ + int whence; + + switch (prWhence) { + case PR_SEEK_SET: + whence = SEEK_SET; + break; + + case PR_SEEK_CUR: + whence = SEEK_CUR; + break; + + case PR_SEEK_END: + whence = SEEK_END; + break; + + default: + return -1; + } + + if (fseek(fd->fp, offset, whence) < 0) + return 0; + else + return ftell(fd->fp); +} + +const char *PR_GetEnv(const char *var) +{ + return getenv(var); +} + + +#include +#include +#include +#include +//#include "primpl.h" +#include "prprf.h" +#include "prlong.h" +#include "prlog.h" +#include "prmem.h" + +typedef struct SprintfStateStr SprintfState; + +struct SprintfStateStr { + int (*stuff)(SprintfState *ss, const char *sp, PRUint32 len); + + char *base; + char *cur; + PRUint32 maxlen; + + int (*func)(void *arg, const char *sp, PRUint32 len); + void *arg; +}; + +#define TYPE_INT16 0 +#define TYPE_UINT16 1 +#define TYPE_INTN 2 +#define TYPE_UINTN 3 +#define TYPE_INT32 4 +#define TYPE_UINT32 5 +#define TYPE_INT64 6 +#define TYPE_UINT64 7 + +#define _LEFT 0x1 +#define _SIGNED 0x2 +#define _SPACED 0x4 +#define _ZEROS 0x8 +#define _NEG 0x10 + +/* +** Fill into the buffer using the data in src +*/ +static int fill2(SprintfState *ss, const char *src, int srclen, int width, + int flags) +{ + char space = ' '; + int rv; + + width -= srclen; + if ((width > 0) && ((flags & _LEFT) == 0)) { /* Right adjusting */ + if (flags & _ZEROS) { + space = '0'; + } + while (--width >= 0) { + rv = (*ss->stuff)(ss, &space, 1); + if (rv < 0) { + return rv; + } + } + } + + /* Copy out the source data */ + rv = (*ss->stuff)(ss, src, srclen); + if (rv < 0) { + return rv; + } + + if ((width > 0) && ((flags & _LEFT) != 0)) { /* Left adjusting */ + while (--width >= 0) { + rv = (*ss->stuff)(ss, &space, 1); + if (rv < 0) { + return rv; + } + } + } + return 0; +} + +/* +** Fill a number. The order is: optional-sign zero-filling conversion-digits +*/ +static int fill_n(SprintfState *ss, const char *src, int srclen, int width, + int prec, int type, int flags) +{ + int zerowidth = 0; + int precwidth = 0; + int signwidth = 0; + int leftspaces = 0; + int rightspaces = 0; + int cvtwidth; + int rv; + char sign; + + if ((type & 1) == 0) { + if (flags & _NEG) { + sign = '-'; + signwidth = 1; + } else if (flags & _SIGNED) { + sign = '+'; + signwidth = 1; + } else if (flags & _SPACED) { + sign = ' '; + signwidth = 1; + } + } + cvtwidth = signwidth + srclen; + + if (prec > 0) { + if (prec > srclen) { + precwidth = prec - srclen; /* Need zero filling */ + cvtwidth += precwidth; + } + } + + if ((flags & _ZEROS) && (prec < 0)) { + if (width > cvtwidth) { + zerowidth = width - cvtwidth; /* Zero filling */ + cvtwidth += zerowidth; + } + } + + if (flags & _LEFT) { + if (width > cvtwidth) { + /* Space filling on the right (i.e. left adjusting) */ + rightspaces = width - cvtwidth; + } + } else { + if (width > cvtwidth) { + /* Space filling on the left (i.e. right adjusting) */ + leftspaces = width - cvtwidth; + } + } + while (--leftspaces >= 0) { + rv = (*ss->stuff)(ss, " ", 1); + if (rv < 0) { + return rv; + } + } + if (signwidth) { + rv = (*ss->stuff)(ss, &sign, 1); + if (rv < 0) { + return rv; + } + } + while (--precwidth >= 0) { + rv = (*ss->stuff)(ss, "0", 1); + if (rv < 0) { + return rv; + } + } + while (--zerowidth >= 0) { + rv = (*ss->stuff)(ss, "0", 1); + if (rv < 0) { + return rv; + } + } + rv = (*ss->stuff)(ss, src, srclen); + if (rv < 0) { + return rv; + } + while (--rightspaces >= 0) { + rv = (*ss->stuff)(ss, " ", 1); + if (rv < 0) { + return rv; + } + } + return 0; +} + +/* +** Convert a long into its printable form +*/ +static int cvt_l(SprintfState *ss, long num, int width, int prec, int radix, + int type, int flags, const char *hexp) +{ + char cvtbuf[100]; + char *cvt; + int digits; + + /* according to the man page this needs to happen */ + if ((prec == 0) && (num == 0)) { + return 0; + } + + /* + ** Converting decimal is a little tricky. In the unsigned case we + ** need to stop when we hit 10 digits. In the signed case, we can + ** stop when the number is zero. + */ + cvt = cvtbuf + sizeof(cvtbuf); + digits = 0; + while (num) { + int digit = (((unsigned long)num) % radix) & 0xF; + *--cvt = hexp[digit]; + digits++; + num = ((unsigned long)num) / radix; + } + if (digits == 0) { + *--cvt = '0'; + digits++; + } + + /* + ** Now that we have the number converted without its sign, deal with + ** the sign and zero padding. + */ + return fill_n(ss, cvt, digits, width, prec, type, flags); +} + +/* +** Convert a 64-bit integer into its printable form +*/ +static int cvt_ll(SprintfState *ss, PRInt64 num, int width, int prec, int radix, + int type, int flags, const char *hexp) +{ + char cvtbuf[100]; + char *cvt; + int digits; + PRInt64 rad; + + /* according to the man page this needs to happen */ + if ((prec == 0) && (LL_IS_ZERO(num))) { + return 0; + } + + /* + ** Converting decimal is a little tricky. In the unsigned case we + ** need to stop when we hit 10 digits. In the signed case, we can + ** stop when the number is zero. + */ + LL_I2L(rad, radix); + cvt = cvtbuf + sizeof(cvtbuf); + digits = 0; + while (!LL_IS_ZERO(num)) { + PRInt32 digit; + PRInt64 quot, rem; + LL_UDIVMOD(", &rem, num, rad); + LL_L2I(digit, rem); + *--cvt = hexp[digit & 0xf]; + digits++; + num = quot; + } + if (digits == 0) { + *--cvt = '0'; + digits++; + } + + /* + ** Now that we have the number converted without its sign, deal with + ** the sign and zero padding. + */ + return fill_n(ss, cvt, digits, width, prec, type, flags); +} + +/* +** Convert a double precision floating point number into its printable +** form. +** +** XXX stop using sprintf to convert floating point +*/ +static int cvt_f(SprintfState *ss, double d, const char *fmt0, const char *fmt1) +{ + char fin[20]; + char fout[300]; + int amount = fmt1 - fmt0; + + if (amount >= sizeof(fin)) { + /* Totally bogus % command to sprintf. Just ignore it */ + return 0; + } + memcpy(fin, fmt0, amount); + fin[amount] = 0; + + /* Convert floating point using the native sprintf code */ + sprintf(fout, fin, d); + + /* + ** This assert will catch overflow's of fout, when building with + ** debugging on. At least this way we can track down the evil piece + ** of calling code and fix it! + */ + + return (*ss->stuff)(ss, fout, strlen(fout)); +} + +/* +** Convert a string into its printable form. "width" is the output +** width. "prec" is the maximum number of characters of "s" to output, +** where -1 means until NUL. +*/ +static int cvt_s(SprintfState *ss, const char *s, int width, int prec, + int flags) +{ + int slen; + + if (prec == 0) + return 0; + + /* Limit string length by precision value */ + slen = s ? strlen(s) : 6; + if (prec > 0) { + if (prec < slen) { + slen = prec; + } + } + + /* and away we go */ + return fill2(ss, s ? s : "(null)", slen, width, flags); +} + +/* +** The workhorse sprintf code. +*/ +static int dosprintf(SprintfState *ss, const char *fmt, va_list ap) +{ + char c; + int flags, width, prec, radix, type; + union { + char ch; + int i; + long l; + PRInt64 ll; + double d; + const char *s; + int *ip; + } u; + const char *fmt0; + static char *hex = "0123456789abcdef"; + static char *HEX = "0123456789ABCDEF"; + char *hexp; + int rv; + + while ((c = *fmt++) != 0) { + if (c != '%') { + rv = (*ss->stuff)(ss, fmt - 1, 1); + if (rv < 0) { + return rv; + } + continue; + } + fmt0 = fmt - 1; + + /* + ** Gobble up the % format string. Hopefully we have handled all + ** of the strange cases! + */ + flags = 0; + c = *fmt++; + if (c == '%') { + /* quoting a % with %% */ + rv = (*ss->stuff)(ss, fmt - 1, 1); + if (rv < 0) { + return rv; + } + continue; + } + + /* + * Examine optional flags. Note that we do not implement the + * '#' flag of sprintf(). The ANSI C spec. of the '#' flag is + * somewhat ambiguous and not ideal, which is perhaps why + * the various sprintf() implementations are inconsistent + * on this feature. + */ + while ((c == '-') || (c == '+') || (c == ' ') || (c == '0')) { + if (c == '-') flags |= _LEFT; + if (c == '+') flags |= _SIGNED; + if (c == ' ') flags |= _SPACED; + if (c == '0') flags |= _ZEROS; + c = *fmt++; + } + if (flags & _SIGNED) flags &= ~_SPACED; + if (flags & _LEFT) flags &= ~_ZEROS; + + /* width */ + if (c == '*') { + c = *fmt++; + width = va_arg(ap, int); + } else { + width = 0; + while ((c >= '0') && (c <= '9')) { + width = (width * 10) + (c - '0'); + c = *fmt++; + } + } + + /* precision */ + prec = -1; + if (c == '.') { + c = *fmt++; + if (c == '*') { + c = *fmt++; + prec = va_arg(ap, int); + } else { + prec = 0; + while ((c >= '0') && (c <= '9')) { + prec = (prec * 10) + (c - '0'); + c = *fmt++; + } + } + } + + /* size */ + type = TYPE_INTN; + if (c == 'h') { + type = TYPE_INT16; + c = *fmt++; + } else if (c == 'L') { + /* XXX not quite sure here */ + type = TYPE_INT64; + c = *fmt++; + } else if (c == 'l') { + type = TYPE_INT32; + c = *fmt++; + if (c == 'l') { + type = TYPE_INT64; + c = *fmt++; + } + } + + /* format */ + hexp = hex; + switch (c) { + case 'd': case 'i': /* decimal/integer */ + radix = 10; + goto fetch_and_convert; + + case 'o': /* octal */ + radix = 8; + type |= 1; + goto fetch_and_convert; + + case 'u': /* unsigned decimal */ + radix = 10; + type |= 1; + goto fetch_and_convert; + + case 'x': /* unsigned hex */ + radix = 16; + type |= 1; + goto fetch_and_convert; + + case 'X': /* unsigned HEX */ + radix = 16; + hexp = HEX; + type |= 1; + goto fetch_and_convert; + + fetch_and_convert: + switch (type) { + case TYPE_INT16: + u.l = va_arg(ap, int); + if (u.l < 0) { + u.l = -u.l; + flags |= _NEG; + } + goto do_long; + case TYPE_UINT16: + u.l = va_arg(ap, int) & 0xffff; + goto do_long; + case TYPE_INTN: + u.l = va_arg(ap, int); + if (u.l < 0) { + u.l = -u.l; + flags |= _NEG; + } + goto do_long; + case TYPE_UINTN: + u.l = va_arg(ap, unsigned int); + goto do_long; + + case TYPE_INT32: + u.l = va_arg(ap, PRInt32); + if (u.l < 0) { + u.l = -u.l; + flags |= _NEG; + } + goto do_long; + case TYPE_UINT32: + u.l = va_arg(ap, PRUint32); + do_long: + rv = cvt_l(ss, u.l, width, prec, radix, type, flags, hexp); + if (rv < 0) { + return rv; + } + break; + + case TYPE_INT64: + u.ll = va_arg(ap, PRInt64); + if (!LL_GE_ZERO(u.ll)) { + LL_NEG(u.ll, u.ll); + flags |= _NEG; + } + goto do_longlong; + case TYPE_UINT64: + u.ll = va_arg(ap, PRUint64); + do_longlong: + rv = cvt_ll(ss, u.ll, width, prec, radix, type, flags, hexp); + if (rv < 0) { + return rv; + } + break; + } + break; + + case 'e': + case 'f': + case 'g': + u.d = va_arg(ap, double); + rv = cvt_f(ss, u.d, fmt0, fmt); + if (rv < 0) { + return rv; + } + break; + + case 'c': + u.ch = va_arg(ap, int); + rv = (*ss->stuff)(ss, &u.ch, 1); + if (rv < 0) { + return rv; + } + break; + + case 'p': + if (sizeof(void *) == sizeof(PRInt32)) { + type = TYPE_UINT32; + } else if (sizeof(void *) == sizeof(PRInt64)) { + type = TYPE_UINT64; + } else if (sizeof(void *) == sizeof(int)) { + type = TYPE_UINTN; + } else { + break; + } + radix = 16; + goto fetch_and_convert; + +#if 0 + case 'C': + case 'S': + case 'E': + case 'G': + /* XXX not supported I suppose */ + break; +#endif + + case 's': + u.s = va_arg(ap, const char*); + rv = cvt_s(ss, u.s, width, prec, flags); + if (rv < 0) { + return rv; + } + break; + + case 'n': + u.ip = va_arg(ap, int*); + if (u.ip) { + *u.ip = ss->cur - ss->base; + } + break; + + default: + /* Not a % token after all... skip it */ +#if 0 + PR_ASSERT(0); +#endif + rv = (*ss->stuff)(ss, "%", 1); + if (rv < 0) { + return rv; + } + rv = (*ss->stuff)(ss, fmt - 1, 1); + if (rv < 0) { + return rv; + } + } + } + + /* Stuff trailing NUL */ + rv = (*ss->stuff)(ss, "\0", 1); + return rv; +} + +/************************************************************************/ + +static int FuncStuff(SprintfState *ss, const char *sp, PRUint32 len) +{ + int rv; + + rv = (*ss->func)(ss->arg, sp, len); + if (rv < 0) { + return rv; + } + ss->maxlen += len; + return 0; +} + +PR_IMPLEMENT(PRUint32) PR_sxprintf(PRStuffFunc func, void *arg, + const char *fmt, ...) +{ + va_list ap; + int rv; + + va_start(ap, fmt); + rv = PR_vsxprintf(func, arg, fmt, ap); + va_end(ap); + return rv; +} + +PR_IMPLEMENT(PRUint32) PR_vsxprintf(PRStuffFunc func, void *arg, + const char *fmt, va_list ap) +{ + SprintfState ss; + int rv; + + ss.stuff = FuncStuff; + ss.func = func; + ss.arg = arg; + ss.maxlen = 0; + rv = dosprintf(&ss, fmt, ap); + return (rv < 0) ? (PRUint32)-1 : ss.maxlen; +} + +/* +** Stuff routine that automatically grows the malloc'd output buffer +** before it overflows. +*/ +static int GrowStuff(SprintfState *ss, const char *sp, PRUint32 len) +{ + ptrdiff_t off; + char *newbase; + PRUint32 newlen; + + off = ss->cur - ss->base; + if (off + len >= ss->maxlen) { + /* Grow the buffer */ + newlen = ss->maxlen + ((len > 32) ? len : 32); + if (ss->base) { + newbase = (char*) PR_REALLOC(ss->base, newlen); + } else { + newbase = (char*) PR_MALLOC(newlen); + } + if (!newbase) { + /* Ran out of memory */ + return -1; + } + ss->base = newbase; + ss->maxlen = newlen; + ss->cur = ss->base + off; + } + + /* Copy data */ + while (len) { + --len; + *ss->cur++ = *sp++; + } + return 0; +} + +/* +** sprintf into a malloc'd buffer +*/ +PR_IMPLEMENT(char *) PR_smprintf(const char *fmt, ...) +{ + va_list ap; + char *rv; + + va_start(ap, fmt); + rv = PR_vsmprintf(fmt, ap); + va_end(ap); + return rv; +} + +PR_IMPLEMENT(char *) PR_vsmprintf(const char *fmt, va_list ap) +{ + SprintfState ss; + int rv; + + ss.stuff = GrowStuff; + ss.base = 0; + ss.cur = 0; + ss.maxlen = 0; + rv = dosprintf(&ss, fmt, ap); + if (rv < 0) { + if (ss.base) { + PR_DELETE(ss.base); + } + return 0; + } + return ss.base; +} + +/* +** Stuff routine that discards overflow data +*/ +static int LimitStuff(SprintfState *ss, const char *sp, PRUint32 len) +{ + PRUint32 limit = ss->maxlen - (ss->cur - ss->base); + + if (len > limit) { + len = limit; + } + while (len) { + --len; + *ss->cur++ = *sp++; + } + return 0; +} + +/* +** sprintf into a fixed size buffer. Make sure there is a NUL at the end +** when finished. +*/ +PR_IMPLEMENT(PRUint32) PR_snprintf(char *out, PRUint32 outlen, const char *fmt, ...) +{ + va_list ap; + int rv; + + if ((PRInt32)outlen <= 0) { + return 0; + } + + va_start(ap, fmt); + rv = PR_vsnprintf(out, outlen, fmt, ap); + va_end(ap); + return rv; +} + +PR_IMPLEMENT(PRUint32) PR_vsnprintf(char *out, PRUint32 outlen,const char *fmt, + va_list ap) +{ + SprintfState ss; + PRUint32 n; + + if ((PRInt32)outlen <= 0) { + return 0; + } + + ss.stuff = LimitStuff; + ss.base = out; + ss.cur = out; + ss.maxlen = outlen; + (void) dosprintf(&ss, fmt, ap); + + /* If we added chars, and we didn't append a null, do it now. */ + if( (ss.cur != ss.base) && (*(ss.cur - 1) != '\0') ) + *(--ss.cur) = '\0'; + + n = ss.cur - ss.base; + return n ? n - 1 : n; +} + +PR_IMPLEMENT(char *) PR_sprintf_append(char *last, const char *fmt, ...) +{ + va_list ap; + char *rv; + + va_start(ap, fmt); + rv = PR_vsprintf_append(last, fmt, ap); + va_end(ap); + return rv; +} + +PR_IMPLEMENT(char *) PR_vsprintf_append(char *last, const char *fmt, va_list ap) +{ + SprintfState ss; + int rv; + + ss.stuff = GrowStuff; + if (last) { + int lastlen = strlen(last); + ss.base = last; + ss.cur = last + lastlen; + ss.maxlen = lastlen; + } else { + ss.base = 0; + ss.cur = 0; + ss.maxlen = 0; + } + rv = dosprintf(&ss, fmt, ap); + if (rv < 0) { + if (ss.base) { + PR_DELETE(ss.base); + } + return 0; + } + return ss.base; +} + +} diff --git a/ef/Utilities/General/Nonspr.h b/ef/Utilities/General/Nonspr.h new file mode 100644 index 000000000000..95899898ff7b --- /dev/null +++ b/ef/Utilities/General/Nonspr.h @@ -0,0 +1,69 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#ifndef _NO_NSPR_H_ +#define _NO_NSPR_H_ + +#include +#include "plstr.h" + +/* Header file for NSPR utilities if NSPR is not being used */ +extern "C" { +inline uint32 PL_strlen(const char *str) { return strlen(str); } + +inline char *PL_strdup(const char *str) { return strdup(str); } + +inline char *PL_strchr(const char *s, char c) { return strchr(s, c); } +inline char *PL_strrchr(const char *s, char c) { return strrchr(s, c); } + +inline char *PL_strcpy(char *dest, const char *src) { + return strcpy(dest, src); +} + +inline char *PL_strncpy(char *dest, const char *src, uint32 max) { + return strncpy(dest, src, max); +} + + +inline char *PL_strcat(char *dst, const char *src) { + return strcat(dst, src); +} + +inline int32 PL_strcasecmp(const char *a, const char *b) { + return strcasecmp(a, b); +} + +inline int32 PL_strncasecmp(const char *a, const char *b, uint32 n) { + return strncasecmp(a, b, n); +} + +inline char *PL_strstr(const char *big, const char *little) { + return strstr(big, little); +} + + +inline int32 PL_strcmp(const char *a, const char *b) { + return strcmp(a, b); +} + +inline int32 PL_strncmp(const char *a, const char *b, uint32 n) { + return strncmp(a, b, n); +} + +} /* extern "C" */ +#endif /* _NO_NSPR_H_ */ diff --git a/ef/Utilities/General/Pool.cpp b/ef/Utilities/General/Pool.cpp new file mode 100644 index 000000000000..4f8beaa1a6b1 --- /dev/null +++ b/ef/Utilities/General/Pool.cpp @@ -0,0 +1,117 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#include +#include +#include "Pool.h" + + +// +// Allocate a new memory pool whose first chunk will have initialSize bytes +// and remaining chunks will have chunkSize bytes. +// +Pool::Pool(size_t initialSize, size_t chunkSize): + initialSize(initialSize >= 256 ? initialSize >= chunkSize ? initialSize : chunkSize : 256), + chunkSize(chunkSize >= 256 ? initialSize : 256), + buffer((ptr)&buffer), + bufferEnd((ptr)&buffer), + headerList(0) +{} + + +// +// Release all memory from this pool and deallocate the pool. +// +Pool::~Pool() +{ + clear(); +} + + +// +// Allocate a block from this pool that won't fit in the space that's +// left between buffer and bufferEnd. +// size has already been rounded up to a doubleword multiple. +// +void *Pool::allocateOverflow(size_t size) +{ + size_t sizePlusHeader = size + blockHeaderSize; + size_t blockSize = sizePlusHeader; + if (blockSize < chunkSize) + blockSize = headerList ? chunkSize : initialSize; + ptr block = static_cast(malloc(blockSize)); + BlockHeader *h = reinterpret_cast(block); + h->next = headerList; + h->size = blockSize; + headerList = h; + if (blockSize != sizePlusHeader) { + buffer = block + sizePlusHeader; + bufferEnd = block + blockSize; + } + return block + blockHeaderSize; +} + + +// +// Release all memory from this pool. +// +void Pool::clear() +{ + buffer = (ptr)&buffer; + bufferEnd = (ptr)&buffer; + BlockHeader *h = headerList; + while (h) { + BlockHeader *next = h->next; + #ifdef DEBUG + memset(h, 0xFF, h->size); // Wipe contents of block + #endif + free(h); + h = next; + } + headerList = 0; +} + +size_t Pool::totalSize() +{ + size_t size = 0; + + for (BlockHeader *block = headerList; block; block = block->next) + size += block->size; + + return size; +} + +// +// Global operator new with a Pool argument. +// +NS_EXPORT void *operator new(size_t size, Pool &pool) +{ + return pool.allocate(size); +} + + +#ifndef __MWERKS__ +// +// Global array operator new with a Pool argument. +// +NS_EXPORT void *operator new[](size_t size, Pool &pool) +{ + return pool.allocate(size); +} +#endif + diff --git a/ef/Utilities/General/Pool.h b/ef/Utilities/General/Pool.h new file mode 100644 index 000000000000..5100fb988309 --- /dev/null +++ b/ef/Utilities/General/Pool.h @@ -0,0 +1,75 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#ifndef POOL_H +#define POOL_H + +#include "Fundamentals.h" + +// Pooled memory allocation +class NS_EXTERN Pool +{ + struct BlockHeader + { + BlockHeader *next; // Linked list of all memory blocks in pool + size_t size; // Physical size of this block, including header + }; + + enum {blockHeaderSize = sizeof(BlockHeader) + 7 & -8}; // BlockHeader size rounded up to a doubleword multiple + + const size_t initialSize; // Size of first chunk to allocate + const size_t chunkSize; // Size of other chunks to allocate + ptr buffer; // Doubleword-aligned pointer to free memory buffer + ptr bufferEnd; // Doubleword-aligned pointer to end of free memory buffer + BlockHeader *headerList; // Root of linked list of all allocated blocks in this pool + + public: + explicit Pool(size_t initialSize = 8192, size_t chunkSize = 1024); + ~Pool(); + private: + Pool(const Pool &); // Copying forbidden + void operator=(const Pool &); // Copying forbidden + + void *allocateOverflow(size_t size); + public: + void *allocate(size_t size); + void clear(); + + // Return the total amount of memory allocated by this pool + size_t totalSize(); +}; + + +// +// Allocate a block of the given size from the pool. +// +inline void *Pool::allocate(size_t size) +{ + size = size + 7 & -8; // Round up to a doubleword multiple + if ((size_t)(bufferEnd - buffer) >= size) { + ptr result = buffer; + buffer += size; + return result; + } + return allocateOverflow(size); +} + +#endif + + + diff --git a/ef/Utilities/General/Sequence.h b/ef/Utilities/General/Sequence.h new file mode 100644 index 000000000000..0e1c451783e5 --- /dev/null +++ b/ef/Utilities/General/Sequence.h @@ -0,0 +1,106 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#ifndef _SEQUENCE_H_ +#define _SEQUENCE_H_ + +#include "Fundamentals.h" +#include "Memory.h" + +template +class Sequence +{ +protected: + N *elts; + Uint32 cnt; + +public: +// ---------------------------------------------------------------------------- +// constructors. + + Sequence() : elts(NULL), cnt(0) {} + Sequence(Uint32 count) : elts(NULL), cnt(0) { reserve(count); } + ~Sequence() { if (elts) MEMOPS::free(elts); } + +// ---------------------------------------------------------------------------- +// copy. + + Sequence(const Sequence& x) : elts(NULL), cnt(0) + { + Uint32 x_count = x.count(); + const N *src = x.elements(); + reserve(x_count); + N *dst = elts; + while (x_count--) *dst++ = *src++; + } + + Sequence& operator=(const Sequence& x) + { + Uint32 x_count = x.count(); + const N *src = x.elements(); + N *dst; + + if ((&x == this) || (x_count == 0)) + return *this; + + reserve(x_count); + dst = elts; + while (x_count--) *dst++ = *src++; // copy the elements. + return *this; + } + +// ---------------------------------------------------------------------------- +// memory management. + + void reserve(Uint32 amount) + { + if (cnt < amount) { + if (elts) MEMOPS::free(elts); + elts = (N*)MEMOPS::alloc(amount * sizeof(N*)); + cnt = amount; + } + } + +// ---------------------------------------------------------------------------- +// pointers on the elements. + + N *elements() { return elts; } + const N *elements() const { return elts; } + +// ---------------------------------------------------------------------------- +// number of elements and the actual capacity. + + unsigned char empty() const { return cnt == 0; } + Uint32 count() const { return cnt; } + +// ---------------------------------------------------------------------------- +// add, remove, get element + + N& operator[](Uint32 index) { assert(index < count()); return elts[index]; } + const N& operator[](Uint32 index) const { assert(index < count()); return elts[index]; } + + void fill(const N& element) + { + N* src = elts; + Uint32 i = cnt; + while (i--) *src++ = element; + } +}; + + +#endif /* _SEQUENCE_H_ */ diff --git a/ef/Utilities/General/StringUtils.h b/ef/Utilities/General/StringUtils.h new file mode 100644 index 000000000000..00e930f78a1c --- /dev/null +++ b/ef/Utilities/General/StringUtils.h @@ -0,0 +1,96 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +// StringUtils.h +// +// Small replacements for the standard string class which is +// probably too big and complicated for our needs. + +#include "prprf.h" +#include "plstr.h" +#include "LogModule.h" + +// TemporaryStringCopy +// +// Make a copy of a string, for temporary use. Intended to be used +// statically. +class TemporaryStringCopy +{ + char* mCopy; + +public: + // Make a copy of a string + TemporaryStringCopy(const char* inStringToCopy) + { + mCopy = new char[PL_strlen(inStringToCopy)+1]; + PL_strcpy(mCopy, inStringToCopy); + } + + // Make a copy of the first len characters of the string */ + TemporaryStringCopy(const char *inStringToCopy, Int32 len) + { + mCopy = new char[len+1]; + mCopy = PL_strncpy(mCopy, inStringToCopy, len); + mCopy[len] = 0; + } + + ~TemporaryStringCopy() { delete [] mCopy; } + + char& operator[](int inIndex) { return mCopy[inIndex]; } + operator char*(void) { return mCopy; } + +#ifdef DEBUG +private: + TemporaryStringCopy(const TemporaryStringCopy &); // Copying forbidden + void operator=(const TemporaryStringCopy &); // Copying forbidden +#endif +}; + + +// TemporaryBuffer +// +// Buffer is thrown away in destructor +class TemporaryBuffer +{ + char *mData; + +public: + TemporaryBuffer(Uint32 len) { mData = new char[len]; } + ~TemporaryBuffer() { delete [] mData; } + + operator char*(void) { return mData; } +}; + +#ifdef DEBUG_LOG +#define DEBUG_TRACER(inLogModule, inString) Tracer(inLogModule, inString) +#else +#define DEBUG_TRACER(inLogModule, inString) +#endif + +class Tracer +{ + TemporaryStringCopy mString; + LogModuleObject& mLogModule; + +public: + Tracer(LogModuleObject& inLogModule, const char* inString) : + mString(inString), + mLogModule(inLogModule) { UT_OBJECTLOG(mLogModule, PR_LOG_ALWAYS, ("--> %s\n", (char*) mString)); } + + ~Tracer() { UT_OBJECTLOG(mLogModule, PR_LOG_ALWAYS, ("<-- %s\n", (char*) mString)); } +}; diff --git a/ef/Utilities/General/SystemEvents.h b/ef/Utilities/General/SystemEvents.h new file mode 100644 index 000000000000..c28053f6c687 --- /dev/null +++ b/ef/Utilities/General/SystemEvents.h @@ -0,0 +1,79 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +// SystemEvents.h +// +// Scott M. Silver +// + +// EventListener and EventBroadcaster which work together +// to distribute interesting events around a system. + +class EventListener; +class EventBroadcaster +{ + Vector mListeners; + void addListener(EventListener& inListener) { mListeners.append(&inListener); } + void removeListener(EventListener& inListener) { } + void broadcastEvent(BroadcastEventKind inKind, void* inArgument); + + static EventBroadcaster& checkAllocated(EventBroadcaster*& ioBroadcaster) + { + if (!ioBroadcaster) + ioBroadcaster = new EventBroadcaster(); + + return *ioBroadcaster; + } + +public: + static void addListener(EventBroadcaster*& ioBroadcaster, EventListener& inListener) + { + checkAllocated(ioBroadcaster).addListener(inListener); + } + + static void broadcastEvent(EventBroadcaster*& ioBroadcaster, BroadcastEventKind inKind, void* inArgument) + { + checkAllocated(ioBroadcaster).broadcastEvent(inKind, inArgument); + } + + static void removeListener(EventBroadcaster*& ioBroadcaster, EventListener& inListener) + { + checkAllocated(ioBroadcaster).removeListener(inListener); + } + +}; + + +class EventListener +{ +#ifdef DEBUG + Vector mBroadcasters; +#endif + + +public: + EventListener(EventBroadcaster*& ioBroadcaster) + { + ioBroadcaster->addListener(ioBroadcaster, *this); + } + + + ~EventListener() { } + + virtual void listenToMessage(BroadcastEventKind inKind, void* inArgument) = 0; +}; diff --git a/ef/Utilities/General/Tree.cpp b/ef/Utilities/General/Tree.cpp new file mode 100644 index 000000000000..ee413769775d --- /dev/null +++ b/ef/Utilities/General/Tree.cpp @@ -0,0 +1,390 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#include "Tree.h" + + +// ---------------------------------------------------------------------------- +// TreeNodeImpl + + +// +// Copy the link data from the src node to this node. On entry this node must not +// be linked to a tree, while src must be linked to a tree; on exit the opposite +// will be true. +// +// CAUTION: Do not call this directly; call TreeImpl::substitute or one of its +// derivatives instead. +// +inline void TreeNodeImpl::move(TreeNodeImpl &src) +{ + assert(!linked && src.linked); + *this = src; + src.unlink(); +} + + +// +// Let s be the subtree with this node as the root. Return the first (if right +// is false) or last (if right is true) node of this subtree. +// +TreeNodeImpl &TreeNodeImpl::extremeNode(bool right) +{ + TreeNodeImpl *p; + TreeNodeImpl *subtree = this; + + while ((p = subtree->getChild(right)) != 0) + subtree = p; + return *subtree; +} + + +// +// Return the node in the tree immediately before this node or nil if this +// node is the first in the tree. +// +TreeNodeImpl *TreeNodeImpl::prev() +{ + TreeNodeImpl *child = getChild(false); + if (child) + return &child->extremeNode(true); + TreeNodeImpl *node = this; + while (node && node->isLeft()) + node = node->getParent(); + if (node) + node = node->getParent(); + return node; +} + + +// +// Return the node in the tree immediately after this node or nil if this +// node is the last in the tree. +// +TreeNodeImpl *TreeNodeImpl::next() +{ + TreeNodeImpl *child = getChild(true); + if (child) + return &child->extremeNode(false); + TreeNodeImpl *node = this; + while (node && node->isRight()) + node = node->getParent(); + if (node) + node = node->getParent(); + return node; +} + + +// ---------------------------------------------------------------------------- +// TreeImpl + + +// +// Link a node to its new parent on the right side (if right is true) or left side +// if (right is false), replacing the parent's previous child link, if any, on that +// side. A nil node indicates that the parent's previous child link should be cleared. +// A nil parent represents the root, in which case right is ignored. +// +void TreeImpl::linkNode(TreeNodeImpl *node, TreeNodeImpl *parent, bool right) +{ + if (node) { + node->setParent(parent); + if (parent) + node->setRight(right); + else + node->setLeft(); + } + if (parent) + parent->setChild(right, node); + else + root = node; +} + + +// +// Rotate a node pair to the right (if right is true) or left (if right is false) +// without changing their colors. The given node starts at the parent of its +// partner and ends as the child of its partner. +// +void TreeImpl::rotate(TreeNodeImpl &node, bool right) +{ + TreeNodeImpl *partner = node.getChild(!right); + assert(partner); + linkNode(partner->getChild(right), &node, !right); + linkNode(partner, node.getParent(), node.isRight()); + linkNode(&node, partner, right); +} + + +// +// Attach a new red node and link it with the parent on the right side (if right is +// true) or left side if (right is false). The given node must not be already linked +// into a tree. +// A nil parent represents the root. +// +void TreeImpl::addNode(TreeNodeImpl &node, TreeNodeImpl *parent, bool right) +{ + assert(!(parent ? parent->getChild(right) : root)); + node.link(); + node.setRed(); + node.setChild(false, 0); + node.setChild(true, 0); + linkNode(&node, parent, right); + nNodes++; +} + + +// +// Make node be the right (if right is true) or left (if right is false) child of +// parent, which must be in the tree. That child must be currently nil. +// If where is nil, the tree must be currently empty, and in this case make node +// be the new root, ignoring the value of right. +// Rebalance the tree as needed. node should not be part of any tree on entry. +// +void TreeImpl::attach(TreeNodeImpl &node, TreeNodeImpl *parent, bool right) +{ + addNode(node, parent, right); + + // Rebalance the tree to make sure that we don't have two red nodes in a row. + TreeNodeImpl *p = &node; + while (true) { + // If we are the root, we make this node black and we're done. + if (!parent) { + p->setBlack(); + break; + } + + // If we're black, we're done. + if (parent->isBlack()) + break; + + // Otherwise we need a more complex rebalance. + right = p->isRight(); + TreeNodeImpl *grandparent = parent->getParent(); + assert(grandparent); + bool parentRight = parent->isRight(); + TreeNodeImpl *uncle = grandparent->getChild(!parentRight); + if (uncle && uncle->isRed()) { + parent->setBlack(); + uncle->setBlack(); + grandparent->setRed(); + p = grandparent; + } else { + if (right != parentRight) { + rotate(*parent, parentRight); + p = parent; + parent = p->getParent(); + } + parent->setBlack(); + grandparent->setRed(); + rotate(*grandparent, !parentRight); + break; + } + parent = p->getParent(); + } +} + + +// +// Insert node into the tree after node where. If where is nil, make node be the first +// node in the tree. Rebalance the tree as needed. +// node should not be part of any tree on entry. +// +void TreeImpl::insertAfter(TreeNodeImpl &node, TreeNodeImpl *where) +{ + TreeNodeImpl *child = where ? where->getChild(true) : root; + if (child) + attach(node, &child->extremeNode(false), false); + else + attach(node, where, true); +} + + +// +// Insert node into the tree before node where. If where is nil, make node be the last +// node in the tree. Rebalance the tree as needed. +// node should not be part of any tree on entry. +// +void TreeImpl::insertBefore(TreeNodeImpl &node, TreeNodeImpl *where) +{ + TreeNodeImpl *child = where ? where->getChild(false) : root; + if (child) + attach(node, &child->extremeNode(true), true); + else + attach(node, where, false); +} + + +// +// Remove the node from the tree, rebalancing the tree as needed. +// +void TreeImpl::remove(TreeNodeImpl &node) +{ + // If the node has both children, exchange node with node's predecessor + // in the tree ordering, which is guaranteed not to have a right child. + if (node.getChild(false) && node.getChild(true)) { + TreeNodeImpl &prev = node.getChild(false)->extremeNode(true); + // Exchange the link fields of prev and node. + TreeNodeImpl nodeCopy = node; + TreeNodeImpl prevCopy = prev; + + node.setRed(prevCopy.isRed()); + prev.setRed(nodeCopy.isRed()); + if (prevCopy.getParent() == &node) + linkNode(&node, &prev, false); + else { + linkNode(&node, prevCopy.getParent(), prevCopy.isRight()); + linkNode(nodeCopy.getChild(false), &prev, false); + } + linkNode(&prev, nodeCopy.getParent(), nodeCopy.isRight()); + linkNode(nodeCopy.getChild(true), &prev, true); + linkNode(prevCopy.getChild(false), &node, false); + node.setChild(true, 0); + // Quiet the assert about a linked node being deleted. + nodeCopy.unlink(); + prevCopy.unlink(); + } + + // At this point node has no more than one child. Let p be that child + // or nil if node has no children. + assert(!(node.getChild(false) && node.getChild(true))); + TreeNodeImpl *p = node.getChild(false); + if (!p) + p = node.getChild(true); + + // Link node's child directly to node's parent, bypassing node. + bool red = node.isRed(); + bool right = node.isRight(); + TreeNodeImpl *parent = node.getParent(); + linkNode(p, parent, right); + nNodes--; + node.unlink(); + + // If we just deleted a black node, we need to rebalance the tree. + if (!red) { + while (!p || p->isBlack()) { + if (!parent) + break; + + TreeNodeImpl *brother = parent->getChild(!right); + assert(brother); + if (brother->isRed()) { + brother->setRed(parent->isRed()); + parent->setRed(); + rotate(*parent, right); + brother = parent->getChild(!right); + } + + TreeNodeImpl *cousin = brother->getChild(!right); + if (cousin && cousin->isRed()) { + cousin->setBlack(); + brother->setRed(parent->isRed()); + parent->setBlack(); + rotate(*parent, right); + break; + } + + cousin = brother->getChild(right); + if (cousin && cousin->isRed()) { + brother->setRed(); + cousin->setBlack(); + rotate(*brother, !right); + } else { + brother->setRed(); + p = parent; + right = p->isRight(); + parent = p->getParent(); + } + } + if (p) + p->setBlack(); + } +} + + +// +// Splice newNode into oldNode's position in the tree. oldNode is removed from +// the tree. +// +void TreeImpl::substitute(TreeNodeImpl &newNode, TreeNodeImpl &oldNode) +{ + if (&newNode != &oldNode) { + newNode.move(oldNode); + + // Change the parent's pointer from oldNode to newNode + TreeNodeImpl *parent = newNode.getParent(); + if (parent) + parent->setChild(newNode.isRight(), &newNode); + else + root = &newNode; + + // Change the children's parent pointers from oldNode to newNode + TreeNodeImpl *child = newNode.getChild(false); + if (child) + child->setParent(&newNode); + child = newNode.getChild(true); + if (child) + child->setParent(&newNode); + } +} + + +#ifdef DEBUG +// +// Verify the integrity of a subtree rooted at the given node. Assert if +// anything wrong is found. +// Increment nNodes by the number of nodes encountered in the subtree. +// Return the number of non-nil black nodes encountered on any path from node +// to a leaf (this number must be constant regardless of the path and leaf +// chosen) in blackDepth. Return true if this node is red. +// +bool TreeImpl::verifySubtree(TreeNodeImpl *node, TreeNodeImpl *parent, bool rightChild, Uint32 &nNodes, Uint32 &blackDepth) +{ + if (node) { + nNodes++; + assert(node->getParent() == parent && node->isRight() == rightChild); + Uint32 leftChildDepth; + Uint32 rightChildDepth; + bool red = node->isRed(); + bool hasRedChild = verifySubtree(node->getChild(false), node, false, nNodes, leftChildDepth); + hasRedChild |= verifySubtree(node->getChild(true), node, true, nNodes, rightChildDepth); + assert(leftChildDepth == rightChildDepth); + if (red) + assert(!hasRedChild); + else + leftChildDepth++; + blackDepth = leftChildDepth; + return red; + } else { + blackDepth = 0; + return false; + } +} + + +// +// Verify that the tree is internally consistent. Assert if anything wrong is found. +// +void TreeImpl::verify() const +{ + Uint32 n = 0; + Uint32 blackDepth; + bool rootIsRed = verifySubtree(root, 0, false, n, blackDepth); + assert(!rootIsRed && n == nNodes); +} +#endif diff --git a/ef/Utilities/General/Tree.h b/ef/Utilities/General/Tree.h new file mode 100644 index 000000000000..0fabf7377a74 --- /dev/null +++ b/ef/Utilities/General/Tree.h @@ -0,0 +1,404 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#ifndef TREE_H +#define TREE_H + +#include "Fundamentals.h" + +// --- PRIVATE ---------------------------------------------------------------- + +struct TreeNodeImpl +{ + private: + TreeNodeImpl *parent; // This node's parent or nil if this is the root + TreeNodeImpl *children[2]; // This node's left (0) and right (1) children + bool red BOOL_8; // This node is black if false, red if true + bool right BOOL_8; // This node is a left child if false, right if true + #ifdef DEBUG + bool linked BOOL_8; // True if this node is linked into a tree + #endif + + public: + #ifdef DEBUG + TreeNodeImpl(): linked(false) {} + ~TreeNodeImpl() {assert(!linked);} + #endif + + void link() {assert(!linked); DEBUG_ONLY(linked = true);} + void unlink() {assert(linked); DEBUG_ONLY(linked = false);} + + TreeNodeImpl *getParent() const {assert(linked); return parent;} + TreeNodeImpl *getChild(bool right) const {assert(linked); return children[right];} + bool isBlack() const {assert(linked); return !red;} + bool isRed() const {assert(linked); return red;} + bool isLeft() const {assert(linked); return !right;} + bool isRight() const {assert(linked); return right;} + + void setParent(TreeNodeImpl *p) {assert(linked); parent = p;} + void setChild(bool right, TreeNodeImpl *c) {assert(linked); children[right] = c;} + void setBlack() {assert(linked); red = false;} + void setRed(bool red = true) {assert(linked); TreeNodeImpl::red = red;} + void setLeft() {assert(linked); right = false;} + void setRight(bool right = true) {assert(linked); TreeNodeImpl::right = right;} + void move(TreeNodeImpl &src); + + TreeNodeImpl &extremeNode(bool right); + TreeNodeImpl *prev(); + TreeNodeImpl *next(); +}; + + +// Base class for Tree. Do not use directly. +class TreeImpl +{ + TreeNodeImpl *root; // The tree's root or nil if the tree is empty + Uint32 nNodes; // Current number of nodes linked into the tree + + public: + TreeImpl(): root(0), nNodes(0) {} + + TreeNodeImpl *getRoot() const {return root;} + TreeNodeImpl *firstNode() const {return root ? &root->extremeNode(false) : 0;} + TreeNodeImpl *lastNode() const {return root ? &root->extremeNode(true) : 0;} + TreeNodeImpl *next(TreeNodeImpl *n) const {return n ? n->next() : firstNode();} + TreeNodeImpl *prev(TreeNodeImpl *n) const {return n ? n->prev() : lastNode();} + Uint32 getNNodes() const {return nNodes;} + + private: + void linkNode(TreeNodeImpl *node, TreeNodeImpl *parent, bool right); + void rotate(TreeNodeImpl &node, bool right); + void addNode(TreeNodeImpl &node, TreeNodeImpl *parent, bool right); + public: + + void attach(TreeNodeImpl &node, TreeNodeImpl *where, bool right); + void insertAfter(TreeNodeImpl &node, TreeNodeImpl *where); + void insertBefore(TreeNodeImpl &node, TreeNodeImpl *where); + void remove(TreeNodeImpl &node); + void substitute(TreeNodeImpl &newNode, TreeNodeImpl &oldNode); + + #ifdef DEBUG + private: + static bool verifySubtree(TreeNodeImpl *node, TreeNodeImpl *parent, bool rightChild, Uint32 &nNodes, Uint32 &blackDepth); + public: + void verify() const; + #endif +}; + + +// --- PUBLIC ----------------------------------------------------------------- + + +// Derive Tree nodes from this class. Node is the node class, which should +// be a subclass of this class. +template +class TreeNode: public TreeNodeImpl +{ + #ifdef DEBUG + TreeNode(const TreeNode &); // Copying forbidden + void operator=(const TreeNode &); // Copying forbidden + public: + TreeNode() {} + #endif + public: + Node *getParent() const {return static_cast(TreeNodeImpl::getParent());} + Node *getChild(bool right) const {return static_cast(TreeNodeImpl::getChild(right));} + + Node *prev() {return static_cast(TreeNodeImpl::prev());} + Node *next() {return static_cast(TreeNodeImpl::next());} +}; + + +// +// A balanced binary tree with nodes of class Node, which must be a subclass of TreeNode. +// +// Only insert, remove, and substitute operations are provided. It is up to the user +// to determine the proper place to insert a node. The Tree also does not do storage +// management (allocation or deallocation) of its nodes; the user should do so explicitly +// if needed. +// +template +class Tree: private TreeImpl +{ + public: + Node *getRoot() const {return static_cast(TreeImpl::getRoot());} + Node *firstNode() const {return static_cast(TreeImpl::firstNode());} + Node *lastNode() const {return static_cast(TreeImpl::lastNode());} + Node *next(Node *n) const {return n ? n->next() : firstNode();} + Node *prev(Node *n) const {return n ? n->prev() : lastNode();} + TreeImpl::getNNodes; + + void attach(Node &node, Node *where, bool right) {TreeImpl::attach(node, where, right);} + void insertAfter(Node &node, Node *where) {TreeImpl::insertAfter(node, where);} + void insertBefore(Node &node, Node *where) {TreeImpl::insertBefore(node, where);} + void remove(Node &node) {TreeImpl::remove(node);} + void substitute(Node &newNode, Node &oldNode) {TreeImpl::substitute(newNode, oldNode);} + + #ifdef DEBUG + TreeImpl::verify; + #endif +}; + + +// +// A sorted balanced binary tree with nodes of class Node, which must be a subclass of +// TreeNode. Each Node has a key of class Key. +// +// Each Key must support the following methods: +// +// Key(const Key &); +// void operator=(const Key &); +// Copy constructor and assignment. +// +// bool operator<(const Key &key2) const; +// Comparisons. These comparisons must induce a full order on all Keys. In particular: +// For any key key1, key1, each Node must support the following methods: +// +// Key getKey() const or +// const Key &getKey() const; +// Returns the node's key. +// +// Find, insert, remove, and substitute operations are provided. The SortedTree does not +// do storage management (allocation or deallocation) of its nodes; the user should do so +// explicitly if needed. +// +template +class SortedTree: public Tree +{ + #ifdef DEBUG + static bool isBetween(Node &node, Node *prev, Node *next); + bool immediatelyAfter(Node &node, Node *prev) const; + bool immediatelyBefore(Node &node, Node *next) const; + #endif + public: + Node *find(Key key) const; + Node *find(Key key, Node *&where, bool &right) const; + Node *findAfter(Key key) const; + Node *findBefore(Key key) const; + + void attach(Node &node, Node *where, bool right); + void insert(Node &node); + void insertAfter(Node &node, Node *where) {assert(immediatelyAfter(node, where)); Tree::insertAfter(node, where);} + void insertBefore(Node &node, Node *where) {assert(immediatelyBefore(node, where)); Tree::insertBefore(node, where);} + void substitute(Node &newNode, Node &oldNode); + + #ifdef DEBUG + void verify() const; + #endif +}; + + +// --- TEMPLATES -------------------------------------------------------------- + +#ifdef DEBUG +// +// Return true if key(prev) <= key(node) <= key(next), where comparisons against a nil +// node's key always succeed. +// +template +inline bool SortedTree::isBetween(Node &node, Node *prev, Node *next) +{ + return !(prev && node.getKey() < prev->getKey() || next && next->getKey() < node.getKey()); +} + +// +// Return true if node can be inserted immediately after prev +// without violating the key ordering of the tree. +// +template +bool SortedTree::immediatelyAfter(Node &node, Node *prev) const +{ + return isBetween(node, prev, next(prev)); +} + + +// +// Return true if node can be inserted immediately before next +// without violating the key ordering of the tree. +// +template +bool SortedTree::immediatelyBefore(Node &node, Node *next) const +{ + return isBetween(node, prev(next), next); +} +#endif + +// +// Find and return a node that contains the given key. If there is no such node, +// return nil. If there is more than one node with the given key in the tree, +// pick one arbitrarily. +// +template +Node *SortedTree::find(Key key) const +{ + Node *p = getRoot(); + while (p) + if (key < p->getKey()) + p = p->getChild(false); + else if (p->getKey() < key) + p = p->getChild(true); + else + break; + return p; +} + + +// +// Find and return a node that contains the given key. If there is no such node, +// return nil and store a node in where and a flag in right that can be passed to +// attach to add a node with the given key to the tree. If there is more than one +// node with the given key in the tree, pick one arbitrarily. +// where and right are undefined if the node has been found. +// +template +Node *SortedTree::find(Key key, Node *&where, bool &right) const +{ + Node *p = getRoot(); + Node *parent = 0; + bool rightChild = false; + while (p) { + if (key < p->getKey()) + rightChild = false; + else if (p->getKey() < key) + rightChild = true; + else + return p; + parent = p; + p = p->getChild(rightChild); + } + where = parent; + right = rightChild; + return 0; +} + + +// +// Find and return a node that contains the given key. If there is no such node, +// return the tree node with the lowest key greater than the given key; if there +// still is no such node (i.e. the given key is greater than the keys of all nodes +// in the tree), return nil. If there is more than one node with the given key in +// the tree, pick one arbitrarily. +// +template +Node *SortedTree::findAfter(Key key) const +{ + Node *where; + bool right; + Node *p = find(key, where, right); + if (!p && where) { + assert(!where->getChild(right)); + if (right) + p = where->next(); + else + p = where; + } + return p; +} + + +// +// Find and return a node that contains the given key. If there is no such node, +// return the tree node with the greatest key less than the given key; if there +// still is no such node (i.e. the given key is lower than the keys of all nodes +// in the tree), return nil. If there is more than one node with the given key in +// the tree, pick one arbitrarily. +// +template +Node *SortedTree::findBefore(Key key) const +{ + Node *where; + bool right; + Node *p = find(key, where, right); + if (!p && where) { + assert(!where->getChild(right)); + if (right) + p = where; + else + p = where->prev(); + } + return p; +} + + +// +// Attach the node at the position (where, right) returned by find. +// +template +inline void SortedTree::attach(Node &node, Node *where, bool right) +{ + assert(right ? immediatelyAfter(node, where) : immediatelyBefore(node, where)); + Tree::attach(node, where, right); +} + + +// +// Insert node into the proper place in the tree. Rebalance the tree as needed. +// If there already are nodes with an equal key in the tree, the new node will be +// inserted arbitrarily either before, after, or between such nodes. +// node should not be part of any tree on entry. +// +template +void SortedTree::insert(Node &node) +{ + Node *where; + bool right; + Node *p = find(node.getKey(), where, right); + if (p) + insertAfter(node, p); + else + attach(node, where, right); +} + + +// +// Splice newNode into oldNode's position in the tree. oldNode is removed from +// the tree. +// +template +inline void SortedTree::substitute(Node &newNode, Node &oldNode) +{ + assert(isBetween(newNode, oldNode.prev(), oldNode.next())); + Tree::substitute(newNode, oldNode); +} + + +#ifdef DEBUG +// +// Verify that the tree is internally consistent and that the entries in it are +// still sorted. Assert if anything wrong is found. +// +template +void SortedTree::verify() const +{ + Tree::verify(); + Node *p = firstNode(); + if (p) { + Node *q; + while ((q = p->next()) != 0) { + assert(!(q->getKey() < p->getKey())); + p = q; + } + } +} +#endif +#endif diff --git a/ef/Utilities/General/Vector.h b/ef/Utilities/General/Vector.h new file mode 100644 index 000000000000..d2a401272bf3 --- /dev/null +++ b/ef/Utilities/General/Vector.h @@ -0,0 +1,146 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#ifndef _VECTOR_H_ +#define _VECTOR_H_ + +#include "Fundamentals.h" + +#define DEFAULT_START_SIZE 128 + +template +class Vector +{ +private: + N *start; + N *finish; + N *end_of_storage; + +public: +// ---------------------------------------------------------------------------- +// constructors. + + Vector() : start(0), finish(0), end_of_storage(0) {} + Vector(unsigned int n) : start(0), finish(0), end_of_storage(0) {reserve(n);} + ~Vector() {if (start) delete[] start;} + +// ---------------------------------------------------------------------------- +// copy. + + Vector(const Vector& x) : start(0), finish(0), end_of_storage(0) + { + unsigned int x_size = x.size(); + const N *src = x.begin(); + if (x_size) + { + reserve(x_size); + finish = start; + while (x_size--) *finish++ = *src++; + } + } + + Vector& operator=(const Vector& x) + { + unsigned int x_size = x.size(); + const N *src = x.begin(); + N *dst; + + if ((&x == this) || (x_size == 0)) + return *this; + + reserve(x_size); + finish = start; + while (x_size--) *finish++ = *src++; // copy the elements. + for (dst = finish; dst < end_of_storage; dst++) *dst = N(); + return *this; + } + +// ---------------------------------------------------------------------------- +// memory management. + + void reserve(unsigned int amount) + { + if (!amount) amount = DEFAULT_START_SIZE; + + if (capacity() < amount) + { + N *tmp = new N[amount]; + N *src = begin(); + N *dst = tmp; + unsigned int actual_size = size(); + + while (actual_size--) *dst++ = *src++; + delete[] start; + finish = tmp + size(); + start = tmp; + end_of_storage = start + amount; + } + } + +// ---------------------------------------------------------------------------- +// pointers on the elements. + + N *begin() {return start;} + const N *begin() const {return start;} + N *end() {return finish;} + const N *end() const {return finish;} + + +// ---------------------------------------------------------------------------- +// number of elements and the actual capacity. + + unsigned char empty() const {return (begin() == end());} + unsigned int size() const {return (unsigned int)(end() - begin());} + unsigned int capacity() const {return (unsigned int)(end_of_storage - begin());} + +// ---------------------------------------------------------------------------- +// add, remove, get element + + N& operator[](unsigned int index) {assert (index < size()); return start[index];} + const N& operator[](unsigned int index) const {assert (index < size()); return start[index];} + + void fill(const N& element) + { + N* src = start; + while (src < finish) *src++ = element; + } + + void append(const N& element) + { + if (finish == end_of_storage) + reserve(2 * capacity()); + + *finish++ = element; + } + + void append(unsigned int count, const N& element) + { + reserve(size() + count); + while (count--) *finish++ = element; + } + + void eraseLast() {if (!empty()) *--finish = N();} + void eraseAll() {while (finish > start) *--finish = N();} + + + N& first() {return *begin();} + N& last() {return *(end() - 1);} +}; + + +#endif /* _VECTOR_H_ */ diff --git a/ef/Utilities/General/md/CatchAssert_md.h b/ef/Utilities/General/md/CatchAssert_md.h new file mode 100644 index 000000000000..c6817daf778c --- /dev/null +++ b/ef/Utilities/General/md/CatchAssert_md.h @@ -0,0 +1,45 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#ifndef XP_PC +#include +#endif + +/* + * Define the real assert for each platform. + * + */ + +/* WIN32 Specific. */ +#ifdef WIN32 + +#undef throwAssert + +#ifdef __cplusplus +extern "C" { +#endif + +_CRTIMP void __cdecl _assert(void *, void *, unsigned); + +#ifdef __cplusplus +} +#endif + +#define throwAssert(exp, filename, linenumber) _assert(exp, filename, linenumber) + +#endif //WIN32 diff --git a/ef/Utilities/General/md/Makefile b/ef/Utilities/General/md/Makefile new file mode 100644 index 000000000000..9e3099598a73 --- /dev/null +++ b/ef/Utilities/General/md/Makefile @@ -0,0 +1,52 @@ +#!gmake +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +####################################################################### +# (1) Directory specific info # +####################################################################### + +DEPTH = ../../.. + +MODULE_NAME = EF + +LOCAL_EXPORTS = CatchAssert_md.h \ + $(NULL) + +####################################################################### +# (2) Include "component" configuration information. # +####################################################################### + +include $(DEPTH)/config/config.mk + +####################################################################### +# (3) Include "local" platform-dependent assignments (OPTIONAL). # +####################################################################### + + + +####################################################################### +# (4) Execute "component" rules. (OPTIONAL) # +####################################################################### + +include $(DEPTH)/config/rules.mk + +####################################################################### +# (7) Execute "local" rules. (OPTIONAL). # +####################################################################### + + + diff --git a/ef/Utilities/Makefile b/ef/Utilities/Makefile new file mode 100644 index 000000000000..36d52f5360b6 --- /dev/null +++ b/ef/Utilities/Makefile @@ -0,0 +1,57 @@ +#!gmake +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +####################################################################### +# (1) Directory specific info # +####################################################################### + +DEPTH = .. + +DIRS = General zlib Disassemblers + +SUBMODULES = $(DIRS) + + +MODULE_NAME = EF + +NO_PROGRAM_IN_SUBDIRS = 1 +NO_INSTALL_IN_SUBDIRS = 1 + +####################################################################### +# (2) Include "component" configuration information. # +####################################################################### + +include $(DEPTH)/config/config.mk + +####################################################################### +# (3) Include "local" platform-dependent assignments (OPTIONAL). # +####################################################################### + + + +####################################################################### +# (4) Execute "component" rules. (OPTIONAL) # +####################################################################### + +include $(DEPTH)/config/rules.mk + +####################################################################### +# (7) Execute "local" rules. (OPTIONAL). # +####################################################################### + + + diff --git a/ef/Utilities/qa/classdump/Makefile b/ef/Utilities/qa/classdump/Makefile new file mode 100644 index 000000000000..2f00a430a097 --- /dev/null +++ b/ef/Utilities/qa/classdump/Makefile @@ -0,0 +1,32 @@ +#!gmake +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +#Unix Makefile for classdump + +#Variables. +CC = gcc +CFLAGS = -g +SRCS = classdump.c +PROGRAM = classdump +OBJS = classdump.o + +#Rules. +$(PROGRAM): $(OBJS) + $(CC) $(CFLAGS) -o $@ $(OBJS) + +classdump.o: classdump.c classfile.h classdump.h + $(CC) -O -c classdump.c diff --git a/ef/Utilities/qa/classdump/classdump.c b/ef/Utilities/qa/classdump/classdump.c new file mode 100644 index 000000000000..81ab61f86356 --- /dev/null +++ b/ef/Utilities/qa/classdump/classdump.c @@ -0,0 +1,539 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +/******************************************************************** +* +* file: classdump.c +* +* author: Patrick Dionisio +* +* purpose: To read and print out a Java classfile. +* +* usage: classfile - +* +********************************************************************/ + +#include +#include +#include "classfile.h" +#include "classdump.h" + +void main(int argc, char* argv[]) +{ + + /*Variables.*/ + int i,j,k = 0; + int count = 0; + int subcount = 0; + int tag = 0; + int length = 0; + int access_flags; + int index = 0; + + /*Pointer to the linked list which store the strings of the constant_pool.*/ + struct linked_list *first_ptr = NULL; + struct linked_list *current_ptr = NULL; + struct linked_list *new_ptr = NULL; + + /*Open class for reading.*/ + FILE *classfile; + + /*Get arguments.*/ + if (argc > 1) classfile = fopen(argv[1],"rb"); + else { + printf("\nNo file to read.\n"); + exit(0); + } + + + /* Print classname */ + printf("classfile:"); + printTab(3); + printf("%s",argv[1]); + + /* Start reading classfile. Refer to the JVM Spec for more info.*/ + + /* u4 magic */ + printf("\nmagic: "); + printTab(4); + printHex4(getu4(classfile)); + + /* u2 minor */ + printf("\nminor: "); + printTab(4); + printDec2(getu2(classfile)); + + /* u2 major */ + printf("\nmajor: "); + printTab(4); + printDec2(getu2(classfile)); + + printf("\n"); + + /* u2 constant_pool_count */ + printf("\nconstant_pool:"); + count = getu2(classfile); + printf("\n"); + + + /* cp_info constant_pool[constant_pool_count-1] */ + for ( i = 1; i <= count - 1; i++ ) + { + tag = getu1(classfile); + + switch (tag) + { + + case CONSTANT_Utf8: + + printDec1(i); + + printTab(1); + printf("utf8"); + + if ( !first_ptr ) { + + first_ptr = malloc(sizeof(struct linked_list)); + (*first_ptr).index = i; + strcpy((*first_ptr).name,getUtf8(classfile)); + current_ptr = first_ptr; + + } + + else { + + new_ptr = malloc(sizeof(struct linked_list)); + if ( new_ptr == NULL ) + { + printf("Out of Memory for new_ptr"); + exit(0); + } + (*new_ptr).index = i; + strcpy((*new_ptr).name,getUtf8(classfile)); + (*new_ptr).next_ptr = NULL; + (*current_ptr).next_ptr = new_ptr; + current_ptr = new_ptr; + + } + + printTab(3); + printf("%s",(*current_ptr).name); + printf("\n"); + break; + + case 2: + + printf("unicode"); + printDec1(i); + break; + + case CONSTANT_Integer: + + printDec1(i); + + printTab(1); + printf("integer"); + + printTab(3); + printDec4(getu4(classfile)); + printf("\n"); + break; + + case CONSTANT_Float: + + printDec1(i); + + printTab(1); + printf("float"); + + printTab(3); + printDec4(getu4(classfile)); + printf("\n"); + break; + + case CONSTANT_Long: + + printDec1(i); + + printTab(1); + printf("long"); + + printTab(3); + printDec4((getu4(classfile)<<32) + getu4(classfile)); + printf("\n"); + break; + + case CONSTANT_Double: + + printDec1(i); + + printTab(1); + printf("double"); + + printTab(3); + printDec4((getu4(classfile)<<32) + getu4(classfile)); + printf("\n"); + break; + + case CONSTANT_Class: + + printDec1(i); + + printTab(1); + printf("class"); + + printTab(3); + printDec2(getu2(classfile)); + printf("\n"); + break; + + case CONSTANT_String: + + printDec1(i); + + printTab(1); + printf("string"); + + printTab(3); + printDec2(getu2(classfile)); + printf("\n"); + break; + + case CONSTANT_Fieldref: + + printDec1(i); + + printTab(1); + printf("fieldref"); + + printTab(2); + printf("class: "); + printDec2(getu2(classfile)); + + printTab(1); + printf("name+type: "); + printDec2(getu2(classfile)); + printf("\n"); + break; + + case CONSTANT_Methodref: + + printDec1(i); + + printTab(1); + printf("methodref"); + + printTab(2); + printf("class: "); + printDec2(getu2(classfile)); + + printTab(1); + printf("name+type: "); + printDec2(getu2(classfile)); + printf("\n"); + break; + + case CONSTANT_InterfaceMethodref: + + printDec1(i); + + printTab(1); + printf("interfacemethodref"); + + printTab(1); + printf("class: "); + printDec2(getu2(classfile)); + + printTab(1); + printf("name+type: "); + printDec2(getu2(classfile)); + printf("\n"); + break; + + case CONSTANT_NameAndType: + + printDec1(i); + + printTab(1); + printf("name+type"); + + printTab(2); + printf("class: "); + printDec2(getu2(classfile)); + + printTab(1); + printf("descriptor: "); + printDec2(getu2(classfile)); + printf("\n"); + break; + + default: + + printf("\nError in Constant Pool."); + exit(0); + + } + + } + + /* u2 access_flags */ + printf("\naccess_flags"); + printTab(3); + access_flags = getu2(classfile); + printf("%s",getAccessFlags(access_flags)); + + /* u2 this_class */ + printf("\nthis_class"); + printTab(3); + printDec2(getu2(classfile)); + + /* u2 super_class */ + printf("\nsuper_class"); + printTab(3); + printDec2(getu2(classfile)); + + printf("\n"); + + /* u2 interfaces_count */ + printf("\ninterfaces"); + printTab(3); + count = getu2(classfile); + printDec2(count); + + /* u2 interfaces[interfaces_count] */ + if ( count != 0 ) for ( i=1; i <= count; i++) + { + printf("\n"); + printTab(1); + printf("interface"); + printTab(2); + printf("%i",i); + printTab(1); + printf("index "); + printDec2(getu2(classfile)); + printf("\n"); + } + + printf("\n"); + + /* u2 fields_count */ + printf("\nfields"); + printTab(4); + count = getu2(classfile); + printDec2(count); + + /* field_info fields[fields_count] */ + if ( count != 0 ) for ( i=1; i <= count; i++) + { + printf("\n"); + printTab(1); + printf("field"); + printTab(3); + printf("%i",i); + + /* u2 access_flags */ + printf("\n"); + printTab(1); + printf("access_flags"); + printTab(2); + access_flags = getu2(classfile); + printf("%s",getAccessFlags(access_flags)); + + /* u2 name_index */ + printf("\n"); + printTab(1); + printf("name"); + printTab(3); + printDec2(getu2(classfile)); + + /* u2 descriptor_index */ + printf("\n"); + printTab(1); + printf("descriptor"); + printTab(2); + printDec2(getu2(classfile)); + + /* u2 atributes_count */ + printf("\n"); + printTab(1); + printf("attributes"); + printTab(2); + subcount = getu2(classfile); + printDec2(subcount); + + /* attribute_info attributes[attributes_count] */ + if ( subcount != 0 ) for ( j=1; j<=subcount; j++) + { + printf("\n"); + printTab(2); + printf("attr_name"); + printTab(1); + index = getu2(classfile); + + if ( whichAttribute(getName(first_ptr,index)) == CONSTANT_VALUE ) + { + getAttributes(CONSTANT_VALUE,classfile,first_ptr); + } + + else /*Silently ignore other attributes.*/ + { + length = getu4(classfile); + for ( k=0; k < length; k++ ) getu1(classfile); + } + } + + printf("\n"); + } + + printf("\n"); + + /* u2 methods_count */ + printf("\nmethods"); + printTab(4); + count = getu2(classfile); + printDec2(count); + + /* methods_info methods[methods_count] */ + if ( count != 0 ) for ( i=1; i<=count; i++) + { + printf("\n"); + printTab(1); + printf("method"); + printTab(3); + printf("%i",i); + + /* u2 access_flags */ + printf("\n"); + printTab(1); + printf("access_flags"); + printTab(2); + access_flags = getu2(classfile); + printf("%s",getAccessFlags(access_flags)); + + /* u2 name_index */ + printf("\n"); + printTab(1); + printf("name"); + printTab(3); + printDec2(getu2(classfile)); + + /* u2 descriptor_index */ + printf("\n"); + printTab(1); + printf("descriptor"); + printTab(2); + printDec2(getu2(classfile)); + + /* u2 atributes_count */ + printf("\n"); + printTab(1); + printf("attributes"); + printTab(2); + subcount = getu2(classfile); + printDec2(subcount); + + /* attribute_info attributes[attributes_count] */ + if ( subcount != 0 ) for ( j=1; j<=subcount; j++) + { + printf("\n"); + printTab(2); + printf("attr_name"); + printTab(1); + index = getu2(classfile); + + switch ( whichAttribute(getName(first_ptr,index)) ) + { + case CODE: + getAttributes(CODE,classfile,first_ptr); + break; + + case EXCEPTIONS: + getAttributes(EXCEPTIONS,classfile,first_ptr); + break; + + default:/*Silently ignore other attributes.*/ + length = getu4(classfile); + for ( k=0; k < length; k++ ) getu1(classfile); + } + + } + + printf("\n"); + } + + /* u2 attributes_count */ + printf("\nattributes"); + count = getu2(classfile); + printTab(3); + printDec2(count); + + /* attributes_info attributes[attributes_count] */ + for ( i=1; i<=count; i++ ) + { + printf("\n"); + printTab(1); + printf("attribute"); + printTab(2); + printf("%i",i); + index = getu2(classfile); + + printf("\n"); + printTab(2); + printf("attr_name"); + printTab(1); + if (whichAttribute(getName(first_ptr,index)) == SOURCE_FILE) + getAttributes(SOURCE_FILE,classfile,first_ptr); + else + { + length = getu4(classfile); + for ( k=0; k < length; k++ ) getu2(classfile); + } + + break; + } + + + printf("\n"); + + /*Free memory.*/ + freeList(first_ptr); + + fclose(classfile); + + +} + + + + + + + + + + + + + + + + + + + + diff --git a/ef/Utilities/qa/classdump/classdump.h b/ef/Utilities/qa/classdump/classdump.h new file mode 100644 index 000000000000..8da8253cbd17 --- /dev/null +++ b/ef/Utilities/qa/classdump/classdump.h @@ -0,0 +1,697 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +/******************************************************************** +* +* classdump.h +* +* author: Patrick Dionisio +* +* purpose: Header file for classdump.c +* +********************************************************************/ + + +/*Variables.*/ + +/*linked_list stores the index and the name of a string in +the constant_pool.*/ +struct linked_list { + + int index; + char name[255]; + struct linked_list *next_ptr; + +}; + +/******************************************************************** +* +* function: void printTab(int i) +* +* purpose: Used for standout format. Prints out tabs +* in by the number of i. +* +*********************************************************************/ + +void printTab(int i) +{ + int j; + + for (j=0; j>4)&15]); + printByte(hex[i&15]); + +} + +/******************************************************************** +* +* function: void printHex2(int i) +* +* purpose: Prints out the hexidecimal value of two bytes. +* +* +*********************************************************************/ + +void printHex2(int i) +{ + /*Print high-byte.*/ + printHex1(i>>8); + + /*Print low-byte.*/ + printHex1(i&0xff); +} + +/******************************************************************** +* +* function: void printHex4(int i) +* +* purpose: Prints out the hexidecimal value of four bytes. +* +* +*********************************************************************/ + +void printHex4(int i) +{ + /*Print out the first two bytes.*/ + printHex2(i>>16); + + /*Print out the next two bytes.*/ + printHex2(i&0xffff); +} + +/******************************************************************** +* +* function: void printDec4(int i) +* +* purpose: Prints out the decimal value of four bytes. +* +* +*********************************************************************/ + +void printDec4(int i) +{ + int k,j=1; + + /*Check if i is negative. If it is, then print out a '-' and + make i positive.*/ + if ( i < 0 ) + { + putc('-',stdout); + i = -i; + } + + /*Print out the bytes.*/ + k = i; + while ( k /= 10 ) j *= 10; + while (j) + { + k = i/j; + printByte(k+'0'); + i -= k*j; + j /= 10; + } +} + +/******************************************************************** +* +* function: void printDec2(int i) +* +* purpose: Prints out the decimal value of the two bytes. +* +* +*********************************************************************/ + +void printDec2(int i) +{ + printDec4(i&0xffff); +} + +/******************************************************************** +* +* function: int printDec1(int i) +* +* purpose: Prints out the decimal value of the one byte. +* +* +*********************************************************************/ + +void printDec1(int i) +{ + printDec4(i&0xff); +} + +/******************************************************************** +* +* function: char * getName(struct linked_list *first_ptr,int index) +* +* purpose: Returns the name stored in the given index from the +* constant_pool. +* +*********************************************************************/ + +char* getName(struct linked_list *first_ptr,int index) +{ + /*The pointer to use in going through the linked list.*/ + struct linked_list *current_ptr = NULL; + current_ptr = first_ptr; + + /*Find the name in the list.*/ + while ( current_ptr != NULL ) + { + if ( (*current_ptr).index == index ) return (*current_ptr).name; + else current_ptr = (*current_ptr).next_ptr; + } + + return "Error in getName"; + +} + +/******************************************************************** +* +* function: void freeList(struct linked_list *first_ptr) +* +* purpose: Frees up the allocated memory. +* +* +*********************************************************************/ + +void freeList(struct linked_list *first_ptr) +{ + /*The pointer to use in going through the linked list.*/ + struct linked_list *current_ptr = NULL; + current_ptr = first_ptr; + + /*Go through and clean the list.*/ + while ( first_ptr != NULL ) + { + current_ptr = (*current_ptr).next_ptr; + free(first_ptr); + first_ptr = current_ptr; + } +} + +/******************************************************************** +* +* function: char* getBytecode(int i, FILE *input) +* +* purpose: Prints the bytecode value. +* +* +*********************************************************************/ + +void getBytecode(int i, FILE *input) +{ + /*Local variables.*/ + int nested[10]; + int j,k,l,m,n,o; + int posn = 0; /*Index for nested.*/ + int posf = 0; /*Current length of code.*/ + + /*Reference type table.*/ + static char typ[256] = { + /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */ + /*0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /*1*/ 1, 2, 1, 2, 2, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, + /*2*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /*3*/ 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, + /*4*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /*5*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /*6*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /*7*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /*8*/ 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /*9*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 6, 6, 6, 6, 6, 6, + /*a*/ 6, 6, 6, 6, 6, 6, 6, 6, 6, 1, 7, 8, 0, 0, 0, 0, + /*b*/ 0, 0, 2, 2, 2, 2, 2, 2, 2, 9,10, 2, 0, 2, 0, 0, + /*c*/ 2, 2, 0, 0,11, 5, 2, 2, 3, 3, 0, 0, 0, 2, 0, 0, + /*d*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /*e*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /*f*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + + + l=posf; + j=posf+i; + posn++; + + /*Print out bytecodes till the length has been reached.*/ + while (posf0xd2) k=0xd2; + + + /*Refer to the type table and print out the correct bytecode along + with any values.*/ + switch (typ[k]) + { + + case 0: + printf(mnem[k]); + break; + + case 1: + m=getu1(input); + printf(mnem[k]); + printf(" "); + printHex1(m); + posf++; + break; + + case 2: + m=getu2(input); + printf(mnem[k]); + printf(" "); + printHex2(m); + posf = posf + 2; + break; + + case 3: + m=getu4(input); + printf(mnem[k]); + printf(" "); + printHex4(m); + posf = posf + 4; + break; + + case 4: + m=getu1(input); + n=getu1(input); + printf(mnem[k]); + printf(" "); + printHex1(m); + printf(","); + printHex1(n); + posf = posf + 2; + break; + + case 5: + m=getu2(input); + n=getu1(input); + printf(mnem[k]); + printf(" "); + printHex2(m); + printf(","); + printHex1(n); + posf = posf + 3; + break; + + case 6: + m=getu2(input); + printf(mnem[k]); + printf(" "); + printHex2(m+nested[posn]); + posf = posf + 2; + break; + + case 7: /*Special case for tableswitch*/ + + /*Read and ignore padded bytes.*/ + for (m=(nested[posn]&3)^3; m>0; m--) + { getu1(input); posf++; } + + m=getu4(input); + n=getu4(input); + o=getu4(input); + posf = posf + 12; + + printf(mnem[k]); + printTab(1); + printHex4(m+nested[posn]); + printf(","); + printHex4(n); + printf(","); + printHex2(o); + posn++; + nested[posn]=n; + + /*Print jump-offsets.*/ + while (nested[posn] <= o) + { + m=getu4(input); + printf("\n"); + printTab(6); + posf = posf + 4; + printHex4(m+nested[posn-1]); + nested[posn]++; + } + + posn--; + printf("\n"); + break; + + case 8: /*Special case for lookupswitch. */ + + /*Read and ignore padded bytes.*/ + for (m=(nested[posn]&3)^3; m>0; m--) + { getu1(input); posf++; } + + m=getu4(input); + n=getu4(input); + posf = posf + 8; + printf(mnem[k]); + printTab(1); + printHex4(m+nested[posn]); + printf(","); + printHex4(n); + printf("\n"); + printTab(6); + posn++; + nested[posn]=0; + + /*Print out offset pairs.*/ + while (nested[posn] < n) + { + m=getu4(input); + o=getu4(input); + posf = posf + 8; + printHex4(m); + printf(" : "); + printHex4(o+nested[posn-1]); + nested[posn]++; + printf("\n"); + printTab(6); + } + + posn--; + printf("\n"); + break; + + case 9: + m=getu2(input); + n=getu1(input); + o=getu1(input); + posf = posf + 4; + printf(mnem[k]); + printf(" "); + printHex2(m); + printf(","); + printHex1(n); + printf(","); + printHex1(o); + break; + + case 10: + m=getu1(input); + posf++; + printf(mnem[k]); + printf(" "); + + switch (m) + { + case 4: printf("T_BOOLEAN"); break; + case 5: printf("T_CHAR"); break; + case 6: printf("T_FLOAT"); break; + case 7: printf("T_DOUBLE"); break; + case 8: printf("T_BYTE"); break; + case 9: printf("T_SHORT"); break; + case 10: printf("T_INT"); break; + case 11: printf("T_LONG"); break; + default: printf("\nError"); + } + break; + + case 11: + m=getu1(input); + n=getu1(input); + posf = posf + 2; + if ( n<0x15 || (n>0x19 && n<0x36) || (n>0x3a && n!=0x84)) printf("\nError"); + + m=(m<<8)+getu1(input); + posf++; + printf(mnem[n]); + printf(" "); + printHex2(m); + break; + + default: printf("\nError"); + } + + } + + if (posf!=j) printf("\nError"); + posn--; + printf("\n"); + +} + + +/******************************************************************** +* +* function: int whichAttribute(char *constant_pool_name) +* +* purpose: Returns the attribute of the passed string. +* +* +*********************************************************************/ + +int whichAttribute(char *constant_pool_name) +{ + if ( strcmp("SourceFile",constant_pool_name) == 0 ) return SOURCE_FILE; + if ( strcmp("ConstantValue",constant_pool_name) == 0 ) return CONSTANT_VALUE; + if ( strcmp("Code",constant_pool_name) == 0 ) return CODE; + if ( strcmp("Exceptions",constant_pool_name) == 0 ) return EXCEPTIONS; + if ( strcmp("LineNumberTable",constant_pool_name) == 0 ) return LINENUMBERTABLE; + if ( strcmp("LocalVariableTable",constant_pool_name) == 0 ) return LOCALVARIABLETABLE; + +} + +/******************************************************************** +* +* function: void getAttributes(int attr, FILE *input, struct linked_list *first_ptr) +* +* purpose: Prints out the attribute info. +* +* +*********************************************************************/ + +void getAttributes(int attr, FILE *input, struct linked_list *first_ptr) +{ + /*Local variables.*/ + int length = 0; + int k = 0; + int count = 0; + int index = 0; + + /*Print out the appropriate attribute. Refer to the JVM Spec for more info.*/ + switch (attr) + { + case SOURCE_FILE: + printf("SourceFile"); + printf(" length "); + printDec4(getu4(input)); + printf(" index "); + printDec2(getu2(input)); + break; + + case CONSTANT_VALUE: + printf("ConstantValue"); + printf(" length "); + printDec4(getu4(input)); + printf(" index "); + printDec2(getu2(input)); + break; + + case CODE: + printf("Code"); + + printf("\n"); + printTab(2); + printf("length"); + printTab(2); + printDec4(getu4(input)); + + printf("\n"); + printTab(2); + printf("max_stack"); + printTab(1); + printDec2(getu2(input)); + + printf("\n"); + printTab(2); + printf("max_local"); + printTab(1); + printDec2(getu2(input)); + + printf("\n"); + printTab(2); + printf("length"); + printTab(2); + length = getu4(input); + printDec4(length); + + /*Print out the bytecodes.*/ + printf("\n\t\tbytecode"); + getBytecode(length,input); + + printf("\n"); + printTab(2); + printf("exceptions"); + length = getu2(input); + printTab(1); + printDec2(length); + for ( k=0; k < length; k++ ) + { + printf("\n"); + printTab(4); + printf("exception %i",k); + printf("\n"); + printTab(4); + printf("start_pc: "); + printDec2(getu2(input)); + printf("end_pc: "); + printDec2(getu2(input)); + printf("handler_pc: "); + printDec2(getu2(input)); + printf("catch_type: "); + printDec2(getu2(input)); + } + + printf("\n"); + printTab(2); + printf("attributes"); + printTab(1); + count = getu2(input); + printDec2(count); + for ( k=0; k +#include + +/*Temp strings.*/ +char tempString[255]; +char access_flags_string[50]; + +/*Define Constant pool tags.*/ +#define CONSTANT_Class 7 +#define CONSTANT_Fieldref 9 +#define CONSTANT_Methodref 10 +#define CONSTANT_InterfaceMethodref 11 +#define CONSTANT_String 8 +#define CONSTANT_Integer 3 +#define CONSTANT_Float 4 +#define CONSTANT_Long 5 +#define CONSTANT_Double 6 +#define CONSTANT_NameAndType 12 +#define CONSTANT_Utf8 1 + +/*Define access_flags.*/ +#define ACC_PUBLIC 0x0001 +#define ACC_PRIVATE 0x0002 +#define ACC_PROTECTED 0x0004 +#define ACC_STATIC 0x0008 +#define ACC_FINAL 0x0010 +#define ACC_SYNCHRONIZED 0x0020 +#define ACC_VOLATILE 0x0040 +#define ACC_TRANSIENT 0x0080 +#define ACC_NATIVE 0x0100 +#define ACC_INTERFACE 0x0200 +#define ACC_ABSTRACT 0x0400 + +/*Define attribute names.*/ +#define SOURCE_FILE 1 +#define CONSTANT_VALUE 2 +#define CODE 3 +#define EXCEPTIONS 4 +#define LINENUMBERTABLE 5 +#define LOCALVARIABLETABLE 6 + + +/*Opcode table*/ + static char *(mnem[]) = { +/*00 */ "nop", +/*01 */ "aconst_null", +/*02 */ "iconst_ml", +/*03 */ "iconst_0", +/*04 */ "iconst_1", +/*05 */ "iconst_2", +/*06 */ "iconst_3", +/*07 */ "iconst_4", +/*08 */ "iconst_5", +/*09 */ "lconst_0", +/*0a */ "lconst_1", +/*0b */ "fconst_0", +/*0c */ "fconst_1", +/*0d */ "fconst_2", +/*0e */ "dconst_0", +/*0f */ "dconst_1", +/*10 xx */ "bipush ", +/*11 xxxx */ "sipush ", +/*12 xx */ "ldc1 ", +/*13 xxxx */ "ldc2 ", +/*14 xxxx */ "ldc2w ", +/*15 xx */ "iload ", +/*16 xx */ "lload ", +/*17 xx */ "fload ", +/*18 xx */ "dload ", +/*19 xx */ "aload ", +/*1a */ "iload_0", +/*1b */ "iload_1", +/*1c */ "iload_2", +/*1d */ "iload_3", +/*1e */ "lload_0", +/*1f */ "lload_1", +/*20 */ "lload_2", +/*21 */ "lload_3", +/*22 */ "fload_0", +/*23 */ "fload_1", +/*24 */ "fload_2", +/*25 */ "fload_3", +/*26 */ "dload_0", +/*27 */ "dload_1", +/*28 */ "dload_2", +/*29 */ "dload_3", +/*2a */ "aload_0", +/*2b */ "aload_1", +/*2c */ "aload_2", +/*2d */ "aload_3", +/*2e */ "iaload", +/*2f */ "laload", +/*30 */ "faload", +/*31 */ "daload", +/*32 */ "aaload", +/*33 */ "baload", +/*34 */ "caload", +/*35 */ "saload", +/*36 xx */ "istore ", +/*37 xx */ "lstore ", +/*38 xx */ "fstore ", +/*39 xx */ "dstore ", +/*3a xx */ "astore ", +/*3b */ "istore_0", +/*3c */ "istore_1", +/*3d */ "istore_2", +/*3e */ "istore_3", +/*3f */ "lstore_0", +/*40 */ "lstore_1", +/*41 */ "lstore_2", +/*42 */ "lstore_3", +/*43 */ "fstore_0", +/*44 */ "fstore_1", +/*45 */ "fstore_2", +/*46 */ "fstore_3", +/*47 */ "dstore_0", +/*48 */ "dstore_1", +/*49 */ "dstore_2", +/*4a */ "dstore_3", +/*4b */ "pstore_0", +/*4c */ "pstore_1", +/*4d */ "pstore_2", +/*4e */ "pstore_3", +/*4f */ "iastore", +/*50 */ "lastore", +/*51 */ "fastore", +/*52 */ "dastore", +/*53 */ "aastore", +/*54 */ "bastore", +/*55 */ "castore", +/*56 */ "sastore", +/*57 */ "pop", +/*58 */ "pop2", +/*59 */ "dup", +/*5a */ "dup_x1", +/*5b */ "dup_x2", +/*5c */ "dup2", +/*5d */ "dup2_x1", +/*5e */ "dup2_x2", +/*5f */ "swap", +/*60 */ "iadd", +/*61 */ "ladd", +/*62 */ "fadd", +/*63 */ "dadd", +/*64 */ "isub", +/*65 */ "lsub", +/*66 */ "fsub", +/*67 */ "dsub", +/*68 */ "imul", +/*69 */ "lmul", +/*6a */ "fmul", +/*6b */ "dmul", +/*6c */ "idiv", +/*6d */ "ldiv", +/*6e */ "fdiv", +/*6f */ "ddiv", +/*70 */ "irem", +/*71 */ "lrem", +/*72 */ "frem", +/*73 */ "drem", +/*74 */ "ineg", +/*75 */ "lneg", +/*76 */ "fneg", +/*77 */ "dneg", +/*78 */ "ishl", +/*79 */ "lshl", +/*7a */ "ishr", +/*7b */ "lshr", +/*7c */ "iushr", +/*7d */ "lushr", +/*7e */ "iand", +/*7f */ "land", +/*80 */ "ior", +/*81 */ "lor", +/*82 */ "ixor", +/*83 */ "lxor", +/*84 xx yy */ "iinc ", +/*85 */ "i2l", +/*86 */ "i2f", +/*87 */ "i2d", +/*88 */ "l2i", +/*89 */ "l2f", +/*8a */ "l2d", +/*8b */ "f2i", +/*8c */ "f2l", +/*8d */ "f2d", +/*8e */ "d2i", +/*8f */ "d2l", +/*90 */ "d2f", +/*91 */ "int2byte", +/*92 */ "int2char", +/*93 */ "int2short", +/*94 */ "lcmp", +/*95 */ "fcmpl", +/*96 */ "fcmpg", +/*97 */ "dcmpl", +/*98 */ "dcmpg", +/*99 xxxx */ "ifeq ", +/*9a xxxx */ "ifne ", +/*9b xxxx */ "iflt ", +/*9c xxxx */ "ifge ", +/*9d xxxx */ "ifgt ", +/*9e xxxx */ "ifle ", +/*9f xxxx */ "if_icmpeq ", +/*a0 xxxx */ "if_icmpne ", +/*a1 xxxx */ "if_icmplt ", +/*a2 xxxx */ "if_icmpge ", +/*a3 xxxx */ "if_icmpgt ", +/*a4 xxxx */ "if_icmple ", +/*a5 xxxx */ "if_acmpeq ", +/*a6 xxxx */ "if_acmpne ", +/*a7 xxxx */ "goto ", +/*a8 xxxx */ "jsr ", +/*a9 xx */ "ret ", +/*aa [..] */ "tableswitch ", +/*ab [..] */ "lookupswitch ", +/*ac */ "ireturn", +/*ad */ "lreturn", +/*ae */ "freturn", +/*af */ "dreturn", +/*b0 */ "areturn", +/*b1 */ "return", +/*b2 xxxx */ "getstatic ", +/*b3 xxxx */ "putstatic ", +/*b4 xxxx */ "getfield ", +/*b5 xxxx */ "putfield ", +/*b6 xxxx */ "invokevirtual ", +/*b7 xxxx */ "invokenonvirtual", +/*b8 xxxx */ "invokestatic ", +/*b9 xxxx nn (nn) */ "invokeinterface ", +/*ba */ "ungueltiger opcode", +/*bb xxxx */ "new ", +/*bc */ "newarray", +/* +bc 04 "newarray T_BOOLEAN", +bc 05 "newarray T_CHAR", +bc 06 "newarray T_FLOAT", +bc 07 "newarray T_DOUBLE", +bc 08 "newarray T_BYTE", +bc 09 "newarray T_SHORT", +bc 0a "newarray T_INT", +bc 0b "newarray T_LONG", +*/ +/*bd xxxx */ "anewarray ", +/*be */ "arraylength", +/*bf */ "athrow", +/*c0 xxxx */ "checkcast ", +/*c1 xxxx */ "instanceof ", +/*c2 */ "monitorenter", +/*c3 */ "monitorexit", +/*c4 xx yy xx */ "", +/* +c4 xx 15 xx "iload", +c4 xx 16 xx "lload", +c4 xx 17 xx "fload", +c4 xx 18 xx "dload", +c4 xx 19 xx "aload", +c4 xx 36 xx "istore", +c4 xx 37 xx "lstore", +c4 xx 38 xx "fstore", +c4 xx 39 xx "dstore", +c4 xx 3a xx "astore", +c4 xx 84 xx yy "iinc", +*/ +/*c5 xxxx yy */ "multianewarray ", +/*c6 xxxx */ "ifnull ", +/*c7 xxxx */ "ifnonnull ", +/*c8 xxxxxxxx */ "goto_w ", +/*c9 xxxxxxxx */ "jsr_w ", +/*ca */ "breakpoint", +/*cb */ "ungueltiger opcode", +/*cc */ "ungueltiger opcode", +/*cd */ "ungueltiger opcode", +/*ce */ "ungueltiger opcode", +/*cf */ "ungueltiger opcode", +/*d0 */ "ungueltiger opcode", +/*d1 xxxx */ "ret_w ", +/*d2 */ "ungueltiger opcode" +}; + + + +/******************************************************************** +* +* function: int getu1(FILE *classfile) +* +* purpose: Reads one byte from the file and returns an integer +* value of the byte. +* +*********************************************************************/ + +int getu1(FILE *classfile) +{ + int i; + if ( (i=getc(classfile)) == EOF ) printf("\nEnd of file reached."); + return i; +} + +/******************************************************************** +* +* function: int getu2(FILE *classfile) +* +* purpose: Reads two bytes from the file and returns the integer +* value of the two bytes. +* +*********************************************************************/ + +int getu2(FILE *classfile) +{ + int i; + i = getu1(classfile); + return ( (i<<8) + getu1(classfile)); +} + +/******************************************************************** +* +* function: int getu4(FILE *classfile) +* +* purpose: Reads four bytes from the file and returns the integer +* value of the four bytes. +* +*********************************************************************/ + +int getu4(FILE *classfile) +{ + int i; + i = getu2(classfile); + return( (i<<16) + getu2(classfile)); +} + +/******************************************************************** +* +* function: char utf8Tochar(int j) +* +* purpose: Returns the char value of the given int. +* +* +*********************************************************************/ + +char utf8Tochar(int j) +{ + char c; + + c = j; + + return c; +} + +/******************************************************************** +* +* function: char* getUtf8(FILE *input) +* +* purpose: Gets the Utf8 data from the file and returns the +* string value. +* +*********************************************************************/ + +char* getUtf8(FILE *input) +{ + /*Local variables.*/ + int length=0; + int i = 0; + + /*Get the length of the string.*/ + length = getu2(input); + + /*Read the string from the file.*/ + for ( i=0; igetConstantPool(); + 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; +} diff --git a/ef/Utilities/qa/constantpool/AttributeHandlers.h b/ef/Utilities/qa/constantpool/AttributeHandlers.h new file mode 100644 index 000000000000..4b2d7628dfa1 --- /dev/null +++ b/ef/Utilities/qa/constantpool/AttributeHandlers.h @@ -0,0 +1,178 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#ifndef _CR_ATTRIBUTEHANDLERS_H_ +#define _CR_ATTRIBUTEHANDLERS_H_ + +#include "ClassReader.h" +#include "FileReader.h" + + +/* An Attribute handler is responsible for parsing and allocating + * a particular attribute + */ +class AttributeHandler { +public: + AttributeHandler(Pool &p, FileReader *_reader, ClassFileReader *_cfr, + const char *_name); + + /* The handle() method determines whether or not it can handle an + * attribute whose name is _name. If it can, then it further parses the + * file and returns a pointer to the attribute. Else, returns NULL + */ + virtual AttributeInfoItem *handle(const char *_name, uint16 nindex, + CrError *status) = 0; + + /* Get name of attribute that this handler will handle */ + const char *getName() { + return name; + } + + FileReader *getReader() { + return reader; + } + + ClassFileReader *getClassReader() { + return cfr; + } + +protected: + Pool &p; + const char *name; + FileReader *reader; + ClassFileReader *cfr; + ConstantPoolItem **constantPool; + int constantPoolCount; + + int validateNameAndLength(const char *_name, uint32 *length, + CrError *status); + + bool invalidIndex(int index) { + return index < 1 || index >= constantPoolCount; + } + + bool invalidAttribute(int index, int type) { + return (invalidIndex(index) || constantPool[index]->getType() != type); + } +}; + +/* The following classes handle various attributes that we are + * currently interested in. + */ +class AttributeHandlerSourceFile : public AttributeHandler { +public: + AttributeHandlerSourceFile(Pool &pool, FileReader *_reader, + ClassFileReader *_cfr): + AttributeHandler(pool, _reader, _cfr, "SourceFile") { + + } + + virtual AttributeInfoItem *handle(const char *_name, uint16 nindex, CrError *status); + +private: +}; + + +class AttributeHandlerConstantValue : public AttributeHandler { +public: + AttributeHandlerConstantValue(Pool &pool, + FileReader *_reader, ClassFileReader *_cfr): + AttributeHandler(pool, _reader, _cfr, "ConstantValue") { + + } + + virtual AttributeInfoItem *handle(const char *_name, uint16 nindex, CrError *status); + +private: +}; + + +class AttributeHandlerCode : public AttributeHandler { +public: + AttributeHandlerCode(Pool &pool, + FileReader *_reader, ClassFileReader *_cfr): + AttributeHandler(pool, _reader, _cfr, "Code") { + + } + + virtual AttributeInfoItem *handle(const char *_name, uint16 nindex, CrError *status); + +private: +}; + + +class AttributeHandlerLineNumberTable : public AttributeHandler { +public: + AttributeHandlerLineNumberTable(Pool &pool, + FileReader *_reader, + ClassFileReader *_cfr): + AttributeHandler(pool, _reader, _cfr, "LineNumberTable") { + + } + + virtual AttributeInfoItem *handle(const char *_name, uint16 nindex, CrError *status); + +private: + +}; + + +class AttributeHandlerLocalVariableTable : public AttributeHandler { +public: + AttributeHandlerLocalVariableTable(Pool &pool, FileReader *_reader, + ClassFileReader *_cfr): + AttributeHandler(pool, _reader, _cfr, "LocalVariableTable") { + + } + + virtual AttributeInfoItem *handle(const char *_name, uint16 nindex, CrError *status); + +private: + +}; + + +class AttributeHandlerExceptions : public AttributeHandler { +public: + AttributeHandlerExceptions(Pool &pool, FileReader *_reader, + ClassFileReader *_cfr): + AttributeHandler(pool, _reader, _cfr, "Exceptions") { + + } + + virtual AttributeInfoItem *handle(const char *_name, uint16 nindex, CrError *status); + +private: + +}; + +/* This handles attributes that we don't know (or care) about */ +class AttributeHandlerDummy : public AttributeHandler { +public: + AttributeHandlerDummy(Pool &pool, + FileReader *_reader, ClassFileReader *_cfr): + AttributeHandler(pool, _reader, _cfr, 0) { + + } + + virtual AttributeInfoItem *handle(const char *_name, uint16 nindex, CrError *status); + +private: +}; + +#endif /* _CR_ATTRIBUTEHANDLERS_H_ */ diff --git a/ef/Utilities/qa/constantpool/Attributes.h b/ef/Utilities/qa/constantpool/Attributes.h new file mode 100644 index 000000000000..d88e2be99c8b --- /dev/null +++ b/ef/Utilities/qa/constantpool/Attributes.h @@ -0,0 +1,352 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#ifndef _CR_ATTRIBUTES_H_ +#define _CR_ATTRIBUTES_H_ + +#include "ConstantPool.h" +#include "DoublyLinkedList.h" + +/* Attribute tags for handlers that we know (care) about */ +#define CR_ATTRIBUTE_SOURCEFILE 1 +#define CR_ATTRIBUTE_CONSTANTVALUE 2 +#define CR_ATTRIBUTE_LINENUMBERTABLE 3 +#define CR_ATTRIBUTE_LOCALVARIABLETABLE 4 +#define CR_ATTRIBUTE_CODE 5 +#define CR_ATTRIBUTE_EXCEPTIONS 6 + + +class AttributeInfoItem : public DoublyLinkedEntry { +public: + AttributeInfoItem(Pool &pool, + const char *nameInfo, uint32 _code, uint32 _length, + uint16 _nameIndex) : + p(pool), name(nameInfo), length(_length), code(_code), + nameIndex(_nameIndex) { } + + uint32 getLength() const { + return length; + } + + const char *getName() const { + return name; + } + + uint32 getCode() const { + return code; + } + + uint16 getNameIndex() const { + return nameIndex; + } +#ifdef DEBUG + virtual void dump(int /*nIndents*/) { + + } +#endif + +protected: + Pool &p; + +private: + const char *name; + uint32 length; + uint32 code; + uint16 nameIndex; +}; + + +class AttributeSourceFile : public AttributeInfoItem { + friend class ClassFileReader; +public: + AttributeSourceFile(Pool &pool, ConstantUtf8 *utf8, uint16 i, uint16 nindex) : + AttributeInfoItem(pool, "SourceFile", CR_ATTRIBUTE_SOURCEFILE, 2, nindex), index(i) { + srcName = utf8; + } + + ConstantUtf8 *getSrcName() const { + return srcName; + } + + uint16 getIndex() const { + return index; + } + +#ifdef DEBUG + virtual void dump(int nIndents); +#endif + +private: + ConstantUtf8 *srcName; + uint16 index; +}; + + +class AttributeConstantValue : public AttributeInfoItem { +public: + AttributeConstantValue(Pool &pool, ConstantPoolItem *val, uint16 i, uint16 nindex) : + AttributeInfoItem(pool, "ConstantValue", CR_ATTRIBUTE_CONSTANTVALUE, 2, nindex), + index(i) { + value = val; + } + + ConstantPoolItem *getValue() const { + return value; + } + + uint16 getIndex() const { + return index; + } + +#ifdef DEBUG + virtual void dump(int nIndents); +#endif + +private: + ConstantPoolItem *value; + uint16 index; +}; + + +class ExceptionItem { +public: + ExceptionItem(uint16 _startPc, uint16 _endPc, + uint16 _handlerPc, ConstantClass *_catcher, uint16 cIndex); + + uint16 getStartPc() const { + return startPc; + } + + uint16 getEndPc() const { + return endPc; + } + + uint16 getHandlerPc() const { + return handlerPc; + } + + ConstantClass *getCatcher() const { + return catcher; + } + + uint16 getCatcherIndex() const { + return catcherIndex; + } + +#ifdef DEBUG + void dump(int nIndents); +#endif + +private: + uint16 startPc, endPc, handlerPc; + uint16 catcherIndex; + ConstantClass *catcher; +}; + + +class AttributeCode : public AttributeInfoItem { + +public: + AttributeCode(Pool &pool, uint16 _length, + uint16 _maxStack, uint16 _maxLocals, uint32 _codeLength, + uint16 nindex, + CrError *status); + + int setNumExceptions(int _numExceptions); + + int setNumAttributes(int _numAttributes); + + /* Get the size of the code */ + uint32 getCodeLength() const { + return codeLength; + } + + uint32 getMaxStack() const { + return maxStack; + } + + uint32 getMaxLocals() const { + return maxLocals; + } + + uint32 getNumExceptions() const { + return numExceptions; + } + + ExceptionItem **getExceptions() const { + return exceptions; + } + + uint32 getNumAttributes() const { + return numAttributes; + } + + AttributeInfoItem **getAttributes() const { + return attributes; + } + + const char *getCode() const { + return (const char *) code; + } + +#ifdef DEBUG + virtual void dump(int nIndents); +#endif + +private: + uint32 maxStack, maxLocals, codeLength, numExceptions; + char *code; + ExceptionItem **exceptions; + uint16 numAttributes; + AttributeInfoItem **attributes; +}; + + +class AttributeExceptions : public AttributeInfoItem { +friend class AttributeHandlerExceptions; +public: + AttributeExceptions(Pool &pool, uint32 _length, uint16 nindex) : + AttributeInfoItem(pool, "Exceptions", CR_ATTRIBUTE_EXCEPTIONS, _length, nindex) { + numExceptions = 0, exceptions = 0; + } + + uint16 getNumExceptions() const { + return numExceptions; + } + + ConstantClass **getExceptions() const { + return exceptions; + } + + int setNumExceptions(uint16 n); + + uint16 *getExcIndices() const { + return excIndices; + } + +#ifdef DEBUG + virtual void dump(int nIndents); +#endif + +private: + uint16 numExceptions; + ConstantClass **exceptions; + uint16 *excIndices; +}; + +typedef struct { + uint16 startPc; + uint16 lineNumber; + +#ifdef DEBUG + void dump(int nIndents) { + print(nIndents, "startPc %d lineNumber %d", startPc, lineNumber); + } +#endif + +} LineNumberEntry; + + +class AttributeLineNumberTable : public AttributeInfoItem { +public: + AttributeLineNumberTable(Pool &pool, uint32 _length, uint16 nindex) : + AttributeInfoItem(pool, "LineNumberTable", CR_ATTRIBUTE_LINENUMBERTABLE, + _length, nindex) { + numEntries = 0, entries = 0; + } + + int setNumEntries(uint16 n); + + uint16 getNumEntries() { + return numEntries; + } + + LineNumberEntry *getEntries() { + return entries; + } + + /* returns the Pc value corresponding to lineNumber, -1 if not found */ + int getPc(uint16 lineNumber); + +#ifdef DEBUG + virtual void dump(int nIndents); +#endif + +private: + uint16 numEntries; + LineNumberEntry *entries; +}; + + +typedef struct { + uint16 startPc; + uint16 length; + ConstantUtf8 *name; + uint16 nameIndex; + ConstantUtf8 *descriptor; + uint16 descIndex; + uint16 index; + +#ifdef DEBUG + void dump(int nIndents) { + print(nIndents, + "startPc %d length %d name %s desc %s", startPc, length, + name->getUtfString(), descriptor->getUtfString()); + } +#endif +} LocalVariableEntry; + + +class AttributeLocalVariableTable : public AttributeInfoItem { +friend class ClassFileReader; + +public: + AttributeLocalVariableTable(Pool &pool, uint32 _length, uint16 nindex) : + AttributeInfoItem(pool, "LocalVariableTable", + CR_ATTRIBUTE_LOCALVARIABLETABLE, + _length, nindex) { + entries = 0; + } + + + int setNumEntries(uint16 n); + + uint16 getNumEntries() { + return numEntries; + } + + LocalVariableEntry *getEntries() { + return entries; + } + + /* Not yet implemented */ + LocalVariableEntry *getEntry(const char * /*_name*/) { + return 0; + } + +#ifdef DEBUG + virtual void dump(int nIndents); +#endif + +private: + uint16 numEntries; + LocalVariableEntry *entries; +}; + + + +#endif /* _CR_ATTRIBUTES_H_ */ diff --git a/ef/Utilities/qa/constantpool/ClassGen.cpp b/ef/Utilities/qa/constantpool/ClassGen.cpp new file mode 100644 index 000000000000..d7d605dc6742 --- /dev/null +++ b/ef/Utilities/qa/constantpool/ClassGen.cpp @@ -0,0 +1,1313 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#include "ClassGen.h" + +/* getType(char *constantType) + * + * function: Compares the passed string to the list of Constant Types. + * Returns the constant type of the given string. + * + */ +int getType(char *constantType) { + + if (strcmp(constantType,"Class") == 0) return 7; + if (strcmp(constantType,"FieldRef") == 0) return 9; + if (strcmp(constantType,"MethodRef") == 0) return 10; + if (strcmp(constantType,"InterfaceMethodRef") == 0) return 11; + if (strcmp(constantType,"String") == 0) return 8; + if (strcmp(constantType,"Integer") == 0) return 3; + if (strcmp(constantType,"Float") == 0) return 4; + if (strcmp(constantType,"Long") == 0) return 5; + if (strcmp(constantType,"Double") == 0) return 6; + if (strcmp(constantType,"NameAndType") == 0) return 12; + if (strcmp(constantType,"Utf8") == 0) return 1; + + //The type is unknown. Return 0 to cause an error. + return 0; + +} + +/* getStringLength(char *line) + * + * function: Finds the length of the passed string array. + * Returns the length of the string from index 0 to '\n'. + * + */ +int getStringLength(char *line) { + + int i = 0; + while (line[i] != '\0') { + i++; + }; + + return i; + +} + +/* isBlankLine(const char *line) + * + *function: Checks if the passed string is a blank line. + *Returns true/false if the string is a blank line or not. + * + */ +bool isBlankLine(const char *line) { + + for (; *line; line++) { + + if (!isspace(*line)) return false; + + } + + return true; + +} + +/* getItem(const char *line) + * + * function: Returns the appropriate classfile item. + * + */ +int getItem(const char *line) { + + if (strcmp(line,"#magic\n") == 0) return CG_MAGIC; + if (strcmp(line,"#minor_version\n") == 0) return CG_MINORVERSION; + if (strcmp(line,"#major_version\n") == 0) return CG_MAJORVERSION; + if (strcmp(line,"#constant_pool_count\n") == 0) return CG_CONSTANTPOOL; + if (strcmp(line,"#access_flags\n") == 0) return CG_ACCESSFLAGS; + if (strcmp(line,"#this_class\n") == 0) return CG_THISCLASS; + if (strcmp(line,"#super_class\n") == 0) return CG_SUPERCLASS; + if (strcmp(line,"#interfaces_count\n") == 0) return CG_INTERFACES; + if (strcmp(line,"#fields_count\n") == 0) return CG_FIELDS; + if (strcmp(line,"#methods_count\n") == 0) return CG_METHODS; + if (strcmp(line,"#attributes_count\n") == 0) return CG_ATTRIBUTES; + + return 0; + +} + +/* getAttribute(const char *line) + * + * function: Returns the appropriate attribute. + * + */ +int getAttribute(const char *line) { + + if (strcmp(line,"SourceFile") == 0) return CR_ATTRIBUTE_SOURCEFILE; + if (strcmp(line,"ConstantValue") == 0) return CR_ATTRIBUTE_CONSTANTVALUE; + if (strcmp(line,"LineNumberTable") == 0) return CR_ATTRIBUTE_LINENUMBERTABLE; + if (strcmp(line,"LocalVariableTable") == 0) return CR_ATTRIBUTE_LOCALVARIABLETABLE; + if (strcmp(line,"Code") == 0) return CR_ATTRIBUTE_CODE; + if (strcmp(line,"Exceptions") == 0) return CR_ATTRIBUTE_EXCEPTIONS; + + return 0; + +} + +/* stripLine(char* line,int size,byte c) + * + * function: Removes the specified char from the line. + * + */ +void stripLine(char* line,int size,byte c) { + + int i = 0; + int j = 0; + + while ( line[i] == c ) i++; + + for (j = 0; j < (size - i); j++) { + + line[j] = line[j+i]; + if (line[j] == '\n') break; + + } + + /* Empty the rest of the string. */ + j++; + while ( j < size ) { + + line[j] = '\0'; + j++; + + } + +} + +/* parseBytecodes(FILE *fp, FileWriter &writer) + * + *function: Parses and generates the bytecodes. + * + */ +void parseBytecodes(FILE *fp,FileWriter &writer) { + + char line[256]; + + fgets(line,sizeof(line),fp); + stripLine(line,sizeof(line),' '); + + while (strcmp(line,"#end_bytecodes\n") != 0) { + + /* Need to add code here. */ + //printf("%s\n",line); + + fgets(line,sizeof(line),fp); + stripLine(line,sizeof(line),' '); + stripLine(line,sizeof(line),'\t'); + + } + + return; + +} + +/* createConstantPool(FILE *fp, FileWriter &writer) + * + *function: Creates the constant pool. + * + */ +void createConstantPool(FILE *fp,FileWriter &writer) { + + char line[256]; + char stringTag[256]; + + /* Init string. */ + for (int m = 0; m < 256; m++) { + + line[m] = '\0'; + stringTag[m] = '\0'; + + } + + fgets(line,sizeof(line),fp); /* #begin_constant_pool */ + fgets(line,sizeof(line),fp); /* #0 Reserved */ + + fgets(line,sizeof(line),fp); + while (strcmp(line,"#end_constant_pool\n") != 0) { + + printf("string: %s", line); + + int index; + char tag; + + /* Get the index and constant tag from the string read. */ + sscanf(line,"\t#%i %s\n",&index,stringTag); + + /* Get the constant type and generate the correct info. */ + + switch(getType(stringTag)) { + + case CR_CONSTANT_UTF8: { /* Utf8 */ + + uint16 utf8Length; + char utf8[256]; + + /* Init utf8. */ + for (int i = 0; i < 256; i++) utf8[i] = '\0'; + + fgets(line,sizeof(line),fp); + stripLine(line,sizeof(line),'\t'); + sscanf(line,"%s",utf8); + + tag = 1; + utf8Length = getStringLength(utf8); + + writer.writeU1(&tag,1); + writer.writeU2(&utf8Length,1); + + printf("length: %i utf8: ",getStringLength(utf8)); + + for (int j = 0; j < getStringLength(utf8); j++) { + writer.writeU1(&utf8[j],1); + printf("%c",utf8[j]); + } + + printf("\n"); + + break; + } + + case CR_CONSTANT_INTEGER: { /* Integer */ + + int tempValue; + uint32 value; + + fgets(line,sizeof(line),fp); + sscanf(line,"\tvalue %i",&tempValue); + value = (uint32)tempValue; + + tag = 3; + + writer.writeU1(&tag,1); + writer.writeU4(&value,1); + + break; + + } + + case CR_CONSTANT_FLOAT: { /* Float */ + int s,e,m; + uint32 s32,e32,m32; + uint32 value; + + fgets(line,sizeof(line),fp); + + /* This will need to be refined later on. */ + sscanf(line,"\tvalue s %i e %i m %i",&s,&e,&m); + e32 = (uint32)e; + m32 = (uint32)m; + + tag = 4; + + /* Compute value. */ + if (s == 1) s32 = 0; + else s32 = 1; + value = (s32 << 31) | (e32 << 23) | (m32 & 0x00ffffff); + + writer.writeU1(&tag,1); + writer.writeU4(&value,1); + + break; + + } + + case CR_CONSTANT_LONG: { /* Long */ + + int tempHi,tempLo; + uint32 hi,lo; + + fgets(line,sizeof(line),fp); + + /* This will need to be refined later on. */ + sscanf(line,"\tvalue hi %i lo %i",&tempHi,&tempLo); + hi = (uint32)tempHi; + lo = (uint32)tempLo; + + tag = 5; + + writer.writeU1(&tag,1); + writer.writeU4(&hi,1); + writer.writeU4(&lo,1); + + break; + } + + case CR_CONSTANT_DOUBLE: { /* Double */ + + char data[8]; + int byte; + + /* This will need to be refined later on. */ + fscanf(fp,"\tvalue "); + for (int i = 0; i < 7; i++) { + fscanf(fp,"%x ",&byte); + data[i] = byte; + } + fscanf(fp,"%x",&byte); + data[7] = byte; + fgets(line,sizeof(line),fp); + + tag = 6; + + writer.writeU1(&tag,1); + writer.writeU1(data,8); + break; + + } + + case CR_CONSTANT_CLASS: { /* Class */ + + int tempTagInfo; + uint16 tagInfo; + + fgets(line,sizeof(line),fp); + + sscanf(line,"\tindex %i",&tempTagInfo); + tagInfo = (uint16)tempTagInfo; + + tag = 7; + + writer.writeU1(&tag,1); + writer.writeU2(&tagInfo,1); + + break; + } + + case CR_CONSTANT_STRING: { /* String */ + + int tempTagInfo; + uint16 tagInfo; + + fgets(line,sizeof(line),fp); + + sscanf(line,"\tindex %i",&tempTagInfo); + tagInfo = (uint16)tempTagInfo; + + tag = 8; + + writer.writeU1(&tag,1); + writer.writeU2(&tagInfo,1); + + break; + } + + case CR_CONSTANT_FIELDREF: { /* FieldRef */ + + int tempClassIndex, tempTypeIndex; + uint16 classIndex; + uint16 typeIndex; + + fgets(line,sizeof(line),fp); + sscanf(line,"\tclassIndex %i typeIndex %i",&tempClassIndex,&tempTypeIndex); + classIndex = (uint16)tempClassIndex; + typeIndex = (uint16)tempTypeIndex; + + tag = 9; + + writer.writeU1(&tag,1); + writer.writeU2(&classIndex,1); + writer.writeU2(&typeIndex,1); + + break; + + } + + case CR_CONSTANT_METHODREF: { /* MethodRef */ + + int tempClassIndex, tempTypeIndex; + uint16 classIndex; + uint16 typeIndex; + + fgets(line,sizeof(line),fp); + sscanf(line,"\tclassIndex %i typeIndex %i",&tempClassIndex,&tempTypeIndex); + classIndex = (uint16)tempClassIndex; + typeIndex = (uint16)tempTypeIndex; + + tag = 10; + + writer.writeU1(&tag,1); + writer.writeU2(&classIndex,1); + writer.writeU2(&typeIndex,1); + + break; + + } + + case CR_CONSTANT_INTERFACEMETHODREF: { /* InterfaceMethodRef */ + + int tempClassIndex, tempTypeIndex; + uint16 classIndex; + uint16 typeIndex; + + fgets(line,sizeof(line),fp); + sscanf(line,"\tclassIndex %i typeIndex %i",&tempClassIndex,&tempTypeIndex); + classIndex = (uint16)tempClassIndex; + typeIndex = (uint16)tempTypeIndex; + + tag = 11; + + printf("InterfaceMethodRef classIndex: %i typeIndex: %i\n",classIndex,typeIndex); + + writer.writeU1(&tag,1); + writer.writeU2(&classIndex,1); + writer.writeU2(&typeIndex,1); + + break; + + } + + case CR_CONSTANT_NAMEANDTYPE: { /* NameAndType */ + + int tempNameIndex, tempDescIndex; + uint16 nameIndex; + uint16 descIndex; + + fgets(line,sizeof(line),fp); + sscanf(line,"\tnameIndex %i descIndex %i",&tempNameIndex,&tempDescIndex); + nameIndex = (uint16)tempNameIndex; + descIndex = (uint16)tempDescIndex; + + tag = 12; + + writer.writeU1(&tag,1); + writer.writeU2(&nameIndex,1); + writer.writeU2(&descIndex,1); + + break; + + } + + default: { + + printf("Error: problem with constantpool\n"); + printf("%s",line); + return; + + } + + } + + /* Read next line. */ + fgets(line,sizeof(line),fp); + + printf("next line: %s\n",line); + + } + + printf("Done with constant pool.\n"); + + return; + +} + +/* createInterfaces(FILE *fp, FileWriter &writer) + * + *function: Creates the interfaces structure. + * + */ +void createInterfaces(FILE *fp,FileWriter &writer) { + + char line[256]; + int tempIndex; + uint16 index; + + fgets(line,sizeof(line),fp); /* #begin_interfaces */ + fgets(line,sizeof(line),fp); /* # */ + + while (strcmp(line,"#end_interfaces\n") != 0) { + + fgets(line,sizeof(line),fp); + sscanf(line,"\tindex %i\n",&tempIndex); + index = (uint16)tempIndex; + + writer.writeU2(&index, 1); + + /* Read next line. */ + fgets(line,sizeof(line),fp); + + } + +} + +/* createFields(FILE *fp, FileWriter &writer, ClassFileReader &reader) + * + *function: Creates the fields structure. + * + */ +void createFields(FILE *fp,FileWriter &writer,ClassFileReader &reader) { + + char line[256]; + uint16 accessFlags; + uint16 nameIndex; + uint16 descIndex; + uint16 attrCount; + int tempFlags, tempNameIndex, tempDescIndex, tempCount; + + fgets(line,sizeof(line),fp); /* #begin_fields */ + fgets(line,sizeof(line),fp); /* # */ + + while (strcmp(line,"#end_fields\n") != 0) { + + /* Access flags */ + fgets(line,sizeof(line),fp); + sscanf(line,"\taccess_flags %x\n",&tempFlags); + accessFlags = (uint16)tempFlags; + writer.writeU2(&accessFlags,1); + + /* Name/Descriptor index */ + fgets(line,sizeof(line),fp); + sscanf(line,"\tnameIndex %i descIndex %i\n",&tempNameIndex,&tempDescIndex); + nameIndex = (uint16)tempNameIndex; + descIndex = (uint16)tempDescIndex; + writer.writeU2(&nameIndex,1); + writer.writeU2(&descIndex,1); + + /* Attributes count */ + fgets(line,sizeof(line),fp); + sscanf(line,"\tattributes_count %i\n",&tempCount); + attrCount = (uint16)tempCount; + writer.writeU2(&attrCount,1); + + /* Attributes structure */ + if ( tempCount > 0 ) { + + char attribute[256]; + int attrIndex; + + /* Init attribute. */ + for (int i = 0; i < 256; i++) attribute[i] = '\0'; + + fgets(line,sizeof(line),fp); /* #begin_attributes */ + fgets(line,sizeof(line),fp); /* # Attribute */ + + while (strcmp(line,"\t#end_attributes\n") != 0) { + + /* Get the attribute string. */ + sscanf(line,"\t\t#%i %s\n",&attrIndex,attribute); + + createAttributes(fp,writer,reader,getAttribute(attribute)); + + /* Read the next line. */ + fgets(line,sizeof(line),fp); + + } + + } + + fgets(line,sizeof(line),fp); + + } + +} + +/* createMethods(FILE *fp, FileWriter &writer,ClassFileReader &reader) + * + *function: Creates the methods structure. + * + */ +void createMethods(FILE *fp,FileWriter &writer,ClassFileReader &reader) { + + char line[256]; + uint16 accessFlags; + uint16 nameIndex; + uint16 descIndex; + uint16 attrCount; + int tempFlags, tempNameIndex, tempDescIndex, tempCount; + + fgets(line,sizeof(line),fp); /* #begin_methods */ + fgets(line,sizeof(line),fp); /* # */ + + while (strcmp(line,"#end_methods\n") != 0) { + + /* Access flags */ + fgets(line,sizeof(line),fp); + sscanf(line,"\taccess_flags %i\n",&tempFlags); + accessFlags = (uint16)tempFlags; + writer.writeU2(&accessFlags,1); + + /* Name/Descriptor index */ + fgets(line,sizeof(line),fp); + sscanf(line,"\tnameIndex %i descIndex %i\n",&tempNameIndex,&tempDescIndex); + nameIndex = (uint16)tempNameIndex; + descIndex = (uint16)tempDescIndex; + writer.writeU2(&nameIndex,1); + writer.writeU2(&descIndex,1); + + /* Attributes count */ + fgets(line,sizeof(line),fp); + sscanf(line,"\tattributes_count %i\n",&tempCount); + attrCount = (uint16)tempCount; + writer.writeU2(&attrCount,1); + + /* Attributes structure */ + if (tempCount > 0) { + + char attribute[256]; + int attrIndex; + + /* Init attribute. */ + for (int i = 0; i < 256; i++) attribute[i] = '\0'; + + fgets(line,sizeof(line),fp); /* #begin_attributes */ + fgets(line,sizeof(line),fp); /* # Attribute */ + + while (strcmp(line,"\t#end_attributes\n") != 0) { + + /* Get the attribute string. */ + sscanf(line,"\t\t#%i %s\n",&attrIndex,attribute); + + createAttributes(fp,writer,reader,getAttribute(attribute)); + + /* Read the next line. */ + fgets(line,sizeof(line),fp); + + } + + } + + /* Read next line. */ + fgets(line,sizeof(line),fp); + + } + +} + +/* createAttributes(FILE *fp, FileWriter &writer,ClassFileReader &reader,int attribute) + * + *function: Creates the attribute structure. + * + */ +void createAttributes(FILE *fp,FileWriter &writer,ClassFileReader &reader,int attribute) { + + char line[256]; + + /* Init attribute. */ + for (int i = 0; i < 256; i++) line[i] = '\0'; + + /* Generate the correct attribute. */ + switch(attribute) { + + case CR_ATTRIBUTE_SOURCEFILE: { /* SourceFile */ + + uint16 nameIndex; + uint32 length; + uint16 index; + int tempNameIndex, tempLength, tempIndex; + + fgets(line,sizeof(line),fp); /* nameIndex */ + stripLine(line,sizeof(line),'\t'); + sscanf(line,"nameIndex %i\n",&tempNameIndex); + nameIndex = (uint16)tempNameIndex; + writer.writeU2(&nameIndex,1); + + fgets(line,sizeof(line),fp); /* length */ + stripLine(line,sizeof(line),'\t'); + sscanf(line,"length %i\n",&tempLength); + length = (uint16)tempLength; + writer.writeU4(&length,1); + + fgets(line,sizeof(line),fp); /* index */ + stripLine(line,sizeof(line),'\t'); + sscanf(line,"index %i\n",&tempIndex); + index = (uint16)tempIndex; + writer.writeU2(&index,1); + + break; + + } + + case CR_ATTRIBUTE_CONSTANTVALUE: { /* Constant Value */ + + uint16 nameIndex; + uint32 length; + uint16 index; + int tempNameIndex, tempLength, tempIndex; + + fgets(line,sizeof(line),fp); /* nameIndex */ + stripLine(line,sizeof(line),'\t'); + sscanf(line,"nameIndex %i\n",&tempNameIndex); + nameIndex = (uint16)tempNameIndex; + writer.writeU2(&nameIndex,1); + + fgets(line,sizeof(line),fp); /* length */ + stripLine(line,sizeof(line),'\t'); + sscanf(line,"length %i\n",&tempLength); + length = (uint16)tempLength; + writer.writeU4(&length,1); + + fgets(line,sizeof(line),fp); /* index */ + stripLine(line,sizeof(line),'\t'); + sscanf(line,"index %i\n",&tempIndex); + index = (uint16)tempIndex; + writer.writeU2(&index,1); + + break; + + } + + case CR_ATTRIBUTE_LINENUMBERTABLE: { /* LineNumberTable Value */ + + uint16 nameIndex; + uint32 length; + uint16 lineNoTableLength; + int tempNameIndex, tempLength, tempCount; + + fgets(line,sizeof(line),fp); /* nameIndex */ + stripLine(line,sizeof(line),'\t'); + sscanf(line,"nameIndex %i\n",&tempNameIndex); + nameIndex = (uint16)tempNameIndex; + writer.writeU2(&nameIndex,1); + + fgets(line,sizeof(line),fp); /* length */ + stripLine(line,sizeof(line),'\t'); + sscanf(line,"length %i\n",&tempLength); + length = (uint32)tempLength; + writer.writeU4(&length,1); + + fgets(line,sizeof(line),fp); /* table_length */ + stripLine(line,sizeof(line),'\t'); + sscanf(line,"table_length %i\n",&tempCount); + lineNoTableLength = (uint16)tempCount; + writer.writeU2(&lineNoTableLength,1); + + /* Line number table. */ + if (tempCount > 0) { + + fgets(line,sizeof(line),fp); /* #begin_line_number_table */ + stripLine(line,sizeof(line),'\t'); + + fgets(line,sizeof(line),fp); /* # */ + + while (strcmp(line,"#end_line_number_table\n") != 0) { + + uint16 startPc; + uint16 lineNo; + int temp; + + fgets(line,sizeof(line),fp); /* start_pc */ + stripLine(line,sizeof(line),'\t'); + sscanf(line,"start_pc %i\n",&temp); + startPc = (uint16)temp; + writer.writeU2(&startPc,1); + + fgets(line,sizeof(line),fp); /* line_number */ + stripLine(line,sizeof(line),'\t'); + sscanf(line,"line_number %i\n",&temp); + lineNo = (uint16)temp; + writer.writeU2(&lineNo,1); + + /* Read next entry. */ + fgets(line,sizeof(line),fp); + stripLine(line,sizeof(line),'\t'); + + } + + } + + break; + + } + + case CR_ATTRIBUTE_LOCALVARIABLETABLE: { /* LocalVariableTable */ + + uint16 nameIndex; + uint32 length; + uint16 localVarTableLength; + int tempNameIndex, tempLength, tempCount; + + fgets(line,sizeof(line),fp); /* nameIndex */ + stripLine(line,sizeof(line),'\t'); + sscanf(line,"nameIndex %i\n",&tempNameIndex); + nameIndex = (uint16)tempNameIndex; + writer.writeU2(&nameIndex,1); + + fgets(line,sizeof(line),fp); /* length */ + stripLine(line,sizeof(line),'\t'); + sscanf(line,"length %i\n",&tempLength); + length = (uint32)tempLength; + writer.writeU4(&length,1); + + fgets(line,sizeof(line),fp); /* table_length */ + stripLine(line,sizeof(line),'\t'); + sscanf(line,"table_length %i\n",&tempCount); + localVarTableLength = (uint16)tempCount; + writer.writeU2(&localVarTableLength,1); + + /* Local variable table. */ + if (tempCount > 0) { + + fgets(line,sizeof(line),fp); /* #begin_local_variable_table */ + stripLine(line,sizeof(line),'\t'); + + fgets(line,sizeof(line),fp); /* # */ + + while (strcmp(line,"#end_local_variable_table\n") != 0) { + + uint16 startPc; + uint16 length; + uint16 nameIndex; + uint16 descIndex; + uint16 index; + int temp; + + fgets(line,sizeof(line),fp); /* start_pc */ + stripLine(line,sizeof(line),'\t'); + sscanf(line,"start_pc %i\n",&temp); + startPc = (uint16)temp; + writer.writeU2(&startPc,1); + + fgets(line,sizeof(line),fp); /* length */ + stripLine(line,sizeof(line),'\t'); + sscanf(line,"length %i\n",&temp); + length = (uint16)temp; + writer.writeU2(&length,1); + + fgets(line,sizeof(line),fp); /* nameIndex */ + stripLine(line,sizeof(line),'\t'); + sscanf(line,"nameIndex %i\n",&temp); + nameIndex = (uint16)temp; + writer.writeU2(&nameIndex,1); + + fgets(line,sizeof(line),fp); /* descIndex */ + stripLine(line,sizeof(line),'\t'); + sscanf(line,"descIndex %i\n",&temp); + descIndex = (uint16)temp; + writer.writeU2(&descIndex,1); + + fgets(line,sizeof(line),fp); /* index */ + stripLine(line,sizeof(line),'\t'); + sscanf(line,"index %i\n",&temp); + index = (uint16)temp; + writer.writeU2(&index,1); + + /* Read next entry. */ + fgets(line,sizeof(line),fp); + stripLine(line,sizeof(line),'\t'); + + } + + } + + break; + + } + + case CR_ATTRIBUTE_CODE: { /* Code */ + + uint16 nameIndex; + uint32 length; + uint16 maxStack; + uint16 maxLocals; + uint32 codeLength; + uint16 exceptionTableLength; + uint16 attrCount; + int temp, tempCount, bytecodeLength; + + fgets(line,sizeof(line),fp); /* nameIndex */ + stripLine(line,sizeof(line),'\t'); + sscanf(line,"nameIndex %i\n",&temp); + nameIndex = (uint16)temp; + writer.writeU2(&nameIndex,1); + + fgets(line,sizeof(line),fp); /* length */ + stripLine(line,sizeof(line),'\t'); + sscanf(line,"length %i\n",&temp); + length = (uint32)temp; + writer.writeU4(&length,1); + + fgets(line,sizeof(line),fp); /* max_stack */ + stripLine(line,sizeof(line),'\t'); + sscanf(line,"max_stack %i\n",&temp); + maxStack = (uint16)temp; + writer.writeU2(&maxStack,1); + + fgets(line,sizeof(line),fp); /* maxLocals */ + stripLine(line,sizeof(line),'\t'); + sscanf(line,"max_locals %i\n",&temp); + maxLocals = (uint16)temp; + writer.writeU2(&maxLocals,1); + + fgets(line,sizeof(line),fp); /* code_length */ + stripLine(line,sizeof(line),'\t'); + sscanf(line,"code_length %i\n",&bytecodeLength); + codeLength = (uint32)bytecodeLength; + writer.writeU4(&codeLength,1); + + /* Temp way for handling bytecodes. */ + if ( bytecodeLength > 0 ) { + + unsigned int bytecodeFromFile; + unsigned char bytecode; + + fgetc(fp); + fgetc(fp); + fscanf(fp,"#bytecodes "); + + /* This needs to be refined. */ + for (int i = 0; i < bytecodeLength - 1; i++) { + + fscanf(fp,"%x ",&bytecodeFromFile); + printf("bytcode: %x\n",bytecode); + bytecode = (unsigned char) bytecodeFromFile; + writer.writeU1((char *)(&bytecode),1); + + } + fscanf(fp,"%x",&bytecodeFromFile); + printf("bytcode: %x\n",bytecodeFromFile); + bytecode = (unsigned char) bytecodeFromFile; + writer.writeU1((char *)(&bytecode),1); + fgets(line,sizeof(line),fp); + + } + + fgets(line,sizeof(line),fp); /* #begin_bytecodes */ + stripLine(line,sizeof(line),'\t'); + + /* Bytecodes */ + parseBytecodes(fp,writer); + + fgets(line,sizeof(line),fp); /* exception_table_length */ + stripLine(line,sizeof(line),'\t'); + sscanf(line,"exception_table_length %i\n",&tempCount); + exceptionTableLength = (uint16)tempCount; + writer.writeU2(&exceptionTableLength,1); + + /* Create exception table length. */ + if ( tempCount > 0 ) { + + uint16 startPc; + uint16 endPc; + uint16 handlerPc; + uint16 catchType; + int temp1, temp2; + + fgets(line,sizeof(line),fp); /* start_pc */ + stripLine(line,sizeof(line),'\t'); + sscanf(line,"start_pc %i end_pc %i\n",&temp1,&temp2); + startPc = (uint16)temp; + endPc = (uint16)temp; + writer.writeU2(&startPc,1); + writer.writeU2(&endPc,1); + + fgets(line,sizeof(line),fp); /* handler_pc */ + stripLine(line,sizeof(line),'\t'); + sscanf(line,"handler_pc %i\n",&temp1); + handlerPc = (uint16)temp1; + writer.writeU2(&handlerPc,1); + + fgets(line,sizeof(line),fp); /* catch_type */ + stripLine(line,sizeof(line),'\t'); + sscanf(line,"catch_type %i\n",&temp1); + catchType = (uint16)temp1; + writer.writeU2(&catchType,1); + + } + + fgets(line,sizeof(line),fp); /* attributes_count */ + stripLine(line,sizeof(line),'\t'); + sscanf(line,"attributes_count %i\n",&tempCount); + attrCount = (uint16)tempCount; + writer.writeU2(&attrCount,1); + + /* Attributes structure */ + if (tempCount > 0) { + + char attribute[256]; + int attrIndex; + + + /* Init attribute. */ + for (int j = 0; j < 256; j++) attribute[j] = '\0'; + + fgets(line,sizeof(line),fp); /* #begin_attributes */ + fgets(line,sizeof(line),fp); /* # Attribute */ + stripLine(line,sizeof(line),'\t'); + + while (strcmp(line,"#end_attributes\n") != 0) { + + /* Get the attribute string. */ + sscanf(line,"#%i %s\n",&attrIndex,attribute); + + createAttributes(fp,writer,reader,getAttribute(attribute)); + + /* Read the next line. */ + fgets(line,sizeof(line),fp); + stripLine(line,sizeof(line),'\t'); + + } + + } + + break; + + } + + case CR_ATTRIBUTE_EXCEPTIONS: { /* Exceptions */ + + uint16 nameIndex; + uint32 length; + uint16 numExceptions; + int tempNameIndex, tempLength, tempCount; + + fgets(line,sizeof(line),fp); /* nameIndex */ + stripLine(line,sizeof(line),'\t'); + sscanf(line,"nameIndex %i\n",&tempNameIndex); + nameIndex = (uint16)tempNameIndex; + writer.writeU2(&nameIndex,1); + + fgets(line,sizeof(line),fp); /* length */ + stripLine(line,sizeof(line),'\t'); + sscanf(line,"length %i\n",&tempLength); + length = (uint32)tempLength; + writer.writeU4(&length,1); + + fgets(line,sizeof(line),fp); /* exceptions_count */ + stripLine(line,sizeof(line),'\t'); + sscanf(line,"exceptions_count %i\n",&tempCount); + numExceptions = (uint16)tempCount; + writer.writeU2(&numExceptions,1); + + /* Excpetion index table. */ + if (tempCount > 0) { + + fgets(line,sizeof(line),fp); /* #begin_exception_index_table */ + stripLine(line,sizeof(line),'\t'); + + fgets(line,sizeof(line),fp); /* # */ + + while (strcmp(line,"#end_exception_index_table\n") != 0) { + + uint16 index; + int temp; + + fgets(line,sizeof(line),fp); /* index */ + stripLine(line,sizeof(line),'\t'); + sscanf(line,"index %i\n",&temp); + index = (uint16)temp; + writer.writeU2(&index,1); + + /* Read next entry. */ + fgets(line,sizeof(line),fp); + stripLine(line,sizeof(line),'\t'); + + } + + } + + break; + + } + + default: { /* Ignore everything else. */ + + printf("Error: problems attribute\n"); + printf("%s",line); + + break; + + } + + } + +} + +/* createClass(FILE *fp,FileWriter &writer,ClassFileReader &reader) + * + * function: Create the class file. + * + */ +void createClass(FILE *fp,FileWriter &writer,ClassFileReader &reader) { + + char line[256]; + + /* Read line by line. */ + while (fgets(line,sizeof(line),fp) != NULL) { + + if (!isBlankLine(line)) { + + switch (getItem(line)) { + + case CG_MAGIC: { /* Magic */ + + uint32 magic; + + fgets(line, sizeof(line), fp); + sscanf(line,"%x\n",&magic); + writer.writeU4(&magic,1); + + break; + + } + + case CG_MINORVERSION: { /* Minor version */ + + int tempMinor; + uint16 minor; + + fgets(line, sizeof(line), fp); + sscanf(line,"%i\n",&tempMinor); + minor = (uint16)tempMinor; + writer.writeU2(&minor,1); + + break; + + } + + case CG_MAJORVERSION: { /* Major version */ + + int tempMajor; + uint16 major; + + fgets(line, sizeof(line), fp); + sscanf(line,"%i\n",&tempMajor); + major = (uint16)tempMajor; + writer.writeU2(&major,1); + + break; + + } + + case CG_CONSTANTPOOL: { /* Constant pool */ + + int tempCount; + uint16 constantpoolcount; + + fgets(line,sizeof(line),fp); + sscanf(line,"%i\n",&tempCount); + constantpoolcount = (uint16)tempCount; + writer.writeU2(&constantpoolcount,1); + + createConstantPool(fp,writer); + + printf("Done with ConstantPool\n"); + + break; + + } + + case CG_ACCESSFLAGS: { /* Access flags */ + + int tempFlags; + uint16 accessFlags; + + fgets(line,sizeof(line),fp); + sscanf(line,"%i\n",&tempFlags); + accessFlags = (uint16)tempFlags; + writer.writeU2(&accessFlags,1); + + break; + + } + + case CG_THISCLASS: { /* This class */ + + int tempClass; + uint16 thisClass; + + fgets(line,sizeof(line),fp); + sscanf(line,"%i\n",&tempClass); + thisClass = (uint16)tempClass; + writer.writeU2(&thisClass,1); + + break; + + } + + case CG_SUPERCLASS: { /* Super class */ + + int tempClass; + uint16 superClass; + + fgets(line,sizeof(line),fp); + sscanf(line,"%i\n",&tempClass); + superClass = (uint16)tempClass; + writer.writeU2(&superClass,1); + + break; + + } + + case CG_INTERFACES: { /* Interfaces */ + + int tempCount; + uint16 interfacesCount; + + fgets(line,sizeof(line),fp); + sscanf(line,"%i\n",&tempCount); + interfacesCount = (uint16)tempCount; + writer.writeU2(&interfacesCount,1); + + if ( tempCount > 0 ) createInterfaces(fp,writer); + + break; + + } + + case CG_FIELDS: { /* Fields */ + + int tempCount; + uint16 fieldsCount; + + /* Fields count */ + fgets(line,sizeof(line),fp); + sscanf(line,"%i\n",&tempCount); + fieldsCount = (uint16)tempCount; + writer.writeU2(&fieldsCount,1); + + if ( tempCount > 0 ) createFields(fp,writer,reader); + + break; + + } + + case CG_METHODS: { /* Methods */ + + int tempCount; + uint16 methodsCount; + + /* Mehtods count */ + fgets(line,sizeof(line),fp); + sscanf(line,"%i\n",&tempCount); + methodsCount = (uint16)tempCount; + writer.writeU2(&methodsCount,1); + + if ( tempCount > 0 ) createMethods(fp,writer,reader); + + break; + + } + + case CG_ATTRIBUTES: { /* Attributes */ + + int tempCount; + uint16 attrCount; + + /* Attributes count */ + fgets(line,sizeof(line),fp); /* */ + stripLine(line,sizeof(line),'\t'); + sscanf(line,"%i\n",&tempCount); + attrCount = (uint16)tempCount; + writer.writeU2(&attrCount,1); + + /* Attributes structure */ + if (tempCount > 0) { + + char attribute[256]; + int attrIndex; + + /* Init attribute. */ + for (int i = 0; i < 256; i++) attribute[i] = '\0'; + + fgets(line,sizeof(line),fp); /* #begin_attributes */ + fgets(line,sizeof(line),fp); /* # Attribute */ + stripLine(line,sizeof(line),'\t'); + + while (strcmp(line,"#end_attributes\n") != 0) { + + /* Get the attribute string. */ + sscanf(line,"#%i %s\n",&attrIndex,attribute); + + createAttributes(fp,writer,reader,getAttribute(attribute)); + + /* Read the next line. */ + fgets(line,sizeof(line),fp); + stripLine(line,sizeof(line),'\t'); + + } + + } + + + } + + default: { /* Ignore other strings read. */ + + break; + + } + + } + + } + + } + + return; + +} + diff --git a/ef/Utilities/qa/constantpool/ClassGen.h b/ef/Utilities/qa/constantpool/ClassGen.h new file mode 100644 index 000000000000..050d544648df --- /dev/null +++ b/ef/Utilities/qa/constantpool/ClassGen.h @@ -0,0 +1,150 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#ifndef _CR_CLASSGEN_H_ +#define _CR_CLASSGEN_H_ + +#include +#include +#include +#include +#include + +#include "ConstantPool.h" +#include "DoublyLinkedList.h" +#include "Attributes.h" +#include "InfoItem.h" +#include "Pool.h" +#include "StringPool.h" +#include "ClassReader.h" +#include "FileReader.h" +#include "FileWriter.h" + +/* Class items */ +#define CG_MAGIC 1 +#define CG_MINORVERSION 2 +#define CG_MAJORVERSION 3 +#define CG_CONSTANTPOOL 4 +#define CG_ACCESSFLAGS 5 +#define CG_THISCLASS 6 +#define CG_SUPERCLASS 7 +#define CG_INTERFACES 8 +#define CG_FIELDS 9 +#define CG_METHODS 10 +#define CG_ATTRIBUTES 11 + +/* byte */ +typedef unsigned char byte; + +/* getType(char *constantType) + * + * function: Compares the passed string to the list of Constant Types. + * Returns the constant type of the given string. + * + */ +int getType(char *constantType); + +/* getStringLength(char *line) + * + * function: Finds the length of the passed string array. + * Returns the length of the string from index 0 to '\n'. + * + */ +int getStringLength(char *line); + +/* isBlankLine(const char *line) + * + *function: Checks if the passed string is a blank line. + *Returns true/false if the string is a blank line or not. + * + */ +bool isBlankLine(const char *line); + +/* getItem(const char *line) + * + * function: Returns the appropriate classfile item. + * + */ +int getItem(const char *line); + +/* getAttribute(const char *line) + * + * function: Returns the appropriate attribute. + * + */ +int getAttribute(const char *line); + +/* stripLine(char* line,int size,byte c) + * + * function: Removes the specified char from the line. + * + */ +void stripLine(char* line,int size,byte c); + +/* parseBytecodes(FILE *fp, FileWriter &writer) + * + *function: Parses and generates the bytecodes. + * + */ +void parseBytecodes(FILE *fp,FileWriter &writer); + +/* createConstantPool(FILE *fp, FileWriter &writer) + * + *function: Creates the constant pool. + * + */ +void createConstantPool(FILE *fp,FileWriter &writer); + +/* createInterfaces(FILE *fp, FileWriter &writer) + * + *function: Creates the interfaces structure. + * + */ +void createInterfaces(FILE *fp,FileWriter &writer,ClassFileReader &reader); + +/* createFields(FILE *fp, FileWriter &writer) + * + *function: Creates the fields structure. + * + */ +void createFields(FILE *fp,FileWriter &writer,ClassFileReader &reader); + +/* createMethods(FILE *fp, FileWriter &writer,ClassFileReader &reader) + * + *function: Creates the methods structure. + * + */ +void createMethods(FILE *fp,FileWriter &writer,ClassFileReader &reader); + +/* createAttributes(FILE *fp, FileWriter &writer,ClassFileReader &reader,int attribute,int tabs) + * + *function: Creates the attribute structure. + * + */ + +void createAttributes(FILE *fp,FileWriter &writer,ClassFileReader &reader,int attribute); + +/* createClass(FILE *fp,FileWriter &writer,ClassFileReader &reader) + * + *function: Create the class file. + * + */ +void createClass(FILE *fp,FileWriter &writer,ClassFileReader &reader); + +#endif /* _CR_CLASSGEN_H_ */ + diff --git a/ef/Utilities/qa/constantpool/ClassReader.cpp b/ef/Utilities/qa/constantpool/ClassReader.cpp new file mode 100644 index 000000000000..7efede3f69bc --- /dev/null +++ b/ef/Utilities/qa/constantpool/ClassReader.cpp @@ -0,0 +1,2817 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#include "ClassReader.h" +#include "AttributeHandlers.h" +#include + +#ifndef NO_NSPR +#include "plstr.h" +#endif + +#ifdef DEBUG +#include "DebugUtils.h" +#include "JavaBytecodes.h" +#include +void indent(int n) +{ + for (; n; n--) + printf(" "); +} + +void title(int nIndents, const char *s) +{ + indent(nIndents); + printf("%s\n", s); +} + +void print(int nIndents, const char *fmt, ...) +{ + va_list args; + static char buffer[2048]; + + indent(nIndents); + va_start(args, fmt); + vsprintf(buffer, fmt, args); + va_end(args); + + printf("%s\n", buffer); +} + +#endif + + +/* Functions to parse method and field descriptors */ +static bool parseFieldDescriptor(Pool &pool, const char *s, JavaType &type, + const char **next) +{ + TypeKind tk; + + switch (*s) { + case 'B': + tk = tkByte; + break; + + case 'C': + tk = tkChar; + break; + + case 'D': + tk = tkDouble; + break; + + case 'F': + tk = tkFloat; + break; + + case 'I': + tk = tkInt; + break; + + case 'J': + tk = tkLong; + break; + + case 'S': + tk = tkShort; + break; + + case 'Z': + tk = tkBoolean; + break; + + case '[': { + JavaType *javaType = new (pool) JavaType; + + if (!javaType) + return false; + + if (!parseFieldDescriptor(pool, s+1, *javaType, next)) + return false; + + type.set(*javaType); + return true; + } + + case 'L': { +#ifdef NO_NSPR + char *t = strchr(++s, ';'); +#else + char *t = PL_strchr(++s, ';'); +#endif + + if (!t) + return false; + + int len = t-s+1; + char *instanceClass = new (pool) char [len]; + + if (!instanceClass) + return false; + +#ifdef NO_NSPR + strncpy(instanceClass, s, len-1); +#else + PL_strncpy(instanceClass, s, len-1); +#endif + + instanceClass[len-1] = 0; + *next = (char *) t+1; + type.set(instanceClass); + return true; + } + + default: + return false; + } + + type.set(tk); + *next = s+1; + return true; +} + + +inline int getJavaSize(const JavaType *type) { + return getTypeKindSize(type->getKind()); +} + + +/* Implementation of ConstantUtf8 */ +ConstantUtf8::ConstantUtf8(Pool &pool, char *str, int len) : + ConstantPoolItem(pool, CR_CONSTANT_UTF8) +{ + data = str; + dataLen = len; +} + +#ifdef DEBUG +void ConstantUtf8::dump(int nIndents) +{ + title(nIndents, "CONSTANT_UTF8"); + print(nIndents, "String: %s", data); +} +#endif + +ConstantUtf8::ConstantUtf8(Pool &pool, int len) : + ConstantPoolItem(pool, CR_CONSTANT_UTF8) +{ + dataLen = len; +} + +/* Implementation of ConstantClass */ +int ConstantClass::resolveAndValidate() +{ + if (pool) + utfString = (ConstantUtf8 *) pool[index]; + + return (utfString && utfString->getType() == CR_CONSTANT_UTF8); +} + +#ifdef DEBUG +void ConstantClass::dump(int nIndents) +{ + title(nIndents, "CONSTANT_CLASS"); + utfString->dump(nIndents+1); +} +#endif + +/* Implementation of ConstantNameAndType */ +int ConstantNameAndType::resolveAndValidate() +{ + if (pool) { + nameInfo = (ConstantUtf8 *) pool[nameIndex]; + descInfo = (ConstantUtf8 *) pool[descIndex]; + } + + return (nameInfo && descInfo && + nameInfo->getType() == CR_CONSTANT_UTF8 && + descInfo->getType() == CR_CONSTANT_UTF8); +} + +#ifdef DEBUG +void ConstantNameAndType::dump(int nIndents) +{ + title(nIndents, "CONSTANT_NAMEANDTYPE (name/desc)"); + nameInfo->dump(nIndents+1); + descInfo->dump(nIndents+1); +} +#endif + +ConstantNameAndType::ConstantNameAndType(Pool &pool, + ConstantPoolItem **array, + int nindex, int dIndex) : + ConstantPoolItem(pool, array, CR_CONSTANT_NAMEANDTYPE) +{ + nameIndex = nindex, descIndex = dIndex; + nameInfo = descInfo = 0; +} + +/* Implementation of ConstantRef */ +int ConstantRef::resolveAndValidate() +{ + if (pool) { + classInfo = (ConstantClass *) pool[classIndex]; + typeInfo = (ConstantNameAndType *) pool[typeIndex]; + } + + return (classInfo && typeInfo && + classInfo->getType() == CR_CONSTANT_CLASS && + typeInfo->getType() == CR_CONSTANT_NAMEANDTYPE); +} + +#ifdef DEBUG +void ConstantRef::dump(int nIndents) +{ + print(nIndents+2, "Printing ClassInfo and typeInfo"); + classInfo->dump(nIndents+1); + typeInfo->dump(nIndents+1); +} +#endif + +ConstantRef::ConstantRef(Pool &pool, + uint8 _type, ConstantPoolItem **array, int cIndex, + int tIndex) : ConstantPoolItem(pool, array, _type) +{ + classIndex = cIndex, typeIndex = tIndex; + classInfo = 0; + typeInfo = 0; +} + +/* Implementation of ConstantFieldRef */ +#ifdef DEBUG +void ConstantFieldRef::dump(int nIndents) +{ + title(nIndents, "CONSTANT_FIELD_REF"); + ConstantRef::dump(nIndents); +} +#endif + +/* Implementation of ConstantMethodRef */ +#ifdef DEBUG +void ConstantMethodRef::dump(int nIndents) { + title(nIndents, "CONSTANT_METHOD_REF"); + ConstantRef::dump(nIndents); +} +#endif + +/* Implementation of class ConstantInterfaceMethodRef */ +#ifdef DEBUG + void ConstantInterfaceMethodRef::dump(int nIndents) { + title(nIndents, "CONSTANT_INTERFACEMETHOD_REF"); + ConstantRef::dump(nIndents); + } +#endif + +/* Implementation of ConstantString */ +int ConstantString::resolveAndValidate() +{ + if (pool) + utfString = (ConstantUtf8 *) pool[index]; + + return (utfString && utfString->getType() == CR_CONSTANT_UTF8); +} + +#ifdef DEBUG +void ConstantString::dump(int nIndents) { + title(nIndents, "CONSTANT_STRING"); + utfString->dump(nIndents+1); +} +#endif + +/* Implementation of ConstantVal */ +#ifdef DEBUG +void ConstantVal::dump(int nIndents) +{ + switch (vk) { + case vkInt: + title(nIndents, "CONSTANT_INT"); + print(nIndents, "Value: %d", value.i); + break; + + case vkFloat: + title(nIndents, "CONSTANT_FLOAT"); + print(nIndents, "Value: %f", value.f); + break; + + case vkDouble: + title(nIndents, "CONSTANT_DOUBLE"); + print(nIndents, "Value: %lf", value.d); + break; + + case vkLong: + title(nIndents, "CONSTANT_LONG"); + break; + + default: + break; + } +} +#endif + +/* Implementation of ConstantFloat */ +ConstantFloat::ConstantFloat(Pool &pool, uint32 _raw): + ConstantVal(pool, CR_CONSTANT_FLOAT, vkFloat), raw(_raw) +{ + if (raw == 0x7f80000) + value.setValueContents(floatPositiveInfinity); + else if (raw == 0xff800000) + value.setValueContents(floatNegativeInfinity); +#if 0 + else if ((raw >= 0x7f800001 && raw <= 0x7fffffff) || + (raw >= 0xff800001 && raw <= 0xffffffff)) +#else + else if ((raw & 0x7f800001) || (raw & 0xff800001)) +#endif + value.setValueContents(floatNaN); + else { + + int s = ((raw >> 31) == 0) ? 1 : -1; + int e = ((raw >> 23) &0xff); + int m = (e == 0) ? (raw & 0x7fffff) << 1: + (raw & 0x7fffff) | 0x800000; + + value.setValueContents((Flt32) s * m * pow(2.0, e-150)); + } +} + +/* Implementation of ConstantLong */ +ConstantLong::ConstantLong(Pool &pool, uint32 _lo, uint32 _hi) : + ConstantVal(pool, CR_CONSTANT_LONG, vkLong), lo(_lo), hi(_hi) +{ +#ifdef HAVE_LONG_LONG + int64 lw, llo, lhi; + + llo = (int64) lo; + lhi = (int64) hi; + lhi <<= 32; + + lw = llo | lhi; + + value.setValueContents(lw); +#else + value.l.lo = lo; + value.l.hi = hi; +#endif +} + + +/* Implementation of ConstantDouble */ +ConstantDouble::ConstantDouble(Pool &pool, char *_data): + ConstantVal(pool, CR_CONSTANT_DOUBLE, vkDouble) +{ + union { + unsigned char c[8]; + Flt64 d; + } u; + + memcpy(data, _data, 8); +#ifdef LITTLE_ENDIAN + u.c[0] = data[7]; + u.c[1] = data[6]; + u.c[2] = data[5]; + u.c[3] = data[4]; + + u.c[4] = data[3]; + u.c[5] = data[2]; + u.c[6] = data[1]; + u.c[7] = data[0]; +#else + u.c[0] = data[0]; + u.c[1] = data[1]; + u.c[2] = data[2]; + u.c[3] = data[3]; + + u.c[4] = data[4]; + u.c[5] = data[5]; + u.c[6] = data[6]; + u.c[7] = data[7]; +#endif + value.d = u.d; +} + +/* Implementation of AttributeSourceFile */ +#ifdef DEBUG +void AttributeSourceFile::dump(int nIndents) { + title(nIndents, "SOURCE-FILE"); + srcName->dump(nIndents+1); +} +#endif + +/* Implementation of AttributeConstantValue */ +#ifdef DEBUG +void AttributeConstantValue::dump(int nIndents) +{ + title(nIndents, "CONSTANT-VALUE"); + value->dump(nIndents+1); +} +#endif + +/* Implementation of ExceptionItem */ +ExceptionItem::ExceptionItem(uint16 _startPc, uint16 _endPc, + uint16 _handlerPc, ConstantClass *_catcher, + uint16 _catcherIndex) { + startPc = _startPc, endPc = _endPc, + handlerPc = _handlerPc, catcher = _catcher; + catcherIndex = _catcherIndex; +} + +#ifdef DEBUG +void ExceptionItem::dump(int nIndents) { + title(nIndents, "ExceptionItem"); + print(nIndents+1, + "Start %u End %u Handler %u", startPc, endPc, handlerPc); + if (catcher) { + print(nIndents+1, "CATCHER:"); + catcher->dump(nIndents+2); + } +} +#endif + +/* Implementation of AttributeCode */ +AttributeCode::AttributeCode(Pool &pool, uint16 _length, + uint16 _maxStack, uint16 _maxLocals, + uint32 _codeLength, + uint16 nindex, + CrError *status): + AttributeInfoItem(pool, "Code", CR_ATTRIBUTE_CODE, _length, nindex) +{ + *status = crErrorNone; + maxStack = _maxStack, maxLocals = _maxLocals, + codeLength = _codeLength; + + numExceptions = 0; + exceptions = 0; + numAttributes = 0; + attributes = 0; + + if (codeLength > 0) + code = new (p) char[codeLength]; + else + code = 0; +} + +int AttributeCode::setNumExceptions(int _numExceptions) +{ + exceptions = new (p) ExceptionItem *[_numExceptions]; + numExceptions = _numExceptions; + return true; +} + +int AttributeCode::setNumAttributes(int _numAttributes) +{ + attributes = new (p) AttributeInfoItem *[_numAttributes]; + numAttributes = _numAttributes; + return true; +} + + +#ifdef DEBUG +void AttributeCode::dump(int nIndents) { + int32 i; + + title(nIndents, "CODE"); + print(nIndents, + "maxStack %u maxLocals %u codeLength %u numExceptions %u", + maxStack, maxLocals, codeLength, numExceptions); + + if (numExceptions > 0) { + title(nIndents, "Exceptions"); + for (i = 0; i < (int32) numExceptions; i++) + exceptions[i]->dump(nIndents+1); + } + + if (numAttributes > 0) { + title(nIndents, "Attributes"); + for (i = 0; i < numAttributes; i++) + attributes[i]->dump(nIndents+1); + } +} +#endif + +/* Implementation of AttributeExceptions */ +int AttributeExceptions::setNumExceptions(uint16 n) +{ + exceptions = new (p) ConstantClass *[n]; + excIndices = new (p) uint16[n]; + + numExceptions = n; + return true; +} + +#ifdef DEBUG +void AttributeExceptions::dump(int nIndents) +{ + int i; + + title(nIndents, "EXCEPTIONS"); + print(nIndents, "numExceptions %d", numExceptions); + + if (numExceptions > 0) { + title(nIndents, "Exceptions"); + for (i = 0; i < numExceptions; i++) + exceptions[i]->dump(nIndents+1); + } +} +#endif + +/* Implementation of AttributeLineNumberTable */ +int AttributeLineNumberTable::setNumEntries(uint16 n) +{ + entries = new (p) LineNumberEntry[n]; + numEntries = n; + return true; +} + +int AttributeLineNumberTable::getPc(uint16 lineNumber) { + int i; + + /* The line numbers are not guaranteed to be in order */ + for (i = 0; i < numEntries; i++) + if (entries[i].lineNumber == lineNumber) + return entries[i].startPc; + + return -1; +} + +#ifdef DEBUG +void AttributeLineNumberTable::dump(int nIndents) +{ + title(nIndents, "LINE-NUMBER-ENTRY"); + + for (int i = 0; i < numEntries; i++) + entries[i].dump(nIndents+1); +} +#endif + + +/* Implementation of AttributeLocalVariableTable */ +int AttributeLocalVariableTable::setNumEntries(uint16 n) { + entries = new (p) LocalVariableEntry[n]; + numEntries = n; + return true; +} + +#ifdef DEBUG +void AttributeLocalVariableTable::dump(int nIndents) +{ + title(nIndents, "LOCAL-VARIABLE-TABLE"); + + for (int i = 0; i < numEntries; i++) + entries[i].dump(nIndents+1); +} +#endif + +/* Implementation of InfoItem */ +InfoItem::InfoItem(Pool &pool, uint16 aflags, ConstantUtf8 *classInfo, + ConstantUtf8 *nameInfo, + ConstantUtf8 *descInfo, + uint16 nIndex, uint16 dIndex) : p(pool), + nameIndex(nIndex), descIndex(dIndex) +{ + accessFlags = aflags; + name = nameInfo; + descriptor = descInfo; + className = classInfo; + attrCount = 0; +} + +int InfoItem::addAttribute(AttributeInfoItem &attribute) +{ + attributes.addLast(attribute); + attrCount++; + return true; +} + +AttributeInfoItem *InfoItem::getAttribute(const char *_name) const +{ + for (DoublyLinkedList::iterator i = attributes.begin(); + !attributes.done(i); i = attributes.advance(i)) { + AttributeInfoItem &attribute = attributes.get(i); + +#ifdef NO_NSPR + if (!(strncmp(_name, attribute.getName(), attribute.getLength()))) +#else + if (!(PL_strncmp(_name, attribute.getName(), attribute.getLength()))) +#endif + return &attribute; + } + + return 0; +} + +AttributeInfoItem *InfoItem::getAttribute(const uint32 code) const +{ + for (DoublyLinkedList::iterator i = attributes.begin(); + !attributes.done(i); i = attributes.advance(i)) { + AttributeInfoItem &attribute = attributes.get(i); + + if (attribute.getCode() == code) + return &attribute; + } + + return 0; +} + + +#ifdef DEBUG +void InfoItem::dump(int nIndents) +{ + print(nIndents, "%s() descriptor:%s", + name->getUtfString(), descriptor->getUtfString()); + print(nIndents, "AccessFlags %x attrCount %d", + accessFlags, attrCount); + + if (attrCount > 0) { + print(nIndents, "-> Attributes (%d):", attrCount); + for (DoublyLinkedList::iterator i = + attributes.begin(); + !attributes.done(i); i = attributes.advance(i)) + attributes.get(i).dump(nIndents+1); + } +} +#endif + +/* Implementation of FieldInfo */ +FieldInfo::FieldInfo(Pool &pool, uint16 aflags, ConstantUtf8 *classInfo, + ConstantUtf8 *nameInfo, + ConstantUtf8 *descInfo, + uint16 nameindex, uint16 descindex) : + InfoItem(pool, aflags, classInfo, nameInfo, descInfo, nameindex, + descindex) { + type = new (pool) JavaType; +} + +void FieldInfo::getInfo(JavaType *&typeRet, + bool &isVolatile, bool &isConstant, + uint32 &offsetRet) const +{ + typeRet = type; + offsetRet = pos.offset; + isVolatile = (getAccessFlags() & CR_FIELD_VOLATILE); + isConstant = false; +} + +void FieldInfo::getInfo(JavaType *&typeRet, + bool &isVolatile, bool &isConstant, + addr &addrRet) const +{ + typeRet = type; + addrRet = pos.a; + isVolatile = (getAccessFlags() & CR_FIELD_VOLATILE); + isConstant = false; +} + + +#ifdef DEBUG +void FieldInfo::dump(int nIndents) +{ + InfoItem::dump(nIndents); + + if (getAccessFlags() & CR_FIELD_STATIC) + print(nIndents, "Address: %x", pos.a); + else + print(nIndents, "Offset: %d", pos.offset); + +} + +#endif + +/* Implementation of MethodInfo */ +MethodInfo::MethodInfo(Pool &pool, uint16 aflags, ConstantUtf8 *classInfo, + ConstantUtf8 *nameInfo, + ConstantUtf8 *descInfo, + uint16 nIndex, uint16 dIndex) : +InfoItem(pool, aflags, classInfo, nameInfo, descInfo, nIndex, dIndex) +{ + paramSize = 10; + + params = new (pool) JavaType[paramSize]; +} + + +const JavaType &MethodInfo::getSignature(int &nParams, + const JavaType *¶mTypes, + bool &isStatic, bool &isNative, + bool &isAbstract) const +{ + nParams = numParams; + paramTypes = params; + + uint16 aFlags = getAccessFlags(); + isStatic = (aFlags & CR_METHOD_STATIC) != 0; + isNative = (aFlags & CR_METHOD_NATIVE) != 0; + isAbstract = (aFlags & CR_METHOD_ABSTRACT) != 0; + return ret; +} + +#if DEBUG_LAURENT +static inline JavaType *newJavaType(Pool& p, uint32 size) {return new(p) JavaType[size];} +#endif + +bool MethodInfo::parseMethodDescriptor(const char *s) +{ + char *paramstr; + const char *t; + + numParams = 0; + + if (!(getAccessFlags() & CR_METHOD_STATIC)) { + /* We need a copy since ~JavaType() deletes the string + * passed to it + */ + const char *t = getClassName()->getUtfString(); + +#ifdef NO_NSPR + int len = strlen(t); +#else + int len = PL_strlen(t); +#endif + + char *s = new (p) char [len+1]; + +#ifdef NO_NSPR + strncpy(s, t, len); +#else + PL_strncpy(s, t, len); +#endif + + s[len] = 0; + + params[0].set(s); + numParams = 1; + } + + if (*s++ != '(') + return false; + + /* Get everything between this and ')' */ +#ifdef NO_NSPR + if (!(t = strchr(s, ')'))) +#else + if (!(t = PL_strchr(s, ')'))) +#endif + return false; + + int len = t-s+1; + + if (len != 1) { + /* This is a very temporary allocation, so we don't use the pool + * to allocate this. Also see the delete paramstr, below + */ + if (!(paramstr = new char[len])) + return false; + +#ifdef NO_NSPR + strncpy((char *) paramstr, s, len-1); +#else + PL_strncpy((char *) paramstr, s, len-1); +#endif + + paramstr[len-1] = 0; + + const char *next = paramstr; + + while (*next) { + + if (numParams+1 > paramSize) { + JavaType *oldParams = params; + +#if DEBUG_LAURENT + // This will avoid an internal compile error (gcc) + params = newJavaType(p, paramSize); +#else + params = new (p) JavaType[paramSize]; +#endif + + for (int i = 0; i < numParams; i++) + params[i].move(oldParams[i]); + + /* We don't do this since we're using a pool to allocate, but + * this is a potential source of runaway memory usage + */ + /* delete [] oldParams;*/ + } + + if (!parseFieldDescriptor(p, next, params[numParams], &next)) + return false; + + numParams++; + } + + delete [] paramstr; + } + + s += len; + + /* Parse the return descriptor */ + if (*s == 'V') { + ret.set(tkVoid); + return true; + } else { + const char *next; + return parseFieldDescriptor(p, s, ret, &next) && !*next; + } +} + + + +/* Implementation of ClassFileReader */ +bool ClassFileReader::lookupConstant(uint16 index, ValueKind &vk, + Value &value) const +{ + if (index < 1 || index >= constantPoolCount) + return false; + + /* Are we dealing with a constant that returns a value? */ + int type = constantPool[index]->getType(); + + /* index must point to a long, float, double, or integer */ + if (!((type > 2 && type < 7))) + return false; + + ConstantVal *val = (ConstantVal *) constantPool[index]; + vk = val->getValueKind(); + value = val->getValue(); + + return true; +} + +/* Index is an index into the field array */ +bool ClassFileReader::lookupStaticField(uint16 index, JavaType *&type, + addr &a, + bool &isVolatile, bool &isConstant) +{ + FieldInfo *fInfo; + + if (index >= fieldCount) + return false; + + isConstant = false; + + fInfo = fieldInfo[index]; + uint16 aFlags = fInfo->getAccessFlags(); + + if (!(aFlags & CR_FIELD_STATIC)) + return false; + + isVolatile = (aFlags & CR_FIELD_VOLATILE) != 0; + fInfo->getType(type); + a = fInfo->pos.a; + + return true; +} + +/* Index is an index into the field array */ +bool ClassFileReader::lookupInstanceField(uint16 index, JavaType *&type, + uint32 &offset, + bool &isVolatile, + bool &isConstant) +{ + FieldInfo *fInfo; + + if (index >= fieldCount) + return false; + + isConstant = false; + + fInfo = fieldInfo[index]; + uint16 aFlags = fInfo->getAccessFlags(); + + if (aFlags & CR_FIELD_STATIC) + return false; + + isVolatile = (aFlags & CR_FIELD_VOLATILE) != 0; + fInfo->getType(type); + offset = fInfo->pos.offset; + + return true; +} + +/* Index is an index into the method array */ +bool ClassFileReader::lookupMethod(uint16 index, + const JavaType *&ret, int &nParams, + const JavaType *¶mTypes, + bool &isStatic, + bool &isNative, + bool &isAbstract) +{ + if (index >= methodCount) + return false; + + ret = &methodInfo[index]->getSignature(nParams, paramTypes, isStatic, + isNative, isAbstract); + return true; +} + +#ifdef DEBUG +void ClassFileReader::dump() +{ + int i; + + print(0, "AccessFlags %x", accessFlags); + print(0, "Major Version %d, Minor Version %d", majorVersion, + minorVersion); + + print(0, "\nThis Class:"); + constantPool[thisClassIndex]->dump(0); + + if (superClassIndex > 0) { + print(0, "\nSuper Class:"); + constantPool[superClassIndex]->dump(0); + } + + print(0, "\nConstant Pool Count: %d", constantPoolCount); + for (i = 1; i < constantPoolCount; i++) { + print(0, "%d.", i); + + if (constantPool[i]) + constantPool[i]->dump(0); + else + print(0, "NULL Constant-pool entry, probably result of a previous\n" + "DOUBLE or LONG"); + } + + print(0, "\nField Count: %d", fieldCount); + for (i = 0; i < fieldCount; i++) { + print(0, "%d.", i+1); + fieldInfo[i]->dump(0); + } + + print(0, "\nInterface Count: %d", interfaceCount); + for (i = 0; i < interfaceCount; i++) { + print(0, "%d.", i+1); + interfaceInfo[i].item->dump(0); + } + + print(0, "\nMethod Count: %d", methodCount); + for (i = 0; i < methodCount; i++) { + print(0, "%d.", i+1); + methodInfo[i]->dump(0); + } + + print(0, "\nAttribute Count: %d", attributeCount); + for (i = 0; i < attributeCount; i++) { + print(0, "%d.", i+1); + attributeInfo[i]->dump(0); + } +} + +void ClassFileReader::dumpClass(char *dumpfile) +{ + /* Create file. */ + FILE *fp; + fp = fopen(dumpfile,"w"); + + /* Begin file */ + fprintf(fp,"#begin_class_file\n"); + fprintf(fp,"\n"); + + /* Magic */ + uint32 magic = 0xCAFEBABE; + fprintf(fp,"#magic\n"); + fprintf(fp,"0x%x\n",magic); + + fprintf(fp,"\n"); + + /* Minor version */ + fprintf(fp,"#minor_version\n"); + fprintf(fp,"%i\n",minorVersion); + + fprintf(fp,"\n"); + + /* Major version */ + fprintf(fp,"#major_version\n"); + fprintf(fp,"%i\n",majorVersion); + + fprintf(fp,"\n"); + + /* Output to stdout. */ + if (true) { + + /* Magic */ + printf("#magic\n"); + printf("0x%x\n",magic); + + printf("\n"); + + /* Minor version */ + printf("#minor_version\n"); + printf("%i\n",minorVersion); + + printf("\n"); + + /* Major version */ + printf("#major_version\n"); + printf("%i\n",majorVersion); + + printf("\n"); + + } + + /* Constant Pool */ + dumpConstantPool(fp); + + fprintf(fp,"\n"); + + /* Access flags */ + fprintf(fp,"#access_flags\n"); + fprintf(fp,"0x%x\n",accessFlags); + + fprintf(fp,"\n"); + + /* This class */ + fprintf(fp,"#this_class\n"); + fprintf(fp,"%i\n",thisClassIndex); + + fprintf(fp,"\n"); + + /* Super class */ + fprintf(fp,"#super_class\n"); + fprintf(fp,"%i\n",superClassIndex); + + fprintf(fp,"\n"); + + /* Output to stdout. */ + if (true) { + + printf("\n"); + + /* Access flags */ + printf("#access_flags\n"); + printf("0x%x\n",(char)accessFlags); + + printf("\n"); + + /* This class */ + printf("#this_class\n"); + printf("%i\n",thisClassIndex); + + printf("\n"); + + /* Super class */ + printf("#super_class\n"); + printf("%i\n",superClassIndex); + + printf("\n"); + + } + + /* Interfaces */ + dumpInterfaces(fp); + + fprintf(fp,"\n"); + + /* Output to stdout. */ + if (true) printf("\n"); + + /* Fields */ + dumpFields(fp); + + fprintf(fp,"\n"); + + /* Output to stdout. */ + if (true) printf("\n"); + + /* Methods */ + dumpMethods(fp); + + fprintf(fp,"\n"); + + /* Output to stdout. */ + if (true) printf("\n"); + + /* Attributes */ + dumpAttributes(fp); + + /* End class file */ + fprintf(fp,"\n"); + fprintf(fp,"#end_class_file"); + + fclose(fp); + +} + +void ClassFileReader::dumpConstantPool(FILE *fp) +{ + + fprintf(fp,"#constant_pool_count\n"); + fprintf(fp,"%i\n",constantPoolCount); + fprintf(fp,"#begin_constant_pool\n"); + + /* Entry 0 is reserved. */ + fprintf(fp,"\t#0 Reserved\n"); + + /* Output to stdout. */ + if (true) { + printf("#constant_pool_count\n"); + printf("%i\n",constantPoolCount); + printf("#begin_constant_pool\n"); + + /* Entry 0 is reserved. */ + printf("\t#0 Reserved\n"); + } + + for (int i = 1; i < constantPoolCount; i++) { + + if (constantPool[i]) { + + switch(constantPool[i]->getType()) { + + case CR_CONSTANT_UTF8: { + + ConstantUtf8 *tempUtf8 = (ConstantUtf8 *)constantPool[i]; + + fprintf(fp, "\t#%i Utf8\n",i); + fprintf(fp, "\t%s\n",tempUtf8->data); + + /* Output to stdout. */ + if (true) { + printf("\t#%i Utf8\n",i); + printf("\t%s\n",tempUtf8->data); + } + + break; + + } + + case CR_CONSTANT_INTEGER: { + + ConstantInt *tempInt = (ConstantInt *)constantPool[i]; + + fprintf(fp, "\t#%i Integer\n", i); + fprintf(fp, "\tvalue %i\n",tempInt->getValue()); + + /* Output to stdout. */ + if (true) { + printf("\t#%i Integer\n",i); + printf("\t#value %i\n",tempInt->getValue()); + } + + break; + + } + + case CR_CONSTANT_FLOAT: { + + int s,e,m; + uint32 raw; + + ConstantFloat *tempFloat = (ConstantFloat *)constantPool[i]; + raw = (uint32)tempFloat->getRaw(); + + /*Use raw to compute for s, e, and m.*/ + /*This doesn't check for +/- Infinity and Nan yet.*/ + s = ((raw >> 31) == 0) ? 1 : -1; + e = ((raw >> 23) &0xff); + m = (e == 0) ? (raw & 0x7fffff) << 1 : + (raw & 0x7fffff) | 0x800000; + + fprintf(fp, "\t#%i Float\n",i); + fprintf(fp, "\tvalue sign %i exponent %i mantissa %i\n",s,e,m); + + /* Output to stdout. */ + if (true) { + printf("\t#%i Float\n",i); + printf("\tvalue sign %i exponent %i mantissa %i\n",s,e,m); + } + + break; + + } + + case CR_CONSTANT_LONG: { + + uint32 hi,lo; + + ConstantLong *tempLong = (ConstantLong *)constantPool[i]; + tempLong->getBits(lo,hi); + + fprintf(fp, "\t#%i Long\n",i); + fprintf(fp, "\tvalue hi %i lo %i\n",hi,lo); + + /* Output to stdout. */ + if (true) { + printf("\t#%i Long\n",i); + printf("\tvalue hi %i lo %i\n",hi,lo); + } + + //Increase count. This is specified in the spec. + i++; + + break; + } + + case CR_CONSTANT_DOUBLE: { + + char* data; + + ConstantDouble *tempDouble = (ConstantDouble *)constantPool[i]; + data = tempDouble->getData(); + + fprintf(fp, "\t#%i Double\n",i); + fprintf(fp, "\tvalue "); + + /* The following will need to be fixed once we know how to handle Doubles. */ + int j; + for (j = 0; j < 8; j++) { + fprintf(fp,"%x ",data[j]); + } + fprintf(fp, "\n"); + + /* Output to stdout. */ + if (true) { + printf("\t#%i Double\n",i); + printf("\tvalue "); + for(j = 0; j < 8 ; j++) printf("%x ",data[j]); + printf("\n"); + } + + //Increase count. This is specified in the spec. + i++; + + break; + + } + + case CR_CONSTANT_CLASS: { + + ConstantClass *tempClass = (ConstantClass *)constantPool[i]; + + fprintf(fp, "\t#%i Class\n",i); + fprintf(fp, "\tindex %i\n",tempClass->index); + + /* Output to stdout. */ + if (true) { + printf("\t#%i Class\n",i); + printf("\tindex %i\n",tempClass->index); + } + + break; + + } + + case CR_CONSTANT_STRING: { + + ConstantString *tempString = (ConstantString *)constantPool[i]; + + fprintf(fp, "\t#%i String\n",i); + fprintf(fp, "\tindex %i\n",tempString->index); + + /* Output to stdout. */ + if (true) { + printf("\t#%i String\n",i); + printf("\tindex %i\n",tempString->index); + } + + break; + } + + case CR_CONSTANT_FIELDREF: { + + ConstantFieldRef *tempFieldRef = (ConstantFieldRef *)constantPool[i]; + ConstantRef *tempRef = (ConstantRef *)tempFieldRef; + + fprintf(fp, "\t#%i FieldRef\n",i); + fprintf(fp, "\tclassIndex %i typeIndex %i\n",tempRef->classIndex,tempRef->typeIndex); + + /* Output to stdout. */ + if (true) { + printf("\t#%i FieldRef\n",i); + printf("\tclassIndex %i typeIndex %i\n",tempRef->classIndex,tempRef->typeIndex); + } + + break; + + } + + case CR_CONSTANT_METHODREF: { + + ConstantMethodRef *tempMethodRef = (ConstantMethodRef *)constantPool[i]; + ConstantRef *tempRef = (ConstantRef *)tempMethodRef; + + fprintf(fp, "\t#%i MethodRef\n",i); + fprintf(fp, "\tclassIndex %i typeIndex %i\n",tempRef->classIndex,tempRef->typeIndex); + + /* Output to stdout. */ + if (true) { + printf("\t#%i MethodRef\n",i); + printf("\tclassIndex %i typeIndex %i\n",tempRef->classIndex,tempRef->typeIndex); + } + + break; + + } + + case CR_CONSTANT_INTERFACEMETHODREF: { + + + ConstantInterfaceMethodRef *tempInterfaceMethodRef = (ConstantInterfaceMethodRef *)constantPool[i]; + ConstantRef *tempRef = (ConstantRef *)tempInterfaceMethodRef; + + fprintf(fp, "\t#%i InterfaceMethodRef\n",i); + fprintf(fp, "\tclassIndex %i typeIndex %i\n",tempRef->classIndex,tempRef->typeIndex); + + /* Output to stdout. */ + if (true) { + printf("\t#%i InterfaceMethodRef\n",i); + printf("\tclassIndex %i typeIndex %i\n",tempRef->classIndex,tempRef->typeIndex); + } + + break; + + } + + case CR_CONSTANT_NAMEANDTYPE: { + + + ConstantNameAndType *tempNameAndType = (ConstantNameAndType *)constantPool[i]; + + fprintf(fp, "\t#%i NameAndType\n",i); + fprintf(fp, "\tnameIndex %i descIndex %i\n",tempNameAndType->nameIndex,tempNameAndType->descIndex); + + /* Output to stdout. */ + if (true) { + printf("\t#%i NameAndType\n",i); + printf("\tnameIndex %i descIndex %i\n",tempNameAndType->nameIndex,tempNameAndType->descIndex); + } + + break; + + } + + default: { + + printf("Error in constant pool\n"); + return; + } + + } + } + else + print(0, "NULL Constant-pool entry, probably result of a previous\n" + "DOUBLE or LONG\n"); + } + + fprintf(fp,"#end_constant_pool\n"); + + /* Output to stdout. */ + if (true) { + printf("#end_constant_pool\n"); + } + +} + +void ClassFileReader::dumpInterfaces(FILE *fp) +{ + fprintf(fp,"#interfaces_count\n"); + fprintf(fp,"%i\n",interfaceCount); + + /* Output to stdout. */ + if (true) { + printf("#interfaces_count\n"); + printf("%i\n",interfaceCount); + } + + if (interfaceCount > 0) { + + fprintf(fp,"#begin_interfaces\n"); + + /* Output to stdout. */ + if (true) printf("#begin_interfaces\n"); + + for (uint16 i = 0; i < interfaceCount; i++ ) { + + fprintf(fp,"\t#%i\n",i); + fprintf(fp,"\tindex %i\n",interfaceInfo[i].index); + + /* Output to stdout. */ + if (true) { + printf("\t#%i\n",i); + printf("\tindex %i\n",interfaceInfo[i].index); + } + } + + fprintf(fp,"#end_interfaces\n"); + + /* Output to stdout. */ + if (true) printf("#end_interfaces\n"); + + } +} + +void ClassFileReader::dumpFields(FILE *fp) +{ + fprintf(fp,"#fields_count\n"); + fprintf(fp,"%i\n",fieldCount); + + /* Output to stdout. */ + if (true) { + printf("#fields_count\n"); + printf("%i\n",fieldCount); + } + + if (fieldCount > 0) { + + fprintf(fp,"#begin_fields\n"); + + /* Output to stdout. */ + if (true) printf("#begin_fields\n"); + + for (uint16 i = 0; i < fieldCount; i++ ) { + + fprintf(fp,"\t#%i\n",i); + + /* Access flags */ + fprintf(fp,"\taccess_flags 0x%x\n",fieldInfo[i]->getAccessFlags()); + + /* Name index */ + fprintf(fp,"\tnameIndex %i descIndex %i\n",fieldInfo[i]->getNameIndex(),fieldInfo[i]->getDescIndex()); + + /* Attributes count */ + fprintf(fp,"\tattributes_count %i\n",fieldInfo[i]->getAttributeCount()); + + /* Output to stdout. */ + if (true) { + + printf("\t#%i\n",i); + + /* Access flags */ + printf("\taccess_flags 0x%x\n",fieldInfo[i]->getAccessFlags()); + + /* Name index */ + printf("\tnameIndex %i descIndex %i\n",fieldInfo[i]->getNameIndex(),fieldInfo[i]->getDescIndex()); + + /* Attributes count */ + printf("\tattributes_count %i\n",fieldInfo[i]->getAttributeCount()); + + } + + /* + * The following attribute_info loop needs to be tested. + */ + if (fieldInfo[i]->getAttributeCount() > 0) { + + fprintf(fp,"\t#begin_attributes\n"); + + /* Output to stdout. */ + if (true) printf("\t#being_attributes\n"); + + int currentCount = 0; + const DoublyLinkedList &list = fieldInfo[i]->getAttributes(); + for (DoublyLinkedList::iterator j = list.begin(); !list.done(j); j = list.advance(j)) { + + AttributeInfoItem &item = list.get(j); + + fprintf(fp,"\t\t#%i %s\n",currentCount,item.getName()); + + /* Attribute name index */ + fprintf(fp,"\t\tnameIndex %i\n",item.getNameIndex()); + + /* Attribute length */ + fprintf(fp,"\t\tlength %i\n",item.getLength()); + + /* Output to stdout. */ + if (true) { + + printf("\t\t#%i %s\n",currentCount,item.getName()); + + /* Attribute name index */ + printf("\t\tnameIndex %i\n",item.getNameIndex()); + + /* Attribute length */ + printf("\t\tlength %i\n",item.getLength()); + + } + + /* Find the correct attribute and generate the corresponding info. */ + switch (item.getCode()) { + + case CR_ATTRIBUTE_CONSTANTVALUE: { /* ConstantValue Attribute */ + + AttributeConstantValue *constVal = static_cast(&item); + fprintf(fp,"\t\tindex: %i\n",constVal->getIndex()); + + /* Output to stdout. */ + if (true) printf("\t\tindex: %i\n",constVal->getIndex()); + + break; + + } + + default: { /* Ignore everything else. */ + break; + } + + } + + currentCount++; + + } + + fprintf(fp,"\t#end_attribute_info\n"); + + /* Output to stdout. */ + if (true) printf("\t#end_attribute_info\n"); + + } + } + + fprintf(fp,"#end_fields\n"); + + /* Output to stdout. */ + if (true) printf("#end_fields\n"); + + + } + +} + +void ClassFileReader::dumpMethods(FILE *fp) { + + /* Total number of bytecodes. */ + int totalBytecodes = 0; + + fprintf(fp,"#methods_count\n"); + fprintf(fp,"%i\n",methodCount); + + /* Output to stdout. */ + if (true) { + printf("#methods_count\n"); + printf("%i\n",methodCount); + } + + if (methodCount > 0) { + + fprintf(fp,"#begin_methods\n"); + + /* Output to stdout. */ + if (true) printf("#begin_methods\n"); + + for (uint i = 0; i < methodCount; i++) { + + ConstantUtf8 *method = methodInfo[i]->getName(); + fprintf(fp,"\t#%i %s\n",i,method->getUtfString()); + fprintf(fp,"\taccess_flags %i\n",methodInfo[i]->getAccessFlags()); + fprintf(fp,"\tnameIndex %i descIndex %i\n",methodInfo[i]->getNameIndex(),methodInfo[i]->getDescIndex()); + fprintf(fp,"\tattributes_count %i\n",methodInfo[i]->getAttributeCount()); + + /* Output to stdout. */ + if (true) { + + printf("\t#%i %s\n",i,method->getUtfString()); + printf("\taccess_flags %i\n",methodInfo[i]->getAccessFlags()); + printf("\tnameIndex %i descIndex %i\n",methodInfo[i]->getNameIndex(),methodInfo[i]->getDescIndex()); + printf("\tattributes_count %i\n",methodInfo[i]->getAttributeCount()); + + } + + if (methodInfo[i]->getAttributeCount() > 0) { + + fprintf(fp,"\t#begin_attributes\n"); + + /* Output to stdout. */ + printf("\t#begin_attributes\n"); + + const DoublyLinkedList &list = methodInfo[i]->getAttributes(); + int currentCount = 0; + for (DoublyLinkedList::iterator j = list.begin(); !list.done(j); j = list.advance(j)) { + + AttributeInfoItem &item = list.get(j); + + fprintf(fp,"\t\t#%i %s\n",currentCount,item.getName()); + + /* Attribute name index */ + fprintf(fp,"\t\tnameIndex %i\n",item.getNameIndex()); + + /* Attribute length */ + fprintf(fp,"\t\tlength %i\n",item.getLength()); + + /* Output to stdout. */ + if (true) { + + printf("\t\t#%i %s\n",currentCount,item.getName()); + + /* Attribute name index */ + printf("\t\tnameIndex %i\n",item.getNameIndex()); + + /* Attribute length */ + printf("\t\tlength %i\n",item.getLength()); + + } + + /* Get the correct code and generate the corresponding info. */ + switch(item.getCode()) { + + case CR_ATTRIBUTE_CODE: { /* Code Attribute */ + + AttributeCode *code = static_cast(&item); + + /* Max stacks */ + fprintf(fp,"\t\tmax_stack %i\n",code->getMaxStack()); + + /* Max locals */ + fprintf(fp,"\t\tmax_locals %i\n",code->getMaxLocals()); + + /* Code length */ + fprintf(fp,"\t\tcode_length %i\n",code->getCodeLength()); + + /* Add to total number of bytecodes. */ + totalBytecodes = totalBytecodes + code->getCodeLength(); + + /* Bytecode */ + + const unsigned char *bytecode = (const unsigned char *)code->getCode(); + + /* Temp way for handling bytecodes. */ + int k; + + uint32 codeLength = code->getCodeLength(); + fprintf(fp,"\t\t#bytecodes "); + for ( k = 0; k < (int)codeLength; k++) { + fprintf(fp,"%x ",bytecode[k]); + } + fprintf(fp,"\n"); + + fprintf(fp,"\t\t#begin_bytecodes\n"); + disassembleBytecodes(fp,bytecode,bytecode+code->getCodeLength(),bytecode,24); + fprintf(fp,"\t\t#end_bytecodes\n"); + + /* Exception table length */ + fprintf(fp,"\t\texception_table_length %i\n",code->getNumExceptions()); + + /* Output to stdout. */ + if (true) { + + /* Max stacks */ + printf("\t\tmax_stack %i\n",code->getMaxStack()); + + /* Max locals */ + printf("\t\tmax_locals %i\n",code->getMaxLocals()); + + /* Code length */ + printf("\t\tcode_length %i\n",code->getCodeLength()); + + /* Temp way for handling bytecodes. */ + printf("\t\t#bytecodes "); + for ( k = 0; k < (int)codeLength; k++) { + printf("%x ",bytecode[k]); + } + printf("\n"); + + /* Bytecode */ + printf("\t\t#begin_bytecodes\n"); + disassembleBytecodes(stdout,bytecode,bytecode+code->getCodeLength(),bytecode,24); + printf("\t\t#end_bytecodes\n"); + + /* Exception table length */ + printf("\t\texception_table_length %i\n",code->getNumExceptions()); + + } + + /* + * The following Exception_Table loop needs to be tested. + */ + if (code->getNumExceptions() > 0) { + + ExceptionItem **exceptionItem = code->getExceptions(); + + fprintf(fp,"\t\t#begin_exception_table\n"); + + /* Output to stdout. */ + if (true) printf("\t\t#begin_exception_table\n"); + + for ( k = 0; k < (int)code->getNumExceptions(); k++) { + + + fprintf(fp,"\t\t\t#%i\n", k); + + /* Start/End pc */ + fprintf(fp,"\t\t\tstart_pc %i end_pc %i\n",exceptionItem[k]->getStartPc(),exceptionItem[k]->getEndPc); + + /* Handler pc */ + fprintf(fp,"\t\t\thandler_pc %i\n",exceptionItem[k]->getHandlerPc()); + + /* Catcher type */ + fprintf(fp,"\t\t\tcatch_type %i\n",exceptionItem[k]->getCatcherIndex()); + + /* Output to stdout. */ + if (true) { + + printf("\t\t\t#%i\n",k); + + /* Start/End pc */ + printf("\t\t\tstart_pc %i end_pc %i\n",exceptionItem[k]->getStartPc(),exceptionItem[k]->getEndPc); + + /* Handler pc */ + printf("\t\t\thandler_pc %i\n",exceptionItem[k]->getHandlerPc()); + + /* Catcher type */ + printf("\t\t\tcatch_type %i\n",exceptionItem[k]->getCatcherIndex()); + + } + + } + + fprintf(fp,"\t\t#end_excpetion_table\n"); + + /* Output to stdout. */ + if (true) printf("\t\t#end_exception_table\n"); + + } + + /* Attributes count */ + fprintf(fp,"\t\tattributes_count %i\n",code->getNumAttributes()); + + /* Output to stdout. */ + if (true) printf("\t\tattributes_count %i\n",code->getNumAttributes()); + + if (code->getNumAttributes() > 0) { + + fprintf(fp,"\t\t#begin_attributes\n"); + + /* Output to stdout. */ + if (true) printf("\t\t#begin_attributes\n"); + + AttributeInfoItem **attributes = code->getAttributes(); + for (uint16 l = 0; l < code->getNumAttributes(); l++) { + + fprintf(fp,"\t\t\t#%i %s\n",l,attributes[l]->getName()); + + /* Attribute name index */ + fprintf(fp,"\t\t\tnameIndex %i\n",attributes[l]->getNameIndex()); + + /* Attribute length */ + fprintf(fp,"\t\t\tlength %i\n",attributes[l]->getLength()); + + /* Output to stdout. */ + if (true) { + + printf("\t\t\t#%i %s\n",l,attributes[l]->getName()); + + /* Attribute name index */ + printf("\t\t\tnameIndex %i\n",attributes[l]->getNameIndex()); + + /* Attribute length */ + printf("\t\t\tlength %i\n",attributes[l]->getLength()); + + } + + /* Get the correct code and generate the corresponding attribute. */ + switch(attributes[l]->getCode()) { + + case CR_ATTRIBUTE_LINENUMBERTABLE: { /* LineNumberTable Attribute */ + + AttributeLineNumberTable *lineNoTable = (AttributeLineNumberTable*)attributes[l]; + + /* Line number table length */ + fprintf(fp,"\t\t\ttable_length %i\n",lineNoTable->getNumEntries()); + + /* Output to stdout. */ + if (true) { + /* Line number table length */ + printf("\t\t\ttable_length %i\n",lineNoTable->getNumEntries()); + } + + if (lineNoTable->getNumEntries() > 0) { + + LineNumberEntry *lineNoEntry = lineNoTable->getEntries(); + + fprintf(fp,"\t\t\t#begin_line_number_table\n"); + + /* Output to stdout. */ + if (true) printf("\t\t\t#begin_line_number_table\n"); + + for(uint16 m = 0; m < lineNoTable->getNumEntries(); m++) { + + fprintf(fp,"\t\t\t\t#%i\n",m); + + /* Start pc */ + fprintf(fp,"\t\t\t\tstart_pc %i\n",lineNoEntry[m].startPc); + + /* Line number */ + fprintf(fp,"\t\t\t\tline_number %i\n",lineNoEntry[m].lineNumber); + + /* Output to stdout. */ + if (true) { + + printf("\t\t\t\t#%i\n",m); + + /* Start pc */ + printf("\t\t\t\tstart_pc %i\n",lineNoEntry[m].startPc); + + /* Line number */ + printf("\t\t\t\tline_number %i\n",lineNoEntry[m].lineNumber); + + } + + } + + fprintf(fp,"\t\t\t#end_line_number_table\n"); + + /* Output to stdout. */ + if (true) printf("\t\t\t#end_line_number_table\n"); + + } + + break; + + } + + /* + * The LocalVariableTable case needs to be tested. + */ + case CR_ATTRIBUTE_LOCALVARIABLETABLE: { /* LocalVariableTable */ + + AttributeLocalVariableTable *localVariableTable = (AttributeLocalVariableTable*)attributes[l]; + + /* Local variable table length */ + fprintf(fp,"\t\t\ttable_length %i\n",localVariableTable->getNumEntries()); + + /* Output to stdout. */ + if (true) { + /* Local variable table length */ + printf("\t\t\ttable_length %i\n",localVariableTable->getNumEntries()); + } + + if(localVariableTable->getNumEntries() > 0) { + + fprintf(fp,"\t\t\t#begin_local_variable_table\n"); + + /* Output to stdout. */ + if (true) printf("\t\t\t#begin_local_variable_table\n"); + + LocalVariableEntry *localVarEntry = localVariableTable->getEntries(); + + for (uint16 m = 0; m < localVariableTable->getNumEntries(); m++) { + + fprintf(fp,"\t\t\t\t#%i\n",m); + + /* Start pc */ + fprintf(fp,"\t\t\t\tstart_pc %i\n",localVarEntry[m].startPc); + + /* Length */ + fprintf(fp,"\t\t\t\tlength %i\n",localVarEntry[m].length); + + /* Name index */ + fprintf(fp,"\t\t\t\tnameIndex %i\n",localVarEntry[m].nameIndex); + + /* Description index */ + fprintf(fp,"\t\t\t\tdescIndex %i\n",localVarEntry[m].descIndex); + + /* Index */ + fprintf(fp,"\t\t\t\tindex %i\n",localVarEntry[m].index); + + /* Output to stdout. */ + if (true) { + + printf("\t\t\t\t#%i\n",m); + + /* Start pc */ + printf("\t\t\t\tstartPc %i\n",localVarEntry[m].startPc); + + /* Length */ + printf("\t\t\t\tlength %i\n",localVarEntry[m].length); + + /* Name index */ + printf("\t\t\t\tnameIndex %i\n",localVarEntry[m].nameIndex); + + /* Description index */ + printf("\t\t\t\tdescIndex %i\n",localVarEntry[m].descIndex); + + /* Index */ + printf("\t\t\t\tindex %i\n",localVarEntry[m].index); + + } + + } + + fprintf(fp,"\t\t\t#end_local_variable_table\n"); + + /* Output to stdout. */ + if (true) printf("\t\t\t#end_local_variable_table\n"); + + } + + } + + default: { /* Ignore everything else. */ + break; + } + + } + + } + + fprintf(fp,"\t\t#end_attributes\n"); + + /* Output to stdout. */ + if (true) printf("\t\t#end_attributes\n"); + + } + + break; + + } + + /* + * The following Exceptions case needs to be tested. + */ + case CR_ATTRIBUTE_EXCEPTIONS: { /* Exceptions Attribute */ + + AttributeExceptions *exceptions = static_cast(&item); + + /* Number of exceptions */ + fprintf(fp,"\t\texceptions_count %i\n",exceptions->getNumExceptions()); + + /* Output to stdout. */ + if (true) { + /* Number of exceptions */ + fprintf(fp,"\t\texceptions_count %i\n",exceptions->getNumExceptions()); + } + + if (exceptions->getNumExceptions() > 0) { + + fprintf(fp,"\t\t#begin_exception_index_table\n"); + + /* Output to stdout. */ + if (true) printf("\t\t#begin_exception_index_table\n"); + + uint16 *indices = exceptions->getExcIndices(); + for (uint16 k = 0; k < exceptions->getNumExceptions(); k++) { + + fprintf(fp,"\t\t\t#%i\n",k); + + /* Index */ + fprintf(fp,"\t\t\tindex %i\n",indices[k]); + + /* Output to stdout. */ + if (true) { + fprintf(fp,"\t\t\t#%i\n",k); + + /* Index */ + fprintf(fp,"\t\t\tindex %i\n",indices[k]); + } + + } + + fprintf(fp,"\t\t#end_exception_index_table\n"); + + /* Output to stdout. */ + if (true) printf("\t\t#end_exception_index_table\n"); + + } + + break; + + } + + default: { /* Ignore everything else. */ + break; + } + + } + + currentCount++; + + } + + fprintf(fp,"\t#end_attributes\n"); + + /* Output to stdout. */ + printf("\t#end_attributes\n"); + + } + + } + + fprintf(fp,"#end_methods\n"); + + /* Output to stdout. */ + if (true) printf("#end_methods\n"); + + } + + printf("TOTAL NUMBER OF BYTECODES: %i", totalBytecodes); + +} + +void ClassFileReader::dumpAttributes(FILE *fp) { + + fprintf(fp,"#attributes_count\n"); + fprintf(fp,"%i\n",attributeCount); + + /* Output to stdout. */ + if (true) { + printf("#attributes_count\n"); + printf("%i\n",attributeCount); + } + + if (attributeCount > 0) { + + fprintf(fp,"#begin_attributes\n"); + + /* Output to stdout. */ + if (true) printf("#begin_attributes\n"); + + for(uint i = 0; i < attributeCount; i++ ) { + + fprintf(fp,"\t#%i %s\n",i,attributeInfo[i]->getName()); + + /* Attribute name index */ + fprintf(fp,"\tnameIndex %i\n",attributeInfo[i]->getNameIndex()); + + /* Attribute length */ + fprintf(fp,"\tlength %i\n",attributeInfo[i]->getLength()); + + /* Output to stdout. */ + if (true) { + + printf("\t#%i %s\n",i,attributeInfo[i]->getName()); + + /* Attribute name index */ + printf("\tnameIndex %i\n",attributeInfo[i]->getNameIndex()); + + /* Attribute length */ + printf("\tlength %i\n",attributeInfo[i]->getLength()); + + } + + /* Get the correct code and generate the corresponding attribute. */ + switch(attributeInfo[i]->getCode()) { + + case CR_ATTRIBUTE_SOURCEFILE: { /* SourceFile Attribute */ + + AttributeSourceFile *srcFile = (AttributeSourceFile*)attributeInfo[i]; + + fprintf(fp,"\tindex %i\n",srcFile->getIndex()); + + /* Output to stdout. */ + printf("\tindex %i\n",srcFile->getIndex()); + + break; + + } + + default: { /* Ignore everything else. */ + break; + } + + } + } + + fprintf(fp,"#end_attributes\n"); + + /* Output to stdout. */ + if (true) printf("#end_attributes\n"); + + } +} + +#endif + +#define CR_BUFFER_SIZE 16184 + + +#define JAVA_MAGIC 0xCAFEBABE + +CrError ClassFileReader::readConstantPool() +{ + uint16 cIndex, tIndex; + uint16 index; + uint32 low, high; + int i; + constantPool[0] = 0; + + for (i = 1; i < constantPoolCount; i++) { + char tag; + + if (!fr->readU1(&tag, 1)) { + return crErrorIO; + } + + switch (tag) { + case CR_CONSTANT_UTF8: { + uint16 len; + + if (!fr->readU2(&len, 1)) { + return crErrorIO; + } + + ConstantUtf8 *utf = new (p) ConstantUtf8(p, len); + char *buf = new char[len+1]; + fr->readU1(buf, len); + buf[len] = 0; + + /* Do we intern all strings that we get, or just class names? */ + utf->data = sp.intern(buf); + delete buf; + + constantPool[i] = utf; + break; + } + + case CR_CONSTANT_INTEGER: { + int32 val; + + + if (!fr->readU4((uint32 *) &val, 1)) { + return crErrorIO; + } + + constantPool[i] = new (p) ConstantInt(p, val); + break; + } + + case CR_CONSTANT_FLOAT: { + uint32 raw; + + if (!fr->readU4(&raw, 1)) { + return crErrorIO; + } + + constantPool[i] = new (p) ConstantFloat(p, raw); + break; + } + + case CR_CONSTANT_LONG: + if (!fr->readU4(&high, 1)) { + return crErrorIO; + } + + if (!fr->readU4(&low, 1)) { + return crErrorIO; + } + + constantPool[i] = new (p) ConstantLong(p, low, high); + constantPool[i+1] = 0; + + /* Longs and doubles take up two constant-pool entries */ + i++; + break; + + case CR_CONSTANT_DOUBLE: { + char buf[8]; + + if (!fr->readU1(buf, 8)) { + return crErrorIO; + } + + constantPool[i] = new (p) ConstantDouble(p, buf); + constantPool[i+1] = 0; + + /* Longs and doubles take up two constant-pool entries */ + i++; + break; + } + + case CR_CONSTANT_CLASS: + if (!fr->readU2(&index, 1)) { +#ifdef DEBUG + print(0, "CR_CONSTANT_CLASS: Cannot read index\n"); +#endif + return crErrorIO; + } + + if (invalidIndex(index)) { +#ifdef DEBUG + print(0, "CR_CONSTANT_CLASS: Invalid index %d\n", index); +#endif + return crErrorInvalidConstant; + } + + constantPool[i] = new (p) ConstantClass(p, constantPool, index); + break; + + case CR_CONSTANT_STRING: + if (!fr->readU2(&index, 1)) { + return crErrorIO; + } + + if (invalidIndex(index)) { +#ifdef DEBUG + print(0, "CR_CONSTANT_STRING: Invalid index %d\n", index); +#endif + return crErrorInvalidConstant; + } + + constantPool[i] = new (p) ConstantString(p, constantPool, index); + break; + + + case CR_CONSTANT_FIELDREF: + if (!fr->readU2(&cIndex, 1)) { + return crErrorIO; + } + + if (!fr->readU2(&tIndex, 1)) { + return crErrorIO; + } + + if (invalidIndex(cIndex) || invalidIndex(tIndex)) { +#ifdef DEBUG + print(0, "CR_CONSTANT_FIELDREF: Invalid indices %d %d\n", + cIndex, tIndex); +#endif + return crErrorInvalidConstant; + } + + constantPool[i] = new (p) ConstantFieldRef(p, constantPool, + cIndex, tIndex); + break; + + case CR_CONSTANT_METHODREF: + if (!fr->readU2(&cIndex, 1)) { + return crErrorIO; + } + + if (!fr->readU2(&tIndex, 1)) { + return crErrorIO; + } + + if (invalidIndex(cIndex) || invalidIndex(tIndex)) { +#ifdef DEBUG + print(0, "CR_CONSTANT_METHODREF: Invalid indices %d %d\n", + cIndex, tIndex); +#endif + return crErrorInvalidConstant; + } + + constantPool[i] = new (p) ConstantMethodRef(p, constantPool, + cIndex, tIndex); + break; + + case CR_CONSTANT_INTERFACEMETHODREF: + if (!fr->readU2(&cIndex, 1)) { + return crErrorIO; + } + + if (!fr->readU2(&tIndex, 1)) { + return crErrorIO; + } + + if (invalidIndex(cIndex) || invalidIndex(tIndex)) { +#ifdef DEBUG + print(0, "CR_CONSTANT_INTERFACEMETHODREF: Invalid indices %d %d\n", + cIndex, tIndex); +#endif + return crErrorInvalidConstant; + } + + constantPool[i] = new (p) ConstantInterfaceMethodRef(p, constantPool, + cIndex, tIndex); + break; + + case CR_CONSTANT_NAMEANDTYPE: { + uint16 nIndex, dIndex; + + if (!fr->readU2(&nIndex, 1)) { + return crErrorIO; + } + + if (!fr->readU2(&dIndex, 1)) { + return crErrorIO; + } + + if (invalidIndex(nIndex) || invalidIndex(dIndex)) { +#ifdef DEBUG + print(0, "CR_CONSTANT_NAMEANDTYPE: Invalid indices %d %d\n", + nIndex, dIndex); +#endif + + return crErrorInvalidConstant; + } + + constantPool[i] = new (p) ConstantNameAndType(p, constantPool, + nIndex, dIndex); + + break; + } + + default: +#ifdef DEBUG + print(0, "UNKNOWN constant type %d\n", tag); +#endif + + return crErrorUnknownConstantType; + } + } + + for (i = 1; i < constantPoolCount; i++) + if (constantPool[i] && + !constantPool[i]->resolveAndValidate()) { +#ifdef DEBUG + print(0, "Cannot resolveAndValidate entry #%d\n", i); +#endif + + return crErrorInvalidConstant; + } + + return crErrorNone; +} + +CrError ClassFileReader::readInterfaces() +{ + for (int i = 0; i < interfaceCount; i++) { + uint16 index; + + if (!fr->readU2(&index, 1)) + return crErrorIO; + + if (invalidIndex(index)) + return crErrorInvalidInterface; + + interfaceInfo[i].item = constantPool[index]; + interfaceInfo[i].index = index; + } + + return crErrorNone; +} + + +AttributeInfoItem *ClassFileReader::readAttribute(CrError *status) +{ + uint16 nameIndex; + AttributeInfoItem *item; + ConstantUtf8 *utf8; + + *status = crErrorNone; + + if (!fr->readU2(&nameIndex, 1)) { + *status = crErrorIO; + return 0; + } + + /* Do we want to read the rest here to recover? */ + if (invalidIndex(nameIndex)) { +#ifdef DEBUG + print(0, "ClassFileReader::readAttribute(): Invalid Name Index (%d)\n", + nameIndex); +#endif + + *status = crErrorInvalidConstant; + return 0; + } + + if (constantPool[nameIndex]->getType() != CR_CONSTANT_UTF8) { +#ifdef DEBUG + print(0, "ClassFileReader::readAttribute(): Invalid Type(%d, %d)\n", + nameIndex, constantPool[nameIndex]->getType()); +#endif + + *status = crErrorInvalidConstant; + return 0; + } + + utf8 = (ConstantUtf8 *) constantPool[nameIndex]; + + + for (int i = 0; i < numAttrHandlers; i++) + if ((item = attrHandlers[i]->handle(utf8->getUtfString(), nameIndex, status)) != 0 && + *status == crErrorNone) + return item; + else if (*status != crErrorNone) { +#ifdef DEBUG + print(0, "Error trying to read attribute (%s); Current handler (%s)\n", + utf8->getUtfString(), attrHandlers[i]->getName()); +#endif + return 0; + } + +#ifdef DEBUG + print(0, "Cannot find a handler for attribute (%s)\n", + utf8->getUtfString()); +#endif + + *status = crErrorInvalidAttribute; + + return 0; +} + +#define ALIGN(size,mod) ((size)+(((size)%(mod)) ? ((mod)-((size)%(mod))) : 0)) + +CrError ClassFileReader::readInfoItems(int count, InfoItem **info, int field) +{ + uint32 offset = 4; /* Offset of first field is 4 */ + CrError def = (field) ? crErrorInvalidField : crErrorInvalidMethod; + + for (int i = 0; i < count; i++) { + uint16 aFlags, nameIndex, descIndex, attrCount; + + if (!fr->readU2(&aFlags, 1)) + return crErrorIO; + + if (!fr->readU2(&nameIndex, 1)) + return crErrorIO; + + if (invalidIndex(nameIndex)) { +#ifdef DEBUG + print(0, "(%d): Invalid name index %d\n", i, nameIndex); +#endif + + return def; + } + + if (!fr->readU2(&descIndex, 1)) + return crErrorIO; + + if (invalidIndex(descIndex)) { +#ifdef DEBUG + print(0, "(%d): Invalid desc index %d\n", i, descIndex); +#endif + + return def; + } + + if (!fr->readU2(&attrCount, 1)) + return crErrorIO; + + if (constantPool[nameIndex]->getType() != CR_CONSTANT_UTF8 || + constantPool[descIndex]->getType() != CR_CONSTANT_UTF8) { +#ifdef DEBUG + print(0, "Invalid type for indices name (%d, %d) or desc (%d, %d)\n", + nameIndex, constantPool[nameIndex]->getType(), + descIndex, constantPool[descIndex]->getType()); +#endif + + return def; + } + + if (field) { + FieldInfo *fInfo; + ConstantUtf8 *desc = (ConstantUtf8 *) constantPool[descIndex]; + + fInfo = new (p) FieldInfo(p, aFlags, + (ConstantUtf8 *) constantPool[thisClassIndex], + (ConstantUtf8 *) constantPool[nameIndex], + desc, nameIndex, descIndex); + + JavaType *type; + fInfo->getType(type); + + const char *next; + if (!parseFieldDescriptor(p, desc->getUtfString(), *type, &next) || + *next) { +#ifdef DEBUG + print(0, "Cannot parse field descriptor for field %s\n", + ((ConstantUtf8 *) constantPool[nameIndex])->getUtfString()); +#endif + return crErrorInvalidField; + } + + if (!(aFlags & CR_FIELD_STATIC)) { + fInfo->pos.offset = offset; + + offset += getJavaSize(type); + offset = ALIGN(offset, CR_ALIGNMENT); + + } else { + int size = getJavaSize(type); + + fInfo->pos.a = objectAddress((obj)(new(p) char[size])); + } + + info[i] = (InfoItem *) fInfo; + } else { + MethodInfo *mInfo; + ConstantUtf8 *desc = (ConstantUtf8 *) constantPool[descIndex]; + + mInfo = new (p) MethodInfo(p, aFlags, + ((ConstantClass *) constantPool[thisClassIndex])->getUtf(), + (ConstantUtf8 *) constantPool[nameIndex], + (ConstantUtf8 *) constantPool[descIndex], + nameIndex, descIndex); + +#if 0 + printf("Method %s\n", ((ConstantUtf8 *) constantPool[nameIndex])->getUtfString()); +#endif + + if (!mInfo->parseMethodDescriptor(desc->getUtfString())) { +#ifdef DEBUG + print(0, "Cannot parse method descriptor for field %s\n", + ((ConstantUtf8 *) constantPool[nameIndex])->getUtfString()); +#endif + return crErrorInvalidMethod; + } + + info[i] = mInfo; + } + + for (int j = 0; j < attrCount; j++) { + CrError status; + AttributeInfoItem *attr = readAttribute(&status); + + if (attr) + info[i]->addAttribute(*attr); + else { +#ifdef DEBUG + print(0, "Cannot add attribute to InfoItem (%d)\n", i); +#endif + info[i] = 0; + return crErrorIO; + } + } + } + + if (field) + objSize = offset; + + return crErrorNone; +} + +CrError ClassFileReader::readMethods() +{ + return readInfoItems(methodCount, (InfoItem **) methodInfo, false); +} + +CrError ClassFileReader::readFields() +{ + return readInfoItems(fieldCount, (InfoItem **) fieldInfo, true); +} + + +CrError ClassFileReader::readAttributes(AttributeInfoItem **attrInfo, + int attrCount) +{ + CrError status; + + for (int i = 0; i < attrCount; i++) + if (!(attrInfo[i] = readAttribute(&status))) + return status; + + return crErrorNone; +} + + +ClassFileReader::ClassFileReader(Pool &pool, StringPool &strPool, + const char *fileName, + CrError *status) : + p(pool), sp(strPool) +{ + if (!fileName) { + *status = crErrorNone; + return; + } + + int st; + fr = new (p) FileReader(p, fileName, &st); + + if (st != 0) { + *status = crErrorFileNotFound; + return; + } + + uint32 magic; + + objSize = 0; + methodInfo = 0; + methodCount = 0; + constantPool = 0, interfaceInfo = 0, fieldInfo = 0, + attributeInfo = 0; + + constantPoolCount = 0, interfaceCount = 0, fieldCount = 0, + attributeCount = 0; + + numAttrHandlers = 0; + attrSize = 10; + attrHandlers = new (p) AttributeHandler *[attrSize]; + + if (!fr) { + *status = crErrorNoMem; + return; + } + + if (!fr->readU4(&magic, 1)) { + *status = crErrorIO; + return; + } + + if (magic != JAVA_MAGIC) { + *status = crErrorInvalidFileType; + return; + } + + /* get the version numbers */ + if (!fr->readU2(&minorVersion, 1) || !fr->readU2(&majorVersion, 1)) { + *status = crErrorIO; + return; + } + + /* Constant pool count */ + if (!fr->readU2(&constantPoolCount, 1)) { + *status = crErrorIO; + return; + } + + constantPool = new (p) ConstantPoolItem *[constantPoolCount]; + + /* Parse the constant pool */ + if ((*status = readConstantPool()) != 0) + return; + + /* Register attribute handlers for all attributes that we can + * handle + */ + addAttrHandler(new (p) AttributeHandlerSourceFile(p, fr, this)); + addAttrHandler(new (p) AttributeHandlerConstantValue(p, fr, this)); + addAttrHandler(new (p) AttributeHandlerCode(p, fr, this)); + addAttrHandler(new (p) AttributeHandlerExceptions(p, fr, this)); + addAttrHandler(new (p) AttributeHandlerLineNumberTable(p, fr, this)); + addAttrHandler(new (p) AttributeHandlerLocalVariableTable(p, fr, this)); + + /* This must always be added after everything else, since it handles + * all attributes that we know nothing about + */ + addAttrHandler(new (p) AttributeHandlerDummy(p, fr, this)); + + /* Access Flags */ + if (!fr->readU2(&accessFlags, 1)) { + *status = crErrorIO; + return; + } + + /* This Class, super Class */ + if (!fr->readU2(&thisClassIndex, 1)) { + *status = crErrorIO; + return; + } + + if (!fr->readU2(&superClassIndex, 1)) { + *status = crErrorIO; + return; + } + + if (invalidIndex(thisClassIndex)) { + *status = crErrorNoClass; + return; + } + + if (superClassIndex > 0 && invalidIndex(superClassIndex)) { + *status = crErrorNoSuperClass; + return; + } + + if (constantPool[thisClassIndex]->getType() != CR_CONSTANT_CLASS) { + *status = crErrorNoClass; + return; + } + + /* If we don't have a super-class, we must be java/lang/Object */ + if (superClassIndex < 1) { +#ifdef NO_NSPR + if (strcmp(((ConstantClass *)constantPool[thisClassIndex])->getUtf()->getUtfString(), "java/lang/Object") != 0) { +#else + if (PL_strcmp(((ConstantClass *)constantPool[thisClassIndex])->getUtf()->getUtfString(), "java/lang/Object") != 0) { +#endif + *status = crErrorNoSuperClass; + return; + } + } else { + if (constantPool[superClassIndex]->getType() != CR_CONSTANT_CLASS) { + *status = crErrorNoClass; + return; + } + } + + /* Interfaces */ + if (!fr->readU2(&interfaceCount, 1)) { + *status = crErrorIO; + return; + } + + if (interfaceCount > 0) { + interfaceInfo = new (p) InterfaceInfo[interfaceCount]; + + if ((*status = readInterfaces()) != 0) + return; + + } else + interfaceInfo = 0; + + /* Fields */ + if (!fr->readU2(&fieldCount, 1)) { + *status = crErrorIO; + return; + } + + if (fieldCount > 0) { + fieldInfo = new (p) FieldInfo *[fieldCount]; + + if ((*status = readFields()) != 0) + return; + } else { + fieldInfo = 0; + objSize = 4; + } + + /* Methods */ + if (!fr->readU2(&methodCount, 1)) { + *status = crErrorIO; + return; + } + + if (methodCount > 0) { + methodInfo = new (p) MethodInfo *[methodCount]; + memset(methodInfo, 0, sizeof(MethodInfo *)*methodCount); + + if ((*status = readMethods()) != 0) + return; + } else + methodInfo = 0; + + /* Attributes */ + if (!fr->readU2(&attributeCount, 1)) { + attributeCount = 0; + *status = crErrorIO; + return; + } + + if (attributeCount > 0) { + attributeInfo = new (p) AttributeInfoItem *[attributeCount]; + + if ((*status = readAttributes(attributeInfo, attributeCount)) != 0) + return; + } else + attributeInfo = 0; + + /* At this point, we must be at the end of the file....*/ +#if 1 + char dummy; + if (fr->readU1(&dummy, 1)) + *status = crErrorSpuriousBytes; + else { + /* Success... */ + *status = crErrorNone; + } +#else + *status = crErrorNone; +#endif +} + +void ClassFileReader::addAttrHandler(AttributeHandler *handler) +{ + if (numAttrHandlers+1 > attrSize) { + AttributeHandler **oldAttrHandlers = attrHandlers; + attrSize += 5; + attrHandlers = new (p) AttributeHandler *[attrSize]; + + for (int i = 0; i < numAttrHandlers; i++) + attrHandlers[i] = oldAttrHandlers[i]; + } + + attrHandlers[numAttrHandlers++] = handler; +} + +bool ClassFileReader::lookupConstant(const char *name, const char *typeStr, + uint8 type, + uint16 &index) const +{ + /* Get interned versions of the name and type string */ + const char *namei = sp.get(name); + const char *typeStri = sp.get(typeStr); + + for (int i = 1; i < constantPoolCount; i++) { + if (constantPool[i] && + constantPool[i]->getType() == type) { + switch (type) { + case CR_CONSTANT_METHODREF: + case CR_CONSTANT_INTERFACEMETHODREF: + case CR_CONSTANT_FIELDREF: { + ConstantNameAndType *ninfo = ((ConstantRef *) constantPool[i])->getTypeInfo(); + ConstantUtf8 *nameUtf = ninfo->getName(); + ConstantUtf8 *typeUtf = ninfo->getDesc(); + + if (nameUtf->getUtfString() == namei && + typeUtf->getUtfString() == typeStri) { + index = i; + return true; + } + + break; + } + + default: + /* If we're here, we don't yet support "type" */ + return false; + } + } + } + + return false; +} + + diff --git a/ef/Utilities/qa/constantpool/ClassReader.h b/ef/Utilities/qa/constantpool/ClassReader.h new file mode 100644 index 000000000000..cb76abba933d --- /dev/null +++ b/ef/Utilities/qa/constantpool/ClassReader.h @@ -0,0 +1,252 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#ifndef _EF_ClassFileReader_H_ +#define _EF_ClassFileReader_H_ + +#include +#include +#include +#include + +#include "ConstantPool.h" +#include "Attributes.h" +#include "InfoItem.h" +#include "Pool.h" +#include "StringPool.h" +#include "FileReader.h" + +#define CR_ALIGNMENT 4 + +class ClassFileReader; +class FileReader; +class AttributeHandler; +class AttributeHandlerCode; + +/* Class access flags */ +#define CR_ACC_PUBLIC 0x0001 +#define CR_ACC_FINAL 0x0010 +#define CR_ACC_SUPER 0x0020 +#define CR_ACC_INTERFACE 0x0200 +#define CR_ACC_ABSTRACT 0x0400 + +struct InterfaceInfo { + ConstantPoolItem *item; + uint16 index; +}; + +/* Reads and parses a class file */ +class ClassFileReader { +friend class AttributeHandlerCode; + +public: + /* returns crErrorNone on success, appropriate error status otherwise */ + ClassFileReader(Pool &p, StringPool &sp, const char *classFileName, + CrError *status); + + ~ClassFileReader() { fr->FileReader::~FileReader(); } + + uint16 getMinorVersion() { + return minorVersion; + } + + uint16 getMajorVersion() { + return majorVersion; + } + + uint16 getAccessFlags() { + return accessFlags; + } + + /* returns a pointer to the class/interface described by the class file */ + ConstantClass *getThisClass() { + return (ConstantClass *) constantPool[thisClassIndex]; + } + + /* returns an index into the constant pool rather than a pointer to + * the class itself + */ + int getThisClassIndex() { + return thisClassIndex; + } + + /* returns a pointer to the super-class */ + ConstantClass *getSuperClass() { + return (superClassIndex > 0) ? (ConstantClass *) + constantPool[superClassIndex] : 0; + } + + /* returns an index into the constant pool table that points to the + * superclass; index is zero if there is no superclass + */ + int getSuperClassIndex() { + return superClassIndex; + } + + /* Return total space taken up by all instance fields in this object */ + int getObjSize() { + return objSize; + } + + /* Constant pool table */ + const ConstantPoolItem **getConstantPool() { + return (const ConstantPoolItem **) constantPool; + } + + uint16 getConstantPoolCount() { + return constantPoolCount; + } + + /* Interface table */ + const InterfaceInfo *getInterfaceInfo() { + return (const InterfaceInfo *) interfaceInfo; + } + + uint16 getInterfaceCount() { + return interfaceCount; + } + + /* Field table */ + const FieldInfo **getFieldInfo() { + return (const FieldInfo **) fieldInfo; + } + + uint16 getFieldCount() { + return fieldCount; + } + + /* Method table */ + const MethodInfo **getMethodInfo() { + return (const MethodInfo **) methodInfo; + } + + uint16 getMethodCount() { + return methodCount; + } + + /* Attribute table */ + const AttributeInfoItem **getAttributeInfo() { + return (const AttributeInfoItem **) attributeInfo; + } + + uint16 getAttributeCount() { + return attributeCount; + } + + bool lookupConstant(uint16 index, ValueKind &vk, Value &value) const; + + /* Look up name "name" in the constant-pool of this + * class. If there is a constant of that name in the + * constant pool of this class whose type is "type", and + * whose type descriptor matches the string typeStr, + * return true and return the index of that item via "index". + * Else, return false + * + */ + bool lookupConstant(const char *name, const char *typeStr, + uint8 type, uint16 &index) const; + + /* Convenience functions */ + + /* Looks up a static field. If this method sets isConstant to true, + * it guarantees that the field will never change value from its + * current value (currently in memory at a). + * Index is an index into the constant pool of the class + */ + bool lookupStaticField(uint16 index, JavaType *&type, addr &a, + bool &isVolatile, bool &isConstant); + + /* Looks up an instance field. If this method sets isConstant to true, + * it guarantees that the field will never change value from its + * current value. + * Index is an index into the constant pool of the class + */ + bool lookupInstanceField(uint16 index, JavaType *&type, uint32 &offset, + bool &isVolatile, bool &isConstant); + + /* Looks up a method, and returns its signature and type. + * Index is an index into the constant pool of the class + */ + bool lookupMethod(uint16 index, const JavaType *&ret, + int &nParams, const JavaType *¶mTypes, + bool &isStatic, bool &isNative, bool &isAbstract); + +#ifdef DEBUG + void dump(); + void dumpClass(char *dumpfile); + void dumpConstantPool(FILE *fp); + void dumpInterfaces(FILE *fp); + void dumpFields(FILE *fp); + void dumpMethods(FILE *fp); + void dumpAttributes(FILE *fp); +#endif + +private: + uint16 minorVersion, majorVersion; + uint16 accessFlags; + uint32 objSize; + + uint16 thisClassIndex, superClassIndex; + + ConstantPoolItem **constantPool; + uint16 constantPoolCount; + + InterfaceInfo *interfaceInfo; + uint16 interfaceCount; + + FieldInfo **fieldInfo; + uint16 fieldCount; + + AttributeInfoItem **attributeInfo; + uint16 attributeCount; + + MethodInfo **methodInfo; + uint16 methodCount; + + class FileReader *fr; + CrError readConstantPool(); + CrError readInterfaces(); + CrError readMethods(); + CrError readAttributes(AttributeInfoItem **attrInfo, + int attrCount); + CrError readFields(); + + CrError readInfoItems(int count, InfoItem **info, int field); + + /* Read one attribute from the current position in the file */ + AttributeInfoItem *readAttribute(CrError *status); + + AttributeHandler **attrHandlers; + int numAttrHandlers; + int attrSize; + + void addAttrHandler(AttributeHandler *handler); + + bool invalidIndex(int index) { + return (index < 1 || index >= constantPoolCount); + } + + Pool &p; + StringPool &sp; +}; + + +#endif /* _EF_ClassFileReader_H_ */ + + + diff --git a/ef/Utilities/qa/constantpool/ClassWorld.h b/ef/Utilities/qa/constantpool/ClassWorld.h new file mode 100644 index 000000000000..8b089f5941e7 --- /dev/null +++ b/ef/Utilities/qa/constantpool/ClassWorld.h @@ -0,0 +1,65 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#ifndef CLASSWORLD_H +#define CLASSWORLD_H + +#include "JavaObject.h" +#include "Pool.h" +#include "HashTable.h" + +struct Package +{ + const char *const name; // Name of the package (stored in the ClassWorld's pool) + + explicit Package(const char *name): name(name) {} + + #ifdef DEBUG + int printRef(FILE *f) const; + #endif +}; + + +// Pool of run-time information for a Java Program. New classes can be added +// to the pool explicitly (at runtime), or by ClassCentral. +class ClassWorld { +public: + ClassWorld(Pool &p) : table(p), pool(p) { } + + Type &getType(const char *packageName, const char *className); + + bool getType(const char *fullyQualifiedClassName, Type *&t) { + return table.get(fullyQualifiedClassName, &t); + } + + void add(const char *className, Type *type) { + table.add(className, type); + } + +private: + HashTable table; + Pool &pool; +}; + +// ---------------------------------------------------------------------------- +// Distinguished packages + +extern Package pkgInternal; // Internal package for housekeeping classes +extern Package pkgJavaLang; + +#endif diff --git a/ef/Utilities/qa/constantpool/ConstantPool.h b/ef/Utilities/qa/constantpool/ConstantPool.h new file mode 100644 index 000000000000..7d9eb2f3dc1f --- /dev/null +++ b/ef/Utilities/qa/constantpool/ConstantPool.h @@ -0,0 +1,410 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#ifndef _CONSTANT_POOL_H_ +#define _CONSTANT_POOL_H_ + +#include "FloatUtils.h" +#include "JavaTypes.h" +#include "prtypes.h" +#include "utils.h" +#include "Pool.h" + +/* Constant pool types */ +#define CR_CONSTANT_CLASS 7 +#define CR_CONSTANT_FIELDREF 9 +#define CR_CONSTANT_METHODREF 10 +#define CR_CONSTANT_INTERFACEMETHODREF 11 +#define CR_CONSTANT_STRING 8 +#define CR_CONSTANT_INTEGER 3 +#define CR_CONSTANT_FLOAT 4 +#define CR_CONSTANT_LONG 5 +#define CR_CONSTANT_DOUBLE 6 +#define CR_CONSTANT_NAMEANDTYPE 12 +#define CR_CONSTANT_UTF8 1 + +typedef enum { + crErrorNone=0, + crErrorFileNotFound, + crErrorInvalidFileType, + crErrorIO, + crErrorNoMem, + crErrorInvalidField, + crErrorInvalidConstant, + crErrorInvalidMethod, + crErrorInvalidReference, + crErrorInvalidInterface, + crErrorInvalidAttribute, + crErrorUnknownConstantType, + crErrorSpuriousBytes, /* Extra (unrecognized) bytes at end of file */ + crErrorSuperClassFinal, /* Super-class is a final class and cannot be + * subclassed + */ + crErrorNoSuperClass, + crErrorNoClass /* No class defined in class file */ +} CrError; + +/* Denizens of the ConstantPool */ +class ConstantPoolItem { +public: + ConstantPoolItem(Pool &pIn, uint8 _type) : pool(0), p(pIn), type(_type) { + + } + + virtual uint8 getType() const { + return type; + } + + /* ResolveAndValidate indices into actual pointers */ + virtual int resolveAndValidate() { + return true; + } + +#ifdef DEBUG + virtual void dump(int /*indent*/) { } +#endif + +protected: + ConstantPoolItem **pool; + Pool &p; + ConstantPoolItem(Pool &pIn, ConstantPoolItem **array, uint8 _type) : + pool(array), p(pIn), type(_type) { } + + +private: + uint8 type; +}; + + + +class ConstantUtf8 : public ConstantPoolItem { +friend class ClassFileReader; +public: + ConstantUtf8(Pool &p, char *str, int len); + + const char *getUtfString() { + return data; + } + + const int getUtfLen() { + return dataLen; + } + +#ifdef DEBUG + virtual void dump(int nIndents); +#endif + +private: + ConstantUtf8(Pool &p, int len); + + /* Pointer to the interned version of the string */ + const char *data; + int dataLen; +}; + + +/* A base class for constant-pool items that point to Utf strings */ +class ConstantUtf : public ConstantPoolItem { +friend class ClassFileReader; +public: + ConstantUtf(Pool &p, uint8 _type, ConstantUtf8 *utf8) : + ConstantPoolItem(p, _type) { + utfString = utf8; + } + + ConstantUtf8 *getUtf() { + return utfString; + } + +protected: + ConstantUtf(Pool &p, ConstantPoolItem **array, uint8 _type) : + ConstantPoolItem(p, array, _type) { + utfString = 0; + } + + ConstantUtf8 *utfString; +}; + + + +class ConstantClass : public ConstantUtf { +friend class ClassFileReader; +public: + ConstantClass(Pool &p, ConstantUtf8 *utf8) : + ConstantUtf(p, CR_CONSTANT_CLASS, utf8) { + utfString = utf8; + } + + virtual ConstantUtf8 *getUtf() { + return utfString; + } + + virtual int resolveAndValidate(); + +#ifdef DEBUG + virtual void dump(int nIndents); +#endif + +private: + ConstantClass(Pool &p, ConstantPoolItem **array, int _index) : + ConstantUtf(p, array, CR_CONSTANT_CLASS) { + index = _index; + } + + int index; +}; + + +class ConstantNameAndType : public ConstantPoolItem { +friend class ClassFileReader; +public: + ConstantNameAndType(Pool &p, ConstantUtf8 *name, ConstantUtf8 *desc): + ConstantPoolItem(p, CR_CONSTANT_NAMEANDTYPE) { + nameInfo = name; + descInfo = desc; + } + + /* Get the name of the constant */ + ConstantUtf8 *getName() { + return nameInfo; + } + + /* returns a class that points to the type string */ + ConstantUtf8 *getDesc() { + return descInfo; + } + + virtual int resolveAndValidate(); + +#ifdef DEBUG + virtual void dump(int nIndents); +#endif + +private: + ConstantNameAndType(Pool &p, + ConstantPoolItem **array, int nindex, int dIndex); + + ConstantUtf8 *nameInfo; + ConstantUtf8 *descInfo; + + int nameIndex, descIndex; +}; + + +/* Base class used by ConstantFieldRef, ConstantMethodRef, + * ConstantInterfaceMethodRef: members of a class + */ +class ConstantRef : public ConstantPoolItem { +friend class ClassFileReader; +public: + ConstantRef(Pool &p, uint8 _type, + ConstantClass *cInfo, ConstantNameAndType *_typeInfo) : + ConstantPoolItem(p, _type) { + classInfo = cInfo; + typeInfo = _typeInfo; + } + + ConstantClass *getClassInfo() { + return classInfo; + } + + ConstantNameAndType *getTypeInfo() { + return typeInfo; + } + + virtual int resolveAndValidate(); + +#ifdef DEBUG + virtual void dump(int nIndents); +#endif + +protected: + ConstantRef(Pool &p, uint8 _type, ConstantPoolItem **array, int cIndex, + int tIndex); + + ConstantClass *classInfo; + ConstantNameAndType *typeInfo; + + int classIndex, typeIndex; +}; + + +class ConstantFieldRef : public ConstantRef { +friend class ClassFileReader; +public: + ConstantFieldRef(Pool &p, ConstantClass *cInfo, + ConstantNameAndType *_type): + ConstantRef(p, CR_CONSTANT_FIELDREF, cInfo, _type) { + + } + +#ifdef DEBUG + virtual void dump(int nIndents); +#endif + +private: + ConstantFieldRef(Pool &p, ConstantPoolItem **array, int cIndex, + int tIndex) : + ConstantRef(p, CR_CONSTANT_FIELDREF, array, cIndex, tIndex) { + + } +}; + +class ConstantMethodRef : public ConstantRef { +friend class ClassFileReader; + +public: + ConstantMethodRef(Pool &p, ConstantClass *cInfo, + ConstantNameAndType *_type): + ConstantRef(p, CR_CONSTANT_METHODREF, cInfo, _type) { + + } + +#ifdef DEBUG +virtual void dump(int nIndents); +#endif + +private: +ConstantMethodRef(Pool &p, ConstantPoolItem **array, int cIndex, + int tIndex) : + ConstantRef(p, CR_CONSTANT_METHODREF, array, cIndex, tIndex) { + + } + +}; + +class ConstantInterfaceMethodRef : public ConstantRef { +friend class ClassFileReader; + +public: + ConstantInterfaceMethodRef(Pool &p, ConstantClass *cInfo, + ConstantNameAndType *_type): + ConstantRef(p, CR_CONSTANT_INTERFACEMETHODREF, cInfo, _type) { + + } + +#ifdef DEBUG + virtual void dump(int nIndents); +#endif + +private: + ConstantInterfaceMethodRef(Pool &p, ConstantPoolItem **array, int cIndex, + int tIndex) : + ConstantRef(p, CR_CONSTANT_INTERFACEMETHODREF, array, cIndex, tIndex) { + + } + +}; + + +class ConstantString : public ConstantUtf { +friend class ClassFileReader; +public: + ConstantString(Pool &p, ConstantUtf8 *utf8) : + ConstantUtf(p, CR_CONSTANT_STRING, utf8) { + utfString = utf8; + } + + ConstantUtf8 *getUtf() { + return utfString; + } + + virtual int resolveAndValidate(); + +#ifdef DEBUG + virtual void dump(int nIndents); +#endif + +private: + ConstantString(Pool &p, ConstantPoolItem **array, int _index): + ConstantUtf(p, array, CR_CONSTANT_STRING) { + index = _index; + } + + int index; +}; + +/* Base class for all constant types that hold a numberic value */ +class ConstantVal : public ConstantPoolItem { +public: + ConstantVal(Pool &p, uint8 _type, ValueKind kind) : + ConstantPoolItem(p, _type), vk(kind) { + + } + + virtual Value getValue() { + return value; + } + + virtual ValueKind getValueKind() { + return vk; + } + +#ifdef DEBUG + virtual void dump(int nIndents); +#endif + +protected: + Value value; + ValueKind vk; +}; + +class ConstantInt : public ConstantVal { +public: + ConstantInt(Pool &p, int32 val): + ConstantVal(p, CR_CONSTANT_INTEGER, vkInt) { + value.setValueContents(val); + } + +}; + + +class ConstantFloat : public ConstantVal { +public: + ConstantFloat(Pool &p, uint32 raw); + + uint32 getRaw() const { return raw; } +private: + uint32 raw; +}; + + +class ConstantLong : public ConstantVal { +public: + ConstantLong(Pool &p, uint32 lo, uint32 hi); + + void getBits(uint32 &_lo, uint32 &_hi) const { _lo = lo, _hi = hi; } +private: + uint32 lo, hi; +}; + + +class ConstantDouble : public ConstantVal { +public: + ConstantDouble(Pool &p, char *data); + + char *getData() { return data; } +private: + char data[8]; +}; + + + +#endif /* _CONSTANT_POOL_H_ */ + + diff --git a/ef/Utilities/qa/constantpool/FileReader.cpp b/ef/Utilities/qa/constantpool/FileReader.cpp new file mode 100644 index 000000000000..34af541d44e5 --- /dev/null +++ b/ef/Utilities/qa/constantpool/FileReader.cpp @@ -0,0 +1,156 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#include +#include +#include + +#include "FileReader.h" + +FileReader::FileReader(Pool &p, const char *fileName, int *status, + int _bufferSize) : pool(p) +{ + fp = 0; + buffer = 0; + + *status = 0; + +#ifdef NO_NSPR + if (!(fp = fopen(fileName, "rb"))) { +#else + if (!(fp = PR_Open(fileName, PR_RDONLY, 0))) { +#endif + *status = 1; + return; + } + + bufferSize = _bufferSize; + eofReached = false; + + buffer = new (pool) char[bufferSize]; + + if (!fillBuf()) + *status = 1; + +} + +/* Fill the buffer, returning number of items read */ +int FileReader::fillBuf() +{ + if (eofReached) + return 0; + +#ifdef NO_NSPR + int nread = fread(buffer, 1, bufferSize, fp); +#else + int nread = PR_Read(fp, buffer, bufferSize); +#endif + + if (nread < bufferSize) { + eofReached = true; + if (fp) +#ifdef NO_NSPR + fclose(fp); +#else + PR_Close(fp); +#endif + fp = 0; + } + + curp = buffer; + limit = buffer+nread; + + return nread; +} + +int FileReader::read1(char *destp, int size) +{ + while (curp+size > limit) { + int nread = (limit-curp); + memcpy(destp, curp, nread); + size -= nread; + destp += nread; + + if (fillBuf() <= 0) + return false; + } + + memcpy(destp, curp, size); + curp += size; + return true; +} + +int FileReader::readU1(char *destp, int numItems) +{ + return read1(destp, numItems); +} + +#ifdef IS_LITTLE_ENDIAN +#define flipU2(x) (((x) & 0xFF00) >> 8) | (((x) & 0x00FF) << 8) +#else +#define flipU2(x) (x) +#endif + +int FileReader::readU2(uint16 *destp, int numItems) +{ + if (!read1((char *) destp, numItems*2)) + return false; + +#ifdef IS_LITTLE_ENDIAN + for (numItems--; numItems >= 0; numItems--) + destp[numItems] = flipU2(destp[numItems]); +#endif + + return true; +} + +#ifdef IS_LITTLE_ENDIAN +#define flipU4(x) (((x) >> 24) |\ + ((((x) << 8) >> 24) << 8) |\ + ((((x) << 16) >> 24) << 16) |\ + ((x) << 24)) +#else +#define flipU4(x) (x) +#endif + +int FileReader::readU4(uint32 *destp, int numItems) +{ + if (!read1((char *) destp, numItems*4)) + return false; + +#ifdef IS_LITTLE_ENDIAN + for (numItems--; numItems >= 0; numItems--) + destp[numItems] = flipU4(destp[numItems]); +#endif + + return true; +} + +FileReader::~FileReader() +{ + if (fp) +#ifdef NO_NSPR + fclose(fp); +#else + PR_Close(fp); +#endif +} + + + + diff --git a/ef/Utilities/qa/constantpool/FileReader.h b/ef/Utilities/qa/constantpool/FileReader.h new file mode 100644 index 000000000000..f38fa293f923 --- /dev/null +++ b/ef/Utilities/qa/constantpool/FileReader.h @@ -0,0 +1,71 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#ifndef _CR_FILEREADER_H_ +#define _CR_FILEREADER_H_ + +#define FR_BUFFERSIZE 8192 + +#include "prtypes.h" + +#ifdef NO_NSPR +#include +#else +#include "prio.h" +#endif + +#include "Pool.h" + +/* Reads a file, allocating space as neccessary */ +class FileReader { +public: + FileReader(Pool &pool, const char *fileName, int *status, + int bufferSize = FR_BUFFERSIZE); + + /* All read routines return True on success, False on failure */ + + /* read an unsigned byte */ + int readU1(char *destp, int numItems); + + /* read an unsigned 16-bit quantity */ + int readU2(uint16 *destp, int numItems); + + /* read an unsigned 32-bit quantity */ + int readU4(uint32 *destp, int numItems); + + ~FileReader(); + +private: + int bufferSize; + char *buffer; + char *curp, *limit; + bool eofReached; + + int fillBuf(); + int read1(char *destp, int size); + Pool &pool; + +#ifdef NO_NSPR + FILE *fp; +#else + PRFileDesc *fp; +#endif +}; + +#endif /* _CR_FILEREADER_H_ */ + diff --git a/ef/Utilities/qa/constantpool/FileWriter.cpp b/ef/Utilities/qa/constantpool/FileWriter.cpp new file mode 100644 index 000000000000..b0d9741d087f --- /dev/null +++ b/ef/Utilities/qa/constantpool/FileWriter.cpp @@ -0,0 +1,95 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#include +#include +#include + +#include "FileWriter.h" + +FileWriter::FileWriter(char *classfile) +{ + fp = fopen(classfile, "wb"); +} + +int FileWriter::write1(char *destp, int numItems) +{ + fwrite(destp,1,numItems,fp); + return true; +} + +int FileWriter::writeU1(char *destp, int numItems) +{ + return write1(destp, numItems); +} + +#ifdef IS_LITTLE_ENDIAN +#define flipU2(x) (((x) & 0xFF00) >> 8) | (((x) & 0x00FF) << 8) +#else +#define flipU2(x) (x) +#endif + +int FileWriter::writeU2(uint16 *destp, int numItems) +{ + +#ifdef IS_LITTLE_ENDIAN + for (int i = 0; i < numItems; i++) + destp[i] = flipU2(destp[i]); +#endif + + if (!write1((char *) destp, numItems*2)) + return false; + + return true; +} + +#ifdef IS_LITTLE_ENDIAN +#define flipU4(x) (((x) >> 24) |\ + ((((x) << 8) >> 24) << 8) |\ + ((((x) << 16) >> 24) << 16) |\ + ((x) << 24)) +#else +#define flipU4(x) (x) +#endif + +int FileWriter::writeU4(uint32 *destp, int numItems) { + +#ifdef IS_LITTLE_ENDIAN + for (int i = 0; i < numItems; i++) + destp[i] = flipU4(destp[i]); +#endif + + if (!write1((char *) destp, numItems*4)) + return false; + + return true; +} + +FileWriter::~FileWriter() +{ + if (fp) + fclose(fp); +} + + + + + + + + diff --git a/ef/Utilities/qa/constantpool/FileWriter.h b/ef/Utilities/qa/constantpool/FileWriter.h new file mode 100644 index 000000000000..78b312e992c5 --- /dev/null +++ b/ef/Utilities/qa/constantpool/FileWriter.h @@ -0,0 +1,52 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#ifndef _CR_FILEWRITER_H_ +#define _CR_FILEWRITER_H_ + +#include "prtypes.h" +#include + +/* Writes a file. */ +class FileWriter { +public: + FileWriter(char *classfile); + + /* All write routines return True on success, False on failure */ + + /* write an unsigned byte */ + int writeU1(char *destp, int numItems); + + /* write an unsigned 16-bit quantity */ + int writeU2(uint16 *destp, int numItems); + + /* write an unsigned 32-bit quantity */ + int writeU4(uint32 *destp, int numItems); + + ~FileWriter(); + +private: + int write1(char *destp, int size); + FILE *fp; +}; + +#endif /* _CR_FILEWRITER_H_ */ + + + + diff --git a/ef/Utilities/qa/constantpool/HelloWorld.class b/ef/Utilities/qa/constantpool/HelloWorld.class new file mode 100644 index 000000000000..f1d3646c7425 Binary files /dev/null and b/ef/Utilities/qa/constantpool/HelloWorld.class differ diff --git a/ef/Utilities/qa/constantpool/HelloWorld.java b/ef/Utilities/qa/constantpool/HelloWorld.java new file mode 100644 index 000000000000..3100b90f1069 --- /dev/null +++ b/ef/Utilities/qa/constantpool/HelloWorld.java @@ -0,0 +1,44 @@ +class HelloWorld implements testInterface { + + static long field = 255L; + + long sum; + + HelloWorld() { + + sum = field + 245L; + + } + + + public void doSomething(String line) { + + System.out.println(line); + + } + + void test(long field){ + + double l = 5000.0D; + int i = 1234567890; + float j = 1234.0F; + long k = 5000L; + + + int m = i + 1; + float n = j + 1000.0F; + long o = k + field; + double p = l + 300.0D; + + } + + public static void main(String[] args) { + + long field = 255L; + + HelloWorld a = new HelloWorld(); + a.test(field); + + } + +} \ No newline at end of file diff --git a/ef/Utilities/qa/constantpool/InfoItem.h b/ef/Utilities/qa/constantpool/InfoItem.h new file mode 100644 index 000000000000..665538d2ba3f --- /dev/null +++ b/ef/Utilities/qa/constantpool/InfoItem.h @@ -0,0 +1,170 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#ifndef _CR_INFOITEM_H_ +#define _CR_INFOITEM_H_ + +#include "ConstantPool.h" +#include "DoublyLinkedList.h" + +#define CR_FIELD_VOLATILE 0x0040 +#define CR_FIELD_STATIC 0x0008 + +#define CR_METHOD_STATIC 0x0008 +#define CR_METHOD_NATIVE 0x0100 +#define CR_METHOD_ABSTRACT 0x0400 +#define CR_METHOD_PRIVATE 0x0002 +#define CR_METHOD_PUBLIC 0x0001 +#define CR_METHOD_PROTECTED 0x0004 +#define CR_METHOD_FINAL 0x0010 +#define CR_METHOD_SYNCHRONIZED 0x0020 + + +/* Base class for types FieldInfo and MethodInfo */ +class InfoItem { +public: + InfoItem(Pool &p, uint16 aflags, ConstantUtf8 *classInfo, + ConstantUtf8 *nameInfo, ConstantUtf8 *descInfo, + uint16 nameIndex, uint16 descIndex); + + + uint16 getAccessFlags() const { + return accessFlags; + } + + ConstantUtf8 *getName() const { + return name; + } + + uint16 getNameIndex() const { + return nameIndex; + } + + uint16 getDescIndex() const { + return descIndex; + } + + /* Returns a class that points to the string representing the + * type descriptor of the field/method + */ + ConstantUtf8 *getDescriptor() const { + return descriptor; + } + + /* returns the name of the class that this field/method is a member of */ + ConstantUtf8 *getClassName() const { + return className; + } + + int getAttributeCount() const { + return attrCount; + } + + const DoublyLinkedList &getAttributes() const { + return attributes; + } + + + /* Looks up an attribute by attribute-name */ + AttributeInfoItem *getAttribute(const char *_name) const; + + /* Look up a known attribute by code name */ + AttributeInfoItem *getAttribute(const uint32 code) const; + +#ifdef DEBUG + virtual void dump(int nIndents); +#endif + + int addAttribute(AttributeInfoItem &attribute); + +protected: + Pool &p; + +private: + uint16 accessFlags; + ConstantUtf8 *name, *descriptor, *className; + uint16 nameIndex, descIndex; + + int attrCount; + DoublyLinkedList attributes; + +}; + +/* A FieldInfo represents one field in a class or interface */ +class FieldInfo: public InfoItem { +friend class ClassFileReader; + +public: + FieldInfo(Pool &p, uint16 aflags, ConstantUtf8 *classInfo, + ConstantUtf8 *nameInfo, ConstantUtf8 *descInfo, + uint16 nameIndex, uint16 descIndex); + + void getType(JavaType *&ret) { + ret = type; + } + + void getInfo(JavaType *&type, + bool &isVolatile, bool &isConstant, + uint32 &offset) const; + + void getInfo(JavaType *&type, bool &isVolatile, bool &isConstant, + addr &a) const; + + +#ifdef DEBUG + virtual void dump(int nIndents); +#endif + +private: + JavaType *type; + + union { + uint32 offset; /* Offset from beginning of stack frame if non-static */ + addr a; /* Address in memory if static */ + } pos; + +}; + +/* A MethodInfo represents one method in a class or interface */ +class MethodInfo: public InfoItem { +public: + MethodInfo(Pool &p, uint16 aflags, ConstantUtf8 *classInfo, + ConstantUtf8 *nameInfo, ConstantUtf8 *descInfo, + uint16 nameIndex, uint16 descIndex); + + + /* Get the signature of the method */ + const JavaType &getSignature(int &nParams, const JavaType *¶mTypes, + bool &isStatic, + bool &isNative, bool &isAbstract) const; + + bool parseMethodDescriptor(const char *s); + +private: + JavaType ret; + + JavaType *params; + int numParams, paramSize; +}; + + +#endif /* _CR_INFOITEM_H_ */ + + + + diff --git a/ef/Utilities/qa/constantpool/JavaObject.cpp b/ef/Utilities/qa/constantpool/JavaObject.cpp new file mode 100644 index 000000000000..a1c7c7c9f535 --- /dev/null +++ b/ef/Utilities/qa/constantpool/JavaObject.cpp @@ -0,0 +1,448 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#include "ClassWorld.h" +#include +#if 0 +#include "ClassCentral.h" +#endif + +// Size of each TypeKind +const int8 typeKindSizes[nTypeKinds] = +{ + 0, // tkVoid + 1, // tkBoolean + 1, // tkUByte + 1, // tkByte + 2, // tkChar + 2, // tkShort + 4, // tkInt + 8, // tkLong + 4, // tkFloat + 8, // tkDouble + 4, // tkObject + 4, // tkSpecial + 4, // tkArray + 4 // tkInterface +}; + +// lg2 of the size of each TypeKind +const int8 lgTypeKindSizes[nTypeKinds] = +{ + -1, // tkVoid + 0, // tkBoolean + 0, // tkUByte + 0, // tkByte + 1, // tkChar + 1, // tkShort + 2, // tkInt + 3, // tkLong + 2, // tkFloat + 3, // tkDouble + 2, // tkObject + 2, // tkSpecial + 2, // tkArray + 2 // tkInterface +}; + +// Number of environment slots taken by each TypeKind +const int8 typeKindNSlots[nTypeKinds] = +{ + 0, // tkVoid + 1, // tkBoolean + 1, // tkUByte + 1, // tkByte + 1, // tkChar + 1, // tkShort + 1, // tkInt + 2, // tkLong + 1, // tkFloat + 2, // tkDouble + 1, // tkObject + 1, // tkSpecial + 1, // tkArray + 1 // tkInterface +}; + + +// ---------------------------------------------------------------------------- + + +// Distinguished classes +const Class *cObject; +const Class *cThrowable; +const Class *cException; +const Class *cRuntimeException; +const Class *cArithmeticException; +const Class *cArrayStoreException; +const Class *cClassCastException; +const Class *cArrayIndexOutOfBoundsException; +const Class *cNegativeArraySizeException; +const Class *cNullPointerException; + +// Internal classes +const Class *cPrimitiveType; +const Class *cPrimitiveArray; +const Class *cObjectArray; +const Class *cClass; +const Class *cInterface; + +// Distinguished interfaces +const Interface *iCloneable; + +// Distinguished objects +const JavaObject *oArithmeticException; +const JavaObject *oArrayStoreException; +const JavaObject *oClassCastException; +const JavaObject *oArrayIndexOutOfBoundsException; +const JavaObject *oNegativeArraySizeException; +const JavaObject *oNullPointerException; + + +// +// Initialize the distinguished classes and objects. +// This routine must be called before any of these are referenced. +// Soon to be obsolete. +// +void initDistinguishedObjects() +{ + cPrimitiveType = &Class::make(pkgInternal, "PrimitiveType", 0, 0, 0, 0, 0, 0, 0, true, sizeof(PrimitiveType), 0); + cPrimitiveArray = &Class::make(pkgInternal, "PrimitiveArray", 0, 0, 0, 0, 0, 0, 0, true, sizeof(Array), 0); + cObjectArray = &Class::make(pkgInternal, "ObjectArray", 0, 0, 0, 0, 0, 0, 0, true, sizeof(Array), 0); + cClass = &Class::make(pkgInternal, "Class", 0, 0, 0, 0, 0, 0, 0, true, sizeof(Class), 0); + cInterface = &Class::make(pkgInternal, "Interface", 0, 0, 0, 0, 0, 0, 0, true, sizeof(Interface), 0); + + PrimitiveType::staticInit(); + Array::staticInit(); + + cObject = &Class::make(pkgJavaLang, "Object", 0, 0, 0, 0, 0, 0, 0, false, sizeof(JavaObject), 0); + cThrowable = &Class::make(pkgJavaLang, "Throwable", cObject, 0, 0, 0, 0, 0, 0, false, sizeof(JavaObject), 0); + cException = &Class::make(pkgJavaLang, "Exception", cThrowable, 0, 0, 0, 0, 0, 0, false, sizeof(JavaObject), 0); + cRuntimeException = &Class::make(pkgJavaLang, "RuntimeException", cException, 0, 0, 0, 0, 0, 0, false, sizeof(JavaObject), 0); + cArithmeticException = &Class::make(pkgJavaLang, "ArithmeticException", cRuntimeException, 0, 0, 0, 0, 0, 0, false, sizeof(JavaObject), 0); + cArrayStoreException = &Class::make(pkgJavaLang, "ArrayStoreException", cRuntimeException, 0, 0, 0, 0, 0, 0, false, sizeof(JavaObject), 0); + cClassCastException = &Class::make(pkgJavaLang, "ClassCastException", cRuntimeException, 0, 0, 0, 0, 0, 0, false, sizeof(JavaObject), 0); + cIndexOutOfBoundsException = &Class::make(pkgJavaLang, "IndexOutOfBoundsException", cRuntimeException, 0, 0, 0, 0, 0, 0, false, sizeof(JavaObject), 0); + cArrayIndexOutOfBoundsException = &Class::make(pkgJavaLang, "ArrayIndexOutOfBoundsException", cIndexOutOfBoundsException, 0, 0, 0, 0, 0, 0, false, sizeof(JavaObject), 0); + cNegativeArraySizeException = &Class::make(pkgJavaLang, "NegativeArraySizeException", cRuntimeException, 0, 0, 0, 0, 0, 0, false, sizeof(JavaObject), 0); + cNullPointerException = &Class::make(pkgJavaLang, "NullPointerException", cRuntimeException, 0, 0, 0, 0, 0, 0, false, sizeof(JavaObject), 0); + + iCloneable = new Interface(pkgJavaLang, "Cloneable", 0, 0, 0, 0, 0, 0); + + oArithmeticException = new JavaObject(*cArithmeticException); + oArrayStoreException = new JavaObject(*cArrayStoreException); + oClassCastException = new JavaObject(*cClassCastException); + oArrayIndexOutOfBoundsException = new JavaObject(*cArrayIndexOutOfBoundsException); + oNegativeArraySizeException = new JavaObject(*cNegativeArraySizeException); + oNullPointerException = new JavaObject(*cNullPointerException); +} + +#if 0 +inline const Class *toClass(ClassCentral ¢ral, const char *className) +{ + return static_cast(central.addClass(className).getThisClass()); +} + +inline const Interface *toInterface(ClassCentral ¢ral, + const char *className) +{ + return static_cast(central.addClass(className).getThisClass()); +} + +// +// Initialize the distinguished classes and objects. +// This routine must be called before any of these are referenced. +// +void initDistinguishedObjects(ClassCentral &c) +{ + cPrimitiveType = &Class::make(pkgInternal, "PrimitiveType", 0, 0, 0, 0, 0, 0, 0, true, sizeof(PrimitiveType), 0); + cPrimitiveArray = &Class::make(pkgInternal, "PrimitiveArray", 0, 0, 0, 0, 0, 0, 0, true, sizeof(Array), 0); + cObjectArray = &Class::make(pkgInternal, "ObjectArray", 0, 0, 0, 0, 0, 0, 0, true, sizeof(Array), 0); + cClass = &Class::make(pkgInternal, "Class", 0, 0, 0, 0, 0, 0, 0, true, sizeof(Class), 0); + cInterface = &Class::make(pkgInternal, "Interface", 0, 0, 0, 0, 0, 0, 0, true, sizeof(Interface), 0); + + PrimitiveType::staticInit(); + Array::staticInit(); + + cObject = toClass(c, "java/lang/Object"); + cThrowable = toClass(c, "java/lang/Throwable"); + cException = toClass(c, "java/lang/Exception"); + cRuntimeException = toClass(c, "java/lang/RuntimeException"); + cArithmeticException = toClass(c, "java/lang/ArithmeticException"); + cArrayStoreException = toClass(c, "java/lang/ArrayStoreException"); + cClassCastException = toClass(c, "java/lang/ClassCastException"); + cIndexOutOfBoundsException = toClass(c, "java/lang/IndexOutOfBoundsException"); + cArrayIndexOutOfBoundsException = toClass(c, "java/lang/ArrayIndexOutOfBoundsException"); + cNegativeArraySizeException = toClass(c, "java/lang/NegativeArraySizeException"); + cNullPointerException = toClass(c, "java/lang/NullPointerException"); + + iCloneable = toInterface(c, "java/lang/Cloneable"); + + oArithmeticException = new JavaObject(*cArithmeticException); + oArrayStoreException = new JavaObject(*cArrayStoreException); + oClassCastException = new JavaObject(*cClassCastException); + oArrayIndexOutOfBoundsException = new JavaObject(*cIndexOutOfBoundsException); + oNegativeArraySizeException = new JavaObject(*cNegativeArraySizeException); + oNullPointerException = new JavaObject(*cNullPointerException); +} +#endif + +// ---------------------------------------------------------------------------- +// Type + +// +// Return true if sub is a subtype of super. In other words, return true if +// an instance or variable of type sub can be assigned to a variable of type super. +// +bool implements(const Type &sub, const Type &super) +{ + // Every type is a subtype of itself. + if (&super == &sub) + return true; + + TypeKind superKind = super.typeKind; + TypeKind subKind = sub.typeKind; + + switch (subKind) { + case tkObject: + switch (superKind) { + // A class's supertypes can only be its superclasses or superinterfaces -- + // never primitive objects, arrays, or special objects. + case tkObject: + return static_cast(&sub)->implements(*static_cast(&super)); + case tkInterface: + return static_cast(&sub)->implements(*static_cast(&super)); + default:; + } + break; + + case tkArray: + switch (superKind) { + // An array's supertypes can only be: + // the class Object, + // the interface Cloneable, or + // arrays whose element type is a supertype of this array's element type. + case tkObject: + return &super == cObject; + case tkArray: + return implements(static_cast(&sub)->elementType, + static_cast(&super)->elementType); + case tkInterface: + return &super == iCloneable; + default:; + } + break; + + case tkInterface: + switch (superKind) { + // An interface's supertypes can only be: + // the class Object, or + // the interface's superinterfaces. + case tkObject: + return &super == cObject; + case tkInterface: + return static_cast(&sub)->implements(*static_cast(&super)); + default:; + } + break; + + default:; + } + + // There are no other nontrivial subtyping relationships. + return false; +} + + +// ---------------------------------------------------------------------------- +// PrimitiveType + +const PrimitiveType *PrimitiveType::primitiveTypes[nPrimitiveTypeKinds]; + +// +// Initialize the table used by the obtain method. +// cPrimitiveType must have already been initialized. +// +void PrimitiveType::staticInit() +{ + assert(cPrimitiveType); + for (TypeKind tk = tkVoid; tk < nPrimitiveTypeKinds; tk = (TypeKind)(tk+1)) + primitiveTypes[tk] = new PrimitiveType(*cPrimitiveType, tk); +} + + +// ---------------------------------------------------------------------------- +// Array + +const Array *Array::primitiveArrays[nPrimitiveTypeKinds]; + + +// +// Initialize a type for arrays. +// Do not call this constructor directly; use obtain or Type::getArrayType instead. +// +Array::Array(const Type &elementType): + Type(isPrimitiveKind(elementType.typeKind) ? *cPrimitiveArray : *cObjectArray, tkArray, elementType.final, 0), + elementType(elementType) +{ + assert(elementType.typeKind != tkVoid); +} + + +// +// Initialize the table used by the obtain method. +// PrimitiveType::obtain must have already been initialized. +// +void Array::staticInit() +{ + primitiveArrays[tkVoid] = 0; // Can't have an array of type Void. + for (TypeKind tk = tkBoolean; tk < nPrimitiveTypeKinds; tk = (TypeKind)(tk+1)) + primitiveArrays[tk] = &PrimitiveType::obtain(tk).getArrayType(); +} + + +// ---------------------------------------------------------------------------- +// ClassOrInterface + +#ifdef DEBUG +// +// Print a reference to this class or interface for debugging purposes. +// Return the number of characters printed. +// +int ClassOrInterface::printRef(FILE *f) const +{ + int o = package.printRef(f); + return o + fprintf(f, ".%s", name); +} +#endif + + + +// ---------------------------------------------------------------------------- +// Class + + +// +// Initialize the fields of a Class object. This constructor may only be called +// from within Class::make because the Class object must be specially allocated to +// allow room for its vtable. +// +inline Class::Class(Package &package, const char *name, const Class *_parent, + uint32 nInterfaces, + Interface **interfaces, + uint32 nFields, + Field **fields, + uint32 nMethods, + Method **methods, + bool final, uint32 instanceSize, uint32 nVTableSlots): + ClassOrInterface(*cClass, tkObject, final, nVTableSlots, package, name, + nInterfaces, interfaces, + nFields, fields, + nMethods, methods), + instanceSize(instanceSize) +{ + parent = const_cast(_parent); +} + + +// +// Initialize a new Class object that describes essential information such as layout +// and inheritance relationships of objects of a single Java class. +// +// package is the package that defined this class. +// name is the unqualified name of this class. +// parent is the parent class or nil if this is the Class for the Object class. +// interfaces is an array of nInterfaces elements that lists all interfaces from which +// this class derives except that the interfaces array does not include interfaces +// from which the parent class derives. +// extraSize is the number of additional bytes taken by fields of this class and should +// be a multiple of 4. +// nExtraVTableSlots is the number of additional virtual methods that this class declares; +// it does not include the one vtable slot used for class membership testing. +// +Class &Class::make(Package &package, const char *name, const Class *parent, uint32 nInterfaces, Interface **interfaces, + uint32 nFields, Field **fields, + uint32 nMethods, Method **methods, + bool final, uint32 extraSize, uint32 nExtraVTableSlots) +{ + uint32 nVTableSlots = nExtraVTableSlots + 1; + if (parent) { + assert(!parent->final); + nVTableSlots += parent->nVTableSlots; + extraSize += parent->instanceSize; + } + void *mem = malloc(sizeof(Class) + nVTableSlots*sizeof(VTableEntry)); + return *new(mem) Class(package, name, parent, nInterfaces, interfaces, + nFields, fields, nMethods, methods, + final, extraSize, nVTableSlots); +} + + +// +// Return true if this class implements class c. +// +bool Class::implements(const Class &c) const +{ + const Class *a = this; + do { + if (a == &c) + return true; + a = a->parent; + } while (a); + return false; +} + + +// +// Return true if this class implements interface i. +// +bool Class::implements(const Interface &i) const +{ + const Class *a = this; + do { + uint32 n = a->nInterfaces; + Interface *const*intfs = a->interfaces; + while (n--) { + if (*intfs == &i) + return true; + intfs++; + } + a = a->parent; + } while (a); + return false; +} + + +// ---------------------------------------------------------------------------- +// Interface + +// +// Return true if this interface implements interface i. +// +bool Interface::implements(const Interface &i) const +{ + uint32 n = nInterfaces; + Interface *const*intfs = interfaces; + while (n--) { + if (*intfs == &i) + return true; + intfs++; + } + return false; +} + diff --git a/ef/Utilities/qa/constantpool/JavaObject.h b/ef/Utilities/qa/constantpool/JavaObject.h new file mode 100644 index 000000000000..1275f29e4e87 --- /dev/null +++ b/ef/Utilities/qa/constantpool/JavaObject.h @@ -0,0 +1,599 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#ifndef JAVAOBJECT_H +#define JAVAOBJECT_H + +#include "Fundamentals.h" + + +// A TypeKind describes the basic kind of a Java value. +// See also Value.h. +enum TypeKind +{ // Size Primitive kind? Final? + tkVoid, // 0 yes yes + tkBoolean, // 1 yes yes + tkUByte, // 1 yes yes + tkByte, // 1 yes yes + tkChar, // 2 yes yes + tkShort, // 2 yes yes + tkInt, // 4 yes yes + tkLong, // 8 yes yes + tkFloat, // 4 yes yes + tkDouble, // 8 yes yes + tkObject, // 4 no sometimes // Java objects + tkSpecial, // 4 no yes // Internal, non-java objects; not used at this time + tkArray, // 4 no sometimes // Java arrays + tkInterface // 4 no no // Java interfaces +}; +const nPrimitiveTypeKinds = tkDouble + 1; +const nTypeKinds = tkInterface + 1; + +inline bool isPrimitiveKind(TypeKind tk) {return tk <= tkDouble;} +inline bool isNonVoidPrimitiveKind(TypeKind tk) {return tk >= tkBoolean && tk <= tkDouble;} +inline bool isDoublewordKind(TypeKind tk) {return tk == tkLong || tk == tkDouble;} +inline int getTypeKindSize(TypeKind tk); +inline int getLgTypeKindSize(TypeKind tk); +inline int nTypeKindSlots(TypeKind tk); +inline bool getTypeKindFromDescriptor(char c, TypeKind &tk); + +// ---------------------------------------------------------------------------- + +struct Type; +struct Class; +struct Interface; +struct Package; + +struct Field; +struct Method; +struct Constructor; + + +// A JavaObject is the header of any Java object. +// It contains just one field -- a pointer to the object's type. +// An actual Java object's fields follow after the end of the JavaEnd structure. +struct JavaObject +{ + const Type &type; // Pointer to the object's type + + explicit JavaObject(const Type &type): type(type) {} + const Class &getClass() const; +}; +const int32 objectTypeOffset = 0; // Offset from object address to its type pointer word + +typedef JavaObject *obj; +typedef const JavaObject *cobj; + +inline ptr objToPtr(obj o) {return reinterpret_cast(o);} +inline cptr objToPtr(cobj o) {return reinterpret_cast(o);} + +inline obj ptrToObj(ptr o) {return reinterpret_cast(o);} +inline cobj ptrToObj(cptr o) {return reinterpret_cast(o);} + + +// ---------------------------------------------------------------------------- + +// A JavaArray is the header of any Java array. +// It contains only two field -- a pointer to the object's type and a +// number of elements. +// An actual Java array's elements follow after the end of the JavaArray structure. +struct JavaArray: JavaObject +{ + const uint32 length; // Number of elements in this array + + JavaArray(Type &type, uint32 length): JavaObject(type), length(length) {} +}; + +const int32 arrayLengthOffset = offsetof(JavaArray, length); // Offset from array address to its length word +const int32 arrayObjectEltsOffset = sizeof(JavaArray); // Offset from array-of-objects address to its first element + + +// ---------------------------------------------------------------------------- + +struct Array; +// A Type describes the contents of a Java object. +// It's also itself a special kind of Java object. +struct Type: JavaObject +{ + const TypeKind typeKind ENUM_8; // Kind of objects described here + const bool final BOOL_8; // True if this type cannot have any subtypes. Note that, by this + // definition, an array type is final if its element type is final. + const uint32 nVTableSlots; // Number of vtable slots for this class; zero if there is no vtable + private: + mutable const Array *arrayType; // Type of arrays whose elements have this Type or null if none declared yet + +protected: // This is an abstract class + Type(const Type &metaType, TypeKind typeKind, bool final, uint32 nVTableSlots): + JavaObject(metaType), typeKind(typeKind), final(final), nVTableSlots(nVTableSlots), arrayType(0) {} + +public: + const Array &getArrayType() const; +}; + +inline Type &asType(JavaObject &o); +bool implements(const Type &sub, const Type &super); + + +// A Type for void, boolean, ubyte, byte, char, short, int, long, float, or double. +struct PrimitiveType: Type +{ + private: + static const PrimitiveType *primitiveTypes[nPrimitiveTypeKinds]; + + // Only initPrimitiveTypes can construct PrimitiveType instances. + PrimitiveType(const Type &metaType, TypeKind typeKind): Type(metaType, typeKind, true, 0) { } + + public: + static const PrimitiveType &obtain(TypeKind tk); + + static void staticInit(); +}; + + +// A Type for any array. +struct Array: Type +{ + const Type &elementType; // Type of elements of this array + + private: + static const Array *primitiveArrays[nPrimitiveTypeKinds]; + public: + + explicit Array(const Type &elementType); + static const Array &obtain(TypeKind elementKind); + + static void staticInit(); +}; + + +// ---------------------------------------------------------------------------- + + +// An abstract class that contains information common to Class and +// Interface objects. +struct ClassOrInterface: Type +{ + friend class ClassFileSummary; + + Package &package; // The package that defines this class or interface + const char *const name; // Unqualified name of the class or interface (stored in the ClassWorld's pool) + const uint32 nInterfaces; // Number of interfaces implemented directly by this class or interface + Interface **interfaces; // Array of nInterfaces implemented directly by this class or interface + //const char *const fullName; // Fully qualified name of the class or interface + const uint32 nFields; + Field **fields; + const uint32 nMethods; + Method **methods; + + protected: + ClassOrInterface(const Type &metaType, TypeKind typeKind, bool final, + uint32 nVTableSlots, Package &package, + const char *name, uint32 nInterfaces, + Interface **interfaces, + uint32 nFields, Field **fields, + uint32 nMethods, Method **methods); + + public: + #ifdef DEBUG + int printRef(FILE *f) const; + #endif + + // Returns fully qualified name of the class in the form + // "class " + const char *toString(); + + // Given a fully qualified className, attempts to load and link the class + // and returns the corresponding Class object. + static Class &forName(const char *className); + + // Creates an instance of the class if the class is instantiable. + JavaObject &newInstance(); + + // Returns true if given Object is an instance of the class represented + // by this class object. + bool isInstance(JavaObject &obj) const; + + // Returns true if the type represented by the specified Class parameter + // can be converted to the type represented by this class object. + bool isAssignableFrom(Class &from) const; + + bool isInterface() const; + bool isArray() const; + bool isPrimitive() const; // Returns true if this class is a primitive type + + // Returns the fully qualified name of the class; unlike toString(), + // does not prepend "class " in front of the name + const char *getName() const; + + // Returns the modifiers (access flags) for this class object. + int getModifiers() const; + + // Returns the class loader object for this class. Need to think about + // this a little bit. + // ClassLoader getClassLoader(); + + // Returns the class object for the super class of this class. Returns + // NULL if this is a primitive type or java/lang/Object + Class *getSuperClass() const; + + // Returns summaries for the interfaces of this class. + // If this class object represents a class, returns an array containing + // objects representing the interfaces directly implemented by the class. + // If this Class object represents an interface, returns an array + // containing objects representing the direct superinterfaces of the + // interface. Returns number of array interfaces actually returned. + // This number could be zero, if the class is a primitive type or + // implements no interfaces. + int getInterfaces(Class *&summaries); + + // If this Class object represents an array type, returns the class + // object representing the component type of the array; + // otherwise returns NULL. + Class *getComponentType(); + + // If this class or interface is a member of another class, returns the + // class object representing the class of which it is a member. If this is + // not the case, returns NULL. Hmmm. Need to think about how to implement + // this. + // Class *getDeclaringClass(); + + // Returns an array containing class objects representing all the public + // classes and interfaces that are members of the class represented by this + // class object. Returns number of class objects returned. + int getClasses(Class *&summaries); + + // Returns an array containing information about the public fields of this + // object. Returns number of fields in object. + int getFields(const Field *&fields); + + // Returns an array containing information about the public methods of + // this object. Returns number of fields in object. + int getMethods(const Method *&methods); + + // Returns an array containing information about the public constructors of + // this object. Returns number of constructors. + int getConstructors(const Constructor *&constructors); + + // Look up fields/methods/constructors. These methods search through + // publicly accessible fields/methods/constructors. + Field &getField(const char *name); + Method &getMethod(const char *name, Class *parameterTypes[], + int numParams); + Constructor &getConstructor(Class *parameterTypes[], + int numParams); + + // The following functions deal with *all* declared fields, methods, or + // constructors, be they public, protected, or private. + int getDeclaredClasses(Class *&summaries); + int getDeclaredFields(const Field *&fields) const; + int getDeclaredMethods(const Method *&methods) const; + int getDeclaredConstructors(const Constructor *&constructors) const; + + Field &getDeclaredField(const char *name); + Method &getDeclaredMethod(const char *name, Class parameterTypes[], int numParams); + Constructor &getDeclaredConstructor(Class parameterTypes[], int numParams); +}; + + +// A vtable contains two kinds of entries: +// Method pointers that point to code (either actual code or stubs that +// load the actual code); +// Class pointers that point to superclasses. +// +// The method pointers are used for dispatching methods inherited from +// superclasses. The Class pointers are used for quickly determining +// whether an object belongs to a particular class. +union VTableEntry +{ + void *codePtr; // Pointer to method + Class *classPtr; // Pointer to superclass +}; + + +// Runtime reflection information about a class, such as its inheritance +// hierarchy, fields and field layout, etc. +// A Class remains in memory as long as a class is alive. It does +// not keep track of a class's constant pool, etc. +struct Class: ClassOrInterface +{ + friend class ClassFileSummary; + + const Class *parent; // The superclass of this class (nil if this is the class Object) + uint32 instanceSize; // Size of instance objects in bytes + + private: + Class(Package &package, const char *name, const Class *parent, uint32 nInterfaces, Interface **interfaces, + uint32 nFields, Field **fields, + uint32 nMethods, Method **methods, + bool final, uint32 instanceSize, uint32 nVTableSlots); + + void setSuper(const Class *p) {parent = p;} + void setSize(uint32 size) {instanceSize = size;} + + public: + static Class &make(Package &package, const char *name, + const Class *parent, uint32 nInterfaces, + Interface **interfaces, + uint32 nFields, Field **fields, + uint32 nMethods, Method **methods, + bool final, uint32 extraSize, uint32 nExtraVTableSlots); + + bool implements(const Class &c) const; + bool implements(const Interface &i) const; + + VTableEntry &getVTableEntry(uint32 vIndex); +}; + +const uint32 vTableOffset = sizeof(Class); // Offset from a Type to beginning of its vtable +inline int32 vTableIndexToOffset(uint32 vIndex) {return (int32)(vTableOffset + vIndex*sizeof(VTableEntry));} + + +struct Interface: ClassOrInterface +{ + Interface(Package &package, const char *name, uint32 nInterfaces, + Interface **interfaces, uint32 nFields, Field **fields, + uint32 nMethods, Method **methods); + + bool implements(const Interface &i) const; + + // Other methods to inquire about this interface +}; + + +// ---------------------------------------------------------------------------- +// Distinguished objects + +// Distinguished classes +extern const Class *cObject; +extern const Class *cThrowable; +extern const Class *cException; +extern const Class *cRuntimeException; +extern const Class *cArithmeticException; +extern const Class *cArrayStoreException; +extern const Class *cClassCastException; +extern const Class *cIndexOutOfBoundsException; +extern const Class *cArrayIndexOutOfBoundsException; +extern const Class *cNegativeArraySizeException; +extern const Class *cNullPointerException; + +// Internal classes +extern const Class *cPrimitiveType; +extern const Class *cPrimitiveArray; +extern const Class *cObjectArray; +extern const Class *cClass; +extern const Class *cInterface; + +// Distinguished interfaces +extern const Interface *iCloneable; + +// Distinguished objects +extern const JavaObject *oArithmeticException; +extern const JavaObject *oArrayStoreException; +extern const JavaObject *oClassCastException; +extern const JavaObject *oArrayIndexOutOfBoundsException; +extern const JavaObject *oNegativeArraySizeException; +extern const JavaObject *oNullPointerException; + +class ClassCentral; +void initDistinguishedObjects(ClassCentral &c); +void initDistinguishedObjectsOld(); // Soon to be obsolete + +// --- INLINES ---------------------------------------------------------------- + + +extern const int8 typeKindSizes[nTypeKinds]; +// +// Return the number of bytes taken by a value that has the given TypeKind. +// +inline int getTypeKindSize(TypeKind tk) +{ + assert((uint)tk < nTypeKinds); + return typeKindSizes[tk]; +} + + +extern const int8 lgTypeKindSizes[nTypeKinds]; +// +// Return the base-2 logarithm of the number of bytes taken by a value +// that has the given TypeKind. +// +inline int getLgTypeKindSize(TypeKind tk) +{ + assert((uint)tk < nTypeKinds); + return lgTypeKindSizes[tk]; +} + + +extern const int8 typeKindNSlots[nTypeKinds]; +// +// Return the number of environment slots taken by a value that has the +// given TypeKind. +// +inline int nTypeKindSlots(TypeKind tk) +{ + assert((uint)tk < nTypeKinds); + return typeKindNSlots[tk]; +} + +// +// If c is the descriptor for a primitive type, sets tk to the +// typeKind of c and returns true. Else, returns false. +// +inline bool getTypeKindFromDescriptor(char c, TypeKind &tk) +{ + bool ret = true; + + switch (c) { + case 'B': + tk = tkByte; + break; + + case 'C': + tk = tkChar; + break; + + case 'D': + tk = tkDouble; + break; + + case 'F': + tk = tkFloat; + break; + + case 'I': + tk = tkInt; + break; + + case 'J': + tk = tkLong; + break; + + case 'S': + tk = tkShort; + break; + + case 'Z': + tk = tkBoolean; + break; + + default: + ret = false; + } + + return ret; +} + + +// ---------------------------------------------------------------------------- + + +// +// Return the type of arrays whose elements have this Type. +// +inline const Array &Type::getArrayType() const +{ + if (arrayType) + return *arrayType; + arrayType = new Array(*this); + return *arrayType; +} + +// +// Assert that this JavaObject is really a Type and return that Type. +// +inline Type &asType(JavaObject &o) +{ + assert(&o.type && + (&o.type == cPrimitiveType || &o.type == cPrimitiveArray || &o.type == cObjectArray || + &o.type == cClass || &o.type == cInterface)); + return *static_cast(&o); +} + + +// +// Return the primitive type corresponding to the given TypeKind. +// +inline const PrimitiveType &PrimitiveType::obtain(TypeKind tk) +{ + assert(isPrimitiveKind(tk) && primitiveTypes[tk]); + return *primitiveTypes[tk]; +} + + +// +// Return a PrimitiveArray corresponding to the given TypeKind. +// +inline const Array &Array::obtain(TypeKind elementKind) +{ + assert(isNonVoidPrimitiveKind(elementKind) && primitiveArrays[elementKind]); + return *primitiveArrays[elementKind]; +} + + +// ---------------------------------------------------------------------------- + + +// +// Return the class of a Java object. The class of an array is Object. +// +inline const Class &JavaObject::getClass() const +{ + return type.typeKind == tkArray ? *cObject : *static_cast(&type); +} + + +// +// Initialize a new ClassOrInterface object. metaType is the type of +// the ClassOrInterface object -- either cClass or cInterface. +// size is the size of instances of this class; size is zero if this is Interface +// instead of a Class. +// package is the package that defined this class or interface, name is the unqualified +// name of this class or interface, and interfaces is an array of nInterfaces elements +// that lists all interfaces from which this class or interface derives except that, +// if this is a Class, the interfaces array does not include interfaces from which +// the parent class derives. +// +inline ClassOrInterface::ClassOrInterface(const Type &metaType, + TypeKind typeKind, bool final, + uint32 nVTableSlots, + Package &package, const char *name, + uint32 nInterfaces, + Interface **interfaces, + uint32 nFields, Field **fields, + uint32 nMethods, Method **methods): + Type(metaType, typeKind, final, nVTableSlots), + package(package), + name(name), + nInterfaces(nInterfaces), + interfaces(interfaces), + nFields(nFields), + fields(fields), + nMethods(nMethods), + methods(methods) +{} + + +// +// Get the vtable entry at the given index. +// +inline VTableEntry &Class::getVTableEntry(uint32 vIndex) +{ + assert(vIndex < nVTableSlots); + return *(VTableEntry *)((ptr)this + vTableIndexToOffset(vIndex)); +} + + +// +// Initialize a new Interface object that describes essential information such as +// inheritance relationships of objects belonging to a single Java interface. +// +// package is the package that defined this interface, name is the unqualified +// name of this interface, and interfaces is an array of nInterfaces elements +// that lists all interfaces from which this interface derives. +// +inline Interface::Interface(Package &package, const char *name, + uint32 nInterfaces, Interface **interfaces, + uint32 nFields, Field **fields, + uint32 nMethods, Method **methods): + ClassOrInterface(*cInterface, tkInterface, false, 0, package, name, + nInterfaces, interfaces, + nFields, fields, + nMethods, methods) +{} + +#endif diff --git a/ef/Utilities/qa/constantpool/Makefile b/ef/Utilities/qa/constantpool/Makefile new file mode 100644 index 000000000000..ce18c1810503 --- /dev/null +++ b/ef/Utilities/qa/constantpool/Makefile @@ -0,0 +1,41 @@ +#!gmake +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +# +# Classreader Makefile +# + +DEPTH = ../.. + +EXECUTABLE = constantpool +OBJECTS = main.o ClassReader.o AttributeHandlers.o JavaTypes.o FloatUtils.o \ + FileReader.o Pool.o JavaObject.o ClassWorld.o FileWriter.o ClassGen.o\ + JavaBytecodes.o DebugUtils.o + + +# Define -DNO_NSPR to run without NSPR +COPTIONS = -DDEBUG -DDEBUG_LAURENT + +include $(DEPTH)/config/config.mk + + + + + + + + diff --git a/ef/Utilities/qa/constantpool/StringPool.h b/ef/Utilities/qa/constantpool/StringPool.h new file mode 100644 index 000000000000..d8e2b55a2615 --- /dev/null +++ b/ef/Utilities/qa/constantpool/StringPool.h @@ -0,0 +1,60 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#ifndef _STRING_POOL_H_ +#define _STRING_POOL_H_ + +#include "HashTable.h" + +class StrNode { + int32 dummy; +}; + +class StringPool : private HashTable { +public: + StringPool(Pool &p) : HashTable(p) { } + + /* Intern "str" if not already interned and return a pointer to + * the interned string + */ + const char *intern(const char *str) { + int hashIndex; + const char *key; + + if ((key = HashTable::get(str, 0, hashIndex)) != 0) + return key; + + return add(str, node, hashIndex); + } + + /* Returns a pointer to the interned string if it exists, NULL + * otherwise + */ + const char *get(const char *str) { + int hashIndex; + + return HashTable::get(str, 0, hashIndex); + } + +private: + StrNode node; +}; + +#endif /* _STRING_POOL_H_ */ + + diff --git a/ef/Utilities/qa/constantpool/constantpool.dsp b/ef/Utilities/qa/constantpool/constantpool.dsp new file mode 100644 index 000000000000..08b2d82a1d71 --- /dev/null +++ b/ef/Utilities/qa/constantpool/constantpool.dsp @@ -0,0 +1,196 @@ +# Microsoft Developer Studio Project File - Name="constantpool" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 5.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=constantpool - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "constantpool.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "constantpool.mak" CFG="constantpool - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "constantpool - Win32 Release" (based on\ + "Win32 (x86) Console Application") +!MESSAGE "constantpool - Win32 Debug" (based on\ + "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "constantpool - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "..\..\winbuild\Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "..\..\dist\WINNT4.0_DBG.OBJ\include\nspr20\pr" /I "..\Utilities" /I "..\ClassReader" /I "..\Reader" /I "..\CodeGen\include" /I "..\CodeGen\common" /I "genfiles" /I "..\RegAlloc\src\regalloc" /I "..\Runtime" /I "..\PrimitiveGraph" /I "..\ClassInfo" /I "..\..\Runtime" /I "..\..\PrimitiveGraph" /I "..\..\..\dist\WINNT4.0_DBG.OBJ\include\\" /I "..\..\Utilities" /I "..\..\ClassReader" /I "..\..\ClassInfo" /I "..\..\Reader" /I "..\..\FileReader" /D "NDEBUG" /D "RELEASE" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "EF_WINDOWS" /D "DEBUG" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib ..\..\..\dist\WINNT4.0_DBG.OBJ\lib\libnspr20.lib ..\..\..\dist\WINNT4.0_DBG.OBJ\lib\libplc20.lib /nologo /subsystem:console /debug /machine:I386 /Fixed:no +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "constantpool - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "..\..\winbuild\electric" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /w /W0 /Gm /GX /Zi /Od /I "." /I "..\..\Reader" /I "..\..\ClassInfo" /I "..\..\Runtime" /I "..\..\PrimitiveGraph" /I "..\..\..\dist\WINNT4.0_DBG.OBJ\include\\" /I "..\..\Utilities" /I "..\..\ClassReader" /I "..\..\ClassCentral" /D "_DEBUG" /D "DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "EF_WINDOWS" /FR /YX /FD /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib ..\..\..\dist\WINNT4.0_DBG.OBJ\lib\libnspr20.lib ..\..\..\dist\WINNT4.0_DBG.OBJ\lib\libplc20.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "constantpool - Win32 Release" +# Name "constantpool - Win32 Debug" +# Begin Group "Utilities" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Utilities\DebugUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Utilities\FloatUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Utilities\JavaBytecodes.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Utilities\JavaTypes.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Utilities\Pool.cpp +# End Source File +# End Group +# Begin Group "Runtime" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Runtime\ClassWorld.cpp +# End Source File +# End Group +# Begin Group "ConstantPool" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\AttributeHandlers.cpp +# End Source File +# Begin Source File + +SOURCE=.\AttributeHandlers.h +# End Source File +# Begin Source File + +SOURCE=.\Attributes.h +# End Source File +# Begin Source File + +SOURCE=.\ClassGen.cpp +# End Source File +# Begin Source File + +SOURCE=.\ClassGen.h +# End Source File +# Begin Source File + +SOURCE=.\ClassReader.cpp +# End Source File +# Begin Source File + +SOURCE=.\ClassReader.h +# End Source File +# Begin Source File + +SOURCE=.\ConstantPool.h +# End Source File +# Begin Source File + +SOURCE=.\FileReader.cpp +# End Source File +# Begin Source File + +SOURCE=.\FileReader.h +# End Source File +# Begin Source File + +SOURCE=.\FileWriter.cpp +# End Source File +# Begin Source File + +SOURCE=.\FileWriter.h +# End Source File +# Begin Source File + +SOURCE=.\InfoItem.h +# End Source File +# Begin Source File + +SOURCE=.\JavaObject.cpp +# End Source File +# End Group +# Begin Group "Reader" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Reader\Reader.cpp +# End Source File +# End Group +# Begin Group "FileReader" + +# PROP Default_Filter "" +# End Group +# Begin Source File + +SOURCE=.\main.cpp +# End Source File +# End Target +# End Project diff --git a/ef/Utilities/qa/constantpool/main.cpp b/ef/Utilities/qa/constantpool/main.cpp new file mode 100644 index 000000000000..950c8abeb8e4 --- /dev/null +++ b/ef/Utilities/qa/constantpool/main.cpp @@ -0,0 +1,130 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +/* main.cpp for constant pool edit */ + +#include "ClassReader.h" +#include "FileWriter.h" +#include "nspr.h" +#include "DebugUtils.h" +#include "JavaBytecodes.h" +#include "ClassGen.h" + +/* main */ +int main(int argc, char **argv) +{ + + //Check for the correct set of arguments. + if (argc < 3) { + printf("Error:\tillegal number of arguments\n"); + printf("Usage:\tconstantpool -d or\n"); + printf("\t\tconstantpool -m \n"); + return 1; + } + + CrError status; + Pool pool; + StringPool sp(pool); + char classname[256]; + + strcpy(classname,argv[2]); + strcat(classname,".class"); + + PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 1); + + //Create instance to read the classfile. + ClassFileReader reader(pool, sp, classname, &status); + + //Check for dump operation. + if (strcmp(argv[1],"-d") == 0) { + + char dumpfile[256]; + + strcpy(dumpfile,argv[2]); + strcat(dumpfile,".txt"); + + if (status != crErrorNone) { + printf("Cannot read class file:error (%d)\n", status); + return 1; + + } else { + + //Dump constant pool into a text file. + reader.dumpClass(dumpfile); + + printf("Read Class File\n"); + return 0; + + } + + } //End if strcmp. + + //Check for merge operation. + if (strcmp(argv[1],"-m") == 0 ) { + + + char filename[256]; + char classfile[256]; + + strcpy(filename,argv[2]); + strcat(filename,".txt"); + + strcpy(classfile,"temp/"); + strcat(classfile,argv[2]); + strcat(classfile,".class"); + + printf("Using %s to create %s\n",filename,classfile); + + //Create instance to write a new classfile. + FileWriter writer(classfile); + + //Open the dumpfile. + FILE *df; + df = fopen(filename,"r"); + if (!df) { + printf("Error: file does not exist."); + return 1; + } + + + /* Create the new classfile. */ + + createClass(df,writer,reader); + + printf("Created new classfile.\n"); + fclose(df); + return 0; + + } //End if strcmp. + + printf("Error: don't know what to do.\n"); + return 1; + +} + + + + + + + + + + + + diff --git a/ef/Utilities/qa/constantpool/test.class b/ef/Utilities/qa/constantpool/test.class new file mode 100644 index 000000000000..f1d3646c7425 Binary files /dev/null and b/ef/Utilities/qa/constantpool/test.class differ diff --git a/ef/Utilities/zlib/Makefile b/ef/Utilities/zlib/Makefile new file mode 100644 index 000000000000..d317e44fd43f --- /dev/null +++ b/ef/Utilities/zlib/Makefile @@ -0,0 +1,47 @@ +#!gmake +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +####################################################################### +# (1) Include manifest file # +####################################################################### + +include manifest.mn + +####################################################################### +# (2) Include "component" configuration information. # +####################################################################### + +include $(DEPTH)/config/config.mk + +####################################################################### +# (3) Include "local" platform-dependent assignments (OPTIONAL). # +####################################################################### + + + +####################################################################### +# (4) Execute "component" rules. (OPTIONAL) # +####################################################################### + +include $(DEPTH)/config/rules.mk + +####################################################################### +# (7) Execute "local" rules. (OPTIONAL). # +####################################################################### + + + diff --git a/ef/Utilities/zlib/adler32.c b/ef/Utilities/zlib/adler32.c new file mode 100644 index 000000000000..480ca700d0c4 --- /dev/null +++ b/ef/Utilities/zlib/adler32.c @@ -0,0 +1,46 @@ +/* adler32.c -- compute the Adler-32 checksum of a data stream + * Copyright (C) 1995-1996 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zlib.h" + +#define BASE 65521L /* largest prime smaller than 65536 */ +#define NMAX 5552 +/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ + +#define DO1(buf,i) {s1 += buf[i]; s2 += s1;} +#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1); +#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2); +#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4); +#define DO16(buf) DO8(buf,0); DO8(buf,8); + +/* ========================================================================= */ +uLong adler32(adler, buf, len) + uLong adler; + const Bytef *buf; + uInt len; +{ + unsigned long s1 = adler & 0xffff; + unsigned long s2 = (adler >> 16) & 0xffff; + int k; + + if (buf == Z_NULL) return 1L; + + while (len > 0) { + k = len < NMAX ? len : NMAX; + len -= k; + while (k >= 16) { + DO16(buf); + buf += 16; + k -= 16; + } + if (k != 0) do { + s1 += *buf++; + s2 += s1; + } while (--k); + s1 %= BASE; + s2 %= BASE; + } + return (s2 << 16) | s1; +} diff --git a/ef/Utilities/zlib/compress.c b/ef/Utilities/zlib/compress.c new file mode 100644 index 000000000000..773a01136b42 --- /dev/null +++ b/ef/Utilities/zlib/compress.c @@ -0,0 +1,55 @@ +/* compress.c -- compress a memory buffer + * Copyright (C) 1995-1996 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zlib.h" + +/* =========================================================================== + Compresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total + size of the destination buffer, which must be at least 0.1% larger than + sourceLen plus 8 bytes. Upon exit, destLen is the actual size of the + compressed buffer. + This function can be used to compress a whole file at once if the + input file is mmap'ed. + compress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer. +*/ +int compress (dest, destLen, source, sourceLen) + Bytef *dest; + uLongf *destLen; + const Bytef *source; + uLong sourceLen; +{ + z_stream stream; + int err; + + stream.next_in = (Bytef*)source; + stream.avail_in = (uInt)sourceLen; +#ifdef MAXSEG_64K + /* Check for source > 64K on 16-bit machine: */ + if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR; +#endif + stream.next_out = dest; + stream.avail_out = (uInt)*destLen; + if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR; + + stream.zalloc = (alloc_func)0; + stream.zfree = (free_func)0; + stream.opaque = (voidpf)0; + + err = deflateInit(&stream, Z_DEFAULT_COMPRESSION); + if (err != Z_OK) return err; + + err = deflate(&stream, Z_FINISH); + if (err != Z_STREAM_END) { + deflateEnd(&stream); + return err == Z_OK ? Z_BUF_ERROR : err; + } + *destLen = stream.total_out; + + err = deflateEnd(&stream); + return err; +} diff --git a/ef/Utilities/zlib/crc32.c b/ef/Utilities/zlib/crc32.c new file mode 100644 index 000000000000..f8bf11e13273 --- /dev/null +++ b/ef/Utilities/zlib/crc32.c @@ -0,0 +1,160 @@ +/* crc32.c -- compute the CRC-32 of a data stream + * Copyright (C) 1995-1996 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zlib.h" + +#define local static + +#ifdef DYNAMIC_CRC_TABLE + +local int crc_table_empty = 1; +local uLongf crc_table[256]; +local void make_crc_table OF((void)); + +/* + Generate a table for a byte-wise 32-bit CRC calculation on the polynomial: + x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1. + + Polynomials over GF(2) are represented in binary, one bit per coefficient, + with the lowest powers in the most significant bit. Then adding polynomials + is just exclusive-or, and multiplying a polynomial by x is a right shift by + one. If we call the above polynomial p, and represent a byte as the + polynomial q, also with the lowest power in the most significant bit (so the + byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p, + where a mod b means the remainder after dividing a by b. + + This calculation is done using the shift-register method of multiplying and + taking the remainder. The register is initialized to zero, and for each + incoming bit, x^32 is added mod p to the register if the bit is a one (where + x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by + x (which is shifting right by one and adding x^32 mod p if the bit shifted + out is a one). We start with the highest power (least significant bit) of + q and repeat for all eight bits of q. + + The table is simply the CRC of all possible eight bit values. This is all + the information needed to generate CRC's on data a byte at a time for all + combinations of CRC register values and incoming bytes. +*/ +local void make_crc_table() +{ + uLong c; + int n, k; + uLong poly; /* polynomial exclusive-or pattern */ + /* terms of polynomial defining this crc (except x^32): */ + static Byte p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26}; + + /* make exclusive-or pattern from polynomial (0xedb88320L) */ + poly = 0L; + for (n = 0; n < sizeof(p)/sizeof(Byte); n++) + poly |= 1L << (31 - p[n]); + + for (n = 0; n < 256; n++) + { + c = (uLong)n; + for (k = 0; k < 8; k++) + c = c & 1 ? poly ^ (c >> 1) : c >> 1; + crc_table[n] = c; + } + crc_table_empty = 0; +} +#else +/* ======================================================================== + * Table of CRC-32's of all single-byte values (made by make_crc_table) + */ +local uLongf crc_table[256] = { + 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, + 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L, + 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, + 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL, + 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L, + 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L, + 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, + 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL, + 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L, + 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL, + 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, + 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L, + 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L, + 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL, + 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, + 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L, + 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL, + 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L, + 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, + 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L, + 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL, + 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L, + 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L, + 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL, + 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L, + 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L, + 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L, + 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L, + 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L, + 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL, + 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, + 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L, + 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L, + 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL, + 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL, + 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L, + 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL, + 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L, + 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, + 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L, + 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL, + 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L, + 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, + 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL, + 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L, + 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L, + 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, + 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L, + 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L, + 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L, + 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, + 0x2d02ef8dL +}; +#endif + +/* ========================================================================= + * This function can be used by asm versions of crc32() + */ +uLongf *get_crc_table() +{ +#ifdef DYNAMIC_CRC_TABLE + if (crc_table_empty) make_crc_table(); +#endif + return (uLongf *)crc_table; +} + +/* ========================================================================= */ +#define DO1(buf) crc = crc_table[((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8); +#define DO2(buf) DO1(buf); DO1(buf); +#define DO4(buf) DO2(buf); DO2(buf); +#define DO8(buf) DO4(buf); DO4(buf); + +/* ========================================================================= */ +uLong crc32(crc, buf, len) + uLong crc; + const Bytef *buf; + uInt len; +{ + if (buf == Z_NULL) return 0L; +#ifdef DYNAMIC_CRC_TABLE + if (crc_table_empty) + make_crc_table(); +#endif + crc = crc ^ 0xffffffffL; + while (len >= 8) + { + DO8(buf); + len -= 8; + } + if (len) do { + DO1(buf); + } while (--len); + return crc ^ 0xffffffffL; +} diff --git a/ef/Utilities/zlib/deflate.c b/ef/Utilities/zlib/deflate.c new file mode 100644 index 000000000000..53711a268509 --- /dev/null +++ b/ef/Utilities/zlib/deflate.c @@ -0,0 +1,1205 @@ +/* deflate.c -- compress data using the deflation algorithm + * Copyright (C) 1995-1996 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + * ALGORITHM + * + * The "deflation" process depends on being able to identify portions + * of the input text which are identical to earlier input (within a + * sliding window trailing behind the input currently being processed). + * + * The most straightforward technique turns out to be the fastest for + * most input files: try all possible matches and select the longest. + * The key feature of this algorithm is that insertions into the string + * dictionary are very simple and thus fast, and deletions are avoided + * completely. Insertions are performed at each input character, whereas + * string matches are performed only when the previous match ends. So it + * is preferable to spend more time in matches to allow very fast string + * insertions and avoid deletions. The matching algorithm for small + * strings is inspired from that of Rabin & Karp. A brute force approach + * is used to find longer strings when a small match has been found. + * A similar algorithm is used in comic (by Jan-Mark Wams) and freeze + * (by Leonid Broukhis). + * A previous version of this file used a more sophisticated algorithm + * (by Fiala and Greene) which is guaranteed to run in linear amortized + * time, but has a larger average cost, uses more memory and is patented. + * However the F&G algorithm may be faster for some highly redundant + * files if the parameter max_chain_length (described below) is too large. + * + * ACKNOWLEDGEMENTS + * + * The idea of lazy evaluation of matches is due to Jan-Mark Wams, and + * I found it in 'freeze' written by Leonid Broukhis. + * Thanks to many people for bug reports and testing. + * + * REFERENCES + * + * Deutsch, L.P.,"'Deflate' Compressed Data Format Specification". + * Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc + * + * A description of the Rabin and Karp algorithm is given in the book + * "Algorithms" by R. Sedgewick, Addison-Wesley, p252. + * + * Fiala,E.R., and Greene,D.H. + * Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595 + * + */ + +#include "deflate.h" + +char deflate_copyright[] = " deflate 1.0.4 Copyright 1995-1996 Jean-loup Gailly "; +/* + If you use the zlib library in a product, an acknowledgment is welcome + in the documentation of your product. If for some reason you cannot + include such an acknowledgment, I would appreciate that you keep this + copyright string in the executable of your product. + */ + +/* =========================================================================== + * Function prototypes. + */ +typedef enum { + need_more, /* block not completed, need more input or more output */ + block_done, /* block flush performed */ + finish_started, /* finish started, need only more output at next deflate */ + finish_done /* finish done, accept no more input or output */ +} block_state; + +typedef block_state (*compress_func) OF((deflate_state *s, int flush)); +/* Compression function. Returns the block state after the call. */ + +local void fill_window OF((deflate_state *s)); +local block_state deflate_stored OF((deflate_state *s, int flush)); +local block_state deflate_fast OF((deflate_state *s, int flush)); +local block_state deflate_slow OF((deflate_state *s, int flush)); +local void lm_init OF((deflate_state *s)); +local uInt longest_match OF((deflate_state *s, IPos cur_match)); +local void putShortMSB OF((deflate_state *s, uInt b)); +local void flush_pending OF((z_streamp strm)); +local int read_buf OF((z_streamp strm, charf *buf, unsigned size)); +#ifdef ASMV + void match_init OF((void)); /* asm code initialization */ +#endif + +#ifdef DEBUG_ZIP +local void check_match OF((deflate_state *s, IPos start, IPos match, + int length)); +#endif + +/* =========================================================================== + * Local data + */ + +#define NIL 0 +/* Tail of hash chains */ + +#ifndef TOO_FAR +# define TOO_FAR 4096 +#endif +/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */ + +#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) +/* Minimum amount of lookahead, except at the end of the input file. + * See deflate.c for comments about the MIN_MATCH+1. + */ + +/* Values for max_lazy_match, good_match and max_chain_length, depending on + * the desired pack level (0..9). The values given below have been tuned to + * exclude worst case performance for pathological files. Better values may be + * found for specific files. + */ +typedef struct config_s { + ush good_length; /* reduce lazy search above this match length */ + ush max_lazy; /* do not perform lazy search above this match length */ + ush nice_length; /* quit search above this match length */ + ush max_chain; + compress_func func; +} config; + +local config configuration_table[10] = { +/* good lazy nice chain */ +/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ +/* 1 */ {4, 4, 8, 4, deflate_fast}, /* maximum speed, no lazy matches */ +/* 2 */ {4, 5, 16, 8, deflate_fast}, +/* 3 */ {4, 6, 32, 32, deflate_fast}, + +/* 4 */ {4, 4, 16, 16, deflate_slow}, /* lazy matches */ +/* 5 */ {8, 16, 32, 32, deflate_slow}, +/* 6 */ {8, 16, 128, 128, deflate_slow}, +/* 7 */ {8, 32, 128, 256, deflate_slow}, +/* 8 */ {32, 128, 258, 1024, deflate_slow}, +/* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* maximum compression */ + +/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4 + * For deflate_fast() (levels <= 3) good is ignored and lazy has a different + * meaning. + */ + +#define EQUAL 0 +/* result of memcmp for equal strings */ + +struct static_tree_desc_s {int dummy;}; /* for buggy compilers */ + +/* =========================================================================== + * Update a hash value with the given input byte + * IN assertion: all calls to to UPDATE_HASH are made with consecutive + * input characters, so that a running hash key can be computed from the + * previous key instead of complete recalculation each time. + */ +#define UPDATE_HASH(s,h,c) (h = (((h)<hash_shift) ^ (c)) & s->hash_mask) + + +/* =========================================================================== + * Insert string str in the dictionary and set match_head to the previous head + * of the hash chain (the most recent string with same hash key). Return + * the previous length of the hash chain. + * IN assertion: all calls to to INSERT_STRING are made with consecutive + * input characters and the first MIN_MATCH bytes of str are valid + * (except for the last MIN_MATCH-1 bytes of the input file). + */ +#define INSERT_STRING(s, str, match_head) \ + (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ + s->prev[(str) & s->w_mask] = match_head = s->head[s->ins_h], \ + s->head[s->ins_h] = (Pos)(str)) + +/* =========================================================================== + * Initialize the hash table (avoiding 64K overflow for 16 bit systems). + * prev[] will be initialized on the fly. + */ +#define CLEAR_HASH(s) \ + s->head[s->hash_size-1] = NIL; \ + zmemzero((charf *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head)); + +/* ========================================================================= */ +int deflateInit_(strm, level, version, stream_size) + z_streamp strm; + int level; + const char *version; + int stream_size; +{ + return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL, + Z_DEFAULT_STRATEGY, version, stream_size); + /* To do: ignore strm->next_in if we use it as window */ +} + +/* ========================================================================= */ +int deflateInit2_(strm, level, method, windowBits, memLevel, strategy, + version, stream_size) + z_streamp strm; + int level; + int method; + int windowBits; + int memLevel; + int strategy; + const char *version; + int stream_size; +{ + deflate_state *s; + int noheader = 0; + + ushf *overlay; + /* We overlay pending_buf and d_buf+l_buf. This works since the average + * output size for (length,distance) codes is <= 24 bits. + */ + + if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || + stream_size != sizeof(z_stream)) { + return Z_VERSION_ERROR; + } + if (strm == Z_NULL) return Z_STREAM_ERROR; + + strm->msg = Z_NULL; + if (strm->zalloc == Z_NULL) { + strm->zalloc = zcalloc; + strm->opaque = (voidpf)0; + } + if (strm->zfree == Z_NULL) strm->zfree = zcfree; + + if (level == Z_DEFAULT_COMPRESSION) level = 6; + + if (windowBits < 0) { /* undocumented feature: suppress zlib header */ + noheader = 1; + windowBits = -windowBits; + } + if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED || + windowBits < 8 || windowBits > 15 || level < 0 || level > 9 || + strategy < 0 || strategy > Z_HUFFMAN_ONLY) { + return Z_STREAM_ERROR; + } + s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state)); + if (s == Z_NULL) return Z_MEM_ERROR; + strm->state = (struct internal_state FAR *)s; + s->strm = strm; + + s->noheader = noheader; + s->w_bits = windowBits; + s->w_size = 1 << s->w_bits; + s->w_mask = s->w_size - 1; + + s->hash_bits = memLevel + 7; + s->hash_size = 1 << s->hash_bits; + s->hash_mask = s->hash_size - 1; + s->hash_shift = ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH); + + s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte)); + s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos)); + s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos)); + + s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */ + + overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2); + s->pending_buf = (uchf *) overlay; + + if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL || + s->pending_buf == Z_NULL) { + strm->msg = (char*)ERR_MSG(Z_MEM_ERROR); + deflateEnd (strm); + return Z_MEM_ERROR; + } + s->d_buf = overlay + s->lit_bufsize/sizeof(ush); + s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize; + + s->level = level; + s->strategy = strategy; + s->method = (Byte)method; + + return deflateReset(strm); +} + +/* ========================================================================= */ +int deflateSetDictionary (strm, dictionary, dictLength) + z_streamp strm; + const Bytef *dictionary; + uInt dictLength; +{ + deflate_state *s; + uInt length = dictLength; + uInt n; + IPos hash_head = 0; + + if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL || + strm->state->status != INIT_STATE) return Z_STREAM_ERROR; + + s = strm->state; + strm->adler = adler32(strm->adler, dictionary, dictLength); + + if (length < MIN_MATCH) return Z_OK; + if (length > MAX_DIST(s)) { + length = MAX_DIST(s); + dictionary += dictLength - length; + } + zmemcpy((charf *)s->window, dictionary, length); + s->strstart = length; + s->block_start = (long)length; + + /* Insert all strings in the hash table (except for the last two bytes). + * s->lookahead stays null, so s->ins_h will be recomputed at the next + * call of fill_window. + */ + s->ins_h = s->window[0]; + UPDATE_HASH(s, s->ins_h, s->window[1]); + for (n = 0; n <= length - MIN_MATCH; n++) { + INSERT_STRING(s, n, hash_head); + } + if (hash_head) hash_head = 0; /* to make compiler happy */ + return Z_OK; +} + +/* ========================================================================= */ +int deflateReset (strm) + z_streamp strm; +{ + deflate_state *s; + + if (strm == Z_NULL || strm->state == Z_NULL || + strm->zalloc == Z_NULL || strm->zfree == Z_NULL) return Z_STREAM_ERROR; + + strm->total_in = strm->total_out = 0; + strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */ + strm->data_type = Z_UNKNOWN; + + s = (deflate_state *)strm->state; + s->pending = 0; + s->pending_out = s->pending_buf; + + if (s->noheader < 0) { + s->noheader = 0; /* was set to -1 by deflate(..., Z_FINISH); */ + } + s->status = s->noheader ? BUSY_STATE : INIT_STATE; + strm->adler = 1; + s->last_flush = Z_NO_FLUSH; + + _tr_init(s); + lm_init(s); + + return Z_OK; +} + +/* ========================================================================= */ +int deflateParams(strm, level, strategy) + z_streamp strm; + int level; + int strategy; +{ + deflate_state *s; + compress_func func; + int err = Z_OK; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + s = strm->state; + + if (level == Z_DEFAULT_COMPRESSION) { + level = 6; + } + if (level < 0 || level > 9 || strategy < 0 || strategy > Z_HUFFMAN_ONLY) { + return Z_STREAM_ERROR; + } + func = configuration_table[s->level].func; + + if (func != configuration_table[level].func && strm->total_in != 0) { + /* Flush the last buffer: */ + err = deflate(strm, Z_PARTIAL_FLUSH); + } + if (s->level != level) { + s->level = level; + s->max_lazy_match = configuration_table[level].max_lazy; + s->good_match = configuration_table[level].good_length; + s->nice_match = configuration_table[level].nice_length; + s->max_chain_length = configuration_table[level].max_chain; + } + s->strategy = strategy; + return err; +} + +/* ========================================================================= + * Put a short in the pending buffer. The 16-bit value is put in MSB order. + * IN assertion: the stream state is correct and there is enough room in + * pending_buf. + */ +local void putShortMSB (s, b) + deflate_state *s; + uInt b; +{ + put_byte(s, (Byte)(b >> 8)); + put_byte(s, (Byte)(b & 0xff)); +} + +/* ========================================================================= + * Flush as much pending output as possible. All deflate() output goes + * through this function so some applications may wish to modify it + * to avoid allocating a large strm->next_out buffer and copying into it. + * (See also read_buf()). + */ +local void flush_pending(strm) + z_streamp strm; +{ + unsigned len = strm->state->pending; + + if (len > strm->avail_out) len = strm->avail_out; + if (len == 0) return; + + zmemcpy(strm->next_out, strm->state->pending_out, len); + strm->next_out += len; + strm->state->pending_out += len; + strm->total_out += len; + strm->avail_out -= len; + strm->state->pending -= len; + if (strm->state->pending == 0) { + strm->state->pending_out = strm->state->pending_buf; + } +} + +/* ========================================================================= */ +int deflate (strm, flush) + z_streamp strm; + int flush; +{ + int old_flush; /* value of flush param for previous deflate call */ + deflate_state *s; + + if (strm == Z_NULL || strm->state == Z_NULL || + flush > Z_FINISH || flush < 0) { + return Z_STREAM_ERROR; + } + s = strm->state; + + if (strm->next_out == Z_NULL || + (strm->next_in == Z_NULL && strm->avail_in != 0) || + (s->status == FINISH_STATE && flush != Z_FINISH)) { + ERR_RETURN(strm, Z_STREAM_ERROR); + } + if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR); + + s->strm = strm; /* just in case */ + old_flush = s->last_flush; + s->last_flush = flush; + + /* Write the zlib header */ + if (s->status == INIT_STATE) { + + uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8; + uInt level_flags = (s->level-1) >> 1; + + if (level_flags > 3) level_flags = 3; + header |= (level_flags << 6); + if (s->strstart != 0) header |= PRESET_DICT; + header += 31 - (header % 31); + + s->status = BUSY_STATE; + putShortMSB(s, header); + + /* Save the adler32 of the preset dictionary: */ + if (s->strstart != 0) { + putShortMSB(s, (uInt)(strm->adler >> 16)); + putShortMSB(s, (uInt)(strm->adler & 0xffff)); + } + strm->adler = 1L; + } + + /* Flush as much pending output as possible */ + if (s->pending != 0) { + flush_pending(strm); + if (strm->avail_out == 0) { + /* Since avail_out is 0, deflate will be called again with + * more output space, but possibly with both pending and + * avail_in equal to zero. There won't be anything to do, + * but this is not an error situation so make sure we + * return OK instead of BUF_ERROR at next call of deflate: + */ + s->last_flush = -1; + return Z_OK; + } + + /* Make sure there is something to do and avoid duplicate consecutive + * flushes. For repeated and useless calls with Z_FINISH, we keep + * returning Z_STREAM_END instead of Z_BUFF_ERROR. + */ + } else if (strm->avail_in == 0 && flush <= old_flush && + flush != Z_FINISH) { + ERR_RETURN(strm, Z_BUF_ERROR); + } + + /* User must not provide more input after the first FINISH: */ + if (s->status == FINISH_STATE && strm->avail_in != 0) { + ERR_RETURN(strm, Z_BUF_ERROR); + } + + /* Start a new block or continue the current one. + */ + if (strm->avail_in != 0 || s->lookahead != 0 || + (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) { + block_state bstate; + + bstate = (*(configuration_table[s->level].func))(s, flush); + + if (bstate == finish_started || bstate == finish_done) { + s->status = FINISH_STATE; + } + if (bstate == need_more || bstate == finish_started) { + if (strm->avail_out == 0) { + s->last_flush = -1; /* avoid BUF_ERROR next call, see above */ + } + return Z_OK; + /* If flush != Z_NO_FLUSH && avail_out == 0, the next call + * of deflate should use the same flush parameter to make sure + * that the flush is complete. So we don't have to output an + * empty block here, this will be done at next call. This also + * ensures that for a very small output buffer, we emit at most + * one empty block. + */ + } + if (bstate == block_done) { + if (flush == Z_PARTIAL_FLUSH) { + _tr_align(s); + } else { /* FULL_FLUSH or SYNC_FLUSH */ + _tr_stored_block(s, (char*)0, 0L, 0); + /* For a full flush, this empty block will be recognized + * as a special marker by inflate_sync(). + */ + if (flush == Z_FULL_FLUSH) { + CLEAR_HASH(s); /* forget history */ + } + } + flush_pending(strm); + if (strm->avail_out == 0) { + s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */ + return Z_OK; + } + } + } + Assert(strm->avail_out > 0, "bug2"); + + if (flush != Z_FINISH) return Z_OK; + if (s->noheader) return Z_STREAM_END; + + /* Write the zlib trailer (adler32) */ + putShortMSB(s, (uInt)(strm->adler >> 16)); + putShortMSB(s, (uInt)(strm->adler & 0xffff)); + flush_pending(strm); + /* If avail_out is zero, the application will call deflate again + * to flush the rest. + */ + s->noheader = -1; /* write the trailer only once! */ + return s->pending != 0 ? Z_OK : Z_STREAM_END; +} + +/* ========================================================================= */ +int deflateEnd (strm) + z_streamp strm; +{ + int status; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + + /* Deallocate in reverse order of allocations: */ + TRY_FREE(strm, strm->state->pending_buf); + TRY_FREE(strm, strm->state->head); + TRY_FREE(strm, strm->state->prev); + TRY_FREE(strm, strm->state->window); + + status = strm->state->status; + ZFREE(strm, strm->state); + strm->state = Z_NULL; + + return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK; +} + +/* ========================================================================= */ +int deflateCopy (dest, source) + z_streamp dest; + z_streamp source; +{ + if (source == Z_NULL || dest == Z_NULL || source->state == Z_NULL) { + return Z_STREAM_ERROR; + } + *dest = *source; + return Z_STREAM_ERROR; /* to be implemented */ +#if 0 + dest->state = (struct internal_state FAR *) + (*dest->zalloc)(1, sizeof(deflate_state)); + if (dest->state == Z_NULL) return Z_MEM_ERROR; + + *(dest->state) = *(source->state); + return Z_OK; +#endif +} + +/* =========================================================================== + * Read a new buffer from the current input stream, update the adler32 + * and total number of bytes read. All deflate() input goes through + * this function so some applications may wish to modify it to avoid + * allocating a large strm->next_in buffer and copying from it. + * (See also flush_pending()). + */ +local int read_buf(strm, buf, size) + z_streamp strm; + charf *buf; + unsigned size; +{ + unsigned len = strm->avail_in; + + if (len > size) len = size; + if (len == 0) return 0; + + strm->avail_in -= len; + + if (!strm->state->noheader) { + strm->adler = adler32(strm->adler, strm->next_in, len); + } + zmemcpy(buf, strm->next_in, len); + strm->next_in += len; + strm->total_in += len; + + return (int)len; +} + +/* =========================================================================== + * Initialize the "longest match" routines for a new zlib stream + */ +local void lm_init (s) + deflate_state *s; +{ + s->window_size = (ulg)2L*s->w_size; + + CLEAR_HASH(s); + + /* Set the default configuration parameters: + */ + s->max_lazy_match = configuration_table[s->level].max_lazy; + s->good_match = configuration_table[s->level].good_length; + s->nice_match = configuration_table[s->level].nice_length; + s->max_chain_length = configuration_table[s->level].max_chain; + + s->strstart = 0; + s->block_start = 0L; + s->lookahead = 0; + s->match_length = s->prev_length = MIN_MATCH-1; + s->match_available = 0; + s->ins_h = 0; +#ifdef ASMV + match_init(); /* initialize the asm code */ +#endif +} + +/* =========================================================================== + * Set match_start to the longest match starting at the given string and + * return its length. Matches shorter or equal to prev_length are discarded, + * in which case the result is equal to prev_length and match_start is + * garbage. + * IN assertions: cur_match is the head of the hash chain for the current + * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1 + * OUT assertion: the match length is not greater than s->lookahead. + */ +#ifndef ASMV +/* For 80x86 and 680x0, an optimized version will be provided in match.asm or + * match.S. The code will be functionally equivalent. + */ +local uInt longest_match(s, cur_match) + deflate_state *s; + IPos cur_match; /* current match */ +{ + unsigned chain_length = s->max_chain_length;/* max hash chain length */ + register Bytef *scan = s->window + s->strstart; /* current string */ + register Bytef *match; /* matched string */ + register int len; /* length of current match */ + int best_len = s->prev_length; /* best match length so far */ + int nice_match = s->nice_match; /* stop if match long enough */ + IPos limit = s->strstart > (IPos)MAX_DIST(s) ? + s->strstart - (IPos)MAX_DIST(s) : NIL; + /* Stop when cur_match becomes <= limit. To simplify the code, + * we prevent matches with the string of window index 0. + */ + Posf *prev = s->prev; + uInt wmask = s->w_mask; + +#ifdef UNALIGNED_OK + /* Compare two bytes at a time. Note: this is not always beneficial. + * Try with and without -DUNALIGNED_OK to check. + */ + register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1; + register ush scan_start = *(ushf*)scan; + register ush scan_end = *(ushf*)(scan+best_len-1); +#else + register Bytef *strend = s->window + s->strstart + MAX_MATCH; + register Byte scan_end1 = scan[best_len-1]; + register Byte scan_end = scan[best_len]; +#endif + + /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. + * It is easy to get rid of this optimization if necessary. + */ + Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); + + /* Do not waste too much time if we already have a good match: */ + if (s->prev_length >= s->good_match) { + chain_length >>= 2; + } + /* Do not look for matches beyond the end of the input. This is necessary + * to make deflate deterministic. + */ + if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; + + Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); + + do { + Assert(cur_match < s->strstart, "no future"); + match = s->window + cur_match; + + /* Skip to next match if the match length cannot increase + * or if the match length is less than 2: + */ +#if (defined(UNALIGNED_OK) && MAX_MATCH == 258) + /* This code assumes sizeof(unsigned short) == 2. Do not use + * UNALIGNED_OK if your compiler uses a different size. + */ + if (*(ushf*)(match+best_len-1) != scan_end || + *(ushf*)match != scan_start) continue; + + /* It is not necessary to compare scan[2] and match[2] since they are + * always equal when the other bytes match, given that the hash keys + * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at + * strstart+3, +5, ... up to strstart+257. We check for insufficient + * lookahead only every 4th comparison; the 128th check will be made + * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is + * necessary to put more guard bytes at the end of the window, or + * to check more often for insufficient lookahead. + */ + Assert(scan[2] == match[2], "scan[2]?"); + scan++, match++; + do { + } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) && + *(ushf*)(scan+=2) == *(ushf*)(match+=2) && + *(ushf*)(scan+=2) == *(ushf*)(match+=2) && + *(ushf*)(scan+=2) == *(ushf*)(match+=2) && + scan < strend); + /* The funny "do {}" generates better code on most compilers */ + + /* Here, scan <= window+strstart+257 */ + Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); + if (*scan == *match) scan++; + + len = (MAX_MATCH - 1) - (int)(strend-scan); + scan = strend - (MAX_MATCH-1); + +#else /* UNALIGNED_OK */ + + if (match[best_len] != scan_end || + match[best_len-1] != scan_end1 || + *match != *scan || + *++match != scan[1]) continue; + + /* The check at best_len-1 can be removed because it will be made + * again later. (This heuristic is not always a win.) + * It is not necessary to compare scan[2] and match[2] since they + * are always equal when the other bytes match, given that + * the hash keys are equal and that HASH_BITS >= 8. + */ + scan += 2, match++; + Assert(*scan == *match, "match[2]?"); + + /* We check for insufficient lookahead only every 8th comparison; + * the 256th check will be made at strstart+258. + */ + do { + } while (*++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + scan < strend); + + Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); + + len = MAX_MATCH - (int)(strend - scan); + scan = strend - MAX_MATCH; + +#endif /* UNALIGNED_OK */ + + if (len > best_len) { + s->match_start = cur_match; + best_len = len; + if (len >= nice_match) break; +#ifdef UNALIGNED_OK + scan_end = *(ushf*)(scan+best_len-1); +#else + scan_end1 = scan[best_len-1]; + scan_end = scan[best_len]; +#endif + } + } while ((cur_match = prev[cur_match & wmask]) > limit + && --chain_length != 0); + + if ((uInt)best_len <= s->lookahead) return best_len; + return s->lookahead; +} +#endif /* ASMV */ + +#ifdef DEBUG_ZIP +/* =========================================================================== + * Check that the match at match_start is indeed a match. + */ +local void check_match(s, start, match, length) + deflate_state *s; + IPos start, match; + int length; +{ + /* check that the match is indeed a match */ + if (zmemcmp((charf *)s->window + match, + (charf *)s->window + start, length) != EQUAL) { + fprintf(stderr, " start %u, match %u, length %d\n", + start, match, length); + do { + fprintf(stderr, "%c%c", s->window[match++], s->window[start++]); + } while (--length != 0); + z_error("invalid match"); + } + if (verbose > 1) { + fprintf(stderr,"\\[%d,%d]", start-match, length); + do { putc(s->window[start++], stderr); } while (--length != 0); + } +} +#else +# define check_match(s, start, match, length) +#endif + +/* =========================================================================== + * Fill the window when the lookahead becomes insufficient. + * Updates strstart and lookahead. + * + * IN assertion: lookahead < MIN_LOOKAHEAD + * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD + * At least one byte has been read, or avail_in == 0; reads are + * performed for at least two bytes (required for the zip translate_eol + * option -- not supported here). + */ +local void fill_window(s) + deflate_state *s; +{ + register unsigned n, m; + register Posf *p; + unsigned more; /* Amount of free space at the end of the window. */ + uInt wsize = s->w_size; + + do { + more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart); + + /* Deal with !@#$% 64K limit: */ + if (more == 0 && s->strstart == 0 && s->lookahead == 0) { + more = wsize; + + } else if (more == (unsigned)(-1)) { + /* Very unlikely, but possible on 16 bit machine if strstart == 0 + * and lookahead == 1 (input done one byte at time) + */ + more--; + + /* If the window is almost full and there is insufficient lookahead, + * move the upper half to the lower one to make room in the upper half. + */ + } else if (s->strstart >= wsize+MAX_DIST(s)) { + + zmemcpy((charf *)s->window, (charf *)s->window+wsize, + (unsigned)wsize); + s->match_start -= wsize; + s->strstart -= wsize; /* we now have strstart >= MAX_DIST */ + + s->block_start -= (long) wsize; + + /* Slide the hash table (could be avoided with 32 bit values + at the expense of memory usage): + */ + n = s->hash_size; + p = &s->head[n]; + do { + m = *--p; + *p = (Pos)(m >= wsize ? m-wsize : NIL); + } while (--n); + + n = wsize; + p = &s->prev[n]; + do { + m = *--p; + *p = (Pos)(m >= wsize ? m-wsize : NIL); + /* If n is not on any hash chain, prev[n] is garbage but + * its value will never be used. + */ + } while (--n); + + more += wsize; + } + if (s->strm->avail_in == 0) return; + + /* If there was no sliding: + * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 && + * more == window_size - lookahead - strstart + * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1) + * => more >= window_size - 2*WSIZE + 2 + * In the BIG_MEM or MMAP case (not yet supported), + * window_size == input_size + MIN_LOOKAHEAD && + * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD. + * Otherwise, window_size == 2*WSIZE so more >= 2. + * If there was sliding, more >= WSIZE. So in all cases, more >= 2. + */ + Assert(more >= 2, "more < 2"); + + n = read_buf(s->strm, (charf *)s->window + s->strstart + s->lookahead, + more); + s->lookahead += n; + + /* Initialize the hash value now that we have some input: */ + if (s->lookahead >= MIN_MATCH) { + s->ins_h = s->window[s->strstart]; + UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]); +#if MIN_MATCH != 3 + Call UPDATE_HASH() MIN_MATCH-3 more times +#endif + } + /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage, + * but this is not important since only literal bytes will be emitted. + */ + + } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0); +} + +/* =========================================================================== + * Flush the current block, with given end-of-file flag. + * IN assertion: strstart is set to the end of the current match. + */ +#define FLUSH_BLOCK_ONLY(s, eof) { \ + _tr_flush_block(s, (s->block_start >= 0L ? \ + (charf *)&s->window[(unsigned)s->block_start] : \ + (charf *)Z_NULL), \ + (ulg)((long)s->strstart - s->block_start), \ + (eof)); \ + s->block_start = s->strstart; \ + flush_pending(s->strm); \ + Tracev((stderr,"[FLUSH]")); \ +} + +/* Same but force premature exit if necessary. */ +#define FLUSH_BLOCK(s, eof) { \ + FLUSH_BLOCK_ONLY(s, eof); \ + if (s->strm->avail_out == 0) return (eof) ? finish_started : need_more; \ +} + +/* =========================================================================== + * Copy without compression as much as possible from the input stream, return + * the current block state. + * This function does not insert new strings in the dictionary since + * uncompressible data is probably not useful. This function is used + * only for the level=0 compression option. + * NOTE: this function should be optimized to avoid extra copying. + */ +local block_state deflate_stored(s, flush) + deflate_state *s; + int flush; +{ + for (;;) { + /* Fill the window as much as possible: */ + if (s->lookahead <= 1) { + + Assert(s->strstart < s->w_size+MAX_DIST(s) || + s->block_start >= (long)s->w_size, "slide too late"); + + fill_window(s); + if (s->lookahead == 0 && flush == Z_NO_FLUSH) return need_more; + + if (s->lookahead == 0) break; /* flush the current block */ + } + Assert(s->block_start >= 0L, "block gone"); + + s->strstart += s->lookahead; + s->lookahead = 0; + + /* Stored blocks are limited to 0xffff bytes: */ + if (s->strstart == 0 || s->strstart > 0xfffe) { + /* strstart == 0 is possible when wraparound on 16-bit machine */ + s->lookahead = s->strstart - 0xffff; + s->strstart = 0xffff; + } + + /* Emit a stored block if it is large enough: */ + if (s->strstart - (uInt)s->block_start >= MAX_DIST(s)) { + FLUSH_BLOCK(s, 0); + } + } + FLUSH_BLOCK(s, flush == Z_FINISH); + return flush == Z_FINISH ? finish_done : block_done; +} + +/* =========================================================================== + * Compress as much as possible from the input stream, return the current + * block state. + * This function does not perform lazy evaluation of matches and inserts + * new strings in the dictionary only for unmatched strings or for short + * matches. It is used only for the fast compression options. + */ +local block_state deflate_fast(s, flush) + deflate_state *s; + int flush; +{ + IPos hash_head = NIL; /* head of the hash chain */ + int bflush; /* set if current block must be flushed */ + + for (;;) { + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the next match, plus MIN_MATCH bytes to insert the + * string following the next match. + */ + if (s->lookahead < MIN_LOOKAHEAD) { + fill_window(s); + if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { + return need_more; + } + if (s->lookahead == 0) break; /* flush the current block */ + } + + /* Insert the string window[strstart .. strstart+2] in the + * dictionary, and set hash_head to the head of the hash chain: + */ + if (s->lookahead >= MIN_MATCH) { + INSERT_STRING(s, s->strstart, hash_head); + } + + /* Find the longest match, discarding those <= prev_length. + * At this point we have always match_length < MIN_MATCH + */ + if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) { + /* To simplify the code, we prevent matches with the string + * of window index 0 (in particular we have to avoid a match + * of the string with itself at the start of the input file). + */ + if (s->strategy != Z_HUFFMAN_ONLY) { + s->match_length = longest_match (s, hash_head); + } + /* longest_match() sets match_start */ + } + if (s->match_length >= MIN_MATCH) { + check_match(s, s->strstart, s->match_start, s->match_length); + + bflush = _tr_tally(s, s->strstart - s->match_start, + s->match_length - MIN_MATCH); + + s->lookahead -= s->match_length; + + /* Insert new strings in the hash table only if the match length + * is not too large. This saves time but degrades compression. + */ + if (s->match_length <= s->max_insert_length && + s->lookahead >= MIN_MATCH) { + s->match_length--; /* string at strstart already in hash table */ + do { + s->strstart++; + INSERT_STRING(s, s->strstart, hash_head); + /* strstart never exceeds WSIZE-MAX_MATCH, so there are + * always MIN_MATCH bytes ahead. + */ + } while (--s->match_length != 0); + s->strstart++; + } else { + s->strstart += s->match_length; + s->match_length = 0; + s->ins_h = s->window[s->strstart]; + UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]); +#if MIN_MATCH != 3 + Call UPDATE_HASH() MIN_MATCH-3 more times +#endif + /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not + * matter since it will be recomputed at next deflate call. + */ + } + } else { + /* No match, output a literal byte */ + Tracevv((stderr,"%c", s->window[s->strstart])); + bflush = _tr_tally (s, 0, s->window[s->strstart]); + s->lookahead--; + s->strstart++; + } + if (bflush) FLUSH_BLOCK(s, 0); + } + FLUSH_BLOCK(s, flush == Z_FINISH); + return flush == Z_FINISH ? finish_done : block_done; +} + +/* =========================================================================== + * Same as above, but achieves better compression. We use a lazy + * evaluation for matches: a match is finally adopted only if there is + * no better match at the next window position. + */ +local block_state deflate_slow(s, flush) + deflate_state *s; + int flush; +{ + IPos hash_head = NIL; /* head of hash chain */ + int bflush; /* set if current block must be flushed */ + + /* Process the input block. */ + for (;;) { + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the next match, plus MIN_MATCH bytes to insert the + * string following the next match. + */ + if (s->lookahead < MIN_LOOKAHEAD) { + fill_window(s); + if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { + return need_more; + } + if (s->lookahead == 0) break; /* flush the current block */ + } + + /* Insert the string window[strstart .. strstart+2] in the + * dictionary, and set hash_head to the head of the hash chain: + */ + if (s->lookahead >= MIN_MATCH) { + INSERT_STRING(s, s->strstart, hash_head); + } + + /* Find the longest match, discarding those <= prev_length. + */ + s->prev_length = s->match_length, s->prev_match = s->match_start; + s->match_length = MIN_MATCH-1; + + if (hash_head != NIL && s->prev_length < s->max_lazy_match && + s->strstart - hash_head <= MAX_DIST(s)) { + /* To simplify the code, we prevent matches with the string + * of window index 0 (in particular we have to avoid a match + * of the string with itself at the start of the input file). + */ + if (s->strategy != Z_HUFFMAN_ONLY) { + s->match_length = longest_match (s, hash_head); + } + /* longest_match() sets match_start */ + + if (s->match_length <= 5 && (s->strategy == Z_FILTERED || + (s->match_length == MIN_MATCH && + s->strstart - s->match_start > TOO_FAR))) { + + /* If prev_match is also MIN_MATCH, match_start is garbage + * but we will ignore the current match anyway. + */ + s->match_length = MIN_MATCH-1; + } + } + /* If there was a match at the previous step and the current + * match is not better, output the previous match: + */ + if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) { + uInt max_insert = s->strstart + s->lookahead - MIN_MATCH; + /* Do not insert strings in hash table beyond this. */ + + check_match(s, s->strstart-1, s->prev_match, s->prev_length); + + bflush = _tr_tally(s, s->strstart -1 - s->prev_match, + s->prev_length - MIN_MATCH); + + /* Insert in hash table all strings up to the end of the match. + * strstart-1 and strstart are already inserted. If there is not + * enough lookahead, the last two strings are not inserted in + * the hash table. + */ + s->lookahead -= s->prev_length-1; + s->prev_length -= 2; + do { + if (++s->strstart <= max_insert) { + INSERT_STRING(s, s->strstart, hash_head); + } + } while (--s->prev_length != 0); + s->match_available = 0; + s->match_length = MIN_MATCH-1; + s->strstart++; + + if (bflush) FLUSH_BLOCK(s, 0); + + } else if (s->match_available) { + /* If there was no match at the previous position, output a + * single literal. If there was a match but the current match + * is longer, truncate the previous match to a single literal. + */ + Tracevv((stderr,"%c", s->window[s->strstart-1])); + if (_tr_tally (s, 0, s->window[s->strstart-1])) { + FLUSH_BLOCK_ONLY(s, 0); + } + s->strstart++; + s->lookahead--; + if (s->strm->avail_out == 0) return need_more; + } else { + /* There is no previous match to compare with, wait for + * the next step to decide. + */ + s->match_available = 1; + s->strstart++; + s->lookahead--; + } + } + Assert (flush != Z_NO_FLUSH, "no flush?"); + if (s->match_available) { + Tracevv((stderr,"%c", s->window[s->strstart-1])); + _tr_tally (s, 0, s->window[s->strstart-1]); + s->match_available = 0; + } + FLUSH_BLOCK(s, flush == Z_FINISH); + return flush == Z_FINISH ? finish_done : block_done; +} diff --git a/ef/Utilities/zlib/deflate.h b/ef/Utilities/zlib/deflate.h new file mode 100644 index 000000000000..eed21cd73166 --- /dev/null +++ b/ef/Utilities/zlib/deflate.h @@ -0,0 +1,273 @@ +/* deflate.h -- internal compression state + * Copyright (C) 1995-1996 Jean-loup Gailly + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +#ifndef _DEFLATE_H +#define _DEFLATE_H + +#include "zutil.h" + +/* =========================================================================== + * Internal compression state. + */ + +#define LENGTH_CODES 29 +/* number of length codes, not counting the special END_BLOCK code */ + +#define LITERALS 256 +/* number of literal bytes 0..255 */ + +#define L_CODES (LITERALS+1+LENGTH_CODES) +/* number of Literal or Length codes, including the END_BLOCK code */ + +#define D_CODES 30 +/* number of distance codes */ + +#define BL_CODES 19 +/* number of codes used to transfer the bit lengths */ + +#define HEAP_SIZE (2*L_CODES+1) +/* maximum heap size */ + +#define MAX_BITS 15 +/* All codes must not exceed MAX_BITS bits */ + +#define INIT_STATE 42 +#define BUSY_STATE 113 +#define FINISH_STATE 666 +/* Stream status */ + + +/* Data structure describing a single value and its code string. */ +typedef struct ct_data_s { + union { + ush freq; /* frequency count */ + ush code; /* bit string */ + } fc; + union { + ush dad; /* father node in Huffman tree */ + ush len; /* length of bit string */ + } dl; +} FAR ct_data; + +#define Freq fc.freq +#define Code fc.code +#define Dad dl.dad +#define Len dl.len + +typedef struct static_tree_desc_s static_tree_desc; + +typedef struct tree_desc_s { + ct_data *dyn_tree; /* the dynamic tree */ + int max_code; /* largest code with non zero frequency */ + static_tree_desc *stat_desc; /* the corresponding static tree */ +} FAR tree_desc; + +typedef ush Pos; +typedef Pos FAR Posf; +typedef unsigned IPos; + +/* A Pos is an index in the character window. We use short instead of int to + * save space in the various tables. IPos is used only for parameter passing. + */ + +typedef struct internal_state { + z_streamp strm; /* pointer back to this zlib stream */ + int status; /* as the name implies */ + Bytef *pending_buf; /* output still pending */ + Bytef *pending_out; /* next pending byte to output to the stream */ + int pending; /* nb of bytes in the pending buffer */ + int noheader; /* suppress zlib header and adler32 */ + Byte data_type; /* UNKNOWN, BINARY or ASCII */ + Byte method; /* STORED (for zip only) or DEFLATED */ + int last_flush; /* value of flush param for previous deflate call */ + + /* used by deflate.c: */ + + uInt w_size; /* LZ77 window size (32K by default) */ + uInt w_bits; /* log2(w_size) (8..16) */ + uInt w_mask; /* w_size - 1 */ + + Bytef *window; + /* Sliding window. Input bytes are read into the second half of the window, + * and move to the first half later to keep a dictionary of at least wSize + * bytes. With this organization, matches are limited to a distance of + * wSize-MAX_MATCH bytes, but this ensures that IO is always + * performed with a length multiple of the block size. Also, it limits + * the window size to 64K, which is quite useful on MSDOS. + * To do: use the user input buffer as sliding window. + */ + + ulg window_size; + /* Actual size of window: 2*wSize, except when the user input buffer + * is directly used as sliding window. + */ + + Posf *prev; + /* Link to older string with same hash index. To limit the size of this + * array to 64K, this link is maintained only for the last 32K strings. + * An index in this array is thus a window index modulo 32K. + */ + + Posf *head; /* Heads of the hash chains or NIL. */ + + uInt ins_h; /* hash index of string to be inserted */ + uInt hash_size; /* number of elements in hash table */ + uInt hash_bits; /* log2(hash_size) */ + uInt hash_mask; /* hash_size-1 */ + + uInt hash_shift; + /* Number of bits by which ins_h must be shifted at each input + * step. It must be such that after MIN_MATCH steps, the oldest + * byte no longer takes part in the hash key, that is: + * hash_shift * MIN_MATCH >= hash_bits + */ + + long block_start; + /* Window position at the beginning of the current output block. Gets + * negative when the window is moved backwards. + */ + + uInt match_length; /* length of best match */ + IPos prev_match; /* previous match */ + int match_available; /* set if previous match exists */ + uInt strstart; /* start of string to insert */ + uInt match_start; /* start of matching string */ + uInt lookahead; /* number of valid bytes ahead in window */ + + uInt prev_length; + /* Length of the best match at previous step. Matches not greater than this + * are discarded. This is used in the lazy match evaluation. + */ + + uInt max_chain_length; + /* To speed up deflation, hash chains are never searched beyond this + * length. A higher limit improves compression ratio but degrades the + * speed. + */ + + uInt max_lazy_match; + /* Attempt to find a better match only when the current match is strictly + * smaller than this value. This mechanism is used only for compression + * levels >= 4. + */ +# define max_insert_length max_lazy_match + /* Insert new strings in the hash table only if the match length is not + * greater than this length. This saves time but degrades compression. + * max_insert_length is used only for compression levels <= 3. + */ + + int level; /* compression level (1..9) */ + int strategy; /* favor or force Huffman coding*/ + + uInt good_match; + /* Use a faster search when the previous match is longer than this */ + + int nice_match; /* Stop searching when current match exceeds this */ + + /* used by trees.c: */ + /* Didn't use ct_data typedef below to supress compiler warning */ + struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */ + struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */ + struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */ + + struct tree_desc_s l_desc; /* desc. for literal tree */ + struct tree_desc_s d_desc; /* desc. for distance tree */ + struct tree_desc_s bl_desc; /* desc. for bit length tree */ + + ush bl_count[MAX_BITS+1]; + /* number of codes at each bit length for an optimal tree */ + + int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */ + int heap_len; /* number of elements in the heap */ + int heap_max; /* element of largest frequency */ + /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. + * The same heap array is used to build all trees. + */ + + uch depth[2*L_CODES+1]; + /* Depth of each subtree used as tie breaker for trees of equal frequency + */ + + uchf *l_buf; /* buffer for literals or lengths */ + + uInt lit_bufsize; + /* Size of match buffer for literals/lengths. There are 4 reasons for + * limiting lit_bufsize to 64K: + * - frequencies can be kept in 16 bit counters + * - if compression is not successful for the first block, all input + * data is still in the window so we can still emit a stored block even + * when input comes from standard input. (This can also be done for + * all blocks if lit_bufsize is not greater than 32K.) + * - if compression is not successful for a file smaller than 64K, we can + * even emit a stored file instead of a stored block (saving 5 bytes). + * This is applicable only for zip (not gzip or zlib). + * - creating new Huffman trees less frequently may not provide fast + * adaptation to changes in the input data statistics. (Take for + * example a binary file with poorly compressible code followed by + * a highly compressible string table.) Smaller buffer sizes give + * fast adaptation but have of course the overhead of transmitting + * trees more frequently. + * - I can't count above 4 + */ + + uInt last_lit; /* running index in l_buf */ + + ushf *d_buf; + /* Buffer for distances. To simplify the code, d_buf and l_buf have + * the same number of elements. To use different lengths, an extra flag + * array would be necessary. + */ + + ulg opt_len; /* bit length of current block with optimal trees */ + ulg static_len; /* bit length of current block with static trees */ + ulg compressed_len; /* total bit length of compressed file */ + uInt matches; /* number of string matches in current block */ + int last_eob_len; /* bit length of EOB code for last block */ + +#ifdef DEBUG_ZIP + ulg bits_sent; /* bit length of the compressed data */ +#endif + + ush bi_buf; + /* Output buffer. bits are inserted starting at the bottom (least + * significant bits). + */ + int bi_valid; + /* Number of valid bits in bi_buf. All bits above the last valid bit + * are always zero. + */ + +} FAR deflate_state; + +/* Output a byte on the stream. + * IN assertion: there is enough room in pending_buf. + */ +#define put_byte(s, c) {s->pending_buf[s->pending++] = (c);} + + +#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) +/* Minimum amount of lookahead, except at the end of the input file. + * See deflate.c for comments about the MIN_MATCH+1. + */ + +#define MAX_DIST(s) ((s)->w_size-MIN_LOOKAHEAD) +/* In order to simplify the code, particularly on 16 bit machines, match + * distances are limited to MAX_DIST instead of WSIZE. + */ + + /* in trees.c */ +void _tr_init OF((deflate_state *s)); +int _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc)); +ulg _tr_flush_block OF((deflate_state *s, charf *buf, ulg stored_len, + int eof)); +void _tr_align OF((deflate_state *s)); +void _tr_stored_block OF((deflate_state *s, charf *buf, ulg stored_len, + int eof)); +#endif diff --git a/ef/Utilities/zlib/example.c b/ef/Utilities/zlib/example.c new file mode 100644 index 000000000000..16a1c2d8e1ee --- /dev/null +++ b/ef/Utilities/zlib/example.c @@ -0,0 +1,501 @@ +/* example.c -- usage example of the zlib compression library + * Copyright (C) 1995-1996 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include +#include "zlib.h" + +#ifdef STDC +# include +# include +#else + extern void exit OF((int)); +#endif + +#define CHECK_ERR(err, msg) { \ + if (err != Z_OK) { \ + fprintf(stderr, "%s error: %d\n", msg, err); \ + exit(1); \ + } \ +} + +const char hello[] = "hello, hello!"; +/* "hello world" would be more standard, but the repeated "hello" + * stresses the compression code better, sorry... + */ + +const char dictionary[] = "hello"; +uLong dictId; /* Adler32 value of the dictionary */ + +void test_compress OF((Byte *compr, uLong comprLen, + Byte *uncompr, uLong uncomprLen)); +void test_gzio OF((const char *out, const char *in, + Byte *uncompr, int uncomprLen)); +void test_deflate OF((Byte *compr, uLong comprLen)); +void test_inflate OF((Byte *compr, uLong comprLen, + Byte *uncompr, uLong uncomprLen)); +void test_large_deflate OF((Byte *compr, uLong comprLen, + Byte *uncompr, uLong uncomprLen)); +void test_large_inflate OF((Byte *compr, uLong comprLen, + Byte *uncompr, uLong uncomprLen)); +void test_flush OF((Byte *compr, uLong comprLen)); +void test_sync OF((Byte *compr, uLong comprLen, + Byte *uncompr, uLong uncomprLen)); +void test_dict_deflate OF((Byte *compr, uLong comprLen)); +void test_dict_inflate OF((Byte *compr, uLong comprLen, + Byte *uncompr, uLong uncomprLen)); +int main OF((int argc, char *argv[])); + +/* =========================================================================== + * Test compress() and uncompress() + */ +void test_compress(compr, comprLen, uncompr, uncomprLen) + Byte *compr, *uncompr; + uLong comprLen, uncomprLen; +{ + int err; + uLong len = strlen(hello)+1; + + err = compress(compr, &comprLen, (const Bytef*)hello, len); + CHECK_ERR(err, "compress"); + + strcpy((char*)uncompr, "garbage"); + + err = uncompress(uncompr, &uncomprLen, compr, comprLen); + CHECK_ERR(err, "uncompress"); + + if (strcmp((char*)uncompr, hello)) { + fprintf(stderr, "bad uncompress\n"); + } else { + printf("uncompress(): %s\n", uncompr); + } +} + +/* =========================================================================== + * Test read/write of .gz files + */ +void test_gzio(out, in, uncompr, uncomprLen) + const char *out; /* output file */ + const char *in; /* input file */ + Byte *uncompr; + int uncomprLen; +{ + int err; + int len = strlen(hello)+1; + gzFile file; + + file = gzopen(out, "wb"); + if (file == NULL) { + fprintf(stderr, "gzopen error\n"); + exit(1); + } + + if (gzwrite(file, (const voidp)hello, (unsigned)len) != len) { + fprintf(stderr, "gzwrite err: %s\n", gzerror(file, &err)); + } + gzclose(file); + + file = gzopen(in, "rb"); + if (file == NULL) { + fprintf(stderr, "gzopen error\n"); + } + strcpy((char*)uncompr, "garbage"); + + uncomprLen = gzread(file, uncompr, (unsigned)uncomprLen); + if (uncomprLen != len) { + fprintf(stderr, "gzread err: %s\n", gzerror(file, &err)); + } + gzclose(file); + + if (strcmp((char*)uncompr, hello)) { + fprintf(stderr, "bad gzread\n"); + } else { + printf("gzread(): %s\n", uncompr); + } +} + +/* =========================================================================== + * Test deflate() with small buffers + */ +void test_deflate(compr, comprLen) + Byte *compr; + uLong comprLen; +{ + z_stream c_stream; /* compression stream */ + int err; + int len = strlen(hello)+1; + + c_stream.zalloc = (alloc_func)0; + c_stream.zfree = (free_func)0; + c_stream.opaque = (voidpf)0; + + err = deflateInit(&c_stream, Z_DEFAULT_COMPRESSION); + CHECK_ERR(err, "deflateInit"); + + c_stream.next_in = (Bytef*)hello; + c_stream.next_out = compr; + + while (c_stream.total_in != (uLong)len && c_stream.total_out < comprLen) { + c_stream.avail_in = c_stream.avail_out = 1; /* force small buffers */ + err = deflate(&c_stream, Z_NO_FLUSH); + CHECK_ERR(err, "deflate"); + } + /* Finish the stream, still forcing small buffers: */ + for (;;) { + c_stream.avail_out = 1; + err = deflate(&c_stream, Z_FINISH); + if (err == Z_STREAM_END) break; + CHECK_ERR(err, "deflate"); + } + + err = deflateEnd(&c_stream); + CHECK_ERR(err, "deflateEnd"); +} + +/* =========================================================================== + * Test inflate() with small buffers + */ +void test_inflate(compr, comprLen, uncompr, uncomprLen) + Byte *compr, *uncompr; + uLong comprLen, uncomprLen; +{ + int err; + z_stream d_stream; /* decompression stream */ + + strcpy((char*)uncompr, "garbage"); + + d_stream.zalloc = (alloc_func)0; + d_stream.zfree = (free_func)0; + d_stream.opaque = (voidpf)0; + + err = inflateInit(&d_stream); + CHECK_ERR(err, "inflateInit"); + + d_stream.next_in = compr; + d_stream.next_out = uncompr; + + while (d_stream.total_out < uncomprLen && d_stream.total_in < comprLen) { + d_stream.avail_in = d_stream.avail_out = 1; /* force small buffers */ + err = inflate(&d_stream, Z_NO_FLUSH); + if (err == Z_STREAM_END) break; + CHECK_ERR(err, "inflate"); + } + + err = inflateEnd(&d_stream); + CHECK_ERR(err, "inflateEnd"); + + if (strcmp((char*)uncompr, hello)) { + fprintf(stderr, "bad inflate\n"); + } else { + printf("inflate(): %s\n", uncompr); + } +} + +/* =========================================================================== + * Test deflate() with large buffers and dynamic change of compression level + */ +void test_large_deflate(compr, comprLen, uncompr, uncomprLen) + Byte *compr, *uncompr; + uLong comprLen, uncomprLen; +{ + z_stream c_stream; /* compression stream */ + int err; + + c_stream.zalloc = (alloc_func)0; + c_stream.zfree = (free_func)0; + c_stream.opaque = (voidpf)0; + + err = deflateInit(&c_stream, Z_BEST_SPEED); + CHECK_ERR(err, "deflateInit"); + + c_stream.next_out = compr; + c_stream.avail_out = (uInt)comprLen; + + /* At this point, uncompr is still mostly zeroes, so it should compress + * very well: + */ + c_stream.next_in = uncompr; + c_stream.avail_in = (uInt)uncomprLen; + err = deflate(&c_stream, Z_NO_FLUSH); + CHECK_ERR(err, "deflate"); + if (c_stream.avail_in != 0) { + fprintf(stderr, "deflate not greedy\n"); + } + + /* Feed in already compressed data and switch to no compression: */ + deflateParams(&c_stream, Z_NO_COMPRESSION, Z_DEFAULT_STRATEGY); + c_stream.next_in = compr; + c_stream.avail_in = (uInt)comprLen/2; + err = deflate(&c_stream, Z_NO_FLUSH); + CHECK_ERR(err, "deflate"); + + /* Switch back to compressing mode: */ + deflateParams(&c_stream, Z_BEST_COMPRESSION, Z_FILTERED); + c_stream.next_in = uncompr; + c_stream.avail_in = (uInt)uncomprLen; + err = deflate(&c_stream, Z_NO_FLUSH); + CHECK_ERR(err, "deflate"); + + err = deflate(&c_stream, Z_FINISH); + if (err != Z_STREAM_END) { + fprintf(stderr, "deflate should report Z_STREAM_END\n"); + } + err = deflateEnd(&c_stream); + CHECK_ERR(err, "deflateEnd"); +} + +/* =========================================================================== + * Test inflate() with large buffers + */ +void test_large_inflate(compr, comprLen, uncompr, uncomprLen) + Byte *compr, *uncompr; + uLong comprLen, uncomprLen; +{ + int err; + z_stream d_stream; /* decompression stream */ + + strcpy((char*)uncompr, "garbage"); + + d_stream.zalloc = (alloc_func)0; + d_stream.zfree = (free_func)0; + d_stream.opaque = (voidpf)0; + + err = inflateInit(&d_stream); + CHECK_ERR(err, "inflateInit"); + + d_stream.next_in = compr; + d_stream.avail_in = (uInt)comprLen; + + for (;;) { + d_stream.next_out = uncompr; /* discard the output */ + d_stream.avail_out = (uInt)uncomprLen; + err = inflate(&d_stream, Z_NO_FLUSH); + if (err == Z_STREAM_END) break; + CHECK_ERR(err, "large inflate"); + } + + err = inflateEnd(&d_stream); + CHECK_ERR(err, "inflateEnd"); + + if (d_stream.total_out != 2*uncomprLen + comprLen/2) { + fprintf(stderr, "bad large inflate: %ld\n", d_stream.total_out); + } else { + printf("large_inflate(): OK\n"); + } +} + +/* =========================================================================== + * Test deflate() with full flush + */ +void test_flush(compr, comprLen) + Byte *compr; + uLong comprLen; +{ + z_stream c_stream; /* compression stream */ + int err; + int len = strlen(hello)+1; + + c_stream.zalloc = (alloc_func)0; + c_stream.zfree = (free_func)0; + c_stream.opaque = (voidpf)0; + + err = deflateInit(&c_stream, Z_DEFAULT_COMPRESSION); + CHECK_ERR(err, "deflateInit"); + + c_stream.next_in = (Bytef*)hello; + c_stream.next_out = compr; + c_stream.avail_in = 3; + c_stream.avail_out = (uInt)comprLen; + err = deflate(&c_stream, Z_FULL_FLUSH); + CHECK_ERR(err, "deflate"); + + compr[3]++; /* force an error in first compressed block */ + c_stream.avail_in = len - 3; + + err = deflate(&c_stream, Z_FINISH); + if (err != Z_STREAM_END) { + CHECK_ERR(err, "deflate"); + } + err = deflateEnd(&c_stream); + CHECK_ERR(err, "deflateEnd"); +} + +/* =========================================================================== + * Test inflateSync() + */ +void test_sync(compr, comprLen, uncompr, uncomprLen) + Byte *compr, *uncompr; + uLong comprLen, uncomprLen; +{ + int err; + z_stream d_stream; /* decompression stream */ + + strcpy((char*)uncompr, "garbage"); + + d_stream.zalloc = (alloc_func)0; + d_stream.zfree = (free_func)0; + d_stream.opaque = (voidpf)0; + + err = inflateInit(&d_stream); + CHECK_ERR(err, "inflateInit"); + + d_stream.next_in = compr; + d_stream.next_out = uncompr; + d_stream.avail_in = 2; /* just read the zlib header */ + d_stream.avail_out = (uInt)uncomprLen; + + inflate(&d_stream, Z_NO_FLUSH); + CHECK_ERR(err, "inflate"); + + d_stream.avail_in = (uInt)comprLen-2; /* read all compressed data */ + err = inflateSync(&d_stream); /* but skip the damaged part */ + CHECK_ERR(err, "inflateSync"); + + err = inflate(&d_stream, Z_FINISH); + if (err != Z_DATA_ERROR) { + fprintf(stderr, "inflate should report DATA_ERROR\n"); + /* Because of incorrect adler32 */ + } + err = inflateEnd(&d_stream); + CHECK_ERR(err, "inflateEnd"); + + printf("after inflateSync(): hel%s\n", uncompr); +} + +/* =========================================================================== + * Test deflate() with preset dictionary + */ +void test_dict_deflate(compr, comprLen) + Byte *compr; + uLong comprLen; +{ + z_stream c_stream; /* compression stream */ + int err; + + c_stream.zalloc = (alloc_func)0; + c_stream.zfree = (free_func)0; + c_stream.opaque = (voidpf)0; + + err = deflateInit(&c_stream, Z_BEST_COMPRESSION); + CHECK_ERR(err, "deflateInit"); + + err = deflateSetDictionary(&c_stream, + (const Bytef*)dictionary, sizeof(dictionary)); + CHECK_ERR(err, "deflateSetDictionary"); + + dictId = c_stream.adler; + c_stream.next_out = compr; + c_stream.avail_out = (uInt)comprLen; + + c_stream.next_in = (Bytef*)hello; + c_stream.avail_in = (uInt)strlen(hello)+1; + + err = deflate(&c_stream, Z_FINISH); + if (err != Z_STREAM_END) { + fprintf(stderr, "deflate should report Z_STREAM_END\n"); + } + err = deflateEnd(&c_stream); + CHECK_ERR(err, "deflateEnd"); +} + +/* =========================================================================== + * Test inflate() with a preset dictionary + */ +void test_dict_inflate(compr, comprLen, uncompr, uncomprLen) + Byte *compr, *uncompr; + uLong comprLen, uncomprLen; +{ + int err; + z_stream d_stream; /* decompression stream */ + + strcpy((char*)uncompr, "garbage"); + + d_stream.zalloc = (alloc_func)0; + d_stream.zfree = (free_func)0; + d_stream.opaque = (voidpf)0; + + err = inflateInit(&d_stream); + CHECK_ERR(err, "inflateInit"); + + d_stream.next_in = compr; + d_stream.avail_in = (uInt)comprLen; + + d_stream.next_out = uncompr; + d_stream.avail_out = (uInt)uncomprLen; + + for (;;) { + err = inflate(&d_stream, Z_NO_FLUSH); + if (err == Z_STREAM_END) break; + if (err == Z_NEED_DICT) { + if (d_stream.adler != dictId) { + fprintf(stderr, "unexpected dictionary"); + exit(1); + } + err = inflateSetDictionary(&d_stream, (const Bytef*)dictionary, + sizeof(dictionary)); + } + CHECK_ERR(err, "inflate with dict"); + } + + err = inflateEnd(&d_stream); + CHECK_ERR(err, "inflateEnd"); + + if (strcmp((char*)uncompr, hello)) { + fprintf(stderr, "bad inflate with dict\n"); + } else { + printf("inflate with dictionary: %s\n", uncompr); + } +} + +/* =========================================================================== + * Usage: example [output.gz [input.gz]] + */ + +int main(argc, argv) + int argc; + char *argv[]; +{ + Byte *compr, *uncompr; + uLong comprLen = 10000*sizeof(int); /* don't overflow on MSDOS */ + uLong uncomprLen = comprLen; + + if (zlibVersion()[0] != ZLIB_VERSION[0]) { + fprintf(stderr, "incompatible zlib version\n"); + exit(1); + + } else if (strcmp(zlibVersion(), ZLIB_VERSION) != 0) { + fprintf(stderr, "warning: different zlib version\n"); + } + + compr = (Byte*)calloc((uInt)comprLen, 1); + uncompr = (Byte*)calloc((uInt)uncomprLen, 1); + /* compr and uncompr are cleared to avoid reading uninitialized + * data and to ensure that uncompr compresses well. + */ + if (compr == Z_NULL || uncompr == Z_NULL) { + printf("out of memory\n"); + exit(1); + } + + test_compress(compr, comprLen, uncompr, uncomprLen); + + test_gzio((argc > 1 ? argv[1] : "foo.gz"), + (argc > 2 ? argv[2] : "foo.gz"), + uncompr, (int)uncomprLen); + + test_deflate(compr, comprLen); + test_inflate(compr, comprLen, uncompr, uncomprLen); + + test_large_deflate(compr, comprLen, uncompr, uncomprLen); + test_large_inflate(compr, comprLen, uncompr, uncomprLen); + + test_flush(compr, comprLen); + test_sync(compr, comprLen, uncompr, uncomprLen); + + test_dict_deflate(compr, comprLen); + test_dict_inflate(compr, comprLen, uncompr, uncomprLen); + + exit(0); + return 0; /* to avoid warning */ +} diff --git a/ef/Utilities/zlib/gzio.c b/ef/Utilities/zlib/gzio.c new file mode 100644 index 000000000000..45c158061bc5 --- /dev/null +++ b/ef/Utilities/zlib/gzio.c @@ -0,0 +1,521 @@ +/* gzio.c -- IO on .gz files + * Copyright (C) 1995-1996 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include + +#include "zutil.h" + +struct internal_state {int dummy;}; /* for buggy compilers */ + +#define Z_BUFSIZE 4096 + +#define ALLOC(size) malloc(size) +#define TRYFREE(p) {if (p) free(p);} + +static int gz_magic[2] = {0x1f, 0x8b}; /* gzip magic header */ + +/* gzip flag byte */ +#define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */ +#define HEAD_CRC 0x02 /* bit 1 set: header CRC present */ +#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */ +#define ORIG_NAME 0x08 /* bit 3 set: original file name present */ +#define COMMENT 0x10 /* bit 4 set: file comment present */ +#define RESERVED 0xE0 /* bits 5..7: reserved */ + +typedef struct gz_stream { + z_stream stream; + int z_err; /* error code for last stream operation */ + int z_eof; /* set if end of input file */ + FILE *file; /* .gz file */ + Byte *inbuf; /* input buffer */ + Byte *outbuf; /* output buffer */ + uLong crc; /* crc32 of uncompressed data */ + char *msg; /* error message */ + char *path; /* path name for debugging only */ + int transparent; /* 1 if input file is not a .gz file */ + char mode; /* 'w' or 'r' */ +} gz_stream; + + +local gzFile gz_open OF((const char *path, const char *mode, int fd)); +local int get_byte OF((gz_stream *s)); +local void check_header OF((gz_stream *s)); +local int destroy OF((gz_stream *s)); +local void putLong OF((FILE *file, uLong x)); +local uLong getLong OF((gz_stream *s)); + +/* =========================================================================== + Opens a gzip (.gz) file for reading or writing. The mode parameter + is as in fopen ("rb" or "wb"). The file is given either by file descriptor + or path name (if fd == -1). + gz_open return NULL if the file could not be opened or if there was + insufficient memory to allocate the (de)compression state; errno + can be checked to distinguish the two cases (if errno is zero, the + zlib error is Z_MEM_ERROR). +*/ +local gzFile gz_open (path, mode, fd) + const char *path; + const char *mode; + int fd; +{ + int err; + int level = Z_DEFAULT_COMPRESSION; /* compression level */ + char *p = (char*)mode; + gz_stream *s; + char fmode[80]; /* copy of mode, without the compression level */ + char *m = fmode; + + if (!path || !mode) return Z_NULL; + + s = (gz_stream *)ALLOC(sizeof(gz_stream)); + if (!s) return Z_NULL; + + s->stream.zalloc = (alloc_func)0; + s->stream.zfree = (free_func)0; + s->stream.opaque = (voidpf)0; + s->stream.next_in = s->inbuf = Z_NULL; + s->stream.next_out = s->outbuf = Z_NULL; + s->stream.avail_in = s->stream.avail_out = 0; + s->file = NULL; + s->z_err = Z_OK; + s->z_eof = 0; + s->crc = crc32(0L, Z_NULL, 0); + s->msg = NULL; + s->transparent = 0; + + s->path = (char*)ALLOC(strlen(path)+1); + if (s->path == NULL) { + return destroy(s), (gzFile)Z_NULL; + } + strcpy(s->path, path); /* do this early for debugging */ + + s->mode = '\0'; + do { + if (*p == 'r') s->mode = 'r'; + if (*p == 'w' || *p == 'a') s->mode = 'w'; + if (*p >= '0' && *p <= '9') { + level = *p - '0'; + } else { + *m++ = *p; /* copy the mode */ + } + } while (*p++ && m != fmode + sizeof(fmode)); + if (s->mode == '\0') return destroy(s), (gzFile)Z_NULL; + + if (s->mode == 'w') { + err = deflateInit2(&(s->stream), level, + Z_DEFLATED, -MAX_WBITS, DEF_MEM_LEVEL, 0); + /* windowBits is passed < 0 to suppress zlib header */ + + s->stream.next_out = s->outbuf = (Byte*)ALLOC(Z_BUFSIZE); + + if (err != Z_OK || s->outbuf == Z_NULL) { + return destroy(s), (gzFile)Z_NULL; + } + } else { + err = inflateInit2(&(s->stream), -MAX_WBITS); + s->stream.next_in = s->inbuf = (Byte*)ALLOC(Z_BUFSIZE); + + if (err != Z_OK || s->inbuf == Z_NULL) { + return destroy(s), (gzFile)Z_NULL; + } + } + s->stream.avail_out = Z_BUFSIZE; + + errno = 0; + s->file = fd < 0 ? FOPEN(path, fmode) : (FILE*)fdopen(fd, fmode); + + if (s->file == NULL) { + return destroy(s), (gzFile)Z_NULL; + } + if (s->mode == 'w') { + /* Write a very simple .gz header: + */ + fprintf(s->file, "%c%c%c%c%c%c%c%c%c%c", gz_magic[0], gz_magic[1], + Z_DEFLATED, 0 /*flags*/, 0,0,0,0 /*time*/, 0 /*xflags*/, OS_CODE); + } else { + check_header(s); /* skip the .gz header */ + } + return (gzFile)s; +} + +/* =========================================================================== + Opens a gzip (.gz) file for reading or writing. +*/ +gzFile gzopen (path, mode) + const char *path; + const char *mode; +{ + return gz_open (path, mode, -1); +} + +/* =========================================================================== + Associate a gzFile with the file descriptor fd. fd is not dup'ed here + to mimic the behavio(u)r of fdopen. +*/ +gzFile gzdopen (fd, mode) + int fd; + const char *mode; +{ + char name[20]; + + if (fd < 0) return (gzFile)Z_NULL; + sprintf(name, "", fd); /* for debugging */ + + return gz_open (name, mode, fd); +} + +/* =========================================================================== + Read a byte from a gz_stream; update next_in and avail_in. Return EOF + for end of file. + IN assertion: the stream s has been sucessfully opened for reading. +*/ +local int get_byte(s) + gz_stream *s; +{ + if (s->z_eof) return EOF; + if (s->stream.avail_in == 0) { + errno = 0; + s->stream.avail_in = fread(s->inbuf, 1, Z_BUFSIZE, s->file); + if (s->stream.avail_in == 0) { + s->z_eof = 1; + if (ferror(s->file)) s->z_err = Z_ERRNO; + return EOF; + } + s->stream.next_in = s->inbuf; + } + s->stream.avail_in--; + return *(s->stream.next_in)++; +} + +/* =========================================================================== + Check the gzip header of a gz_stream opened for reading. Set the stream + mode to transparent if the gzip magic header is not present; set s->err + to Z_DATA_ERROR if the magic header is present but the rest of the header + is incorrect. + IN assertion: the stream s has already been created sucessfully; + s->stream.avail_in is zero for the first time, but may be non-zero + for concatenated .gz files. +*/ +local void check_header(s) + gz_stream *s; +{ + int method; /* method byte */ + int flags; /* flags byte */ + uInt len; + int c; + + /* Check the gzip magic header */ + for (len = 0; len < 2; len++) { + c = get_byte(s); + if (c != gz_magic[len]) { + s->transparent = 1; + if (c != EOF) s->stream.avail_in++, s->stream.next_in--; + s->z_err = s->stream.avail_in != 0 ? Z_OK : Z_STREAM_END; + return; + } + } + method = get_byte(s); + flags = get_byte(s); + if (method != Z_DEFLATED || (flags & RESERVED) != 0) { + s->z_err = Z_DATA_ERROR; + return; + } + + /* Discard time, xflags and OS code: */ + for (len = 0; len < 6; len++) (void)get_byte(s); + + if ((flags & EXTRA_FIELD) != 0) { /* skip the extra field */ + len = (uInt)get_byte(s); + len += ((uInt)get_byte(s))<<8; + /* len is garbage if EOF but the loop below will quit anyway */ + while (len-- != 0 && get_byte(s) != EOF) ; + } + if ((flags & ORIG_NAME) != 0) { /* skip the original file name */ + while ((c = get_byte(s)) != 0 && c != EOF) ; + } + if ((flags & COMMENT) != 0) { /* skip the .gz file comment */ + while ((c = get_byte(s)) != 0 && c != EOF) ; + } + if ((flags & HEAD_CRC) != 0) { /* skip the header crc */ + for (len = 0; len < 2; len++) (void)get_byte(s); + } + s->z_err = s->z_eof ? Z_DATA_ERROR : Z_OK; +} + + /* =========================================================================== + * Cleanup then free the given gz_stream. Return a zlib error code. + Try freeing in the reverse order of allocations. + */ +local int destroy (s) + gz_stream *s; +{ + int err = Z_OK; + + if (!s) return Z_STREAM_ERROR; + + TRYFREE(s->msg); + + if (s->stream.state != NULL) { + if (s->mode == 'w') { + err = deflateEnd(&(s->stream)); + } else if (s->mode == 'r') { + err = inflateEnd(&(s->stream)); + } + } + if (s->file != NULL && fclose(s->file)) { + err = Z_ERRNO; + } + if (s->z_err < 0) err = s->z_err; + + TRYFREE(s->inbuf); + TRYFREE(s->outbuf); + TRYFREE(s->path); + TRYFREE(s); + return err; +} + +/* =========================================================================== + Reads the given number of uncompressed bytes from the compressed file. + gzread returns the number of bytes actually read (0 for end of file). +*/ +int gzread (file, buf, len) + gzFile file; + voidp buf; + unsigned len; +{ + gz_stream *s = (gz_stream*)file; + Bytef *start = buf; /* starting point for crc computation */ + Byte *next_out; /* == stream.next_out but not forced far (for MSDOS) */ + + if (s == NULL || s->mode != 'r') return Z_STREAM_ERROR; + + if (s->z_err == Z_DATA_ERROR || s->z_err == Z_ERRNO) return -1; + if (s->z_err == Z_STREAM_END) return 0; /* EOF */ + + s->stream.next_out = next_out = buf; + s->stream.avail_out = len; + + while (s->stream.avail_out != 0) { + + if (s->transparent) { + /* Copy first the lookahead bytes: */ + uInt n = s->stream.avail_in; + if (n > s->stream.avail_out) n = s->stream.avail_out; + if (n > 0) { + zmemcpy(s->stream.next_out, s->stream.next_in, n); + next_out += n; + s->stream.next_out = next_out; + s->stream.next_in += n; + s->stream.avail_out -= n; + s->stream.avail_in -= n; + } + if (s->stream.avail_out > 0) { + s->stream.avail_out -= fread(next_out, 1, s->stream.avail_out, + s->file); + } + return (int)(len - s->stream.avail_out); + } + if (s->stream.avail_in == 0 && !s->z_eof) { + + errno = 0; + s->stream.avail_in = fread(s->inbuf, 1, Z_BUFSIZE, s->file); + if (s->stream.avail_in == 0) { + s->z_eof = 1; + if (ferror(s->file)) { + s->z_err = Z_ERRNO; + break; + } + } + s->stream.next_in = s->inbuf; + } + s->z_err = inflate(&(s->stream), Z_NO_FLUSH); + + if (s->z_err == Z_STREAM_END) { + /* Check CRC and original size */ + s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start)); + start = s->stream.next_out; + + if (getLong(s) != s->crc || getLong(s) != s->stream.total_out) { + s->z_err = Z_DATA_ERROR; + } else { + /* Check for concatenated .gz files: */ + check_header(s); + if (s->z_err == Z_OK) { + inflateReset(&(s->stream)); + s->crc = crc32(0L, Z_NULL, 0); + } + } + } + if (s->z_err != Z_OK || s->z_eof) break; + } + s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start)); + + return (int)(len - s->stream.avail_out); +} + +/* =========================================================================== + Writes the given number of uncompressed bytes into the compressed file. + gzwrite returns the number of bytes actually written (0 in case of error). +*/ +int gzwrite (file, buf, len) + gzFile file; + const voidp buf; + unsigned len; +{ + gz_stream *s = (gz_stream*)file; + + if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR; + + s->stream.next_in = buf; + s->stream.avail_in = len; + + while (s->stream.avail_in != 0) { + + if (s->stream.avail_out == 0) { + + s->stream.next_out = s->outbuf; + if (fwrite(s->outbuf, 1, Z_BUFSIZE, s->file) != Z_BUFSIZE) { + s->z_err = Z_ERRNO; + break; + } + s->stream.avail_out = Z_BUFSIZE; + } + s->z_err = deflate(&(s->stream), Z_NO_FLUSH); + if (s->z_err != Z_OK) break; + } + s->crc = crc32(s->crc, buf, len); + + return (int)(len - s->stream.avail_in); +} + +/* =========================================================================== + Flushes all pending output into the compressed file. The parameter + flush is as in the deflate() function. + gzflush should be called only when strictly necessary because it can + degrade compression. +*/ +int gzflush (file, flush) + gzFile file; + int flush; +{ + uInt len; + int done = 0; + gz_stream *s = (gz_stream*)file; + + if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR; + + s->stream.avail_in = 0; /* should be zero already anyway */ + + for (;;) { + len = Z_BUFSIZE - s->stream.avail_out; + + if (len != 0) { + if ((uInt)fwrite(s->outbuf, 1, len, s->file) != len) { + s->z_err = Z_ERRNO; + return Z_ERRNO; + } + s->stream.next_out = s->outbuf; + s->stream.avail_out = Z_BUFSIZE; + } + if (done) break; + s->z_err = deflate(&(s->stream), flush); + + /* deflate has finished flushing only when it hasn't used up + * all the available space in the output buffer: + */ + done = (s->stream.avail_out != 0 || s->z_err == Z_STREAM_END); + + if (s->z_err != Z_OK && s->z_err != Z_STREAM_END) break; + } + fflush(s->file); + return s->z_err == Z_STREAM_END ? Z_OK : s->z_err; +} + +/* =========================================================================== + Outputs a long in LSB order to the given file +*/ +local void putLong (file, x) + FILE *file; + uLong x; +{ + int n; + for (n = 0; n < 4; n++) { + fputc((int)(x & 0xff), file); + x >>= 8; + } +} + +/* =========================================================================== + Reads a long in LSB order from the given gz_stream. Sets +*/ +local uLong getLong (s) + gz_stream *s; +{ + uLong x = (uLong)get_byte(s); + int c; + + x += ((uLong)get_byte(s))<<8; + x += ((uLong)get_byte(s))<<16; + c = get_byte(s); + if (c == EOF) s->z_err = Z_DATA_ERROR; + x += ((uLong)c)<<24; + return x; +} + +/* =========================================================================== + Flushes all pending output if necessary, closes the compressed file + and deallocates all the (de)compression state. +*/ +int gzclose (file) + gzFile file; +{ + int err; + gz_stream *s = (gz_stream*)file; + + if (s == NULL) return Z_STREAM_ERROR; + + if (s->mode == 'w') { + err = gzflush (file, Z_FINISH); + if (err != Z_OK) return destroy(file); + + putLong (s->file, s->crc); + putLong (s->file, s->stream.total_in); + + } + return destroy(file); +} + +/* =========================================================================== + Returns the error message for the last error which occured on the + given compressed file. errnum is set to zlib error number. If an + error occured in the file system and not in the compression library, + errnum is set to Z_ERRNO and the application may consult errno + to get the exact error code. +*/ +const char* gzerror (file, errnum) + gzFile file; + int *errnum; +{ + char *m; + gz_stream *s = (gz_stream*)file; + + if (s == NULL) { + *errnum = Z_STREAM_ERROR; + return (const char*)ERR_MSG(Z_STREAM_ERROR); + } + *errnum = s->z_err; + if (*errnum == Z_OK) return (const char*)""; + + m = (char*)(*errnum == Z_ERRNO ? zstrerror(errno) : s->stream.msg); + + if (m == NULL || *m == '\0') m = (char*)ERR_MSG(s->z_err); + + TRYFREE(s->msg); + s->msg = (char*)ALLOC(strlen(s->path) + strlen(m) + 3); + strcpy(s->msg, s->path); + strcat(s->msg, ": "); + strcat(s->msg, m); + return (const char*)s->msg; +} diff --git a/ef/Utilities/zlib/infblock.c b/ef/Utilities/zlib/infblock.c new file mode 100644 index 000000000000..1fbb677c6f74 --- /dev/null +++ b/ef/Utilities/zlib/infblock.c @@ -0,0 +1,402 @@ +/* infblock.c -- interpret and process block types to last block + * Copyright (C) 1995-1996 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zutil.h" +#include "infblock.h" +#include "inftrees.h" +#include "infcodes.h" +#include "infutil.h" + +struct inflate_codes_state {int dummy;}; /* for buggy compilers */ + +/* Table for deflate from PKZIP's appnote.txt. */ +local uInt border[] = { /* Order of the bit length code lengths */ + 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; + +/* + Notes beyond the 1.93a appnote.txt: + + 1. Distance pointers never point before the beginning of the output + stream. + 2. Distance pointers can point back across blocks, up to 32k away. + 3. There is an implied maximum of 7 bits for the bit length table and + 15 bits for the actual data. + 4. If only one code exists, then it is encoded using one bit. (Zero + would be more efficient, but perhaps a little confusing.) If two + codes exist, they are coded using one bit each (0 and 1). + 5. There is no way of sending zero distance codes--a dummy must be + sent if there are none. (History: a pre 2.0 version of PKZIP would + store blocks with no distance codes, but this was discovered to be + too harsh a criterion.) Valid only for 1.93a. 2.04c does allow + zero distance codes, which is sent as one code of zero bits in + length. + 6. There are up to 286 literal/length codes. Code 256 represents the + end-of-block. Note however that the static length tree defines + 288 codes just to fill out the Huffman codes. Codes 286 and 287 + cannot be used though, since there is no length base or extra bits + defined for them. Similarily, there are up to 30 distance codes. + However, static trees define 32 codes (all 5 bits) to fill out the + Huffman codes, but the last two had better not show up in the data. + 7. Unzip can check dynamic Huffman blocks for complete code sets. + The exception is that a single code would not be complete (see #4). + 8. The five bits following the block type is really the number of + literal codes sent minus 257. + 9. Length codes 8,16,16 are interpreted as 13 length codes of 8 bits + (1+6+6). Therefore, to output three times the length, you output + three codes (1+1+1), whereas to output four times the same length, + you only need two codes (1+3). Hmm. + 10. In the tree reconstruction algorithm, Code = Code + Increment + only if BitLength(i) is not zero. (Pretty obvious.) + 11. Correction: 4 Bits: # of Bit Length codes - 4 (4 - 19) + 12. Note: length code 284 can represent 227-258, but length code 285 + really is 258. The last length deserves its own, short code + since it gets used a lot in very redundant files. The length + 258 is special since 258 - 3 (the min match length) is 255. + 13. The literal/length and distance code bit lengths are read as a + single stream of lengths. It is possible (and advantageous) for + a repeat code (16, 17, or 18) to go across the boundary between + the two sets of lengths. + */ + + +void inflate_blocks_reset(s, z, c) +inflate_blocks_statef *s; +z_streamp z; +uLongf *c; +{ + if (s->checkfn != Z_NULL) + *c = s->check; + if (s->mode == BTREE || s->mode == DTREE) + ZFREE(z, s->sub.trees.blens); + if (s->mode == CODES) + { + inflate_codes_free(s->sub.decode.codes, z); + inflate_trees_free(s->sub.decode.td, z); + inflate_trees_free(s->sub.decode.tl, z); + } + s->mode = TYPE; + s->bitk = 0; + s->bitb = 0; + s->read = s->write = s->window; + if (s->checkfn != Z_NULL) + z->adler = s->check = (*s->checkfn)(0L, Z_NULL, 0); + Trace((stderr, "inflate: blocks reset\n")); +} + + +inflate_blocks_statef *inflate_blocks_new(z, c, w) +z_streamp z; +check_func c; +uInt w; +{ + inflate_blocks_statef *s; + + if ((s = (inflate_blocks_statef *)ZALLOC + (z,1,sizeof(struct inflate_blocks_state))) == Z_NULL) + return s; + if ((s->window = (Bytef *)ZALLOC(z, 1, w)) == Z_NULL) + { + ZFREE(z, s); + return Z_NULL; + } + s->end = s->window + w; + s->checkfn = c; + s->mode = TYPE; + Trace((stderr, "inflate: blocks allocated\n")); + inflate_blocks_reset(s, z, &s->check); + return s; +} + + +#ifdef DEBUG_ZIP + extern uInt inflate_hufts; +#endif +int inflate_blocks(s, z, r) +inflate_blocks_statef *s; +z_streamp z; +int r; +{ + uInt t; /* temporary storage */ + uLong b; /* bit buffer */ + uInt k; /* bits in bit buffer */ + Bytef *p; /* input data pointer */ + uInt n; /* bytes available there */ + Bytef *q; /* output window write pointer */ + uInt m; /* bytes to end of window or read pointer */ + + /* copy input/output information to locals (UPDATE macro restores) */ + LOAD + + /* process input based on current state */ + while (1) switch (s->mode) + { + case TYPE: + NEEDBITS(3) + t = (uInt)b & 7; + s->last = t & 1; + switch (t >> 1) + { + case 0: /* stored */ + Trace((stderr, "inflate: stored block%s\n", + s->last ? " (last)" : "")); + DUMPBITS(3) + t = k & 7; /* go to byte boundary */ + DUMPBITS(t) + s->mode = LENS; /* get length of stored block */ + break; + case 1: /* fixed */ + Trace((stderr, "inflate: fixed codes block%s\n", + s->last ? " (last)" : "")); + { + uInt bl, bd; + inflate_huft *tl, *td; + + inflate_trees_fixed(&bl, &bd, &tl, &td); + s->sub.decode.codes = inflate_codes_new(bl, bd, tl, td, z); + if (s->sub.decode.codes == Z_NULL) + { + r = Z_MEM_ERROR; + LEAVE + } + s->sub.decode.tl = Z_NULL; /* don't try to free these */ + s->sub.decode.td = Z_NULL; + } + DUMPBITS(3) + s->mode = CODES; + break; + case 2: /* dynamic */ + Trace((stderr, "inflate: dynamic codes block%s\n", + s->last ? " (last)" : "")); + DUMPBITS(3) + s->mode = TABLE; + break; + case 3: /* illegal */ + DUMPBITS(3) + s->mode = BAD; + z->msg = (char*)"invalid block type"; + r = Z_DATA_ERROR; + LEAVE + } + break; + case LENS: + NEEDBITS(32) + if ((((~b) >> 16) & 0xffff) != (b & 0xffff)) + { + s->mode = BAD; + z->msg = (char*)"invalid stored block lengths"; + r = Z_DATA_ERROR; + LEAVE + } + s->sub.left = (uInt)b & 0xffff; + b = k = 0; /* dump bits */ + Tracev((stderr, "inflate: stored length %u\n", s->sub.left)); + s->mode = s->sub.left ? STORED : (s->last ? DRY : TYPE); + break; + case STORED: + if (n == 0) + LEAVE + NEEDOUT + t = s->sub.left; + if (t > n) t = n; + if (t > m) t = m; + zmemcpy(q, p, t); + p += t; n -= t; + q += t; m -= t; + if ((s->sub.left -= t) != 0) + break; + Tracev((stderr, "inflate: stored end, %lu total out\n", + z->total_out + (q >= s->read ? q - s->read : + (s->end - s->read) + (q - s->window)))); + s->mode = s->last ? DRY : TYPE; + break; + case TABLE: + NEEDBITS(14) + s->sub.trees.table = t = (uInt)b & 0x3fff; +#ifndef PKZIP_BUG_WORKAROUND + if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29) + { + s->mode = BAD; + z->msg = (char*)"too many length or distance symbols"; + r = Z_DATA_ERROR; + LEAVE + } +#endif + t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f); + if (t < 19) + t = 19; + if ((s->sub.trees.blens = (uIntf*)ZALLOC(z, t, sizeof(uInt))) == Z_NULL) + { + r = Z_MEM_ERROR; + LEAVE + } + DUMPBITS(14) + s->sub.trees.index = 0; + Tracev((stderr, "inflate: table sizes ok\n")); + s->mode = BTREE; + case BTREE: + while (s->sub.trees.index < 4 + (s->sub.trees.table >> 10)) + { + NEEDBITS(3) + s->sub.trees.blens[border[s->sub.trees.index++]] = (uInt)b & 7; + DUMPBITS(3) + } + while (s->sub.trees.index < 19) + s->sub.trees.blens[border[s->sub.trees.index++]] = 0; + s->sub.trees.bb = 7; + t = inflate_trees_bits(s->sub.trees.blens, &s->sub.trees.bb, + &s->sub.trees.tb, z); + if (t != Z_OK) + { + r = t; + if (r == Z_DATA_ERROR) + s->mode = BAD; + LEAVE + } + s->sub.trees.index = 0; + Tracev((stderr, "inflate: bits tree ok\n")); + s->mode = DTREE; + case DTREE: + while (t = s->sub.trees.table, + s->sub.trees.index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f)) + { + inflate_huft *h; + uInt i, j, c; + + t = s->sub.trees.bb; + NEEDBITS(t) + h = s->sub.trees.tb + ((uInt)b & inflate_mask[t]); + t = h->word.what.Bits; + c = h->more.Base; + if (c < 16) + { + DUMPBITS(t) + s->sub.trees.blens[s->sub.trees.index++] = c; + } + else /* c == 16..18 */ + { + i = c == 18 ? 7 : c - 14; + j = c == 18 ? 11 : 3; + NEEDBITS(t + i) + DUMPBITS(t) + j += (uInt)b & inflate_mask[i]; + DUMPBITS(i) + i = s->sub.trees.index; + t = s->sub.trees.table; + if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) || + (c == 16 && i < 1)) + { + s->mode = BAD; + z->msg = (char*)"invalid bit length repeat"; + r = Z_DATA_ERROR; + LEAVE + } + c = c == 16 ? s->sub.trees.blens[i - 1] : 0; + do { + s->sub.trees.blens[i++] = c; + } while (--j); + s->sub.trees.index = i; + } + } + inflate_trees_free(s->sub.trees.tb, z); + s->sub.trees.tb = Z_NULL; + { + uInt bl, bd; + inflate_huft *tl, *td; + inflate_codes_statef *c; + + bl = 9; /* must be <= 9 for lookahead assumptions */ + bd = 6; /* must be <= 9 for lookahead assumptions */ + t = s->sub.trees.table; +#ifdef DEBUG_ZIP + inflate_hufts = 0; +#endif + t = inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f), + s->sub.trees.blens, &bl, &bd, &tl, &td, z); + if (t != Z_OK) + { + if (t == (uInt)Z_DATA_ERROR) + s->mode = BAD; + r = t; + LEAVE + } + Tracev((stderr, "inflate: trees ok, %d * %d bytes used\n", + inflate_hufts, sizeof(inflate_huft))); + if ((c = inflate_codes_new(bl, bd, tl, td, z)) == Z_NULL) + { + inflate_trees_free(td, z); + inflate_trees_free(tl, z); + r = Z_MEM_ERROR; + LEAVE + } + ZFREE(z, s->sub.trees.blens); + s->sub.decode.codes = c; + s->sub.decode.tl = tl; + s->sub.decode.td = td; + } + s->mode = CODES; + case CODES: + UPDATE + if ((r = inflate_codes(s, z, r)) != Z_STREAM_END) + return inflate_flush(s, z, r); + r = Z_OK; + inflate_codes_free(s->sub.decode.codes, z); + inflate_trees_free(s->sub.decode.td, z); + inflate_trees_free(s->sub.decode.tl, z); + LOAD + Tracev((stderr, "inflate: codes end, %lu total out\n", + z->total_out + (q >= s->read ? q - s->read : + (s->end - s->read) + (q - s->window)))); + if (!s->last) + { + s->mode = TYPE; + break; + } + if (k > 7) /* return unused byte, if any */ + { + Assert(k < 16, "inflate_codes grabbed too many bytes") + k -= 8; + n++; + p--; /* can always return one */ + } + s->mode = DRY; + case DRY: + FLUSH + if (s->read != s->write) + LEAVE + s->mode = DONE; + case DONE: + r = Z_STREAM_END; + LEAVE + case BAD: + r = Z_DATA_ERROR; + LEAVE + default: + r = Z_STREAM_ERROR; + LEAVE + } +} + + +int inflate_blocks_free(s, z, c) +inflate_blocks_statef *s; +z_streamp z; +uLongf *c; +{ + inflate_blocks_reset(s, z, c); + ZFREE(z, s->window); + ZFREE(z, s); + Trace((stderr, "inflate: blocks freed\n")); + return Z_OK; +} + + +void inflate_set_dictionary(s, d, n) +inflate_blocks_statef *s; +const Bytef *d; +uInt n; +{ + zmemcpy((charf *)s->window, d, n); + s->read = s->write = s->window + n; +} diff --git a/ef/Utilities/zlib/infblock.h b/ef/Utilities/zlib/infblock.h new file mode 100644 index 000000000000..3ecd50cd3a62 --- /dev/null +++ b/ef/Utilities/zlib/infblock.h @@ -0,0 +1,37 @@ +/* infblock.h -- header to use infblock.c + * Copyright (C) 1995-1996 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +struct inflate_blocks_state; +typedef struct inflate_blocks_state FAR inflate_blocks_statef; + +extern inflate_blocks_statef * inflate_blocks_new OF(( + z_streamp z, + check_func c, /* check function */ + uInt w)); /* window size */ + +extern int inflate_blocks OF(( + inflate_blocks_statef *, + z_streamp , + int)); /* initial return code */ + +extern void inflate_blocks_reset OF(( + inflate_blocks_statef *, + z_streamp , + uLongf *)); /* check value on output */ + +extern int inflate_blocks_free OF(( + inflate_blocks_statef *, + z_streamp , + uLongf *)); /* check value on output */ + +extern void inflate_set_dictionary OF(( + inflate_blocks_statef *s, + const Bytef *d, /* dictionary */ + uInt n)); /* dictionary length */ diff --git a/ef/Utilities/zlib/infcodes.c b/ef/Utilities/zlib/infcodes.c new file mode 100644 index 000000000000..3ae3818a194a --- /dev/null +++ b/ef/Utilities/zlib/infcodes.c @@ -0,0 +1,247 @@ +/* infcodes.c -- process literals and length/distance pairs + * Copyright (C) 1995-1996 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zutil.h" +#include "inftrees.h" +#include "infblock.h" +#include "infcodes.h" +#include "infutil.h" +#include "inffast.h" + +/* simplify the use of the inflate_huft type with some defines */ +#define base more.Base +#define next more.Next +#define exop word.what.Exop +#define bits word.what.Bits + +/* inflate codes private state */ +struct inflate_codes_state { + + /* mode */ + enum { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */ + START, /* x: set up for LEN */ + LEN, /* i: get length/literal/eob next */ + LENEXT, /* i: getting length extra (have base) */ + DIST, /* i: get distance next */ + DISTEXT, /* i: getting distance extra */ + COPY, /* o: copying bytes in window, waiting for space */ + LIT, /* o: got literal, waiting for output space */ + WASH, /* o: got eob, possibly still output waiting */ + END, /* x: got eob and all data flushed */ + BADCODE} /* x: got error */ + mode; /* current inflate_codes mode */ + + /* mode dependent information */ + uInt len; + union { + struct { + inflate_huft *tree; /* pointer into tree */ + uInt need; /* bits needed */ + } code; /* if LEN or DIST, where in tree */ + uInt lit; /* if LIT, literal */ + struct { + uInt get; /* bits to get for extra */ + uInt dist; /* distance back to copy from */ + } copy; /* if EXT or COPY, where and how much */ + } sub; /* submode */ + + /* mode independent information */ + Byte lbits; /* ltree bits decoded per branch */ + Byte dbits; /* dtree bits decoder per branch */ + inflate_huft *ltree; /* literal/length/eob tree */ + inflate_huft *dtree; /* distance tree */ + +}; + + +inflate_codes_statef *inflate_codes_new(bl, bd, tl, td, z) +uInt bl, bd; +inflate_huft *tl; +inflate_huft *td; /* need separate declaration for Borland C++ */ +z_streamp z; +{ + inflate_codes_statef *c; + + if ((c = (inflate_codes_statef *) + ZALLOC(z,1,sizeof(struct inflate_codes_state))) != Z_NULL) + { + c->mode = START; + c->lbits = (Byte)bl; + c->dbits = (Byte)bd; + c->ltree = tl; + c->dtree = td; + Tracev((stderr, "inflate: codes new\n")); + } + return c; +} + + +int inflate_codes(s, z, r) +inflate_blocks_statef *s; +z_streamp z; +int r; +{ + uInt j; /* temporary storage */ + inflate_huft *t; /* temporary pointer */ + uInt e; /* extra bits or operation */ + uLong b; /* bit buffer */ + uInt k; /* bits in bit buffer */ + Bytef *p; /* input data pointer */ + uInt n; /* bytes available there */ + Bytef *q; /* output window write pointer */ + uInt m; /* bytes to end of window or read pointer */ + Bytef *f; /* pointer to copy strings from */ + inflate_codes_statef *c = s->sub.decode.codes; /* codes state */ + + /* copy input/output information to locals (UPDATE macro restores) */ + LOAD + + /* process input and output based on current state */ + while (1) switch (c->mode) + { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */ + case START: /* x: set up for LEN */ +#ifndef SLOW + if (m >= 258 && n >= 10) + { + UPDATE + r = inflate_fast(c->lbits, c->dbits, c->ltree, c->dtree, s, z); + LOAD + if (r != Z_OK) + { + c->mode = r == Z_STREAM_END ? WASH : BADCODE; + break; + } + } +#endif /* !SLOW */ + c->sub.code.need = c->lbits; + c->sub.code.tree = c->ltree; + c->mode = LEN; + case LEN: /* i: get length/literal/eob next */ + j = c->sub.code.need; + NEEDBITS(j) + t = c->sub.code.tree + ((uInt)b & inflate_mask[j]); + DUMPBITS(t->bits) + e = (uInt)(t->exop); + if (e == 0) /* literal */ + { + c->sub.lit = t->base; + Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ? + "inflate: literal '%c'\n" : + "inflate: literal 0x%02x\n", t->base)); + c->mode = LIT; + break; + } + if (e & 16) /* length */ + { + c->sub.copy.get = e & 15; + c->len = t->base; + c->mode = LENEXT; + break; + } + if ((e & 64) == 0) /* next table */ + { + c->sub.code.need = e; + c->sub.code.tree = t->next; + break; + } + if (e & 32) /* end of block */ + { + Tracevv((stderr, "inflate: end of block\n")); + c->mode = WASH; + break; + } + c->mode = BADCODE; /* invalid code */ + z->msg = (char*)"invalid literal/length code"; + r = Z_DATA_ERROR; + LEAVE + case LENEXT: /* i: getting length extra (have base) */ + j = c->sub.copy.get; + NEEDBITS(j) + c->len += (uInt)b & inflate_mask[j]; + DUMPBITS(j) + c->sub.code.need = c->dbits; + c->sub.code.tree = c->dtree; + Tracevv((stderr, "inflate: length %u\n", c->len)); + c->mode = DIST; + case DIST: /* i: get distance next */ + j = c->sub.code.need; + NEEDBITS(j) + t = c->sub.code.tree + ((uInt)b & inflate_mask[j]); + DUMPBITS(t->bits) + e = (uInt)(t->exop); + if (e & 16) /* distance */ + { + c->sub.copy.get = e & 15; + c->sub.copy.dist = t->base; + c->mode = DISTEXT; + break; + } + if ((e & 64) == 0) /* next table */ + { + c->sub.code.need = e; + c->sub.code.tree = t->next; + break; + } + c->mode = BADCODE; /* invalid code */ + z->msg = (char*)"invalid distance code"; + r = Z_DATA_ERROR; + LEAVE + case DISTEXT: /* i: getting distance extra */ + j = c->sub.copy.get; + NEEDBITS(j) + c->sub.copy.dist += (uInt)b & inflate_mask[j]; + DUMPBITS(j) + Tracevv((stderr, "inflate: distance %u\n", c->sub.copy.dist)); + c->mode = COPY; + case COPY: /* o: copying bytes in window, waiting for space */ +#ifndef __TURBOC__ /* Turbo C bug for following expression */ + f = (uInt)(q - s->window) < c->sub.copy.dist ? + s->end - (c->sub.copy.dist - (q - s->window)) : + q - c->sub.copy.dist; +#else + f = q - c->sub.copy.dist; + if ((uInt)(q - s->window) < c->sub.copy.dist) + f = s->end - (c->sub.copy.dist - (uInt)(q - s->window)); +#endif + while (c->len) + { + NEEDOUT + OUTBYTE(*f++) + if (f == s->end) + f = s->window; + c->len--; + } + c->mode = START; + break; + case LIT: /* o: got literal, waiting for output space */ + NEEDOUT + OUTBYTE(c->sub.lit) + c->mode = START; + break; + case WASH: /* o: got eob, possibly more output */ + FLUSH + if (s->read != s->write) + LEAVE + c->mode = END; + case END: + r = Z_STREAM_END; + LEAVE + case BADCODE: /* x: got error */ + r = Z_DATA_ERROR; + LEAVE + default: + r = Z_STREAM_ERROR; + LEAVE + } +} + + +void inflate_codes_free(c, z) +inflate_codes_statef *c; +z_streamp z; +{ + ZFREE(z, c); + Tracev((stderr, "inflate: codes free\n")); +} diff --git a/ef/Utilities/zlib/infcodes.h b/ef/Utilities/zlib/infcodes.h new file mode 100644 index 000000000000..c2c38df2c060 --- /dev/null +++ b/ef/Utilities/zlib/infcodes.h @@ -0,0 +1,27 @@ +/* infcodes.h -- header to use infcodes.c + * Copyright (C) 1995-1996 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +struct inflate_codes_state; +typedef struct inflate_codes_state FAR inflate_codes_statef; + +extern inflate_codes_statef *inflate_codes_new OF(( + uInt, uInt, + inflate_huft *, inflate_huft *, + z_streamp )); + +extern int inflate_codes OF(( + inflate_blocks_statef *, + z_streamp , + int)); + +extern void inflate_codes_free OF(( + inflate_codes_statef *, + z_streamp )); + diff --git a/ef/Utilities/zlib/inffast.c b/ef/Utilities/zlib/inffast.c new file mode 100644 index 000000000000..86eee4a2992c --- /dev/null +++ b/ef/Utilities/zlib/inffast.c @@ -0,0 +1,168 @@ +/* inffast.c -- process literals and length/distance pairs fast + * Copyright (C) 1995-1996 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zutil.h" +#include "inftrees.h" +#include "infblock.h" +#include "infcodes.h" +#include "infutil.h" +#include "inffast.h" + +struct inflate_codes_state {int dummy;}; /* for buggy compilers */ + +/* simplify the use of the inflate_huft type with some defines */ +#define base more.Base +#define next more.Next +#define exop word.what.Exop +#define bits word.what.Bits + +/* macros for bit input with no checking and for returning unused bytes */ +#define GRABBITS(j) {while(k<(j)){b|=((uLong)NEXTBYTE)<>3);p-=c;k&=7;} + +/* Called with number of bytes left to write in window at least 258 + (the maximum string length) and number of input bytes available + at least ten. The ten bytes are six bytes for the longest length/ + distance pair plus four bytes for overloading the bit buffer. */ + +int inflate_fast(bl, bd, tl, td, s, z) +uInt bl, bd; +inflate_huft *tl; +inflate_huft *td; /* need separate declaration for Borland C++ */ +inflate_blocks_statef *s; +z_streamp z; +{ + inflate_huft *t; /* temporary pointer */ + uInt e; /* extra bits or operation */ + uLong b; /* bit buffer */ + uInt k; /* bits in bit buffer */ + Bytef *p; /* input data pointer */ + uInt n; /* bytes available there */ + Bytef *q; /* output window write pointer */ + uInt m; /* bytes to end of window or read pointer */ + uInt ml; /* mask for literal/length tree */ + uInt md; /* mask for distance tree */ + uInt c; /* bytes to copy */ + uInt d; /* distance back to copy from */ + Bytef *r; /* copy source pointer */ + + /* load input, output, bit values */ + LOAD + + /* initialize masks */ + ml = inflate_mask[bl]; + md = inflate_mask[bd]; + + /* do until not enough input or output space for fast loop */ + do { /* assume called with m >= 258 && n >= 10 */ + /* get literal/length code */ + GRABBITS(20) /* max bits for literal/length code */ + if ((e = (t = tl + ((uInt)b & ml))->exop) == 0) + { + DUMPBITS(t->bits) + Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ? + "inflate: * literal '%c'\n" : + "inflate: * literal 0x%02x\n", t->base)); + *q++ = (Byte)t->base; + m--; + continue; + } + do { + DUMPBITS(t->bits) + if (e & 16) + { + /* get extra bits for length */ + e &= 15; + c = t->base + ((uInt)b & inflate_mask[e]); + DUMPBITS(e) + Tracevv((stderr, "inflate: * length %u\n", c)); + + /* decode distance base of block to copy */ + GRABBITS(15); /* max bits for distance code */ + e = (t = td + ((uInt)b & md))->exop; + do { + DUMPBITS(t->bits) + if (e & 16) + { + /* get extra bits to add to distance base */ + e &= 15; + GRABBITS(e) /* get extra bits (up to 13) */ + d = t->base + ((uInt)b & inflate_mask[e]); + DUMPBITS(e) + Tracevv((stderr, "inflate: * distance %u\n", d)); + + /* do the copy */ + m -= c; + if ((uInt)(q - s->window) >= d) /* offset before dest */ + { /* just copy */ + r = q - d; + *q++ = *r++; c--; /* minimum count is three, */ + *q++ = *r++; c--; /* so unroll loop a little */ + } + else /* else offset after destination */ + { + e = d - (uInt)(q - s->window); /* bytes from offset to end */ + r = s->end - e; /* pointer to offset */ + if (c > e) /* if source crosses, */ + { + c -= e; /* copy to end of window */ + do { + *q++ = *r++; + } while (--e); + r = s->window; /* copy rest from start of window */ + } + } + do { /* copy all or what's left */ + *q++ = *r++; + } while (--c); + break; + } + else if ((e & 64) == 0) + e = (t = t->next + ((uInt)b & inflate_mask[e]))->exop; + else + { + z->msg = (char*)"invalid distance code"; + UNGRAB + UPDATE + return Z_DATA_ERROR; + } + } while (1); + break; + } + if ((e & 64) == 0) + { + if ((e = (t = t->next + ((uInt)b & inflate_mask[e]))->exop) == 0) + { + DUMPBITS(t->bits) + Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ? + "inflate: * literal '%c'\n" : + "inflate: * literal 0x%02x\n", t->base)); + *q++ = (Byte)t->base; + m--; + break; + } + } + else if (e & 32) + { + Tracevv((stderr, "inflate: * end of block\n")); + UNGRAB + UPDATE + return Z_STREAM_END; + } + else + { + z->msg = (char*)"invalid literal/length code"; + UNGRAB + UPDATE + return Z_DATA_ERROR; + } + } while (1); + } while (m >= 258 && n >= 10); + + /* not enough input or output--restore pointers and return */ + UNGRAB + UPDATE + return Z_OK; +} diff --git a/ef/Utilities/zlib/inffast.h b/ef/Utilities/zlib/inffast.h new file mode 100644 index 000000000000..8cc644efb1f3 --- /dev/null +++ b/ef/Utilities/zlib/inffast.h @@ -0,0 +1,17 @@ +/* inffast.h -- header to use inffast.c + * Copyright (C) 1995-1996 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +extern int inflate_fast OF(( + uInt, + uInt, + inflate_huft *, + inflate_huft *, + inflate_blocks_statef *, + z_streamp )); diff --git a/ef/Utilities/zlib/inflate.c b/ef/Utilities/zlib/inflate.c new file mode 100644 index 000000000000..74cc69c86847 --- /dev/null +++ b/ef/Utilities/zlib/inflate.c @@ -0,0 +1,345 @@ +/* inflate.c -- zlib interface to inflate modules + * Copyright (C) 1995-1996 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zutil.h" +#include "infblock.h" + +struct inflate_blocks_state {int dummy;}; /* for buggy compilers */ + +/* inflate private state */ +struct internal_state { + + /* mode */ + enum { + METHOD, /* waiting for method byte */ + FLAG, /* waiting for flag byte */ + DICT4, /* four dictionary check bytes to go */ + DICT3, /* three dictionary check bytes to go */ + DICT2, /* two dictionary check bytes to go */ + DICT1, /* one dictionary check byte to go */ + DICT0, /* waiting for inflateSetDictionary */ + BLOCKS, /* decompressing blocks */ + CHECK4, /* four check bytes to go */ + CHECK3, /* three check bytes to go */ + CHECK2, /* two check bytes to go */ + CHECK1, /* one check byte to go */ + DONE, /* finished check, done */ + BAD} /* got an error--stay here */ + mode; /* current inflate mode */ + + /* mode dependent information */ + union { + uInt method; /* if FLAGS, method byte */ + struct { + uLong was; /* computed check value */ + uLong need; /* stream check value */ + } check; /* if CHECK, check values to compare */ + uInt marker; /* if BAD, inflateSync's marker bytes count */ + } sub; /* submode */ + + /* mode independent information */ + int nowrap; /* flag for no wrapper */ + uInt wbits; /* log2(window size) (8..15, defaults to 15) */ + inflate_blocks_statef + *blocks; /* current inflate_blocks state */ + +}; + + +int inflateReset(z) +z_streamp z; +{ + uLong c; + + if (z == Z_NULL || z->state == Z_NULL) + return Z_STREAM_ERROR; + z->total_in = z->total_out = 0; + z->msg = Z_NULL; + z->state->mode = z->state->nowrap ? BLOCKS : METHOD; + inflate_blocks_reset(z->state->blocks, z, &c); + Trace((stderr, "inflate: reset\n")); + return Z_OK; +} + + +int inflateEnd(z) +z_streamp z; +{ + uLong c; + + if (z == Z_NULL || z->state == Z_NULL || z->zfree == Z_NULL) + return Z_STREAM_ERROR; + if (z->state->blocks != Z_NULL) + inflate_blocks_free(z->state->blocks, z, &c); + ZFREE(z, z->state); + z->state = Z_NULL; + Trace((stderr, "inflate: end\n")); + return Z_OK; +} + + +int inflateInit2_(z, w, version, stream_size) +z_streamp z; +int w; +const char *version; +int stream_size; +{ + if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || + stream_size != sizeof(z_stream)) + return Z_VERSION_ERROR; + + /* initialize state */ + if (z == Z_NULL) + return Z_STREAM_ERROR; + z->msg = Z_NULL; + if (z->zalloc == Z_NULL) + { + z->zalloc = zcalloc; + z->opaque = (voidpf)0; + } + if (z->zfree == Z_NULL) z->zfree = zcfree; + if ((z->state = (struct internal_state FAR *) + ZALLOC(z,1,sizeof(struct internal_state))) == Z_NULL) + return Z_MEM_ERROR; + z->state->blocks = Z_NULL; + + /* handle undocumented nowrap option (no zlib header or check) */ + z->state->nowrap = 0; + if (w < 0) + { + w = - w; + z->state->nowrap = 1; + } + + /* set window size */ + if (w < 8 || w > 15) + { + inflateEnd(z); + return Z_STREAM_ERROR; + } + z->state->wbits = (uInt)w; + + /* create inflate_blocks state */ + if ((z->state->blocks = + inflate_blocks_new(z, z->state->nowrap ? Z_NULL : adler32, (uInt)1 << w)) + == Z_NULL) + { + inflateEnd(z); + return Z_MEM_ERROR; + } + Trace((stderr, "inflate: allocated\n")); + + /* reset state */ + inflateReset(z); + return Z_OK; +} + + +int inflateInit_(z, version, stream_size) +z_streamp z; +const char *version; +int stream_size; +{ + return inflateInit2_(z, DEF_WBITS, version, stream_size); +} + + +#define NEEDBYTE {if(z->avail_in==0)return r;r=Z_OK;} +#define NEXTBYTE (z->avail_in--,z->total_in++,*z->next_in++) + +int inflate(z, f) +z_streamp z; +int f; +{ + int r; + uInt b; + + if (z == Z_NULL || z->state == Z_NULL || z->next_in == Z_NULL || f < 0) + return Z_STREAM_ERROR; + r = Z_BUF_ERROR; + while (1) switch (z->state->mode) + { + case METHOD: + NEEDBYTE + if (((z->state->sub.method = NEXTBYTE) & 0xf) != Z_DEFLATED) + { + z->state->mode = BAD; + z->msg = (char*)"unknown compression method"; + z->state->sub.marker = 5; /* can't try inflateSync */ + break; + } + if ((z->state->sub.method >> 4) + 8 > z->state->wbits) + { + z->state->mode = BAD; + z->msg = (char*)"invalid window size"; + z->state->sub.marker = 5; /* can't try inflateSync */ + break; + } + z->state->mode = FLAG; + case FLAG: + NEEDBYTE + b = NEXTBYTE; + if (((z->state->sub.method << 8) + b) % 31) + { + z->state->mode = BAD; + z->msg = (char*)"incorrect header check"; + z->state->sub.marker = 5; /* can't try inflateSync */ + break; + } + Trace((stderr, "inflate: zlib header ok\n")); + if (!(b & PRESET_DICT)) + { + z->state->mode = BLOCKS; + break; + } + z->state->mode = DICT4; + case DICT4: + NEEDBYTE + z->state->sub.check.need = (uLong)NEXTBYTE << 24; + z->state->mode = DICT3; + case DICT3: + NEEDBYTE + z->state->sub.check.need += (uLong)NEXTBYTE << 16; + z->state->mode = DICT2; + case DICT2: + NEEDBYTE + z->state->sub.check.need += (uLong)NEXTBYTE << 8; + z->state->mode = DICT1; + case DICT1: + NEEDBYTE + z->state->sub.check.need += (uLong)NEXTBYTE; + z->adler = z->state->sub.check.need; + z->state->mode = DICT0; + return Z_NEED_DICT; + case DICT0: + z->state->mode = BAD; + z->msg = (char*)"need dictionary"; + z->state->sub.marker = 0; /* can try inflateSync */ + return Z_STREAM_ERROR; + case BLOCKS: + r = inflate_blocks(z->state->blocks, z, r); + if (r == Z_DATA_ERROR) + { + z->state->mode = BAD; + z->state->sub.marker = 0; /* can try inflateSync */ + break; + } + if (r != Z_STREAM_END) + return r; + r = Z_OK; + inflate_blocks_reset(z->state->blocks, z, &z->state->sub.check.was); + if (z->state->nowrap) + { + z->state->mode = DONE; + break; + } + z->state->mode = CHECK4; + case CHECK4: + NEEDBYTE + z->state->sub.check.need = (uLong)NEXTBYTE << 24; + z->state->mode = CHECK3; + case CHECK3: + NEEDBYTE + z->state->sub.check.need += (uLong)NEXTBYTE << 16; + z->state->mode = CHECK2; + case CHECK2: + NEEDBYTE + z->state->sub.check.need += (uLong)NEXTBYTE << 8; + z->state->mode = CHECK1; + case CHECK1: + NEEDBYTE + z->state->sub.check.need += (uLong)NEXTBYTE; + + if (z->state->sub.check.was != z->state->sub.check.need) + { + z->state->mode = BAD; + z->msg = (char*)"incorrect data check"; + z->state->sub.marker = 5; /* can't try inflateSync */ + break; + } + Trace((stderr, "inflate: zlib check ok\n")); + z->state->mode = DONE; + case DONE: + return Z_STREAM_END; + case BAD: + return Z_DATA_ERROR; + default: + return Z_STREAM_ERROR; + } +} + + +int inflateSetDictionary(z, dictionary, dictLength) +z_streamp z; +const Bytef *dictionary; +uInt dictLength; +{ + uInt length = dictLength; + + if (z == Z_NULL || z->state == Z_NULL || z->state->mode != DICT0) + return Z_STREAM_ERROR; + + if (adler32(1L, dictionary, dictLength) != z->adler) return Z_DATA_ERROR; + z->adler = 1L; + + if (length >= ((uInt)1<state->wbits)) + { + length = (1<state->wbits)-1; + dictionary += dictLength - length; + } + inflate_set_dictionary(z->state->blocks, dictionary, length); + z->state->mode = BLOCKS; + return Z_OK; +} + + +int inflateSync(z) +z_streamp z; +{ + uInt n; /* number of bytes to look at */ + Bytef *p; /* pointer to bytes */ + uInt m; /* number of marker bytes found in a row */ + uLong r, w; /* temporaries to save total_in and total_out */ + + /* set up */ + if (z == Z_NULL || z->state == Z_NULL) + return Z_STREAM_ERROR; + if (z->state->mode != BAD) + { + z->state->mode = BAD; + z->state->sub.marker = 0; + } + if ((n = z->avail_in) == 0) + return Z_BUF_ERROR; + p = z->next_in; + m = z->state->sub.marker; + + /* search */ + while (n && m < 4) + { + if (*p == (Byte)(m < 2 ? 0 : 0xff)) + m++; + else if (*p) + m = 0; + else + m = 4 - m; + p++, n--; + } + + /* restore */ + z->total_in += p - z->next_in; + z->next_in = p; + z->avail_in = n; + z->state->sub.marker = m; + + /* return no joy or set up to restart on a new block */ + if (m != 4) + return Z_DATA_ERROR; + r = z->total_in; w = z->total_out; + inflateReset(z); + z->total_in = r; z->total_out = w; + z->state->mode = BLOCKS; + return Z_OK; +} diff --git a/ef/Utilities/zlib/inftrees.c b/ef/Utilities/zlib/inftrees.c new file mode 100644 index 000000000000..b4053bf036f8 --- /dev/null +++ b/ef/Utilities/zlib/inftrees.c @@ -0,0 +1,470 @@ +/* inftrees.c -- generate Huffman trees for efficient decoding + * Copyright (C) 1995-1996 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zutil.h" +#include "inftrees.h" + +char inflate_copyright[] = " inflate 1.0.4 Copyright 1995-1996 Mark Adler "; +/* + If you use the zlib library in a product, an acknowledgment is welcome + in the documentation of your product. If for some reason you cannot + include such an acknowledgment, I would appreciate that you keep this + copyright string in the executable of your product. + */ +struct internal_state {int dummy;}; /* for buggy compilers */ + +/* simplify the use of the inflate_huft type with some defines */ +#define base more.Base +#define next more.Next +#define exop word.what.Exop +#define bits word.what.Bits + + +local int huft_build OF(( + uIntf *, /* code lengths in bits */ + uInt, /* number of codes */ + uInt, /* number of "simple" codes */ + uIntf *, /* list of base values for non-simple codes */ + uIntf *, /* list of extra bits for non-simple codes */ + inflate_huft * FAR*,/* result: starting table */ + uIntf *, /* maximum lookup bits (returns actual) */ + z_streamp )); /* for zalloc function */ + +local voidpf falloc OF(( + voidpf, /* opaque pointer (not used) */ + uInt, /* number of items */ + uInt)); /* size of item */ + +/* Tables for deflate from PKZIP's appnote.txt. */ +local uInt cplens[31] = { /* Copy lengths for literal codes 257..285 */ + 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, + 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; + /* actually lengths - 2; also see note #13 above about 258 */ +local uInt cplext[31] = { /* Extra bits for literal codes 257..285 */ + 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, + 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 192, 192}; /* 192==invalid */ +local uInt cpdist[30] = { /* Copy offsets for distance codes 0..29 */ + 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, + 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, + 8193, 12289, 16385, 24577}; +local uInt cpdext[30] = { /* Extra bits for distance codes */ + 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, + 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, + 12, 12, 13, 13}; + +/* + Huffman code decoding is performed using a multi-level table lookup. + The fastest way to decode is to simply build a lookup table whose + size is determined by the longest code. However, the time it takes + to build this table can also be a factor if the data being decoded + is not very long. The most common codes are necessarily the + shortest codes, so those codes dominate the decoding time, and hence + the speed. The idea is you can have a shorter table that decodes the + shorter, more probable codes, and then point to subsidiary tables for + the longer codes. The time it costs to decode the longer codes is + then traded against the time it takes to make longer tables. + + This results of this trade are in the variables lbits and dbits + below. lbits is the number of bits the first level table for literal/ + length codes can decode in one step, and dbits is the same thing for + the distance codes. Subsequent tables are also less than or equal to + those sizes. These values may be adjusted either when all of the + codes are shorter than that, in which case the longest code length in + bits is used, or when the shortest code is *longer* than the requested + table size, in which case the length of the shortest code in bits is + used. + + There are two different values for the two tables, since they code a + different number of possibilities each. The literal/length table + codes 286 possible values, or in a flat code, a little over eight + bits. The distance table codes 30 possible values, or a little less + than five bits, flat. The optimum values for speed end up being + about one bit more than those, so lbits is 8+1 and dbits is 5+1. + The optimum values may differ though from machine to machine, and + possibly even between compilers. Your mileage may vary. + */ + + +/* If BMAX needs to be larger than 16, then h and x[] should be uLong. */ +#define BMAX 15 /* maximum bit length of any code */ +#define N_MAX 288 /* maximum number of codes in any set */ + +#ifdef DEBUG_ZIP + uInt inflate_hufts; +#endif + +local int huft_build(b, n, s, d, e, t, m, zs) +uIntf *b; /* code lengths in bits (all assumed <= BMAX) */ +uInt n; /* number of codes (assumed <= N_MAX) */ +uInt s; /* number of simple-valued codes (0..s-1) */ +uIntf *d; /* list of base values for non-simple codes */ +uIntf *e; /* list of extra bits for non-simple codes */ +inflate_huft * FAR *t; /* result: starting table */ +uIntf *m; /* maximum lookup bits, returns actual */ +z_streamp zs; /* for zalloc function */ +/* Given a list of code lengths and a maximum table size, make a set of + tables to decode that set of codes. Return Z_OK on success, Z_BUF_ERROR + if the given code set is incomplete (the tables are still built in this + case), Z_DATA_ERROR if the input is invalid (all zero length codes or an + over-subscribed set of lengths), or Z_MEM_ERROR if not enough memory. */ +{ + + uInt a; /* counter for codes of length k */ + uInt c[BMAX+1]; /* bit length count table */ + uInt f; /* i repeats in table every f entries */ + int g; /* maximum code length */ + int h; /* table level */ + register uInt i; /* counter, current code */ + register uInt j; /* counter */ + register int k; /* number of bits in current code */ + int l; /* bits per table (returned in m) */ + register uIntf *p; /* pointer into c[], b[], or v[] */ + inflate_huft *q; /* points to current table */ + struct inflate_huft_s r; /* table entry for structure assignment */ + inflate_huft *u[BMAX]; /* table stack */ + uInt v[N_MAX]; /* values in order of bit length */ + register int w; /* bits before this table == (l * h) */ + uInt x[BMAX+1]; /* bit offsets, then code stack */ + uIntf *xp; /* pointer into x */ + int y; /* number of dummy codes added */ + uInt z; /* number of entries in current table */ + + + /* Generate counts for each bit length */ + p = c; +#define C0 *p++ = 0; +#define C2 C0 C0 C0 C0 +#define C4 C2 C2 C2 C2 + C4 /* clear c[]--assume BMAX+1 is 16 */ + p = b; i = n; + do { + c[*p++]++; /* assume all entries <= BMAX */ + } while (--i); + if (c[0] == n) /* null input--all zero length codes */ + { + *t = (inflate_huft *)Z_NULL; + *m = 0; + return Z_OK; + } + + + /* Find minimum and maximum length, bound *m by those */ + l = *m; + for (j = 1; j <= BMAX; j++) + if (c[j]) + break; + k = j; /* minimum code length */ + if ((uInt)l < j) + l = j; + for (i = BMAX; i; i--) + if (c[i]) + break; + g = i; /* maximum code length */ + if ((uInt)l > i) + l = i; + *m = l; + + + /* Adjust last length count to fill out codes, if needed */ + for (y = 1 << j; j < i; j++, y <<= 1) + if ((y -= c[j]) < 0) + return Z_DATA_ERROR; + if ((y -= c[i]) < 0) + return Z_DATA_ERROR; + c[i] += y; + + + /* Generate starting offsets into the value table for each length */ + x[1] = j = 0; + p = c + 1; xp = x + 2; + while (--i) { /* note that i == g from above */ + *xp++ = (j += *p++); + } + + + /* Make a table of values in order of bit lengths */ + p = b; i = 0; + do { + if ((j = *p++) != 0) + v[x[j]++] = i; + } while (++i < n); + + + /* Generate the Huffman codes and for each, make the table entries */ + x[0] = i = 0; /* first Huffman code is zero */ + p = v; /* grab values in bit order */ + h = -1; /* no tables yet--level -1 */ + w = -l; /* bits decoded == (l * h) */ + u[0] = (inflate_huft *)Z_NULL; /* just to keep compilers happy */ + q = (inflate_huft *)Z_NULL; /* ditto */ + z = 0; /* ditto */ + + /* go through the bit lengths (k already is bits in shortest code) */ + for (; k <= g; k++) + { + a = c[k]; + while (a--) + { + /* here i is the Huffman code of length k bits for value *p */ + /* make tables up to required level */ + while (k > w + l) + { + h++; + w += l; /* previous table always l bits */ + + /* compute minimum size table less than or equal to l bits */ + z = g - w; + z = z > (uInt)l ? l : z; /* table size upper limit */ + if ((f = 1 << (j = k - w)) > a + 1) /* try a k-w bit table */ + { /* too few codes for k-w bit table */ + f -= a + 1; /* deduct codes from patterns left */ + xp = c + k; + if (j < z) + while (++j < z) /* try smaller tables up to z bits */ + { + if ((f <<= 1) <= *++xp) + break; /* enough codes to use up j bits */ + f -= *xp; /* else deduct codes from patterns */ + } + } + z = 1 << j; /* table entries for j-bit table */ + + /* allocate and link in new table */ + if ((q = (inflate_huft *)ZALLOC + (zs,z + 1,sizeof(inflate_huft))) == Z_NULL) + { + if (h) + inflate_trees_free(u[0], zs); + return Z_MEM_ERROR; /* not enough memory */ + } +#ifdef DEBUG_ZIP + inflate_hufts += z + 1; +#endif + *t = q + 1; /* link to list for huft_free() */ + *(t = &(q->next)) = Z_NULL; + u[h] = ++q; /* table starts after link */ + + /* connect to last table, if there is one */ + if (h) + { + x[h] = i; /* save pattern for backing up */ + r.bits = (Byte)l; /* bits to dump before this table */ + r.exop = (Byte)j; /* bits in this table */ + r.next = q; /* pointer to this table */ + j = i >> (w - l); /* (get around Turbo C bug) */ + u[h-1][j] = r; /* connect to last table */ + } + } + + /* set up table entry in r */ + r.bits = (Byte)(k - w); + if (p >= v + n) + r.exop = 128 + 64; /* out of values--invalid code */ + else if (*p < s) + { + r.exop = (Byte)(*p < 256 ? 0 : 32 + 64); /* 256 is end-of-block */ + r.base = *p++; /* simple code is just the value */ + } + else + { + r.exop = (Byte)(e[*p - s] + 16 + 64);/* non-simple--look up in lists */ + r.base = d[*p++ - s]; + } + + /* fill code-like entries with r */ + f = 1 << (k - w); + for (j = i >> w; j < z; j += f) + q[j] = r; + + /* backwards increment the k-bit code i */ + for (j = 1 << (k - 1); i & j; j >>= 1) + i ^= j; + i ^= j; + + /* backup over finished tables */ + while ((i & ((1 << w) - 1)) != x[h]) + { + h--; /* don't need to update q */ + w -= l; + } + } + } + + + /* Return Z_BUF_ERROR if we were given an incomplete table */ + return y != 0 && g != 1 ? Z_BUF_ERROR : Z_OK; +} + + +int inflate_trees_bits(c, bb, tb, z) +uIntf *c; /* 19 code lengths */ +uIntf *bb; /* bits tree desired/actual depth */ +inflate_huft * FAR *tb; /* bits tree result */ +z_streamp z; /* for zfree function */ +{ + int r; + + r = huft_build(c, 19, 19, (uIntf*)Z_NULL, (uIntf*)Z_NULL, tb, bb, z); + if (r == Z_DATA_ERROR) + z->msg = (char*)"oversubscribed dynamic bit lengths tree"; + else if (r == Z_BUF_ERROR) + { + inflate_trees_free(*tb, z); + z->msg = (char*)"incomplete dynamic bit lengths tree"; + r = Z_DATA_ERROR; + } + return r; +} + + +int inflate_trees_dynamic(nl, nd, c, bl, bd, tl, td, z) +uInt nl; /* number of literal/length codes */ +uInt nd; /* number of distance codes */ +uIntf *c; /* that many (total) code lengths */ +uIntf *bl; /* literal desired/actual bit depth */ +uIntf *bd; /* distance desired/actual bit depth */ +inflate_huft * FAR *tl; /* literal/length tree result */ +inflate_huft * FAR *td; /* distance tree result */ +z_streamp z; /* for zfree function */ +{ + int r; + + /* build literal/length tree */ + if ((r = huft_build(c, nl, 257, cplens, cplext, tl, bl, z)) != Z_OK) + { + if (r == Z_DATA_ERROR) + z->msg = (char*)"oversubscribed literal/length tree"; + else if (r == Z_BUF_ERROR) + { + inflate_trees_free(*tl, z); + z->msg = (char*)"incomplete literal/length tree"; + r = Z_DATA_ERROR; + } + return r; + } + + /* build distance tree */ + if ((r = huft_build(c + nl, nd, 0, cpdist, cpdext, td, bd, z)) != Z_OK) + { + if (r == Z_DATA_ERROR) + z->msg = (char*)"oversubscribed literal/length tree"; + else if (r == Z_BUF_ERROR) { +#ifdef PKZIP_BUG_WORKAROUND + r = Z_OK; + } +#else + inflate_trees_free(*td, z); + z->msg = (char*)"incomplete literal/length tree"; + r = Z_DATA_ERROR; + } + inflate_trees_free(*tl, z); + return r; +#endif + } + + /* done */ + return Z_OK; +} + + +/* build fixed tables only once--keep them here */ +local int fixed_built = 0; +#define FIXEDH 530 /* number of hufts used by fixed tables */ +local inflate_huft fixed_mem[FIXEDH]; +local uInt fixed_bl; +local uInt fixed_bd; +local inflate_huft *fixed_tl; +local inflate_huft *fixed_td; + + +local voidpf falloc(q, n, s) +voidpf q; /* opaque pointer */ +uInt n; /* number of items */ +uInt s; /* size of item */ +{ + Assert(s == sizeof(inflate_huft) && n <= (uInt) *(intf *)q, + "inflate_trees falloc overflow"); + *(intf *)q -= n+s-s; /* s-s to avoid warning */ + return (voidpf)(fixed_mem + *(intf *)q); +} + + +int inflate_trees_fixed(bl, bd, tl, td) +uIntf *bl; /* literal desired/actual bit depth */ +uIntf *bd; /* distance desired/actual bit depth */ +inflate_huft * FAR *tl; /* literal/length tree result */ +inflate_huft * FAR *td; /* distance tree result */ +{ + /* build fixed tables if not already (multiple overlapped executions ok) */ + if (!fixed_built) + { + int k; /* temporary variable */ + unsigned c[288]; /* length list for huft_build */ + z_stream z; /* for falloc function */ + int f = FIXEDH; /* number of hufts left in fixed_mem */ + + /* set up fake z_stream for memory routines */ + z.zalloc = falloc; + z.zfree = Z_NULL; + z.opaque = (voidpf)&f; + + /* literal table */ + for (k = 0; k < 144; k++) + c[k] = 8; + for (; k < 256; k++) + c[k] = 9; + for (; k < 280; k++) + c[k] = 7; + for (; k < 288; k++) + c[k] = 8; + fixed_bl = 7; + huft_build(c, 288, 257, cplens, cplext, &fixed_tl, &fixed_bl, &z); + + /* distance table */ + for (k = 0; k < 30; k++) + c[k] = 5; + fixed_bd = 5; + huft_build(c, 30, 0, cpdist, cpdext, &fixed_td, &fixed_bd, &z); + + /* done */ + Assert(f == 0, "invalid build of fixed tables"); + fixed_built = 1; + } + *bl = fixed_bl; + *bd = fixed_bd; + *tl = fixed_tl; + *td = fixed_td; + return Z_OK; +} + + +int inflate_trees_free(t, z) +inflate_huft *t; /* table to free */ +z_streamp z; /* for zfree function */ +/* Free the malloc'ed tables built by huft_build(), which makes a linked + list of the tables it made, with the links in a dummy first entry of + each table. */ +{ + register inflate_huft *p, *q, *r; + + /* Reverse linked list */ + p = Z_NULL; + q = t; + while (q != Z_NULL) + { + r = (q - 1)->next; + (q - 1)->next = p; + p = q; + q = r; + } + /* Go through linked list, freeing from the malloced (t[-1]) address. */ + while (p != Z_NULL) + { + q = (--p)->next; + ZFREE(z,p); + p = q; + } + return Z_OK; +} diff --git a/ef/Utilities/zlib/inftrees.h b/ef/Utilities/zlib/inftrees.h new file mode 100644 index 000000000000..5fe4c9ec0b6c --- /dev/null +++ b/ef/Utilities/zlib/inftrees.h @@ -0,0 +1,59 @@ +/* inftrees.h -- header to use inftrees.c + * Copyright (C) 1995-1996 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* Huffman code lookup table entry--this entry is four bytes for machines + that have 16-bit pointers (e.g. PC's in the small or medium model). */ + +typedef struct inflate_huft_s FAR inflate_huft; + +struct inflate_huft_s { + union { + struct { + Byte Exop; /* number of extra bits or operation */ + Byte Bits; /* number of bits in this code or subcode */ + } what; + Bytef *pad; /* pad structure to a power of 2 (4 bytes for */ + } word; /* 16-bit, 8 bytes for 32-bit machines) */ + union { + uInt Base; /* literal, length base, or distance base */ + inflate_huft *Next; /* pointer to next level of table */ + } more; +}; + +#ifdef DEBUG_ZIP + extern uInt inflate_hufts; +#endif + +extern int inflate_trees_bits OF(( + uIntf *, /* 19 code lengths */ + uIntf *, /* bits tree desired/actual depth */ + inflate_huft * FAR *, /* bits tree result */ + z_streamp )); /* for zalloc, zfree functions */ + +extern int inflate_trees_dynamic OF(( + uInt, /* number of literal/length codes */ + uInt, /* number of distance codes */ + uIntf *, /* that many (total) code lengths */ + uIntf *, /* literal desired/actual bit depth */ + uIntf *, /* distance desired/actual bit depth */ + inflate_huft * FAR *, /* literal/length tree result */ + inflate_huft * FAR *, /* distance tree result */ + z_streamp )); /* for zalloc, zfree functions */ + +extern int inflate_trees_fixed OF(( + uIntf *, /* literal desired/actual bit depth */ + uIntf *, /* distance desired/actual bit depth */ + inflate_huft * FAR *, /* literal/length tree result */ + inflate_huft * FAR *)); /* distance tree result */ + +extern int inflate_trees_free OF(( + inflate_huft *, /* tables to free */ + z_streamp )); /* for zfree function */ + diff --git a/ef/Utilities/zlib/infutil.c b/ef/Utilities/zlib/infutil.c new file mode 100644 index 000000000000..eb21199c3509 --- /dev/null +++ b/ef/Utilities/zlib/infutil.c @@ -0,0 +1,87 @@ +/* inflate_util.c -- data and routines common to blocks and codes + * Copyright (C) 1995-1996 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zutil.h" +#include "infblock.h" +#include "inftrees.h" +#include "infcodes.h" +#include "infutil.h" + +struct inflate_codes_state {int dummy;}; /* for buggy compilers */ + +/* And'ing with mask[n] masks the lower n bits */ +uInt inflate_mask[17] = { + 0x0000, + 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff, + 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff +}; + + +/* copy as much as possible from the sliding window to the output area */ +int inflate_flush(s, z, r) +inflate_blocks_statef *s; +z_streamp z; +int r; +{ + uInt n; + Bytef *p; + Bytef *q; + + /* local copies of source and destination pointers */ + p = z->next_out; + q = s->read; + + /* compute number of bytes to copy as far as end of window */ + n = (uInt)((q <= s->write ? s->write : s->end) - q); + if (n > z->avail_out) n = z->avail_out; + if (n && r == Z_BUF_ERROR) r = Z_OK; + + /* update counters */ + z->avail_out -= n; + z->total_out += n; + + /* update check information */ + if (s->checkfn != Z_NULL) + z->adler = s->check = (*s->checkfn)(s->check, q, n); + + /* copy as far as end of window */ + zmemcpy(p, q, n); + p += n; + q += n; + + /* see if more to copy at beginning of window */ + if (q == s->end) + { + /* wrap pointers */ + q = s->window; + if (s->write == s->end) + s->write = s->window; + + /* compute bytes to copy */ + n = (uInt)(s->write - q); + if (n > z->avail_out) n = z->avail_out; + if (n && r == Z_BUF_ERROR) r = Z_OK; + + /* update counters */ + z->avail_out -= n; + z->total_out += n; + + /* update check information */ + if (s->checkfn != Z_NULL) + z->adler = s->check = (*s->checkfn)(s->check, q, n); + + /* copy */ + zmemcpy(p, q, n); + p += n; + q += n; + } + + /* update pointers */ + z->next_out = p; + s->read = q; + + /* done */ + return r; +} diff --git a/ef/Utilities/zlib/infutil.h b/ef/Utilities/zlib/infutil.h new file mode 100644 index 000000000000..702cd290c37e --- /dev/null +++ b/ef/Utilities/zlib/infutil.h @@ -0,0 +1,99 @@ +/* infutil.h -- types and macros common to blocks and codes + * Copyright (C) 1995-1996 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +#ifndef _INFUTIL_H +#define _INFUTIL_H + +typedef enum { + TYPE, /* get type bits (3, including end bit) */ + LENS, /* get lengths for stored */ + STORED, /* processing stored block */ + TABLE, /* get table lengths */ + BTREE, /* get bit lengths tree for a dynamic block */ + DTREE, /* get length, distance trees for a dynamic block */ + CODES, /* processing fixed or dynamic block */ + DRY, /* output remaining window bytes */ + DONE, /* finished last block, done */ + BAD} /* got a data error--stuck here */ +inflate_block_mode; + +/* inflate blocks semi-private state */ +struct inflate_blocks_state { + + /* mode */ + inflate_block_mode mode; /* current inflate_block mode */ + + /* mode dependent information */ + union { + uInt left; /* if STORED, bytes left to copy */ + struct { + uInt table; /* table lengths (14 bits) */ + uInt index; /* index into blens (or border) */ + uIntf *blens; /* bit lengths of codes */ + uInt bb; /* bit length tree depth */ + inflate_huft *tb; /* bit length decoding tree */ + } trees; /* if DTREE, decoding info for trees */ + struct { + inflate_huft *tl; + inflate_huft *td; /* trees to free */ + inflate_codes_statef + *codes; + } decode; /* if CODES, current state */ + } sub; /* submode */ + uInt last; /* true if this block is the last block */ + + /* mode independent information */ + uInt bitk; /* bits in bit buffer */ + uLong bitb; /* bit buffer */ + Bytef *window; /* sliding window */ + Bytef *end; /* one byte after sliding window */ + Bytef *read; /* window read pointer */ + Bytef *write; /* window write pointer */ + check_func checkfn; /* check function */ + uLong check; /* check on output */ + +}; + + +/* defines for inflate input/output */ +/* update pointers and return */ +#define UPDBITS {s->bitb=b;s->bitk=k;} +#define UPDIN {z->avail_in=n;z->total_in+=p-z->next_in;z->next_in=p;} +#define UPDOUT {s->write=q;} +#define UPDATE {UPDBITS UPDIN UPDOUT} +#define LEAVE {UPDATE return inflate_flush(s,z,r);} +/* get bytes and bits */ +#define LOADIN {p=z->next_in;n=z->avail_in;b=s->bitb;k=s->bitk;} +#define NEEDBYTE {if(n)r=Z_OK;else LEAVE} +#define NEXTBYTE (n--,*p++) +#define NEEDBITS(j) {while(k<(j)){NEEDBYTE;b|=((uLong)NEXTBYTE)<>=(j);k-=(j);} +/* output bytes */ +#define WAVAIL (uInt)(qread?s->read-q-1:s->end-q) +#define LOADOUT {q=s->write;m=(uInt)WAVAIL;} +#define WRAP {if(q==s->end&&s->read!=s->window){q=s->window;m=(uInt)WAVAIL;}} +#define FLUSH {UPDOUT r=inflate_flush(s,z,r); LOADOUT} +#define NEEDOUT {if(m==0){WRAP if(m==0){FLUSH WRAP if(m==0) LEAVE}}r=Z_OK;} +#define OUTBYTE(a) {*q++=(Byte)(a);m--;} +/* load local pointers */ +#define LOAD {LOADIN LOADOUT} + +/* masks for lower bits (size given to avoid silly warnings with Visual C++) */ +extern uInt inflate_mask[17]; + +/* copy as much as possible from the sliding window to the output area */ +extern int inflate_flush OF(( + inflate_blocks_statef *, + z_streamp , + int)); + +struct internal_state {int dummy;}; /* for buggy compilers */ + +#endif diff --git a/ef/Utilities/zlib/macbuild/zlib.prj2 b/ef/Utilities/zlib/macbuild/zlib.prj2 new file mode 100644 index 000000000000..0c5022cb5935 Binary files /dev/null and b/ef/Utilities/zlib/macbuild/zlib.prj2 differ diff --git a/ef/Utilities/zlib/macbuild/zlib.prj2.exp b/ef/Utilities/zlib/macbuild/zlib.prj2.exp new file mode 100644 index 000000000000..fabf7e8e4ced --- /dev/null +++ b/ef/Utilities/zlib/macbuild/zlib.prj2.exp @@ -0,0 +1,53 @@ +adler32 +compress +crc32 +get_crc_table +deflate_copyright +deflateCopy +deflateEnd +deflate +deflateParams +deflateReset +deflateSetDictionary +deflateInit2_ +deflateInit_ +gzerror +gzclose +gzflush +gzwrite +gzread +gzdopen +gzopen +inflate_set_dictionary +inflate_blocks_free +inflate_blocks +inflate_blocks_new +inflate_blocks_reset +inflate_codes_free +inflate_codes +inflate_codes_new +inflate_fast +inflateSync +inflateSetDictionary +inflate +inflateInit_ +inflateInit2_ +inflateEnd +inflateReset +inflate_copyright +inflate_trees_free +inflate_trees_fixed +inflate_trees_dynamic +inflate_trees_bits +inflate_mask +inflate_flush +_tr_tally +_tr_flush_block +_tr_align +_tr_stored_block +_tr_init +uncompress +z_errmsg +zcfree +zcalloc +zlibVersion diff --git a/ef/Utilities/zlib/manifest.mn b/ef/Utilities/zlib/manifest.mn new file mode 100644 index 000000000000..f0cbe82136ab --- /dev/null +++ b/ef/Utilities/zlib/manifest.mn @@ -0,0 +1,47 @@ +#!gmake +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. +DEPTH = ../.. + +MODULE_NAME = EF + +CSRCS = adler32.c \ + compress.c \ + crc32.c \ + deflate.c \ + gzio.c \ + infblock.c \ + infcodes.c \ + inffast.c \ + inflate.c \ + inftrees.c \ + infutil.c \ + trees.c \ + uncompr.c \ + zutil.c \ + $(NULL) + +LOCAL_EXPORTS = deflate.h \ + infblock.h \ + infcodes.h \ + inffast.h \ + inftrees.h \ + infutil.h \ + zconf.h \ + zlib.h \ + zutil.h \ + $(NULL) + diff --git a/ef/Utilities/zlib/minigzip.c b/ef/Utilities/zlib/minigzip.c new file mode 100644 index 000000000000..2bbed75675bc --- /dev/null +++ b/ef/Utilities/zlib/minigzip.c @@ -0,0 +1,244 @@ +/* minigzip.c -- simulate gzip using the zlib compression library + * Copyright (C) 1995-1996 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + * minigzip is a minimal implementation of the gzip utility. This is + * only an example of using zlib and isn't meant to replace the + * full-featured gzip. No attempt is made to deal with file systems + * limiting names to 14 or 8+3 characters, etc... Error checking is + * very limited. So use minigzip only for testing; use gzip for the + * real thing. On MSDOS, use only on file names without extension + * or in pipe mode. + */ + +#include +#include "zlib.h" + +#ifdef STDC +# include +# include +#else + extern void exit OF((int)); +#endif + + +#if defined(MSDOS) || defined(OS2) || defined(WIN32) +# include +# include +# define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY) +#else +# define SET_BINARY_MODE(file) +#endif + +#ifdef VMS +# define unlink delete +# define GZ_SUFFIX "-gz" +#endif +#ifdef RISCOS +# define unlink remove +# define GZ_SUFFIX "-gz" +# define fileno(file) file->__file +#endif + +#ifndef GZ_SUFFIX +# define GZ_SUFFIX ".gz" +#endif +#define SUFFIX_LEN sizeof(GZ_SUFFIX) + +extern int unlink OF((const char *)); + +#define BUFLEN 4096 +#define MAX_NAME_LEN 1024 + +#define local static +/* For MSDOS and other systems with limitation on stack size. For Unix, + #define local + works also. + */ + +char *prog; + +void error OF((const char *msg)); +void gz_compress OF((FILE *in, gzFile out)); +void gz_uncompress OF((gzFile in, FILE *out)); +void file_compress OF((char *file)); +void file_uncompress OF((char *file)); +int main OF((int argc, char *argv[])); + +/* =========================================================================== + * Display error message and exit + */ +void error(msg) + const char *msg; +{ + fprintf(stderr, "%s: %s\n", prog, msg); + exit(1); +} + +/* =========================================================================== + * Compress input to output then close both files. + */ +void gz_compress(in, out) + FILE *in; + gzFile out; +{ + local char buf[BUFLEN]; + int len; + int err; + + for (;;) { + len = fread(buf, 1, sizeof(buf), in); + if (ferror(in)) { + perror("fread"); + exit(1); + } + if (len == 0) break; + + if (gzwrite(out, buf, (unsigned)len) != len) error(gzerror(out, &err)); + } + fclose(in); + if (gzclose(out) != Z_OK) error("failed gzclose"); +} + +/* =========================================================================== + * Uncompress input to output then close both files. + */ +void gz_uncompress(in, out) + gzFile in; + FILE *out; +{ + local char buf[BUFLEN]; + int len; + int err; + + for (;;) { + len = gzread(in, buf, sizeof(buf)); + if (len < 0) error (gzerror(in, &err)); + if (len == 0) break; + + if ((int)fwrite(buf, 1, (unsigned)len, out) != len) { + error("failed fwrite"); + } + } + if (fclose(out)) error("failed fclose"); + + if (gzclose(in) != Z_OK) error("failed gzclose"); +} + + +/* =========================================================================== + * Compress the given file: create a corresponding .gz file and remove the + * original. + */ +void file_compress(file) + char *file; +{ + local char outfile[MAX_NAME_LEN]; + FILE *in; + gzFile out; + + strcpy(outfile, file); + strcat(outfile, GZ_SUFFIX); + + in = fopen(file, "rb"); + if (in == NULL) { + perror(file); + exit(1); + } + out = gzopen(outfile, "wb"); /* use "wb9" for maximal compression */ + if (out == NULL) { + fprintf(stderr, "%s: can't gzopen %s\n", prog, outfile); + exit(1); + } + gz_compress(in, out); + + unlink(file); +} + + +/* =========================================================================== + * Uncompress the given file and remove the original. + */ +void file_uncompress(file) + char *file; +{ + local char buf[MAX_NAME_LEN]; + char *infile, *outfile; + FILE *out; + gzFile in; + int len = strlen(file); + + strcpy(buf, file); + + if (len > SUFFIX_LEN && strcmp(file+len-SUFFIX_LEN, GZ_SUFFIX) == 0) { + infile = file; + outfile = buf; + outfile[len-3] = '\0'; + } else { + outfile = file; + infile = buf; + strcat(infile, GZ_SUFFIX); + } + in = gzopen(infile, "rb"); + if (in == NULL) { + fprintf(stderr, "%s: can't gzopen %s\n", prog, infile); + exit(1); + } + out = fopen(outfile, "wb"); + if (out == NULL) { + perror(file); + exit(1); + } + + gz_uncompress(in, out); + + unlink(infile); +} + + +/* =========================================================================== + * Usage: minigzip [-d] [files...] + */ + +int main(argc, argv) + int argc; + char *argv[]; +{ + int uncompr = 0; + gzFile file; + + prog = argv[0]; + argc--, argv++; + + if (argc > 0) { + uncompr = (strcmp(*argv, "-d") == 0); + if (uncompr) { + argc--, argv++; + } + } + if (argc == 0) { + SET_BINARY_MODE(stdin); + SET_BINARY_MODE(stdout); + if (uncompr) { + file = gzdopen(fileno(stdin), "rb"); + if (file == NULL) error("can't gzdopen stdin"); + gz_uncompress(file, stdout); + } else { + file = gzdopen(fileno(stdout), "wb"); /* "wb9" for max compr. */ + if (file == NULL) error("can't gzdopen stdout"); + gz_compress(stdin, file); + } + } else { + do { + if (uncompr) { + file_uncompress(*argv); + } else { + file_compress(*argv); + } + } while (argv++, --argc); + } + exit(0); + return 0; /* to avoid warning */ +} diff --git a/ef/Utilities/zlib/trees.c b/ef/Utilities/zlib/trees.c new file mode 100644 index 000000000000..99cf6603236e --- /dev/null +++ b/ef/Utilities/zlib/trees.c @@ -0,0 +1,1139 @@ +/* trees.c -- output deflated data using Huffman coding + * Copyright (C) 1995-1996 Jean-loup Gailly + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + * ALGORITHM + * + * The "deflation" process uses several Huffman trees. The more + * common source values are represented by shorter bit sequences. + * + * Each code tree is stored in a compressed form which is itself + * a Huffman encoding of the lengths of all the code strings (in + * ascending order by source values). The actual code strings are + * reconstructed from the lengths in the inflate process, as described + * in the deflate specification. + * + * REFERENCES + * + * Deutsch, L.P.,"'Deflate' Compressed Data Format Specification". + * Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc + * + * Storer, James A. + * Data Compression: Methods and Theory, pp. 49-50. + * Computer Science Press, 1988. ISBN 0-7167-8156-5. + * + * Sedgewick, R. + * Algorithms, p290. + * Addison-Wesley, 1983. ISBN 0-201-06672-6. + */ + +#include "deflate.h" + +#ifdef DEBUG_ZIP +# include +#endif + +/* =========================================================================== + * Constants + */ + +#define MAX_BL_BITS 7 +/* Bit length codes must not exceed MAX_BL_BITS bits */ + +#define END_BLOCK 256 +/* end of block literal code */ + +#define REP_3_6 16 +/* repeat previous bit length 3-6 times (2 bits of repeat count) */ + +#define REPZ_3_10 17 +/* repeat a zero length 3-10 times (3 bits of repeat count) */ + +#define REPZ_11_138 18 +/* repeat a zero length 11-138 times (7 bits of repeat count) */ + +local int extra_lbits[LENGTH_CODES] /* extra bits for each length code */ + = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0}; + +local int extra_dbits[D_CODES] /* extra bits for each distance code */ + = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13}; + +local int extra_blbits[BL_CODES]/* extra bits for each bit length code */ + = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7}; + +local uch bl_order[BL_CODES] + = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15}; +/* The lengths of the bit length codes are sent in order of decreasing + * probability, to avoid transmitting the lengths for unused bit length codes. + */ + +#define Buf_size (8 * 2*sizeof(char)) +/* Number of bits used within bi_buf. (bi_buf might be implemented on + * more than 16 bits on some systems.) + */ + +/* =========================================================================== + * Local data. These are initialized only once. + */ + +local ct_data static_ltree[L_CODES+2]; +/* The static literal tree. Since the bit lengths are imposed, there is no + * need for the L_CODES extra codes used during heap construction. However + * The codes 286 and 287 are needed to build a canonical tree (see _tr_init + * below). + */ + +local ct_data static_dtree[D_CODES]; +/* The static distance tree. (Actually a trivial tree since all codes use + * 5 bits.) + */ + +local uch dist_code[512]; +/* distance codes. The first 256 values correspond to the distances + * 3 .. 258, the last 256 values correspond to the top 8 bits of + * the 15 bit distances. + */ + +local uch length_code[MAX_MATCH-MIN_MATCH+1]; +/* length code for each normalized match length (0 == MIN_MATCH) */ + +local int base_length[LENGTH_CODES]; +/* First normalized length for each code (0 = MIN_MATCH) */ + +local int base_dist[D_CODES]; +/* First normalized distance for each code (0 = distance of 1) */ + +struct static_tree_desc_s { + ct_data *static_tree; /* static tree or NULL */ + intf *extra_bits; /* extra bits for each code or NULL */ + int extra_base; /* base index for extra_bits */ + int elems; /* max number of elements in the tree */ + int max_length; /* max bit length for the codes */ +}; + +local static_tree_desc static_l_desc = +{static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS}; + +local static_tree_desc static_d_desc = +{static_dtree, extra_dbits, 0, D_CODES, MAX_BITS}; + +local static_tree_desc static_bl_desc = +{(ct_data *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS}; + +/* =========================================================================== + * Local (static) routines in this file. + */ + +local void tr_static_init OF((void)); +local void init_block OF((deflate_state *s)); +local void pqdownheap OF((deflate_state *s, ct_data *tree, int k)); +local void gen_bitlen OF((deflate_state *s, tree_desc *desc)); +local void gen_codes OF((ct_data *tree, int max_code, ushf *bl_count)); +local void build_tree OF((deflate_state *s, tree_desc *desc)); +local void scan_tree OF((deflate_state *s, ct_data *tree, int max_code)); +local void send_tree OF((deflate_state *s, ct_data *tree, int max_code)); +local int build_bl_tree OF((deflate_state *s)); +local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes, + int blcodes)); +local void compress_block OF((deflate_state *s, ct_data *ltree, + ct_data *dtree)); +local void set_data_type OF((deflate_state *s)); +local unsigned bi_reverse OF((unsigned value, int length)); +local void bi_windup OF((deflate_state *s)); +local void bi_flush OF((deflate_state *s)); +local void copy_block OF((deflate_state *s, charf *buf, unsigned len, + int header)); + +#ifndef DEBUG_ZIP +# define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len) + /* Send a code of the given tree. c and tree must not have side effects */ + +#else /* DEBUG_ZIP */ +# define send_code(s, c, tree) \ + { if (verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \ + send_bits(s, tree[c].Code, tree[c].Len); } +#endif + +#define d_code(dist) \ + ((dist) < 256 ? dist_code[dist] : dist_code[256+((dist)>>7)]) +/* Mapping from a distance to a distance code. dist is the distance - 1 and + * must not have side effects. dist_code[256] and dist_code[257] are never + * used. + */ + +/* =========================================================================== + * Output a short LSB first on the stream. + * IN assertion: there is enough room in pendingBuf. + */ +#define put_short(s, w) { \ + put_byte(s, (uch)((w) & 0xff)); \ + put_byte(s, (uch)((ush)(w) >> 8)); \ +} + +/* =========================================================================== + * Send a value on a given number of bits. + * IN assertion: length <= 16 and value fits in length bits. + */ +#ifdef DEBUG_ZIP +local void send_bits OF((deflate_state *s, int value, int length)); + +local void send_bits(s, value, length) + deflate_state *s; + int value; /* value to send */ + int length; /* number of bits */ +{ + Tracevv((stderr," l %2d v %4x ", length, value)); + Assert(length > 0 && length <= 15, "invalid length"); + s->bits_sent += (ulg)length; + + /* If not enough room in bi_buf, use (valid) bits from bi_buf and + * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid)) + * unused bits in value. + */ + if (s->bi_valid > (int)Buf_size - length) { + s->bi_buf |= (value << s->bi_valid); + put_short(s, s->bi_buf); + s->bi_buf = (ush)value >> (Buf_size - s->bi_valid); + s->bi_valid += length - Buf_size; + } else { + s->bi_buf |= value << s->bi_valid; + s->bi_valid += length; + } +} +#else /* !DEBUG_ZIP */ + +#define send_bits(s, value, length) \ +{ int len = length;\ + if (s->bi_valid > (int)Buf_size - len) {\ + int val = value;\ + s->bi_buf |= (val << s->bi_valid);\ + put_short(s, s->bi_buf);\ + s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\ + s->bi_valid += len - Buf_size;\ + } else {\ + s->bi_buf |= (value) << s->bi_valid;\ + s->bi_valid += len;\ + }\ +} +#endif /* DEBUG_ZIP */ + + +#define MAX(a,b) (a >= b ? a : b) +/* the arguments must not have side effects */ + +/* =========================================================================== + * Initialize the various 'constant' tables. In a multi-threaded environment, + * this function may be called by two threads concurrently, but this is + * harmless since both invocations do exactly the same thing. + */ +local void tr_static_init() +{ + static int static_init_done = 0; + int n; /* iterates over tree elements */ + int bits; /* bit counter */ + int length; /* length value */ + int code; /* code value */ + int dist; /* distance index */ + ush bl_count[MAX_BITS+1]; + /* number of codes at each bit length for an optimal tree */ + + if (static_init_done) return; + + /* Initialize the mapping length (0..255) -> length code (0..28) */ + length = 0; + for (code = 0; code < LENGTH_CODES-1; code++) { + base_length[code] = length; + for (n = 0; n < (1< dist code (0..29) */ + dist = 0; + for (code = 0 ; code < 16; code++) { + base_dist[code] = dist; + for (n = 0; n < (1<>= 7; /* from now on, all distances are divided by 128 */ + for ( ; code < D_CODES; code++) { + base_dist[code] = dist << 7; + for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) { + dist_code[256 + dist++] = (uch)code; + } + } + Assert (dist == 256, "tr_static_init: 256+dist != 512"); + + /* Construct the codes of the static literal tree */ + for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0; + n = 0; + while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++; + while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++; + while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++; + while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++; + /* Codes 286 and 287 do not exist, but we must include them in the + * tree construction to get a canonical Huffman tree (longest code + * all ones) + */ + gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count); + + /* The static distance tree is trivial: */ + for (n = 0; n < D_CODES; n++) { + static_dtree[n].Len = 5; + static_dtree[n].Code = bi_reverse((unsigned)n, 5); + } + static_init_done = 1; +} + +/* =========================================================================== + * Initialize the tree data structures for a new zlib stream. + */ +void _tr_init(s) + deflate_state *s; +{ + tr_static_init(); + + s->compressed_len = 0L; + + s->l_desc.dyn_tree = s->dyn_ltree; + s->l_desc.stat_desc = &static_l_desc; + + s->d_desc.dyn_tree = s->dyn_dtree; + s->d_desc.stat_desc = &static_d_desc; + + s->bl_desc.dyn_tree = s->bl_tree; + s->bl_desc.stat_desc = &static_bl_desc; + + s->bi_buf = 0; + s->bi_valid = 0; + s->last_eob_len = 8; /* enough lookahead for inflate */ +#ifdef DEBUG_ZIP + s->bits_sent = 0L; +#endif + + /* Initialize the first block of the first file: */ + init_block(s); +} + +/* =========================================================================== + * Initialize a new block. + */ +local void init_block(s) + deflate_state *s; +{ + int n; /* iterates over tree elements */ + + /* Initialize the trees. */ + for (n = 0; n < L_CODES; n++) s->dyn_ltree[n].Freq = 0; + for (n = 0; n < D_CODES; n++) s->dyn_dtree[n].Freq = 0; + for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0; + + s->dyn_ltree[END_BLOCK].Freq = 1; + s->opt_len = s->static_len = 0L; + s->last_lit = s->matches = 0; +} + +#define SMALLEST 1 +/* Index within the heap array of least frequent node in the Huffman tree */ + + +/* =========================================================================== + * Remove the smallest element from the heap and recreate the heap with + * one less element. Updates heap and heap_len. + */ +#define pqremove(s, tree, top) \ +{\ + top = s->heap[SMALLEST]; \ + s->heap[SMALLEST] = s->heap[s->heap_len--]; \ + pqdownheap(s, tree, SMALLEST); \ +} + +/* =========================================================================== + * Compares to subtrees, using the tree depth as tie breaker when + * the subtrees have equal frequency. This minimizes the worst case length. + */ +#define smaller(tree, n, m, depth) \ + (tree[n].Freq < tree[m].Freq || \ + (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m])) + +/* =========================================================================== + * Restore the heap property by moving down the tree starting at node k, + * exchanging a node with the smallest of its two sons if necessary, stopping + * when the heap property is re-established (each father smaller than its + * two sons). + */ +local void pqdownheap(s, tree, k) + deflate_state *s; + ct_data *tree; /* the tree to restore */ + int k; /* node to move down */ +{ + int v = s->heap[k]; + int j = k << 1; /* left son of k */ + while (j <= s->heap_len) { + /* Set j to the smallest of the two sons: */ + if (j < s->heap_len && + smaller(tree, s->heap[j+1], s->heap[j], s->depth)) { + j++; + } + /* Exit if v is smaller than both sons */ + if (smaller(tree, v, s->heap[j], s->depth)) break; + + /* Exchange v with the smallest son */ + s->heap[k] = s->heap[j]; k = j; + + /* And continue down the tree, setting j to the left son of k */ + j <<= 1; + } + s->heap[k] = v; +} + +/* =========================================================================== + * Compute the optimal bit lengths for a tree and update the total bit length + * for the current block. + * IN assertion: the fields freq and dad are set, heap[heap_max] and + * above are the tree nodes sorted by increasing frequency. + * OUT assertions: the field len is set to the optimal bit length, the + * array bl_count contains the frequencies for each bit length. + * The length opt_len is updated; static_len is also updated if stree is + * not null. + */ +local void gen_bitlen(s, desc) + deflate_state *s; + tree_desc *desc; /* the tree descriptor */ +{ + ct_data *tree = desc->dyn_tree; + int max_code = desc->max_code; + ct_data *stree = desc->stat_desc->static_tree; + intf *extra = desc->stat_desc->extra_bits; + int base = desc->stat_desc->extra_base; + int max_length = desc->stat_desc->max_length; + int h; /* heap index */ + int n, m; /* iterate over the tree elements */ + int bits; /* bit length */ + int xbits; /* extra bits */ + ush f; /* frequency */ + int overflow = 0; /* number of elements with bit length too large */ + + for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0; + + /* In a first pass, compute the optimal bit lengths (which may + * overflow in the case of the bit length tree). + */ + tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */ + + for (h = s->heap_max+1; h < HEAP_SIZE; h++) { + n = s->heap[h]; + bits = tree[tree[n].Dad].Len + 1; + if (bits > max_length) bits = max_length, overflow++; + tree[n].Len = (ush)bits; + /* We overwrite tree[n].Dad which is no longer needed */ + + if (n > max_code) continue; /* not a leaf node */ + + s->bl_count[bits]++; + xbits = 0; + if (n >= base) xbits = extra[n-base]; + f = tree[n].Freq; + s->opt_len += (ulg)f * (bits + xbits); + if (stree) s->static_len += (ulg)f * (stree[n].Len + xbits); + } + if (overflow == 0) return; + + Trace((stderr,"\nbit length overflow\n")); + /* This happens for example on obj2 and pic of the Calgary corpus */ + + /* Find the first bit length which could increase: */ + do { + bits = max_length-1; + while (s->bl_count[bits] == 0) bits--; + s->bl_count[bits]--; /* move one leaf down the tree */ + s->bl_count[bits+1] += 2; /* move one overflow item as its brother */ + s->bl_count[max_length]--; + /* The brother of the overflow item also moves one step up, + * but this does not affect bl_count[max_length] + */ + overflow -= 2; + } while (overflow > 0); + + /* Now recompute all bit lengths, scanning in increasing frequency. + * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all + * lengths instead of fixing only the wrong ones. This idea is taken + * from 'ar' written by Haruhiko Okumura.) + */ + for (bits = max_length; bits != 0; bits--) { + n = s->bl_count[bits]; + while (n != 0) { + m = s->heap[--h]; + if (m > max_code) continue; + if (tree[m].Len != (unsigned) bits) { + Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits)); + s->opt_len += ((long)bits - (long)tree[m].Len) + *(long)tree[m].Freq; + tree[m].Len = (ush)bits; + } + n--; + } + } +} + +/* =========================================================================== + * Generate the codes for a given tree and bit counts (which need not be + * optimal). + * IN assertion: the array bl_count contains the bit length statistics for + * the given tree and the field len is set for all tree elements. + * OUT assertion: the field code is set for all tree elements of non + * zero code length. + */ +local void gen_codes (tree, max_code, bl_count) + ct_data *tree; /* the tree to decorate */ + int max_code; /* largest code with non zero frequency */ + ushf *bl_count; /* number of codes at each bit length */ +{ + ush next_code[MAX_BITS+1]; /* next code value for each bit length */ + ush code = 0; /* running code value */ + int bits; /* bit index */ + int n; /* code index */ + + /* The distribution counts are first used to generate the code values + * without bit reversal. + */ + for (bits = 1; bits <= MAX_BITS; bits++) { + next_code[bits] = code = (code + bl_count[bits-1]) << 1; + } + /* Check that the bit counts in bl_count are consistent. The last code + * must be all ones. + */ + Assert (code + bl_count[MAX_BITS]-1 == (1<dyn_tree; + ct_data *stree = desc->stat_desc->static_tree; + int elems = desc->stat_desc->elems; + int n, m; /* iterate over heap elements */ + int max_code = -1; /* largest code with non zero frequency */ + int node; /* new node being created */ + + /* Construct the initial heap, with least frequent element in + * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1]. + * heap[0] is not used. + */ + s->heap_len = 0, s->heap_max = HEAP_SIZE; + + for (n = 0; n < elems; n++) { + if (tree[n].Freq != 0) { + s->heap[++(s->heap_len)] = max_code = n; + s->depth[n] = 0; + } else { + tree[n].Len = 0; + } + } + + /* The pkzip format requires that at least one distance code exists, + * and that at least one bit should be sent even if there is only one + * possible code. So to avoid special checks later on we force at least + * two codes of non zero frequency. + */ + while (s->heap_len < 2) { + node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0); + tree[node].Freq = 1; + s->depth[node] = 0; + s->opt_len--; if (stree) s->static_len -= stree[node].Len; + /* node is 0 or 1 so it does not have extra bits */ + } + desc->max_code = max_code; + + /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree, + * establish sub-heaps of increasing lengths: + */ + for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n); + + /* Construct the Huffman tree by repeatedly combining the least two + * frequent nodes. + */ + node = elems; /* next internal node of the tree */ + do { + pqremove(s, tree, n); /* n = node of least frequency */ + m = s->heap[SMALLEST]; /* m = node of next least frequency */ + + s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */ + s->heap[--(s->heap_max)] = m; + + /* Create a new node father of n and m */ + tree[node].Freq = tree[n].Freq + tree[m].Freq; + s->depth[node] = (uch) (MAX(s->depth[n], s->depth[m]) + 1); + tree[n].Dad = tree[m].Dad = (ush)node; +#ifdef DUMP_BL_TREE + if (tree == s->bl_tree) { + fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)", + node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq); + } +#endif + /* and insert the new node in the heap */ + s->heap[SMALLEST] = node++; + pqdownheap(s, tree, SMALLEST); + + } while (s->heap_len >= 2); + + s->heap[--(s->heap_max)] = s->heap[SMALLEST]; + + /* At this point, the fields freq and dad are set. We can now + * generate the bit lengths. + */ + gen_bitlen(s, (tree_desc *)desc); + + /* The field len is now set, we can generate the bit codes */ + gen_codes ((ct_data *)tree, max_code, s->bl_count); +} + +/* =========================================================================== + * Scan a literal or distance tree to determine the frequencies of the codes + * in the bit length tree. + */ +local void scan_tree (s, tree, max_code) + deflate_state *s; + ct_data *tree; /* the tree to be scanned */ + int max_code; /* and its largest code of non zero frequency */ +{ + int n; /* iterates over all tree elements */ + int prevlen = -1; /* last emitted length */ + int curlen; /* length of current code */ + int nextlen = tree[0].Len; /* length of next code */ + int count = 0; /* repeat count of the current code */ + int max_count = 7; /* max repeat count */ + int min_count = 4; /* min repeat count */ + + if (nextlen == 0) max_count = 138, min_count = 3; + tree[max_code+1].Len = (ush)0xffff; /* guard */ + + for (n = 0; n <= max_code; n++) { + curlen = nextlen; nextlen = tree[n+1].Len; + if (++count < max_count && curlen == nextlen) { + continue; + } else if (count < min_count) { + s->bl_tree[curlen].Freq += count; + } else if (curlen != 0) { + if (curlen != prevlen) s->bl_tree[curlen].Freq++; + s->bl_tree[REP_3_6].Freq++; + } else if (count <= 10) { + s->bl_tree[REPZ_3_10].Freq++; + } else { + s->bl_tree[REPZ_11_138].Freq++; + } + count = 0; prevlen = curlen; + if (nextlen == 0) { + max_count = 138, min_count = 3; + } else if (curlen == nextlen) { + max_count = 6, min_count = 3; + } else { + max_count = 7, min_count = 4; + } + } +} + +/* =========================================================================== + * Send a literal or distance tree in compressed form, using the codes in + * bl_tree. + */ +local void send_tree (s, tree, max_code) + deflate_state *s; + ct_data *tree; /* the tree to be scanned */ + int max_code; /* and its largest code of non zero frequency */ +{ + int n; /* iterates over all tree elements */ + int prevlen = -1; /* last emitted length */ + int curlen; /* length of current code */ + int nextlen = tree[0].Len; /* length of next code */ + int count = 0; /* repeat count of the current code */ + int max_count = 7; /* max repeat count */ + int min_count = 4; /* min repeat count */ + + /* tree[max_code+1].Len = -1; */ /* guard already set */ + if (nextlen == 0) max_count = 138, min_count = 3; + + for (n = 0; n <= max_code; n++) { + curlen = nextlen; nextlen = tree[n+1].Len; + if (++count < max_count && curlen == nextlen) { + continue; + } else if (count < min_count) { + do { send_code(s, curlen, s->bl_tree); } while (--count != 0); + + } else if (curlen != 0) { + if (curlen != prevlen) { + send_code(s, curlen, s->bl_tree); count--; + } + Assert(count >= 3 && count <= 6, " 3_6?"); + send_code(s, REP_3_6, s->bl_tree); send_bits(s, count-3, 2); + + } else if (count <= 10) { + send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count-3, 3); + + } else { + send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count-11, 7); + } + count = 0; prevlen = curlen; + if (nextlen == 0) { + max_count = 138, min_count = 3; + } else if (curlen == nextlen) { + max_count = 6, min_count = 3; + } else { + max_count = 7, min_count = 4; + } + } +} + +/* =========================================================================== + * Construct the Huffman tree for the bit lengths and return the index in + * bl_order of the last bit length code to send. + */ +local int build_bl_tree(s) + deflate_state *s; +{ + int max_blindex; /* index of last bit length code of non zero freq */ + + /* Determine the bit length frequencies for literal and distance trees */ + scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code); + scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code); + + /* Build the bit length tree: */ + build_tree(s, (tree_desc *)(&(s->bl_desc))); + /* opt_len now includes the length of the tree representations, except + * the lengths of the bit lengths codes and the 5+5+4 bits for the counts. + */ + + /* Determine the number of bit length codes to send. The pkzip format + * requires that at least 4 bit length codes be sent. (appnote.txt says + * 3 but the actual value used is 4.) + */ + for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) { + if (s->bl_tree[bl_order[max_blindex]].Len != 0) break; + } + /* Update opt_len to include the bit length tree and counts */ + s->opt_len += 3*(max_blindex+1) + 5+5+4; + Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld", + s->opt_len, s->static_len)); + + return max_blindex; +} + +/* =========================================================================== + * Send the header for a block using dynamic Huffman trees: the counts, the + * lengths of the bit length codes, the literal tree and the distance tree. + * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. + */ +local void send_all_trees(s, lcodes, dcodes, blcodes) + deflate_state *s; + int lcodes, dcodes, blcodes; /* number of codes for each tree */ +{ + int rank; /* index in bl_order */ + + Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes"); + Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES, + "too many codes"); + Tracev((stderr, "\nbl counts: ")); + send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */ + send_bits(s, dcodes-1, 5); + send_bits(s, blcodes-4, 4); /* not -3 as stated in appnote.txt */ + for (rank = 0; rank < blcodes; rank++) { + Tracev((stderr, "\nbl code %2d ", bl_order[rank])); + send_bits(s, s->bl_tree[bl_order[rank]].Len, 3); + } + Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent)); + + send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */ + Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent)); + + send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */ + Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent)); +} + +/* =========================================================================== + * Send a stored block + */ +void _tr_stored_block(s, buf, stored_len, eof) + deflate_state *s; + charf *buf; /* input block */ + ulg stored_len; /* length of input block */ + int eof; /* true if this is the last block for a file */ +{ + send_bits(s, (STORED_BLOCK<<1)+eof, 3); /* send block type */ + s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L; + s->compressed_len += (stored_len + 4) << 3; + + copy_block(s, buf, (unsigned)stored_len, 1); /* with header */ +} + +/* =========================================================================== + * Send one empty static block to give enough lookahead for inflate. + * This takes 10 bits, of which 7 may remain in the bit buffer. + * The current inflate code requires 9 bits of lookahead. If the + * last two codes for the previous block (real code plus EOB) were coded + * on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode + * the last real code. In this case we send two empty static blocks instead + * of one. (There are no problems if the previous block is stored or fixed.) + * To simplify the code, we assume the worst case of last real code encoded + * on one bit only. + */ +void _tr_align(s) + deflate_state *s; +{ + send_bits(s, STATIC_TREES<<1, 3); + send_code(s, END_BLOCK, static_ltree); + s->compressed_len += 10L; /* 3 for block type, 7 for EOB */ + bi_flush(s); + /* Of the 10 bits for the empty block, we have already sent + * (10 - bi_valid) bits. The lookahead for the last real code (before + * the EOB of the previous block) was thus at least one plus the length + * of the EOB plus what we have just sent of the empty static block. + */ + if (1 + s->last_eob_len + 10 - s->bi_valid < 9) { + send_bits(s, STATIC_TREES<<1, 3); + send_code(s, END_BLOCK, static_ltree); + s->compressed_len += 10L; + bi_flush(s); + } + s->last_eob_len = 7; +} + +/* =========================================================================== + * Determine the best encoding for the current block: dynamic trees, static + * trees or store, and output the encoded block to the zip file. This function + * returns the total compressed length for the file so far. + */ +ulg _tr_flush_block(s, buf, stored_len, eof) + deflate_state *s; + charf *buf; /* input block, or NULL if too old */ + ulg stored_len; /* length of input block */ + int eof; /* true if this is the last block for a file */ +{ + ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */ + int max_blindex = 0; /* index of last bit length code of non zero freq */ + + /* Build the Huffman trees unless a stored block is forced */ + if (s->level > 0) { + + /* Check if the file is ascii or binary */ + if (s->data_type == Z_UNKNOWN) set_data_type(s); + + /* Construct the literal and distance trees */ + build_tree(s, (tree_desc *)(&(s->l_desc))); + Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len, + s->static_len)); + + build_tree(s, (tree_desc *)(&(s->d_desc))); + Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len, + s->static_len)); + /* At this point, opt_len and static_len are the total bit lengths of + * the compressed block data, excluding the tree representations. + */ + + /* Build the bit length tree for the above two trees, and get the index + * in bl_order of the last bit length code to send. + */ + max_blindex = build_bl_tree(s); + + /* Determine the best encoding. Compute first the block length in bytes*/ + opt_lenb = (s->opt_len+3+7)>>3; + static_lenb = (s->static_len+3+7)>>3; + + Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ", + opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len, + s->last_lit)); + + if (static_lenb <= opt_lenb) opt_lenb = static_lenb; + + } else { + Assert(buf != (char*)0, "lost buf"); + opt_lenb = static_lenb = stored_len + 5; /* force a stored block */ + } + + /* If compression failed and this is the first and last block, + * and if the .zip file can be seeked (to rewrite the local header), + * the whole file is transformed into a stored file: + */ +#ifdef STORED_FILE_OK +# ifdef FORCE_STORED_FILE + if (eof && s->compressed_len == 0L) { /* force stored file */ +# else + if (stored_len <= opt_lenb && eof && s->compressed_len==0L && seekable()) { +# endif + /* Since LIT_BUFSIZE <= 2*WSIZE, the input data must be there: */ + if (buf == (charf*)0) error ("block vanished"); + + copy_block(buf, (unsigned)stored_len, 0); /* without header */ + s->compressed_len = stored_len << 3; + s->method = STORED; + } else +#endif /* STORED_FILE_OK */ + +#ifdef FORCE_STORED + if (buf != (char*)0) { /* force stored block */ +#else + if (stored_len+4 <= opt_lenb && buf != (char*)0) { + /* 4: two words for the lengths */ +#endif + /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. + * Otherwise we can't have processed more than WSIZE input bytes since + * the last block flush, because compression would have been + * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to + * transform a block into a stored block. + */ + _tr_stored_block(s, buf, stored_len, eof); + +#ifdef FORCE_STATIC + } else if (static_lenb >= 0) { /* force static trees */ +#else + } else if (static_lenb == opt_lenb) { +#endif + send_bits(s, (STATIC_TREES<<1)+eof, 3); + compress_block(s, (ct_data *)static_ltree, (ct_data *)static_dtree); + s->compressed_len += 3 + s->static_len; + } else { + send_bits(s, (DYN_TREES<<1)+eof, 3); + send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1, + max_blindex+1); + compress_block(s, (ct_data *)s->dyn_ltree, (ct_data *)s->dyn_dtree); + s->compressed_len += 3 + s->opt_len; + } + Assert (s->compressed_len == s->bits_sent, "bad compressed size"); + init_block(s); + + if (eof) { + bi_windup(s); + s->compressed_len += 7; /* align on byte boundary */ + } + Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3, + s->compressed_len-7*eof)); + + return s->compressed_len >> 3; +} + +/* =========================================================================== + * Save the match info and tally the frequency counts. Return true if + * the current block must be flushed. + */ +int _tr_tally (s, dist, lc) + deflate_state *s; + unsigned dist; /* distance of matched string */ + unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */ +{ + s->d_buf[s->last_lit] = (ush)dist; + s->l_buf[s->last_lit++] = (uch)lc; + if (dist == 0) { + /* lc is the unmatched char */ + s->dyn_ltree[lc].Freq++; + } else { + s->matches++; + /* Here, lc is the match length - MIN_MATCH */ + dist--; /* dist = match distance - 1 */ + Assert((ush)dist < (ush)MAX_DIST(s) && + (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) && + (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match"); + + s->dyn_ltree[length_code[lc]+LITERALS+1].Freq++; + s->dyn_dtree[d_code(dist)].Freq++; + } + + /* Try to guess if it is profitable to stop the current block here */ + if (s->level > 2 && (s->last_lit & 0xfff) == 0) { + /* Compute an upper bound for the compressed length */ + ulg out_length = (ulg)s->last_lit*8L; + ulg in_length = (ulg)((long)s->strstart - s->block_start); + int dcode; + for (dcode = 0; dcode < D_CODES; dcode++) { + out_length += (ulg)s->dyn_dtree[dcode].Freq * + (5L+extra_dbits[dcode]); + } + out_length >>= 3; + Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ", + s->last_lit, in_length, out_length, + 100L - out_length*100L/in_length)); + if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1; + } + return (s->last_lit == s->lit_bufsize-1); + /* We avoid equality with lit_bufsize because of wraparound at 64K + * on 16 bit machines and because stored blocks are restricted to + * 64K-1 bytes. + */ +} + +/* =========================================================================== + * Send the block data compressed using the given Huffman trees + */ +local void compress_block(s, ltree, dtree) + deflate_state *s; + ct_data *ltree; /* literal tree */ + ct_data *dtree; /* distance tree */ +{ + unsigned dist; /* distance of matched string */ + int lc; /* match length or unmatched char (if dist == 0) */ + unsigned lx = 0; /* running index in l_buf */ + unsigned code; /* the code to send */ + int extra; /* number of extra bits to send */ + + if (s->last_lit != 0) do { + dist = s->d_buf[lx]; + lc = s->l_buf[lx++]; + if (dist == 0) { + send_code(s, lc, ltree); /* send a literal byte */ + Tracecv(isgraph(lc), (stderr," '%c' ", lc)); + } else { + /* Here, lc is the match length - MIN_MATCH */ + code = length_code[lc]; + send_code(s, code+LITERALS+1, ltree); /* send the length code */ + extra = extra_lbits[code]; + if (extra != 0) { + lc -= base_length[code]; + send_bits(s, lc, extra); /* send the extra length bits */ + } + dist--; /* dist is now the match distance - 1 */ + code = d_code(dist); + Assert (code < D_CODES, "bad d_code"); + + send_code(s, code, dtree); /* send the distance code */ + extra = extra_dbits[code]; + if (extra != 0) { + dist -= base_dist[code]; + send_bits(s, dist, extra); /* send the extra distance bits */ + } + } /* literal or match pair ? */ + + /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */ + Assert((uInt)s->pending < s->lit_bufsize + 2*lx, "pendingBuf overflow"); + + } while (lx < s->last_lit); + + send_code(s, END_BLOCK, ltree); + s->last_eob_len = ltree[END_BLOCK].Len; +} + +/* =========================================================================== + * Set the data type to ASCII or BINARY, using a crude approximation: + * binary if more than 20% of the bytes are <= 6 or >= 128, ascii otherwise. + * IN assertion: the fields freq of dyn_ltree are set and the total of all + * frequencies does not exceed 64K (to fit in an int on 16 bit machines). + */ +local void set_data_type(s) + deflate_state *s; +{ + int n = 0; + unsigned ascii_freq = 0; + unsigned bin_freq = 0; + while (n < 7) bin_freq += s->dyn_ltree[n++].Freq; + while (n < 128) ascii_freq += s->dyn_ltree[n++].Freq; + while (n < LITERALS) bin_freq += s->dyn_ltree[n++].Freq; + s->data_type = (Byte)(bin_freq > (ascii_freq >> 2) ? Z_BINARY : Z_ASCII); +} + +/* =========================================================================== + * Reverse the first len bits of a code, using straightforward code (a faster + * method would use a table) + * IN assertion: 1 <= len <= 15 + */ +local unsigned bi_reverse(code, len) + unsigned code; /* the value to invert */ + int len; /* its bit length */ +{ + register unsigned res = 0; + do { + res |= code & 1; + code >>= 1, res <<= 1; + } while (--len > 0); + return res >> 1; +} + +/* =========================================================================== + * Flush the bit buffer, keeping at most 7 bits in it. + */ +local void bi_flush(s) + deflate_state *s; +{ + if (s->bi_valid == 16) { + put_short(s, s->bi_buf); + s->bi_buf = 0; + s->bi_valid = 0; + } else if (s->bi_valid >= 8) { + put_byte(s, (Byte)s->bi_buf); + s->bi_buf >>= 8; + s->bi_valid -= 8; + } +} + +/* =========================================================================== + * Flush the bit buffer and align the output on a byte boundary + */ +local void bi_windup(s) + deflate_state *s; +{ + if (s->bi_valid > 8) { + put_short(s, s->bi_buf); + } else if (s->bi_valid > 0) { + put_byte(s, (Byte)s->bi_buf); + } + s->bi_buf = 0; + s->bi_valid = 0; +#ifdef DEBUG_ZIP + s->bits_sent = (s->bits_sent+7) & ~7; +#endif +} + +/* =========================================================================== + * Copy a stored block, storing first the length and its + * one's complement if requested. + */ +local void copy_block(s, buf, len, header) + deflate_state *s; + charf *buf; /* the input data */ + unsigned len; /* its length */ + int header; /* true if block header must be written */ +{ + bi_windup(s); /* align on byte boundary */ + s->last_eob_len = 8; /* enough lookahead for inflate */ + + if (header) { + put_short(s, (ush)len); + put_short(s, (ush)~len); +#ifdef DEBUG_ZIP + s->bits_sent += 2*16; +#endif + } +#ifdef DEBUG_ZIP + s->bits_sent += (ulg)len<<3; +#endif + while (len--) { + put_byte(s, *buf++); + } +} diff --git a/ef/Utilities/zlib/uncompr.c b/ef/Utilities/zlib/uncompr.c new file mode 100644 index 000000000000..72f4045bbf04 --- /dev/null +++ b/ef/Utilities/zlib/uncompr.c @@ -0,0 +1,56 @@ +/* uncompr.c -- decompress a memory buffer + * Copyright (C) 1995-1996 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zlib.h" + +/* =========================================================================== + Decompresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total + size of the destination buffer, which must be large enough to hold the + entire uncompressed data. (The size of the uncompressed data must have + been saved previously by the compressor and transmitted to the decompressor + by some mechanism outside the scope of this compression library.) + Upon exit, destLen is the actual size of the compressed buffer. + This function can be used to decompress a whole file at once if the + input file is mmap'ed. + + uncompress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer, or Z_DATA_ERROR if the input data was corrupted. +*/ +int uncompress (dest, destLen, source, sourceLen) + Bytef *dest; + uLongf *destLen; + const Bytef *source; + uLong sourceLen; +{ + z_stream stream; + int err; + + stream.next_in = (Bytef*)source; + stream.avail_in = (uInt)sourceLen; + /* Check for source > 64K on 16-bit machine: */ + if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR; + + stream.next_out = dest; + stream.avail_out = (uInt)*destLen; + if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR; + + stream.zalloc = (alloc_func)0; + stream.zfree = (free_func)0; + + err = inflateInit(&stream); + if (err != Z_OK) return err; + + err = inflate(&stream, Z_FINISH); + if (err != Z_STREAM_END) { + inflateEnd(&stream); + return err; + } + *destLen = stream.total_out; + + err = inflateEnd(&stream); + return err; +} diff --git a/ef/Utilities/zlib/zconf.h b/ef/Utilities/zlib/zconf.h new file mode 100644 index 000000000000..fff75621ad6f --- /dev/null +++ b/ef/Utilities/zlib/zconf.h @@ -0,0 +1,192 @@ +/* zconf.h -- configuration of the zlib compression library + * Copyright (C) 1995-1996 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#ifndef _ZCONF_H +#define _ZCONF_H + +#ifdef XP_PC +# include +#endif + +/* + * If you *really* need a unique prefix for all types and library functions, + * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it. + */ +#ifdef Z_PREFIX +# define deflateInit_ z_deflateInit_ +# define deflate z_deflate +# define deflateEnd z_deflateEnd +# define inflateInit_ z_inflateInit_ +# define inflate z_inflate +# define inflateEnd z_inflateEnd +# define deflateInit2_ z_deflateInit2_ +# define deflateSetDictionary z_deflateSetDictionary +# define deflateCopy z_deflateCopy +# define deflateReset z_deflateReset +# define deflateParams z_deflateParams +# define inflateInit2_ z_inflateInit2_ +# define inflateSetDictionary z_inflateSetDictionary +# define inflateSync z_inflateSync +# define inflateReset z_inflateReset +# define compress z_compress +# define uncompress z_uncompress +# define adler32 z_adler32 +# define crc32 z_crc32 +# define get_crc_table z_get_crc_table + +# define Byte z_Byte +# define uInt z_uInt +# define uLong z_uLong +# define Bytef z_Bytef +# define charf z_charf +# define intf z_intf +# define uIntf z_uIntf +# define uLongf z_uLongf +# define voidpf z_voidpf +# define voidp z_voidp +#endif + +#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32) +# define WIN32 +#endif +#if defined(__GNUC__) || defined(WIN32) || defined(__386__) || defined(i386) +# ifndef __32BIT__ +# define __32BIT__ +# endif +#endif +#if defined(__MSDOS__) && !defined(MSDOS) +# define MSDOS +#endif + +/* + * Compile with -DMAXSEG_64K if the alloc function cannot allocate more + * than 64k bytes at a time (needed on systems with 16-bit int). + */ +#if defined(MSDOS) && !defined(__32BIT__) +# define MAXSEG_64K +#endif +#ifdef MSDOS +# define UNALIGNED_OK +#endif + +#if (defined(MSDOS) || defined(_WINDOWS) || defined(WIN32)) && !defined(STDC) +# define STDC +#endif +#if (defined(__STDC__) || defined(__cplusplus)) && !defined(STDC) +# define STDC +#endif + +#ifndef STDC +# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */ +# define const +# endif +#endif + +/* Some Mac compilers merge all .h files incorrectly: */ +#if defined(__MWERKS__) || defined(applec) ||defined(THINK_C) ||defined(__SC__) +# define NO_DUMMY_DECL +#endif + +/* Maximum value for memLevel in deflateInit2 */ +#ifndef MAX_MEM_LEVEL +# ifdef MAXSEG_64K +# define MAX_MEM_LEVEL 8 +# else +# define MAX_MEM_LEVEL 9 +# endif +#endif + +/* Maximum value for windowBits in deflateInit2 and inflateInit2 */ +#ifndef MAX_WBITS +# define MAX_WBITS 15 /* 32K LZ77 window */ +#endif + +/* The memory requirements for deflate are (in bytes): + 1 << (windowBits+2) + 1 << (memLevel+9) + that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) + plus a few kilobytes for small objects. For example, if you want to reduce + the default memory requirements from 256K to 128K, compile with + make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" + Of course this will generally degrade compression (there's no free lunch). + + The memory requirements for inflate are (in bytes) 1 << windowBits + that is, 32K for windowBits=15 (default value) plus a few kilobytes + for small objects. +*/ + + /* Type declarations */ + +#ifndef OF /* function prototypes */ +# ifdef STDC +# define OF(args) args +# else +# define OF(args) () +# endif +#endif + +/* The following definitions for FAR are needed only for MSDOS mixed + * model programming (small or medium model with some far allocations). + * This was tested only with MSC; for other MSDOS compilers you may have + * to define NO_MEMCPY in zutil.h. If you don't need the mixed model, + * just define FAR to be empty. + */ +#ifndef FAR + +#if (defined(M_I86SM) || defined(M_I86MM)) && !defined(__32BIT__) + /* MSC small or medium model */ +# define SMALL_MEDIUM +# ifdef _MSC_VER +# define FAR __far +# else +# define FAR far +# endif +#endif + +#if defined(__BORLANDC__) && (defined(__SMALL__) || defined(__MEDIUM__)) +# ifndef __32BIT__ +# define SMALL_MEDIUM +# define FAR __far +# endif +#endif + +#ifndef FAR +# define FAR +#endif + +#endif /* FAR */ + +typedef unsigned char Byte; /* 8 bits */ +typedef unsigned int uInt; /* 16 bits or more */ +typedef unsigned long uLong; /* 32 bits or more */ + +#if defined(__BORLANDC__) && defined(SMALL_MEDIUM) + /* Borland C/C++ ignores FAR inside typedef */ +# define Bytef Byte FAR +#else + typedef Byte FAR Bytef; +#endif +typedef char FAR charf; +typedef int FAR intf; +typedef uInt FAR uIntf; +typedef uLong FAR uLongf; + +#ifdef STDC + typedef void FAR *voidpf; + typedef void *voidp; +#else + typedef Byte FAR *voidpf; + typedef Byte *voidp; +#endif + + +/* Compile with -DZLIB_DLL for Windows DLL support */ +#if (defined(_WINDOWS) || defined(WINDOWS)) && defined(ZLIB_DLL) +# include +# define EXPORT WINAPI +#else +# define EXPORT +#endif + +#endif /* _ZCONF_H */ diff --git a/ef/Utilities/zlib/zlib.h b/ef/Utilities/zlib/zlib.h new file mode 100644 index 000000000000..337fe9fe8a39 --- /dev/null +++ b/ef/Utilities/zlib/zlib.h @@ -0,0 +1,780 @@ +/* zlib.h -- interface of the 'zlib' general purpose compression library + version 1.0.4, Jul 24th, 1996. + + Copyright (C) 1995-1996 Jean-loup Gailly and Mark Adler + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Jean-loup Gailly Mark Adler + gzip@prep.ai.mit.edu madler@alumni.caltech.edu + + + The data format used by the zlib library is described by RFCs (Request for + Comments) 1950 to 1952 in the files ftp://ds.internic.net/rfc/rfc1950.txt + (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format). +*/ + +#ifndef _ZLIB_H +#define _ZLIB_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "zconf.h" + +#define ZLIB_VERSION "1.0.4" + +/* + The 'zlib' compression library provides in-memory compression and + decompression functions, including integrity checks of the uncompressed + data. This version of the library supports only one compression method + (deflation) but other algorithms may be added later and will have the same + stream interface. + + For compression the application must provide the output buffer and + may optionally provide the input buffer for optimization. For decompression, + the application must provide the input buffer and may optionally provide + the output buffer for optimization. + + Compression can be done in a single step if the buffers are large + enough (for example if an input file is mmap'ed), or can be done by + repeated calls of the compression function. In the latter case, the + application must provide more input and/or consume the output + (providing more output space) before each call. + + The library does not install any signal handler. It is recommended to + add at least a handler for SIGSEGV when decompressing; the library checks + the consistency of the input data whenever possible but may go nuts + for some forms of corrupted input. +*/ + +typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size)); +typedef void (*free_func) OF((voidpf opaque, voidpf address)); + +struct internal_state; + +typedef struct z_stream_s { + Bytef *next_in; /* next input byte */ + uInt avail_in; /* number of bytes available at next_in */ + uLong total_in; /* total nb of input bytes read so far */ + + Bytef *next_out; /* next output byte should be put there */ + uInt avail_out; /* remaining free space at next_out */ + uLong total_out; /* total nb of bytes output so far */ + + char *msg; /* last error message, NULL if no error */ + struct internal_state FAR *state; /* not visible by applications */ + + alloc_func zalloc; /* used to allocate the internal state */ + free_func zfree; /* used to free the internal state */ + voidpf opaque; /* private data object passed to zalloc and zfree */ + + int data_type; /* best guess about the data type: ascii or binary */ + uLong adler; /* adler32 value of the uncompressed data */ + uLong reserved; /* reserved for future use */ +} z_stream; + +typedef z_stream FAR *z_streamp; + +/* + The application must update next_in and avail_in when avail_in has + dropped to zero. It must update next_out and avail_out when avail_out + has dropped to zero. The application must initialize zalloc, zfree and + opaque before calling the init function. All other fields are set by the + compression library and must not be updated by the application. + + The opaque value provided by the application will be passed as the first + parameter for calls of zalloc and zfree. This can be useful for custom + memory management. The compression library attaches no meaning to the + opaque value. + + zalloc must return Z_NULL if there is not enough memory for the object. + On 16-bit systems, the functions zalloc and zfree must be able to allocate + exactly 65536 bytes, but will not be required to allocate more than this + if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, + pointers returned by zalloc for objects of exactly 65536 bytes *must* + have their offset normalized to zero. The default allocation function + provided by this library ensures this (see zutil.c). To reduce memory + requirements and avoid any allocation of 64K objects, at the expense of + compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h). + + The fields total_in and total_out can be used for statistics or + progress reports. After compression, total_in holds the total size of + the uncompressed data and may be saved for use in the decompressor + (particularly if the decompressor wants to decompress everything in + a single step). +*/ + + /* constants */ + +#define Z_NO_FLUSH 0 +#define Z_PARTIAL_FLUSH 1 +#define Z_SYNC_FLUSH 2 +#define Z_FULL_FLUSH 3 +#define Z_FINISH 4 +/* Allowed flush values; see deflate() below for details */ + +#define Z_OK 0 +#define Z_STREAM_END 1 +#define Z_NEED_DICT 2 +#define Z_ERRNO (-1) +#define Z_STREAM_ERROR (-2) +#define Z_DATA_ERROR (-3) +#define Z_MEM_ERROR (-4) +#define Z_BUF_ERROR (-5) +#define Z_VERSION_ERROR (-6) +/* Return codes for the compression/decompression functions. Negative + * values are errors, positive values are used for special but normal events. + */ + +#define Z_NO_COMPRESSION 0 +#define Z_BEST_SPEED 1 +#define Z_BEST_COMPRESSION 9 +#define Z_DEFAULT_COMPRESSION (-1) +/* compression levels */ + +#define Z_FILTERED 1 +#define Z_HUFFMAN_ONLY 2 +#define Z_DEFAULT_STRATEGY 0 +/* compression strategy; see deflateInit2() below for details */ + +#define Z_BINARY 0 +#define Z_ASCII 1 +#define Z_UNKNOWN 2 +/* Possible values of the data_type field */ + +#define Z_DEFLATED 8 +/* The deflate compression method (the only one supported in this version) */ + +#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */ + +#define zlib_version zlibVersion() +/* for compatibility with versions < 1.0.2 */ + + /* basic functions */ + +extern const char * EXPORT zlibVersion OF((void)); +/* The application can compare zlibVersion and ZLIB_VERSION for consistency. + If the first character differs, the library code actually used is + not compatible with the zlib.h header file used by the application. + This check is automatically made by deflateInit and inflateInit. + */ + +/* +extern int EXPORT deflateInit OF((z_streamp strm, int level)); + + Initializes the internal stream state for compression. The fields + zalloc, zfree and opaque must be initialized before by the caller. + If zalloc and zfree are set to Z_NULL, deflateInit updates them to + use default allocation functions. + + The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9: + 1 gives best speed, 9 gives best compression, 0 gives no compression at + all (the input data is simply copied a block at a time). + Z_DEFAULT_COMPRESSION requests a default compromise between speed and + compression (currently equivalent to level 6). + + deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if level is not a valid compression level, + Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible + with the version assumed by the caller (ZLIB_VERSION). + msg is set to null if there is no error message. deflateInit does not + perform any compression: this will be done by deflate(). +*/ + + +extern int EXPORT deflate OF((z_streamp strm, int flush)); +/* + Performs one or both of the following actions: + + - Compress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), next_in and avail_in are updated and + processing will resume at this point for the next call of deflate(). + + - Provide more output starting at next_out and update next_out and avail_out + accordingly. This action is forced if the parameter flush is non zero. + Forcing flush frequently degrades the compression ratio, so this parameter + should be set only when necessary (in interactive applications). + Some output may be provided even if flush is not set. + + Before the call of deflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming + more output, and updating avail_in or avail_out accordingly; avail_out + should never be zero before the call. The application can consume the + compressed output when it wants, for example when the output buffer is full + (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK + and with zero avail_out, it must be called again after making room in the + output buffer because there might be more output pending. + + If the parameter flush is set to Z_PARTIAL_FLUSH, the current compression + block is terminated and flushed to the output buffer so that the + decompressor can get all input data available so far. For method 9, a future + variant on method 8, the current block will be flushed but not terminated. + Z_SYNC_FLUSH has the same effect as partial flush except that the compressed + output is byte aligned (the compressor can clear its internal bit buffer) + and the current block is always terminated; this can be useful if the + compressor has to be restarted from scratch after an interruption (in which + case the internal state of the compressor may be lost). + If flush is set to Z_FULL_FLUSH, the compression block is terminated, a + special marker is output and the compression dictionary is discarded; this + is useful to allow the decompressor to synchronize if one compressed block + has been damaged (see inflateSync below). Flushing degrades compression and + so should be used only when necessary. Using Z_FULL_FLUSH too often can + seriously degrade the compression. If deflate returns with avail_out == 0, + this function must be called again with the same value of the flush + parameter and more output space (updated avail_out), until the flush is + complete (deflate returns with non-zero avail_out). + + If the parameter flush is set to Z_FINISH, pending input is processed, + pending output is flushed and deflate returns with Z_STREAM_END if there + was enough output space; if deflate returns with Z_OK, this function must be + called again with Z_FINISH and more output space (updated avail_out) but no + more input data, until it returns with Z_STREAM_END or an error. After + deflate has returned Z_STREAM_END, the only possible operations on the + stream are deflateReset or deflateEnd. + + Z_FINISH can be used immediately after deflateInit if all the compression + is to be done in a single step. In this case, avail_out must be at least + 0.1% larger than avail_in plus 12 bytes. If deflate does not return + Z_STREAM_END, then it must be called again as described above. + + deflate() may update data_type if it can make a good guess about + the input data type (Z_ASCII or Z_BINARY). In doubt, the data is considered + binary. This field is only for information purposes and does not affect + the compression algorithm in any manner. + + deflate() returns Z_OK if some progress has been made (more input + processed or more output produced), Z_STREAM_END if all input has been + consumed and all output has been produced (only when flush is set to + Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example + if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible. +*/ + + +extern int EXPORT deflateEnd OF((z_streamp strm)); +/* + All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any + pending output. + + deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the + stream state was inconsistent, Z_DATA_ERROR if the stream was freed + prematurely (some input or output was discarded). In the error case, + msg may be set but then points to a static string (which must not be + deallocated). +*/ + + +/* +extern int EXPORT inflateInit OF((z_streamp strm)); + + Initializes the internal stream state for decompression. The fields + zalloc, zfree and opaque must be initialized before by the caller. If + zalloc and zfree are set to Z_NULL, inflateInit updates them to use default + allocation functions. + + inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_VERSION_ERROR if the zlib library version is incompatible + with the version assumed by the caller. msg is set to null if there is no + error message. inflateInit does not perform any decompression: this will be + done by inflate(). +*/ + + +extern int EXPORT inflate OF((z_streamp strm, int flush)); +/* + Performs one or both of the following actions: + + - Decompress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), next_in is updated and processing + will resume at this point for the next call of inflate(). + + - Provide more output starting at next_out and update next_out and avail_out + accordingly. inflate() provides as much output as possible, until there + is no more input data or no more space in the output buffer (see below + about the flush parameter). + + Before the call of inflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming + more output, and updating the next_* and avail_* values accordingly. + The application can consume the uncompressed output when it wants, for + example when the output buffer is full (avail_out == 0), or after each + call of inflate(). If inflate returns Z_OK and with zero avail_out, it + must be called again after making room in the output buffer because there + might be more output pending. + + If the parameter flush is set to Z_PARTIAL_FLUSH, inflate flushes as much + output as possible to the output buffer. The flushing behavior of inflate is + not specified for values of the flush parameter other than Z_PARTIAL_FLUSH + and Z_FINISH, but the current implementation actually flushes as much output + as possible anyway. + + inflate() should normally be called until it returns Z_STREAM_END or an + error. However if all decompression is to be performed in a single step + (a single call of inflate), the parameter flush should be set to + Z_FINISH. In this case all pending input is processed and all pending + output is flushed; avail_out must be large enough to hold all the + uncompressed data. (The size of the uncompressed data may have been saved + by the compressor for this purpose.) The next operation on this stream must + be inflateEnd to deallocate the decompression state. The use of Z_FINISH + is never required, but can be used to inform inflate that a faster routine + may be used for the single inflate() call. + + inflate() returns Z_OK if some progress has been made (more input + processed or more output produced), Z_STREAM_END if the end of the + compressed data has been reached and all uncompressed output has been + produced, Z_NEED_DICT if a preset dictionary is needed at this point (see + inflateSetDictionary below), Z_DATA_ERROR if the input data was corrupted, + Z_STREAM_ERROR if the stream structure was inconsistent (for example if + next_in or next_out was NULL), Z_MEM_ERROR if there was not enough memory, + Z_BUF_ERROR if no progress is possible or if there was not enough room in + the output buffer when Z_FINISH is used. In the Z_DATA_ERROR case, the + application may then call inflateSync to look for a good compression block. + In the Z_NEED_DICT case, strm->adler is set to the Adler32 value of the + dictionary chosen by the compressor. +*/ + + +extern int EXPORT inflateEnd OF((z_streamp strm)); +/* + All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any + pending output. + + inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state + was inconsistent. In the error case, msg may be set but then points to a + static string (which must not be deallocated). +*/ + + /* Advanced functions */ + +/* + The following functions are needed only in some special applications. +*/ + +/* +extern int EXPORT deflateInit2 OF((z_streamp strm, + int level, + int method, + int windowBits, + int memLevel, + int strategy)); + + This is another version of deflateInit with more compression options. The + fields next_in, zalloc, zfree and opaque must be initialized before by + the caller. + + The method parameter is the compression method. It must be Z_DEFLATED in + this version of the library. (Method 9 will allow a 64K history buffer and + partial block flushes.) + + The windowBits parameter is the base two logarithm of the window size + (the size of the history buffer). It should be in the range 8..15 for this + version of the library (the value 16 will be allowed for method 9). Larger + values of this parameter result in better compression at the expense of + memory usage. The default value is 15 if deflateInit is used instead. + + The memLevel parameter specifies how much memory should be allocated + for the internal compression state. memLevel=1 uses minimum memory but + is slow and reduces compression ratio; memLevel=9 uses maximum memory + for optimal speed. The default value is 8. See zconf.h for total memory + usage as a function of windowBits and memLevel. + + The strategy parameter is used to tune the compression algorithm. Use the + value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a + filter (or predictor), or Z_HUFFMAN_ONLY to force Huffman encoding only (no + string match). Filtered data consists mostly of small values with a + somewhat random distribution. In this case, the compression algorithm is + tuned to compress them better. The effect of Z_FILTERED is to force more + Huffman coding and less string matching; it is somewhat intermediate + between Z_DEFAULT and Z_HUFFMAN_ONLY. The strategy parameter only affects + the compression ratio but not the correctness of the compressed output even + if it is not set appropriately. + + If next_in is not null, the library will use this buffer to hold also + some history information; the buffer must either hold the entire input + data, or have at least 1<<(windowBits+1) bytes and be writable. If next_in + is null, the library will allocate its own history buffer (and leave next_in + null). next_out need not be provided here but must be provided by the + application for the next call of deflate(). + + If the history buffer is provided by the application, next_in must + must never be changed by the application since the compressor maintains + information inside this buffer from call to call; the application + must provide more input only by increasing avail_in. next_in is always + reset by the library in this case. + + deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was + not enough memory, Z_STREAM_ERROR if a parameter is invalid (such as + an invalid method). msg is set to null if there is no error message. + deflateInit2 does not perform any compression: this will be done by + deflate(). +*/ + +extern int EXPORT deflateSetDictionary OF((z_streamp strm, + const Bytef *dictionary, + uInt dictLength)); +/* + Initializes the compression dictionary (history buffer) from the given + byte sequence without producing any compressed output. This function must + be called immediately after deflateInit or deflateInit2, before any call + of deflate. The compressor and decompressor must use exactly the same + dictionary (see inflateSetDictionary). + The dictionary should consist of strings (byte sequences) that are likely + to be encountered later in the data to be compressed, with the most commonly + used strings preferably put towards the end of the dictionary. Using a + dictionary is most useful when the data to be compressed is short and + can be predicted with good accuracy; the data can then be compressed better + than with the default empty dictionary. In this version of the library, + only the last 32K bytes of the dictionary are used. + Upon return of this function, strm->adler is set to the Adler32 value + of the dictionary; the decompressor may later use this value to determine + which dictionary has been used by the compressor. (The Adler32 value + applies to the whole dictionary even if only a subset of the dictionary is + actually used by the compressor.) + + deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a + parameter is invalid (such as NULL dictionary) or the stream state + is inconsistent (for example if deflate has already been called for this + stream). deflateSetDictionary does not perform any compression: this will + be done by deflate(). +*/ + +extern int EXPORT deflateCopy OF((z_streamp dest, + z_streamp source)); +/* + Sets the destination stream as a complete copy of the source stream. If + the source stream is using an application-supplied history buffer, a new + buffer is allocated for the destination stream. The compressed output + buffer is always application-supplied. It's the responsibility of the + application to provide the correct values of next_out and avail_out for the + next call of deflate. + + This function can be useful when several compression strategies will be + tried, for example when there are several ways of pre-processing the input + data with a filter. The streams that will be discarded should then be freed + by calling deflateEnd. Note that deflateCopy duplicates the internal + compression state which can be quite large, so this strategy is slow and + can consume lots of memory. + + deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if the source stream state was inconsistent + (such as zalloc being NULL). msg is left unchanged in both source and + destination. +*/ + +extern int EXPORT deflateReset OF((z_streamp strm)); +/* + This function is equivalent to deflateEnd followed by deflateInit, + but does not free and reallocate all the internal compression state. + The stream will keep the same compression level and any other attributes + that may have been set by deflateInit2. + + deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being NULL). +*/ + +extern int EXPORT deflateParams OF((z_streamp strm, int level, int strategy)); +/* + Dynamically update the compression level and compression strategy. + This can be used to switch between compression and straight copy of + the input data, or to switch to a different kind of input data requiring + a different strategy. If the compression level is changed, the input + available so far is compressed with the old level (and may be flushed); + the new level will take effect only at the next call of deflate(). + + Before the call of deflateParams, the stream state must be set as for + a call of deflate(), since the currently available input may have to + be compressed and flushed. In particular, strm->avail_out must be non-zero. + + deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source + stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR + if strm->avail_out was zero. +*/ + +/* +extern int EXPORT inflateInit2 OF((z_streamp strm, + int windowBits)); + + This is another version of inflateInit with more compression options. The + fields next_out, zalloc, zfree and opaque must be initialized before by + the caller. + + The windowBits parameter is the base two logarithm of the maximum window + size (the size of the history buffer). It should be in the range 8..15 for + this version of the library (the value 16 will be allowed soon). The + default value is 15 if inflateInit is used instead. If a compressed stream + with a larger window size is given as input, inflate() will return with + the error code Z_DATA_ERROR instead of trying to allocate a larger window. + + If next_out is not null, the library will use this buffer for the history + buffer; the buffer must either be large enough to hold the entire output + data, or have at least 1< + +#include "zutil.h" + +struct internal_state {int dummy;}; /* for buggy compilers */ + +#ifndef STDC +extern void exit OF((int)); +#endif + +const char *z_errmsg[10] = { +"need dictionary", /* Z_NEED_DICT 2 */ +"stream end", /* Z_STREAM_END 1 */ +"", /* Z_OK 0 */ +"file error", /* Z_ERRNO (-1) */ +"stream error", /* Z_STREAM_ERROR (-2) */ +"data error", /* Z_DATA_ERROR (-3) */ +"insufficient memory", /* Z_MEM_ERROR (-4) */ +"buffer error", /* Z_BUF_ERROR (-5) */ +"incompatible version",/* Z_VERSION_ERROR (-6) */ +""}; + + +const char *zlibVersion() +{ + return ZLIB_VERSION; +} + +#ifdef DEBUG_ZIP +void z_error (m) + char *m; +{ + fprintf(stderr, "%s\n", m); + exit(1); +} +#endif + +#ifndef HAVE_MEMCPY + +void zmemcpy(dest, source, len) + Bytef* dest; + Bytef* source; + uInt len; +{ + if (len == 0) return; + do { + *dest++ = *source++; /* ??? to be unrolled */ + } while (--len != 0); +} + +int zmemcmp(s1, s2, len) + Bytef* s1; + Bytef* s2; + uInt len; +{ + uInt j; + + for (j = 0; j < len; j++) { + if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1; + } + return 0; +} + +void zmemzero(dest, len) + Bytef* dest; + uInt len; +{ + if (len == 0) return; + do { + *dest++ = 0; /* ??? to be unrolled */ + } while (--len != 0); +} +#endif + +#ifdef __TURBOC__ +#if (defined( __BORLANDC__) || !defined(SMALL_MEDIUM)) && !defined(__32BIT__) +/* Small and medium model in Turbo C are for now limited to near allocation + * with reduced MAX_WBITS and MAX_MEM_LEVEL + */ +# define MY_ZCALLOC + +/* Turbo C malloc() does not allow dynamic allocation of 64K bytes + * and farmalloc(64K) returns a pointer with an offset of 8, so we + * must fix the pointer. Warning: the pointer must be put back to its + * original form in order to free it, use zcfree(). + */ + +#define MAX_PTR 10 +/* 10*64K = 640K */ + +local int next_ptr = 0; + +typedef struct ptr_table_s { + voidpf org_ptr; + voidpf new_ptr; +} ptr_table; + +local ptr_table table[MAX_PTR]; +/* This table is used to remember the original form of pointers + * to large buffers (64K). Such pointers are normalized with a zero offset. + * Since MSDOS is not a preemptive multitasking OS, this table is not + * protected from concurrent access. This hack doesn't work anyway on + * a protected system like OS/2. Use Microsoft C instead. + */ + +voidpf zcalloc (voidpf opaque, unsigned items, unsigned size) +{ + voidpf buf = opaque; /* just to make some compilers happy */ + ulg bsize = (ulg)items*size; + + /* If we allocate less than 65520 bytes, we assume that farmalloc + * will return a usable pointer which doesn't have to be normalized. + */ + if (bsize < 65520L) { + buf = farmalloc(bsize); + if (*(ush*)&buf != 0) return buf; + } else { + buf = farmalloc(bsize + 16L); + } + if (buf == NULL || next_ptr >= MAX_PTR) return NULL; + table[next_ptr].org_ptr = buf; + + /* Normalize the pointer to seg:0 */ + *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4; + *(ush*)&buf = 0; + table[next_ptr++].new_ptr = buf; + return buf; +} + +void zcfree (voidpf opaque, voidpf ptr) +{ + int n; + if (*(ush*)&ptr != 0) { /* object < 64K */ + farfree(ptr); + return; + } + /* Find the original pointer */ + for (n = 0; n < next_ptr; n++) { + if (ptr != table[n].new_ptr) continue; + + farfree(table[n].org_ptr); + while (++n < next_ptr) { + table[n-1] = table[n]; + } + next_ptr--; + return; + } + ptr = opaque; /* just to make some compilers happy */ + Assert(0, "zcfree: ptr not found"); +} +#endif +#endif /* __TURBOC__ */ + + +#if defined(M_I86) && !defined(__32BIT__) +/* Microsoft C in 16-bit mode */ + +# define MY_ZCALLOC + +#if (!defined(_MSC_VER) || (_MSC_VER < 600)) +# define _halloc halloc +# define _hfree hfree +#endif + +voidpf zcalloc (voidpf opaque, unsigned items, unsigned size) +{ + if (opaque) opaque = 0; /* to make compiler happy */ + return _halloc((long)items, size); +} + +void zcfree (voidpf opaque, voidpf ptr) +{ + if (opaque) opaque = 0; /* to make compiler happy */ + _hfree(ptr); +} + +#endif /* MSC */ + + +#ifndef MY_ZCALLOC /* Any system without a special alloc function */ + +#ifndef STDC +extern voidp calloc OF((uInt items, uInt size)); +extern void free OF((voidpf ptr)); +#endif + +voidpf zcalloc (opaque, items, size) + voidpf opaque; + unsigned items; + unsigned size; +{ + if (opaque) items += size - size; /* make compiler happy */ + return (voidpf)calloc(items, size); +} + +void zcfree (opaque, ptr) + voidpf opaque; + voidpf ptr; +{ + free(ptr); + if (opaque) return; /* make compiler happy */ +} + +#endif /* MY_ZCALLOC */ diff --git a/ef/Utilities/zlib/zutil.h b/ef/Utilities/zlib/zutil.h new file mode 100644 index 000000000000..a9f0f91d0670 --- /dev/null +++ b/ef/Utilities/zlib/zutil.h @@ -0,0 +1,201 @@ +/* zutil.h -- internal interface and configuration of the compression library + * Copyright (C) 1995-1996 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +#ifndef _Z_UTIL_H +#define _Z_UTIL_H + +#include "zlib.h" + +#if defined(MSDOS)||defined(VMS)||defined(CRAY)||defined(WIN32)||defined(RISCOS) +# include +# include +#else + extern int errno; +#endif +#ifdef STDC +# include +# include +#endif + +#ifndef local +# define local static +#endif +/* compile with -Dlocal if your debugger can't find static symbols */ + +typedef unsigned char uch; +typedef uch FAR uchf; +typedef unsigned short ush; +typedef ush FAR ushf; +typedef unsigned long ulg; + +extern const char *z_errmsg[10]; /* indexed by 2-zlib_error */ +/* (size given to avoid silly warnings with Visual C++) */ + +#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)] + +#define ERR_RETURN(strm,err) \ + return (strm->msg = (char*)ERR_MSG(err), (err)) +/* To be used only when the state is known to be valid */ + + /* common constants */ + +#ifndef DEF_WBITS +# define DEF_WBITS MAX_WBITS +#endif +/* default windowBits for decompression. MAX_WBITS is for compression only */ + +#if MAX_MEM_LEVEL >= 8 +# define DEF_MEM_LEVEL 8 +#else +# define DEF_MEM_LEVEL MAX_MEM_LEVEL +#endif +/* default memLevel */ + +#define STORED_BLOCK 0 +#define STATIC_TREES 1 +#define DYN_TREES 2 +/* The three kinds of block type */ + +#define MIN_MATCH 3 +#define MAX_MATCH 258 +/* The minimum and maximum match lengths */ + +#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */ + + /* target dependencies */ + +#ifdef MSDOS +# define OS_CODE 0x00 +# ifdef __TURBOC__ +# include +# else /* MSC or DJGPP */ +# include +# endif +#endif + +#ifdef OS2 +# define OS_CODE 0x06 +#endif + +#ifdef WIN32 /* Window 95 & Windows NT */ +# define OS_CODE 0x0b +#endif + +#if defined(VAXC) || defined(VMS) +# define OS_CODE 0x02 +# define FOPEN(name, mode) \ + fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512") +#endif + +#ifdef AMIGA +# define OS_CODE 0x01 +#endif + +#if defined(ATARI) || defined(atarist) +# define OS_CODE 0x05 +#endif + +#ifdef MACOS +# define OS_CODE 0x07 +#endif + +#ifdef __50SERIES /* Prime/PRIMOS */ +# define OS_CODE 0x0F +#endif + +#ifdef TOPS20 +# define OS_CODE 0x0a +#endif + +#if defined(_BEOS_) || defined(RISCOS) +# define fdopen(fd,mode) NULL /* No fdopen() */ +#endif + + /* Common defaults */ + +#ifndef OS_CODE +# define OS_CODE 0x03 /* assume Unix */ +#endif + +#ifndef FOPEN +# define FOPEN(name, mode) fopen((name), (mode)) +#endif + + /* functions */ + +#ifdef HAVE_STRERROR + extern char *strerror OF((int)); +# define zstrerror(errnum) strerror(errnum) +#else +# define zstrerror(errnum) "" +#endif + +#if defined(pyr) +# define NO_MEMCPY +#endif +#if (defined(M_I86SM) || defined(M_I86MM)) && !defined(_MSC_VER) + /* Use our own functions for small and medium model with MSC <= 5.0. + * You may have to use the same strategy for Borland C (untested). + */ +# define NO_MEMCPY +#endif +#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY) +# define HAVE_MEMCPY +#endif +#ifdef HAVE_MEMCPY +# ifdef SMALL_MEDIUM /* MSDOS small or medium model */ +# define zmemcpy _fmemcpy +# define zmemcmp _fmemcmp +# define zmemzero(dest, len) _fmemset(dest, 0, len) +# else +# define zmemcpy memcpy +# define zmemcmp memcmp +# define zmemzero(dest, len) memset(dest, 0, len) +# endif +#else + extern void zmemcpy OF((Bytef* dest, Bytef* source, uInt len)); + extern int zmemcmp OF((Bytef* s1, Bytef* s2, uInt len)); + extern void zmemzero OF((Bytef* dest, uInt len)); +#endif + +/* Diagnostic functions */ +#ifdef DEBUG_ZIP +# include +# ifndef verbose +# define verbose 0 +# endif + extern void z_error OF((char *m)); +# define Assert(cond,msg) {if(!(cond)) z_error(msg);} +# define Trace(x) fprintf x +# define Tracev(x) {if (verbose) fprintf x ;} +# define Tracevv(x) {if (verbose>1) fprintf x ;} +# define Tracec(c,x) {if (verbose && (c)) fprintf x ;} +# define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;} +#else +# define Assert(cond,msg) +# define Trace(x) +# define Tracev(x) +# define Tracevv(x) +# define Tracec(c,x) +# define Tracecv(c,x) +#endif + + +typedef uLong (*check_func) OF((uLong check, const Bytef *buf, uInt len)); + +voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size)); +void zcfree OF((voidpf opaque, voidpf ptr)); + +#define ZALLOC(strm, items, size) \ + (*((strm)->zalloc))((strm)->opaque, (items), (size)) +#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr)) +#define TRY_FREE(s, p) {if (p) ZFREE(s, p);} + +#endif /* _Z_UTIL_H */ diff --git a/ef/VM/Makefile b/ef/VM/Makefile new file mode 100644 index 000000000000..1b5c98b43449 --- /dev/null +++ b/ef/VM/Makefile @@ -0,0 +1,47 @@ +#! gmake +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +####################################################################### +# (1) Include manifest file # +####################################################################### + +include manifest.mn + +####################################################################### +# (2) Include "component" configuration information. # +####################################################################### + +include $(DEPTH)/config/config.mk + +####################################################################### +# (3) Include "local" platform-dependent assignments (OPTIONAL). # +####################################################################### + +include config.mk + +####################################################################### +# (4) Execute "component" rules. (OPTIONAL) # +####################################################################### + +include $(DEPTH)/config/rules.mk + +####################################################################### +# (7) Execute "local" rules. (OPTIONAL). # +####################################################################### + +include rules.mk + diff --git a/ef/VM/config.mk b/ef/VM/config.mk new file mode 100644 index 000000000000..b2187b7d4abd --- /dev/null +++ b/ef/VM/config.mk @@ -0,0 +1,19 @@ +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +OBJS = $(wildcard $(DEPTH)/$(OBJDIR)/EF/*$(OBJ_SUFFIX)) +LDFLAGS += $(NSPR_LIBS) + diff --git a/ef/VM/manifest.mn b/ef/VM/manifest.mn new file mode 100644 index 000000000000..1d5f4c6cd40f --- /dev/null +++ b/ef/VM/manifest.mn @@ -0,0 +1,27 @@ +#! gmake +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +DEPTH = .. + +IMPORTS = nspr20/19971028 \ + $(NULL) + +LIBRARY_NAME = EF + +LIBRARIES = DisassembleX86 DebuggerChannel $(NULL) + + diff --git a/ef/VM/rules.mk b/ef/VM/rules.mk new file mode 100644 index 000000000000..a1f25630cbee --- /dev/null +++ b/ef/VM/rules.mk @@ -0,0 +1,22 @@ +#! gmake +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +ifeq ($(OS_ARCH),WINNT) +libs:: $(SHARED_LIBRARY) +else +libs:: $(LIBRARY) +endif diff --git a/ef/config/Linux.mk b/ef/config/Linux.mk new file mode 100644 index 000000000000..e33a4f5973ce --- /dev/null +++ b/ef/config/Linux.mk @@ -0,0 +1,53 @@ +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +# +# Config stuff for Linux +# + +#include $(DEPTH)/config/UNIX.mk + +CC = gcc +CXX = g++ +AS = gcc -c +RANLIB = ranlib +MKSHLIB = $(LD) $(DSO_LDOPTS) -soname $(@:$(OBJDIR)/%.so=%.so) +MKMODULE = ld -Ur -o $@ + +WARNING_CFLAG = -Wall + +INCLUDES += -I$(subst libgcc.a,include, \ + $(shell gcc -print-libgcc-file-name)) +ifeq ($(CPU_ARCH),x86) +DEPENDFLAGS += -D__i386__ +endif + +OS_CFLAGS = $(DSO_CFLAGS) -DLINUX -Dlinux +OS_CXXFLAGS = $(OS_CFLAGS) +OS_ASFLAGS = -DLINUX -Dlinux +OS_LDFLAGS = +OS_LIBS = -lm + +DSO_CFLAGS = -fPIC +DSO_LDFLAGS = -Wl,export-dynamic +DSO_LDOPTS = -shared + +PERL = perl + +ifeq ($(CXX), g++) +OS_CFLAGS += -fhandle-exceptions +endif + diff --git a/ef/config/LinuxELF2.0.mk b/ef/config/LinuxELF2.0.mk new file mode 100644 index 000000000000..264ca4abde71 --- /dev/null +++ b/ef/config/LinuxELF2.0.mk @@ -0,0 +1,21 @@ +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +# +# Config stuff for Linux 2.0 (ELF) +# + +include $(DEPTH)/config/Linux.mk diff --git a/ef/config/LinuxELF2.1.mk b/ef/config/LinuxELF2.1.mk new file mode 100644 index 000000000000..7ef038005f09 --- /dev/null +++ b/ef/config/LinuxELF2.1.mk @@ -0,0 +1,15 @@ +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. diff --git a/ef/config/Makefile b/ef/config/Makefile new file mode 100644 index 000000000000..62d54b49bbb0 --- /dev/null +++ b/ef/config/Makefile @@ -0,0 +1,43 @@ +#! gmake +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +DEPTH = .. + +include $(DEPTH)/config/config.mk +DIRS = mkdepend +CSRCS = nsinstall.c pathsub.c + +PLSRCS = nfspwd.pl + +ifneq ($(OS_ARCH),WINNT) +PROGRAM = $(OBJDIR)/nsinstall +TARGETS = $(PROGRAM) $(OBJDIR)/$(PLSRCS:.pl=) +endif + +MKDEPENDENCIES = + +include $(DEPTH)/config/rules.mk + +# Redefine MAKE_OBJDIR for just this directory (nsinstall is not compiled yet !) +define MAKE_OBJDIR +if test ! -d $(@D); then rm -rf $(@D); mkdir $(@D); fi +endef + +export:: $(TARGETS) + +clean clobber realclean clobber_all:: + $(MAKE) $@ -C ./mkdepend diff --git a/ef/config/SunOS5.5.1.mk b/ef/config/SunOS5.5.1.mk new file mode 100644 index 000000000000..7ef038005f09 --- /dev/null +++ b/ef/config/SunOS5.5.1.mk @@ -0,0 +1,15 @@ +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. diff --git a/ef/config/SunOS5.5.mk b/ef/config/SunOS5.5.mk new file mode 100644 index 000000000000..7ef038005f09 --- /dev/null +++ b/ef/config/SunOS5.5.mk @@ -0,0 +1,15 @@ +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. diff --git a/ef/config/SunOS5.6.mk b/ef/config/SunOS5.6.mk new file mode 100644 index 000000000000..7ef038005f09 --- /dev/null +++ b/ef/config/SunOS5.6.mk @@ -0,0 +1,15 @@ +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. diff --git a/ef/config/SunOS5.mk b/ef/config/SunOS5.mk new file mode 100644 index 000000000000..7ef038005f09 --- /dev/null +++ b/ef/config/SunOS5.mk @@ -0,0 +1,15 @@ +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. diff --git a/ef/config/UNIX.mk b/ef/config/UNIX.mk new file mode 100644 index 000000000000..1b59611f59cd --- /dev/null +++ b/ef/config/UNIX.mk @@ -0,0 +1,82 @@ +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +OBJ_SUFFIX = o +LIB_SUFFIX = a +DLL_SUFFIX = so +AR = ar cr $@ + +ifdef BUILD_OPT +OPTIMIZER = -O +DEFINES = -DXP_UNIX -UDEBUG -DNDEBUG +OBJDIR_TAG = _OPT +else +OPTIMIZER = -g +DEFINES = -DXP_UNIX -DDEBUG -UNDEBUG -DDEBUG_$(shell whoami) -DPR_LOGGING +OBJDIR_TAG = _DBG +endif + +EXCEPTION_FLAG = -fhandle-exceptions + +# +# Name of the binary code directories +# + +OBJDIR_NAME = $(OS_CONFIG)$(COMPILER_TAG)$(OBJDIR_TAG).OBJ + +# +# Install +# + +#################################################################### +# +# One can define the makefile variable NSDISTMODE to control +# how files are published to the 'dist' directory. If not +# defined, the default is "install using relative symbolic +# links". The two possible values are "copy", which copies files +# but preserves source mtime, and "absolute_symlink", which +# installs using absolute symbolic links. The "absolute_symlink" +# option requires NFSPWD. +# +#################################################################### + +NSINSTALL = $(DEPTH)/config/$(OBJDIR_NAME)/nsinstall + +ifeq ($(NSDISTMODE),copy) +# copy files, but preserve source mtime +INSTALL = $(NSINSTALL) -t +else +ifeq ($(NSDISTMODE),absolute_symlink) +# install using absolute symbolic links +INSTALL = $(NSINSTALL) -L `$(NFSPWD)` +else +# install using relative symbolic links +INSTALL = $(NSINSTALL) -R +endif +endif + +define MAKE_OBJDIR +if test ! -d $(@D); then rm -rf $(@D); $(NSINSTALL) -D $(@D); fi +endef + +# +# Dependencies +# + +MKDEPEND_DIR = $(DEPTH)/config/mkdepend +MKDEPEND = $(MKDEPEND_DIR)/$(OBJDIR_NAME)/mkdepend +MKDEPENDENCIES = $(OBJDIR_NAME)/depend.mk + diff --git a/ef/config/WINNT.mk b/ef/config/WINNT.mk new file mode 100644 index 000000000000..7ef038005f09 --- /dev/null +++ b/ef/config/WINNT.mk @@ -0,0 +1,15 @@ +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. diff --git a/ef/config/WINNT4.0.mk b/ef/config/WINNT4.0.mk new file mode 100644 index 000000000000..7ef038005f09 --- /dev/null +++ b/ef/config/WINNT4.0.mk @@ -0,0 +1,15 @@ +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. diff --git a/ef/config/arch.mk b/ef/config/arch.mk new file mode 100644 index 000000000000..7a1afe6d4c1f --- /dev/null +++ b/ef/config/arch.mk @@ -0,0 +1,59 @@ +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +ifeq ($(OS_ARCH),SunOS) + CPU_ARCH = $(shell uname -p) +endif + + +# +# Force the IRIX64 machines to use IRIX. +# +ifeq ($(OS_ARCH),IRIX) + CPU_ARCH = mips +endif + + +ifeq ($(OS_ARCH),AIX) + CPU_ARCH = ppc +endif + + +# +# OS_OBJTYPE is used only by Linux +# + +ifeq ($(OS_ARCH),Linux) + OS_OBJTYPE := ELF + CPU_ARCH := $(shell uname -m) + ifneq (,$(findstring 86,$(CPU_ARCH))) + CPU_ARCH = x86 + endif +endif + +ifeq ($(OS_ARCH),HP-UX) + CPU_ARCH = hppa +endif + +ifeq ($(OS_ARCH),WINNT) + CPU_ARCH = $(shell uname -p) + ifeq ($(CPU_ARCH),I386) + CPU_ARCH = x86 + endif +endif + + + diff --git a/ef/config/config.mk b/ef/config/config.mk new file mode 100644 index 000000000000..cd59f532d734 --- /dev/null +++ b/ef/config/config.mk @@ -0,0 +1,119 @@ +#! gmake +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +ifndef EF_CONFIG_MK + +EF_CONFIG_MK=1 + +CORE_DEPTH = $(DEPTH)/.. + +include $(DEPTH)/config/coreconfig.mk +include $(DEPTH)/config/arch.mk +include $(DEPTH)/config/$(OS_CONFIG).mk + +ifeq ($(OS_ARCH),WINNT) + CCC = cl + EXC_FLAGS = -GX + OS_DLLFLAGS = -nologo -DLL -incremental:yes -subsystem:console -machine:I386 wsock32.lib + EF_LIBS = $(DIST)/lib/EF.lib + EF_LIB_FILES = $(EF_LIBS) + NSPR_LIBS = $(DIST)/lib/libnspr21.lib $(DIST)/lib/libplc21_s.lib + BROWSE_INFO_DIR = $(DEPTH)/$(OBJDIR)/BrowseInfo + BROWSE_INFO_OBJS = $(wildcard $(BROWSE_INFO_DIR)/*.sbr) + BROWSE_INFO_PROGRAM = bscmake + BROWSE_INFO_FLAGS = -nologo -incremental:yes + BROWSE_INFO_FILE = $(BROWSE_INFO_DIR)/ef.bsc + YACC = "$(NSTOOLS)/bin/yacc$(PROG_SUFFIX)" -l -b y.tab + LN = "$(NSTOOLS)/bin/ln$(PROG_SUFFIX)" -f + +# Flag to generate pre-compiled headers + CFLAGS += -YX -Fp$(OBJDIR)/ef.pch -Fd$(OBJDIR)/ef.pdb + MKDIR = mkdir +else + CCC = gcc + AS = gcc + ASFLAGS += -x assembler-with-cpp + CFLAGS += -fdollars-in-identifiers + EXC_FLAGS = -fhandle-exceptions + EF_LIBS = -lEF + EF_LIB_FILES = $(DIST)/lib/libEF.a + NSPR_LIBS = -L$(DIST)/lib -lnspr21 -lplc21 + MKDIR = mkdir -p + LN = ln -s -f +endif + +CFLAGS += $(EXC_FLAGS) +#LDFLAGS += $(NSPR_LIBS) + +ifeq ($(CPU_ARCH),x86) +ARCH_DEFINES += -DGENERATE_FOR_X86 +NO_GENERIC = 1 +endif + +ifeq ($(CPU_ARCH),ppc) +ARCH_DEFINES += -DGENERATE_FOR_PPC +endif + +ifeq ($(CPU_ARCH),sparc) +# No CodeGenerator for sparc yet. +ARCH_DEFINES += -DGENERATE_FOR_X86 +CPU_ARCH = x86 +endif + +ifeq ($(CPU_ARCH),hppa) +# No CodeGenerator for hppa yet. +ARCH_DEFINES += -DGENERATE_FOR_X86 +CPU_ARCH = x86 +endif + +ifneq ($(NO_GENERIC),1) +GENERIC = generic +endif + +ARCH_DEFINES += -DTARGET_CPU=$(CPU_ARCH) +CFLAGS += $(ARCH_DEFINES) + + +# +# Some tools. +# +NFSPWD = $(DEPTH)/config/$(OBJDIR)/nfspwd +JAVAH = $(DIST)/bin/javah$(PROG_SUFFIX) +BURG = $(DEPTH)/Tools/Burg/$(OBJDIR)/burg$(PROG_SUFFIX) +PERL = perl + +HEADER_GEN_DIR = $(DEPTH)/GenIncludes +LOCAL_EXPORT_DIR = $(DEPTH)/LocalIncludes + +INCLUDES += -I $(LOCAL_EXPORT_DIR) -I $(LOCAL_EXPORT_DIR)/md/$(CPU_ARCH) -I $(DIST)/include -I $(DEPTH)/Includes + +ifneq ($(HEADER_GEN),) +INCLUDES += -I $(HEADER_GEN_DIR) +CFLAGS += -DIMPORTING_VM_FILES +PACKAGE_CLASSES = $(HEADER_GEN) +PATH_CLASSES = $(subst .,/,$(PACKAGE_CLASSES)) +CLASS_FILE_NAMES = $(subst .,_,$(PACKAGE_CLASSES)) +HEADER_INCLUDES = $(patsubst %,$(HEADER_GEN_DIR)/%.h,$(CLASS_FILE_NAMES)) +endif + +MKDEPEND_DIR = $(DEPTH)/config/mkdepend +MKDEPEND = $(MKDEPEND_DIR)/$(OBJDIR_NAME)/mkdepend +MKDEPENDENCIES = $(OBJDIR_NAME)/depend.mk + +endif + + diff --git a/ef/config/coreconfig.mk b/ef/config/coreconfig.mk new file mode 100644 index 000000000000..66d7dedc0ad9 --- /dev/null +++ b/ef/config/coreconfig.mk @@ -0,0 +1,50 @@ +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +# +# Configuration information for building in the "Core Components" source module +# This is a copy of the coreconf config file without ruleset.mk. +# We need to do this until we can convince the coreconf folks to not include +# ruleset.mk in their config.mk file +# +ifndef ($(CORE_DEPTH)) + CORE_DEPTH=$(DEPTH)/.. +endif + +include $(CORE_DEPTH)/coreconf/arch.mk + +include $(CORE_DEPTH)/coreconf/command.mk + +include $(CORE_DEPTH)/coreconf/$(OS_CONFIG).mk + +include $(CORE_DEPTH)/coreconf/platform.mk + +include $(CORE_DEPTH)/coreconf/tree.mk + +include $(CORE_DEPTH)/coreconf/module.mk + +include $(CORE_DEPTH)/coreconf/version.mk + +include $(CORE_DEPTH)/coreconf/location.mk + +include $(CORE_DEPTH)/coreconf/source.mk + +include $(CORE_DEPTH)/coreconf/headers.mk + +include $(CORE_DEPTH)/coreconf/prefix.mk + +include $(CORE_DEPTH)/coreconf/suffix.mk + diff --git a/ef/config/corerules.mk b/ef/config/corerules.mk new file mode 100644 index 000000000000..863ea7837a67 --- /dev/null +++ b/ef/config/corerules.mk @@ -0,0 +1,749 @@ +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +####################################################################### +### ### +### R U L E S O F E N G A G E M E N T ### +### ### +####################################################################### + +####################################################################### +# Double-Colon rules for utilizing the binary release model. # +####################################################################### + +all:: export libs program install + +autobuild:: export private_export libs program install + +platform:: + @echo $(OBJDIR_NAME) + + +# +# IMPORTS will always be associated with a component. Therefore, +# the "import" rule will always change directory to the top-level +# of a component, and traverse the IMPORTS keyword from the +# "manifest.mn" file located at this level only. +# +# note: if there is a trailing slash, the component will be appended +# (see import.pl - only used for xpheader.jar) + +import:: + @echo "== import.pl ==" + @perl -I$(CORE_DEPTH)/coreconf $(CORE_DEPTH)/coreconf/import.pl \ + "RELEASE_TREE=$(RELEASE_TREE)" \ + "IMPORTS=$(IMPORTS)" \ + "VERSION=$(VERSION)" \ + "OS_ARCH=$(OS_ARCH)" \ + "PLATFORM=$(PLATFORM)" \ + "SOURCE_RELEASE_PREFIX=$(SOURCE_RELEASE_XP_DIR)" \ + "SOURCE_MD_DIR=$(SOURCE_MD_DIR)" \ + "SOURCE_XP_DIR=$(SOURCE_XP_DIR)" \ + "FILES=$(XPCLASS_JAR) $(XPHEADER_JAR) $(MDHEADER_JAR) $(MDBINARY_JAR)" \ + "$(XPCLASS_JAR)=$(RELEASE_XP_DIR)|$(SOURCE_CLASSES_DIR)" \ + "$(XPHEADER_JAR)=$(RELEASE_XP_DIR)|$(SOURCE_XP_DIR)/public/" \ + "$(MDHEADER_JAR)=$(RELEASE_MD_DIR)|$(SOURCE_MD_DIR)/include" \ + "$(MDBINARY_JAR)=$(RELEASE_MD_DIR)|$(SOURCE_MD_DIR)" + +# perl -I$(CORE_DEPTH)/coreconf $(CORE_DEPTH)/coreconf/import.pl \ +# "IMPORTS=$(IMPORTS)" \ +# "RELEASE_TREE=$(RELEASE_TREE)" \ +# "VERSION=$(VERSION)" \ +# "PLATFORM=$(PLATFORM)" \ +# "SOURCE_MD_DIR=$(SOURCE_MD_DIR)" \ +# "SOURCE_XP_DIR=$(SOURCE_XP_DIR)" \ +# "OS_ARCH=$(OS_ARCH)" ; + + +export:: +ifndef NO_EXPORT_IN_SUBDIRS + +$(LOOP_OVER_DIRS) +endif + +private_export:: + +$(LOOP_OVER_DIRS) + +release_export:: + +$(LOOP_OVER_DIRS) + +libs :: $(TARGETS) +ifndef NO_LIBS_IN_SUBDIRS + +$(LOOP_OVER_DIRS) +endif + +program :: $(TARGETS) +ifndef NO_PROGRAM_IN_SUBDIRS + +$(LOOP_OVER_DIRS) +endif + +install:: $(TARGETS) +ifdef LIBRARY + $(INSTALL) -m 444 $(LIBRARY) $(SOURCE_LIB_DIR) +endif + +ifdef SHARED_LIBRARY +ifeq ($(OS_ARCH),WINNT) + $(INSTALL) -m 555 $(SHARED_LIBRARY) $(SOURCE_BIN_DIR) +else + $(INSTALL) -m 555 $(SHARED_LIBRARY) $(SOURCE_LIB_DIR) +endif +endif +ifdef IMPORT_LIBRARY + $(INSTALL) -m 555 $(IMPORT_LIBRARY) $(SOURCE_LIB_DIR) +endif +ifdef PROGRAM + $(INSTALL) -m 555 $(PROGRAM) $(SOURCE_BIN_DIR) +endif +ifdef PROGRAMS + $(INSTALL) -m 555 $(PROGRAMS) $(SOURCE_BIN_DIR) +endif +ifndef NO_INSTALL_IN_SUBDIRS + +$(LOOP_OVER_DIRS) +endif + +tests:: + +$(LOOP_OVER_DIRS) + +clean clobber:: + rm -rf $(ALL_TRASH) + +$(LOOP_OVER_DIRS) + +realclean clobber_all:: + rm -rf $(wildcard *.OBJ) dist $(ALL_TRASH) + +$(LOOP_OVER_DIRS) + +#ifdef ALL_PLATFORMS +#all_platforms:: $(NFSPWD) +# @d=`$(NFSPWD)`; \ +# if test ! -d LOGS; then rm -rf LOGS; mkdir LOGS; fi; \ +# for h in $(PLATFORM_HOSTS); do \ +# echo "On $$h: $(MAKE) $(ALL_PLATFORMS) >& LOGS/$$h.log";\ +# rsh $$h -n "(chdir $$d; \ +# $(MAKE) $(ALL_PLATFORMS) >& LOGS/$$h.log; \ +# echo DONE) &" 2>&1 > LOGS/$$h.pid & \ +# sleep 1; \ +# done +# +#$(NFSPWD): +# cd $(@D); $(MAKE) $(@F) +#endif + +####################################################################### +# Double-Colon rules for populating the binary release model. # +####################################################################### + + +release_clean:: + rm -rf $(SOURCE_XP_DIR)/release + +release:: release_clean release_export release_md release_jars release_cpdistdir + +release_cpdistdir:: + @echo "== cpdist.pl ==" + @perl -I$(CORE_DEPTH)/coreconf $(CORE_DEPTH)/coreconf/cpdist.pl \ + "RELEASE_TREE=$(RELEASE_TREE)" \ + "CORE_DEPTH=$(CORE_DEPTH)" \ + "MODULE=${MODULE}" \ + "OS_ARCH=$(OS_ARCH)" \ + "RELEASE=$(RELEASE)" \ + "PLATFORM=$(PLATFORM)" \ + "RELEASE_VERSION=$(RELEASE_VERSION)" \ + "SOURCE_RELEASE_PREFIX=$(SOURCE_RELEASE_XP_DIR)" \ + "RELEASE_XP_DIR=$(RELEASE_XP_DIR)" \ + "RELEASE_MD_DIR=$(RELEASE_MD_DIR)" \ + "FILES=$(XPCLASS_JAR) $(XPHEADER_JAR) $(MDHEADER_JAR) $(MDBINARY_JAR) XP_FILES MD_FILES" \ + "$(XPCLASS_JAR)=$(SOURCE_RELEASE_CLASSES_DIR)|x"\ + "$(XPHEADER_JAR)=$(SOURCE_RELEASE_XPHEADERS_DIR)|x" \ + "$(MDHEADER_JAR)=$(SOURCE_RELEASE_MDHEADERS_DIR)|m" \ + "$(MDBINARY_JAR)=$(SOURCE_RELEASE_MD_DIR)|m" \ + "XP_FILES=$(XP_FILES)|xf" \ + "MD_FILES=$(MD_FILES)|mf" + + +# Add $(SOURCE_RELEASE_XPSOURCE_JAR) to FILES line when ready + +# $(SOURCE_RELEASE_xxx_JAR) is a name like yyy.jar +# $(SOURCE_RELEASE_xx_DIR) is a name like + +release_jars:: + @echo "== release.pl ==" + @perl -I$(CORE_DEPTH)/coreconf $(CORE_DEPTH)/coreconf/release.pl \ + "RELEASE_TREE=$(RELEASE_TREE)" \ + "PLATFORM=$(PLATFORM)" \ + "OS_ARCH=$(OS_ARCH)" \ + "RELEASE_VERSION=$(RELEASE_VERSION)" \ + "SOURCE_RELEASE_DIR=$(SOURCE_RELEASE_DIR)" \ + "FILES=$(XPCLASS_JAR) $(XPHEADER_JAR) $(MDHEADER_JAR) $(MDBINARY_JAR)" \ + "$(XPCLASS_JAR)=$(SOURCE_RELEASE_PREFIX)/$(SOURCE_RELEASE_CLASSES_DIR)|b"\ + "$(XPHEADER_JAR)=$(SOURCE_RELEASE_PREFIX)/$(SOURCE_RELEASE_XPHEADERS_DIR)|a" \ + "$(MDHEADER_JAR)=$(SOURCE_RELEASE_PREFIX)/$(SOURCE_RELEASE_MDHEADERS_DIR)|a" \ + "$(MDBINARY_JAR)=$(SOURCE_RELEASE_PREFIX)/$(SOURCE_RELEASE_MD_DIR)|bi" +# "$(XPSOURCE_JAR)=$(SOURCE_RELEASE_PREFIX)|a" + + + +release_md:: +ifdef LIBRARY + $(INSTALL) -m 444 $(LIBRARY) $(SOURCE_RELEASE_PREFIX)/$(SOURCE_RELEASE_LIB_DIR) +endif +ifdef SHARED_LIBRARY + $(INSTALL) -m 555 $(SHARED_LIBRARY) $(SOURCE_RELEASE_PREFIX)/$(SOURCE_RELEASE_LIB_DIR) +endif +ifdef IMPORT_LIBRARY + $(INSTALL) -m 555 $(IMPORT_LIBRARY) $(SOURCE_RELEASE_PREFIX)/$(SOURCE_RELEASE_LIB_DIR) +endif +ifdef PROGRAM + $(INSTALL) -m 555 $(PROGRAM) $(SOURCE_RELEASE_PREFIX)/$(SOURCE_RELEASE_BIN_DIR) +endif +ifdef PROGRAMS + $(INSTALL) -m 555 $(PROGRAMS) $(SOURCE_RELEASE_PREFIX)/$(SOURCE_RELEASE_BIN_DIR) +endif + +$(LOOP_OVER_DIRS) + + +alltags: + rm -f TAGS + find . -name dist -prune -o \( -name '*.[hc]' -o -name '*.cp' -o -name '*.cpp' \) -print | xargs etags -a + find . -name dist -prune -o \( -name '*.[hc]' -o -name '*.cp' -o -name '*.cpp' \) -print | xargs ctags -a + +$(PROGRAM): $(OBJS) + @$(MAKE_OBJDIR) +ifeq ($(OS_ARCH),WINNT) + $(CC) $(OBJS) -Fe$@ -link $(LDFLAGS) $(OS_LIBS) $(EXTRA_LIBS) +else + $(CC) -o $@ $(CFLAGS) $(OBJS) $(LDFLAGS) $(OS_LIBS) +endif + $(INSTALL) -m 555 $(PROGRAM) $(SOURCE_BIN_DIR) + +$(LIBRARY): $(OBJS) + @$(MAKE_OBJDIR) + rm -f $@ + $(AR) $(OBJS) + $(RANLIB) $@ + $(INSTALL) -m 444 $(LIBRARY) $(SOURCE_LIB_DIR) + + +ifeq ($(OS_TARGET), WIN16) +$(IMPORT_LIBRARY): $(SHARED_LIBRARY) + wlib +$(SHARED_LIBRARY) + $(INSTALL) -m 555 $(IMPORT_LIBRARY) $(SOURCE_LIB_DIR) +endif + +$(SHARED_LIBRARY): $(OBJS) + @$(MAKE_OBJDIR) + rm -f $@ +ifeq ($(OS_ARCH), AIX) + echo "#!" > $(OBJDIR)/lib$(LIBRARY_NAME)_syms + nm -B -C -g $(OBJS) \ + | awk '/ [T,D] / {print $$3}' \ + | sed -e 's/^\.//' \ + | sort -u >> $(OBJDIR)/lib$(LIBRARY_NAME)_syms + $(LD) $(XCFLAGS) -o $@ $(OBJS) -bE:$(OBJDIR)/lib$(LIBRARY_NAME)_syms \ + -bM:SRE -bnoentry $(OS_LIBS) $(EXTRA_LIBS) +else +ifeq ($(OS_ARCH), WINNT) +ifeq ($(OS_TARGET), WIN16) + echo system windows dll initinstance >w16link + echo option map >>w16link + echo option oneautodata >>w16link + echo option heapsize=32K >>w16link + echo debug watcom all >>w16link + echo name $@ >>w16link + echo file >>w16link + echo $(W16OBJS) >>w16link + echo $(W16LIBS) >>w16link + #echo extra: $(EXTRA_LIBS), os_libs: $(OS_LIBS), $(W16LIBS) >>w16link + echo libfile libentry >>w16link + $(LINK) @w16link. + rm w16link +else + $(LINK_DLL) -MAP $(DLLBASE) $(OS_LIBS) $(EXTRA_LIBS) $(OBJS) $(LDFLAGS) +endif + $(INSTALL) -m 555 $(LIBRARY) $(SOURCE_LIB_DIR) +else + $(MKSHLIB) -o $@ $(OBJS) $(LD_LIBS) $(OS_LIBS) $(EXTRA_LIBS) + chmod +x $@ +endif +endif +ifeq ($(OS_ARCH),WINNT) + $(INSTALL) -m 555 $(SHARED_LIBRARY) $(SOURCE_BIN_DIR) +else + $(INSTALL) -m 555 $(SHARED_LIBRARY) $(SOURCE_LIB_DIR) +endif + +$(PURE_LIBRARY): + rm -f $@ +ifneq ($(OS_ARCH), WINNT) + $(AR) $(OBJS) +endif + $(RANLIB) $@ + +ifeq ($(OS_ARCH), WINNT) +$(RES): $(RESNAME) + @$(MAKE_OBJDIR) + $(RC) -Fo$(RES) $(RESNAME) + @echo $(RES) finished + +$(DLL): $(OBJS) $(EXTRA_LIBS) + @$(MAKE_OBJDIR) + rm -f $@ + $(LINK_DLL) $(OBJS) $(OS_LIBS) $(EXTRA_LIBS) +endif + +$(OBJDIR)/$(PROG_PREFIX)%$(PROG_SUFFIX): $(OBJDIR)/$(PROG_PREFIX)%$(OBJ_SUFFIX) + @$(MAKE_OBJDIR) +ifeq ($(OS_ARCH),WINNT) + $(CC) $(OBJDIR)/$(PROG_PREFIX)$*$(OBJ_SUFFIX) -Fe$@ -link $(LDFLAGS) $(OS_LIBS) $(EXTRA_LIBS) +else + $(CC) -o $@ $(OBJDIR)/$(PROG_PREFIX)$*$(OBJ_SUFFIX) $(LDFLAGS) +endif + +ifdef HAVE_PURIFY +$(OBJDIR)/$(PROG_PREFIX)%.pure: $(OBJDIR)/%$(OBJ_SUFFIX) + @$(MAKE_OBJDIR) +ifeq ($(OS_ARCH),WINNT) + $(PURIFY) $(CC) -Fo$@ -c $(CFLAGS) $(OBJDIR)/$(PROG_PREFIX)$*$(OBJ_SUFFIX) $(PURELDFLAGS) +else + $(PURIFY) $(CC) -o $@ $(CFLAGS) $(OBJDIR)/$(PROG_PREFIX)$*$(OBJ_SUFFIX) $(PURELDFLAGS) +endif +endif + +WCCFLAGS1 := $(subst /,\\,$(CFLAGS)) +WCCFLAGS2 := $(subst -I,-i=,$(WCCFLAGS1)) +WCCFLAGS3 := $(subst -D,-d,$(WCCFLAGS2)) + +$(OBJDIR)/$(PROG_PREFIX)%$(OBJ_SUFFIX): %.c + @$(MAKE_OBJDIR) +ifeq ($(OS_ARCH), WINNT) +ifeq ($(OS_TARGET), WIN16) + # $(CORE_DEPTH)/coreconf/w16opt $(WCCFLAGS3) + echo $(WCCFLAGS3) >w16wccf + $(CC) -zq -fo$(OBJDIR)\\$(PROG_PREFIX)$*$(OBJ_SUFFIX) @w16wccf $*.c + rm w16wccf +else +ifdef GENERATE_BROWSE_INFO + @mkdir $(BROWSE_INFO_DIR) + $(CC) -Fo$@ -c $(CFLAGS) $*.c -FR$(BROWSE_INFO_DIR)/$*.sbr +else + $(CC) -Fo$@ -c $(CFLAGS) $*.c +endif + +endif +else + $(CC) -o $@ -c $(CFLAGS) $*.c +endif + +$(OBJDIR)/$(PROG_PREFIX)%$(OBJ_SUFFIX): %.s + @$(MAKE_OBJDIR) + $(AS) -o $@ $(ASFLAGS) -c $*.s + +$(OBJDIR)/$(PROG_PREFIX)%$(OBJ_SUFFIX): %.S + @$(MAKE_OBJDIR) + $(AS) -o $@ $(ASFLAGS) -c $*.S + +$(OBJDIR)/$(PROG_PREFIX)%: %.cpp + @$(MAKE_OBJDIR) +ifeq ($(OS_ARCH), WINNT) + $(CCC) -o $@ -c $(CFLAGS) $< +endif + + +# +# Please keep the next two rules in sync. +# +$(OBJDIR)/$(PROG_PREFIX)%$(OBJ_SUFFIX): %.cc + @$(MAKE_OBJDIR) + $(CCC) -o $@ -c $(CFLAGS) $*.cc + +$(OBJDIR)/$(PROG_PREFIX)%$(OBJ_SUFFIX): %.cpp + @$(MAKE_OBJDIR) +ifdef STRICT_CPLUSPLUS_SUFFIX + echo "#line 1 \"$*.cpp\"" | cat - $*.cpp > $(OBJDIR)/t_$*.cc + $(CCC) -o $@ -c $(CFLAGS) $(OBJDIR)/t_$*.cc + rm -f $(OBJDIR)/t_$*.cc +else +ifeq ($(OS_ARCH),WINNT) +ifdef GENERATE_BROWSE_INFO + @mkdir $(BROWSE_INFO_DIR) + $(CCC) -Fo$@ -c $(CFLAGS) $*.cpp -FR$(BROWSE_INFO_DIR)/$*.sbr +else + $(CCC) -Fo$@ -c $(CFLAGS) $*.cpp +endif +else + $(CCC) -o $@ -c $(CFLAGS) $*.cpp +endif +endif #STRICT_CPLUSPLUS_SUFFIX + +%.i: %.cpp + $(CCC) -C -E $(CFLAGS) $< > $*.i + +%.i: %.c + $(CC) -C -E $(CFLAGS) $< > $*.i + +%: %.pl + rm -f $@; cp $*.pl $@; chmod +x $@ + +%: %.sh + rm -f $@; cp $*.sh $@; chmod +x $@ + +ifdef DIRS +$(DIRS):: + @if test -d $@; then \ + set $(EXIT_ON_ERROR); \ + echo "cd $@; $(MAKE)"; \ + cd $@; $(MAKE); \ + set +e; \ + else \ + echo "Skipping non-directory $@..."; \ + fi; \ + $(CLICK_STOPWATCH) +endif + +################################################################################ +# Bunch of things that extend the 'export' rule (in order): +################################################################################ + +$(JAVA_DESTPATH) $(JAVA_DESTPATH)/$(PACKAGE) $(JMCSRCDIR):: + @if test ! -d $@; then \ + echo Creating $@; \ + rm -rf $@; \ + $(NSINSTALL) -D $@; \ + fi + +################################################################################ +## IDL_GEN + +ifneq ($(IDL_GEN),) + +#export:: +# $(IDL2JAVA) $(IDL_GEN) + +#all:: export + +#clobber:: +# rm -f $(IDL_GEN:.idl=.class) # XXX wrong! + +endif + +################################################################################ +### JSRCS -- for compiling java files + +ifneq ($(JSRCS),) +export:: $(JAVA_DESTPATH) $(JAVA_DESTPATH)/$(PACKAGE) + @list=`perl $(NETLIBDEPTH)/coreconf/outofdate.pl $(PERLARG) \ + -d $(JAVA_DESTPATH)/$(PACKAGE) $(JSRCS)`; \ + if test "$$list"x != "x"; then \ + echo $(JAVAC) $$list; \ + $(JAVAC) $$list; \ + fi + +all:: export + +clobber:: + rm -f $(SOURCE_XP_DIR)/classes/$(PACKAGE)/*.class + +endif + +# +# JDIRS -- like JSRCS, except you can give a list of directories and it will +# compile all the out-of-date java files in those directories. +# +# NOTE: recursing through these can speed things up, but they also cause +# some builds to run out of memory +# +ifdef JDIRS +export:: $(JAVA_DESTPATH) $(JAVA_DESTPATH)/$(PACKAGE) + @for d in $(JDIRS); do \ + if test -d $$d; then \ + set $(EXIT_ON_ERROR); \ + files=`echo $$d/*.java`; \ + list=`perl $(NETLIBDEPTH)/coreconf/outofdate.pl $(PERLARG) \ + -d $(JAVA_DESTPATH)/$(PACKAGE) $$files`; \ + if test "$${list}x" != "x"; then \ + echo Building all java files in $$d; \ + echo $(JAVAC) $$list; \ + $(JAVAC) $$list; \ + fi; \ + set +e; \ + else \ + echo "Skipping non-directory $$d..."; \ + fi; \ + $(CLICK_STOPWATCH); \ + done +endif + +# +# JDK_GEN -- for generating "old style" native methods +# +# Generate JDK Headers and Stubs into the '_gen' and '_stubs' directory +# +ifneq ($(JDK_GEN),) +ifdef NSBUILDROOT + INCLUDES += -I$(JDK_GEN_DIR) -I$(SOURCE_XP_DIR) +else + INCLUDES += -I$(JDK_GEN_DIR) +endif +JDK_PACKAGE_CLASSES := $(JDK_GEN) +JDK_PATH_CLASSES := $(subst .,/,$(JDK_PACKAGE_CLASSES)) +JDK_HEADER_CLASSFILES := $(patsubst %,$(JAVA_DESTPATH)/%.class,$(JDK_PATH_CLASSES)) +JDK_STUB_CLASSFILES := $(patsubst %,$(JAVA_DESTPATH)/%.class,$(JDK_PATH_CLASSES)) +JDK_HEADER_CFILES := $(patsubst %,$(JDK_GEN_DIR)/%.h,$(JDK_GEN)) +JDK_STUB_CFILES := $(patsubst %,$(JDK_STUB_DIR)/%.c,$(JDK_GEN)) + +$(JDK_HEADER_CFILES): $(JDK_HEADER_CLASSFILES) +$(JDK_STUB_CFILES): $(JDK_STUB_CLASSFILES) + +export:: + @echo Generating/Updating JDK headers + $(JAVAH) -d $(JDK_GEN_DIR) $(JDK_PACKAGE_CLASSES) + @echo Generating/Updating JDK stubs + $(JAVAH) -stubs -d $(JDK_STUB_DIR) $(JDK_PACKAGE_CLASSES) +ifndef NO_MAC_JAVA_SHIT + @if test ! -d $(NETLIBDEPTH)/lib/mac/Java/; then \ + echo "!!! You need to have a ns/lib/mac/Java directory checked out."; \ + echo "!!! This allows us to automatically update generated files for the mac."; \ + echo "!!! If you see any modified files there, please check them in."; \ + fi + @echo Generating/Updating JDK headers for the Mac + $(JAVAH) -mac -d $(NETLIBDEPTH)/lib/mac/Java/_gen $(JDK_PACKAGE_CLASSES) + @echo Generating/Updating JDK stubs for the Mac + $(JAVAH) -mac -stubs -d $(NETLIBDEPTH)/lib/mac/Java/_stubs $(JDK_PACKAGE_CLASSES) +endif +endif + +# +# JRI_GEN -- for generating JRI native methods +# +# Generate JRI Headers and Stubs into the 'jri' directory +# +ifneq ($(JRI_GEN),) +ifdef NSBUILDROOT + INCLUDES += -I$(JRI_GEN_DIR) -I$(SOURCE_XP_DIR) +else + INCLUDES += -I$(JRI_GEN_DIR) +endif +JRI_PACKAGE_CLASSES := $(JRI_GEN) +JRI_PATH_CLASSES := $(subst .,/,$(JRI_PACKAGE_CLASSES)) +JRI_HEADER_CLASSFILES := $(patsubst %,$(JAVA_DESTPATH)/%.class,$(JRI_PATH_CLASSES)) +JRI_STUB_CLASSFILES := $(patsubst %,$(JAVA_DESTPATH)/%.class,$(JRI_PATH_CLASSES)) +JRI_HEADER_CFILES := $(patsubst %,$(JRI_GEN_DIR)/%.h,$(JRI_GEN)) +JRI_STUB_CFILES := $(patsubst %,$(JRI_GEN_DIR)/%.c,$(JRI_GEN)) + +$(JRI_HEADER_CFILES): $(JRI_HEADER_CLASSFILES) +$(JRI_STUB_CFILES): $(JRI_STUB_CLASSFILES) + +export:: + @echo Generating/Updating JRI headers + $(JAVAH) -jri -d $(JRI_GEN_DIR) $(JRI_PACKAGE_CLASSES) + @echo Generating/Updating JRI stubs + $(JAVAH) -jri -stubs -d $(JRI_GEN_DIR) $(JRI_PACKAGE_CLASSES) +ifndef NO_MAC_JAVA_SHIT + @if test ! -d $(NETLIBDEPTH)/lib/mac/Java/; then \ + echo "!!! You need to have a ns/lib/mac/Java directory checked out."; \ + echo "!!! This allows us to automatically update generated files for the mac."; \ + echo "!!! If you see any modified files there, please check them in."; \ + fi + @echo Generating/Updating JRI headers for the Mac + $(JAVAH) -jri -mac -d $(NETLIBDEPTH)/lib/mac/Java/_jri $(JRI_PACKAGE_CLASSES) + @echo Generating/Updating JRI stubs for the Mac + $(JAVAH) -jri -mac -stubs -d $(NETLIBDEPTH)/lib/mac/Java/_jri $(JRI_PACKAGE_CLASSES) +endif +endif + +# +# JMC_EXPORT -- for declaring which java classes are to be exported for jmc +# +ifneq ($(JMC_EXPORT),) +JMC_EXPORT_PATHS := $(subst .,/,$(JMC_EXPORT)) +JMC_EXPORT_FILES := $(patsubst %,$(JAVA_DESTPATH)/$(PACKAGE)/%.class,$(JMC_EXPORT_PATHS)) + +# +# We're doing NSINSTALL -t here (copy mode) because calling INSTALL will pick up +# your NSDISTMODE and make links relative to the current directory. This is a +# problem because the source isn't in the current directory: +# +export:: $(JMC_EXPORT_FILES) $(JMCSRCDIR) + $(NSINSTALL) -t -m 444 $(JMC_EXPORT_FILES) $(JMCSRCDIR) +endif + +# +# JMC_GEN -- for generating java modules +# +# Provide default export & install rules when using JMC_GEN +# +ifneq ($(JMC_GEN),) + INCLUDES += -I$(JMC_GEN_DIR) -I. + JMC_HEADERS := $(patsubst %,$(JMC_GEN_DIR)/%.h,$(JMC_GEN)) + JMC_STUBS := $(patsubst %,$(JMC_GEN_DIR)/%.c,$(JMC_GEN)) + JMC_OBJS := $(patsubst %,$(OBJDIR)/%$(OBJ_SUFFIX),$(JMC_GEN)) + +$(JMC_GEN_DIR)/M%.h: $(JMCSRCDIR)/%.class + $(JMC) -d $(JMC_GEN_DIR) -interface $(JMC_GEN_FLAGS) $(?F:.class=) + +$(JMC_GEN_DIR)/M%.c: $(JMCSRCDIR)/%.class + $(JMC) -d $(JMC_GEN_DIR) -module $(JMC_GEN_FLAGS) $(?F:.class=) + +$(OBJDIR)/M%$(OBJ_SUFFIX): $(JMC_GEN_DIR)/M%.h $(JMC_GEN_DIR)/M%.c + @$(MAKE_OBJDIR) + $(CC) -o $@ -c $(CFLAGS) $(JMC_GEN_DIR)/M$*.c + +export:: $(JMC_HEADERS) $(JMC_STUBS) +endif + +# +# Copy each element of EXPORTS to $(SOURCE_XP_DIR)/public/$(MODULE)/ +# +ifneq ($(EXPORTS),) +$(SOURCE_XP_DIR)/public/$(MODULE):: + @if test ! -d $@; then \ + echo Creating $@; \ + $(NSINSTALL) -D $@; \ + fi + +export:: $(EXPORTS) $(SOURCE_XP_DIR)/public/$(MODULE) + $(INSTALL) -m 444 $(EXPORTS) $(SOURCE_XP_DIR)/public/$(MODULE) +endif + +# Duplicate export rule for private exports, with different directories + +ifneq ($(PRIVATE_EXPORTS),) +$(SOURCE_XP_DIR)/private/$(MODULE):: + @if test ! -d $@; then \ + echo Creating $@; \ + $(NSINSTALL) -D $@; \ + fi + +private_export:: $(PRIVATE_EXPORTS) $(SOURCE_XP_DIR)/private/$(MODULE) + $(INSTALL) -m 444 $(PRIVATE_EXPORTS) $(SOURCE_XP_DIR)/private/$(MODULE) +else +private_export:: +endif + +# Duplicate export rule for releases, with different directories + +ifneq ($(EXPORTS),) +$(SOURCE_XP_DIR)/release/include:: + @if test ! -d $@; then \ + echo Creating $@; \ + $(NSINSTALL) -D $@; \ + fi + +release_export:: $(EXPORTS) $(SOURCE_XP_DIR)/release/include + $(INSTALL) -m 444 $(EXPORTS) $(SOURCE_XP_DIR)/release/include +endif + + + + +################################################################################ + +-include $(DEPENDENCIES) + +ifneq ($(OS_ARCH),WINNT) +# Can't use sed because of its 4000-char line length limit, so resort to perl +.DEFAULT: + @perl -e ' \ + open(MD, "< $(DEPENDENCIES)"); \ + while () { \ + if (m@ \.*/*$< @) { \ + $$found = 1; \ + last; \ + } \ + } \ + if ($$found) { \ + print "Removing stale dependency $< from $(DEPENDENCIES)\n"; \ + seek(MD, 0, 0); \ + $$tmpname = "$(OBJDIR)/fix.md" . $$$$; \ + open(TMD, "> " . $$tmpname); \ + while () { \ + s@ \.*/*$< @ @; \ + if (!print TMD "$$_") { \ + unlink(($$tmpname)); \ + exit(1); \ + } \ + } \ + close(TMD); \ + if (!rename($$tmpname, "$(DEPENDENCIES)")) { \ + unlink(($$tmpname)); \ + } \ + } elsif ("$<" ne "$(DEPENDENCIES)") { \ + print "$(MAKE): *** No rule to make target $<. Stop.\n"; \ + exit(1); \ + }' +endif + +############################################################################# +# X dependency system +############################################################################# + +$(MKDEPENDENCIES): $(CSRCS) $(CPPSRCS) $(ASFILES) Makefile \ + manifest.mn $(EXPORTS) $(LOCAL_EXPORTS) + @$(MAKE_OBJDIR) + touch $(MKDEPENDENCIES) + $(MKDEPEND) -p$(OBJDIR_NAME)/ -o'$(OBJ_SUFFIX)' -f$(MKDEPENDENCIES) $(INCLUDES) $(CSRCS) $(CPPSRCS) $(ASFILES) + +$(MKDEPEND): + cd $(MKDEPEND_DIR); $(MAKE) + +ifdef OBJS +depend:: $(MKDEPEND) $(MKDEPENDENCIES) +else +depend:: +endif + +$(LOOP_OVER_DIRS) + +dependclean:: + rm -f $(MKDEPENDENCIES) + +$(LOOP_OVER_DIR) + +# CUR_DIR is neccesary since it seems to crash gmake otherwise +CUR_DIR = $(shell pwd) + +ifndef NO_IMPLICIT_DEPENDENCIES + +ifdef OBJS +libs:: $(MKDEPENDENCIES) +endif + +endif + +#ifneq ($(filter *.mk,$(wildcard $(CUR_DIR)/$(OBJDIR)/depend.mk)),) +-include $(CUR_DIR)/$(OBJDIR)/depend.mk +#endif + + +################################################################################ +# Special gmake rules. +################################################################################ + +# +# Re-define the list of default suffixes, so gmake won't have to churn through +# hundreds of built-in suffix rules for stuff we don't need. +# +.SUFFIXES: +.SUFFIXES: .out .a .ln .o .obj .c .cc .C .cpp .y .l .s .S .h .sh .i .pl .class .java .html + +# +# Don't delete these files if we get killed. +# +.PRECIOUS: .java $(JDK_HEADERS) $(JDK_STUBS) $(JRI_HEADERS) $(JRI_STUBS) $(JMC_HEADERS) $(JMC_STUBS) + +# +# Fake targets. Always run these rules, even if a file/directory with that +# name already exists. +# +.PHONY: all all_platforms alltags boot clean clobber clobber_all export install libs realclean release $(OBJDIR) $(DIRS) + diff --git a/ef/config/genburg.bat b/ef/config/genburg.bat new file mode 100755 index 000000000000..bda01fac1c00 --- /dev/null +++ b/ef/config/genburg.bat @@ -0,0 +1 @@ +perl %2 %3 %4 %4.h %4.cpp %3.burg.h | %1 -I -o %3.burg.cpp diff --git a/ef/config/mkdepend/Makefile b/ef/config/mkdepend/Makefile new file mode 100644 index 000000000000..c20f44728e8f --- /dev/null +++ b/ef/config/mkdepend/Makefile @@ -0,0 +1,39 @@ +#! gmake +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +DEPTH = ../.. + +PROGRAM = mkdepend + +include $(DEPTH)/config/config.mk + +CSRCS = \ + cppsetup.c \ + ifparser.c \ + include.c \ + main.c \ + parse.c \ + pr.c \ + $(NULL) + +CFLAGS += -DINCLUDEDIR=\"/usr/include\" -DOBJSUFFIX=\".$(OBJ_SUFFIX)\" -DNeedVarargsPrototypes +MKDEPENDENCIES = + +include $(DEPTH)/config/rules.mk + +program:: $(PROGRAM) + diff --git a/ef/config/mkdepend/cppsetup.c b/ef/config/mkdepend/cppsetup.c new file mode 100644 index 000000000000..d56bb5b1c632 --- /dev/null +++ b/ef/config/mkdepend/cppsetup.c @@ -0,0 +1,243 @@ +/* $XConsortium: cppsetup.c,v 1.13 94/04/17 20:10:32 gildea Exp $ */ +/* + +Copyright (c) 1993, 1994 X Consortium + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of the X Consortium shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from the X Consortium. + +*/ + +#include "def.h" + +#ifdef CPP +/* + * This file is strictly for the sake of cpy.y and yylex.c (if + * you indeed have the source for cpp). + */ +#define IB 1 +#define SB 2 +#define NB 4 +#define CB 8 +#define QB 16 +#define WB 32 +#define SALT '#' +#if pdp11 | vax | ns16000 | mc68000 | ibm032 +#define COFF 128 +#else +#define COFF 0 +#endif +/* + * These variables used by cpy.y and yylex.c + */ +extern char *outp, *inp, *newp, *pend; +extern char *ptrtab; +extern char fastab[]; +extern char slotab[]; + +/* + * cppsetup + */ +struct filepointer *currentfile; +struct inclist *currentinc; + +int cppsetup(line, filep, inc) + register char *line; + register struct filepointer *filep; + register struct inclist *inc; +{ + register char *p, savec; + static boolean setupdone = FALSE; + boolean value; + + if (!setupdone) { + cpp_varsetup(); + setupdone = TRUE; + } + + currentfile = filep; + currentinc = inc; + inp = newp = line; + for (p=newp; *p; p++) + ; + + /* + * put a newline back on the end, and set up pend, etc. + */ + *p++ = '\n'; + savec = *p; + *p = '\0'; + pend = p; + + ptrtab = slotab+COFF; + *--inp = SALT; + outp=inp; + value = yyparse(); + *p = savec; + return(value); +} + +struct symtab *lookup(symbol) + char *symbol; +{ + static struct symtab undefined; + struct symtab *sp; + + sp = isdefined(symbol, currentinc, NULL); + if (sp == NULL) { + sp = &undefined; + sp->s_value = NULL; + } + return (sp); +} + +pperror(tag, x0,x1,x2,x3,x4) + int tag,x0,x1,x2,x3,x4; +{ + warning("\"%s\", line %d: ", currentinc->i_file, currentfile->f_line); + warning(x0,x1,x2,x3,x4); +} + + +yyerror(s) + register char *s; +{ + fatalerr("Fatal error: %s\n", s); +} +#else /* not CPP */ + +#include "ifparser.h" +struct _parse_data { + struct filepointer *filep; + struct inclist *inc; + const char *line; +}; + +static const char * +_my_if_errors (ip, cp, expecting) + IfParser *ip; + const char *cp; + const char *expecting; +{ + struct _parse_data *pd = (struct _parse_data *) ip->data; + int lineno = pd->filep->f_line; + char *filename = pd->inc->i_file; + char prefix[300]; + int prefixlen; + int i; + + sprintf (prefix, "\"%s\":%d", filename, lineno); + prefixlen = strlen(prefix); + fprintf (stderr, "%s: %s", prefix, pd->line); + i = cp - pd->line; + if (i > 0 && pd->line[i-1] != '\n') { + putc ('\n', stderr); + } + for (i += prefixlen + 3; i > 0; i--) { + putc (' ', stderr); + } + fprintf (stderr, "^--- expecting %s\n", expecting); + return NULL; +} + + +#define MAXNAMELEN 256 + +static struct symtab * +_lookup_variable (ip, var, len) + IfParser *ip; + const char *var; + int len; +{ + char tmpbuf[MAXNAMELEN + 1]; + struct _parse_data *pd = (struct _parse_data *) ip->data; + + if (len > MAXNAMELEN) + return 0; + + strncpy (tmpbuf, var, len); + tmpbuf[len] = '\0'; + return isdefined (tmpbuf, pd->inc, NULL); +} + + +static int +_my_eval_defined (ip, var, len) + IfParser *ip; + const char *var; + int len; +{ + if (_lookup_variable (ip, var, len)) + return 1; + else + return 0; +} + +#define isvarfirstletter(ccc) (isalpha(ccc) || (ccc) == '_') + +static int +_my_eval_variable (ip, var, len) + IfParser *ip; + const char *var; + int len; +{ + struct symtab *s; + + s = _lookup_variable (ip, var, len); + if (!s) + return 0; + do { + var = s->s_value; + if (!isvarfirstletter(*var)) + break; + s = _lookup_variable (ip, var, strlen(var)); + } while (s); + + return atoi(var); +} + + +int +cppsetup(line, filep, inc) + register char *line; + register struct filepointer *filep; + register struct inclist *inc; +{ + IfParser ip; + struct _parse_data pd; + int val = 0; + + pd.filep = filep; + pd.inc = inc; + pd.line = line; + ip.funcs.handle_error = _my_if_errors; + ip.funcs.eval_defined = _my_eval_defined; + ip.funcs.eval_variable = _my_eval_variable; + ip.data = (char *) &pd; + + (void) ParseIfExpression (&ip, line, &val); + if (val) + return IF; + else + return IFFALSE; +} +#endif /* CPP */ + diff --git a/ef/config/mkdepend/def.h b/ef/config/mkdepend/def.h new file mode 100644 index 000000000000..8d45f2f6d8da --- /dev/null +++ b/ef/config/mkdepend/def.h @@ -0,0 +1,157 @@ +/* $XConsortium: def.h,v 1.25 94/04/17 20:10:33 gildea Exp $ */ +/* + +Copyright (c) 1993, 1994 X Consortium + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of the X Consortium shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from the X Consortium. + +*/ + +#include +#include +#include +#include +#include +#include +#include + +#define MAXDEFINES 512 +#define MAXFILES 1024 /* Increased from 512. -mcafee */ +#define MAXDIRS 64 +#define SYMTABINC 10 /* must be > 1 for define() to work right */ +#define TRUE 1 +#define FALSE 0 + +/* the following must match the directives table in main.c */ +#define IF 0 +#define IFDEF 1 +#define IFNDEF 2 +#define ELSE 3 +#define ENDIF 4 +#define DEFINE 5 +#define UNDEF 6 +#define INCLUDE 7 +#define LINE 8 +#define PRAGMA 9 +#define ERROR 10 +#define IDENT 11 +#define SCCS 12 +#define ELIF 13 +#define EJECT 14 +#define IFFALSE 15 /* pseudo value --- never matched */ +#define ELIFFALSE 16 /* pseudo value --- never matched */ +#define INCLUDEDOT 17 /* pseudo value --- never matched */ +#define IFGUESSFALSE 18 /* pseudo value --- never matched */ +#define ELIFGUESSFALSE 19 /* pseudo value --- never matched */ + +#ifdef DEBUG +extern int _debugmask; +/* + * debug levels are: + * + * 0 show ifn*(def)*,endif + * 1 trace defined/!defined + * 2 show #include + * 3 show #include SYMBOL + * 4-6 unused + */ +#define debug(level,arg) { if (_debugmask & (1 << level)) warning arg; } +#else +#define debug(level,arg) /**/ +#endif /* DEBUG */ + +typedef unsigned char boolean; + +struct symtab { + char *s_name; + char *s_value; +}; + +struct inclist { + char *i_incstring; /* string from #include line */ + char *i_file; /* path name of the include file */ + struct inclist **i_list; /* list of files it itself includes */ + int i_listlen; /* length of i_list */ + struct symtab *i_defs; /* symbol table for this file */ + int i_ndefs; /* current # defines */ + int i_deflen; /* amount of space in table */ + boolean i_defchecked; /* whether defines have been checked */ + boolean i_notified; /* whether we have revealed includes */ + boolean i_marked; /* whether it's in the makefile */ + boolean i_searched; /* whether we have read this */ + boolean i_included_sym; /* whether #include SYMBOL was found */ + /* Can't use i_list if TRUE */ +}; + +struct filepointer { + char *f_p; + char *f_base; + char *f_end; + long f_len; + long f_line; +}; + +#ifndef X_NOT_STDC_ENV +#include +#if defined(macII) && !defined(__STDC__) /* stdlib.h fails to define these */ +char *malloc(), *realloc(); +#endif /* macII */ +#else +char *malloc(); +char *realloc(); +#endif + +char *copy(); +char *base_name(); +char *getline(); +struct symtab *slookup(); +struct symtab *isdefined(); +struct symtab *fdefined(); +struct filepointer *getfile(); +struct inclist *newinclude(); +struct inclist *inc_path(); +void remove_dotdot(char *path); +int isdot(char *p); +int isdotdot(char *p); +int issymbolic(char *dir, char *component); +void define2(char *name, char *val, struct inclist *file); +void pr(struct inclist *ip, char *file, char *base); +void included_by(struct inclist *ip, struct inclist *newfile); +int find_includes(struct filepointer *filep, struct inclist *file, struct inclist *file_red, int recursion, boolean failOK); +void freefile(struct filepointer *fp); +int deftype (char *line, struct filepointer *filep, struct inclist *file_red, struct inclist *file, int parse_it); +void recursive_pr_include(struct inclist *head, char *file, char *base); +void inc_clean (); +void define(char *def, struct inclist *file); +void redirect(char *line, char *makefile); +int gobble(struct filepointer *filep, struct inclist *file, struct inclist *file_red); +void undefine(char *symbol, struct inclist *file); +void add_include(struct filepointer *filep, struct inclist *file, struct inclist *file_red, char *include, boolean dot, int failOK); +int match(char *str, char **list); +int zero_value(char *exp, struct filepointer *filep, struct inclist *file_red); +int cppsetup(char *line, struct filepointer *filep, struct inclist *inc); + +#if NeedVarargsPrototypes +extern void fatalerr(char *, ...); +extern void warning(char *, ...); +extern void warning1(char *, ...); +#endif diff --git a/ef/config/mkdepend/ifparser.c b/ef/config/mkdepend/ifparser.c new file mode 100644 index 000000000000..23dbc92b9f1f --- /dev/null +++ b/ef/config/mkdepend/ifparser.c @@ -0,0 +1,462 @@ +/* + * $XConsortium: ifparser.c,v 1.8 95/06/03 00:01:41 gildea Exp $ + * + * Copyright 1992 Network Computing Devices, Inc. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose and without fee is hereby granted, provided + * that the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Network Computing Devices may not be + * used in advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. Network Computing Devices makes + * no representations about the suitability of this software for any purpose. + * It is provided ``as is'' without express or implied warranty. + * + * NETWORK COMPUTING DEVICES DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, + * IN NO EVENT SHALL NETWORK COMPUTING DEVICES BE LIABLE FOR ANY SPECIAL, + * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + * Author: Jim Fulton + * Network Computing Devices, Inc. + * + * Simple if statement processor + * + * This module can be used to evaluate string representations of C language + * if constructs. It accepts the following grammar: + * + * EXPRESSION := VALUE + * | VALUE BINOP EXPRESSION + * + * VALUE := '(' EXPRESSION ')' + * | '!' VALUE + * | '-' VALUE + * | 'defined' '(' variable ')' + * | 'defined' variable + * | # variable '(' variable-list ')' + * | variable + * | number + * + * BINOP := '*' | '/' | '%' + * | '+' | '-' + * | '<<' | '>>' + * | '<' | '>' | '<=' | '>=' + * | '==' | '!=' + * | '&' | '|' + * | '&&' | '||' + * + * The normal C order of precidence is supported. + * + * + * External Entry Points: + * + * ParseIfExpression parse a string for #if + */ + +#include +#include +#include "ifparser.h" +#include + +extern int remove_dotdot(char *path); + +/**************************************************************************** + Internal Macros and Utilities for Parser + ****************************************************************************/ + +#define DO(val) if (!(val)) return NULL +#define CALLFUNC(ggg,fff) (*((ggg)->funcs.fff)) +#define SKIPSPACE(ccc) while (isspace(*ccc)) ccc++ +#define isvarfirstletter(ccc) (isalpha(ccc) || (ccc) == '_') + + +static const char * +parse_variable (g, cp, varp) + IfParser *g; + const char *cp; + const char **varp; +{ + SKIPSPACE (cp); + + if (!isvarfirstletter (*cp)) + return CALLFUNC(g, handle_error) (g, cp, "variable name"); + + *varp = cp; + /* EMPTY */ + for (cp++; isalnum(*cp) || *cp == '_'; cp++) ; + return cp; +} + + +static const char * +parse_number (g, cp, valp) + IfParser *g; + const char *cp; + int *valp; +{ + SKIPSPACE (cp); + + if (!isdigit(*cp)) + return CALLFUNC(g, handle_error) (g, cp, "number"); + +#ifdef WIN32 + *valp = strtol(cp, &cp, 0); +#else + *valp = atoi (cp); + /* EMPTY */ + for (cp++; isdigit(*cp); cp++) ; +#endif + return cp; +} + + +static const char * +parse_value (g, cp, valp) + IfParser *g; + const char *cp; + int *valp; +{ + const char *var; + + *valp = 0; + + SKIPSPACE (cp); + if (!*cp) + return cp; + + switch (*cp) { + case '(': + DO (cp = ParseIfExpression (g, cp + 1, valp)); + SKIPSPACE (cp); + if (*cp == '?') + while (*cp != ')') + cp++; + + if (*cp != ')') + return CALLFUNC(g, handle_error) (g, cp, ")"); + + return cp + 1; /* skip the right paren */ + + case '!': + DO (cp = parse_value (g, cp + 1, valp)); + *valp = !(*valp); + return cp; + + case '-': + DO (cp = parse_value (g, cp + 1, valp)); + *valp = -(*valp); + return cp; + + case '#': + DO (cp = parse_variable (g, cp + 1, &var)); + SKIPSPACE (cp); + if (*cp != '(') + return CALLFUNC(g, handle_error) (g, cp, "("); + do { + DO (cp = parse_variable (g, cp + 1, &var)); + SKIPSPACE (cp); + } while (*cp && *cp != ')'); + if (*cp != ')') + return CALLFUNC(g, handle_error) (g, cp, ")"); + *valp = 1; /* XXX */ + return cp + 1; + + case 'd': + if (strncmp (cp, "defined", 7) == 0 && !isalnum(cp[7])) { + int paren = 0; + int len; + + cp += 7; + SKIPSPACE (cp); + if (*cp == '(') { + paren = 1; + cp++; + } + DO (cp = parse_variable (g, cp, &var)); + len = cp - var; + SKIPSPACE (cp); + if (paren && *cp != ')') + return CALLFUNC(g, handle_error) (g, cp, ")"); + *valp = (*(g->funcs.eval_defined)) (g, var, len); + return cp + paren; /* skip the right paren */ + } + /* fall out */ + } + + if (isdigit(*cp)) { + DO (cp = parse_number (g, cp, valp)); + } else if (!isvarfirstletter(*cp)) + return CALLFUNC(g, handle_error) (g, cp, "variable or number"); + else { + DO (cp = parse_variable (g, cp, &var)); + *valp = (*(g->funcs.eval_variable)) (g, var, cp - var); + } + + return cp; +} + + + +static const char * +parse_product (g, cp, valp) + IfParser *g; + const char *cp; + int *valp; +{ + int rightval; + + DO (cp = parse_value (g, cp, valp)); + SKIPSPACE (cp); + + switch (*cp) { + case '*': + DO (cp = parse_product (g, cp + 1, &rightval)); + *valp = (*valp * rightval); + break; + + case '/': + DO (cp = parse_product (g, cp + 1, &rightval)); + *valp = (*valp / rightval); + break; + + case '%': + DO (cp = parse_product (g, cp + 1, &rightval)); + *valp = (*valp % rightval); + break; + } + return cp; +} + + +static const char * +parse_sum (g, cp, valp) + IfParser *g; + const char *cp; + int *valp; +{ + int rightval; + + DO (cp = parse_product (g, cp, valp)); + SKIPSPACE (cp); + + switch (*cp) { + case '+': + DO (cp = parse_sum (g, cp + 1, &rightval)); + *valp = (*valp + rightval); + break; + + case '-': + DO (cp = parse_sum (g, cp + 1, &rightval)); + *valp = (*valp - rightval); + break; + } + return cp; +} + + +static const char * +parse_shift (g, cp, valp) + IfParser *g; + const char *cp; + int *valp; +{ + int rightval; + + DO (cp = parse_sum (g, cp, valp)); + SKIPSPACE (cp); + + switch (*cp) { + case '<': + if (cp[1] == '<') { + DO (cp = parse_shift (g, cp + 2, &rightval)); + *valp = (*valp << rightval); + } + break; + + case '>': + if (cp[1] == '>') { + DO (cp = parse_shift (g, cp + 2, &rightval)); + *valp = (*valp >> rightval); + } + break; + } + return cp; +} + + +static const char * +parse_inequality (g, cp, valp) + IfParser *g; + const char *cp; + int *valp; +{ + int rightval; + + DO (cp = parse_shift (g, cp, valp)); + SKIPSPACE (cp); + + switch (*cp) { + case '<': + if (cp[1] == '=') { + DO (cp = parse_inequality (g, cp + 2, &rightval)); + *valp = (*valp <= rightval); + } else { + DO (cp = parse_inequality (g, cp + 1, &rightval)); + *valp = (*valp < rightval); + } + break; + + case '>': + if (cp[1] == '=') { + DO (cp = parse_inequality (g, cp + 2, &rightval)); + *valp = (*valp >= rightval); + } else { + DO (cp = parse_inequality (g, cp + 1, &rightval)); + *valp = (*valp > rightval); + } + break; + } + return cp; +} + + +static const char * +parse_equality (g, cp, valp) + IfParser *g; + const char *cp; + int *valp; +{ + int rightval; + + DO (cp = parse_inequality (g, cp, valp)); + SKIPSPACE (cp); + + switch (*cp) { + case '=': + if (cp[1] == '=') + cp++; + DO (cp = parse_equality (g, cp + 1, &rightval)); + *valp = (*valp == rightval); + break; + + case '!': + if (cp[1] != '=') + break; + DO (cp = parse_equality (g, cp + 2, &rightval)); + *valp = (*valp != rightval); + break; + } + return cp; +} + + +static const char * +parse_band (g, cp, valp) + IfParser *g; + const char *cp; + int *valp; +{ + int rightval; + + DO (cp = parse_equality (g, cp, valp)); + SKIPSPACE (cp); + + switch (*cp) { + case '&': + if (cp[1] != '&') { + DO (cp = parse_band (g, cp + 1, &rightval)); + *valp = (*valp & rightval); + } + break; + } + return cp; +} + + +static const char * +parse_bor (g, cp, valp) + IfParser *g; + const char *cp; + int *valp; +{ + int rightval; + + DO (cp = parse_band (g, cp, valp)); + SKIPSPACE (cp); + + switch (*cp) { + case '|': + if (cp[1] != '|') { + DO (cp = parse_bor (g, cp + 1, &rightval)); + *valp = (*valp | rightval); + } + break; + } + return cp; +} + + +static const char * +parse_land (g, cp, valp) + IfParser *g; + const char *cp; + int *valp; +{ + int rightval; + + DO (cp = parse_bor (g, cp, valp)); + SKIPSPACE (cp); + + switch (*cp) { + case '&': + if (cp[1] != '&') + return CALLFUNC(g, handle_error) (g, cp, "&&"); + DO (cp = parse_land (g, cp + 2, &rightval)); + *valp = (*valp && rightval); + break; + } + return cp; +} + + +static const char * +parse_lor (g, cp, valp) + IfParser *g; + const char *cp; + int *valp; +{ + int rightval; + + DO (cp = parse_land (g, cp, valp)); + SKIPSPACE (cp); + + switch (*cp) { + case '|': + if (cp[1] != '|') + return CALLFUNC(g, handle_error) (g, cp, "||"); + DO (cp = parse_lor (g, cp + 2, &rightval)); + *valp = (*valp || rightval); + break; + } + return cp; +} + + +/**************************************************************************** + External Entry Points + ****************************************************************************/ + +const char * +ParseIfExpression (g, cp, valp) + IfParser *g; + const char *cp; + int *valp; +{ + return parse_lor (g, cp, valp); +} + + diff --git a/ef/config/mkdepend/ifparser.h b/ef/config/mkdepend/ifparser.h new file mode 100644 index 000000000000..c3337982262f --- /dev/null +++ b/ef/config/mkdepend/ifparser.h @@ -0,0 +1,76 @@ +/* + * $XConsortium: ifparser.h,v 1.1 92/08/22 13:05:39 rws Exp $ + * + * Copyright 1992 Network Computing Devices, Inc. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose and without fee is hereby granted, provided + * that the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Network Computing Devices may not be + * used in advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. Network Computing Devices makes + * no representations about the suitability of this software for any purpose. + * It is provided ``as is'' without express or implied warranty. + * + * NETWORK COMPUTING DEVICES DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, + * IN NO EVENT SHALL NETWORK COMPUTING DEVICES BE LIABLE FOR ANY SPECIAL, + * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + * Author: Jim Fulton + * Network Computing Devices, Inc. + * + * Simple if statement processor + * + * This module can be used to evaluate string representations of C language + * if constructs. It accepts the following grammar: + * + * EXPRESSION := VALUE + * | VALUE BINOP EXPRESSION + * + * VALUE := '(' EXPRESSION ')' + * | '!' VALUE + * | '-' VALUE + * | 'defined' '(' variable ')' + * | variable + * | number + * + * BINOP := '*' | '/' | '%' + * | '+' | '-' + * | '<<' | '>>' + * | '<' | '>' | '<=' | '>=' + * | '==' | '!=' + * | '&' | '|' + * | '&&' | '||' + * + * The normal C order of precidence is supported. + * + * + * External Entry Points: + * + * ParseIfExpression parse a string for #if + */ + +#include + +#define const /**/ +typedef int Bool; +#define False 0 +#define True 1 + +typedef struct _if_parser { + struct { /* functions */ + char *(*handle_error) (/* struct _if_parser *, const char *, + const char * */); + int (*eval_variable) (/* struct _if_parser *, const char *, int */); + int (*eval_defined) (/* struct _if_parser *, const char *, int */); + } funcs; + char *data; +} IfParser; + +char *ParseIfExpression (/* IfParser *, const char *, int * */); + diff --git a/ef/config/mkdepend/imakemdep.h b/ef/config/mkdepend/imakemdep.h new file mode 100644 index 000000000000..3487c3c7ab01 --- /dev/null +++ b/ef/config/mkdepend/imakemdep.h @@ -0,0 +1,727 @@ + +/* $XConsortium: imakemdep.h,v 1.83 95/04/07 19:47:46 kaleb Exp $ */ +/* $XFree86: xc/config/imake/imakemdep.h,v 3.12 1995/07/08 10:22:17 dawes Exp $ */ +/* + +Copyright (c) 1993, 1994 X Consortium + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of the X Consortium shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from the X Consortium. + +*/ + + +/* + * This file contains machine-dependent constants for the imake utility. + * When porting imake, read each of the steps below and add in any necessary + * definitions. In general you should *not* edit ccimake.c or imake.c! + */ + +#ifdef CCIMAKE +/* + * Step 1: imake_ccflags + * Define any special flags that will be needed to get imake.c to compile. + * These will be passed to the compile along with the contents of the + * make variable BOOTSTRAPCFLAGS. + */ +#ifdef hpux +#ifdef hp9000s800 +#define imake_ccflags "-DSYSV" +#else +#define imake_ccflags "-Wc,-Nd4000,-Ns3000 -DSYSV" +#endif +#endif + +#if defined(macII) || defined(_AUX_SOURCE) +#define imake_ccflags "-DmacII -DSYSV" +#endif + +#ifdef stellar +#define imake_ccflags "-DSYSV" +#endif + +#if defined(USL) || defined(Oki) || defined(NCR) +#define imake_ccflags "-Xc -DSVR4" +#endif + +#ifdef sony +#if defined(SYSTYPE_SYSV) || defined(_SYSTYPE_SYSV) +#define imake_ccflags "-DSVR4" +#else +#include +#if NEWSOS < 41 +#define imake_ccflags "-Dbsd43 -DNOSTDHDRS" +#else +#if NEWSOS < 42 +#define imake_ccflags "-Dbsd43" +#endif +#endif +#endif +#endif + +#ifdef _CRAY +#define imake_ccflags "-DSYSV -DUSG" +#endif + +#if defined(_IBMR2) || defined(aix) +#define imake_ccflags "-Daix -DSYSV" +#endif + +#ifdef Mips +# if defined(SYSTYPE_BSD) || defined(BSD) || defined(BSD43) +# define imake_ccflags "-DBSD43" +# else +# define imake_ccflags "-DSYSV" +# endif +#endif + +#ifdef is68k +#define imake_ccflags "-Dluna -Duniosb" +#endif + +#ifdef SYSV386 +# ifdef SVR4 +# define imake_ccflags "-Xc -DSVR4" +# else +# define imake_ccflags "-DSYSV" +# endif +#endif + +#ifdef SVR4 +# ifdef i386 +# define imake_ccflags "-Xc -DSVR4" +# endif +#endif + +#ifdef SYSV +# ifdef i386 +# define imake_ccflags "-DSYSV" +# endif +#endif + +#ifdef __convex__ +#define imake_ccflags "-fn -tm c1" +#endif + +#ifdef apollo +#define imake_ccflags "-DX_NOT_POSIX" +#endif + +#ifdef WIN32 +#define imake_ccflags "-nologo -batch -D__STDC__" +#endif + +#ifdef __uxp__ +#define imake_ccflags "-DSVR4 -DANSICPP" +#endif + +#ifdef __sxg__ +#define imake_ccflags "-DSYSV -DUSG -DNOSTDHDRS" +#endif + +#ifdef sequent +#define imake_ccflags "-DX_NOT_STDC_ENV -DX_NOT_POSIX" +#endif + +#ifdef _SEQUENT_ +#define imake_ccflags "-DSYSV -DUSG" +#endif + +#if defined(SX) || defined(PC_UX) +#define imake_ccflags "-DSYSV" +#endif + +#ifdef nec_ews_svr2 +#define imake_ccflags "-DUSG" +#endif + +#if defined(nec_ews_svr4) || defined(_nec_ews_svr4) || defined(_nec_up) || defined(_nec_ft) +#define imake_ccflags "-DSVR4" +#endif + +#ifdef MACH +#define imake_ccflags "-DNOSTDHDRS" +#endif + +/* this is for OS/2 under EMX. This won't work with DOS */ +#if defined(__EMX__) +#define imake_ccflags "-DBSD43" +#endif + +#else /* not CCIMAKE */ +#ifndef MAKEDEPEND +/* + * Step 2: dup2 + * If your OS doesn't have a dup2() system call to duplicate one file + * descriptor onto another, define such a mechanism here (if you don't + * already fall under the existing category(ies). + */ +#if defined(SYSV) && !defined(_CRAY) && !defined(Mips) && !defined(_SEQUENT_) +#define dup2(fd1,fd2) ((fd1 == fd2) ? fd1 : (close(fd2), \ + fcntl(fd1, F_DUPFD, fd2))) +#endif + + +/* + * Step 3: FIXUP_CPP_WHITESPACE + * If your cpp collapses tabs macro expansions into a single space and + * replaces escaped newlines with a space, define this symbol. This will + * cause imake to attempt to patch up the generated Makefile by looking + * for lines that have colons in them (this is why the rules file escapes + * all colons). One way to tell if you need this is to see whether or not + * your Makefiles have no tabs in them and lots of @@ strings. + */ +#if defined(sun) || defined(SYSV) || defined(SVR4) || defined(hcx) || defined(WIN32) || (defined(AMOEBA) && defined(CROSS_COMPILE)) +#define FIXUP_CPP_WHITESPACE +#endif +#ifdef WIN32 +#define REMOVE_CPP_LEADSPACE +#define INLINE_SYNTAX +#define MAGIC_MAKE_VARS +#endif +#ifdef __minix_vmd +#define FIXUP_CPP_WHITESPACE +#endif + +/* + * Step 4: USE_CC_E, DEFAULT_CC, DEFAULT_CPP + * If you want to use cc -E instead of cpp, define USE_CC_E. + * If use cc -E but want a different compiler, define DEFAULT_CC. + * If the cpp you need is not in /lib/cpp, define DEFAULT_CPP. + */ +#ifdef hpux +#define USE_CC_E +#endif +#ifdef WIN32 +#define USE_CC_E +#define DEFAULT_CC "cl" +#endif +#ifdef apollo +#define DEFAULT_CPP "/usr/lib/cpp" +#endif +#if defined(_IBMR2) && !defined(DEFAULT_CPP) +#define DEFAULT_CPP "/usr/lpp/X11/Xamples/util/cpp/cpp" +#endif +#if defined(sun) && defined(SVR4) +#define DEFAULT_CPP "/usr/ccs/lib/cpp" +#endif +#ifdef __bsdi__ +#define DEFAULT_CPP "/usr/bin/cpp" +#endif +#ifdef __uxp__ +#define DEFAULT_CPP "/usr/ccs/lib/cpp" +#endif +#ifdef __sxg__ +#define DEFAULT_CPP "/usr/lib/cpp" +#endif +#ifdef _CRAY +#define DEFAULT_CPP "/lib/pcpp" +#endif +#if defined(__386BSD__) || defined(__NetBSD__) || defined(__FreeBSD__) +#define DEFAULT_CPP "/usr/libexec/cpp" +#endif +#ifdef MACH +#define USE_CC_E +#endif +#ifdef __minix_vmd +#define DEFAULT_CPP "/usr/lib/cpp" +#endif +#if defined(__EMX__) +/* expects cpp in PATH */ +#define DEFAULT_CPP "cpp" +#endif + +/* + * Step 5: cpp_argv + * The following table contains the flags that should be passed + * whenever a Makefile is being generated. If your preprocessor + * doesn't predefine any unique symbols, choose one and add it to the + * end of this table. Then, do the following: + * + * a. Use this symbol in Imake.tmpl when setting MacroFile. + * b. Put this symbol in the definition of BootstrapCFlags in your + * .cf file. + * c. When doing a make World, always add "BOOTSTRAPCFLAGS=-Dsymbol" + * to the end of the command line. + * + * Note that you may define more than one symbol (useful for platforms + * that support multiple operating systems). + */ + +#define ARGUMENTS 50 /* number of arguments in various arrays */ +char *cpp_argv[ARGUMENTS] = { + "cc", /* replaced by the actual program to exec */ + "-I.", /* add current directory to include path */ +#ifdef unix + "-Uunix", /* remove unix symbol so that filename unix.c okay */ +#endif +#if defined(__386BSD__) || defined(__NetBSD__) || defined(__FreeBSD__) || defined(MACH) +# ifdef __i386__ + "-D__i386__", +# endif +# ifdef __GNUC__ + "-traditional", +# endif +#endif +#ifdef M4330 + "-DM4330", /* Tektronix */ +#endif +#ifdef M4310 + "-DM4310", /* Tektronix */ +#endif +#if defined(macII) || defined(_AUX_SOURCE) + "-DmacII", /* Apple A/UX */ +#endif +#ifdef USL + "-DUSL", /* USL */ +#endif +#ifdef sony + "-Dsony", /* Sony */ +#if !defined(SYSTYPE_SYSV) && !defined(_SYSTYPE_SYSV) && NEWSOS < 42 + "-Dbsd43", +#endif +#endif +#ifdef _IBMR2 + "-D_IBMR2", /* IBM RS-6000 (we ensured that aix is defined above */ +#ifndef aix +#define aix /* allow BOOTSTRAPCFLAGS="-D_IBMR2" */ +#endif +#endif /* _IBMR2 */ +#ifdef aix + "-Daix", /* AIX instead of AOS */ +#ifndef ibm +#define ibm /* allow BOOTSTRAPCFLAGS="-Daix" */ +#endif +#endif /* aix */ +#ifdef ibm + "-Dibm", /* IBM PS/2 and RT under both AOS and AIX */ +#endif +#ifdef luna + "-Dluna", /* OMRON luna 68K and 88K */ +#ifdef luna1 + "-Dluna1", +#endif +#ifdef luna88k /* need not on UniOS-Mach Vers. 1.13 */ + "-traditional", /* for some older version */ +#endif /* instead of "-DXCOMM=\\#" */ +#ifdef uniosb + "-Duniosb", +#endif +#ifdef uniosu + "-Duniosu", +#endif +#endif /* luna */ +#ifdef _CRAY /* Cray */ + "-Ucray", +#endif +#ifdef Mips + "-DMips", /* Define and use Mips for Mips Co. OS/mach. */ +# if defined(SYSTYPE_BSD) || defined(BSD) || defined(BSD43) + "-DBSD43", /* Mips RISCOS supports two environments */ +# else + "-DSYSV", /* System V environment is the default */ +# endif +#endif /* Mips */ +#ifdef MOTOROLA + "-DMOTOROLA", /* Motorola Delta Systems */ +# ifdef SYSV + "-DSYSV", +# endif +# ifdef SVR4 + "-DSVR4", +# endif +#endif /* MOTOROLA */ +#ifdef i386 + "-Di386", +# ifdef SVR4 + "-DSVR4", +# endif +# ifdef SYSV + "-DSYSV", +# ifdef ISC + "-DISC", +# ifdef ISC40 + "-DISC40", /* ISC 4.0 */ +# else +# ifdef ISC202 + "-DISC202", /* ISC 2.0.2 */ +# else +# ifdef ISC30 + "-DISC30", /* ISC 3.0 */ +# else + "-DISC22", /* ISC 2.2.1 */ +# endif +# endif +# endif +# endif +# ifdef SCO + "-DSCO", +# ifdef SCO324 + "-DSCO324", +# endif +# endif +# endif +# ifdef ESIX + "-DESIX", +# endif +# ifdef ATT + "-DATT", +# endif +# ifdef DELL + "-DDELL", +# endif +#endif +#ifdef SYSV386 /* System V/386 folks, obsolete */ + "-Di386", +# ifdef SVR4 + "-DSVR4", +# endif +# ifdef ISC + "-DISC", +# ifdef ISC40 + "-DISC40", /* ISC 4.0 */ +# else +# ifdef ISC202 + "-DISC202", /* ISC 2.0.2 */ +# else +# ifdef ISC30 + "-DISC30", /* ISC 3.0 */ +# else + "-DISC22", /* ISC 2.2.1 */ +# endif +# endif +# endif +# endif +# ifdef SCO + "-DSCO", +# ifdef SCO324 + "-DSCO324", +# endif +# endif +# ifdef ESIX + "-DESIX", +# endif +# ifdef ATT + "-DATT", +# endif +# ifdef DELL + "-DDELL", +# endif +#endif +#ifdef __osf__ + "-D__osf__", +# ifdef __mips__ + "-D__mips__", +# endif +# ifdef __alpha + "-D__alpha", +# endif +# ifdef __i386__ + "-D__i386__", +# endif +# ifdef __GNUC__ + "-traditional", +# endif +#endif +#ifdef Oki + "-DOki", +#endif +#ifdef sun +#ifdef SVR4 + "-DSVR4", +#endif +#endif +#ifdef WIN32 + "-DWIN32", + "-nologo", + "-batch", + "-D__STDC__", +#endif +#ifdef NCR + "-DNCR", /* NCR */ +#endif +#ifdef linux + "-traditional", + "-Dlinux", +#endif +#ifdef __uxp__ + "-D__uxp__", +#endif +#ifdef __sxg__ + "-D__sxg__", +#endif +#ifdef nec_ews_svr2 + "-Dnec_ews_svr2", +#endif +#ifdef AMOEBA + "-DAMOEBA", +# ifdef CROSS_COMPILE + "-DCROSS_COMPILE", +# ifdef CROSS_i80386 + "-Di80386", +# endif +# ifdef CROSS_sparc + "-Dsparc", +# endif +# ifdef CROSS_mc68000 + "-Dmc68000", +# endif +# else +# ifdef i80386 + "-Di80386", +# endif +# ifdef sparc + "-Dsparc", +# endif +# ifdef mc68000 + "-Dmc68000", +# endif +# endif +#endif +#ifdef __minix_vmd + "-Dminix", +#endif + +#if defined(__EMX__) + "-traditional", + "-Demxos2", +#endif + +}; +#else /* else MAKEDEPEND */ +/* + * Step 6: predefs + * If your compiler and/or preprocessor define any specific symbols, add + * them to the the following table. The definition of struct symtab is + * in util/makedepend/def.h. + */ +struct symtab predefs[] = { +#ifdef apollo + {"apollo", "1"}, +#endif +#ifdef ibm032 + {"ibm032", "1"}, +#endif +#ifdef ibm + {"ibm", "1"}, +#endif +#ifdef aix + {"aix", "1"}, +#endif +#ifdef sun + {"sun", "1"}, +#endif +#ifdef sun2 + {"sun2", "1"}, +#endif +#ifdef sun3 + {"sun3", "1"}, +#endif +#ifdef sun4 + {"sun4", "1"}, +#endif +#ifdef sparc + {"sparc", "1"}, +#endif +#ifdef __sparc__ + {"__sparc__", "1"}, +#endif +#ifdef hpux + {"hpux", "1"}, +#endif +#ifdef __hpux + {"__hpux", "1"}, +#endif +#ifdef __hp9000s800 + {"__hp9000s800", "1"}, +#endif +#ifdef __hp9000s700 + {"__hp9000s700", "1"}, +#endif +#ifdef vax + {"vax", "1"}, +#endif +#ifdef VMS + {"VMS", "1"}, +#endif +#ifdef cray + {"cray", "1"}, +#endif +#ifdef CRAY + {"CRAY", "1"}, +#endif +#ifdef _CRAY + {"_CRAY", "1"}, +#endif +#ifdef att + {"att", "1"}, +#endif +#ifdef mips + {"mips", "1"}, +#endif +#ifdef __mips__ + {"__mips__", "1"}, +#endif +#ifdef ultrix + {"ultrix", "1"}, +#endif +#ifdef stellar + {"stellar", "1"}, +#endif +#ifdef mc68000 + {"mc68000", "1"}, +#endif +#ifdef mc68020 + {"mc68020", "1"}, +#endif +#ifdef __GNUC__ + {"__GNUC__", "1"}, +#endif +#if __STDC__ + {"__STDC__", "1"}, +#endif +#ifdef __HIGHC__ + {"__HIGHC__", "1"}, +#endif +#ifdef CMU + {"CMU", "1"}, +#endif +#ifdef luna + {"luna", "1"}, +#ifdef luna1 + {"luna1", "1"}, +#endif +#ifdef luna2 + {"luna2", "1"}, +#endif +#ifdef luna88k + {"luna88k", "1"}, +#endif +#ifdef uniosb + {"uniosb", "1"}, +#endif +#ifdef uniosu + {"uniosu", "1"}, +#endif +#endif +#ifdef ieeep754 + {"ieeep754", "1"}, +#endif +#ifdef is68k + {"is68k", "1"}, +#endif +#ifdef m68k + {"m68k", "1"}, +#endif +#ifdef m88k + {"m88k", "1"}, +#endif +#ifdef __m88k__ + {"__m88k__", "1"}, +#endif +#ifdef bsd43 + {"bsd43", "1"}, +#endif +#ifdef hcx + {"hcx", "1"}, +#endif +#ifdef sony + {"sony", "1"}, +#ifdef SYSTYPE_SYSV + {"SYSTYPE_SYSV", "1"}, +#endif +#ifdef _SYSTYPE_SYSV + {"_SYSTYPE_SYSV", "1"}, +#endif +#endif +#ifdef __OSF__ + {"__OSF__", "1"}, +#endif +#ifdef __osf__ + {"__osf__", "1"}, +#endif +#ifdef __alpha + {"__alpha", "1"}, +#endif +#ifdef __DECC + {"__DECC", "1"}, +#endif +#ifdef __decc + {"__decc", "1"}, +#endif +#ifdef __uxp__ + {"__uxp__", "1"}, +#endif +#ifdef __sxg__ + {"__sxg__", "1"}, +#endif +#ifdef _SEQUENT_ + {"_SEQUENT_", "1"}, + {"__STDC__", "1"}, +#endif +#ifdef __bsdi__ + {"__bsdi__", "1"}, +#endif +#ifdef nec_ews_svr2 + {"nec_ews_svr2", "1"}, +#endif +#ifdef nec_ews_svr4 + {"nec_ews_svr4", "1"}, +#endif +#ifdef _nec_ews_svr4 + {"_nec_ews_svr4", "1"}, +#endif +#ifdef _nec_up + {"_nec_up", "1"}, +#endif +#ifdef SX + {"SX", "1"}, +#endif +#ifdef nec + {"nec", "1"}, +#endif +#ifdef _nec_ft + {"_nec_ft", "1"}, +#endif +#ifdef PC_UX + {"PC_UX", "1"}, +#endif +#ifdef sgi + {"sgi", "1"}, +#endif +#ifdef __sgi + {"__sgi", "1"}, +#endif +#ifdef __FreeBSD__ + {"__FreeBSD__", "1"}, +#endif +#ifdef __NetBSD__ + {"__NetBSD__", "1"}, +#endif +#ifdef __EMX__ + {"__EMX__", "1"}, +#endif + /* add any additional symbols before this line */ + {NULL, NULL} +}; + +#endif /* MAKEDEPEND */ +#endif /* CCIMAKE */ diff --git a/ef/config/mkdepend/include.c b/ef/config/mkdepend/include.c new file mode 100644 index 000000000000..994233a88683 --- /dev/null +++ b/ef/config/mkdepend/include.c @@ -0,0 +1,308 @@ +/* $XConsortium: include.c,v 1.17 94/12/05 19:33:08 gildea Exp $ */ +/* + +Copyright (c) 1993, 1994 X Consortium + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of the X Consortium shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from the X Consortium. + +*/ + + +#include "def.h" + +extern struct inclist inclist[ MAXFILES ], + *inclistp; +extern char *includedirs[ ]; +extern char *notdotdot[ ]; +extern boolean show_where_not; +extern boolean warn_multiple; + +struct inclist *inc_path(file, include, dot) + register char *file, + *include; + boolean dot; +{ + static char path[ BUFSIZ ]; + register char **pp, *p; + register struct inclist *ip; + struct stat st; + boolean found = FALSE; + + /* + * Check all previously found include files for a path that + * has already been expanded. + */ + for (ip = inclist; ip->i_file; ip++) + if ((strcmp(ip->i_incstring, include) == 0) && !ip->i_included_sym) + { + found = TRUE; + break; + } + + /* + * If the path was surrounded by "" or is an absolute path, + * then check the exact path provided. + */ + if (!found && (dot || *include == '/')) { + if (stat(include, &st) == 0) { + ip = newinclude(include, include); + found = TRUE; + } + else if (show_where_not) + warning1("\tnot in %s\n", include); + } + + /* + * See if this include file is in the directory of the + * file being compiled. + */ + if (!found) { + for (p=file+strlen(file); p>file; p--) + if (*p == '/') + break; + if (p == file) + strcpy(path, include); + else { + strncpy(path, file, (p-file) + 1); + path[ (p-file) + 1 ] = '\0'; + strcpy(path + (p-file) + 1, include); + } + remove_dotdot(path); + if (stat(path, &st) == 0) { + ip = newinclude(path, include); + found = TRUE; + } + else if (show_where_not) + warning1("\tnot in %s\n", path); + } + + /* + * Check the include directories specified. (standard include dir + * should be at the end.) + */ + if (!found) + for (pp = includedirs; *pp; pp++) { + sprintf(path, "%s/%s", *pp, include); + remove_dotdot(path); + if (stat(path, &st) == 0) { + ip = newinclude(path, include); + found = TRUE; + break; + } + else if (show_where_not) + warning1("\tnot in %s\n", path); + } + + if (!found) + ip = NULL; + return(ip); +} + +/* + * Occasionally, pathnames are created that look like .../x/../y + * Any of the 'x/..' sequences within the name can be eliminated. + * (but only if 'x' is not a symbolic link!!) + */ +void remove_dotdot(path) + char *path; +{ + register char *end, *from, *to, **cp; + char *components[ MAXFILES ], + newpath[ BUFSIZ ]; + boolean component_copied; + + /* + * slice path up into components. + */ + to = newpath; + if (*path == '/') + *to++ = '/'; + *to = '\0'; + cp = components; + for (from=end=path; *end; end++) + if (*end == '/') { + while (*end == '/') + *end++ = '\0'; + if (*from) + *cp++ = from; + from = end; + } + *cp++ = from; + *cp = NULL; + + /* + * Recursively remove all 'x/..' component pairs. + */ + cp = components; + while(*cp) { + if (!isdot(*cp) && !isdotdot(*cp) && isdotdot(*(cp+1)) + && !issymbolic(newpath, *cp)) + { + char **fp = cp + 2; + char **tp = cp; + + do + *tp++ = *fp; /* move all the pointers down */ + while (*fp++); + if (cp != components) + cp--; /* go back and check for nested ".." */ + } else { + cp++; + } + } + /* + * Concatenate the remaining path elements. + */ + cp = components; + component_copied = FALSE; + while(*cp) { + if (component_copied) + *to++ = '/'; + component_copied = TRUE; + for (from = *cp; *from; ) + *to++ = *from++; + *to = '\0'; + cp++; + } + *to++ = '\0'; + + /* + * copy the reconstituted path back to our pointer. + */ + strcpy(path, newpath); +} + +int isdot(p) + register char *p; +{ + if(p && *p++ == '.' && *p++ == '\0') + return(TRUE); + return(FALSE); +} + +int isdotdot(p) + register char *p; +{ + if(p && *p++ == '.' && *p++ == '.' && *p++ == '\0') + return(TRUE); + return(FALSE); +} + +int issymbolic(dir, component) + register char *dir, *component; +{ +#ifdef S_IFLNK + struct stat st; + char buf[ BUFSIZ ], **pp; + + sprintf(buf, "%s%s%s", dir, *dir ? "/" : "", component); + for (pp=notdotdot; *pp; pp++) + if (strcmp(*pp, buf) == 0) + return (TRUE); + if (lstat(buf, &st) == 0 + && (st.st_mode & S_IFMT) == S_IFLNK) { + *pp++ = copy(buf); + if (pp >= ¬dotdot[ MAXDIRS ]) + fatalerr("out of .. dirs, increase MAXDIRS\n"); + return(TRUE); + } +#endif + return(FALSE); +} + +/* + * Add an include file to the list of those included by 'file'. + */ +struct inclist *newinclude(newfile, incstring) + register char *newfile, *incstring; +{ + register struct inclist *ip; + + /* + * First, put this file on the global list of include files. + */ + ip = inclistp++; + if (inclistp == inclist + MAXFILES - 1) + fatalerr("out of space: increase MAXFILES\n"); + ip->i_file = copy(newfile); + ip->i_included_sym = FALSE; + if (incstring == NULL) + ip->i_incstring = ip->i_file; + else + ip->i_incstring = copy(incstring); + + return(ip); +} + +void included_by(ip, newfile) + register struct inclist *ip, *newfile; +{ + register i; + + if (ip == NULL) + return; + /* + * Put this include file (newfile) on the list of files included + * by 'file'. If 'file' is NULL, then it is not an include + * file itself (i.e. was probably mentioned on the command line). + * If it is already on the list, don't stick it on again. + */ + if (ip->i_list == NULL) + ip->i_list = (struct inclist **) + malloc(sizeof(struct inclist *) * ++ip->i_listlen); + else { + for (i=0; ii_listlen; i++) + if (ip->i_list[ i ] == newfile) { + i = strlen(newfile->i_file); + if (!ip->i_included_sym && + !(i > 2 && + newfile->i_file[i-1] == 'c' && + newfile->i_file[i-2] == '.')) + { + /* only bitch if ip has */ + /* no #include SYMBOL lines */ + /* and is not a .c file */ + if (warn_multiple) + { + warning("%s includes %s more than once!\n", + ip->i_file, newfile->i_file); + warning1("Already have\n"); + for (i=0; ii_listlen; i++) + warning1("\t%s\n", ip->i_list[i]->i_file); + } + } + return; + } + ip->i_list = (struct inclist **) realloc(ip->i_list, + sizeof(struct inclist *) * ++ip->i_listlen); + } + ip->i_list[ ip->i_listlen-1 ] = newfile; +} + +void inc_clean () +{ + register struct inclist *ip; + + for (ip = inclist; ip < inclistp; ip++) { + ip->i_marked = FALSE; + } +} diff --git a/ef/config/mkdepend/main.c b/ef/config/mkdepend/main.c new file mode 100644 index 000000000000..2f4925c148ec --- /dev/null +++ b/ef/config/mkdepend/main.c @@ -0,0 +1,715 @@ +/* $XConsortium: main.c,v 1.84 94/11/30 16:10:44 kaleb Exp $ */ +/* $XFree86: xc/config/makedepend/main.c,v 3.4 1995/07/15 14:53:49 dawes Exp $ */ +/* + +Copyright (c) 1993, 1994 X Consortium + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of the X Consortium shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from the X Consortium. + +*/ + +#include "def.h" +#ifdef hpux +#define sigvec sigvector +#endif /* hpux */ + +#ifdef X_POSIX_C_SOURCE +#define _POSIX_C_SOURCE X_POSIX_C_SOURCE +#include +#undef _POSIX_C_SOURCE +#else +#if defined(X_NOT_POSIX) || defined(_POSIX_SOURCE) +#include +#else +#define _POSIX_SOURCE +#include +#undef _POSIX_SOURCE +#endif +#endif + +#if NeedVarargsPrototypes +#include +#endif + +#ifndef _WIN32 +#include +#endif + +#ifdef MINIX +#define USE_CHMOD 1 +#endif + +#ifdef DEBUG +int _debugmask; +#endif + +char *ProgramName; + +char *directives[] = { + "if", + "ifdef", + "ifndef", + "else", + "endif", + "define", + "undef", + "include", + "line", + "pragma", + "error", + "ident", + "sccs", + "elif", + "eject", + NULL +}; + +#define MAKEDEPEND +#include "imakemdep.h" /* from config sources */ +#undef MAKEDEPEND + +struct inclist inclist[ MAXFILES ], + *inclistp = inclist, + maininclist; + +char *filelist[ MAXFILES ]; +char *includedirs[ MAXDIRS + 1 ]; +char *notdotdot[ MAXDIRS ]; +char *objprefix = ""; +char *objsuffix = OBJSUFFIX; +char *startat = "# DO NOT DELETE"; +int width = 78; +boolean append = FALSE; +boolean printed = FALSE; +boolean verbose = FALSE; +boolean show_where_not = FALSE; +boolean warn_multiple = FALSE; /* Warn on multiple includes of same file */ + +static +#ifdef SIGNALRETURNSINT +int +#else +void +#endif +catch (sig) + int sig; +{ + fflush (stdout); + fatalerr ("got signal %d\n", sig); +} + +#if defined(USG) || (defined(i386) && defined(SYSV)) || defined(WIN32) || defined(__EMX__) || defined(Lynx_22) || defined(FREEBSD) +#define USGISH +#endif + +#ifndef USGISH +#ifndef _POSIX_SOURCE +#define sigaction sigvec +#define sa_handler sv_handler +#define sa_mask sv_mask +#define sa_flags sv_flags +#endif +struct sigaction sig_act; +#endif /* USGISH */ + +int +main(argc, argv) + int argc; + char **argv; +{ + register char **fp = filelist; + register char **incp = includedirs; + register char *p; + register struct inclist *ip; + char *makefile = NULL; + struct filepointer *filecontent; + struct symtab *psymp = predefs; + char *endmarker = NULL; + char *defincdir = NULL; + + ProgramName = argv[0]; + + while (psymp->s_name) + { + define2(psymp->s_name, psymp->s_value, &maininclist); + psymp++; + } + if (argc == 2 && argv[1][0] == '@') { + struct stat ast; + int afd; + char *args; + char **nargv; + int nargc; + char quotechar = '\0'; + + nargc = 1; + if ((afd = open(argv[1]+1, O_RDONLY)) < 0) + fatalerr("cannot open \"%s\"\n", argv[1]+1); + fstat(afd, &ast); + args = (char *)malloc(ast.st_size + 1); + if ((ast.st_size = read(afd, args, ast.st_size)) < 0) + fatalerr("failed to read %s\n", argv[1]+1); + args[ast.st_size] = '\0'; + close(afd); + for (p = args; *p; p++) { + if (quotechar) { + if (quotechar == '\\' || + (*p == quotechar && p[-1] != '\\')) + quotechar = '\0'; + continue; + } + switch (*p) { + case '\\': + case '"': + case '\'': + quotechar = *p; + break; + case ' ': + case '\n': + *p = '\0'; + if (p > args && p[-1]) + nargc++; + break; + } + } + if (p[-1]) + nargc++; + nargv = (char **)malloc(nargc * sizeof(char *)); + nargv[0] = argv[0]; + argc = 1; + for (p = args; argc < nargc; p += strlen(p) + 1) + if (*p) nargv[argc++] = p; + argv = nargv; + } + for(argc--, argv++; argc; argc--, argv++) { + /* if looking for endmarker then check before parsing */ + if (endmarker && strcmp (endmarker, *argv) == 0) { + endmarker = NULL; + continue; + } + if (**argv != '-') { + /* treat +thing as an option for C++ */ + if (endmarker && **argv == '+') + continue; + *fp++ = argv[0]; + continue; + } + switch(argv[0][1]) { + case '-': + endmarker = &argv[0][2]; + if (endmarker[0] == '\0') endmarker = "--"; + break; + case 'D': + if (argv[0][2] == '\0') { + argv++; + argc--; + } + for (p=argv[0] + 2; *p ; p++) + if (*p == '=') { + *p = ' '; + break; + } + define(argv[0] + 2, &maininclist); + break; + case 'I': + if (incp >= includedirs + MAXDIRS) + fatalerr("Too many -I flags.\n"); + *incp++ = argv[0]+2; + if (**(incp-1) == '\0') { + *(incp-1) = *(++argv); + argc--; + } + break; + case 'Y': + defincdir = argv[0]+2; + break; + /* do not use if endmarker processing */ + case 'a': + if (endmarker) break; + append = TRUE; + break; + case 'w': + if (endmarker) break; + if (argv[0][2] == '\0') { + argv++; + argc--; + width = atoi(argv[0]); + } else + width = atoi(argv[0]+2); + break; + case 'o': + if (endmarker) break; + if (argv[0][2] == '\0') { + argv++; + argc--; + objsuffix = argv[0]; + } else + objsuffix = argv[0]+2; + break; + case 'p': + if (endmarker) break; + if (argv[0][2] == '\0') { + argv++; + argc--; + objprefix = argv[0]; + } else + objprefix = argv[0]+2; + break; + case 'v': + if (endmarker) break; + verbose = TRUE; +#ifdef DEBUG + if (argv[0][2]) + _debugmask = atoi(argv[0]+2); +#endif + break; + case 's': + if (endmarker) break; + startat = argv[0]+2; + if (*startat == '\0') { + startat = *(++argv); + argc--; + } + if (*startat != '#') + fatalerr("-s flag's value should start %s\n", + "with '#'."); + break; + case 'f': + if (endmarker) break; + makefile = argv[0]+2; + if (*makefile == '\0') { + makefile = *(++argv); + argc--; + } + break; + + case 'm': + warn_multiple = TRUE; + break; + + /* Ignore -O, -g so we can just pass ${CFLAGS} to + makedepend + */ + case 'O': + case 'g': + break; + default: + if (endmarker) break; + /* fatalerr("unknown opt = %s\n", argv[0]); */ + warning("ignoring option %s\n", argv[0]); + } + } + if (!defincdir) { +#ifdef PREINCDIR + if (incp >= includedirs + MAXDIRS) + fatalerr("Too many -I flags.\n"); + *incp++ = PREINCDIR; +#endif + if (incp >= includedirs + MAXDIRS) + fatalerr("Too many -I flags.\n"); + *incp++ = INCLUDEDIR; +#ifdef POSTINCDIR + if (incp >= includedirs + MAXDIRS) + fatalerr("Too many -I flags.\n"); + *incp++ = POSTINCDIR; +#endif + } else if (*defincdir) { + if (incp >= includedirs + MAXDIRS) + fatalerr("Too many -I flags.\n"); + *incp++ = defincdir; + } + + redirect(startat, makefile); + + /* + * catch signals. + */ +#ifdef USGISH +/* should really reset SIGINT to SIG_IGN if it was. */ +#ifdef SIGHUP + signal (SIGHUP, catch); +#endif + signal (SIGINT, catch); +#ifdef SIGQUIT + signal (SIGQUIT, catch); +#endif + signal (SIGILL, catch); +#ifdef SIGBUS + signal (SIGBUS, catch); +#endif + signal (SIGSEGV, catch); +#ifdef SIGSYS + signal (SIGSYS, catch); +#endif +#else + sig_act.sa_handler = catch; +#ifdef _POSIX_SOURCE + sigemptyset(&sig_act.sa_mask); + sigaddset(&sig_act.sa_mask, SIGINT); + sigaddset(&sig_act.sa_mask, SIGQUIT); +#ifdef SIGBUS + sigaddset(&sig_act.sa_mask, SIGBUS); +#endif + sigaddset(&sig_act.sa_mask, SIGILL); + sigaddset(&sig_act.sa_mask, SIGSEGV); + sigaddset(&sig_act.sa_mask, SIGHUP); + sigaddset(&sig_act.sa_mask, SIGPIPE); +#ifdef SIGSYS + sigaddset(&sig_act.sa_mask, SIGSYS); +#endif +#else + sig_act.sa_mask = ((1<<(SIGINT -1)) + |(1<<(SIGQUIT-1)) +#ifdef SIGBUS + |(1<<(SIGBUS-1)) +#endif + |(1<<(SIGILL-1)) + |(1<<(SIGSEGV-1)) + |(1<<(SIGHUP-1)) + |(1<<(SIGPIPE-1)) +#ifdef SIGSYS + |(1<<(SIGSYS-1)) +#endif + ); +#endif /* _POSIX_SOURCE */ + sig_act.sa_flags = 0; + sigaction(SIGHUP, &sig_act, (struct sigaction *)0); + sigaction(SIGINT, &sig_act, (struct sigaction *)0); + sigaction(SIGQUIT, &sig_act, (struct sigaction *)0); + sigaction(SIGILL, &sig_act, (struct sigaction *)0); +#ifdef SIGBUS + sigaction(SIGBUS, &sig_act, (struct sigaction *)0); +#endif + sigaction(SIGSEGV, &sig_act, (struct sigaction *)0); +#ifdef SIGSYS + sigaction(SIGSYS, &sig_act, (struct sigaction *)0); +#endif +#endif /* USGISH */ + + /* + * now peruse through the list of files. + */ + for(fp=filelist; *fp; fp++) { + filecontent = getfile(*fp); + ip = newinclude(*fp, (char *)NULL); + + find_includes(filecontent, ip, ip, 0, FALSE); + freefile(filecontent); + recursive_pr_include(ip, ip->i_file, base_name(*fp)); + inc_clean(); + } + if (printed) + printf("\n"); + exit(0); +} + +struct filepointer *getfile(file) + char *file; +{ + register int fd; + struct filepointer *content; + struct stat st; + + content = (struct filepointer *)malloc(sizeof(struct filepointer)); + if ((fd = open(file, O_RDONLY)) < 0) { + warning("cannot open \"%s\"\n", file); + content->f_p = content->f_base = content->f_end = (char *)malloc(1); + *content->f_p = '\0'; + return(content); + } + fstat(fd, &st); + content->f_base = (char *)malloc(st.st_size+1); + if (content->f_base == NULL) + fatalerr("cannot allocate mem\n"); + if ((st.st_size = read(fd, content->f_base, st.st_size)) < 0) + fatalerr("failed to read %s\n", file); + close(fd); + content->f_len = st.st_size+1; + content->f_p = content->f_base; + content->f_end = content->f_base + st.st_size; + *content->f_end = '\0'; + content->f_line = 0; + return(content); +} + +void freefile(fp) + struct filepointer *fp; +{ + free(fp->f_base); + free(fp); +} + +char *copy(str) + register char *str; +{ + register char *p = (char *)malloc(strlen(str) + 1); + + strcpy(p, str); + return(p); +} + +int match(str, list) + register char *str, **list; +{ + register int i; + + for (i=0; *list; i++, list++) + if (strcmp(str, *list) == 0) + return(i); + return(-1); +} + +/* + * Get the next line. We only return lines beginning with '#' since that + * is all this program is ever interested in. + */ +char *getline(filep) + register struct filepointer *filep; +{ + register char *p, /* walking pointer */ + *eof, /* end of file pointer */ + *bol; /* beginning of line pointer */ + register lineno; /* line number */ + + p = filep->f_p; + eof = filep->f_end; + if (p >= eof) + return((char *)NULL); + lineno = filep->f_line; + + for(bol = p--; ++p < eof; ) { + if (*p == '/' && *(p+1) == '*') { /* consume comments */ + *p++ = ' ', *p++ = ' '; + while (*p) { + if (*p == '*' && *(p+1) == '/') { + *p++ = ' ', *p = ' '; + break; + } + else if (*p == '\n') + lineno++; + *p++ = ' '; + } + continue; + } +#ifdef WIN32 + else if (*p == '/' && *(p+1) == '/') { /* consume comments */ + *p++ = ' ', *p++ = ' '; + while (*p && *p != '\n') + *p++ = ' '; + lineno++; + continue; + } +#endif + else if (*p == '\\') { + if (*(p+1) == '\n') { + *p = ' '; + *(p+1) = ' '; + lineno++; + } + } + else if (*p == '\n') { + lineno++; + if (*bol == '#') { + register char *cp; + + *p++ = '\0'; + /* punt lines with just # (yacc generated) */ + for (cp = bol+1; + *cp && (*cp == ' ' || *cp == '\t'); cp++); + if (*cp) goto done; + } + bol = p+1; + } + } + if (*bol != '#') + bol = NULL; +done: + filep->f_p = p; + filep->f_line = lineno; + return(bol); +} + +/* + * Strip the file name down to what we want to see in the Makefile. + * It will have objprefix and objsuffix around it. + */ +char *base_name(file) + register char *file; +{ + register char *p; + + file = copy(file); + for(p=file+strlen(file); p>file && *p != '.'; p--) ; + + if (*p == '.') + *p = '\0'; + return(file); +} + +#if defined(USG) && !defined(CRAY) && !defined(SVR4) && !defined(__EMX__) +int rename (from, to) + char *from, *to; +{ + (void) unlink (to); + if (link (from, to) == 0) { + unlink (from); + return 0; + } else { + return -1; + } +} +#endif /* USGISH */ + +void redirect(line, makefile) + char *line, + *makefile; +{ + struct stat st; + FILE *fdin, *fdout; + char backup[ BUFSIZ ], + buf[ BUFSIZ ]; + boolean found = FALSE; + int len; + + /* + * if makefile is "-" then let it pour onto stdout. + */ + if (makefile && *makefile == '-' && *(makefile+1) == '\0') + return; + + /* + * use a default makefile is not specified. + */ + if (!makefile) { + if (stat("Makefile", &st) == 0) + makefile = "Makefile"; + else if (stat("makefile", &st) == 0) + makefile = "makefile"; + else + fatalerr("[mM]akefile is not present\n"); + } + else + stat(makefile, &st); + if ((fdin = fopen(makefile, "r")) == NULL) + fatalerr("cannot open \"%s\"\n", makefile); + sprintf(backup, "%s.bak", makefile); + unlink(backup); +#if defined(WIN32) || defined(__EMX__) + fclose(fdin); + + /* Remove backup file if it already exists */ + _unlink(backup); +#endif + + if (rename(makefile, backup) < 0) + fatalerr("cannot rename %s to %s\n", makefile, backup); + +#if defined(WIN32) || defined(__EMX__) + if ((fdin = fopen(backup, "r")) == NULL) + fatalerr("cannot open \"%s\"\n", backup); +#endif + if ((fdout = freopen(makefile, "w", stdout)) == NULL) + fatalerr("cannot open \"%s\"\n", makefile); + len = strlen(line); + while (!found && fgets(buf, BUFSIZ, fdin)) { + if (*buf == '#' && strncmp(line, buf, len) == 0) + found = TRUE; + fputs(buf, fdout); + } + if (!found) { + if (verbose) + warning("Adding new delimiting line \"%s\" and dependencies...\n", + line); + puts(line); /* same as fputs(fdout); but with newline */ + } else if (append) { + while (fgets(buf, BUFSIZ, fdin)) { + fputs(buf, fdout); + } + } + fflush(fdout); +#if defined(USGISH) || defined(_SEQUENT_) || defined(USE_CHMOD) + chmod(makefile, st.st_mode); +#else + fchmod(fileno(fdout), st.st_mode); +#endif /* USGISH */ +} + +#if NeedVarargsPrototypes +void fatalerr(char *msg, ...) +#else +/*VARARGS*/ +void fatalerr(msg,x1,x2,x3,x4,x5,x6,x7,x8,x9) + char *msg; +#endif +{ +#if NeedVarargsPrototypes + va_list args; +#endif + fprintf(stderr, "%s: error: ", ProgramName); +#if NeedVarargsPrototypes + va_start(args, msg); + vfprintf(stderr, msg, args); + va_end(args); +#else + fprintf(stderr, msg,x1,x2,x3,x4,x5,x6,x7,x8,x9); +#endif + exit (1); +} + +#if NeedVarargsPrototypes +void warning(char *msg, ...) +#else +/*VARARGS0*/ +void warning(msg,x1,x2,x3,x4,x5,x6,x7,x8,x9) + char *msg; +#endif +{ +#if NeedVarargsPrototypes + va_list args; +#endif + fprintf(stderr, "%s: warning: ", ProgramName); +#if NeedVarargsPrototypes + va_start(args, msg); + vfprintf(stderr, msg, args); + va_end(args); +#else + fprintf(stderr, msg,x1,x2,x3,x4,x5,x6,x7,x8,x9); +#endif +} + +#if NeedVarargsPrototypes +void warning1(char *msg, ...) +#else +/*VARARGS0*/ +void warning1(msg,x1,x2,x3,x4,x5,x6,x7,x8,x9) + char *msg; +#endif +{ +#if NeedVarargsPrototypes + va_list args; + va_start(args, msg); + vfprintf(stderr, msg, args); + va_end(args); +#else + fprintf(stderr, msg,x1,x2,x3,x4,x5,x6,x7,x8,x9); +#endif +} diff --git a/ef/config/mkdepend/mkdepend.man b/ef/config/mkdepend/mkdepend.man new file mode 100644 index 000000000000..9c3cdccd988c --- /dev/null +++ b/ef/config/mkdepend/mkdepend.man @@ -0,0 +1,368 @@ +.\" $XConsortium: mkdepend.man,v 1.15 94/04/17 20:10:37 gildea Exp $ +.\" Copyright (c) 1993, 1994 X Consortium +.\" +.\" Permission is hereby granted, free of charge, to any person obtaining a +.\" copy of this software and associated documentation files (the "Software"), +.\" to deal in the Software without restriction, including without limitation +.\" the rights to use, copy, modify, merge, publish, distribute, sublicense, +.\" and/or sell copies of the Software, and to permit persons to whom the +.\" Software furnished to do so, subject to the following conditions: +.\" +.\" The above copyright notice and this permission notice shall be included in +.\" all copies or substantial portions of the Software. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +.\" IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +.\" FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +.\" THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +.\" WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +.\" OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +.\" SOFTWARE. +.\" +.\" Except as contained in this notice, the name of the X Consortium shall not +.\" be used in advertising or otherwise to promote the sale, use or other +.\" dealing in this Software without prior written authorization from the +.\" X Consortium. +.TH MAKEDEPEND 1 "Release 6" "X Version 11" +.UC 4 +.SH NAME +makedepend \- create dependencies in makefiles +.SH SYNOPSIS +.B makedepend +[ +.B \-Dname=def +] [ +.B \-Dname +] [ +.B \-Iincludedir +] [ +.B \-Yincludedir +] [ +.B \-a +] [ +.B \-fmakefile +] [ +.B \-oobjsuffix +] [ +.B \-pobjprefix +] [ +.B \-sstring +] [ +.B \-wwidth +] [ +.B \-v +] [ +.B \-m +] [ +\-\^\- +.B otheroptions +\-\^\- +] +sourcefile .\|.\|. +.br +.SH DESCRIPTION +.B Makedepend +reads each +.I sourcefile +in sequence and parses it like a C-preprocessor, +processing all +.I #include, +.I #define, +.I #undef, +.I #ifdef, +.I #ifndef, +.I #endif, +.I #if +and +.I #else +directives so that it can correctly tell which +.I #include, +directives would be used in a compilation. +Any +.I #include, +directives can reference files having other +.I #include +directives, and parsing will occur in these files as well. +.PP +Every file that a +.I sourcefile +includes, +directly or indirectly, +is what +.B makedepend +calls a "dependency". +These dependencies are then written to a +.I makefile +in such a way that +.B make(1) +will know which object files must be recompiled when a dependency has changed. +.PP +By default, +.B makedepend +places its output in the file named +.I makefile +if it exists, otherwise +.I Makefile. +An alternate makefile may be specified with the +.B \-f +option. +It first searches the makefile for +the line +.sp + # DO NOT DELETE THIS LINE \-\^\- make depend depends on it. +.sp +or one provided with the +.B \-s +option, +as a delimiter for the dependency output. +If it finds it, it will delete everything +following this to the end of the makefile +and put the output after this line. +If it doesn't find it, the program +will append the string to the end of the makefile +and place the output following that. +For each +.I sourcefile +appearing on the command line, +.B makedepend +puts lines in the makefile of the form +.sp + sourcefile.o:\0dfile .\|.\|. +.sp +Where "sourcefile.o" is the name from the command +line with its suffix replaced with ".o", +and "dfile" is a dependency discovered in a +.I #include +directive while parsing +.I sourcefile +or one of the files it included. +.SH EXAMPLE +Normally, +.B makedepend +will be used in a makefile target so that typing "make depend" will +bring the dependencies up to date for the makefile. +For example, +.nf + SRCS\0=\0file1.c\0file2.c\0.\|.\|. + CFLAGS\0=\0\-O\0\-DHACK\0\-I\^.\^.\^/foobar\0\-xyz + depend: + makedepend\0\-\^\-\0$(CFLAGS)\0\-\^\-\0$(SRCS) +.fi +.SH OPTIONS +.B Makedepend +will ignore any option that it does not understand so that you may use +the same arguments that you would for +.B cc(1). +.TP 5 +.B \-Dname=def or \-Dname +Define. +This places a definition for +.I name +in +.B makedepend's +symbol table. +Without +.I =def +the symbol becomes defined as "1". +.TP 5 +.B \-Iincludedir +Include directory. +This option tells +.B makedepend +to prepend +.I includedir +to its list of directories to search when it encounters +a +.I #include +directive. +By default, +.B makedepend +only searches the standard include directories (usually /usr/include +and possibly a compiler-dependent directory). +.TP 5 +.B \-Yincludedir +Replace all of the standard include directories with the single specified +include directory; you can omit the +.I includedir +to simply prevent searching the standard include directories. +.TP 5 +.B \-a +Append the dependencies to the end of the file instead of replacing them. +.TP 5 +.B \-fmakefile +Filename. +This allows you to specify an alternate makefile in which +.B makedepend +can place its output. +.TP 5 +.B \-oobjsuffix +Object file suffix. +Some systems may have object files whose suffix is something other +than ".o". +This option allows you to specify another suffix, such as +".b" with +.I -o.b +or ":obj" +with +.I -o:obj +and so forth. +.TP 5 +.B \-pobjprefix +Object file prefix. +The prefix is prepended to the name of the object file. This is +usually used to designate a different directory for the object file. +The default is the empty string. +.TP 5 +.B \-sstring +Starting string delimiter. +This option permits you to specify +a different string for +.B makedepend +to look for in the makefile. +.TP 5 +.B \-wwidth +Line width. +Normally, +.B makedepend +will ensure that every output line that it writes will be no wider than +78 characters for the sake of readability. +This option enables you to change this width. +.TP 5 +.B \-v +Verbose operation. +This option causes +.B makedepend +to emit the list of files included by each input file on standard output. +.TP 5 +.B \-m +Warn about multiple inclusion. +This option causes +.B makedepend +to produce a warning if any input file includes another file more than +once. In previous versions of +.B makedepend +this was the default behavior; the default has been changed to better +match the behavior of the C compiler, which does not consider multiple +inclusion to be an error. This option is provided for backward +compatibility, and to aid in debugging problems related to multiple +inclusion. +.TP 5 +.B "\-\^\- options \-\^\-" +If +.B makedepend +encounters a double hyphen (\-\^\-) in the argument list, +then any unrecognized argument following it +will be silently ignored; a second double hyphen terminates this +special treatment. +In this way, +.B makedepend +can be made to safely ignore esoteric compiler arguments that might +normally be found in a CFLAGS +.B make +macro (see the +.B EXAMPLE +section above). +All options that +.B makedepend +recognizes and appear between the pair of double hyphens +are processed normally. +.SH ALGORITHM +The approach used in this program enables it to run an order of magnitude +faster than any other "dependency generator" I have ever seen. +Central to this performance are two assumptions: +that all files compiled by a single +makefile will be compiled with roughly the same +.I -I +and +.I -D +options; +and that most files in a single directory will include largely the +same files. +.PP +Given these assumptions, +.B makedepend +expects to be called once for each makefile, with +all source files that are maintained by the +makefile appearing on the command line. +It parses each source and include +file exactly once, maintaining an internal symbol table +for each. +Thus, the first file on the command line will take an amount of time +proportional to the amount of time that a normal C preprocessor takes. +But on subsequent files, if it encounter's an include file +that it has already parsed, it does not parse it again. +.PP +For example, +imagine you are compiling two files, +.I file1.c +and +.I file2.c, +they each include the header file +.I header.h, +and the file +.I header.h +in turn includes the files +.I def1.h +and +.I def2.h. +When you run the command +.sp + makedepend\0file1.c\0file2.c +.sp +.B makedepend +will parse +.I file1.c +and consequently, +.I header.h +and then +.I def1.h +and +.I def2.h. +It then decides that the dependencies for this file are +.sp + file1.o:\0header.h\0def1.h\0def2.h +.sp +But when the program parses +.I file2.c +and discovers that it, too, includes +.I header.h, +it does not parse the file, +but simply adds +.I header.h, +.I def1.h +and +.I def2.h +to the list of dependencies for +.I file2.o. +.SH "SEE ALSO" +cc(1), make(1) +.SH BUGS +.B makedepend +parses, but does not currently evaluate, the SVR4 +#predicate(token-list) preprocessor expression; +such expressions are simply assumed to be true. +This may cause the wrong +.I #include +directives to be evaluated. +.PP +Imagine you are parsing two files, +say +.I file1.c +and +.I file2.c, +each includes the file +.I def.h. +The list of files that +.I def.h +includes might truly be different when +.I def.h +is included by +.I file1.c +than when it is included by +.I file2.c. +But once +.B makedepend +arrives at a list of dependencies for a file, +it is cast in concrete. +.SH AUTHOR +Todd Brunhoff, Tektronix, Inc. and MIT Project Athena diff --git a/ef/config/mkdepend/parse.c b/ef/config/mkdepend/parse.c new file mode 100644 index 000000000000..1c34a87bb3f5 --- /dev/null +++ b/ef/config/mkdepend/parse.c @@ -0,0 +1,567 @@ +/* $XConsortium: parse.c,v 1.30 94/04/17 20:10:38 gildea Exp $ */ +/* + +Copyright (c) 1993, 1994 X Consortium + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of the X Consortium shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from the X Consortium. + +*/ + +#include "def.h" + +extern char *directives[]; +extern struct inclist maininclist; + +int find_includes(filep, file, file_red, recursion, failOK) + struct filepointer *filep; + struct inclist *file, *file_red; + int recursion; + boolean failOK; +{ + register char *line; + register int type; + boolean recfailOK; + + while ((line = getline(filep))) { + switch(type = deftype(line, filep, file_red, file, TRUE)) { + case IF: + doif: + type = find_includes(filep, file, + file_red, recursion+1, failOK); + while ((type == ELIF) || (type == ELIFFALSE) || + (type == ELIFGUESSFALSE)) + type = gobble(filep, file, file_red); + if (type == ELSE) + gobble(filep, file, file_red); + break; + case IFFALSE: + case IFGUESSFALSE: + doiffalse: + if (type == IFGUESSFALSE || type == ELIFGUESSFALSE) + recfailOK = TRUE; + else + recfailOK = failOK; + type = gobble(filep, file, file_red); + if (type == ELSE) + find_includes(filep, file, + file_red, recursion+1, recfailOK); + else + if (type == ELIF) + goto doif; + else + if ((type == ELIFFALSE) || (type == ELIFGUESSFALSE)) + goto doiffalse; + break; + case IFDEF: + case IFNDEF: + if ((type == IFDEF && isdefined(line, file_red, NULL)) + || (type == IFNDEF && !isdefined(line, file_red, NULL))) { + debug(1,(type == IFNDEF ? + "line %d: %s !def'd in %s via %s%s\n" : "", + filep->f_line, line, + file->i_file, file_red->i_file, ": doit")); + type = find_includes(filep, file, + file_red, recursion+1, failOK); + while (type == ELIF || type == ELIFFALSE || type == ELIFGUESSFALSE) + type = gobble(filep, file, file_red); + if (type == ELSE) + gobble(filep, file, file_red); + } + else { + debug(1,(type == IFDEF ? + "line %d: %s !def'd in %s via %s%s\n" : "", + filep->f_line, line, + file->i_file, file_red->i_file, ": gobble")); + type = gobble(filep, file, file_red); + if (type == ELSE) + find_includes(filep, file, + file_red, recursion+1, failOK); + else if (type == ELIF) + goto doif; + else if (type == ELIFFALSE || type == ELIFGUESSFALSE) + goto doiffalse; + } + break; + case ELSE: + case ELIFFALSE: + case ELIFGUESSFALSE: + case ELIF: + if (!recursion) + gobble(filep, file, file_red); + case ENDIF: + if (recursion) + return(type); + case DEFINE: + define(line, file); + break; + case UNDEF: + if (!*line) { + warning("%s, line %d: incomplete undef == \"%s\"\n", + file_red->i_file, filep->f_line, line); + break; + } + undefine(line, file_red); + break; + case INCLUDE: + add_include(filep, file, file_red, line, FALSE, failOK); + break; + case INCLUDEDOT: + add_include(filep, file, file_red, line, TRUE, failOK); + break; + case ERROR: + warning("%s: %d: %s\n", file_red->i_file, + filep->f_line, line); + break; + + case PRAGMA: + case IDENT: + case SCCS: + case EJECT: + break; + case -1: + warning("%s", file_red->i_file); + if (file_red != file) + warning1(" (reading %s)", file->i_file); + warning1(", line %d: unknown directive == \"%s\"\n", + filep->f_line, line); + break; + case -2: + warning("%s", file_red->i_file); + if (file_red != file) + warning1(" (reading %s)", file->i_file); + warning1(", line %d: incomplete include == \"%s\"\n", + filep->f_line, line); + break; + } + } + return(-1); +} + +int gobble(filep, file, file_red) + register struct filepointer *filep; + struct inclist *file, *file_red; +{ + register char *line; + register int type; + + while ((line = getline(filep))) { + switch(type = deftype(line, filep, file_red, file, FALSE)) { + case IF: + case IFFALSE: + case IFGUESSFALSE: + case IFDEF: + case IFNDEF: + type = gobble(filep, file, file_red); + while ((type == ELIF) || (type == ELIFFALSE) || + (type == ELIFGUESSFALSE)) + type = gobble(filep, file, file_red); + if (type == ELSE) + (void)gobble(filep, file, file_red); + break; + case ELSE: + case ENDIF: + debug(0,("%s, line %d: #%s\n", + file->i_file, filep->f_line, + directives[type])); + return(type); + case DEFINE: + case UNDEF: + case INCLUDE: + case INCLUDEDOT: + case PRAGMA: + case ERROR: + case IDENT: + case SCCS: + case EJECT: + break; + case ELIF: + case ELIFFALSE: + case ELIFGUESSFALSE: + return(type); + case -1: + warning("%s, line %d: unknown directive == \"%s\"\n", + file_red->i_file, filep->f_line, line); + break; + } + } + return(-1); +} + +/* + * Decide what type of # directive this line is. + */ +int deftype (line, filep, file_red, file, parse_it) + register char *line; + register struct filepointer *filep; + register struct inclist *file_red, *file; + int parse_it; +{ + register char *p; + char *directive, savechar; + register int ret; + + /* + * Parse the directive... + */ + directive=line+1; + while (*directive == ' ' || *directive == '\t') + directive++; + + p = directive; + while (*p >= 'a' && *p <= 'z') + p++; + savechar = *p; + *p = '\0'; + ret = match(directive, directives); + *p = savechar; + + /* If we don't recognize this compiler directive or we happen to just + * be gobbling up text while waiting for an #endif or #elif or #else + * in the case of an #elif we must check the zero_value and return an + * ELIF or an ELIFFALSE. + */ + + if (ret == ELIF && !parse_it) + { + while (*p == ' ' || *p == '\t') + p++; + /* + * parse an expression. + */ + debug(0,("%s, line %d: #elif %s ", + file->i_file, filep->f_line, p)); + ret = zero_value(p, filep, file_red); + if (ret != IF) + { + debug(0,("false...\n")); + if (ret == IFFALSE) + return(ELIFFALSE); + else + return(ELIFGUESSFALSE); + } + else + { + debug(0,("true...\n")); + return(ELIF); + } + } + + if (ret < 0 || ! parse_it) + return(ret); + + /* + * now decide how to parse the directive, and do it. + */ + while (*p == ' ' || *p == '\t') + p++; + switch (ret) { + case IF: + /* + * parse an expression. + */ + ret = zero_value(p, filep, file_red); + debug(0,("%s, line %d: %s #if %s\n", + file->i_file, filep->f_line, ret?"false":"true", p)); + break; + case IFDEF: + case IFNDEF: + debug(0,("%s, line %d: #%s %s\n", + file->i_file, filep->f_line, directives[ret], p)); + case UNDEF: + /* + * separate the name of a single symbol. + */ + while (isalnum(*p) || *p == '_') + *line++ = *p++; + *line = '\0'; + break; + case INCLUDE: + debug(2,("%s, line %d: #include %s\n", + file->i_file, filep->f_line, p)); + + /* Support ANSI macro substitution */ + { + struct symtab *sym = isdefined(p, file_red, NULL); + while (sym) { + p = sym->s_value; + debug(3,("%s : #includes SYMBOL %s = %s\n", + file->i_incstring, + sym -> s_name, + sym -> s_value)); + /* mark file as having included a 'soft include' */ + file->i_included_sym = TRUE; + sym = isdefined(p, file_red, NULL); + } + } + + /* + * Separate the name of the include file. + */ + while (*p && *p != '"' && *p != '<') + p++; + if (! *p) + return(-2); + if (*p++ == '"') { + ret = INCLUDEDOT; + while (*p && *p != '"') + *line++ = *p++; + } else + while (*p && *p != '>') + *line++ = *p++; + *line = '\0'; + break; + case DEFINE: + /* + * copy the definition back to the beginning of the line. + */ + strcpy (line, p); + break; + case ELSE: + case ENDIF: + case ELIF: + case PRAGMA: + case ERROR: + case IDENT: + case SCCS: + case EJECT: + debug(0,("%s, line %d: #%s\n", + file->i_file, filep->f_line, directives[ret])); + /* + * nothing to do. + */ + break; + } + return(ret); +} + +struct symtab *isdefined(symbol, file, srcfile) + register char *symbol; + struct inclist *file; + struct inclist **srcfile; +{ + register struct symtab *val; + + if ((val = slookup(symbol, &maininclist))) { + debug(1,("%s defined on command line\n", symbol)); + if (srcfile != NULL) *srcfile = &maininclist; + return(val); + } + if ((val = fdefined(symbol, file, srcfile))) + return(val); + debug(1,("%s not defined in %s\n", symbol, file->i_file)); + return(NULL); +} + +struct symtab *fdefined(symbol, file, srcfile) + register char *symbol; + struct inclist *file; + struct inclist **srcfile; +{ + register struct inclist **ip; + register struct symtab *val; + register int i; + static int recurse_lvl = 0; + + if (file->i_defchecked) + return(NULL); + file->i_defchecked = TRUE; + if ((val = slookup(symbol, file))) + debug(1,("%s defined in %s as %s\n", symbol, file->i_file, val->s_value)); + if ((val == NULL && file->i_list)) + { + for (ip = file->i_list, i=0; i < file->i_listlen; i++, ip++) + if ((val = fdefined(symbol, *ip, srcfile))) { + break; + } + } + else if (val != NULL && srcfile != NULL) *srcfile = file; + recurse_lvl--; + file->i_defchecked = FALSE; + + return(val); +} + +/* + * Return type based on if the #if expression evaluates to 0 + */ +int zero_value(exp, filep, file_red) + register char *exp; + register struct filepointer *filep; + register struct inclist *file_red; +{ + if (cppsetup(exp, filep, file_red)) + return(IFFALSE); + else + return(IF); +} + +void define(def, file) + char *def; + struct inclist *file; +{ + char *val; + + /* Separate symbol name and its value */ + val = def; + while (isalnum(*val) || *val == '_') + val++; + if (*val) + *val++ = '\0'; + while (*val == ' ' || *val == '\t') + val++; + + if (!*val) + val = "1"; + define2(def, val, file); +} + +void define2(name, val, file) + char *name, *val; + struct inclist *file; +{ + int first, last, below; + register struct symtab *sp = NULL, *dest; + + /* Make space if it's needed */ + if (file->i_defs == NULL) + { + file->i_defs = (struct symtab *) + malloc(sizeof (struct symtab) * SYMTABINC); + file->i_deflen = SYMTABINC; + file->i_ndefs = 0; + } + else if (file->i_ndefs == file->i_deflen) + file->i_defs = (struct symtab *) + realloc(file->i_defs, + sizeof(struct symtab)*(file->i_deflen+=SYMTABINC)); + + if (file->i_defs == NULL) + fatalerr("malloc()/realloc() failure in insert_defn()\n"); + + below = first = 0; + last = file->i_ndefs - 1; + while (last >= first) + { + /* Fast inline binary search */ + register char *s1; + register char *s2; + register int middle = (first + last) / 2; + + /* Fast inline strchr() */ + s1 = name; + s2 = file->i_defs[middle].s_name; + while (*s1++ == *s2++) + if (s2[-1] == '\0') break; + + /* If exact match, set sp and break */ + if (*--s1 == *--s2) + { + sp = file->i_defs + middle; + break; + } + + /* If name > i_defs[middle] ... */ + if (*s1 > *s2) + { + below = first; + first = middle + 1; + } + /* else ... */ + else + { + below = last = middle - 1; + } + } + + /* Search is done. If we found an exact match to the symbol name, + just replace its s_value */ + if (sp != NULL) + { + free(sp->s_value); + sp->s_value = copy(val); + return; + } + + sp = file->i_defs + file->i_ndefs++; + dest = file->i_defs + below + 1; + while (sp > dest) + { + *sp = sp[-1]; + sp--; + } + sp->s_name = copy(name); + sp->s_value = copy(val); +} + +struct symtab *slookup(symbol, file) + register char *symbol; + register struct inclist *file; +{ + register int first = 0; + register int last = file->i_ndefs - 1; + + if (file) while (last >= first) + { + /* Fast inline binary search */ + register char *s1; + register char *s2; + register int middle = (first + last) / 2; + + /* Fast inline strchr() */ + s1 = symbol; + s2 = file->i_defs[middle].s_name; + while (*s1++ == *s2++) + if (s2[-1] == '\0') break; + + /* If exact match, we're done */ + if (*--s1 == *--s2) + { + return file->i_defs + middle; + } + + /* If symbol > i_defs[middle] ... */ + if (*s1 > *s2) + { + first = middle + 1; + } + /* else ... */ + else + { + last = middle - 1; + } + } + return(NULL); +} + +void undefine(symbol, file) + char *symbol; + register struct inclist *file; +{ + register struct symtab *ptr; + struct inclist *srcfile; + while ((ptr = isdefined(symbol, file, &srcfile)) != NULL) + { + srcfile->i_ndefs--; + for (; ptr < srcfile->i_defs + srcfile->i_ndefs; ptr++) + *ptr = ptr[1]; + } +} diff --git a/ef/config/mkdepend/pr.c b/ef/config/mkdepend/pr.c new file mode 100644 index 000000000000..e1b8224b15fa --- /dev/null +++ b/ef/config/mkdepend/pr.c @@ -0,0 +1,132 @@ +/* $XConsortium: pr.c,v 1.17 94/04/17 20:10:38 gildea Exp $ */ +/* + +Copyright (c) 1993, 1994 X Consortium + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of the X Consortium shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from the X Consortium. + +*/ + +#include "def.h" + +extern struct inclist inclist[ MAXFILES ], + *inclistp; +extern char *objprefix; +extern char *objsuffix; +extern int width; +extern boolean printed; +extern boolean verbose; +extern boolean show_where_not; + +void add_include(filep, file, file_red, include, dot, failOK) + struct filepointer *filep; + struct inclist *file, *file_red; + char *include; + boolean dot; +{ + register struct inclist *newfile; + register struct filepointer *content; + + /* + * First decide what the pathname of this include file really is. + */ + newfile = inc_path(file->i_file, include, dot); + if (newfile == NULL) { + if (failOK) + return; + if (file != file_red) + warning("%s (reading %s, line %d): ", + file_red->i_file, file->i_file, filep->f_line); + else + warning("%s, line %d: ", file->i_file, filep->f_line); + warning1("cannot find include file \"%s\"\n", include); + show_where_not = TRUE; + newfile = inc_path(file->i_file, include, dot); + show_where_not = FALSE; + } + + if (newfile) { + + /* Only add new dependency files if they don't have "/usr/include" in them. */ + if (!(newfile && newfile->i_file && strstr(newfile->i_file, "/usr/"))) { + included_by(file, newfile); + } + + if (!newfile->i_searched) { + newfile->i_searched = TRUE; + content = getfile(newfile->i_file); + find_includes(content, newfile, file_red, 0, failOK); + freefile(content); + } + } +} + +void recursive_pr_include(head, file, base) + register struct inclist *head; + register char *file, *base; +{ + register int i; + + if (head->i_marked) + return; + head->i_marked = TRUE; + if (head->i_file != file) + pr(head, file, base); + for (i=0; ii_listlen; i++) + recursive_pr_include(head->i_list[ i ], file, base); +} + +void pr(ip, file, base) + register struct inclist *ip; + char *file, *base; +{ + static char *lastfile; + static int current_len; + register int len, i; + char buf[ BUFSIZ ]; + + printed = TRUE; + len = strlen(ip->i_file)+1; + if (current_len + len > width || file != lastfile) { + lastfile = file; + sprintf(buf, "\n%s%s%s: %s", objprefix, base, objsuffix, + ip->i_file); + len = current_len = strlen(buf); + } + else { + buf[0] = ' '; + strcpy(buf+1, ip->i_file); + current_len += len; + } + fwrite(buf, len, 1, stdout); + + /* + * If verbose is set, then print out what this file includes. + */ + if (! verbose || ip->i_list == NULL || ip->i_notified) + return; + ip->i_notified = TRUE; + lastfile = NULL; + printf("\n# %s includes:", ip->i_file); + for (i=0; ii_listlen; i++) + printf("\n#\t%s", ip->i_list[ i ]->i_incstring); +} diff --git a/ef/config/nfspwd.pl b/ef/config/nfspwd.pl new file mode 100644 index 000000000000..0b13fc270783 --- /dev/null +++ b/ef/config/nfspwd.pl @@ -0,0 +1,29 @@ +#! perl +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +require "fastcwd.pl"; + +$_ = &fastcwd; +if (m@^/[uh]/@o || s@^/tmp_mnt/@/@o) { + print("$_\n"); +} elsif ((($user, $rest) = m@^/usr/people/(\w+)/(.*)@o) + && readlink("/u/$user") eq "/usr/people/$user") { + print("/u/$user/$rest\n"); +} else { + chop($host = `hostname`); + print("/h/$host$_\n"); +} diff --git a/ef/config/nsinstall.c b/ef/config/nsinstall.c new file mode 100644 index 000000000000..847324daa442 --- /dev/null +++ b/ef/config/nsinstall.c @@ -0,0 +1,316 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +/* +** Netscape portable install command. +** +** Brendan Eich, 7/20/95 +*/ +#include /* OSF/1 requires this before grp.h, so put it first */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "pathsub.h" + +#define HAVE_LCHOWN + +#if defined(AIX) || defined(BSDI) || defined(HPUX) || defined(LINUX) || defined(SUNOS4) || defined(SCO) || defined(UNIXWARE) +#undef HAVE_LCHOWN +#endif + +#ifdef LINUX +#include +#endif + +#if defined(SCO) || defined(UNIXWARE) || defined(SNI) || defined (NCR) +#if !defined(S_ISLNK) && defined(S_IFLNK) +#define S_ISLNK(a) (((a) & S_IFMT) == S_IFLNK) +#endif +#endif + +#if defined(SNI) +extern int fchmod(int fildes, mode_t mode); +#endif + +static void +usage(void) +{ + fprintf(stderr, + "usage: %s [-C cwd] [-L linkprefix] [-m mode] [-o owner] [-g group]\n" + " %*s [-DdltR] file [file ...] directory\n", + program, strlen(program), ""); + exit(2); +} + +static int +mkdirs(char *path, mode_t mode) +{ + char *cp; + struct stat sb; + + while (*path == '/' && path[1] == '/') + path++; + while ((cp = strrchr(path, '/')) && cp[1] == '\0') + *cp = '\0'; + if (cp && cp != path) { + *cp = '\0'; + if ((lstat(path, &sb) < 0 || !S_ISDIR(sb.st_mode)) && + mkdirs(path, mode) < 0) { + return -1; + } + *cp = '/'; + } + return mkdir(path, mode); +} + +static uid_t +touid(char *owner) +{ + struct passwd *pw; + uid_t uid; + char *cp; + + pw = getpwnam(owner); + if (pw) + return pw->pw_uid; + uid = strtol(owner, &cp, 0); + if (uid == 0 && cp == owner) + fail("cannot find uid for %s", owner); + return uid; +} + +static gid_t +togid(char *group) +{ + struct group *gr; + gid_t gid; + char *cp; + + gr = getgrnam(group); + if (gr) + return gr->gr_gid; + gid = strtol(group, &cp, 0); + if (gid == 0 && cp == group) + fail("cannot find gid for %s", group); + return gid; +} + +int +main(int argc, char **argv) +{ + int onlydir, dodir, dolink, dorelsymlink, dotimes, opt, len, lplen, tdlen, bnlen, exists, fromfd, tofd, cc, wc; + mode_t mode = 0755; + char *linkprefix, *owner, *group, *cp, *cwd, *todir, *toname, *name, *base, *linkname, *bp, buf[BUFSIZ]; + uid_t uid; + gid_t gid; + struct stat sb, tosb; + struct utimbuf utb; + + program = argv[0]; + cwd = linkname = linkprefix = owner = group = 0; + onlydir = dodir = dolink = dorelsymlink = dotimes = lplen = 0; + + while ((opt = getopt(argc, argv, "C:DdlL:Rm:o:g:t")) != EOF) { + switch (opt) { + case 'C': + cwd = optarg; + break; + case 'D': + onlydir = 1; + break; + case 'd': + dodir = 1; + break; + case 'l': + dolink = 1; + break; + case 'L': + linkprefix = optarg; + lplen = strlen(linkprefix); + dolink = 1; + break; + case 'R': + dolink = dorelsymlink = 1; + break; + case 'm': + mode = strtoul(optarg, &cp, 8); + if (mode == 0 && cp == optarg) + usage(); + break; + case 'o': + owner = optarg; + break; + case 'g': + group = optarg; + break; + case 't': + dotimes = 1; + break; + default: + usage(); + } + } + + argc -= optind; + argv += optind; + if (argc < 2 - onlydir) + usage(); + + todir = argv[argc-1]; + if ((stat(todir, &sb) < 0 || !S_ISDIR(sb.st_mode)) && + mkdirs(todir, 0777) < 0) { + fail("cannot make directory %s", todir); + } + if (onlydir) + return 0; + + if (!cwd) + cwd = getcwd(0, PATH_MAX); + xchdir(todir); + todir = getcwd(0, PATH_MAX); + tdlen = strlen(todir); + xchdir(cwd); + tdlen = strlen(todir); + + uid = owner ? touid(owner) : -1; + gid = group ? togid(group) : -1; + + while (--argc > 0) { + name = *argv++; + len = strlen(name); + base = xbasename(name); + bnlen = strlen(base); + toname = xmalloc(tdlen + 1 + bnlen + 1); + sprintf(toname, "%s/%s", todir, base); + exists = (lstat(toname, &tosb) == 0); + + if (dodir) { + /* -d means create a directory, always */ + if (exists && !S_ISDIR(tosb.st_mode)) { + (void) unlink(toname); + exists = 0; + } + if (!exists && mkdir(toname, mode) < 0) + fail("cannot make directory %s", toname); + if ((owner || group) && chown(toname, uid, gid) < 0) + fail("cannot change owner of %s", toname); + } else if (dolink) { + if (*name == '/') { + /* source is absolute pathname, link to it directly */ + linkname = 0; + } else { + if (linkprefix) { + /* -L implies -l and prefixes names with a $cwd arg. */ + len += lplen + 1; + linkname = xmalloc(len + 1); + sprintf(linkname, "%s/%s", linkprefix, name); + } else if (dorelsymlink) { + /* Symlink the relative path from todir to source name. */ + linkname = xmalloc(PATH_MAX); + + if (*todir == '/') { + /* todir is absolute: skip over common prefix. */ + lplen = relatepaths(todir, cwd, linkname); + strcpy(linkname + lplen, name); + } else { + /* todir is named by a relative path: reverse it. */ + reversepath(todir, name, len, linkname); + xchdir(cwd); + } + + len = strlen(linkname); + } + name = linkname; + } + + /* Check for a pre-existing symlink with identical content. */ + if (exists && + (!S_ISLNK(tosb.st_mode) || + readlink(toname, buf, sizeof buf) != len || + strncmp(buf, name, len) != 0)) { + (void) (S_ISDIR(tosb.st_mode) ? rmdir : unlink)(toname); + exists = 0; + } + if (!exists && symlink(name, toname) < 0) + fail("cannot make symbolic link %s", toname); +#ifdef HAVE_LCHOWN + if ((owner || group) && lchown(toname, uid, gid) < 0) + fail("cannot change owner of %s", toname); +#endif + + if (linkname) { + free(linkname); + linkname = 0; + } + } else { + /* Copy from name to toname, which might be the same file. */ + fromfd = open(name, O_RDONLY); + if (fromfd < 0 || fstat(fromfd, &sb) < 0) + fail("cannot access %s", name); + if (exists && (!S_ISREG(tosb.st_mode) || access(toname, W_OK) < 0)) + (void) (S_ISDIR(tosb.st_mode) ? rmdir : unlink)(toname); + tofd = open(toname, O_CREAT | O_WRONLY, 0666); + if (tofd < 0) + fail("cannot create %s", toname); + + bp = buf; + while ((cc = read(fromfd, bp, sizeof buf)) > 0) { + while ((wc = write(tofd, bp, cc)) > 0) { + if ((cc -= wc) == 0) + break; + bp += wc; + } + if (wc < 0) + fail("cannot write to %s", toname); + } + if (cc < 0) + fail("cannot read from %s", name); + + if (ftruncate(tofd, sb.st_size) < 0) + fail("cannot truncate %s", toname); + if (dotimes) { + utb.actime = sb.st_atime; + utb.modtime = sb.st_mtime; + if (utime(toname, &utb) < 0) + fail("cannot set times of %s", toname); + } + if (fchmod(tofd, mode) < 0) + fail("cannot change mode of %s", toname); + if ((owner || group) && fchown(tofd, uid, gid) < 0) + fail("cannot change owner of %s", toname); + + /* Must check for delayed (NFS) write errors on close. */ + if (close(tofd) < 0) + fail("cannot write to %s", toname); + close(fromfd); + } + + free(toname); + } + + free(cwd); + free(todir); + return 0; +} diff --git a/ef/config/pathsub.c b/ef/config/pathsub.c new file mode 100644 index 000000000000..1b20e41b0821 --- /dev/null +++ b/ef/config/pathsub.c @@ -0,0 +1,218 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +/* +** Pathname subroutines. +** +** Brendan Eich, 8/29/95 +*/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "pathsub.h" +#ifdef USE_REENTRANT_LIBC +#include "libc_r.h" +#endif /* USE_REENTRANT_LIBC */ + +char *program; + +void +fail(char *format, ...) +{ + int error; + va_list ap; + +#ifdef USE_REENTRANT_LIBC + R_STRERROR_INIT_R(); +#endif + + error = errno; + fprintf(stderr, "%s: ", program); + va_start(ap, format); + vfprintf(stderr, format, ap); + va_end(ap); + if (error) + +#ifdef USE_REENTRANT_LIBC + R_STRERROR_R(errno); + fprintf(stderr, ": %s", r_strerror_r); +#else + fprintf(stderr, ": %s", strerror(errno)); +#endif + + putc('\n', stderr); + exit(1); +} + +char * +getcomponent(char *path, char *name) +{ + if (*path == '\0') + return 0; + if (*path == '/') { + *name++ = '/'; + } else { + do { + *name++ = *path++; + } while (*path != '/' && *path != '\0'); + } + *name = '\0'; + while (*path == '/') + path++; + return path; +} + +#ifdef UNIXWARE +/* Sigh. The static buffer in Unixware's readdir is too small. */ +struct dirent * readdir(DIR *d) +{ + static struct dirent *buf = NULL; +#define MAX_PATH_LEN 1024 + + + if(buf == NULL) + buf = (struct dirent *) malloc(sizeof(struct dirent) + MAX_PATH_LEN) +; + return(readdir_r(d, buf)); +} +#endif + +char * +ino2name(ino_t ino, char *dir) +{ + DIR *dp; + struct dirent *ep; + char *name; + + dp = opendir(".."); + if (!dp) + fail("cannot read parent directory"); + for (;;) { + if (!(ep = readdir(dp))) + fail("cannot find current directory"); + if (ep->d_ino == ino) + break; + } + name = xstrdup(ep->d_name); + closedir(dp); + return name; +} + +void * +xmalloc(size_t size) +{ + void *p = malloc(size); + if (!p) + fail("cannot allocate %u bytes", size); + return p; +} + +char * +xstrdup(char *s) +{ + return strcpy(xmalloc(strlen(s) + 1), s); +} + +char * +xbasename(char *path) +{ + char *cp; + + while ((cp = strrchr(path, '/')) && cp[1] == '\0') + *cp = '\0'; + if (!cp) return path; + return cp + 1; +} + +void +xchdir(char *dir) +{ + if (chdir(dir) < 0) + fail("cannot change directory to %s", dir); +} + +int +relatepaths(char *from, char *to, char *outpath) +{ + char *cp, *cp2; + int len; + char buf[NAME_MAX]; + + assert(*from == '/' && *to == '/'); + for (cp = to, cp2 = from; *cp == *cp2; cp++, cp2++) + if (*cp == '\0') + break; + while (cp[-1] != '/') + cp--, cp2--; + if (cp - 1 == to) { + /* closest common ancestor is /, so use full pathname */ + len = strlen(strcpy(outpath, to)); + if (outpath[len] != '/') { + outpath[len++] = '/'; + outpath[len] = '\0'; + } + } else { + len = 0; + while ((cp2 = getcomponent(cp2, buf)) != 0) { + strcpy(outpath + len, "../"); + len += 3; + } + while ((cp = getcomponent(cp, buf)) != 0) { + sprintf(outpath + len, "%s/", buf); + len += strlen(outpath + len); + } + } + return len; +} + +void +reversepath(char *inpath, char *name, int len, char *outpath) +{ + char *cp, *cp2; + char buf[NAME_MAX]; + struct stat sb; + + cp = strcpy(outpath + PATH_MAX - (len + 1), name); + cp2 = inpath; + while ((cp2 = getcomponent(cp2, buf)) != 0) { + if (strcmp(buf, ".") == 0) + continue; + if (strcmp(buf, "..") == 0) { + if (stat(".", &sb) < 0) + fail("cannot stat current directory"); + name = ino2name(sb.st_ino, ".."); + len = strlen(name); + cp -= len + 1; + strcpy(cp, name); + cp[len] = '/'; + free(name); + xchdir(".."); + } else { + cp -= 3; + strncpy(cp, "../", 3); + xchdir(buf); + } + } + strcpy(outpath, cp); +} diff --git a/ef/config/pathsub.h b/ef/config/pathsub.h new file mode 100644 index 000000000000..47c012410966 --- /dev/null +++ b/ef/config/pathsub.h @@ -0,0 +1,58 @@ +/* -*- 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.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#ifndef pathsub_h___ +#define pathsub_h___ +/* +** Pathname subroutines. +** +** Brendan Eich, 8/29/95 +*/ +#include +#include + +#if SUNOS4 +#include "../pr/include/md/sunos4.h" +#endif + +#ifndef PATH_MAX +#define PATH_MAX 1024 +#endif + +/* + * Just prevent stupidity + */ +#undef NAME_MAX +#define NAME_MAX 256 + +extern char *program; + +extern void fail(char *format, ...); +extern char *getcomponent(char *path, char *name); +extern char *ino2name(ino_t ino, char *dir); +extern void *xmalloc(size_t size); +extern char *xstrdup(char *s); +extern char *xbasename(char *path); +extern void xchdir(char *dir); + +/* Relate absolute pathnames from and to returning the result in outpath. */ +extern int relatepaths(char *from, char *to, char *outpath); + +/* XXX changes current working directory -- caveat emptor */ +extern void reversepath(char *inpath, char *name, int len, char *outpath); + +#endif /* pathsub_h___ */ diff --git a/ef/config/rules.mk b/ef/config/rules.mk new file mode 100644 index 000000000000..b5961c4bbcae --- /dev/null +++ b/ef/config/rules.mk @@ -0,0 +1,131 @@ +#! gmake +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +include $(CORE_DEPTH)/coreconf/ruleset.mk + +# Set TARGETS to null so that the coreconf rules work +TARGETS = + +# This is actually our modified version of +# $(CORE_DEPTH)/coreconf/rules.mk, and should +# hopefully be temporary until we can get the +# coreconf people to merge our changes with theirs +include $(DEPTH)/config/corerules.mk + +ifneq ($(MODULE_NAME),) + +# OBJFILTERS is neccesary for the ifneq check below +# since OBJS seems to have an undetermined number of blanks in it +OBJFILTERS = $(filter %$(OBJ_SUFFIX),$(OBJS)) + +ifneq ($(OBJFILTERS),) +MODULE_FILE = $(OBJDIR)/moduleFile +$(MODULE_FILE): $(OBJS) + @$(MKDIR) $(DEPTH)/$(OBJDIR)/$(MODULE_NAME) + @$(MAKE_OBJDIR) + cp -f $? $(DEPTH)/$(OBJDIR)/$(MODULE_NAME) + touch $(MODULE_FILE) + +libs:: $(MODULE_FILE) + +clean:: + rm -f $(MODULE_FILE) +endif + +endif + + +ifneq ($(HEADER_GEN),) +$(HEADER_INCLUDES): + @$(MKDIR) $(HEADER_GEN_DIR) + $(JAVAH) -classpath $(DEPTH)/../dist/classes -d $(HEADER_GEN_DIR) $(HEADER_GEN) + +$(OBJS) : $(HEADER_INCLUDES) +endif + + +ifneq ($(filter %.h,$(LOCAL_EXPORTS)),) +LOCAL_EXPORT_FILES = $(addprefix $(LOCAL_EXPORT_DIR)/,$(LOCAL_EXPORTS)) + +$(LOCAL_EXPORT_DIR)/%.h : %.h + @$(MKDIR) $(LOCAL_EXPORT_DIR) + @rm -f $(LOCAL_EXPORT_DIR)/$< + $(LN) $(CUR_DIR)/$< $(LOCAL_EXPORT_DIR)/$< + +export:: $(LOCAL_EXPORT_FILES) +endif + + +ifneq ($(filter %.h,$(LOCAL_MD_EXPORTS_x86)),) +LOCAL_MD_x86_EXPORT_FILES = $(addprefix $(LOCAL_EXPORT_DIR)/md/x86/,$(LOCAL_MD_EXPORTS_x86)) + +$(LOCAL_EXPORT_DIR)/md/x86/%.h : %.h + @$(MKDIR) $(LOCAL_EXPORT_DIR)/md/x86 + @rm -f $(LOCAL_EXPORT_DIR)/md/x86/$< + $(LN) $(CUR_DIR)/$< $(LOCAL_EXPORT_DIR)/md/x86/$< + +export:: $(LOCAL_MD_x86_EXPORT_FILES) +endif + +ifneq ($(filter %.h,$(LOCAL_MD_EXPORTS_ppc)),) +export:: + @$(MKDIR) $(LOCAL_EXPORT_DIR)/md/ppc + @$(LN) $(LOCAL_MD_EXPORTS_ppc) $(LOCAL_EXPORT_DIR)/md/ppc +endif + +ifneq ($(filter %.h,$(LOCAL_MD_EXPORTS_sparc)),) +export:: + @$(MKDIR) $(LOCAL_EXPORT_DIR)/md/sparc + @$(LN) $(LOCAL_MD_EXPORTS_sparc) $(LOCAL_EXPORT_DIR)/md/sparc +endif + +ifneq ($(filter %.h,$(LOCAL_MD_EXPORTS_hppa)),) +export:: + @$(MKDIR) $(LOCAL_EXPORT_DIR)/md/hppa + @$(LN) $(LOCAL_MD_EXPORTS_hppa) $(LOCAL_EXPORT_DIR)/md/hppa/$< +endif + +# Browse information +$(BROWSE_INFO_FILE): $(BROWSE_INFO_OBJS) + $(BROWSE_INFO_PROGRAM) $(BROWSE_INFO_FLAGS) -o $(BROWSE_INFO_FILE) $(BROWSE_INFO_OBJS) + @cp $(BROWSE_INFO_FILE) $(DIST)/lib + +# Remove additional ef-specific junk +clean:: + rm -f $(OBJDIR)/vc50*.* + rm -f $(OBJDIR)/BrowseInfo/*.sbr + +clobber:: + rm -r -f $(OBJDIR)/BrowseInfo + +ifneq ($(LIBRARIES),) + +# Add the lib prefix on all platforms except WINNT + +ifeq ($(OS_ARCH),WINNT) +LIBRARIES := $(addprefix $(DIST)/lib/,$(LIBRARIES)) +LIBRARIES := $(addsuffix .lib,$(LIBRARIES)) +else +LIBRARIES := $(addprefix -l,$(LIBRARIES)) +endif + +LDFLAGS += $(LIBRARIES) +endif + + + + diff --git a/ef/manifest.mn b/ef/manifest.mn new file mode 100644 index 000000000000..4e6d1c67778d --- /dev/null +++ b/ef/manifest.mn @@ -0,0 +1,24 @@ +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +DEPTH = . + +EF_DIRS = Compiler Debugger Runtime Utilities Exports + +# Do not mess with the order of directories +DIRS = $(EF_DIRS) VM Tools Packages Driver + +NO_INSTALL_IN_SUBDIRS = 1 \ No newline at end of file diff --git a/ef/rules.mk b/ef/rules.mk new file mode 100644 index 000000000000..11b2905b0f37 --- /dev/null +++ b/ef/rules.mk @@ -0,0 +1,23 @@ +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +clean clobber:: + rm -r -f $(LOCAL_EXPORT_DIR) + cd $(MKDEPEND_DIR); $(MAKE) clobber + +export:: $(MKDEPEND) + +