// Copyright 2019 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.

#include 'src/builtins/builtins-regexp-gen.h'

namespace regexp {

transitioning macro
RegExpPrototypeSearchBodyFast(implicit context: Context)(
    regexp: JSRegExp, string: String): JSAny {
  assert(IsFastRegExpPermissive(regexp));

  // Grab the initial value of last index.
  const previousLastIndex: Smi = FastLoadLastIndex(regexp);

  // Ensure last index is 0.
  FastStoreLastIndex(regexp, 0);

  // Call exec.
  try {
    const matchIndices: RegExpMatchInfo =
        RegExpPrototypeExecBodyWithoutResultFast(
            UnsafeCast<JSRegExp>(regexp), string)
        otherwise DidNotMatch;

    // Successful match.
    // Reset last index.
    FastStoreLastIndex(regexp, previousLastIndex);

    // Return the index of the match.
    return UnsafeCast<Smi>(
        matchIndices.objects[kRegExpMatchInfoFirstCaptureIndex]);
  } label DidNotMatch {
    // Reset last index and return -1.
    FastStoreLastIndex(regexp, previousLastIndex);
    return SmiConstant(-1);
  }
}

extern macro RegExpBuiltinsAssembler::BranchIfRegExpResult(
    implicit context: Context)(Object): never labels IsUnmodified,
    IsModified;

macro
IsRegExpResult(implicit context: Context)(execResult: HeapObject): bool {
  BranchIfRegExpResult(execResult) otherwise return true, return false;
}

transitioning macro RegExpPrototypeSearchBodySlow(implicit context: Context)(
    regexp: JSReceiver, string: String): JSAny {
  // Grab the initial value of last index.
  const previousLastIndex = SlowLoadLastIndex(regexp);
  const smiZero: Smi = 0;

  // Ensure last index is 0.
  if (!SameValue(previousLastIndex, smiZero)) {
    SlowStoreLastIndex(regexp, smiZero);
  }

  // Call exec.
  const execResult = RegExpExec(regexp, string);

  // Reset last index if necessary.
  const currentLastIndex = SlowLoadLastIndex(regexp);
  if (!SameValue(currentLastIndex, previousLastIndex)) {
    SlowStoreLastIndex(regexp, previousLastIndex);
  }

  // Return -1 if no match was found.
  if (execResult == Null) {
    return SmiConstant(-1);
  }

  // Return the index of the match.
  const fastExecResult = Cast<JSRegExpResult>(execResult)
      otherwise return GetProperty(execResult, 'index');
  return fastExecResult.index;
}

// Helper that skips a few initial checks. and assumes...
// 1) receiver is a "fast permissive" RegExp
// 2) pattern is a string
transitioning builtin RegExpSearchFast(implicit context: Context)(
    receiver: JSRegExp, string: String): JSAny {
  return RegExpPrototypeSearchBodyFast(receiver, string);
}

// ES#sec-regexp.prototype-@@search
// RegExp.prototype [ @@search ] ( string )
transitioning javascript builtin RegExpPrototypeSearch(
    js-implicit context: NativeContext, receiver: JSAny)(string: JSAny): JSAny {
  ThrowIfNotJSReceiver(
      receiver, MessageTemplate::kIncompatibleMethodReceiver,
      'RegExp.prototype.@@search');
  const receiver = UnsafeCast<JSReceiver>(receiver);
  const string: String = ToString_Inline(string);

  if (IsFastRegExpPermissive(receiver)) {
    // TODO(pwong): Could be optimized to remove the overhead of calling the
    //              builtin (at the cost of a larger builtin).
    return RegExpSearchFast(UnsafeCast<JSRegExp>(receiver), string);
  }
  return RegExpPrototypeSearchBodySlow(receiver, string);
}
}
