gecko-dev/ef/Compiler/FrontEnd/BytecodeTranslator.h

166 строки
7.7 KiB
C++

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#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