| OLD | NEW |
| 1 // Copyright 2009 the V8 project authors. All rights reserved. | 1 // Copyright 2009 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 29 matching lines...) Expand all Loading... |
| 40 | 40 |
| 41 class FastCodeGenerator: public AstVisitor { | 41 class FastCodeGenerator: public AstVisitor { |
| 42 public: | 42 public: |
| 43 FastCodeGenerator(MacroAssembler* masm, Handle<Script> script, bool is_eval) | 43 FastCodeGenerator(MacroAssembler* masm, Handle<Script> script, bool is_eval) |
| 44 : masm_(masm), | 44 : masm_(masm), |
| 45 function_(NULL), | 45 function_(NULL), |
| 46 script_(script), | 46 script_(script), |
| 47 is_eval_(is_eval), | 47 is_eval_(is_eval), |
| 48 nesting_stack_(NULL), | 48 nesting_stack_(NULL), |
| 49 loop_depth_(0), | 49 loop_depth_(0), |
| 50 location_(kStack), |
| 50 true_label_(NULL), | 51 true_label_(NULL), |
| 51 false_label_(NULL) { | 52 false_label_(NULL) { |
| 52 } | 53 } |
| 53 | 54 |
| 54 static Handle<Code> MakeCode(FunctionLiteral* fun, | 55 static Handle<Code> MakeCode(FunctionLiteral* fun, |
| 55 Handle<Script> script, | 56 Handle<Script> script, |
| 56 bool is_eval); | 57 bool is_eval); |
| 57 | 58 |
| 58 void Generate(FunctionLiteral* fun); | 59 void Generate(FunctionLiteral* fun); |
| 59 | 60 |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 203 virtual int Exit(int stack_depth) { | 204 virtual int Exit(int stack_depth) { |
| 204 return stack_depth + kForInStackElementCount; | 205 return stack_depth + kForInStackElementCount; |
| 205 } | 206 } |
| 206 private: | 207 private: |
| 207 // TODO(lrn): Check that this value is correct when implementing | 208 // TODO(lrn): Check that this value is correct when implementing |
| 208 // for-in. | 209 // for-in. |
| 209 static const int kForInStackElementCount = 5; | 210 static const int kForInStackElementCount = 5; |
| 210 DISALLOW_COPY_AND_ASSIGN(ForIn); | 211 DISALLOW_COPY_AND_ASSIGN(ForIn); |
| 211 }; | 212 }; |
| 212 | 213 |
| 214 enum Location { |
| 215 kAccumulator, |
| 216 kStack |
| 217 }; |
| 213 | 218 |
| 214 int SlotOffset(Slot* slot); | 219 int SlotOffset(Slot* slot); |
| 215 | 220 |
| 216 // Emit code to complete the evaluation of an expression based on its | 221 // Emit code to convert a pure value (in a register, slot, as a literal, |
| 217 // expression context and given its value is in a register, non-lookup | 222 // or on top of the stack) into the result expected according to an |
| 218 // slot, or a literal. | 223 // expression context. |
| 219 void Apply(Expression::Context context, Register reg); | 224 void Apply(Expression::Context context, Register reg); |
| 220 void Apply(Expression::Context context, Slot* slot, Register scratch); | 225 void Apply(Expression::Context context, Slot* slot); |
| 221 void Apply(Expression::Context context, Literal* lit); | 226 void Apply(Expression::Context context, Literal* lit); |
| 222 | |
| 223 // Emit code to complete the evaluation of an expression based on its | |
| 224 // expression context and given its value is on top of the stack. | |
| 225 void ApplyTOS(Expression::Context context); | 227 void ApplyTOS(Expression::Context context); |
| 226 | 228 |
| 227 // Emit code to discard count elements from the top of stack, then | 229 // Emit code to discard count elements from the top of stack, then convert |
| 228 // complete the evaluation of an expression based on its expression | 230 // a pure value into the result expected according to an expression |
| 229 // context and given its value is in a register. | 231 // context. |
| 230 void DropAndApply(int count, Expression::Context context, Register reg); | 232 void DropAndApply(int count, Expression::Context context, Register reg); |
| 231 | 233 |
| 234 // Emit code to convert pure control flow to a pair of labels into the |
| 235 // result expected according to an expression context. |
| 236 void Apply(Expression::Context context, |
| 237 Label* materialize_true, |
| 238 Label* materialize_false); |
| 239 |
| 240 // Helper function to convert a pure value into a test context. The value |
| 241 // is expected on the stack or the accumulator, depending on the platform. |
| 242 // See the platform-specific implementation for details. |
| 243 void DoTest(Expression::Context context); |
| 244 |
| 232 void Move(Slot* dst, Register source, Register scratch1, Register scratch2); | 245 void Move(Slot* dst, Register source, Register scratch1, Register scratch2); |
| 233 void Move(Register dst, Slot* source); | 246 void Move(Register dst, Slot* source); |
| 234 | 247 |
| 235 // Return an operand used to read/write to a known (ie, non-LOOKUP) slot. | 248 // Return an operand used to read/write to a known (ie, non-LOOKUP) slot. |
| 236 // May emit code to traverse the context chain, destroying the scratch | 249 // May emit code to traverse the context chain, destroying the scratch |
| 237 // register. | 250 // register. |
| 238 MemOperand EmitSlotSearch(Slot* slot, Register scratch); | 251 MemOperand EmitSlotSearch(Slot* slot, Register scratch); |
| 239 | 252 |
| 240 // Test the JavaScript value in source as if in a test context, compile | 253 void VisitForValue(Expression* expr, Location where) { |
| 241 // control flow to a pair of labels. | 254 ASSERT(expr->context() == Expression::kValue); |
| 242 void TestAndBranch(Register source, Label* true_label, Label* false_label); | 255 Location saved_location = location_; |
| 256 location_ = where; |
| 257 Visit(expr); |
| 258 location_ = saved_location; |
| 259 } |
| 243 | 260 |
| 244 void VisitForControl(Expression* expr, Label* if_true, Label* if_false) { | 261 void VisitForControl(Expression* expr, Label* if_true, Label* if_false) { |
| 245 ASSERT(expr->context() == Expression::kTest || | 262 ASSERT(expr->context() == Expression::kTest || |
| 246 expr->context() == Expression::kValueTest || | 263 expr->context() == Expression::kValueTest || |
| 247 expr->context() == Expression::kTestValue); | 264 expr->context() == Expression::kTestValue); |
| 248 Label* saved_true = true_label_; | 265 Label* saved_true = true_label_; |
| 249 Label* saved_false = false_label_; | 266 Label* saved_false = false_label_; |
| 250 true_label_ = if_true; | 267 true_label_ = if_true; |
| 251 false_label_ = if_false; | 268 false_label_ = if_false; |
| 252 Visit(expr); | 269 Visit(expr); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 270 // Platform-specific support for compiling assignments. | 287 // Platform-specific support for compiling assignments. |
| 271 | 288 |
| 272 // Load a value from a named property. | 289 // Load a value from a named property. |
| 273 // The receiver is left on the stack by the IC. | 290 // The receiver is left on the stack by the IC. |
| 274 void EmitNamedPropertyLoad(Property* expr); | 291 void EmitNamedPropertyLoad(Property* expr); |
| 275 | 292 |
| 276 // Load a value from a keyed property. | 293 // Load a value from a keyed property. |
| 277 // The receiver and the key is left on the stack by the IC. | 294 // The receiver and the key is left on the stack by the IC. |
| 278 void EmitKeyedPropertyLoad(Property* expr); | 295 void EmitKeyedPropertyLoad(Property* expr); |
| 279 | 296 |
| 280 // Apply the compound assignment operator. Expects both operands on top | 297 // Apply the compound assignment operator. Expects the left operand on top |
| 281 // of the stack. | 298 // of the stack and the right one in the accumulator. |
| 282 void EmitCompoundAssignmentOp(Token::Value op, Expression::Context context); | 299 void EmitBinaryOp(Token::Value op, Expression::Context context); |
| 283 | 300 |
| 284 // Complete a variable assignment. The right-hand-side value is expected | 301 // Complete a variable assignment. The right-hand-side value is expected |
| 285 // on top of the stack. | 302 // in the accumulator. |
| 286 void EmitVariableAssignment(Variable* var, Expression::Context context); | 303 void EmitVariableAssignment(Variable* var, Expression::Context context); |
| 287 | 304 |
| 288 // Complete a named property assignment. The receiver and right-hand-side | 305 // Complete a named property assignment. The receiver is expected on top |
| 289 // value are expected on top of the stack. | 306 // of the stack and the right-hand-side value in the accumulator. |
| 290 void EmitNamedPropertyAssignment(Assignment* expr); | 307 void EmitNamedPropertyAssignment(Assignment* expr); |
| 291 | 308 |
| 292 // Complete a keyed property assignment. The reciever, key, and | 309 // Complete a keyed property assignment. The receiver and key are |
| 293 // right-hand-side value are expected on top of the stack. | 310 // expected on top of the stack and the right-hand-side value in the |
| 311 // accumulator. |
| 294 void EmitKeyedPropertyAssignment(Assignment* expr); | 312 void EmitKeyedPropertyAssignment(Assignment* expr); |
| 295 | 313 |
| 296 void SetFunctionPosition(FunctionLiteral* fun); | 314 void SetFunctionPosition(FunctionLiteral* fun); |
| 297 void SetReturnPosition(FunctionLiteral* fun); | 315 void SetReturnPosition(FunctionLiteral* fun); |
| 298 void SetStatementPosition(Statement* stmt); | 316 void SetStatementPosition(Statement* stmt); |
| 299 void SetStatementPosition(int pos); | 317 void SetStatementPosition(int pos); |
| 300 void SetSourcePosition(int pos); | 318 void SetSourcePosition(int pos); |
| 301 | 319 |
| 302 // Non-local control flow support. | 320 // Non-local control flow support. |
| 303 void EnterFinallyBlock(); | 321 void EnterFinallyBlock(); |
| (...skipping 27 matching lines...) Expand all Loading... |
| 331 void EmitLogicalOperation(BinaryOperation* expr); | 349 void EmitLogicalOperation(BinaryOperation* expr); |
| 332 | 350 |
| 333 MacroAssembler* masm_; | 351 MacroAssembler* masm_; |
| 334 FunctionLiteral* function_; | 352 FunctionLiteral* function_; |
| 335 Handle<Script> script_; | 353 Handle<Script> script_; |
| 336 bool is_eval_; | 354 bool is_eval_; |
| 337 Label return_label_; | 355 Label return_label_; |
| 338 NestedStatement* nesting_stack_; | 356 NestedStatement* nesting_stack_; |
| 339 int loop_depth_; | 357 int loop_depth_; |
| 340 | 358 |
| 359 Location location_; |
| 341 Label* true_label_; | 360 Label* true_label_; |
| 342 Label* false_label_; | 361 Label* false_label_; |
| 343 | 362 |
| 344 friend class NestedStatement; | 363 friend class NestedStatement; |
| 345 | 364 |
| 346 DISALLOW_COPY_AND_ASSIGN(FastCodeGenerator); | 365 DISALLOW_COPY_AND_ASSIGN(FastCodeGenerator); |
| 347 }; | 366 }; |
| 348 | 367 |
| 349 | 368 |
| 350 } } // namespace v8::internal | 369 } } // namespace v8::internal |
| 351 | 370 |
| 352 #endif // V8_FAST_CODEGEN_H_ | 371 #endif // V8_FAST_CODEGEN_H_ |
| OLD | NEW |