11cb0ef41Sopenharmony_ci// Copyright 2020 the V8 project authors. All rights reserved.
21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be
31cb0ef41Sopenharmony_ci// found in the LICENSE file.
41cb0ef41Sopenharmony_ci
51cb0ef41Sopenharmony_cinamespace internal {
61cb0ef41Sopenharmony_ci
71cb0ef41Sopenharmony_cinamespace runtime {
81cb0ef41Sopenharmony_ciextern runtime GetTemplateObject(implicit context: Context)(
91cb0ef41Sopenharmony_ci    TemplateObjectDescription, SharedFunctionInfo, Smi): JSAny;
101cb0ef41Sopenharmony_ci}
111cb0ef41Sopenharmony_ci
121cb0ef41Sopenharmony_cibuiltin GetTemplateObject(
131cb0ef41Sopenharmony_ci    context: Context, shared: SharedFunctionInfo,
141cb0ef41Sopenharmony_ci    description: TemplateObjectDescription, slot: uintptr,
151cb0ef41Sopenharmony_ci    maybeFeedbackVector: Undefined|FeedbackVector): JSArray {
161cb0ef41Sopenharmony_ci  // TODO(jgruber): Consider merging with the GetTemplateObject bytecode
171cb0ef41Sopenharmony_ci  // handler; the current advantage of the split implementation is that the
181cb0ef41Sopenharmony_ci  // bytecode can skip most work if feedback exists.
191cb0ef41Sopenharmony_ci
201cb0ef41Sopenharmony_ci  // TODO(v8:9891): Remove this dcheck once all callers are ported to Torque.
211cb0ef41Sopenharmony_ci  // This dcheck ensures correctness of maybeFeedbackVector's type which can
221cb0ef41Sopenharmony_ci  // be easily broken for calls from CSA.
231cb0ef41Sopenharmony_ci  dcheck(
241cb0ef41Sopenharmony_ci      IsUndefined(maybeFeedbackVector) ||
251cb0ef41Sopenharmony_ci      Is<FeedbackVector>(maybeFeedbackVector));
261cb0ef41Sopenharmony_ci  try {
271cb0ef41Sopenharmony_ci    const vector =
281cb0ef41Sopenharmony_ci        Cast<FeedbackVector>(maybeFeedbackVector) otherwise CallRuntime;
291cb0ef41Sopenharmony_ci    return Cast<JSArray>(ic::LoadFeedbackVectorSlot(vector, slot))
301cb0ef41Sopenharmony_ci        otherwise CallRuntime;
311cb0ef41Sopenharmony_ci  } label CallRuntime deferred {
321cb0ef41Sopenharmony_ci    const result = UnsafeCast<JSArray>(runtime::GetTemplateObject(
331cb0ef41Sopenharmony_ci        description, shared, Convert<Smi>(Signed(slot))));
341cb0ef41Sopenharmony_ci    const vector =
351cb0ef41Sopenharmony_ci        Cast<FeedbackVector>(maybeFeedbackVector) otherwise return result;
361cb0ef41Sopenharmony_ci    ic::StoreFeedbackVectorSlot(vector, slot, result);
371cb0ef41Sopenharmony_ci    return result;
381cb0ef41Sopenharmony_ci  }
391cb0ef41Sopenharmony_ci}
401cb0ef41Sopenharmony_ci
411cb0ef41Sopenharmony_ciextern transitioning builtin ForInFilter(implicit context: Context)(
421cb0ef41Sopenharmony_ci    JSAny, HeapObject): JSAny;
431cb0ef41Sopenharmony_ciextern enum ForInFeedback extends uint31 { kAny, ...}
441cb0ef41Sopenharmony_ciextern macro UpdateFeedback(
451cb0ef41Sopenharmony_ci    SmiTagged<ForInFeedback>, Undefined | FeedbackVector, uintptr,
461cb0ef41Sopenharmony_ci    constexpr UpdateFeedbackMode): void;
471cb0ef41Sopenharmony_ci
481cb0ef41Sopenharmony_ci@export
491cb0ef41Sopenharmony_citransitioning macro ForInNextSlow(
501cb0ef41Sopenharmony_ci    context: Context, slot: uintptr, receiver: JSAnyNotSmi, key: JSAny,
511cb0ef41Sopenharmony_ci    cacheType: Object, maybeFeedbackVector: Undefined|FeedbackVector,
521cb0ef41Sopenharmony_ci    guaranteedFeedback: constexpr UpdateFeedbackMode): JSAny {
531cb0ef41Sopenharmony_ci  dcheck(receiver.map != cacheType);  // Handled on the fast path.
541cb0ef41Sopenharmony_ci  UpdateFeedback(
551cb0ef41Sopenharmony_ci      SmiTag<ForInFeedback>(ForInFeedback::kAny), maybeFeedbackVector, slot,
561cb0ef41Sopenharmony_ci      guaranteedFeedback);
571cb0ef41Sopenharmony_ci  return ForInFilter(key, receiver);
581cb0ef41Sopenharmony_ci}
591cb0ef41Sopenharmony_ci
601cb0ef41Sopenharmony_ci// Note: the untagged {slot} parameter must be in the first couple of args to
611cb0ef41Sopenharmony_ci// guarantee it's allocated in a register.
621cb0ef41Sopenharmony_citransitioning builtin ForInNext(
631cb0ef41Sopenharmony_ci    context: Context, slot: uintptr, receiver: JSAnyNotSmi,
641cb0ef41Sopenharmony_ci    cacheArray: FixedArray, cacheType: Object, cacheIndex: Smi,
651cb0ef41Sopenharmony_ci    feedbackVector: FeedbackVector): JSAny {
661cb0ef41Sopenharmony_ci  // Load the next key from the enumeration array.
671cb0ef41Sopenharmony_ci  const key = UnsafeCast<JSAny>(cacheArray.objects[cacheIndex]);
681cb0ef41Sopenharmony_ci
691cb0ef41Sopenharmony_ci  if (receiver.map == cacheType) {
701cb0ef41Sopenharmony_ci    // The enum cache is in use for {receiver}, the {key} is definitely valid.
711cb0ef41Sopenharmony_ci    return key;
721cb0ef41Sopenharmony_ci  }
731cb0ef41Sopenharmony_ci
741cb0ef41Sopenharmony_ci  return ForInNextSlow(
751cb0ef41Sopenharmony_ci      context, slot, receiver, key, cacheType, feedbackVector,
761cb0ef41Sopenharmony_ci      UpdateFeedbackMode::kGuaranteedFeedback);
771cb0ef41Sopenharmony_ci}
781cb0ef41Sopenharmony_ci
791cb0ef41Sopenharmony_ciextern macro GetImportMetaObject(Context): Object;
801cb0ef41Sopenharmony_ciextern macro LoadContextFromBaseline(): Context;
811cb0ef41Sopenharmony_ci
821cb0ef41Sopenharmony_cibuiltin GetImportMetaObjectBaseline(): Object {
831cb0ef41Sopenharmony_ci  const context: Context = LoadContextFromBaseline();
841cb0ef41Sopenharmony_ci  return GetImportMetaObject(context);
851cb0ef41Sopenharmony_ci}
861cb0ef41Sopenharmony_ci
871cb0ef41Sopenharmony_ci}  // namespace internal
88