00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #ifndef V8_CODEGEN_ARM_H_
00029 #define V8_CODEGEN_ARM_H_
00030
00031 #include "scopes.h"
00032
00033 namespace v8 { namespace internal {
00034
00035
00036 class DeferredCode;
00037
00038
00039 enum OverwriteMode { NO_OVERWRITE, OVERWRITE_LEFT, OVERWRITE_RIGHT };
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052 enum InitState { CONST_INIT, NOT_CONST_INIT };
00053 enum TypeofState { INSIDE_TYPEOF, NOT_INSIDE_TYPEOF };
00054
00055 class Reference BASE_EMBEDDED {
00056 public:
00057
00058 enum Type { ILLEGAL = -1, SLOT = 0, NAMED = 1, KEYED = 2 };
00059 Reference(CodeGenerator* cgen, Expression* expression);
00060 ~Reference();
00061
00062 Expression* expression() const { return expression_; }
00063 Type type() const { return type_; }
00064 void set_type(Type value) {
00065 ASSERT(type_ == ILLEGAL);
00066 type_ = value;
00067 }
00068
00069
00070 int size() const { return type_; }
00071
00072 bool is_illegal() const { return type_ == ILLEGAL; }
00073 bool is_slot() const { return type_ == SLOT; }
00074 bool is_property() const { return type_ == NAMED || type_ == KEYED; }
00075
00076
00077 Handle<String> GetName();
00078
00079
00080
00081
00082 void GetValue(TypeofState typeof_state);
00083
00084
00085
00086
00087
00088 void SetValue(InitState init_state);
00089
00090 private:
00091 CodeGenerator* cgen_;
00092 Expression* expression_;
00093 Type type_;
00094 };
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105 class CodeGenState BASE_EMBEDDED {
00106 public:
00107
00108
00109 explicit CodeGenState(CodeGenerator* owner);
00110
00111
00112
00113
00114 CodeGenState(CodeGenerator* owner,
00115 TypeofState typeof_state,
00116 Label* true_target,
00117 Label* false_target);
00118
00119
00120
00121 ~CodeGenState();
00122
00123 TypeofState typeof_state() const { return typeof_state_; }
00124 Label* true_target() const { return true_target_; }
00125 Label* false_target() const { return false_target_; }
00126
00127 private:
00128 CodeGenerator* owner_;
00129 TypeofState typeof_state_;
00130 Label* true_target_;
00131 Label* false_target_;
00132 CodeGenState* previous_;
00133 };
00134
00135
00136
00137
00138
00139 class CodeGenerator: public Visitor {
00140 public:
00141
00142
00143 static Handle<Code> MakeCode(FunctionLiteral* fun,
00144 Handle<Script> script,
00145 bool is_eval);
00146
00147 static void SetFunctionInfo(Handle<JSFunction> fun,
00148 int length,
00149 int function_token_position,
00150 int start_position,
00151 int end_position,
00152 bool is_expression,
00153 bool is_toplevel,
00154 Handle<Script> script);
00155
00156
00157 MacroAssembler* masm() { return masm_; }
00158
00159 CodeGenState* state() { return state_; }
00160 void set_state(CodeGenState* state) { state_ = state; }
00161
00162 void AddDeferred(DeferredCode* code) { deferred_.Add(code); }
00163
00164 private:
00165
00166 CodeGenerator(int buffer_size, Handle<Script> script, bool is_eval);
00167 virtual ~CodeGenerator() { delete masm_; }
00168
00169
00170 Scope* scope() const { return scope_; }
00171
00172 void ProcessDeferred();
00173
00174 bool is_eval() { return is_eval_; }
00175
00176
00177 bool has_cc() const { return cc_reg_ != al; }
00178 TypeofState typeof_state() const { return state_->typeof_state(); }
00179 Label* true_target() const { return state_->true_target(); }
00180 Label* false_target() const { return state_->false_target(); }
00181
00182
00183
00184 #define DEF_VISIT(type) \
00185 void Visit##type(type* node);
00186 NODE_LIST(DEF_VISIT)
00187 #undef DEF_VISIT
00188
00189
00190 void GenCode(FunctionLiteral* fun);
00191
00192
00193 void LoadReference(Reference* ref);
00194 void UnloadReference(Reference* ref);
00195
00196
00197 MemOperand ParameterOperand(int index) const {
00198 int num_parameters = scope()->num_parameters();
00199
00200
00201 ASSERT(-2 <= index && index < num_parameters);
00202 int offset = (1 + num_parameters - index) * kPointerSize;
00203 return MemOperand(fp, offset);
00204 }
00205
00206 MemOperand FunctionOperand() const {
00207 return MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset);
00208 }
00209
00210 MemOperand ContextOperand(Register context, int index) const {
00211 return MemOperand(context, Context::SlotOffset(index));
00212 }
00213
00214 MemOperand SlotOperand(Slot* slot, Register tmp);
00215
00216
00217 MemOperand GlobalObject() const {
00218 return ContextOperand(cp, Context::GLOBAL_INDEX);
00219 }
00220
00221 void LoadCondition(Expression* x,
00222 TypeofState typeof_state,
00223 Label* true_target,
00224 Label* false_target,
00225 bool force_cc);
00226 void Load(Expression* x, TypeofState typeof_state = NOT_INSIDE_TYPEOF);
00227 void LoadGlobal();
00228 void LoadGlobalReceiver(Register scratch);
00229
00230
00231 void LoadFromSlot(Slot* slot, TypeofState typeof_state);
00232
00233
00234
00235
00236
00237
00238
00239 void LoadTypeofExpression(Expression* x);
00240
00241 void ToBoolean(Label* true_target, Label* false_target);
00242
00243 void GenericBinaryOperation(Token::Value op);
00244 void Comparison(Condition cc, bool strict = false);
00245
00246 void SmiOperation(Token::Value op, Handle<Object> value, bool reversed);
00247
00248 void CallWithArguments(ZoneList<Expression*>* arguments, int position);
00249
00250
00251 void Branch(bool if_true, Label* L);
00252 void CheckStack();
00253 void CleanStack(int num_bytes);
00254
00255 bool CheckForInlineRuntimeCall(CallRuntime* node);
00256 Handle<JSFunction> BuildBoilerplate(FunctionLiteral* node);
00257 void ProcessDeclarations(ZoneList<Declaration*>* declarations);
00258
00259 Handle<Code> ComputeCallInitialize(int argc);
00260
00261
00262
00263 void DeclareGlobals(Handle<FixedArray> pairs);
00264
00265
00266 void InstantiateBoilerplate(Handle<JSFunction> boilerplate);
00267
00268
00269 void GenerateIsSmi(ZoneList<Expression*>* args);
00270 void GenerateIsNonNegativeSmi(ZoneList<Expression*>* args);
00271 void GenerateIsArray(ZoneList<Expression*>* args);
00272
00273
00274 void GenerateArgumentsLength(ZoneList<Expression*>* args);
00275 void GenerateArgumentsAccess(ZoneList<Expression*>* args);
00276
00277
00278 void GenerateValueOf(ZoneList<Expression*>* args);
00279 void GenerateSetValueOf(ZoneList<Expression*>* args);
00280
00281
00282 void GenerateFastCharCodeAt(ZoneList<Expression*>* args);
00283
00284
00285 void GenerateObjectEquals(ZoneList<Expression*>* args);
00286
00287
00288
00289
00290
00291
00292
00293
00294 static const int kFastSwitchMaxOverheadFactor = 10;
00295
00296
00297
00298 static const int kFastSwitchMinCaseCount = 5;
00299
00300
00301
00302
00303
00304 int FastCaseSwitchMaxOverheadFactor();
00305
00306
00307
00308
00309
00310 int FastCaseSwitchMinCaseCount();
00311
00312
00313
00314
00315 void GenerateFastCaseSwitchJumpTable(SwitchStatement* node,
00316 int min_index,
00317 int range,
00318 Label* fail_label,
00319 Vector<Label*> case_targets,
00320 Vector<Label> case_labels);
00321
00322
00323
00324 void GenerateFastCaseSwitchCases(SwitchStatement* node,
00325 Vector<Label> case_labels);
00326
00327
00328 void GenerateFastCaseSwitchStatement(SwitchStatement* node,
00329 int min_index,
00330 int range,
00331 int default_index);
00332
00333
00334
00335
00336 bool TryGenerateFastCaseSwitchStatement(SwitchStatement* node);
00337
00338
00339
00340
00341
00342 void RecordStatementPosition(Node* node);
00343
00344
00345 void EnterJSFrame();
00346 void ExitJSFrame();
00347
00348
00349 bool is_eval_;
00350 Handle<Script> script_;
00351 List<DeferredCode*> deferred_;
00352
00353
00354 MacroAssembler* masm_;
00355
00356
00357 Scope* scope_;
00358 Condition cc_reg_;
00359 CodeGenState* state_;
00360 bool is_inside_try_;
00361 int break_stack_height_;
00362
00363
00364 Label function_return_;
00365
00366 friend class Reference;
00367 friend class Property;
00368 friend class VariableProxy;
00369 friend class Slot;
00370
00371 DISALLOW_COPY_AND_ASSIGN(CodeGenerator);
00372 };
00373
00374 } }
00375
00376 #endif // V8_CODEGEN_ARM_H_