Index: src/bootstrapper.cc |
diff --git a/src/bootstrapper.cc b/src/bootstrapper.cc |
index 0189e77d15427161350a4df5bc7faf036ad52d17..1edefd48784e14385354f642b7f0d57093bf8cb3 100644 |
--- a/src/bootstrapper.cc |
+++ b/src/bootstrapper.cc |
@@ -364,17 +364,6 @@ void InstallFunction(Handle<JSObject> target, Handle<JSFunction> function, |
InstallFunction(target, name, function, name_string, attributes); |
} |
-Handle<JSFunction> InstallGetter(Handle<JSObject> target, |
- Handle<Name> property_name, |
- Handle<JSFunction> getter, |
- PropertyAttributes attributes = DONT_ENUM) { |
- Handle<Object> setter = target->GetIsolate()->factory()->undefined_value(); |
- JSObject::DefineAccessor(target, property_name, getter, setter, attributes) |
- .Check(); |
- getter->shared()->set_native(true); |
- return getter; |
-} |
- |
Handle<JSFunction> CreateFunction(Isolate* isolate, Handle<String> name, |
InstanceType type, int instance_size, |
MaybeHandle<JSObject> maybe_prototype, |
@@ -460,17 +449,54 @@ Handle<JSFunction> SimpleInstallFunction(Handle<JSObject> base, |
return fun; |
} |
+void SimpleInstallGetterSetter(Handle<JSObject> base, Handle<String> name, |
+ Builtins::Name call_getter, |
+ Builtins::Name call_setter, |
+ PropertyAttributes attribs) { |
+ Isolate* const isolate = base->GetIsolate(); |
+ |
+ Handle<String> getter_name = |
+ Name::ToFunctionName(name, isolate->factory()->get_string()) |
+ .ToHandleChecked(); |
+ Handle<JSFunction> getter = |
+ SimpleCreateFunction(isolate, getter_name, call_getter, 0, false); |
+ getter->shared()->set_native(true); |
+ |
+ Handle<String> setter_name = |
+ Name::ToFunctionName(name, isolate->factory()->set_string()) |
+ .ToHandleChecked(); |
+ Handle<JSFunction> setter = |
+ SimpleCreateFunction(isolate, setter_name, call_setter, 0, false); |
+ setter->shared()->set_native(true); |
+ |
+ JSObject::DefineAccessor(base, name, getter, setter, attribs).Check(); |
+} |
+ |
Handle<JSFunction> SimpleInstallGetter(Handle<JSObject> base, |
- Handle<String> name, Builtins::Name call, |
- bool adapt) { |
+ Handle<String> name, |
+ Handle<Name> property_name, |
+ Builtins::Name call, bool adapt) { |
Isolate* const isolate = base->GetIsolate(); |
- Handle<String> fun_name = |
+ |
+ Handle<String> getter_name = |
Name::ToFunctionName(name, isolate->factory()->get_string()) |
.ToHandleChecked(); |
- Handle<JSFunction> fun = |
- SimpleCreateFunction(isolate, fun_name, call, 0, adapt); |
- InstallGetter(base, name, fun); |
- return fun; |
+ Handle<JSFunction> getter = |
+ SimpleCreateFunction(isolate, getter_name, call, 0, adapt); |
+ getter->shared()->set_native(true); |
+ |
+ Handle<Object> setter = isolate->factory()->undefined_value(); |
+ |
+ JSObject::DefineAccessor(base, property_name, getter, setter, DONT_ENUM) |
+ .Check(); |
+ |
+ return getter; |
+} |
+ |
+Handle<JSFunction> SimpleInstallGetter(Handle<JSObject> base, |
+ Handle<String> name, Builtins::Name call, |
+ bool adapt) { |
+ return SimpleInstallGetter(base, name, name, call, adapt); |
} |
Handle<JSFunction> SimpleInstallGetter(Handle<JSObject> base, |
@@ -1659,14 +1685,105 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object, |
shared->DontAdaptArguments(); |
shared->set_length(2); |
- // RegExp.prototype setup. |
- |
- // Install the "constructor" property on the {prototype}. |
- JSObject::AddProperty(prototype, factory->constructor_string(), regexp_fun, |
- DONT_ENUM); |
+ { |
+ // RegExp.prototype setup. |
+ |
+ // Install the "constructor" property on the {prototype}. |
+ JSObject::AddProperty(prototype, factory->constructor_string(), |
+ regexp_fun, DONT_ENUM); |
+ |
+ SimpleInstallFunction(prototype, "exec", Builtins::kRegExpPrototypeExec, |
+ 1, true, DONT_ENUM); |
+ |
+ SimpleInstallGetter(prototype, factory->flags_string(), |
+ Builtins::kRegExpPrototypeFlagsGetter, true); |
+ SimpleInstallGetter(prototype, factory->global_string(), |
+ Builtins::kRegExpPrototypeGlobalGetter, true); |
+ SimpleInstallGetter(prototype, factory->ignoreCase_string(), |
+ Builtins::kRegExpPrototypeIgnoreCaseGetter, true); |
+ SimpleInstallGetter(prototype, factory->multiline_string(), |
+ Builtins::kRegExpPrototypeMultilineGetter, true); |
+ SimpleInstallGetter(prototype, factory->source_string(), |
+ Builtins::kRegExpPrototypeSourceGetter, false); |
+ SimpleInstallGetter(prototype, factory->sticky_string(), |
+ Builtins::kRegExpPrototypeStickyGetter, true); |
+ SimpleInstallGetter(prototype, factory->unicode_string(), |
+ Builtins::kRegExpPrototypeUnicodeGetter, true); |
+ } |
- SimpleInstallFunction(prototype, "exec", Builtins::kRegExpPrototypeExec, 1, |
- true, DONT_ENUM); |
+ { |
+ // RegExp getters and setters. |
+ |
+ // TODO(jgruber): This should really be DONT_ENUM | DONT_DELETE. |
+ // However, that currently breaks layout test expectations. Note that |
+ // Firefox sets a couple of these as enumerable. |
+ // On the other hand, installing attributes as DONT_ENUM matches the draft |
+ // specification at |
Yang
2016/10/06 07:56:13
Good to know.
|
+ // https://github.com/claudepache/es-regexp-legacy-static-properties. |
+ const PropertyAttributes no_enum = DONT_ENUM; |
+ |
+ SimpleInstallGetter(regexp_fun, |
+ factory->InternalizeUtf8String("[Symbol.species]"), |
+ factory->species_symbol(), |
+ Builtins::kRegExpPrototypeSpeciesGetter, false); |
+ |
+ // Static properties set by a successful match. |
+ |
+ SimpleInstallGetterSetter(regexp_fun, factory->input_string(), |
+ Builtins::kRegExpInputGetter, |
+ Builtins::kRegExpInputSetter, DONT_DELETE); |
+ SimpleInstallGetterSetter( |
+ regexp_fun, factory->InternalizeUtf8String("$_"), |
+ Builtins::kRegExpInputGetter, Builtins::kRegExpInputSetter, no_enum); |
+ |
+ SimpleInstallGetterSetter( |
+ regexp_fun, factory->InternalizeUtf8String("lastMatch"), |
+ Builtins::kRegExpLastMatchGetter, Builtins::kEmptyFunction, no_enum); |
+ SimpleInstallGetterSetter( |
+ regexp_fun, factory->InternalizeUtf8String("$&"), |
+ Builtins::kRegExpLastMatchGetter, Builtins::kEmptyFunction, no_enum); |
+ |
+ SimpleInstallGetterSetter( |
+ regexp_fun, factory->InternalizeUtf8String("lastParen"), |
+ Builtins::kRegExpLastParenGetter, Builtins::kEmptyFunction, no_enum); |
+ SimpleInstallGetterSetter( |
+ regexp_fun, factory->InternalizeUtf8String("$+"), |
+ Builtins::kRegExpLastParenGetter, Builtins::kEmptyFunction, no_enum); |
+ |
+ SimpleInstallGetterSetter(regexp_fun, |
+ factory->InternalizeUtf8String("leftContext"), |
+ Builtins::kRegExpLeftContextGetter, |
+ Builtins::kEmptyFunction, no_enum); |
+ SimpleInstallGetterSetter(regexp_fun, |
+ factory->InternalizeUtf8String("$`"), |
+ Builtins::kRegExpLeftContextGetter, |
+ Builtins::kEmptyFunction, no_enum); |
+ |
+ SimpleInstallGetterSetter(regexp_fun, |
+ factory->InternalizeUtf8String("rightContext"), |
+ Builtins::kRegExpRightContextGetter, |
+ Builtins::kEmptyFunction, no_enum); |
+ SimpleInstallGetterSetter(regexp_fun, |
+ factory->InternalizeUtf8String("$'"), |
+ Builtins::kRegExpRightContextGetter, |
+ Builtins::kEmptyFunction, no_enum); |
+ |
+#define INSTALL_CAPTURE_GETTER(i) \ |
+ SimpleInstallGetterSetter(regexp_fun, \ |
+ factory->InternalizeUtf8String("$" #i), \ |
+ Builtins::kRegExpCapture##i##Getter, \ |
+ Builtins::kEmptyFunction, DONT_DELETE) |
+ INSTALL_CAPTURE_GETTER(1); |
+ INSTALL_CAPTURE_GETTER(2); |
+ INSTALL_CAPTURE_GETTER(3); |
+ INSTALL_CAPTURE_GETTER(4); |
+ INSTALL_CAPTURE_GETTER(5); |
+ INSTALL_CAPTURE_GETTER(6); |
+ INSTALL_CAPTURE_GETTER(7); |
+ INSTALL_CAPTURE_GETTER(8); |
+ INSTALL_CAPTURE_GETTER(9); |
+#undef INSTALL_CAPTURE_GETTER |
+ } |
DCHECK(regexp_fun->has_initial_map()); |
Handle<Map> initial_map(regexp_fun->initial_map()); |