%PDF- %PDF-
Mini Shell

Mini Shell

Direktori : /home/vacivi36/vittasync.vacivitta.com.br/vittasync/node/deps/v8/src/builtins/
Upload File :
Create Path :
Current File : /home/vacivi36/vittasync.vacivitta.com.br/vittasync/node/deps/v8/src/builtins/object-groupby.tq

// Copyright 2023 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 collections {

extern macro CollectionsBuiltinsAssembler::AddValueToKeyedGroup(
    OrderedHashMap, Object, Object, String): OrderedHashMap;

extern macro CollectionsBuiltinsAssembler::NormalizeNumberKey(JSAny): JSAny;

}  // namespace collections

// https://tc39.es/proposal-array-grouping/#sec-group-by
transitioning macro CoerceGroupKey(
    implicit context: Context)(key: JSAny, coerceToProperty: Boolean): JSAny {
  // 6.g. If coercion is property, then
  if (coerceToProperty == True) {
    // i. Set key to Completion(ToPropertyKey(key)).
    return ToName(key);
  }
  // 6.h. Else,
  //    i. Assert: coercion is zero.
  //   ii. If key is -0𝔽, set key to +0𝔽.
  return collections::NormalizeNumberKey(key);
}

// https://tc39.es/proposal-array-grouping/#sec-group-by
transitioning builtin GroupByGeneric(
    implicit context: Context)(items: JSAny, initialGroups: OrderedHashMap,
    callbackfn: Callable, coerceToProperty: Boolean,
    methodName: String): OrderedHashMap {
  let groups = initialGroups;

  // 4. Let iteratorRecord be ? GetIterator(items, sync).
  const fastIteratorResultMap = GetIteratorResultMap();
  const iteratorRecord = iterator::GetIterator(items);

  // 5. Let k be 0.
  let k: Number = 0;

  // 6. Repeat,
  while (true) {
    // a. If k ≥ 2^53 - 1, then
    //   i. Let error be ThrowCompletion(a newly created TypeError object).
    //   ii. Return ? IteratorClose(iteratorRecord, error).
    //
    // The spec requires that we throw an exception if index reaches 2^53-1,
    // but an empty loop would take >100 days to do this many iterations. To
    // actually run for that long would require an iterator that never set
    // done to true and a target array which somehow never ran out of
    // memory, e.g. a proxy that discarded the values. Ignoring this case
    // just means we would call the callback with 2^53.
    dcheck(k < kMaxSafeInteger);

    // b. Let next be ? IteratorStep(iteratorRecord).
    let next: JSReceiver;
    try {
      next = iterator::IteratorStep(iteratorRecord, fastIteratorResultMap)
          otherwise NextIsFalse;
    }
    // c. If next is false, then
    label NextIsFalse {
      // i. Return groups.
      return groups;
    }

    // d. Let value be ? IteratorValue(next).
    const value = iterator::IteratorValue(next, fastIteratorResultMap);

    // e. Let key be Completion(Call(callbackfn, undefined, « value, 𝔽(k) »)).
    let key: JSAny;
    try {
      key = Call(context, callbackfn, Undefined, value, k);
      key = CoerceGroupKey(key, coerceToProperty);
    } catch (e, message) {
      // f. and g.ii.
      // IfAbruptCloseIterator(key, iteratorRecord).
      iterator::IteratorCloseOnException(iteratorRecord);
      ReThrowWithMessage(context, e, message);
    }

    // i. Perform AddValueToKeyedGroup(groups, key, value).
    groups = collections::AddValueToKeyedGroup(groups, key, value, methodName);

    // j. Set k to k + 1.
    k += 1;
  }

  unreachable;
}

