// -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- // // 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 oqr // implied. See the License for the specific language governing // rights and limitations under the License. // // The Original Code is the JavaScript 2 Prototype. // // 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. #ifndef icodegenerator_h #define icodegenerator_h #include "utilities.h" #include "parser.h" #include #include #include namespace JavaScript { typedef uint32 Register; enum ICodeOp { // Operand1 Operand2 Operand3 NOP, MOVE_TO, // Source Register Destination Register LOAD_VAR, // index of frame slot Destination Register SAVE_VAR, // index of frame slot Source Register LOAD_IMMEDIATE, // immediate (double) Destination Register LOAD_NAME, // StringAtom & Destination Register SAVE_NAME, // StringAtom & Source Register NEW_OBJECT, // Destination Register GET_PROP, // StringAtom & Base Register Destination Register SET_PROP, // StringAtom & Base Register Source Register ADD, // Source Register 1 Source Register 2 Destination Register SUBTRACT, MULTIPLY, DIVIDE, // maintain contiguity COMPARE_LT, // Source Register 1 Source Register 2 Destination Register COMPARE_LE, COMPARE_EQ, COMPARE_NE, COMPARE_GE, COMPARE_GT, NOT, // Source Register Destination Register BRANCH, // Target label BRANCH_LT, // Target label Condition Register BRANCH_LE, BRANCH_EQ, BRANCH_NE, BRANCH_GE, BRANCH_GT, RETURN // Source Register }; class Instruction { public: Instruction(ICodeOp op) : itsOp(op) { } #ifdef DEBUG // provide a virtual destructor, so we can see dynamic type in debugger. virtual ~Instruction() { } #endif ICodeOp itsOp; ICodeOp getBranchOp() { return ((itsOp >= COMPARE_LT) && (itsOp <= COMPARE_GT)) ? (ICodeOp)(BRANCH_LT + (itsOp - COMPARE_LT)) : NOP; } ICodeOp opcode() { return itsOp; } }; template class Instruction_1 : public Instruction { public: Instruction_1(ICodeOp op, Operand1 operand1) : Instruction(op), itsOperand1(operand1) { } Operand1 itsOperand1; Operand1& o1() { return itsOperand1; } }; template class Instruction_2 : public Instruction { public: Instruction_2(ICodeOp op, Operand1 operand1, Operand2 operand2) : Instruction(op), itsOperand1(operand1), itsOperand2(operand2) { } Operand1 itsOperand1; Operand2 itsOperand2; Operand1& o1() { return itsOperand1; } Operand2& o2() { return itsOperand2; } }; template class Instruction_3 : public Instruction { public: Instruction_3(ICodeOp op, Operand1 operand1, Operand2 operand2, Operand3 operand3) : Instruction(op), itsOperand1(operand1), itsOperand2(operand2), itsOperand3(operand3) { } Operand1 itsOperand1; Operand2 itsOperand2; Operand3 itsOperand3; Operand1& o1() { return itsOperand1; } Operand2& o2() { return itsOperand2; } Operand3& o3() { return itsOperand3; } }; typedef Instruction_3 GetProp, SetProp; typedef Instruction_2 LoadName, SaveName; typedef Instruction_2 LoadImmediate; typedef Instruction_2 LoadVar, SaveVar; typedef Instruction_1 Branch; typedef Instruction_2 BranchCond; typedef Instruction_3 Arithmetic; typedef Instruction_3 Compare; typedef Instruction_2 Move; class Return : public Instruction_1 { public: Return(Register source) : Instruction_1(RETURN, source) {} }; class NewObject : public Instruction_1 { public: NewObject(Register dest) : Instruction_1(NEW_OBJECT, dest) {} }; typedef std::vector InstructionStream; typedef InstructionStream::iterator InstructionIterator; /****************************************************************/ class Label { public: Label(InstructionStream *base, int32 offset) : itsBase(base), itsOffset(offset) { } InstructionStream *itsBase; int32 itsOffset; }; typedef std::vector