// Copyright 2017 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "src/builtins/builtins-iterator-gen.h"
#include "src/builtins/growable-fixed-array-gen.h"

#include "src/heap/factory-inl.h"

namespace v8 {
namespace internal {

using compiler::Node;

TNode<Object> IteratorBuiltinsAssembler::GetIteratorMethod(Node* context,
                                                           Node* object) {
  return GetProperty(context, object, factory()->iterator_symbol());
}

IteratorRecord IteratorBuiltinsAssembler::GetIterator(Node* context,
                                                      Node* object,
                                                      Label* if_exception,
                                                      Variable* exception) {
  Node* method = GetIteratorMethod(context, object);
  return GetIterator(context, object, method, if_exception, exception);
}

IteratorRecord IteratorBuiltinsAssembler::GetIterator(Node* context,
                                                      Node* object,
                                                      Node* method,
                                                      Label* if_exception,
                                                      Variable* exception) {
  GotoIfException(method, if_exception, exception);

  Label if_not_callable(this, Label::kDeferred), if_callable(this);
  GotoIf(TaggedIsSmi(method), &if_not_callable);
  Branch(IsCallable(method), &if_callable, &if_not_callable);

  BIND(&if_not_callable);
  {
    Node* ret = CallRuntime(Runtime::kThrowTypeError, context,
                            SmiConstant(MessageTemplate::kNotIterable), object);
    GotoIfException(ret, if_exception, exception);
    Unreachable();
  }

  BIND(&if_callable);
  {
    Callable callable = CodeFactory::Call(isolate());
    Node* iterator = CallJS(callable, context, method, object);
    GotoIfException(iterator, if_exception, exception);

    Label get_next(this), if_notobject(this, Label::kDeferred);
    GotoIf(TaggedIsSmi(iterator), &if_notobject);
    Branch(IsJSReceiver(iterator), &get_next, &if_notobject);

    BIND(&if_notobject);
    {
      Node* ret = CallRuntime(Runtime::kThrowSymbolIteratorInvalid, context);
      GotoIfException(ret, if_exception, exception);
      Unreachable();
    }

    BIND(&get_next);
    Node* const next = GetProperty(context, iterator, factory()->next_string());
    GotoIfException(next, if_exception, exception);

    return IteratorRecord{TNode<JSReceiver>::UncheckedCast(iterator),
                          TNode<Object>::UncheckedCast(next)};
  }
}

Node* IteratorBuiltinsAssembler::IteratorStep(
    Node* context, const IteratorRecord& iterator, Label* if_done,
    Node* fast_iterator_result_map, Label* if_exception, Variable* exception) {
  DCHECK_NOT_NULL(if_done);
  // 1. a. Let result be ? Invoke(iterator, "next", « »).
  Callable callable = CodeFactory::Call(isolate());
  Node* result = CallJS(callable, context, iterator.next, iterator.object);
  GotoIfException(result, if_exception, exception);

  // 3. If Type(result) is not Object, throw a TypeError exception.
  Label if_notobject(this, Label::kDeferred), return_result(this);
  GotoIf(TaggedIsSmi(result), &if_notobject);
  Node* result_map = LoadMap(result);

  if (fast_iterator_result_map != nullptr) {
    // Fast iterator result case:
    Label if_generic(this);

    // 4. Return result.
    GotoIfNot(WordEqual(result_map, fast_iterator_result_map), &if_generic);

    // IteratorComplete
    // 2. Return ToBoolean(? Get(iterResult, "done")).
    Node* done = LoadObjectField(result, JSIteratorResult::kDoneOffset);
    BranchIfToBooleanIsTrue(done, if_done, &return_result);

    BIND(&if_generic);
  }

  // Generic iterator result case:
  {
    // 3. If Type(result) is not Object, throw a TypeError exception.
    GotoIfNot(IsJSReceiverMap(result_map), &if_notobject);

    // IteratorComplete
    // 2. Return ToBoolean(? Get(iterResult, "done")).
    Node* done = GetProperty(context, result, factory()->done_string());
    GotoIfException(done, if_exception, exception);
    BranchIfToBooleanIsTrue(done, if_done, &return_result);
  }

  BIND(&if_notobject);
  {
    Node* ret =
        CallRuntime(Runtime::kThrowIteratorResultNotAnObject, context, result);
    GotoIfException(ret, if_exception, exception);
    Unreachable();
  }

  BIND(&return_result);
  return result;
}

Node* IteratorBuiltinsAssembler::IteratorValue(Node* context, Node* result,
                                               Node* fast_iterator_result_map,
                                               Label* if_exception,
                                               Variable* exception) {
  CSA_ASSERT(this, IsJSReceiver(result));

  Label exit(this);
  VARIABLE(var_value, MachineRepresentation::kTagged);
  if (fast_iterator_result_map != nullptr) {
    // Fast iterator result case:
    Label if_generic(this);
    Node* map = LoadMap(result);
    GotoIfNot(WordEqual(map, fast_iterator_result_map), &if_generic);
    var_value.Bind(LoadObjectField(result, JSIteratorResult::kValueOffset));
    Goto(&exit);

    BIND(&if_generic);
  }

  // Generic iterator result case:
  {
    Node* value = GetProperty(context, result, factory()->value_string());
    GotoIfException(value, if_exception, exception);
    var_value.Bind(value);
    Goto(&exit);
  }

  BIND(&exit);
  return var_value.value();
}

void IteratorBuiltinsAssembler::IteratorCloseOnException(
    Node* context, const IteratorRecord& iterator, Label* if_exception,
    Variable* exception) {
  // Perform ES #sec-iteratorclose when an exception occurs. This simpler
  // algorithm does not include redundant steps which are never reachable from
  // the spec IteratorClose algorithm.
  DCHECK_NOT_NULL(if_exception);
  DCHECK_NOT_NULL(exception);
  CSA_ASSERT(this, IsNotTheHole(exception->value()));
  CSA_ASSERT(this, IsJSReceiver(iterator.object));

  // Let return be ? GetMethod(iterator, "return").
  Node* method =
      GetProperty(context, iterator.object, factory()->return_string());
  GotoIfException(method, if_exception, exception);

  // If return is undefined, return Completion(completion).
  GotoIf(Word32Or(IsUndefined(method), IsNull(method)), if_exception);

  {
    // Let innerResult be Call(return, iterator, « »).
    // If an exception occurs, the original exception remains bound
    Node* inner_result =
        CallJS(CodeFactory::Call(isolate()), context, method, iterator.object);
    GotoIfException(inner_result, if_exception, nullptr);

    // (If completion.[[Type]] is throw) return Completion(completion).
    Goto(if_exception);
  }
}

void IteratorBuiltinsAssembler::IteratorCloseOnException(
    Node* context, const IteratorRecord& iterator, Variable* exception) {
  Label rethrow(this, Label::kDeferred);
  IteratorCloseOnException(context, iterator, &rethrow, exception);

  BIND(&rethrow);
  CallRuntime(Runtime::kReThrow, context, exception->value());
  Unreachable();
}

TNode<JSArray> IteratorBuiltinsAssembler::IterableToList(
    TNode<Context> context, TNode<Object> iterable, TNode<Object> iterator_fn) {
  Label fast_path(this), slow_path(this), done(this);

  TVARIABLE(JSArray, created_list);

  // This is a fast-path for ignoring the iterator.
  // TODO(petermarshall): Port IterableToListCanBeElided to CSA.
  Node* elided =
      CallRuntime(Runtime::kIterableToListCanBeElided, context, iterable);
  CSA_ASSERT(this, IsBoolean(elided));
  Branch(IsTrue(elided), &fast_path, &slow_path);

  BIND(&fast_path);
  {
    TNode<JSArray> input_array = CAST(iterable);
    created_list = CAST(CloneFastJSArray(context, input_array));
    Goto(&done);
  }

  BIND(&slow_path);
  {
    // 1. Let iteratorRecord be ? GetIterator(items, method).
    IteratorRecord iterator_record =
        GetIterator(context, iterable, iterator_fn);

    // 2. Let values be a new empty List.
    GrowableFixedArray values(state());

    Variable* vars[] = {values.var_array(), values.var_length(),
                        values.var_capacity()};
    Label loop_start(this, 3, vars), loop_end(this);
    Goto(&loop_start);
    // 3. Let next be true.
    // 4. Repeat, while next is not false
    BIND(&loop_start);
    {
      //  a. Set next to ? IteratorStep(iteratorRecord).
      TNode<Object> next =
          CAST(IteratorStep(context, iterator_record, &loop_end));
      //  b. If next is not false, then
      //   i. Let nextValue be ? IteratorValue(next).
      TNode<Object> next_value = CAST(IteratorValue(context, next));
      //   ii. Append nextValue to the end of the List values.
      values.Push(next_value);
      Goto(&loop_start);
    }
    BIND(&loop_end);

    created_list = values.ToJSArray(context);
    Goto(&done);
  }

  BIND(&done);
  return created_list.value();
}

TNode<JSArray> IteratorBuiltinsAssembler::IterableToList(
    TNode<Context> context, TNode<Object> iterable) {
  TNode<Object> method = GetIteratorMethod(context, iterable);
  return IterableToList(context, iterable, method);
}

}  // namespace internal
}  // namespace v8
