LCOV - code coverage report
Current view: top level - src/builtins - builtins-iterator-gen.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 75 75 100.0 %
Date: 2017-10-20 Functions: 5 5 100.0 %

          Line data    Source code
       1             : // Copyright 2017 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-iterator-gen.h"
       6             : 
       7             : #include "src/factory-inl.h"
       8             : 
       9             : namespace v8 {
      10             : namespace internal {
      11             : 
      12             : using compiler::Node;
      13             : 
      14         124 : Node* IteratorBuiltinsAssembler::GetIterator(Node* context, Node* object,
      15             :                                              Label* if_exception,
      16             :                                              Variable* exception) {
      17         248 :   Node* method = GetProperty(context, object, factory()->iterator_symbol());
      18         124 :   GotoIfException(method, if_exception, exception);
      19             : 
      20         124 :   Callable callable = CodeFactory::Call(isolate());
      21         124 :   Node* iterator = CallJS(callable, context, method, object);
      22         124 :   GotoIfException(iterator, if_exception, exception);
      23             : 
      24         124 :   Label done(this), if_notobject(this, Label::kDeferred);
      25         248 :   GotoIf(TaggedIsSmi(iterator), &if_notobject);
      26         248 :   Branch(IsJSReceiver(iterator), &done, &if_notobject);
      27             : 
      28         124 :   BIND(&if_notobject);
      29             :   {
      30             :     Node* ret =
      31             :         CallRuntime(Runtime::kThrowTypeError, context,
      32         124 :                     SmiConstant(MessageTemplate::kNotAnIterator), iterator);
      33         124 :     GotoIfException(ret, if_exception, exception);
      34         124 :     Unreachable();
      35             :   }
      36             : 
      37         124 :   BIND(&done);
      38         124 :   return iterator;
      39             : }
      40             : 
      41         124 : Node* IteratorBuiltinsAssembler::IteratorStep(Node* context, Node* iterator,
      42             :                                               Label* if_done,
      43             :                                               Node* fast_iterator_result_map,
      44             :                                               Label* if_exception,
      45             :                                               Variable* exception) {
      46             :   DCHECK_NOT_NULL(if_done);
      47             : 
      48             :   // IteratorNext
      49         248 :   Node* next_method = GetProperty(context, iterator, factory()->next_string());
      50         124 :   GotoIfException(next_method, if_exception, exception);
      51             : 
      52             :   // 1. a. Let result be ? Invoke(iterator, "next", « »).
      53         124 :   Callable callable = CodeFactory::Call(isolate());
      54         124 :   Node* result = CallJS(callable, context, next_method, iterator);
      55         124 :   GotoIfException(result, if_exception, exception);
      56             : 
      57             :   // 3. If Type(result) is not Object, throw a TypeError exception.
      58         124 :   Label if_notobject(this, Label::kDeferred), return_result(this);
      59         248 :   GotoIf(TaggedIsSmi(result), &if_notobject);
      60         248 :   GotoIfNot(IsJSReceiver(result), &if_notobject);
      61             : 
      62         248 :   VARIABLE(var_done, MachineRepresentation::kTagged);
      63             : 
      64         124 :   if (fast_iterator_result_map != nullptr) {
      65             :     // Fast iterator result case:
      66             :     Label if_generic(this);
      67             : 
      68             :     // 4. Return result.
      69         248 :     Node* map = LoadMap(result);
      70         248 :     GotoIfNot(WordEqual(map, fast_iterator_result_map), &if_generic);
      71             : 
      72             :     // IteratorComplete
      73             :     // 2. Return ToBoolean(? Get(iterResult, "done")).
      74             :     Node* done = LoadObjectField(result, JSIteratorResult::kDoneOffset);
      75             :     CSA_ASSERT(this, IsBoolean(done));
      76         124 :     var_done.Bind(done);
      77         124 :     Goto(&return_result);
      78             : 
      79         124 :     BIND(&if_generic);
      80             :   }
      81             : 
      82             :   // Generic iterator result case:
      83             :   {
      84             :     // IteratorComplete
      85             :     // 2. Return ToBoolean(? Get(iterResult, "done")).
      86         248 :     Node* done = GetProperty(context, result, factory()->done_string());
      87         124 :     GotoIfException(done, if_exception, exception);
      88         124 :     var_done.Bind(done);
      89             : 
      90             :     Label to_boolean(this, Label::kDeferred);
      91         248 :     GotoIf(TaggedIsSmi(done), &to_boolean);
      92         248 :     Branch(IsBoolean(done), &return_result, &to_boolean);
      93             : 
      94         124 :     BIND(&to_boolean);
      95         124 :     var_done.Bind(CallBuiltin(Builtins::kToBoolean, context, done));
      96         124 :     Goto(&return_result);
      97             :   }
      98             : 
      99         124 :   BIND(&if_notobject);
     100             :   {
     101             :     Node* ret =
     102             :         CallRuntime(Runtime::kThrowIteratorResultNotAnObject, context, result);
     103         124 :     GotoIfException(ret, if_exception, exception);
     104         124 :     Unreachable();
     105             :   }
     106             : 
     107         124 :   BIND(&return_result);
     108         372 :   GotoIf(IsTrue(var_done.value()), if_done);
     109         124 :   return result;
     110             : }
     111             : 
     112         124 : Node* IteratorBuiltinsAssembler::IteratorValue(Node* context, Node* result,
     113             :                                                Node* fast_iterator_result_map,
     114             :                                                Label* if_exception,
     115             :                                                Variable* exception) {
     116             :   CSA_ASSERT(this, IsJSReceiver(result));
     117             : 
     118         124 :   Label exit(this);
     119         248 :   VARIABLE(var_value, MachineRepresentation::kTagged);
     120         124 :   if (fast_iterator_result_map != nullptr) {
     121             :     // Fast iterator result case:
     122             :     Label if_generic(this);
     123         248 :     Node* map = LoadMap(result);
     124         248 :     GotoIfNot(WordEqual(map, fast_iterator_result_map), &if_generic);
     125         124 :     var_value.Bind(LoadObjectField(result, JSIteratorResult::kValueOffset));
     126         124 :     Goto(&exit);
     127             : 
     128         124 :     BIND(&if_generic);
     129             :   }
     130             : 
     131             :   // Generic iterator result case:
     132             :   {
     133         248 :     Node* value = GetProperty(context, result, factory()->value_string());
     134         124 :     GotoIfException(value, if_exception, exception);
     135         124 :     var_value.Bind(value);
     136         124 :     Goto(&exit);
     137             :   }
     138             : 
     139         124 :   BIND(&exit);
     140         248 :   return var_value.value();
     141             : }
     142             : 
     143         124 : void IteratorBuiltinsAssembler::IteratorCloseOnException(Node* context,
     144             :                                                          Node* iterator,
     145             :                                                          Label* if_exception,
     146             :                                                          Variable* exception) {
     147             :   // Perform ES #sec-iteratorclose when an exception occurs. This simpler
     148             :   // algorithm does not include redundant steps which are never reachable from
     149             :   // the spec IteratorClose algorithm.
     150             :   DCHECK_NOT_NULL(if_exception);
     151             :   DCHECK_NOT_NULL(exception);
     152             :   CSA_ASSERT(this, IsNotTheHole(exception->value()));
     153             :   CSA_ASSERT(this, IsJSReceiver(iterator));
     154             : 
     155             :   // Let return be ? GetMethod(iterator, "return").
     156         248 :   Node* method = GetProperty(context, iterator, factory()->return_string());
     157         124 :   GotoIfException(method, if_exception, exception);
     158             : 
     159             :   // If return is undefined, return Completion(completion).
     160         496 :   GotoIf(Word32Or(IsUndefined(method), IsNull(method)), if_exception);
     161             : 
     162             :   {
     163             :     // Let innerResult be Call(return, iterator, « »).
     164             :     // If an exception occurs, the original exception remains bound
     165             :     Node* inner_result =
     166         124 :         CallJS(CodeFactory::Call(isolate()), context, method, iterator);
     167         124 :     GotoIfException(inner_result, if_exception, nullptr);
     168             : 
     169             :     // (If completion.[[Type]] is throw) return Completion(completion).
     170         124 :     Goto(if_exception);
     171             :   }
     172         124 : }
     173             : 
     174          62 : void IteratorBuiltinsAssembler::IteratorCloseOnException(Node* context,
     175             :                                                          Node* iterator,
     176             :                                                          Variable* exception) {
     177          62 :   Label rethrow(this, Label::kDeferred);
     178          62 :   IteratorCloseOnException(context, iterator, &rethrow, exception);
     179             : 
     180          62 :   BIND(&rethrow);
     181          62 :   CallRuntime(Runtime::kReThrow, context, exception->value());
     182          62 :   Unreachable();
     183          62 : }
     184             : 
     185             : }  // namespace internal
     186             : }  // namespace v8

Generated by: LCOV version 1.10