void ESTreeIRGen::emitRestProperty(
    bool declInit,
    ESTree::RestElementNode *rest,
    const llvh::SmallVectorImpl<Value *> &excludedItems,
    hermes::Value *source) {
  auto lref = createLRef(rest->_argument, declInit);

  // Construct the excluded items.
  HBCAllocObjectFromBufferInst::ObjectPropertyMap exMap{};
  llvh::SmallVector<Value *, 4> computedExcludedItems{};
  // Keys need de-duping so we don't create a dummy exclusion object with
  // duplicate keys.
  llvh::DenseSet<Literal *> keyDeDupeSet;
  auto *zeroValue = Builder.getLiteralPositiveZero();

  for (Value *key : excludedItems) {
    if (auto *lit = llvh::dyn_cast<Literal>(key)) {
      // If the key is a literal, we can place it in the
      // HBCAllocObjectFromBufferInst buffer.
      if (keyDeDupeSet.insert(lit).second) {
        exMap.emplace_back(std::make_pair(lit, zeroValue));
      }
    } else {
      // If the key is not a literal, then we have to dynamically populate the
      // excluded object with it after creation from the buffer.
      computedExcludedItems.push_back(key);
    }
  }

  Value *excludedObj;
  if (excludedItems.empty()) {
    excludedObj = Builder.getLiteralUndefined();
  } else {
    // This size is only a hint as the true size may change if there are
    // duplicates when computedExcludedItems is processed at run-time.
    auto excludedSizeHint = exMap.size() + computedExcludedItems.size();
    if (exMap.empty()) {
      excludedObj = Builder.createAllocObjectInst(excludedSizeHint);
    } else {
      excludedObj =
          Builder.createHBCAllocObjectFromBufferInst(exMap, excludedSizeHint);
    }
    for (Value *key : computedExcludedItems) {
      Builder.createStorePropertyInst(zeroValue, excludedObj, key);
    }
  }

  auto *restValue = genBuiltinCall(
      BuiltinMethod::HermesBuiltin_copyDataProperties,
      {Builder.createAllocObjectInst(0), source, excludedObj});

  lref.emitStore(restValue);
}
void ESTreeIRGen::emitRestProperty(
    bool declInit,
    ESTree::RestElementNode *rest,
    const llvh::SmallVectorImpl<Value *> &excludedItems,
    hermes::Value *source) {
  auto lref = createLRef(rest->_argument, declInit);

   
  HBCAllocObjectFromBufferInst::ObjectPropertyMap exMap{};
  llvh::SmallVector<Value *, 4> computedExcludedItems{};
   
   
  llvh::DenseSet<Literal *> keyDeDupeSet;
  auto *zeroValue = Builder.getLiteralPositiveZero();

  for (Value *key : excludedItems) {
    if (auto *lit = llvh::dyn_cast<Literal>(key)) {
       
       
      if (keyDeDupeSet.insert(lit).second) {
        exMap.emplace_back(std::make_pair(lit, zeroValue));
      }
    } else {
       
       
      computedExcludedItems.push_back(key);
    }
  }

  Value *excludedObj;
  if (excludedItems.empty()) {
    excludedObj = Builder.getLiteralUndefined();
  } else {
     
     
    auto excludedSizeHint = exMap.size() + computedExcludedItems.size();
    if (exMap.empty()) {
      excludedObj = Builder.createAllocObjectInst(excludedSizeHint);
    } else {
      excludedObj =
          Builder.createHBCAllocObjectFromBufferInst(exMap, excludedSizeHint);
    }
    for (Value *key : computedExcludedItems) {
      Builder.createStorePropertyInst(zeroValue, excludedObj, key);
    }
  }

  auto *restValue = genBuiltinCall(
      BuiltinMethod::HermesBuiltin_copyDataProperties,
      {Builder.createAllocObjectInst(0), source, excludedObj});

  lref.emitStore(restValue);
}