Index: src/codegen-arm.cc |
=================================================================== |
--- src/codegen-arm.cc (revision 479) |
+++ src/codegen-arm.cc (working copy) |
@@ -30,269 +30,15 @@ |
#include "bootstrapper.h" |
#include "codegen-inl.h" |
#include "debug.h" |
-#include "prettyprinter.h" |
-#include "scopeinfo.h" |
#include "scopes.h" |
#include "runtime.h" |
namespace v8 { namespace internal { |
-class ArmCodeGenerator; |
- |
- |
-// ----------------------------------------------------------------------------- |
-// Reference support |
- |
-// A reference is a C++ stack-allocated object that keeps an ECMA |
-// reference on the execution stack while in scope. For variables |
-// the reference is empty, indicating that it isn't necessary to |
-// store state on the stack for keeping track of references to those. |
-// 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(). |
- enum Type { ILLEGAL = -1, SLOT = 0, NAMED = 1, KEYED = 2 }; |
- Reference(ArmCodeGenerator* cgen, Expression* expression); |
- ~Reference(); |
- |
- Expression* expression() const { return expression_; } |
- Type type() const { return type_; } |
- void set_type(Type value) { |
- ASSERT(type_ == ILLEGAL); |
- type_ = value; |
- } |
- // The size of the reference or -1 if the reference is illegal. |
- int size() const { return type_; } |
- |
- bool is_illegal() const { return type_ == ILLEGAL; } |
- bool is_slot() const { return type_ == SLOT; } |
- bool is_property() const { return type_ == NAMED || type_ == KEYED; } |
- |
- // Return the name. Only valid for named property references. |
- Handle<String> GetName(); |
- |
- // Generate code to push the value of the reference on top of the |
- // expression stack. The reference is expected to be already on top of |
- // the expression stack, and it is left in place with its value above it. |
- void GetValue(TypeofState typeof_state); |
- |
- // Generate code to store the value on top of the expression stack in the |
- // reference. The reference is expected to be immediately below the value |
- // on the expression stack. The stored value is left in place (with the |
- // reference intact below it) to support chained assignments. |
- void SetValue(InitState init_state); |
- |
- private: |
- ArmCodeGenerator* cgen_; |
- Expression* expression_; |
- Type type_; |
-}; |
- |
- |
// ------------------------------------------------------------------------- |
-// Code generation state |
- |
-// The state is passed down the AST by the code generator (and back up, in |
-// the form of the state of the label pair). It is threaded through the |
-// call stack. Constructing a state implicitly pushes it on the owning code |
-// generator's stack of states, and destroying one implicitly pops it. |
- |
-class CodeGenState BASE_EMBEDDED { |
- public: |
- // Create an initial code generator state. Destroying the initial state |
- // leaves the code generator with a NULL state. |
- explicit CodeGenState(ArmCodeGenerator* owner); |
- |
- // Create a code generator state based on a code generator's current |
- // state. The new state has its own typeof state and pair of branch |
- // labels. |
- CodeGenState(ArmCodeGenerator* owner, |
- TypeofState typeof_state, |
- Label* true_target, |
- Label* false_target); |
- |
- // Destroy a code generator state and restore the owning code generator's |
- // previous state. |
- ~CodeGenState(); |
- |
- TypeofState typeof_state() const { return typeof_state_; } |
- Label* true_target() const { return true_target_; } |
- Label* false_target() const { return false_target_; } |
- |
- private: |
- ArmCodeGenerator* owner_; |
- TypeofState typeof_state_; |
- Label* true_target_; |
- Label* false_target_; |
- CodeGenState* previous_; |
-}; |
- |
- |
-// ----------------------------------------------------------------------------- |
-// ArmCodeGenerator |
- |
-class ArmCodeGenerator: public CodeGenerator { |
- public: |
- static Handle<Code> MakeCode(FunctionLiteral* fun, |
- Handle<Script> script, |
- bool is_eval); |
- |
- MacroAssembler* masm() { return masm_; } |
- |
- Scope* scope() const { return scope_; } |
- |
- CodeGenState* state() { return state_; } |
- void set_state(CodeGenState* state) { state_ = state; } |
- |
- private: |
- // Assembler |
- MacroAssembler* masm_; // to generate code |
- |
- // Code generation state |
- Scope* scope_; |
- Condition cc_reg_; |
- CodeGenState* state_; |
- int break_stack_height_; |
- |
- // Labels |
- Label function_return_; |
- |
- // Construction/destruction |
- ArmCodeGenerator(int buffer_size, |
- Handle<Script> script, |
- bool is_eval); |
- |
- virtual ~ArmCodeGenerator() { delete masm_; } |
- |
- // Main code generation function |
- void GenCode(FunctionLiteral* fun); |
- |
- // The following are used by class Reference. |
- void LoadReference(Reference* ref); |
- void UnloadReference(Reference* ref); |
- |
- // State |
- bool has_cc() const { return cc_reg_ != al; } |
- TypeofState typeof_state() const { return state_->typeof_state(); } |
- Label* true_target() const { return state_->true_target(); } |
- Label* false_target() const { return state_->false_target(); } |
- |
- |
- // Expressions |
- MemOperand GlobalObject() const { |
- return ContextOperand(cp, Context::GLOBAL_INDEX); |
- } |
- |
- MemOperand ContextOperand(Register context, int index) const { |
- return MemOperand(context, Context::SlotOffset(index)); |
- } |
- |
- MemOperand ParameterOperand(int index) const { |
- int num_parameters = scope()->num_parameters(); |
- // index -2 corresponds to the activated closure, -1 corresponds |
- // to the receiver |
- ASSERT(-2 <= index && index < num_parameters); |
- int offset = (1 + num_parameters - index) * kPointerSize; |
- return MemOperand(fp, offset); |
- } |
- |
- MemOperand FunctionOperand() const { |
- return MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset); |
- } |
- |
- MemOperand SlotOperand(Slot* slot, Register tmp); |
- |
- void LoadCondition(Expression* x, |
- TypeofState typeof_state, |
- Label* true_target, |
- Label* false_target, |
- bool force_cc); |
- void Load(Expression* x, TypeofState typeof_state = NOT_INSIDE_TYPEOF); |
- void LoadGlobal(); |
- |
- // Read a value from a slot and leave it on top of the expression stack. |
- void LoadFromSlot(Slot* slot, TypeofState typeof_state); |
- |
- // Special code for typeof expressions: Unfortunately, we must |
- // be careful when loading the expression in 'typeof' |
- // expressions. We are not allowed to throw reference errors for |
- // non-existing properties of the global object, so we must make it |
- // look like an explicit property access, instead of an access |
- // through the context chain. |
- void LoadTypeofExpression(Expression* x); |
- |
- void ToBoolean(Label* true_target, Label* false_target); |
- |
- void GenericBinaryOperation(Token::Value op); |
- void Comparison(Condition cc, bool strict = false); |
- |
- void SmiOperation(Token::Value op, Handle<Object> value, bool reversed); |
- |
- void CallWithArguments(ZoneList<Expression*>* arguments, int position); |
- |
- // Declare global variables and functions in the given array of |
- // name/value pairs. |
- virtual void DeclareGlobals(Handle<FixedArray> pairs); |
- |
- // Instantiate the function boilerplate. |
- void InstantiateBoilerplate(Handle<JSFunction> boilerplate); |
- |
- // Control flow |
- void Branch(bool if_true, Label* L); |
- void CheckStack(); |
- void CleanStack(int num_bytes); |
- |
- // Node visitors |
-#define DEF_VISIT(type) \ |
- virtual void Visit##type(type* node); |
- NODE_LIST(DEF_VISIT) |
-#undef DEF_VISIT |
- |
- // Fast-case switch |
- static const int kFastCaseSwitchMaxOverheadFactor = 10; |
- static const int kFastCaseSwitchMinCaseCount = 5; |
- virtual int FastCaseSwitchMaxOverheadFactor(); |
- virtual int FastCaseSwitchMinCaseCount(); |
- virtual void GenerateFastCaseSwitchJumpTable( |
- SwitchStatement* node, int min_index, int range, Label *fail_label, |
- SmartPointer<Label*> &case_targets, SmartPointer<Label> &case_labels); |
- |
- void RecordStatementPosition(Node* node); |
- |
- // Activation frames |
- void EnterJSFrame(); |
- void ExitJSFrame(); |
- |
- virtual void GenerateIsSmi(ZoneList<Expression*>* args); |
- virtual void GenerateIsNonNegativeSmi(ZoneList<Expression*>* args); |
- virtual void GenerateIsArray(ZoneList<Expression*>* args); |
- |
- virtual void GenerateArgumentsLength(ZoneList<Expression*>* args); |
- virtual void GenerateArgumentsAccess(ZoneList<Expression*>* args); |
- |
- virtual void GenerateValueOf(ZoneList<Expression*>* args); |
- virtual void GenerateSetValueOf(ZoneList<Expression*>* args); |
- |
- virtual void GenerateFastCharCodeAt(ZoneList<Expression*>* args); |
- |
- virtual void GenerateObjectEquals(ZoneList<Expression*>* args); |
- |
- friend class Reference; |
- friend class Property; |
- friend class VariableProxy; |
- friend class Slot; |
-}; |
- |
- |
-// ------------------------------------------------------------------------- |
// CodeGenState implementation. |
-CodeGenState::CodeGenState(ArmCodeGenerator* owner) |
+CodeGenState::CodeGenState(CodeGenerator* owner) |
: owner_(owner), |
typeof_state_(NOT_INSIDE_TYPEOF), |
true_target_(NULL), |
@@ -302,7 +48,7 @@ |
} |
-CodeGenState::CodeGenState(ArmCodeGenerator* owner, |
+CodeGenState::CodeGenState(CodeGenerator* owner, |
TypeofState typeof_state, |
Label* true_target, |
Label* false_target) |
@@ -322,98 +68,15 @@ |
// ----------------------------------------------------------------------------- |
-// ArmCodeGenerator implementation |
+// CodeGenerator implementation |
#define __ masm_-> |
-Handle<Code> ArmCodeGenerator::MakeCode(FunctionLiteral* flit, |
- Handle<Script> script, |
- bool is_eval) { |
-#ifdef ENABLE_DISASSEMBLER |
- bool print_code = FLAG_print_code && !Bootstrapper::IsActive(); |
-#endif // ENABLE_DISASSEMBLER |
- |
-#ifdef DEBUG |
- bool print_source = false; |
- bool print_ast = false; |
- const char* ftype; |
- |
- if (Bootstrapper::IsActive()) { |
- print_source = FLAG_print_builtin_source; |
- print_ast = FLAG_print_builtin_ast; |
- print_code = FLAG_print_builtin_code; |
- ftype = "builtin"; |
- } else { |
- print_source = FLAG_print_source; |
- print_ast = FLAG_print_ast; |
- ftype = "user-defined"; |
- } |
- |
- if (FLAG_trace_codegen || print_source || print_ast) { |
- PrintF("*** Generate code for %s function: ", ftype); |
- flit->name()->ShortPrint(); |
- PrintF(" ***\n"); |
- } |
- |
- if (print_source) { |
- PrintF("--- Source from AST ---\n%s\n", PrettyPrinter().PrintProgram(flit)); |
- } |
- |
- if (print_ast) { |
- PrintF("--- AST ---\n%s\n", AstPrinter().PrintProgram(flit)); |
- } |
-#endif // DEBUG |
- |
- // Generate code. |
- const int initial_buffer_size = 4 * KB; |
- ArmCodeGenerator cgen(initial_buffer_size, script, is_eval); |
- cgen.GenCode(flit); |
- if (cgen.HasStackOverflow()) { |
- ASSERT(!Top::has_pending_exception()); |
- return Handle<Code>::null(); |
- } |
- |
- // Process any deferred code. |
- cgen.ProcessDeferred(); |
- |
- // Allocate and install the code. |
- CodeDesc desc; |
- cgen.masm()->GetCode(&desc); |
- ScopeInfo<> sinfo(flit->scope()); |
- Code::Flags flags = Code::ComputeFlags(Code::FUNCTION); |
- Handle<Code> code = Factory::NewCode(desc, &sinfo, flags); |
- |
- // Add unresolved entries in the code to the fixup list. |
- Bootstrapper::AddFixup(*code, cgen.masm()); |
- |
-#ifdef ENABLE_DISASSEMBLER |
- if (print_code) { |
- // Print the source code if available. |
- if (!script->IsUndefined() && !script->source()->IsUndefined()) { |
- PrintF("--- Raw source ---\n"); |
- StringInputBuffer stream(String::cast(script->source())); |
- stream.Seek(flit->start_position()); |
- // flit->end_position() points to the last character in the stream. We |
- // need to compensate by adding one to calculate the length. |
- int source_len = flit->end_position() - flit->start_position() + 1; |
- for (int i = 0; i < source_len; i++) { |
- if (stream.has_more()) PrintF("%c", stream.GetNext()); |
- } |
- PrintF("\n\n"); |
- } |
- PrintF("--- Code ---\n"); |
- code->Disassemble(); |
- } |
-#endif // ENABLE_DISASSEMBLER |
- |
- return code; |
-} |
- |
- |
-ArmCodeGenerator::ArmCodeGenerator(int buffer_size, |
- Handle<Script> script, |
- bool is_eval) |
- : CodeGenerator(is_eval, script), |
+CodeGenerator::CodeGenerator(int buffer_size, Handle<Script> script, |
+ bool is_eval) |
+ : is_eval_(is_eval), |
+ script_(script), |
+ deferred_(8), |
masm_(new MacroAssembler(NULL, buffer_size)), |
scope_(NULL), |
cc_reg_(al), |
@@ -430,7 +93,7 @@ |
// pp: caller's parameter pointer |
// cp: callee's context |
-void ArmCodeGenerator::GenCode(FunctionLiteral* fun) { |
+void CodeGenerator::GenCode(FunctionLiteral* fun) { |
Scope* scope = fun->scope(); |
ZoneList<Statement*>* body = fun->body(); |
@@ -620,7 +283,7 @@ |
} |
-MemOperand ArmCodeGenerator::SlotOperand(Slot* slot, Register tmp) { |
+MemOperand CodeGenerator::SlotOperand(Slot* slot, Register tmp) { |
// Currently, this assertion will fail if we try to assign to |
// a constant variable that is constant because it is read-only |
// (such as the variable referring to a named function expression). |
@@ -679,7 +342,7 @@ |
// code register. If force_cc is set, the value is forced to set the condition |
// code register and no value is pushed. If the condition code register was set, |
// has_cc() is true and cc_reg_ contains the condition to test for 'true'. |
-void ArmCodeGenerator::LoadCondition(Expression* x, |
+void CodeGenerator::LoadCondition(Expression* x, |
TypeofState typeof_state, |
Label* true_target, |
Label* false_target, |
@@ -697,7 +360,7 @@ |
} |
-void ArmCodeGenerator::Load(Expression* x, TypeofState typeof_state) { |
+void CodeGenerator::Load(Expression* x, TypeofState typeof_state) { |
Label true_target; |
Label false_target; |
LoadCondition(x, typeof_state, &true_target, &false_target, false); |
@@ -746,7 +409,7 @@ |
} |
-void ArmCodeGenerator::LoadGlobal() { |
+void CodeGenerator::LoadGlobal() { |
__ ldr(r0, GlobalObject()); |
__ push(r0); |
} |
@@ -755,7 +418,7 @@ |
// TODO(1241834): Get rid of this function in favor of just using Load, now |
// that we have the INSIDE_TYPEOF typeof state. => Need to handle global |
// variables w/o reference errors elsewhere. |
-void ArmCodeGenerator::LoadTypeofExpression(Expression* x) { |
+void CodeGenerator::LoadTypeofExpression(Expression* x) { |
Variable* variable = x->AsVariableProxy()->AsVariable(); |
if (variable != NULL && !variable->is_this() && variable->is_global()) { |
// NOTE: This is somewhat nasty. We force the compiler to load |
@@ -773,7 +436,7 @@ |
} |
-Reference::Reference(ArmCodeGenerator* cgen, Expression* expression) |
+Reference::Reference(CodeGenerator* cgen, Expression* expression) |
: cgen_(cgen), expression_(expression), type_(ILLEGAL) { |
cgen->LoadReference(this); |
} |
@@ -784,8 +447,9 @@ |
} |
-void ArmCodeGenerator::LoadReference(Reference* ref) { |
+void CodeGenerator::LoadReference(Reference* ref) { |
Comment cmnt(masm_, "[ LoadReference"); |
+ |
Expression* e = ref->expression(); |
Property* property = e->AsProperty(); |
Variable* var = e->AsVariableProxy()->AsVariable(); |
@@ -826,8 +490,9 @@ |
} |
-void ArmCodeGenerator::UnloadReference(Reference* ref) { |
+void CodeGenerator::UnloadReference(Reference* ref) { |
Comment cmnt(masm_, "[ UnloadReference"); |
+ |
int size = ref->size(); |
if (size <= 0) { |
// Do nothing. No popping is necessary. |
@@ -842,7 +507,7 @@ |
// ECMA-262, section 9.2, page 30: ToBoolean(). Convert the given |
// register to a boolean in the condition code register. The code |
// may jump to 'false_target' in case the register converts to 'false'. |
-void ArmCodeGenerator::ToBoolean(Label* true_target, |
+void CodeGenerator::ToBoolean(Label* true_target, |
Label* false_target) { |
// Note: The generated code snippet does not change stack variables. |
// Only the condition code should be set. |
@@ -957,7 +622,7 @@ |
}; |
-void ArmCodeGenerator::GenericBinaryOperation(Token::Value op) { |
+void CodeGenerator::GenericBinaryOperation(Token::Value op) { |
// sp[0] : y |
// sp[1] : x |
// result : r0 |
@@ -1082,7 +747,7 @@ |
}; |
-void ArmCodeGenerator::SmiOperation(Token::Value op, |
+void CodeGenerator::SmiOperation(Token::Value op, |
Handle<Object> value, |
bool reversed) { |
// NOTE: This is an attempt to inline (a bit) more of the code for |
@@ -1217,7 +882,7 @@ |
} |
-void ArmCodeGenerator::Comparison(Condition cc, bool strict) { |
+void CodeGenerator::Comparison(Condition cc, bool strict) { |
// sp[0] : y |
// sp[1] : x |
// result : cc register |
@@ -1298,7 +963,7 @@ |
// Call the function on the stack with the given arguments. |
-void ArmCodeGenerator::CallWithArguments(ZoneList<Expression*>* args, |
+void CodeGenerator::CallWithArguments(ZoneList<Expression*>* args, |
int position) { |
// Push the arguments ("left-to-right") on the stack. |
for (int i = 0; i < args->length(); i++) { |
@@ -1318,7 +983,7 @@ |
} |
-void ArmCodeGenerator::Branch(bool if_true, Label* L) { |
+void CodeGenerator::Branch(bool if_true, Label* L) { |
ASSERT(has_cc()); |
Condition cc = if_true ? cc_reg_ : NegateCondition(cc_reg_); |
__ b(cc, L); |
@@ -1326,7 +991,7 @@ |
} |
-void ArmCodeGenerator::CheckStack() { |
+void CodeGenerator::CheckStack() { |
if (FLAG_check_stack) { |
Comment cmnt(masm_, "[ check stack"); |
StackCheckStub stub; |
@@ -1335,7 +1000,7 @@ |
} |
-void ArmCodeGenerator::VisitBlock(Block* node) { |
+void CodeGenerator::VisitBlock(Block* node) { |
Comment cmnt(masm_, "[ Block"); |
if (FLAG_debug_info) RecordStatementPosition(node); |
node->set_break_stack_height(break_stack_height_); |
@@ -1344,7 +1009,7 @@ |
} |
-void ArmCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { |
+void CodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { |
__ mov(r0, Operand(pairs)); |
__ push(r0); |
__ push(cp); |
@@ -1355,7 +1020,7 @@ |
} |
-void ArmCodeGenerator::VisitDeclaration(Declaration* node) { |
+void CodeGenerator::VisitDeclaration(Declaration* node) { |
Comment cmnt(masm_, "[ Declaration"); |
Variable* var = node->proxy()->var(); |
ASSERT(var != NULL); // must have been resolved |
@@ -1420,7 +1085,7 @@ |
} |
-void ArmCodeGenerator::VisitExpressionStatement(ExpressionStatement* node) { |
+void CodeGenerator::VisitExpressionStatement(ExpressionStatement* node) { |
Comment cmnt(masm_, "[ ExpressionStatement"); |
if (FLAG_debug_info) RecordStatementPosition(node); |
Expression* expression = node->expression(); |
@@ -1430,13 +1095,13 @@ |
} |
-void ArmCodeGenerator::VisitEmptyStatement(EmptyStatement* node) { |
+void CodeGenerator::VisitEmptyStatement(EmptyStatement* node) { |
Comment cmnt(masm_, "// EmptyStatement"); |
// nothing to do |
} |
-void ArmCodeGenerator::VisitIfStatement(IfStatement* node) { |
+void CodeGenerator::VisitIfStatement(IfStatement* node) { |
Comment cmnt(masm_, "[ IfStatement"); |
// Generate different code depending on which |
// parts of the if statement are present or not. |
@@ -1500,7 +1165,7 @@ |
} |
-void ArmCodeGenerator::CleanStack(int num_bytes) { |
+void CodeGenerator::CleanStack(int num_bytes) { |
ASSERT(num_bytes >= 0); |
if (num_bytes > 0) { |
__ add(sp, sp, Operand(num_bytes)); |
@@ -1508,7 +1173,7 @@ |
} |
-void ArmCodeGenerator::VisitContinueStatement(ContinueStatement* node) { |
+void CodeGenerator::VisitContinueStatement(ContinueStatement* node) { |
Comment cmnt(masm_, "[ ContinueStatement"); |
if (FLAG_debug_info) RecordStatementPosition(node); |
CleanStack(break_stack_height_ - node->target()->break_stack_height()); |
@@ -1516,7 +1181,7 @@ |
} |
-void ArmCodeGenerator::VisitBreakStatement(BreakStatement* node) { |
+void CodeGenerator::VisitBreakStatement(BreakStatement* node) { |
Comment cmnt(masm_, "[ BreakStatement"); |
if (FLAG_debug_info) RecordStatementPosition(node); |
CleanStack(break_stack_height_ - node->target()->break_stack_height()); |
@@ -1524,7 +1189,7 @@ |
} |
-void ArmCodeGenerator::VisitReturnStatement(ReturnStatement* node) { |
+void CodeGenerator::VisitReturnStatement(ReturnStatement* node) { |
Comment cmnt(masm_, "[ ReturnStatement"); |
if (FLAG_debug_info) RecordStatementPosition(node); |
Load(node->expression()); |
@@ -1535,7 +1200,7 @@ |
} |
-void ArmCodeGenerator::VisitWithEnterStatement(WithEnterStatement* node) { |
+void CodeGenerator::VisitWithEnterStatement(WithEnterStatement* node) { |
Comment cmnt(masm_, "[ WithEnterStatement"); |
if (FLAG_debug_info) RecordStatementPosition(node); |
Load(node->expression()); |
@@ -1552,7 +1217,7 @@ |
} |
-void ArmCodeGenerator::VisitWithExitStatement(WithExitStatement* node) { |
+void CodeGenerator::VisitWithExitStatement(WithExitStatement* node) { |
Comment cmnt(masm_, "[ WithExitStatement"); |
// Pop context. |
__ ldr(cp, ContextOperand(cp, Context::PREVIOUS_INDEX)); |
@@ -1561,16 +1226,16 @@ |
} |
-int ArmCodeGenerator::FastCaseSwitchMaxOverheadFactor() { |
- return kFastCaseSwitchMaxOverheadFactor; |
+int CodeGenerator::FastCaseSwitchMaxOverheadFactor() { |
+ return kFastSwitchMaxOverheadFactor; |
} |
-int ArmCodeGenerator::FastCaseSwitchMinCaseCount() { |
- return kFastCaseSwitchMinCaseCount; |
+int CodeGenerator::FastCaseSwitchMinCaseCount() { |
+ return kFastSwitchMinCaseCount; |
} |
-void ArmCodeGenerator::GenerateFastCaseSwitchJumpTable( |
+void CodeGenerator::GenerateFastCaseSwitchJumpTable( |
SwitchStatement* node, int min_index, int range, Label *fail_label, |
SmartPointer<Label*> &case_targets, SmartPointer<Label> &case_labels) { |
@@ -1603,7 +1268,7 @@ |
} |
-void ArmCodeGenerator::VisitSwitchStatement(SwitchStatement* node) { |
+void CodeGenerator::VisitSwitchStatement(SwitchStatement* node) { |
Comment cmnt(masm_, "[ SwitchStatement"); |
if (FLAG_debug_info) RecordStatementPosition(node); |
node->set_break_stack_height(break_stack_height_); |
@@ -1671,7 +1336,7 @@ |
} |
-void ArmCodeGenerator::VisitLoopStatement(LoopStatement* node) { |
+void CodeGenerator::VisitLoopStatement(LoopStatement* node) { |
Comment cmnt(masm_, "[ LoopStatement"); |
if (FLAG_debug_info) RecordStatementPosition(node); |
node->set_break_stack_height(break_stack_height_); |
@@ -1743,7 +1408,7 @@ |
} |
-void ArmCodeGenerator::VisitForInStatement(ForInStatement* node) { |
+void CodeGenerator::VisitForInStatement(ForInStatement* node) { |
Comment cmnt(masm_, "[ ForInStatement"); |
if (FLAG_debug_info) RecordStatementPosition(node); |
@@ -1931,7 +1596,7 @@ |
} |
-void ArmCodeGenerator::VisitTryCatch(TryCatch* node) { |
+void CodeGenerator::VisitTryCatch(TryCatch* node) { |
Comment cmnt(masm_, "[ TryCatch"); |
Label try_block, exit; |
@@ -2020,7 +1685,7 @@ |
} |
-void ArmCodeGenerator::VisitTryFinally(TryFinally* node) { |
+void CodeGenerator::VisitTryFinally(TryFinally* node) { |
Comment cmnt(masm_, "[ TryFinally"); |
// State: Used to keep track of reason for entering the finally |
@@ -2153,7 +1818,7 @@ |
} |
-void ArmCodeGenerator::VisitDebuggerStatement(DebuggerStatement* node) { |
+void CodeGenerator::VisitDebuggerStatement(DebuggerStatement* node) { |
Comment cmnt(masm_, "[ DebuggerStatament"); |
if (FLAG_debug_info) RecordStatementPosition(node); |
__ CallRuntime(Runtime::kDebugBreak, 1); |
@@ -2161,7 +1826,7 @@ |
} |
-void ArmCodeGenerator::InstantiateBoilerplate(Handle<JSFunction> boilerplate) { |
+void CodeGenerator::InstantiateBoilerplate(Handle<JSFunction> boilerplate) { |
ASSERT(boilerplate->IsBoilerplate()); |
// Push the boilerplate on the stack. |
@@ -2175,7 +1840,7 @@ |
} |
-void ArmCodeGenerator::VisitFunctionLiteral(FunctionLiteral* node) { |
+void CodeGenerator::VisitFunctionLiteral(FunctionLiteral* node) { |
Comment cmnt(masm_, "[ FunctionLiteral"); |
// Build the function boilerplate and instantiate it. |
@@ -2186,14 +1851,14 @@ |
} |
-void ArmCodeGenerator::VisitFunctionBoilerplateLiteral( |
+void CodeGenerator::VisitFunctionBoilerplateLiteral( |
FunctionBoilerplateLiteral* node) { |
Comment cmnt(masm_, "[ FunctionBoilerplateLiteral"); |
InstantiateBoilerplate(node->boilerplate()); |
} |
-void ArmCodeGenerator::VisitConditional(Conditional* node) { |
+void CodeGenerator::VisitConditional(Conditional* node) { |
Comment cmnt(masm_, "[ Conditional"); |
Label then, else_, exit; |
LoadCondition(node->condition(), NOT_INSIDE_TYPEOF, &then, &else_, true); |
@@ -2207,7 +1872,7 @@ |
} |
-void ArmCodeGenerator::LoadFromSlot(Slot* slot, TypeofState typeof_state) { |
+void CodeGenerator::LoadFromSlot(Slot* slot, TypeofState typeof_state) { |
if (slot->type() == Slot::LOOKUP) { |
ASSERT(slot->var()->mode() == Variable::DYNAMIC); |
@@ -2245,14 +1910,15 @@ |
} |
-void ArmCodeGenerator::VisitSlot(Slot* node) { |
+void CodeGenerator::VisitSlot(Slot* node) { |
Comment cmnt(masm_, "[ Slot"); |
LoadFromSlot(node, typeof_state()); |
} |
-void ArmCodeGenerator::VisitVariableProxy(VariableProxy* node) { |
+void CodeGenerator::VisitVariableProxy(VariableProxy* node) { |
Comment cmnt(masm_, "[ VariableProxy"); |
+ |
Variable* var = node->var(); |
Expression* expr = var->rewrite(); |
if (expr != NULL) { |
@@ -2265,14 +1931,14 @@ |
} |
-void ArmCodeGenerator::VisitLiteral(Literal* node) { |
+void CodeGenerator::VisitLiteral(Literal* node) { |
Comment cmnt(masm_, "[ Literal"); |
__ mov(r0, Operand(node->handle())); |
__ push(r0); |
} |
-void ArmCodeGenerator::VisitRegExpLiteral(RegExpLiteral* node) { |
+void CodeGenerator::VisitRegExpLiteral(RegExpLiteral* node) { |
Comment cmnt(masm_, "[ RexExp Literal"); |
// Retrieve the literal array and check the allocated entry. |
@@ -2343,7 +2009,7 @@ |
} |
-void ArmCodeGenerator::VisitObjectLiteral(ObjectLiteral* node) { |
+void CodeGenerator::VisitObjectLiteral(ObjectLiteral* node) { |
Comment cmnt(masm_, "[ ObjectLiteral"); |
ObjectLiteralDeferred* deferred = new ObjectLiteralDeferred(this, node); |
@@ -2416,7 +2082,7 @@ |
} |
-void ArmCodeGenerator::VisitArrayLiteral(ArrayLiteral* node) { |
+void CodeGenerator::VisitArrayLiteral(ArrayLiteral* node) { |
Comment cmnt(masm_, "[ ArrayLiteral"); |
// Call runtime to create the array literal. |
@@ -2460,7 +2126,7 @@ |
} |
-void ArmCodeGenerator::VisitAssignment(Assignment* node) { |
+void CodeGenerator::VisitAssignment(Assignment* node) { |
Comment cmnt(masm_, "[ Assignment"); |
if (FLAG_debug_info) RecordStatementPosition(node); |
@@ -2506,7 +2172,7 @@ |
} |
-void ArmCodeGenerator::VisitThrow(Throw* node) { |
+void CodeGenerator::VisitThrow(Throw* node) { |
Comment cmnt(masm_, "[ Throw"); |
Load(node->exception()); |
@@ -2516,14 +2182,15 @@ |
} |
-void ArmCodeGenerator::VisitProperty(Property* node) { |
+void CodeGenerator::VisitProperty(Property* node) { |
Comment cmnt(masm_, "[ Property"); |
+ |
Reference property(this, node); |
property.GetValue(typeof_state()); |
} |
-void ArmCodeGenerator::VisitCall(Call* node) { |
+void CodeGenerator::VisitCall(Call* node) { |
Comment cmnt(masm_, "[ Call"); |
ZoneList<Expression*>* args = node->arguments(); |
@@ -2649,7 +2316,7 @@ |
} |
-void ArmCodeGenerator::VisitCallNew(CallNew* node) { |
+void CodeGenerator::VisitCallNew(CallNew* node) { |
Comment cmnt(masm_, "[ CallNew"); |
// According to ECMA-262, section 11.2.2, page 44, the function |
@@ -2684,7 +2351,7 @@ |
} |
-void ArmCodeGenerator::GenerateValueOf(ZoneList<Expression*>* args) { |
+void CodeGenerator::GenerateValueOf(ZoneList<Expression*>* args) { |
ASSERT(args->length() == 1); |
Label leave; |
Load(args->at(0)); |
@@ -2705,7 +2372,7 @@ |
} |
-void ArmCodeGenerator::GenerateSetValueOf(ZoneList<Expression*>* args) { |
+void CodeGenerator::GenerateSetValueOf(ZoneList<Expression*>* args) { |
ASSERT(args->length() == 2); |
Label leave; |
Load(args->at(0)); // Load the object. |
@@ -2732,7 +2399,7 @@ |
} |
-void ArmCodeGenerator::GenerateIsSmi(ZoneList<Expression*>* args) { |
+void CodeGenerator::GenerateIsSmi(ZoneList<Expression*>* args) { |
ASSERT(args->length() == 1); |
Load(args->at(0)); |
__ pop(r0); |
@@ -2741,7 +2408,7 @@ |
} |
-void ArmCodeGenerator::GenerateIsNonNegativeSmi(ZoneList<Expression*>* args) { |
+void CodeGenerator::GenerateIsNonNegativeSmi(ZoneList<Expression*>* args) { |
ASSERT(args->length() == 1); |
Load(args->at(0)); |
__ pop(r0); |
@@ -2753,14 +2420,14 @@ |
// This should generate code that performs a charCodeAt() call or returns |
// undefined in order to trigger the slow case, Runtime_StringCharCodeAt. |
// It is not yet implemented on ARM, so it always goes to the slow case. |
-void ArmCodeGenerator::GenerateFastCharCodeAt(ZoneList<Expression*>* args) { |
+void CodeGenerator::GenerateFastCharCodeAt(ZoneList<Expression*>* args) { |
ASSERT(args->length() == 2); |
__ mov(r0, Operand(Factory::undefined_value())); |
__ push(r0); |
} |
-void ArmCodeGenerator::GenerateIsArray(ZoneList<Expression*>* args) { |
+void CodeGenerator::GenerateIsArray(ZoneList<Expression*>* args) { |
ASSERT(args->length() == 1); |
Load(args->at(0)); |
Label answer; |
@@ -2781,7 +2448,7 @@ |
} |
-void ArmCodeGenerator::GenerateArgumentsLength(ZoneList<Expression*>* args) { |
+void CodeGenerator::GenerateArgumentsLength(ZoneList<Expression*>* args) { |
ASSERT(args->length() == 0); |
// Seed the result with the formal parameters count, which will be used |
@@ -2795,7 +2462,7 @@ |
} |
-void ArmCodeGenerator::GenerateArgumentsAccess(ZoneList<Expression*>* args) { |
+void CodeGenerator::GenerateArgumentsAccess(ZoneList<Expression*>* args) { |
ASSERT(args->length() == 1); |
// Satisfy contract with ArgumentsAccessStub: |
@@ -2811,7 +2478,7 @@ |
} |
-void ArmCodeGenerator::GenerateObjectEquals(ZoneList<Expression*>* args) { |
+void CodeGenerator::GenerateObjectEquals(ZoneList<Expression*>* args) { |
ASSERT(args->length() == 2); |
// Load the two objects into registers and perform the comparison. |
@@ -2824,7 +2491,7 @@ |
} |
-void ArmCodeGenerator::VisitCallRuntime(CallRuntime* node) { |
+void CodeGenerator::VisitCallRuntime(CallRuntime* node) { |
if (CheckForInlineRuntimeCall(node)) return; |
ZoneList<Expression*>* args = node->arguments(); |
@@ -2860,7 +2527,7 @@ |
} |
-void ArmCodeGenerator::VisitUnaryOperation(UnaryOperation* node) { |
+void CodeGenerator::VisitUnaryOperation(UnaryOperation* node) { |
Comment cmnt(masm_, "[ UnaryOperation"); |
Token::Value op = node->op(); |
@@ -2985,7 +2652,7 @@ |
} |
-void ArmCodeGenerator::VisitCountOperation(CountOperation* node) { |
+void CodeGenerator::VisitCountOperation(CountOperation* node) { |
Comment cmnt(masm_, "[ CountOperation"); |
bool is_postfix = node->is_postfix(); |
@@ -3065,7 +2732,7 @@ |
} |
-void ArmCodeGenerator::VisitBinaryOperation(BinaryOperation* node) { |
+void CodeGenerator::VisitBinaryOperation(BinaryOperation* node) { |
Comment cmnt(masm_, "[ BinaryOperation"); |
Token::Value op = node->op(); |
@@ -3187,13 +2854,13 @@ |
} |
-void ArmCodeGenerator::VisitThisFunction(ThisFunction* node) { |
+void CodeGenerator::VisitThisFunction(ThisFunction* node) { |
__ ldr(r0, FunctionOperand()); |
__ push(r0); |
} |
-void ArmCodeGenerator::VisitCompareOperation(CompareOperation* node) { |
+void CodeGenerator::VisitCompareOperation(CompareOperation* node) { |
Comment cmnt(masm_, "[ CompareOperation"); |
// Get the expressions from the node. |
@@ -3388,7 +3055,7 @@ |
} |
-void ArmCodeGenerator::RecordStatementPosition(Node* node) { |
+void CodeGenerator::RecordStatementPosition(Node* node) { |
if (FLAG_debug_info) { |
int statement_pos = node->statement_pos(); |
if (statement_pos == RelocInfo::kNoPosition) return; |
@@ -3397,7 +3064,7 @@ |
} |
-void ArmCodeGenerator::EnterJSFrame() { |
+void CodeGenerator::EnterJSFrame() { |
#if defined(DEBUG) |
{ Label done, fail; |
__ tst(r1, Operand(kSmiTagMask)); |
@@ -3407,7 +3074,7 @@ |
__ cmp(r2, Operand(JS_FUNCTION_TYPE)); |
__ b(eq, &done); |
__ bind(&fail); |
- __ stop("ArmCodeGenerator::EnterJSFrame - r1 not a function"); |
+ __ stop("CodeGenerator::EnterJSFrame - r1 not a function"); |
__ bind(&done); |
} |
#endif // DEBUG |
@@ -3417,7 +3084,7 @@ |
} |
-void ArmCodeGenerator::ExitJSFrame() { |
+void CodeGenerator::ExitJSFrame() { |
// Drop the execution stack down to the frame pointer and restore the caller |
// frame pointer and return address. |
__ mov(sp, fp); |
@@ -4499,21 +4166,4 @@ |
#undef __ |
-// ----------------------------------------------------------------------------- |
-// CodeGenerator interface |
- |
-// MakeCode() is just a wrapper for CodeGenerator::MakeCode() |
-// so we don't have to expose the entire CodeGenerator class in |
-// the .h file. |
-Handle<Code> CodeGenerator::MakeCode(FunctionLiteral* fun, |
- Handle<Script> script, |
- bool is_eval) { |
- Handle<Code> code = ArmCodeGenerator::MakeCode(fun, script, is_eval); |
- if (!code.is_null()) { |
- Counters::total_compiled_code_size.Increment(code->instruction_size()); |
- } |
- return code; |
-} |
- |
- |
} } // namespace v8::internal |