// https://tc39.es/proposal-array-grouping/#sec-group-by
transitioning macro GroupByImpl(
    implicit context: Context)(items: JSAny, callback: JSAny,
    coerceToProperty: Boolean, methodName: constexpr string): OrderedHashMap {
  // 1. Perform ? RequireObjectCoercible(items).
  RequireObjectCoercible(items, methodName);

  // 2. If IsCallable(callbackfn) is false, throw a TypeError exception.
  const callbackfn = Cast<Callable>(callback)
      otherwise ThrowTypeError(MessageTemplate::kCalledNonCallable, callback);

  // 3. Let groups be a new empty List.
  let groups = AllocateOrderedHashMap();

  try {
    typeswitch (items) {
      case (array: FastJSArrayForReadWithNoCustomIteration): {
        // Per spec, the iterator and its next method are cached up front. This
        // means that we only need to check for no custom iteration once up
        // front. Even though the grouping callback has arbitrary side effects,
        // mutations to %ArrayIteratorPrototype% will not be reflected during
        // the iteration itself. Therefore we don't need a "no custom iteration"
        // witness.
        let fastArrayWitness = NewFastJSArrayForReadWitness(array);
        const stableArray = fastArrayWitness.stable;
        let k: Smi = 0;

        try {
          while (k < stableArray.length) {
            fastArrayWitness.Recheck() otherwise goto SlowArrayContinuation;
            let value: JSAny;
            try {
              value =
                  fastArrayWitness.LoadElementNoHole(k) otherwise IsUndefined;
            } label IsUndefined {
              value = Undefined;
            }
            const key = CoerceGroupKey(
                Call(context, callbackfn, Undefined, value, k),
                coerceToProperty);
            groups = collections::AddValueToKeyedGroup(
                groups, key, value, methodName);
            ++k;
          }
        } label SlowArrayContinuation deferred {
          // The grouping callback can mutate the array such that it is no
          // longer fast, but it is still a JSArray. Since the spec caches the
          // iterator up front, a fully generic fallback is not needed. Instead
          // we encode the array iterator logic here directly for the rest of
          // the loop.
          while (k < stableArray.length) {
            const value = GetProperty(stableArray, k);
            const key = CoerceGroupKey(
                Call(context, callbackfn, Undefined, value, k),
                coerceToProperty);
            groups = collections::AddValueToKeyedGroup(
                groups, key, value, methodName);
            ++k;
          }
        }

        return groups;
      }
      case (JSAny): {
        goto SlowGeneric;
      }
    }
  } label SlowGeneric {
    return GroupByGeneric(
        items, groups, callbackfn, coerceToProperty, methodName);
  }
}

transitioning javascript builtin ObjectGroupBy(
    js-implicit context: NativeContext, receiver: JSAny)(items: JSAny,
    callback: JSAny): JSAny {
  // 1. Let groups be ? GroupBy(items, callbackfn, property).
  const groups: OrderedHashMap = GroupByImpl(
      items, callback, /* coerceToProperty */ True, 'Object.groupBy');

  let iter = collections::NewUnmodifiedOrderedHashMapIterator(groups);

  // 2. Let obj be OrdinaryObjectCreate(null).
  // 3. For each Record { [[Key]], [[Elements]] } g of groups, do
  //   a. Let elements be CreateArrayFromList(g.[[Elements]]).
  //   b. Perform ! CreateDataPropertyOrThrow(obj, g.[[Key]], elements).
  let properties: NameDictionary|SwissNameDictionary;

  @if(V8_ENABLE_SWISS_NAME_DICTIONARY) {
    properties =
        AllocateSwissNameDictionary(Convert<intptr>(iter.usedCapacity));
  }
  @ifnot(V8_ENABLE_SWISS_NAME_DICTIONARY) {
    properties = AllocateNameDictionary(Convert<intptr>(iter.usedCapacity));
  }
  const nullProtoMap = LoadSlowObjectWithNullPrototypeMap(context);
  const obj = AllocateJSObjectFromMap(nullProtoMap, properties);

  // TODO(v8:12499): Determine more specific elements map if worth it.
  try {
    const arrayMap = GetFastPackedElementsJSArrayMap();
    while (true) {
      const entry = iter.Next() otherwise Done;
      const elements = ArrayListElements(UnsafeCast<ArrayList>(entry.value));
      const array = NewJSArray(arrayMap, elements);
      CreateDataProperty(obj, entry.key, array);
    }
  } label Done {}

  // 4. Return obj.
  return obj;
}

Zerion Mini Shell 1.0