Commit a10b4712 authored by jgruber's avatar jgruber Committed by Commit bot

[regexp] Port remaining JS functions in regexp.js

This ports RegExpInitialize, IsRegExp, InternalMatch and InternalReplace to C++
/ TurboFan. InternalMatch is in TurboFan because it calls RegExpExecStub and
needs to construct a RegExpResult (which are, respectively, a PlatformStub and
a CodeStubAssembler function).

Except for LastMatchInfo (and GetSubstitution, which could be moved to string.js
anytime), regexp.js is now completely empty.

BUG=v8:5339

Review-Url: https://codereview.chromium.org/2409513003
Cr-Commit-Position: refs/heads/master@{#40277}
parent 34e0596a
......@@ -1865,6 +1865,17 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object,
initial_map->set_unused_property_fields(0);
initial_map->set_instance_size(initial_map->instance_size() +
num_fields * kPointerSize);
{ // Internal: RegExpInternalMatch
Handle<JSFunction> function =
factory->NewFunction(isolate->factory()->empty_string(),
isolate->builtins()->RegExpInternalMatch(),
JS_OBJECT_TYPE, JSObject::kHeaderSize);
function->shared()->set_internal_formal_parameter_count(2);
function->shared()->set_length(2);
function->shared()->set_native(true);
isolate->native_context()->set(Context::REGEXP_INTERNAL_MATCH, *function);
}
}
{ // -- E r r o r
......
......@@ -1655,5 +1655,63 @@ void Builtins::Generate_RegExpPrototypeReplace(CodeStubAssembler* a) {
}
}
namespace {
// TODO(jgruber): Replace this with a FixedArray.
compiler::Node* GetInternalMatchInfo(CodeStubAssembler* a,
compiler::Node* context) {
typedef compiler::Node Node;
const ElementsKind elements_kind = FAST_ELEMENTS;
Node* const native_context = a->LoadNativeContext(context);
Node* const array_map =
a->LoadJSArrayElementsMap(elements_kind, native_context);
Node* const capacity = a->IntPtrConstant(RegExpImpl::kLastMatchOverhead + 2);
Node* const allocation_site = nullptr;
Node* const smi_zero = a->SmiConstant(Smi::kZero);
return a->AllocateJSArray(elements_kind, array_map, capacity, smi_zero,
allocation_site,
CodeStubAssembler::INTPTR_PARAMETERS);
}
} // namespace
// Simple string matching functionality for internal use which does not modify
// the last match info.
void Builtins::Generate_RegExpInternalMatch(CodeStubAssembler* a) {
typedef CodeStubAssembler::Label Label;
typedef compiler::Node Node;
Isolate* const isolate = a->isolate();
Node* const regexp = a->Parameter(1);
Node* const string = a->Parameter(2);
Node* const context = a->Parameter(5);
Node* const null = a->NullConstant();
Node* const smi_zero = a->SmiConstant(Smi::FromInt(0));
Node* const internal_match_info = GetInternalMatchInfo(a, context);
Callable exec_callable = CodeFactory::RegExpExec(isolate);
Node* const match_indices = a->CallStub(
exec_callable, context, regexp, string, smi_zero, internal_match_info);
Label if_matched(a), if_didnotmatch(a);
a->Branch(a->WordEqual(match_indices, null), &if_didnotmatch, &if_matched);
a->Bind(&if_didnotmatch);
a->Return(null);
a->Bind(&if_matched);
{
Node* const match_elements = a->LoadElements(match_indices);
Node* result = ConstructNewResultFromMatchInfo(isolate, a, context,
match_elements, string);
a->Return(result);
}
}
} // namespace internal
} // namespace v8
......@@ -575,6 +575,7 @@ namespace internal {
CPP(RegExpCapture8Getter) \
CPP(RegExpCapture9Getter) \
CPP(RegExpConstructor) \
TFJ(RegExpInternalMatch, 3) \
CPP(RegExpInputGetter) \
CPP(RegExpInputSetter) \
CPP(RegExpLastMatchGetter) \
......
......@@ -51,6 +51,7 @@ enum ContextLookupFlags {
V(OBJECT_IS_FROZEN, JSFunction, object_is_frozen) \
V(OBJECT_IS_SEALED, JSFunction, object_is_sealed) \
V(OBJECT_KEYS, JSFunction, object_keys) \
V(REGEXP_INTERNAL_MATCH, JSFunction, regexp_internal_match) \
V(REFLECT_APPLY_INDEX, JSFunction, reflect_apply) \
V(REFLECT_CONSTRUCT_INDEX, JSFunction, reflect_construct) \
V(REFLECT_DEFINE_PROPERTY_INDEX, JSFunction, reflect_define_property) \
......
......@@ -26,8 +26,6 @@ var GlobalString = global.String;
var InstallFunctions = utils.InstallFunctions;
var InstallGetter = utils.InstallGetter;
var InternalArray = utils.InternalArray;
var InternalRegExpMatch;
var InternalRegExpReplace
var ObjectHasOwnProperty = utils.ImportNow("ObjectHasOwnProperty");
var OverrideFunction = utils.OverrideFunction;
var patternSymbol = utils.ImportNow("intl_pattern_symbol");
......@@ -39,8 +37,6 @@ var StringSubstring = GlobalString.prototype.substring;
utils.Import(function(from) {
ArrayJoin = from.ArrayJoin;
ArrayPush = from.ArrayPush;
InternalRegExpMatch = from.InternalRegExpMatch;
InternalRegExpReplace = from.InternalRegExpReplace;
});
// Utilities for definitions
......@@ -249,7 +245,7 @@ function GetTimezoneNameLocationPartRE() {
* Parameter locales is treated as a priority list.
*/
function supportedLocalesOf(service, locales, options) {
if (IS_NULL(InternalRegExpMatch(GetServiceRE(), service))) {
if (IS_NULL(%regexp_internal_match(GetServiceRE(), service))) {
throw %make_error(kWrongServiceType, service);
}
......@@ -297,7 +293,7 @@ function lookupSupportedLocalesOf(requestedLocales, availableLocales) {
var matchedLocales = new InternalArray();
for (var i = 0; i < requestedLocales.length; ++i) {
// Remove -u- extension.
var locale = InternalRegExpReplace(
var locale = %RegExpInternalReplace(
GetUnicodeExtensionRE(), requestedLocales[i], '');
do {
if (!IS_UNDEFINED(availableLocales[locale])) {
......@@ -407,7 +403,7 @@ function resolveLocale(service, requestedLocales, options) {
* lookup algorithm.
*/
function lookupMatcher(service, requestedLocales) {
if (IS_NULL(InternalRegExpMatch(GetServiceRE(), service))) {
if (IS_NULL(%regexp_internal_match(GetServiceRE(), service))) {
throw %make_error(kWrongServiceType, service);
}
......@@ -418,12 +414,12 @@ function lookupMatcher(service, requestedLocales) {
for (var i = 0; i < requestedLocales.length; ++i) {
// Remove all extensions.
var locale = InternalRegExpReplace(
var locale = %RegExpInternalReplace(
GetAnyExtensionRE(), requestedLocales[i], '');
do {
if (!IS_UNDEFINED(AVAILABLE_LOCALES[service][locale])) {
// Return the resolved locale and extension.
var extensionMatch = InternalRegExpMatch(
var extensionMatch = %regexp_internal_match(
GetUnicodeExtensionRE(), requestedLocales[i]);
var extension = IS_NULL(extensionMatch) ? '' : extensionMatch[0];
return {'locale': locale, 'extension': extension, 'position': i};
......@@ -621,7 +617,7 @@ function getOptimalLanguageTag(original, resolved) {
// Preserve extensions of resolved locale, but swap base tags with original.
var resolvedBase = new GlobalRegExp('^' + locales[1].base, 'g');
return InternalRegExpReplace(resolvedBase, resolved, locales[0].base);
return %RegExpInternalReplace(resolvedBase, resolved, locales[0].base);
}
......@@ -636,7 +632,7 @@ function getAvailableLocalesOf(service) {
for (var i in available) {
if (HAS_OWN_PROPERTY(available, i)) {
var parts = InternalRegExpMatch(
var parts = %regexp_internal_match(
/^([a-z]{2,3})-([A-Z][a-z]{3})-([A-Z]{2})$/, i);
if (!IS_NULL(parts)) {
// Build xx-ZZ. We don't care about the actual value,
......@@ -708,7 +704,7 @@ function toTitleCaseWord(word) {
* 'of', 'au' and 'es' are special-cased and lowercased.
*/
function toTitleCaseTimezoneLocation(location) {
var match = InternalRegExpMatch(GetTimezoneNameLocationPartRE(), location)
var match = %regexp_internal_match(GetTimezoneNameLocationPartRE(), location)
if (IS_NULL(match)) throw %make_range_error(kExpectedLocation, location);
var result = toTitleCaseWord(match[1]);
......@@ -743,7 +739,7 @@ function canonicalizeLanguageTag(localeID) {
// Optimize for the most common case; a language code alone in
// the canonical form/lowercase (e.g. "en", "fil").
if (IS_STRING(localeID) &&
!IS_NULL(InternalRegExpMatch(/^[a-z]{2,3}$/, localeID))) {
!IS_NULL(%regexp_internal_match(/^[a-z]{2,3}$/, localeID))) {
return localeID;
}
......@@ -821,7 +817,7 @@ function initializeLocaleList(locales) {
*/
function isStructuallyValidLanguageTag(locale) {
// Check if it's well-formed, including grandfadered tags.
if (IS_NULL(InternalRegExpMatch(GetLanguageTagRE(), locale))) {
if (IS_NULL(%regexp_internal_match(GetLanguageTagRE(), locale))) {
return false;
}
......@@ -843,7 +839,7 @@ function isStructuallyValidLanguageTag(locale) {
var parts = %StringSplit(locale, '-', kMaxUint32);
for (var i = 1; i < parts.length; i++) {
var value = parts[i];
if (!IS_NULL(InternalRegExpMatch(GetLanguageVariantRE(), value)) &&
if (!IS_NULL(%regexp_internal_match(GetLanguageVariantRE(), value)) &&
extensions.length === 0) {
if (%ArrayIndexOf(variants, value, 0) === -1) {
%_Call(ArrayPush, variants, value);
......@@ -852,7 +848,7 @@ function isStructuallyValidLanguageTag(locale) {
}
}
if (!IS_NULL(InternalRegExpMatch(GetLanguageSingletonRE(), value))) {
if (!IS_NULL(%regexp_internal_match(GetLanguageSingletonRE(), value))) {
if (%ArrayIndexOf(extensions, value, 0) === -1) {
%_Call(ArrayPush, extensions, value);
} else {
......@@ -1121,7 +1117,7 @@ AddBoundMethod(Intl.Collator, 'compare', compare, 2, 'collator');
*/
function isWellFormedCurrencyCode(currency) {
return typeof currency == "string" && currency.length == 3 &&
IS_NULL(InternalRegExpMatch(/[^A-Za-z]/, currency));
IS_NULL(%regexp_internal_match(/[^A-Za-z]/, currency));
}
......@@ -1439,57 +1435,57 @@ function appendToLDMLString(option, pairs) {
*/
function fromLDMLString(ldmlString) {
// First remove '' quoted text, so we lose 'Uhr' strings.
ldmlString = InternalRegExpReplace(GetQuotedStringRE(), ldmlString, '');
ldmlString = %RegExpInternalReplace(GetQuotedStringRE(), ldmlString, '');
var options = {};
var match = InternalRegExpMatch(/E{3,5}/, ldmlString);
var match = %regexp_internal_match(/E{3,5}/, ldmlString);
options = appendToDateTimeObject(
options, 'weekday', match, {EEEEE: 'narrow', EEE: 'short', EEEE: 'long'});
match = InternalRegExpMatch(/G{3,5}/, ldmlString);
match = %regexp_internal_match(/G{3,5}/, ldmlString);
options = appendToDateTimeObject(
options, 'era', match, {GGGGG: 'narrow', GGG: 'short', GGGG: 'long'});
match = InternalRegExpMatch(/y{1,2}/, ldmlString);
match = %regexp_internal_match(/y{1,2}/, ldmlString);
options = appendToDateTimeObject(
options, 'year', match, {y: 'numeric', yy: '2-digit'});
match = InternalRegExpMatch(/M{1,5}/, ldmlString);
match = %regexp_internal_match(/M{1,5}/, ldmlString);
options = appendToDateTimeObject(options, 'month', match, {MM: '2-digit',
M: 'numeric', MMMMM: 'narrow', MMM: 'short', MMMM: 'long'});
// Sometimes we get L instead of M for month - standalone name.
match = InternalRegExpMatch(/L{1,5}/, ldmlString);
match = %regexp_internal_match(/L{1,5}/, ldmlString);
options = appendToDateTimeObject(options, 'month', match, {LL: '2-digit',
L: 'numeric', LLLLL: 'narrow', LLL: 'short', LLLL: 'long'});
match = InternalRegExpMatch(/d{1,2}/, ldmlString);
match = %regexp_internal_match(/d{1,2}/, ldmlString);
options = appendToDateTimeObject(
options, 'day', match, {d: 'numeric', dd: '2-digit'});
match = InternalRegExpMatch(/h{1,2}/, ldmlString);
match = %regexp_internal_match(/h{1,2}/, ldmlString);
if (match !== null) {
options['hour12'] = true;
}
options = appendToDateTimeObject(
options, 'hour', match, {h: 'numeric', hh: '2-digit'});
match = InternalRegExpMatch(/H{1,2}/, ldmlString);
match = %regexp_internal_match(/H{1,2}/, ldmlString);
if (match !== null) {
options['hour12'] = false;
}
options = appendToDateTimeObject(
options, 'hour', match, {H: 'numeric', HH: '2-digit'});
match = InternalRegExpMatch(/m{1,2}/, ldmlString);
match = %regexp_internal_match(/m{1,2}/, ldmlString);
options = appendToDateTimeObject(
options, 'minute', match, {m: 'numeric', mm: '2-digit'});
match = InternalRegExpMatch(/s{1,2}/, ldmlString);
match = %regexp_internal_match(/s{1,2}/, ldmlString);
options = appendToDateTimeObject(
options, 'second', match, {s: 'numeric', ss: '2-digit'});
match = InternalRegExpMatch(/z|zzzz/, ldmlString);
match = %regexp_internal_match(/z|zzzz/, ldmlString);
options = appendToDateTimeObject(
options, 'timeZoneName', match, {z: 'short', zzzz: 'long'});
......@@ -1818,7 +1814,7 @@ function canonicalizeTimeZoneID(tzID) {
// We expect only _, '-' and / beside ASCII letters.
// All inputs should conform to Area/Location(/Location)* from now on.
var match = InternalRegExpMatch(GetTimezoneNameCheckRE(), tzID);
var match = %regexp_internal_match(GetTimezoneNameCheckRE(), tzID);
if (IS_NULL(match)) throw %make_range_error(kExpectedTimezoneID, tzID);
var result = toTitleCaseTimezoneLocation(match[1]) + '/' +
......
......@@ -8,14 +8,6 @@
%CheckIsBootstrapping();
// -------------------------------------------------------------------
// Imports
var GlobalRegExp = global.RegExp;
var GlobalRegExpPrototype = GlobalRegExp.prototype;
var RegExpExecJS = GlobalRegExp.prototype.exec;
var matchSymbol = utils.ImportNow("match_symbol");
// -------------------------------------------------------------------
// Property of the builtins object for recording the result of the last
......@@ -34,52 +26,6 @@ var RegExpLastMatchInfo = {
CAPTURE1: 0
};
// -------------------------------------------------------------------
// ES#sec-isregexp IsRegExp ( argument )
function IsRegExp(o) {
if (!IS_RECEIVER(o)) return false;
var is_regexp = o[matchSymbol];
if (!IS_UNDEFINED(is_regexp)) return TO_BOOLEAN(is_regexp);
return IS_REGEXP(o);
}
// ES#sec-regexpinitialize
// Runtime Semantics: RegExpInitialize ( obj, pattern, flags )
function RegExpInitialize(object, pattern, flags) {
pattern = IS_UNDEFINED(pattern) ? '' : TO_STRING(pattern);
flags = IS_UNDEFINED(flags) ? '' : TO_STRING(flags);
%RegExpInitializeAndCompile(object, pattern, flags);
return object;
}
// This is kind of performance sensitive, so we want to avoid unnecessary
// type checks on inputs. But we also don't want to inline it several times
// manually, so we use a macro :-)
macro RETURN_NEW_RESULT_FROM_MATCH_INFO(MATCHINFO, STRING)
var numResults = NUMBER_OF_CAPTURES(MATCHINFO) >> 1;
var start = MATCHINFO[CAPTURE0];
var end = MATCHINFO[CAPTURE1];
// Calculate the substring of the first match before creating the result array
// to avoid an unnecessary write barrier storing the first result.
var first = %_SubString(STRING, start, end);
var result = %_RegExpConstructResult(numResults, start, STRING);
result[0] = first;
if (numResults == 1) return result;
var j = REGEXP_FIRST_CAPTURE + 2;
for (var i = 1; i < numResults; i++) {
start = MATCHINFO[j++];
if (start != -1) {
end = MATCHINFO[j];
result[i] = %_SubString(STRING, start, end);
}
j++;
}
return result;
endmacro
// ES#sec-getsubstitution
// GetSubstitution(matched, str, position, captures, replacement)
// Expand the $-expressions in the string and return a new string with
......@@ -169,40 +115,11 @@ function GetSubstitution(matched, string, position, captures, replacement) {
%InstallToContext(["regexp_last_match_info", RegExpLastMatchInfo]);
// -------------------------------------------------------------------
// Internal
var InternalRegExpMatchInfo = {
REGEXP_NUMBER_OF_CAPTURES: 2,
REGEXP_LAST_SUBJECT: "",
REGEXP_LAST_INPUT: UNDEFINED,
CAPTURE0: 0,
CAPTURE1: 0
};
function InternalRegExpMatch(regexp, subject) {
var matchInfo = %_RegExpExec(regexp, subject, 0, InternalRegExpMatchInfo);
if (!IS_NULL(matchInfo)) {
RETURN_NEW_RESULT_FROM_MATCH_INFO(matchInfo, subject);
}
return null;
}
function InternalRegExpReplace(regexp, subject, replacement) {
return %StringReplaceGlobalRegExpWithString(
subject, regexp, replacement, InternalRegExpMatchInfo);
}
// -------------------------------------------------------------------
// Exports
utils.Export(function(to) {
to.GetSubstitution = GetSubstitution;
to.InternalRegExpMatch = InternalRegExpMatch;
to.InternalRegExpReplace = InternalRegExpReplace;
to.IsRegExp = IsRegExp;
to.RegExpInitialize = RegExpInitialize;
to.RegExpLastMatchInfo = RegExpLastMatchInfo;
});
})
......@@ -13,10 +13,8 @@ var ArrayJoin;
var GetSubstitution;
var GlobalRegExp = global.RegExp;
var GlobalString = global.String;
var IsRegExp;
var MaxSimple;
var MinSimple;
var RegExpInitialize;
var matchSymbol = utils.ImportNow("match_symbol");
var replaceSymbol = utils.ImportNow("replace_symbol");
var searchSymbol = utils.ImportNow("search_symbol");
......@@ -25,10 +23,8 @@ var splitSymbol = utils.ImportNow("split_symbol");
utils.Import(function(from) {
ArrayJoin = from.ArrayJoin;
GetSubstitution = from.GetSubstitution;
IsRegExp = from.IsRegExp;
MaxSimple = from.MaxSimple;
MinSimple = from.MinSimple;
RegExpInitialize = from.RegExpInitialize;
});
//-------------------------------------------------------------------
......@@ -60,8 +56,7 @@ function StringMatchJS(pattern) {
var subject = TO_STRING(this);
// Equivalent to RegExpCreate (ES#sec-regexpcreate)
var regexp = %_NewObject(GlobalRegExp, GlobalRegExp);
RegExpInitialize(regexp, pattern);
var regexp = %RegExpCreate(pattern);
return regexp[matchSymbol](subject);
}
......@@ -143,8 +138,7 @@ function StringSearch(pattern) {
var subject = TO_STRING(this);
// Equivalent to RegExpCreate (ES#sec-regexpcreate)
var regexp = %_NewObject(GlobalRegExp, GlobalRegExp);
RegExpInitialize(regexp, pattern);
var regexp = %RegExpCreate(pattern);
return %_Call(regexp[searchSymbol], regexp, subject);
}
......
......@@ -656,16 +656,11 @@ MUST_USE_RESULT static Object* StringReplaceGlobalRegExpWithEmptyString(
return *answer;
}
namespace {
RUNTIME_FUNCTION(Runtime_StringReplaceGlobalRegExpWithString) {
HandleScope scope(isolate);
DCHECK(args.length() == 4);
CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
CONVERT_ARG_HANDLE_CHECKED(String, replacement, 2);
CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 1);
CONVERT_ARG_HANDLE_CHECKED(JSObject, last_match_info, 3);
Object* StringReplaceGlobalRegExpWithStringHelper(
Isolate* isolate, Handle<JSRegExp> regexp, Handle<String> subject,
Handle<String> replacement, Handle<JSObject> last_match_info) {
CHECK(regexp->GetFlags() & JSRegExp::kGlobal);
CHECK(last_match_info->HasFastObjectElements());
......@@ -687,6 +682,20 @@ RUNTIME_FUNCTION(Runtime_StringReplaceGlobalRegExpWithString) {
replacement, last_match_info);
}
} // namespace
RUNTIME_FUNCTION(Runtime_StringReplaceGlobalRegExpWithString) {
HandleScope scope(isolate);
DCHECK(args.length() == 4);
CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
CONVERT_ARG_HANDLE_CHECKED(String, replacement, 2);
CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 1);
CONVERT_ARG_HANDLE_CHECKED(JSObject, last_match_info, 3);
return StringReplaceGlobalRegExpWithStringHelper(
isolate, regexp, subject, replacement, last_match_info);
}
RUNTIME_FUNCTION(Runtime_StringSplit) {
HandleScope handle_scope(isolate);
......@@ -769,6 +778,32 @@ RUNTIME_FUNCTION(Runtime_StringSplit) {
return *result;
}
// ES##sec-regexpcreate
// RegExpCreate ( P, F )
RUNTIME_FUNCTION(Runtime_RegExpCreate) {
HandleScope scope(isolate);
DCHECK(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(Object, source_object, 0);
Handle<String> source;
if (source_object->IsUndefined(isolate)) {
source = isolate->factory()->empty_string();
} else {
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
isolate, source, Object::ToString(isolate, source_object));
}
Handle<Map> map(isolate->regexp_function()->initial_map());
Handle<JSRegExp> regexp =
Handle<JSRegExp>::cast(isolate->factory()->NewJSObjectFromMap(map));
JSRegExp::Flags flags = JSRegExp::kNone;
RETURN_FAILURE_ON_EXCEPTION(isolate,
JSRegExp::Initialize(regexp, source, flags));
return *regexp;
}
RUNTIME_FUNCTION(Runtime_RegExpExec) {
HandleScope scope(isolate);
......@@ -835,6 +870,22 @@ RUNTIME_FUNCTION(Runtime_RegExpInitializeAndCompile) {
return *regexp;
}
RUNTIME_FUNCTION(Runtime_RegExpInternalReplace) {
HandleScope scope(isolate);
DCHECK(args.length() == 3);
CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 0);
CONVERT_ARG_HANDLE_CHECKED(String, subject, 1);
CONVERT_ARG_HANDLE_CHECKED(String, replacement, 2);
static const int kInitialMatchSlots = 2;
Handle<JSArray> internal_match_info = isolate->factory()->NewJSArray(
FAST_ELEMENTS, 0, RegExpImpl::kLastMatchOverhead + kInitialMatchSlots,
INITIALIZE_ARRAY_ELEMENTS_WITH_HOLE);
return StringReplaceGlobalRegExpWithStringHelper(
isolate, regexp, subject, replacement, internal_match_info);
}
namespace {
class MatchInfoBackedMatch : public String::Match {
......
......@@ -459,12 +459,14 @@ namespace internal {
#define FOR_EACH_INTRINSIC_REGEXP(F) \
F(StringReplaceGlobalRegExpWithString, 4, 1) \
F(StringSplit, 3, 1) \
F(RegExpCreate, 1, 1) \
F(RegExpExec, 4, 1) \
F(RegExpFlags, 1, 1) \
F(RegExpReplace, 3, 1) \
F(RegExpSource, 1, 1) \
F(RegExpConstructResult, 3, 1) \
F(RegExpInitializeAndCompile, 3, 1) \
F(RegExpInternalReplace, 3, 1) \
F(RegExpExecReThrow, 4, 1) \
F(IsRegExp, 1, 1)
......
......@@ -78,7 +78,7 @@ bytecodes: [
/* 15 S> */ B(LdrUndefined), R(0),
B(CreateArrayLiteral), U8(0), U8(0), U8(9),
B(Star), R(1),
B(CallJSRuntime), U8(147), R(0), U8(2),
B(CallJSRuntime), U8(148), R(0), U8(2),
/* 44 S> */ B(Return),
]
constant pool: [
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment