Welcome to mirror list, hosted at ThFree Co, Russian Federation.

regexp-search.tq « builtins « src « v8 « deps - github.com/nodejs/node.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 14fb9f9b03c202d1db60e28c272049615eb69764 (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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
// 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);
  }
}