OLD | NEW |
1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 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 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
64 // ----------------------------------------------------------------------------- | 64 // ----------------------------------------------------------------------------- |
65 // Full code generator. | 65 // Full code generator. |
66 | 66 |
67 class FullCodeGenerator: public AstVisitor { | 67 class FullCodeGenerator: public AstVisitor { |
68 public: | 68 public: |
69 explicit FullCodeGenerator(MacroAssembler* masm) | 69 explicit FullCodeGenerator(MacroAssembler* masm) |
70 : masm_(masm), | 70 : masm_(masm), |
71 info_(NULL), | 71 info_(NULL), |
72 nesting_stack_(NULL), | 72 nesting_stack_(NULL), |
73 loop_depth_(0), | 73 loop_depth_(0), |
74 location_(kStack), | 74 context_(NULL) { |
75 true_label_(NULL), | |
76 false_label_(NULL), | |
77 fall_through_(NULL) { | |
78 } | 75 } |
79 | 76 |
80 static Handle<Code> MakeCode(CompilationInfo* info); | 77 static Handle<Code> MakeCode(CompilationInfo* info); |
81 | 78 |
82 void Generate(CompilationInfo* info); | 79 void Generate(CompilationInfo* info); |
83 | 80 |
84 private: | 81 private: |
85 class Breakable; | 82 class Breakable; |
86 class Iteration; | 83 class Iteration; |
87 class TryCatch; | 84 class TryCatch; |
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
225 virtual ~ForIn() {} | 222 virtual ~ForIn() {} |
226 virtual ForIn* AsForIn() { return this; } | 223 virtual ForIn* AsForIn() { return this; } |
227 virtual int Exit(int stack_depth) { | 224 virtual int Exit(int stack_depth) { |
228 return stack_depth + kForInStackElementCount; | 225 return stack_depth + kForInStackElementCount; |
229 } | 226 } |
230 private: | 227 private: |
231 static const int kForInStackElementCount = 5; | 228 static const int kForInStackElementCount = 5; |
232 DISALLOW_COPY_AND_ASSIGN(ForIn); | 229 DISALLOW_COPY_AND_ASSIGN(ForIn); |
233 }; | 230 }; |
234 | 231 |
235 enum Location { | |
236 kAccumulator, | |
237 kStack | |
238 }; | |
239 | |
240 enum ConstantOperand { | 232 enum ConstantOperand { |
241 kNoConstants, | 233 kNoConstants, |
242 kLeftConstant, | 234 kLeftConstant, |
243 kRightConstant | 235 kRightConstant |
244 }; | 236 }; |
245 | 237 |
246 // Compute the frame pointer relative offset for a given local or | 238 // Compute the frame pointer relative offset for a given local or |
247 // parameter slot. | 239 // parameter slot. |
248 int SlotOffset(Slot* slot); | 240 int SlotOffset(Slot* slot); |
249 | 241 |
250 // Determine whether or not to inline the smi case for the given | 242 // Determine whether or not to inline the smi case for the given |
251 // operation. | 243 // operation. |
252 bool ShouldInlineSmiCase(Token::Value op); | 244 bool ShouldInlineSmiCase(Token::Value op); |
253 | 245 |
254 // Compute which (if any) of the operands is a compile-time constant. | 246 // Compute which (if any) of the operands is a compile-time constant. |
255 ConstantOperand GetConstantOperand(Token::Value op, | 247 ConstantOperand GetConstantOperand(Token::Value op, |
256 Expression* left, | 248 Expression* left, |
257 Expression* right); | 249 Expression* right); |
258 | 250 |
259 // Emit code to convert a pure value (in a register, slot, as a literal, | |
260 // or on top of the stack) into the result expected according to an | |
261 // expression context. | |
262 void Apply(Expression::Context context, Register reg); | |
263 | |
264 // Slot cannot have type Slot::LOOKUP. | |
265 void Apply(Expression::Context context, Slot* slot); | |
266 | |
267 void Apply(Expression::Context context, Literal* lit); | |
268 void ApplyTOS(Expression::Context context); | |
269 | |
270 // Emit code to discard count elements from the top of stack, then convert | |
271 // a pure value into the result expected according to an expression | |
272 // context. | |
273 void DropAndApply(int count, Expression::Context context, Register reg); | |
274 | |
275 // Set up branch labels for a test expression. | |
276 void PrepareTest(Label* materialize_true, | |
277 Label* materialize_false, | |
278 Label** if_true, | |
279 Label** if_false, | |
280 Label** fall_through); | |
281 | |
282 // Emit code to convert pure control flow to a pair of labels into the | |
283 // result expected according to an expression context. | |
284 void Apply(Expression::Context context, | |
285 Label* materialize_true, | |
286 Label* materialize_false); | |
287 | |
288 // Emit code to convert constant control flow (true or false) into | |
289 // the result expected according to an expression context. | |
290 void Apply(Expression::Context context, bool flag); | |
291 | |
292 // Helper function to convert a pure value into a test context. The value | 251 // Helper function to convert a pure value into a test context. The value |
293 // is expected on the stack or the accumulator, depending on the platform. | 252 // is expected on the stack or the accumulator, depending on the platform. |
294 // See the platform-specific implementation for details. | 253 // See the platform-specific implementation for details. |
295 void DoTest(Label* if_true, Label* if_false, Label* fall_through); | 254 void DoTest(Label* if_true, Label* if_false, Label* fall_through); |
296 | 255 |
297 // Helper function to split control flow and avoid a branch to the | 256 // Helper function to split control flow and avoid a branch to the |
298 // fall-through label if it is set up. | 257 // fall-through label if it is set up. |
299 void Split(Condition cc, | 258 void Split(Condition cc, |
300 Label* if_true, | 259 Label* if_true, |
301 Label* if_false, | 260 Label* if_false, |
302 Label* fall_through); | 261 Label* fall_through); |
303 | 262 |
304 void Move(Slot* dst, Register source, Register scratch1, Register scratch2); | 263 void Move(Slot* dst, Register source, Register scratch1, Register scratch2); |
305 void Move(Register dst, Slot* source); | 264 void Move(Register dst, Slot* source); |
306 | 265 |
307 // Return an operand used to read/write to a known (ie, non-LOOKUP) slot. | 266 // Return an operand used to read/write to a known (ie, non-LOOKUP) slot. |
308 // May emit code to traverse the context chain, destroying the scratch | 267 // May emit code to traverse the context chain, destroying the scratch |
309 // register. | 268 // register. |
310 MemOperand EmitSlotSearch(Slot* slot, Register scratch); | 269 MemOperand EmitSlotSearch(Slot* slot, Register scratch); |
311 | 270 |
312 void VisitForEffect(Expression* expr) { | 271 void VisitForEffect(Expression* expr) { |
313 Expression::Context saved_context = context_; | 272 EffectContext context(this); |
314 context_ = Expression::kEffect; | |
315 Visit(expr); | 273 Visit(expr); |
316 context_ = saved_context; | |
317 } | 274 } |
318 | 275 |
319 void VisitForValue(Expression* expr, Location where) { | 276 void VisitForAccumulatorValue(Expression* expr) { |
320 Expression::Context saved_context = context_; | 277 AccumulatorValueContext context(this); |
321 Location saved_location = location_; | |
322 context_ = Expression::kValue; | |
323 location_ = where; | |
324 Visit(expr); | 278 Visit(expr); |
325 context_ = saved_context; | 279 } |
326 location_ = saved_location; | 280 |
| 281 void VisitForStackValue(Expression* expr) { |
| 282 StackValueContext context(this); |
| 283 Visit(expr); |
327 } | 284 } |
328 | 285 |
329 void VisitForControl(Expression* expr, | 286 void VisitForControl(Expression* expr, |
330 Label* if_true, | 287 Label* if_true, |
331 Label* if_false, | 288 Label* if_false, |
332 Label* fall_through) { | 289 Label* fall_through) { |
333 Expression::Context saved_context = context_; | 290 TestContext context(this, if_true, if_false, fall_through); |
334 Label* saved_true = true_label_; | |
335 Label* saved_false = false_label_; | |
336 Label* saved_fall_through = fall_through_; | |
337 context_ = Expression::kTest; | |
338 true_label_ = if_true; | |
339 false_label_ = if_false; | |
340 fall_through_ = fall_through; | |
341 Visit(expr); | 291 Visit(expr); |
342 context_ = saved_context; | |
343 true_label_ = saved_true; | |
344 false_label_ = saved_false; | |
345 fall_through_ = saved_fall_through; | |
346 } | 292 } |
347 | 293 |
348 void VisitDeclarations(ZoneList<Declaration*>* declarations); | 294 void VisitDeclarations(ZoneList<Declaration*>* declarations); |
349 void DeclareGlobals(Handle<FixedArray> pairs); | 295 void DeclareGlobals(Handle<FixedArray> pairs); |
350 | 296 |
351 // Try to perform a comparison as a fast inlined literal compare if | 297 // Try to perform a comparison as a fast inlined literal compare if |
352 // the operands allow it. Returns true if the compare operations | 298 // the operands allow it. Returns true if the compare operations |
353 // has been matched and all code generated; false otherwise. | 299 // has been matched and all code generated; false otherwise. |
354 bool TryLiteralCompare(Token::Value op, | 300 bool TryLiteralCompare(Token::Value op, |
355 Expression* left, | 301 Expression* left, |
(...skipping 26 matching lines...) Expand all Loading... |
382 | 328 |
383 // Platform-specific code for loading variables. | 329 // Platform-specific code for loading variables. |
384 void EmitLoadGlobalSlotCheckExtensions(Slot* slot, | 330 void EmitLoadGlobalSlotCheckExtensions(Slot* slot, |
385 TypeofState typeof_state, | 331 TypeofState typeof_state, |
386 Label* slow); | 332 Label* slow); |
387 MemOperand ContextSlotOperandCheckExtensions(Slot* slot, Label* slow); | 333 MemOperand ContextSlotOperandCheckExtensions(Slot* slot, Label* slow); |
388 void EmitDynamicLoadFromSlotFastCase(Slot* slot, | 334 void EmitDynamicLoadFromSlotFastCase(Slot* slot, |
389 TypeofState typeof_state, | 335 TypeofState typeof_state, |
390 Label* slow, | 336 Label* slow, |
391 Label* done); | 337 Label* done); |
392 void EmitVariableLoad(Variable* expr, Expression::Context context); | 338 void EmitVariableLoad(Variable* expr); |
393 | 339 |
394 // Platform-specific support for allocating a new closure based on | 340 // Platform-specific support for allocating a new closure based on |
395 // the given function info. | 341 // the given function info. |
396 void EmitNewClosure(Handle<SharedFunctionInfo> info); | 342 void EmitNewClosure(Handle<SharedFunctionInfo> info); |
397 | 343 |
398 // Platform-specific support for compiling assignments. | 344 // Platform-specific support for compiling assignments. |
399 | 345 |
400 // Load a value from a named property. | 346 // Load a value from a named property. |
401 // The receiver is left on the stack by the IC. | 347 // The receiver is left on the stack by the IC. |
402 void EmitNamedPropertyLoad(Property* expr); | 348 void EmitNamedPropertyLoad(Property* expr); |
403 | 349 |
404 // Load a value from a keyed property. | 350 // Load a value from a keyed property. |
405 // The receiver and the key is left on the stack by the IC. | 351 // The receiver and the key is left on the stack by the IC. |
406 void EmitKeyedPropertyLoad(Property* expr); | 352 void EmitKeyedPropertyLoad(Property* expr); |
407 | 353 |
408 // Apply the compound assignment operator. Expects the left operand on top | 354 // Apply the compound assignment operator. Expects the left operand on top |
409 // of the stack and the right one in the accumulator. | 355 // of the stack and the right one in the accumulator. |
410 void EmitBinaryOp(Token::Value op, | 356 void EmitBinaryOp(Token::Value op, |
411 Expression::Context context, | |
412 OverwriteMode mode); | 357 OverwriteMode mode); |
413 | 358 |
414 // Helper functions for generating inlined smi code for certain | 359 // Helper functions for generating inlined smi code for certain |
415 // binary operations. | 360 // binary operations. |
416 void EmitInlineSmiBinaryOp(Expression* expr, | 361 void EmitInlineSmiBinaryOp(Expression* expr, |
417 Token::Value op, | 362 Token::Value op, |
418 Expression::Context context, | |
419 OverwriteMode mode, | 363 OverwriteMode mode, |
420 Expression* left, | 364 Expression* left, |
421 Expression* right, | 365 Expression* right, |
422 ConstantOperand constant); | 366 ConstantOperand constant); |
423 | 367 |
424 void EmitConstantSmiBinaryOp(Expression* expr, | 368 void EmitConstantSmiBinaryOp(Expression* expr, |
425 Token::Value op, | 369 Token::Value op, |
426 Expression::Context context, | |
427 OverwriteMode mode, | 370 OverwriteMode mode, |
428 bool left_is_constant_smi, | 371 bool left_is_constant_smi, |
429 Smi* value); | 372 Smi* value); |
430 | 373 |
431 void EmitConstantSmiBitOp(Expression* expr, | 374 void EmitConstantSmiBitOp(Expression* expr, |
432 Token::Value op, | 375 Token::Value op, |
433 Expression::Context context, | |
434 OverwriteMode mode, | 376 OverwriteMode mode, |
435 Smi* value); | 377 Smi* value); |
436 | 378 |
437 void EmitConstantSmiShiftOp(Expression* expr, | 379 void EmitConstantSmiShiftOp(Expression* expr, |
438 Token::Value op, | 380 Token::Value op, |
439 Expression::Context context, | |
440 OverwriteMode mode, | 381 OverwriteMode mode, |
441 Smi* value); | 382 Smi* value); |
442 | 383 |
443 void EmitConstantSmiAdd(Expression* expr, | 384 void EmitConstantSmiAdd(Expression* expr, |
444 Expression::Context context, | |
445 OverwriteMode mode, | 385 OverwriteMode mode, |
446 bool left_is_constant_smi, | 386 bool left_is_constant_smi, |
447 Smi* value); | 387 Smi* value); |
448 | 388 |
449 void EmitConstantSmiSub(Expression* expr, | 389 void EmitConstantSmiSub(Expression* expr, |
450 Expression::Context context, | |
451 OverwriteMode mode, | 390 OverwriteMode mode, |
452 bool left_is_constant_smi, | 391 bool left_is_constant_smi, |
453 Smi* value); | 392 Smi* value); |
454 | 393 |
455 // Assign to the given expression as if via '='. The right-hand-side value | 394 // Assign to the given expression as if via '='. The right-hand-side value |
456 // is expected in the accumulator. | 395 // is expected in the accumulator. |
457 void EmitAssignment(Expression* expr); | 396 void EmitAssignment(Expression* expr); |
458 | 397 |
459 // Complete a variable assignment. The right-hand-side value is expected | 398 // Complete a variable assignment. The right-hand-side value is expected |
460 // in the accumulator. | 399 // in the accumulator. |
461 void EmitVariableAssignment(Variable* var, | 400 void EmitVariableAssignment(Variable* var, |
462 Token::Value op, | 401 Token::Value op); |
463 Expression::Context context); | |
464 | 402 |
465 // Complete a named property assignment. The receiver is expected on top | 403 // Complete a named property assignment. The receiver is expected on top |
466 // of the stack and the right-hand-side value in the accumulator. | 404 // of the stack and the right-hand-side value in the accumulator. |
467 void EmitNamedPropertyAssignment(Assignment* expr); | 405 void EmitNamedPropertyAssignment(Assignment* expr); |
468 | 406 |
469 // Complete a keyed property assignment. The receiver and key are | 407 // Complete a keyed property assignment. The receiver and key are |
470 // expected on top of the stack and the right-hand-side value in the | 408 // expected on top of the stack and the right-hand-side value in the |
471 // accumulator. | 409 // accumulator. |
472 void EmitKeyedPropertyAssignment(Assignment* expr); | 410 void EmitKeyedPropertyAssignment(Assignment* expr); |
473 | 411 |
(...skipping 11 matching lines...) Expand all Loading... |
485 // Loop nesting counter. | 423 // Loop nesting counter. |
486 int loop_depth() { return loop_depth_; } | 424 int loop_depth() { return loop_depth_; } |
487 void increment_loop_depth() { loop_depth_++; } | 425 void increment_loop_depth() { loop_depth_++; } |
488 void decrement_loop_depth() { | 426 void decrement_loop_depth() { |
489 ASSERT(loop_depth_ > 0); | 427 ASSERT(loop_depth_ > 0); |
490 loop_depth_--; | 428 loop_depth_--; |
491 } | 429 } |
492 | 430 |
493 MacroAssembler* masm() { return masm_; } | 431 MacroAssembler* masm() { return masm_; } |
494 | 432 |
| 433 class ExpressionContext; |
| 434 const ExpressionContext* context() { return context_; } |
| 435 void set_new_context(const ExpressionContext* context) { context_ = context; } |
| 436 |
495 Handle<Script> script() { return info_->script(); } | 437 Handle<Script> script() { return info_->script(); } |
496 bool is_eval() { return info_->is_eval(); } | 438 bool is_eval() { return info_->is_eval(); } |
497 FunctionLiteral* function() { return info_->function(); } | 439 FunctionLiteral* function() { return info_->function(); } |
498 Scope* scope() { return info_->scope(); } | 440 Scope* scope() { return info_->scope(); } |
499 | 441 |
500 static Register result_register(); | 442 static Register result_register(); |
501 static Register context_register(); | 443 static Register context_register(); |
502 | 444 |
503 // Set fields in the stack frame. Offsets are the frame pointer relative | 445 // Set fields in the stack frame. Offsets are the frame pointer relative |
504 // offsets defined in, e.g., StandardFrameConstants. | 446 // offsets defined in, e.g., StandardFrameConstants. |
505 void StoreToFrameField(int frame_offset, Register value); | 447 void StoreToFrameField(int frame_offset, Register value); |
506 | 448 |
507 // Load a value from the current context. Indices are defined as an enum | 449 // Load a value from the current context. Indices are defined as an enum |
508 // in v8::internal::Context. | 450 // in v8::internal::Context. |
509 void LoadContextField(Register dst, int context_index); | 451 void LoadContextField(Register dst, int context_index); |
510 | 452 |
511 // Create an operand for a context field. | 453 // Create an operand for a context field. |
512 MemOperand ContextOperand(Register context, int context_index); | 454 MemOperand ContextOperand(Register context, int context_index); |
513 | 455 |
514 // AST node visit functions. | 456 // AST node visit functions. |
515 #define DECLARE_VISIT(type) virtual void Visit##type(type* node); | 457 #define DECLARE_VISIT(type) virtual void Visit##type(type* node); |
516 AST_NODE_LIST(DECLARE_VISIT) | 458 AST_NODE_LIST(DECLARE_VISIT) |
517 #undef DECLARE_VISIT | 459 #undef DECLARE_VISIT |
518 // Handles the shortcutted logical binary operations in VisitBinaryOperation. | 460 // Handles the shortcutted logical binary operations in VisitBinaryOperation. |
519 void EmitLogicalOperation(BinaryOperation* expr); | 461 void EmitLogicalOperation(BinaryOperation* expr); |
520 | 462 |
521 void VisitForTypeofValue(Expression* expr, Location where); | 463 void VisitForTypeofValue(Expression* expr); |
522 | |
523 void VisitLogicalForValue(Expression* expr, | |
524 Token::Value op, | |
525 Location where, | |
526 Label* done); | |
527 | |
528 | 464 |
529 MacroAssembler* masm_; | 465 MacroAssembler* masm_; |
530 CompilationInfo* info_; | 466 CompilationInfo* info_; |
531 | 467 |
532 Label return_label_; | 468 Label return_label_; |
533 NestedStatement* nesting_stack_; | 469 NestedStatement* nesting_stack_; |
534 int loop_depth_; | 470 int loop_depth_; |
535 | 471 |
536 Expression::Context context_; | 472 class ExpressionContext { |
537 Location location_; | 473 public: |
538 Label* true_label_; | 474 explicit ExpressionContext(FullCodeGenerator* codegen) |
539 Label* false_label_; | 475 : masm_(codegen->masm()), old_(codegen->context()), codegen_(codegen) { |
540 Label* fall_through_; | 476 codegen->set_new_context(this); |
| 477 } |
| 478 |
| 479 virtual ~ExpressionContext() { |
| 480 codegen_->set_new_context(old_); |
| 481 } |
| 482 |
| 483 // Convert constant control flow (true or false) to the result expected for |
| 484 // this expression context. |
| 485 virtual void Plug(bool flag) const = 0; |
| 486 |
| 487 // Emit code to convert a pure value (in a register, slot, as a literal, |
| 488 // or on top of the stack) into the result expected according to this |
| 489 // expression context. |
| 490 virtual void Plug(Register reg) const = 0; |
| 491 |
| 492 // Emit code to convert pure control flow to a pair of labels into the |
| 493 // result expected according to this expression context. |
| 494 virtual void Plug(Label* materialize_true, |
| 495 Label* materialize_false) const = 0; |
| 496 |
| 497 virtual void Plug(Slot* slot) const = 0; |
| 498 virtual void Plug(Handle<Object> lit) const = 0; |
| 499 virtual void Plug(Heap::RootListIndex index) const = 0; |
| 500 virtual void PlugTOS() const = 0; |
| 501 |
| 502 // Emit code to discard count elements from the top of stack, then convert |
| 503 // a pure value into the result expected according to this expression |
| 504 // context. |
| 505 virtual void DropAndPlug(int count, Register reg) const = 0; |
| 506 |
| 507 // For shortcutting operations || and &&. |
| 508 virtual void EmitLogicalLeft(BinaryOperation* expr, |
| 509 Label* eval_right, |
| 510 Label* done) const = 0; |
| 511 |
| 512 // Set up branch labels for a test expression. |
| 513 virtual void PrepareTest(Label* materialize_true, |
| 514 Label* materialize_false, |
| 515 Label** if_true, |
| 516 Label** if_false, |
| 517 Label** fall_through) const = 0; |
| 518 |
| 519 // Returns true if we are evaluating only for side effects (ie if the result |
| 520 // will be discarded. |
| 521 virtual bool IsEffect() const { return false; } |
| 522 |
| 523 // Returns true if we are branching on the value rather than materializing |
| 524 // it. |
| 525 virtual bool IsTest() const { return false; } |
| 526 |
| 527 protected: |
| 528 FullCodeGenerator* codegen() const { return codegen_; } |
| 529 MacroAssembler* masm() const { return masm_; } |
| 530 MacroAssembler* masm_; |
| 531 |
| 532 private: |
| 533 const ExpressionContext* old_; |
| 534 FullCodeGenerator* codegen_; |
| 535 }; |
| 536 |
| 537 class AccumulatorValueContext : public ExpressionContext { |
| 538 public: |
| 539 explicit AccumulatorValueContext(FullCodeGenerator* codegen) |
| 540 : ExpressionContext(codegen) { } |
| 541 |
| 542 virtual void Plug(bool flag) const; |
| 543 virtual void Plug(Register reg) const; |
| 544 virtual void Plug(Label* materialize_true, Label* materialize_false) const; |
| 545 virtual void Plug(Slot* slot) const; |
| 546 virtual void Plug(Handle<Object> lit) const; |
| 547 virtual void Plug(Heap::RootListIndex) const; |
| 548 virtual void PlugTOS() const; |
| 549 virtual void DropAndPlug(int count, Register reg) const; |
| 550 virtual void EmitLogicalLeft(BinaryOperation* expr, |
| 551 Label* eval_right, |
| 552 Label* done) const; |
| 553 virtual void PrepareTest(Label* t, |
| 554 Label* f, |
| 555 Label** i_t, |
| 556 Label** i_f, |
| 557 Label** ft) const; |
| 558 }; |
| 559 |
| 560 class StackValueContext : public ExpressionContext { |
| 561 public: |
| 562 explicit StackValueContext(FullCodeGenerator* codegen) |
| 563 : ExpressionContext(codegen) { } |
| 564 |
| 565 virtual void Plug(bool flag) const; |
| 566 virtual void Plug(Register reg) const; |
| 567 virtual void Plug(Label* materialize_true, Label* materialize_false) const; |
| 568 virtual void Plug(Slot* slot) const; |
| 569 virtual void Plug(Handle<Object> lit) const; |
| 570 virtual void Plug(Heap::RootListIndex) const; |
| 571 virtual void PlugTOS() const; |
| 572 virtual void DropAndPlug(int count, Register reg) const; |
| 573 virtual void EmitLogicalLeft(BinaryOperation* expr, |
| 574 Label* eval_right, |
| 575 Label* done) const; |
| 576 virtual void PrepareTest(Label* t, |
| 577 Label* f, |
| 578 Label** i_t, |
| 579 Label** i_f, |
| 580 Label** ft) const; |
| 581 }; |
| 582 |
| 583 class TestContext : public ExpressionContext { |
| 584 public: |
| 585 explicit TestContext(FullCodeGenerator* codegen, |
| 586 Label* true_label, |
| 587 Label* false_label, |
| 588 Label* fall_through) |
| 589 : ExpressionContext(codegen), |
| 590 true_label_(true_label), |
| 591 false_label_(false_label), |
| 592 fall_through_(fall_through) { } |
| 593 |
| 594 virtual void Plug(bool flag) const; |
| 595 virtual void Plug(Register reg) const; |
| 596 virtual void Plug(Label* materialize_true, Label* materialize_false) const; |
| 597 virtual void Plug(Slot* slot) const; |
| 598 virtual void Plug(Handle<Object> lit) const; |
| 599 virtual void Plug(Heap::RootListIndex) const; |
| 600 virtual void PlugTOS() const; |
| 601 virtual void DropAndPlug(int count, Register reg) const; |
| 602 virtual void EmitLogicalLeft(BinaryOperation* expr, |
| 603 Label* eval_right, |
| 604 Label* done) const; |
| 605 virtual void PrepareTest(Label* t, |
| 606 Label* f, |
| 607 Label** i_t, |
| 608 Label** i_f, |
| 609 Label** ft) const; |
| 610 virtual bool IsTest() const { return true; } |
| 611 |
| 612 private: |
| 613 Label* true_label_; |
| 614 Label* false_label_; |
| 615 Label* fall_through_; |
| 616 }; |
| 617 |
| 618 class EffectContext : public ExpressionContext { |
| 619 public: |
| 620 explicit EffectContext(FullCodeGenerator* codegen) |
| 621 : ExpressionContext(codegen) { } |
| 622 |
| 623 virtual void Plug(bool flag) const; |
| 624 virtual void Plug(Register reg) const; |
| 625 virtual void Plug(Label* materialize_true, Label* materialize_false) const; |
| 626 virtual void Plug(Slot* slot) const; |
| 627 virtual void Plug(Handle<Object> lit) const; |
| 628 virtual void Plug(Heap::RootListIndex) const; |
| 629 virtual void PlugTOS() const; |
| 630 virtual void DropAndPlug(int count, Register reg) const; |
| 631 virtual void EmitLogicalLeft(BinaryOperation* expr, |
| 632 Label* eval_right, |
| 633 Label* done) const; |
| 634 virtual void PrepareTest(Label* t, |
| 635 Label* f, |
| 636 Label** i_t, |
| 637 Label** i_f, |
| 638 Label** ft) const; |
| 639 virtual bool IsEffect() const { return true; } |
| 640 }; |
| 641 |
| 642 const ExpressionContext* context_; |
541 | 643 |
542 friend class NestedStatement; | 644 friend class NestedStatement; |
543 | 645 |
544 DISALLOW_COPY_AND_ASSIGN(FullCodeGenerator); | 646 DISALLOW_COPY_AND_ASSIGN(FullCodeGenerator); |
545 }; | 647 }; |
546 | 648 |
547 | 649 |
548 } } // namespace v8::internal | 650 } } // namespace v8::internal |
549 | 651 |
550 #endif // V8_FULL_CODEGEN_H_ | 652 #endif // V8_FULL_CODEGEN_H_ |
OLD | NEW |