Add a VirtualFrame class to the IA32 code generator. All frame

accesses (eg, parameters, locals, and the expression stack elements)
and mutation (pushes and pops) go through the virtual frame.

The frame initially contains no state, and directly emits instructions
in the obvious way.  It is not currently used for deferred code.
Review URL: http://codereview.chromium.org/7076

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@489 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent dc892fa7
This diff is collapsed.
......@@ -38,8 +38,66 @@ class DeferredCode;
// Mode to overwrite BinaryExpression values.
enum OverwriteMode { NO_OVERWRITE, OVERWRITE_LEFT, OVERWRITE_RIGHT };
enum InitState { CONST_INIT, NOT_CONST_INIT };
enum TypeofState { INSIDE_TYPEOF, NOT_INSIDE_TYPEOF };
// -------------------------------------------------------------------------
// Virtual frame
class VirtualFrame BASE_EMBEDDED {
public:
explicit VirtualFrame(CodeGenerator* cgen);
void Enter();
void Exit();
void AllocateLocals();
Operand Top() const { return Operand(esp, 0); }
Operand Element(int index) const {
return Operand(esp, index * kPointerSize);
}
Operand Local(int index) const {
ASSERT(0 <= index && index < frame_local_count_);
return Operand(ebp, kLocal0Offset - index * kPointerSize);
}
Operand Function() const { return Operand(ebp, kFunctionOffset); }
Operand Context() const { return Operand(ebp, kContextOffset); }
Operand Parameter(int index) const {
ASSERT(-1 <= index && index < parameter_count_);
return Operand(ebp, (1 + parameter_count_ - index) * kPointerSize);
}
Operand Receiver() const { return Parameter(-1); }
inline void Drop(int count);
inline void Pop();
inline void Pop(Register reg);
inline void Pop(Operand operand);
// -----------------------------------------------------------------------------
inline void Push(Register reg);
inline void Push(Operand operand);
inline void Push(Immediate immediate);
private:
static const int kLocal0Offset = JavaScriptFrameConstants::kLocal0Offset;
static const int kFunctionOffset = JavaScriptFrameConstants::kFunctionOffset;
static const int kContextOffset = StandardFrameConstants::kContextOffset;
MacroAssembler* masm_;
int frame_local_count_;
int parameter_count_;
};
// -------------------------------------------------------------------------
// Reference support
// A reference is a C++ stack-allocated object that keeps an ECMA
......@@ -49,9 +107,6 @@ enum OverwriteMode { NO_OVERWRITE, OVERWRITE_LEFT, OVERWRITE_RIGHT };
// For properties, we keep either one (named) or two (indexed) values
// on the execution stack to represent the reference.
enum InitState { CONST_INIT, NOT_CONST_INIT };
enum TypeofState { INSIDE_TYPEOF, NOT_INSIDE_TYPEOF };
class Reference BASE_EMBEDDED {
public:
// The values of the types is important, see size().
......@@ -135,10 +190,9 @@ class CodeGenState BASE_EMBEDDED {
// -----------------------------------------------------------------------------
// -------------------------------------------------------------------------
// CodeGenerator
//
class CodeGenerator: public Visitor {
public:
// Takes a function literal, generates code for it. This function should only
......@@ -159,6 +213,8 @@ class CodeGenerator: public Visitor {
// Accessors
MacroAssembler* masm() { return masm_; }
VirtualFrame* frame() const { return frame_; }
CodeGenState* state() { return state_; }
void set_state(CodeGenState* state) { state_ = state; }
......@@ -196,19 +252,6 @@ class CodeGenerator: public Visitor {
void LoadReference(Reference* ref);
void UnloadReference(Reference* ref);
// Support functions for accessing parameters and other operands.
Operand ParameterOperand(int index) const {
int num_parameters = scope()->num_parameters();
ASSERT(-2 <= index && index < num_parameters);
return Operand(ebp, (1 + num_parameters - index) * kPointerSize);
}
Operand ReceiverOperand() const { return ParameterOperand(-1); }
Operand FunctionOperand() const {
return Operand(ebp, JavaScriptFrameConstants::kFunctionOffset);
}
Operand ContextOperand(Register context, int index) const {
return Operand(context, Context::SlotOffset(index));
}
......@@ -349,11 +392,6 @@ class CodeGenerator: public Visitor {
// should be generated or not.
void RecordStatementPosition(Node* node);
// Activation frames.
void EnterJSFrame();
void ExitJSFrame();
bool is_eval_; // Tells whether code is generated for eval.
Handle<Script> script_;
List<DeferredCode*> deferred_;
......@@ -363,6 +401,7 @@ class CodeGenerator: public Visitor {
// Code generation state
Scope* scope_;
VirtualFrame* frame_;
Condition cc_reg_;
CodeGenState* state_;
bool is_inside_try_;
......@@ -371,10 +410,8 @@ class CodeGenerator: public Visitor {
// Labels
Label function_return_;
friend class VirtualFrame;
friend class Reference;
friend class Property;
friend class VariableProxy;
friend class Slot;
DISALLOW_COPY_AND_ASSIGN(CodeGenerator);
};
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment