summaryrefslogtreecommitdiff
path: root/deps/v8/src/builtins/object-fromentries.tq
blob: 32115e78eab250cc765cdfa2c6ab02f16a20a1f2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
// Copyright 2018 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.

namespace object {

  transitioning macro ObjectFromEntriesFastCase(implicit context: Context)(
      iterable: Object): JSObject labels IfSlow {
    typeswitch (iterable) {
      case (array: FastJSArrayWithNoCustomIteration): {
        const elements: FixedArray =
            Cast<FixedArray>(array.elements) otherwise IfSlow;
        const length: Smi = array.length;
        const result: JSObject = NewJSObject();

        for (let k: Smi = 0; k < length; ++k) {
          const value: Object = array::LoadElementOrUndefined(elements, k);
          const pair: KeyValuePair =
              collections::LoadKeyValuePairNoSideEffects(value)
              otherwise IfSlow;
          // Bail out if ToPropertyKey will attempt to load and call
          // Symbol.toPrimitive, toString, and valueOf, which could
          // invalidate assumptions about the iterable.
          if (Is<JSReceiver>(pair.key)) goto IfSlow;
          FastCreateDataProperty(result, pair.key, pair.value);
        }
        return result;
      }
      case (Object): {
        goto IfSlow;
      }
    }
  }

  transitioning javascript builtin
  ObjectFromEntries(js-implicit context: Context, receiver: Object)(
      ...arguments): Object {
    const iterable: Object = arguments[0];
    try {
      if (IsNullOrUndefined(iterable)) goto Throw;
      return ObjectFromEntriesFastCase(iterable) otherwise IfSlow;
    }
    label IfSlow {
      const result: JSObject = NewJSObject();
      const fastIteratorResultMap: Map = GetIteratorResultMap();
      let i: iterator::IteratorRecord = iterator::GetIterator(iterable);
      try {
        assert(!IsNullOrUndefined(i.object));
        while (true) {
          const step: JSReceiver =
              iterator::IteratorStep(i, fastIteratorResultMap)
              otherwise return result;
          const iteratorValue: Object =
              iterator::IteratorValue(step, fastIteratorResultMap);
          const pair: KeyValuePair =
              collections::LoadKeyValuePair(iteratorValue);
          FastCreateDataProperty(result, pair.key, pair.value);
        }
        return result;
      } catch (e) deferred {
        iterator::IteratorCloseOnException(i, e);
      }
    }
    label Throw deferred {
      ThrowTypeError(kNotIterable);
    }
  }
}  // namespace object