From 1aa9f3eb116165b85ea8716e7f555b5d0cea85f3 Mon Sep 17 00:00:00 2001 From: "rogerl%netscape.com" Date: Tue, 3 Sep 2002 15:20:24 +0000 Subject: [PATCH] Labor day progress. DotReference, class instance variable definition and associated oevrride resolution support. Branch logic support. git-svn-id: svn://10.0.0.236/trunk@128706 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/js2/src/bytecodecontainer.cpp | 83 ++++- mozilla/js2/src/bytecodecontainer.h | 61 +++- mozilla/js2/src/epimetheus.cpp | 5 - mozilla/js2/src/js2engine.cpp | 72 +++- mozilla/js2/src/js2engine.h | 31 +- mozilla/js2/src/js2metadata.cpp | 457 ++++++++++++++++++++++++-- mozilla/js2/src/js2metadata.h | 75 ++++- mozilla/js2/src/js2op_access.cpp | 90 ++--- mozilla/js2/src/js2op_arithmetic.cpp | 12 +- mozilla/js2/src/js2op_flowcontrol.cpp | 80 +++++ mozilla/js2/src/js2op_invocation.cpp | 38 ++- 11 files changed, 867 insertions(+), 137 deletions(-) create mode 100644 mozilla/js2/src/js2op_flowcontrol.cpp diff --git a/mozilla/js2/src/bytecodecontainer.cpp b/mozilla/js2/src/bytecodecontainer.cpp index 78cfced1d0b..0d91f9d7f2f 100644 --- a/mozilla/js2/src/bytecodecontainer.cpp +++ b/mozilla/js2/src/bytecodecontainer.cpp @@ -60,14 +60,34 @@ namespace JavaScript { namespace MetaData { - - - BytecodeContainer::~BytecodeContainer() - { - for (std::vector::iterator i = mMultinameList.begin(), end = mMultinameList.end(); (i != end); i++) - delete *i; + // Establish the label's location in a bytecode container + void Label::setLocation(BytecodeContainer *bCon, uint32 location) + { + mHasLocation = true; + mLocation = location; + for (std::vector::iterator i = mFixupList.begin(), end = mFixupList.end(); + (i != end); i++) + { + uint32 branchLocation = *i; + bCon->setOffset(branchLocation, int32(mLocation - branchLocation)); + } } + // Add a branch location to the list of fixups for this label + // (or resolve the branch if the location is known already) + void Label::addFixup(BytecodeContainer *bCon, uint32 branchLocation) + { + if (mHasLocation) + bCon->addOffset(int32(mLocation - branchLocation)); + else { + mFixupList.push_back(branchLocation); + bCon->addLong(0); + } + } + + + + // Look up the pc and return a position from the map size_t BytecodeContainer::getPosition(uint16 pc) { for (std::vector::iterator i = pcMap.begin(), end = pcMap.end(); (i != end); i++) @@ -76,6 +96,57 @@ namespace MetaData { return 0; } + + // insert the opcode, marking it's position in the pcmap and + // adjusting the stack as appropriate. + void BytecodeContainer::emitOp(JS2Op op, size_t pos) + { + adjustStack(op); + addByte((uint8)op); + pcMap.push_back(MapEntry(mBuffer.size(), pos)); + } + + // insert the opcode, marking it's position in the pcmap and + // adjusting the stack as supplied. + void BytecodeContainer::emitOp(JS2Op op, size_t pos, int32 effect) + { + adjustStack(op, effect); + addByte((uint8)op); + pcMap.push_back(std::pair(mBuffer.size(), pos)); + } + + // Track the high-water mark for the stack + // and watch for a bad negative stack + void BytecodeContainer::adjustStack(JS2Op op, int32 effect) + { + mStackTop += effect; + if (mStackTop > mStackMax) + mStackMax = mStackTop; + ASSERT(mStackTop >= 0); + } + + // get a new label + BytecodeContainer::LabelID BytecodeContainer::getLabel() + { + LabelID result = mLabelList.size(); + mLabelList.push_back(Label()); + return result; + } + // set the current pc as needing a fixup to a label + void BytecodeContainer::addFixup(LabelID label) + { + ASSERT(label < mLabelList.size()); + mLabelList[label].addFixup(this, mBuffer.size()); + } + // set the current pc as the position for a label + void BytecodeContainer::setLabel(LabelID label) + { + ASSERT(label < mLabelList.size()); + mLabelList[label].setLocation(this, mBuffer.size()); + } + + + } } diff --git a/mozilla/js2/src/bytecodecontainer.h b/mozilla/js2/src/bytecodecontainer.h index 0f9259ae3e2..c3c3b7499f9 100644 --- a/mozilla/js2/src/bytecodecontainer.h +++ b/mozilla/js2/src/bytecodecontainer.h @@ -47,6 +47,40 @@ namespace JavaScript { namespace MetaData { +class BytecodeContainer; + +class Label { +public: + + typedef enum { InternalLabel, NamedLabel, BreakLabel, ContinueLabel } LabelKind; + + Label() : mKind(InternalLabel), mHasLocation(false) { } + Label(LabelStmtNode *lbl) : mKind(NamedLabel), mHasLocation(false), mLabelStmt(lbl) { } + Label(LabelKind kind) : mKind(kind), mHasLocation(false) { } + + bool matches(const StringAtom *name) + { + return ((mKind == NamedLabel) && (mLabelStmt->name.compare(*name) == 0)); + } + + bool matches(LabelKind kind) + { + return (mKind == kind); + } + + void addFixup(BytecodeContainer *bcg, uint32 branchLocation); + void setLocation(BytecodeContainer *bcg, uint32 location); + + std::vector mFixupList; + + LabelKind mKind; + bool mHasLocation; + LabelStmtNode *mLabelStmt; + + uint32 mLocation; +}; + + class Multiname; class Frame; @@ -54,22 +88,25 @@ class Frame; class BytecodeContainer { public: BytecodeContainer() : mStackTop(0), mStackMax(0) { } - BytecodeContainer::~BytecodeContainer() ; + BytecodeContainer::~BytecodeContainer() { } uint8 *getCodeStart() { return mBuffer.begin(); } typedef std::pair MapEntry; std::vector pcMap; + typedef uint32 LabelID; size_t getPosition(uint16 pc); - void emitOp(JS2Op op, size_t pos) { adjustStack(op); addByte((uint8)op); pcMap.push_back(MapEntry(mBuffer.size(), pos)); } - void emitOp(JS2Op op, size_t pos, int32 effect) - { adjustStack(op, effect); addByte((uint8)op); pcMap.push_back(std::pair(mBuffer.size(), pos)); } + void emitOp(JS2Op op, size_t pos); + void emitOp(JS2Op op, size_t pos, int32 effect); + + void emitBranch(JS2Op op, LabelID tgt, size_t pos) + { emitOp(op, pos); addFixup(tgt); } void adjustStack(JS2Op op) { adjustStack(op, JS2Engine::getStackEffect(op)); } - void adjustStack(JS2Op op, int32 effect){ mStackTop += effect; if (mStackTop > mStackMax) mStackMax = mStackTop; ASSERT(mStackTop >= 0); } + void adjustStack(JS2Op op, int32 effect); void addByte(uint8 v) { mBuffer.push_back(v); } @@ -89,12 +126,15 @@ public: void addFrame(Frame *f) { mFrameList.push_back(f); addShort(mFrameList.size() - 1); } + void addOffset(int32 v) { mBuffer.insert(mBuffer.end(), (uint8 *)&v, (uint8 *)(&v) + sizeof(int32)); } + void setOffset(uint32 index, int32 v) { *((int32 *)(mBuffer.begin() + index)) = v; } void addString(const StringAtom &x, size_t pos) { emitOp(eString, pos); addPointer(&x); } void addString(String &x, size_t pos) { emitOp(eString, pos); addPointer(&x); } void addString(String *x, size_t pos) { emitOp(eString, pos); addPointer(x); } static String *getString(void *pc) { return (String *)getPointer(pc); } - // XXX We lose StringAtom here - is there anyway of stashing these in a bytecodecontainer? + // XXX We lose StringAtom here (and is it safe to stash the address of a StringAtom?) + // - is there any way of keeping StringAtoms themselves in a bytecodeContainer? typedef std::vector CodeBuffer; @@ -102,9 +142,14 @@ public: std::vector mMultinameList; // gc tracking std::vector mFrameList; // gc tracking - int32 mStackTop; // keep these as signed so as to - int32 mStackMax; // track if they go negative. + int32 mStackTop; // keep these as signed so as to... + int32 mStackMax; // ...track if they go negative. + std::vector