LCOV - code coverage report
Current view: top level - src/builtins - builtins-generator-gen.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 40 40 100.0 %
Date: 2017-04-26 Functions: 7 7 100.0 %

          Line data    Source code
       1             : // Copyright 2016 the V8 project authors. All rights reserved.
       2             : // Use of this source code is governed by a BSD-style license that can be
       3             : // found in the LICENSE file.
       4             : 
       5             : #include "src/builtins/builtins-utils-gen.h"
       6             : #include "src/builtins/builtins.h"
       7             : #include "src/code-factory.h"
       8             : #include "src/code-stub-assembler.h"
       9             : #include "src/isolate.h"
      10             : #include "src/objects-inl.h"
      11             : 
      12             : namespace v8 {
      13             : namespace internal {
      14             : 
      15             : class GeneratorBuiltinsAssembler : public CodeStubAssembler {
      16             :  public:
      17             :   explicit GeneratorBuiltinsAssembler(compiler::CodeAssemblerState* state)
      18         129 :       : CodeStubAssembler(state) {}
      19             : 
      20             :  protected:
      21             :   void GeneratorPrototypeResume(Node* receiver, Node* value, Node* context,
      22             :                                 JSGeneratorObject::ResumeMode resume_mode,
      23             :                                 char const* const method_name);
      24             : };
      25             : 
      26         129 : void GeneratorBuiltinsAssembler::GeneratorPrototypeResume(
      27             :     Node* receiver, Node* value, Node* context,
      28             :     JSGeneratorObject::ResumeMode resume_mode, char const* const method_name) {
      29         129 :   Node* closed = SmiConstant(JSGeneratorObject::kGeneratorClosed);
      30             : 
      31             :   // Check if the {receiver} is actually a JSGeneratorObject.
      32             :   Label if_receiverisincompatible(this, Label::kDeferred);
      33         129 :   GotoIf(TaggedIsSmi(receiver), &if_receiverisincompatible);
      34         129 :   Node* receiver_instance_type = LoadInstanceType(receiver);
      35             :   GotoIfNot(Word32Equal(receiver_instance_type,
      36             :                         Int32Constant(JS_GENERATOR_OBJECT_TYPE)),
      37         129 :             &if_receiverisincompatible);
      38             : 
      39             :   // Check if the {receiver} is running or already closed.
      40             :   Node* receiver_continuation =
      41         129 :       LoadObjectField(receiver, JSGeneratorObject::kContinuationOffset);
      42         129 :   Label if_receiverisclosed(this, Label::kDeferred),
      43         129 :       if_receiverisrunning(this, Label::kDeferred);
      44         129 :   GotoIf(SmiEqual(receiver_continuation, closed), &if_receiverisclosed);
      45             :   DCHECK_LT(JSGeneratorObject::kGeneratorExecuting,
      46             :             JSGeneratorObject::kGeneratorClosed);
      47         129 :   GotoIf(SmiLessThan(receiver_continuation, closed), &if_receiverisrunning);
      48             : 
      49             :   // Resume the {receiver} using our trampoline.
      50             :   Node* result =
      51             :       CallStub(CodeFactory::ResumeGenerator(isolate()), context, value,
      52             :                receiver, SmiConstant(resume_mode),
      53         258 :                SmiConstant(static_cast<int>(SuspendFlags::kGeneratorYield)));
      54         129 :   Return(result);
      55             : 
      56         129 :   BIND(&if_receiverisincompatible);
      57             :   {
      58             :     // The {receiver} is not a valid JSGeneratorObject.
      59             :     CallRuntime(Runtime::kThrowIncompatibleMethodReceiver, context,
      60             :                 HeapConstant(
      61             :                     factory()->NewStringFromAsciiChecked(method_name, TENURED)),
      62         258 :                 receiver);
      63         129 :     Unreachable();
      64             :   }
      65             : 
      66         129 :   BIND(&if_receiverisclosed);
      67             :   {
      68             :     Callable create_iter_result_object =
      69         129 :         CodeFactory::CreateIterResultObject(isolate());
      70             : 
      71             :     // The {receiver} is closed already.
      72             :     Node* result = nullptr;
      73         129 :     switch (resume_mode) {
      74             :       case JSGeneratorObject::kNext:
      75             :         result = CallStub(create_iter_result_object, context,
      76          43 :                           UndefinedConstant(), TrueConstant());
      77          43 :         break;
      78             :       case JSGeneratorObject::kReturn:
      79             :         result =
      80          43 :             CallStub(create_iter_result_object, context, value, TrueConstant());
      81          43 :         break;
      82             :       case JSGeneratorObject::kThrow:
      83          43 :         result = CallRuntime(Runtime::kThrow, context, value);
      84          43 :         break;
      85             :     }
      86         129 :     Return(result);
      87             :   }
      88             : 
      89         129 :   BIND(&if_receiverisrunning);
      90             :   {
      91         129 :     CallRuntime(Runtime::kThrowGeneratorRunning, context);
      92         129 :     Unreachable();
      93         129 :   }
      94         129 : }
      95             : 
      96             : // ES6 #sec-generator.prototype.next
      97         172 : TF_BUILTIN(GeneratorPrototypeNext, GeneratorBuiltinsAssembler) {
      98             :   Node* receiver = Parameter(Descriptor::kReceiver);
      99             :   Node* value = Parameter(Descriptor::kValue);
     100             :   Node* context = Parameter(Descriptor::kContext);
     101             :   GeneratorPrototypeResume(receiver, value, context, JSGeneratorObject::kNext,
     102          43 :                            "[Generator].prototype.next");
     103          43 : }
     104             : 
     105             : // ES6 #sec-generator.prototype.return
     106         172 : TF_BUILTIN(GeneratorPrototypeReturn, GeneratorBuiltinsAssembler) {
     107             :   Node* receiver = Parameter(Descriptor::kReceiver);
     108             :   Node* value = Parameter(Descriptor::kValue);
     109             :   Node* context = Parameter(Descriptor::kContext);
     110             :   GeneratorPrototypeResume(receiver, value, context, JSGeneratorObject::kReturn,
     111          43 :                            "[Generator].prototype.return");
     112          43 : }
     113             : 
     114             : // ES6 #sec-generator.prototype.throw
     115         172 : TF_BUILTIN(GeneratorPrototypeThrow, GeneratorBuiltinsAssembler) {
     116             :   Node* receiver = Parameter(Descriptor::kReceiver);
     117             :   Node* exception = Parameter(Descriptor::kException);
     118             :   Node* context = Parameter(Descriptor::kContext);
     119             :   GeneratorPrototypeResume(receiver, exception, context,
     120             :                            JSGeneratorObject::kThrow,
     121          43 :                            "[Generator].prototype.throw");
     122          43 : }
     123             : 
     124             : }  // namespace internal
     125             : }  // namespace v8

Generated by: LCOV version 1.10