1// Copyright 2018 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
5namespace object {
6
7transitioning macro ObjectFromEntriesFastCase(implicit context: Context)(
8    iterable: JSAny): JSObject labels IfSlow {
9  typeswitch (iterable) {
10    case (array: FastJSArrayWithNoCustomIteration): {
11      const elements: FixedArray =
12          Cast<FixedArray>(array.elements) otherwise IfSlow;
13      const length: Smi = array.length;
14      const result: JSObject = NewJSObject();
15
16      for (let k: Smi = 0; k < length; ++k) {
17        const value: JSAny = array::LoadElementOrUndefined(elements, k);
18        const pair: KeyValuePair =
19            collections::LoadKeyValuePairNoSideEffects(value)
20            otherwise IfSlow;
21        // CreateDataProperty only handles Names and Numbers. Bail out if
22        // the key is not one of those types. Note that JSReceivers should
23        // always bail to the slow path, as calling Symbol.toPrimitive,
24        // toString, or valueOf could invalidate assumptions about the
25        // iterable.
26        typeswitch (pair.key) {
27          case (Name): {
28            CreateDataProperty(result, pair.key, pair.value);
29          }
30          case (Number): {
31            CreateDataProperty(result, pair.key, pair.value);
32          }
33          case (oddball: Oddball): {
34            CreateDataProperty(result, oddball.to_string, pair.value);
35          }
36          case (JSAny): {
37            goto IfSlow;
38          }
39        }
40      }
41      return result;
42    }
43    case (JSAny): {
44      goto IfSlow;
45    }
46  }
47}
48
49transitioning javascript builtin
50ObjectFromEntries(
51    js-implicit context: NativeContext, receiver: JSAny)(...arguments): JSAny {
52  const iterable: JSAny = arguments[0];
53  try {
54    if (IsNullOrUndefined(iterable)) goto Throw;
55    return ObjectFromEntriesFastCase(iterable) otherwise IfSlow;
56  } label IfSlow {
57    const result: JSObject = NewJSObject();
58    const fastIteratorResultMap: Map = GetIteratorResultMap();
59    let i: iterator::IteratorRecord = iterator::GetIterator(iterable);
60    try {
61      dcheck(!IsNullOrUndefined(i.object));
62      while (true) {
63        const step: JSReceiver =
64            iterator::IteratorStep(i, fastIteratorResultMap)
65            otherwise return result;
66        const iteratorValue: JSAny =
67            iterator::IteratorValue(step, fastIteratorResultMap);
68        const pair: KeyValuePair = collections::LoadKeyValuePair(iteratorValue);
69        CreateDataProperty(result, pair.key, pair.value);
70      }
71      return result;
72    } catch (e, message) deferred {
73      iterator::IteratorCloseOnException(i);
74      ReThrowWithMessage(context, e, message);
75    }
76  } label Throw deferred {
77    ThrowTypeError(MessageTemplate::kNotIterable);
78  }
79}
80}  // namespace object
81