diff --git a/js/src/jsatom.cpp b/js/src/jsatom.cpp index d3b584bcbc40..1f6aa082ffd6 100644 --- a/js/src/jsatom.cpp +++ b/js/src/jsatom.cpp @@ -138,18 +138,24 @@ const char *const js_common_atom_names[] = { js_eval_str, /* evalAtom */ js_fileName_str, /* fileNameAtom */ js_get_str, /* getAtom */ + js_global_str, /* globalAtom */ + js_ignoreCase_str, /* ignoreCaseAtom */ js_index_str, /* indexAtom */ js_input_str, /* inputAtom */ js_iterator_str, /* iteratorAtom */ + js_lastIndex_str, /* lastIndexAtom */ js_length_str, /* lengthAtom */ js_lineNumber_str, /* lineNumberAtom */ js_message_str, /* messageAtom */ + js_multiline_str, /* multilineAtom */ js_name_str, /* nameAtom */ js_next_str, /* nextAtom */ js_noSuchMethod_str, /* noSuchMethodAtom */ js_proto_str, /* protoAtom */ js_set_str, /* setAtom */ + js_source_str, /* sourceAtom */ js_stack_str, /* stackAtom */ + js_sticky_str, /* stickyAtom */ js_toLocaleString_str, /* toLocaleStringAtom */ js_toSource_str, /* toSourceAtom */ js_toString_str, /* toStringAtom */ @@ -224,12 +230,16 @@ const char js_eval_str[] = "eval"; const char js_fileName_str[] = "fileName"; const char js_get_str[] = "get"; const char js_getter_str[] = "getter"; +const char js_global_str[] = "global"; +const char js_ignoreCase_str[] = "ignoreCase"; const char js_index_str[] = "index"; const char js_input_str[] = "input"; const char js_iterator_str[] = "__iterator__"; +const char js_lastIndex_str[] = "lastIndex"; const char js_length_str[] = "length"; const char js_lineNumber_str[] = "lineNumber"; const char js_message_str[] = "message"; +const char js_multiline_str[] = "multiline"; const char js_name_str[] = "name"; const char js_next_str[] = "next"; const char js_noSuchMethod_str[] = "__noSuchMethod__"; @@ -237,7 +247,9 @@ const char js_object_str[] = "object"; const char js_proto_str[] = "__proto__"; const char js_setter_str[] = "setter"; const char js_set_str[] = "set"; +const char js_source_str[] = "source"; const char js_stack_str[] = "stack"; +const char js_sticky_str[] = "sticky"; const char js_toSource_str[] = "toSource"; const char js_toString_str[] = "toString"; const char js_toLocaleString_str[] = "toLocaleString"; diff --git a/js/src/jsatom.h b/js/src/jsatom.h index 05b820b945df..efa1519e20f2 100644 --- a/js/src/jsatom.h +++ b/js/src/jsatom.h @@ -250,18 +250,24 @@ struct JSAtomState { JSAtom *evalAtom; JSAtom *fileNameAtom; JSAtom *getAtom; + JSAtom *globalAtom; + JSAtom *ignoreCaseAtom; JSAtom *indexAtom; JSAtom *inputAtom; JSAtom *iteratorAtom; + JSAtom *lastIndexAtom; JSAtom *lengthAtom; JSAtom *lineNumberAtom; JSAtom *messageAtom; + JSAtom *multilineAtom; JSAtom *nameAtom; JSAtom *nextAtom; JSAtom *noSuchMethodAtom; JSAtom *protoAtom; JSAtom *setAtom; + JSAtom *sourceAtom; JSAtom *stackAtom; + JSAtom *stickyAtom; JSAtom *toLocaleStringAtom; JSAtom *toSourceAtom; JSAtom *toStringAtom; @@ -393,12 +399,16 @@ extern const char js_eval_str[]; extern const char js_fileName_str[]; extern const char js_get_str[]; extern const char js_getter_str[]; +extern const char js_global_str[]; +extern const char js_ignoreCase_str[]; extern const char js_index_str[]; extern const char js_input_str[]; extern const char js_iterator_str[]; +extern const char js_lastIndex_str[]; extern const char js_length_str[]; extern const char js_lineNumber_str[]; extern const char js_message_str[]; +extern const char js_multiline_str[]; extern const char js_name_str[]; extern const char js_namespace_str[]; extern const char js_next_str[]; @@ -410,8 +420,10 @@ extern const char js_qualifier_str[]; extern const char js_send_str[]; extern const char js_setter_str[]; extern const char js_set_str[]; +extern const char js_source_str[]; extern const char js_space_str[]; extern const char js_stack_str[]; +extern const char js_sticky_str[]; extern const char js_stago_str[]; extern const char js_star_str[]; extern const char js_starQualifier_str[]; diff --git a/js/src/jsregexp.cpp b/js/src/jsregexp.cpp index 406d51042c40..d13492eda6d9 100644 --- a/js/src/jsregexp.cpp +++ b/js/src/jsregexp.cpp @@ -5128,19 +5128,53 @@ lastIndex_setter(JSContext *cx, JSObject *obj, jsval id, jsval *vp) return SetRegExpLastIndex(cx, obj, lastIndex); } -#define REGEXP_PROP_ATTRS (JSPROP_PERMANENT | JSPROP_SHARED) -#define RO_REGEXP_PROP_ATTRS (REGEXP_PROP_ATTRS | JSPROP_READONLY) +static JSBool +regexp_resolve(JSContext *cx, JSObject *obj, jsid id, uintN flags, JSObject **objp) +{ + JS_ASSERT(obj->isRegExp()); -static JSPropertySpec regexp_props[] = { - {"source", 0, RO_REGEXP_PROP_ATTRS, source_getter, NULL}, - {"global", 0, RO_REGEXP_PROP_ATTRS, global_getter, NULL}, - {"ignoreCase", 0, RO_REGEXP_PROP_ATTRS, ignoreCase_getter, NULL}, - {"lastIndex", 0, REGEXP_PROP_ATTRS, lastIndex_getter, - lastIndex_setter}, - {"multiline", 0, RO_REGEXP_PROP_ATTRS, multiline_getter, NULL}, - {"sticky", 0, RO_REGEXP_PROP_ATTRS, sticky_getter, NULL}, - {0,0,0,0,0} -}; + if (!JSID_IS_ATOM(id)) + return JS_TRUE; + + if (id == ATOM_TO_JSID(cx->runtime->atomState.lastIndexAtom)) { + if (!js_DefineNativeProperty(cx, obj, id, JSVAL_VOID, + lastIndex_getter, lastIndex_setter, + JSPROP_PERMANENT | JSPROP_SHARED, 0, 0, NULL)) { + return JS_FALSE; + } + *objp = obj; + return JS_TRUE; + } + + static const struct LazyProp { + const char *name; + uint16 atomOffset; + JSPropertyOp getter; + } props[] = { + { js_source_str, ATOM_OFFSET(source), source_getter }, + { js_global_str, ATOM_OFFSET(global), global_getter }, + { js_ignoreCase_str, ATOM_OFFSET(ignoreCase), ignoreCase_getter }, + { js_multiline_str, ATOM_OFFSET(multiline), multiline_getter }, + { js_sticky_str, ATOM_OFFSET(sticky), sticky_getter } + }; + + for (size_t i = 0; i < JS_ARRAY_LENGTH(props); i++) { + const LazyProp &lazy = props[i]; + JSAtom *atom = OFFSET_TO_ATOM(cx->runtime, lazy.atomOffset); + if (id == ATOM_TO_JSID(atom)) { + if (!js_DefineNativeProperty(cx, obj, id, JSVAL_VOID, + lazy.getter, NULL, + JSPROP_PERMANENT | JSPROP_SHARED | JSPROP_READONLY, + 0, 0, NULL)) { + return JS_FALSE; + } + *objp = obj; + return JS_TRUE; + } + } + + return JS_TRUE; +} /* * RegExp class static properties and their Perl counterparts: @@ -5266,12 +5300,11 @@ DEFINE_STATIC_SETTER(static_multiline_setter, return false; res->multiline = JSVAL_TO_BOOLEAN(*vp)) -#define REGEXP_STATIC_PROP_ATTRS (REGEXP_PROP_ATTRS | JSPROP_ENUMERATE) -#define RO_REGEXP_STATIC_PROP_ATTRS (REGEXP_STATIC_PROP_ATTRS | JSPROP_READONLY) +const uint8 REGEXP_STATIC_PROP_ATTRS = JSPROP_PERMANENT | JSPROP_SHARED | JSPROP_ENUMERATE; +const uint8 RO_REGEXP_STATIC_PROP_ATTRS = REGEXP_STATIC_PROP_ATTRS | JSPROP_READONLY; static JSPropertySpec regexp_static_props[] = { - {"input", 0, REGEXP_STATIC_PROP_ATTRS, static_input_getter, - static_input_setter}, + {"input", 0, REGEXP_STATIC_PROP_ATTRS, static_input_getter, static_input_setter}, {"multiline", 0, REGEXP_STATIC_PROP_ATTRS, static_multiline_getter, static_multiline_setter}, {"lastMatch", 0, RO_REGEXP_STATIC_PROP_ATTRS, static_lastMatch_getter, NULL}, @@ -5366,12 +5399,12 @@ regexp_trace(JSTracer *trc, JSObject *obj) JSClass js_RegExpClass = { js_RegExp_str, - JSCLASS_HAS_PRIVATE | + JSCLASS_HAS_PRIVATE | JSCLASS_NEW_RESOLVE | JSCLASS_HAS_RESERVED_SLOTS(JSObject::REGEXP_FIXED_RESERVED_SLOTS) | JSCLASS_MARK_IS_TRACE | JSCLASS_HAS_CACHED_PROTO(JSProto_RegExp), JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, - JS_EnumerateStub, JS_ResolveStub, + JS_EnumerateStub, reinterpret_cast(regexp_resolve), JS_ConvertStub, regexp_finalize, NULL, NULL, regexp_call, NULL, @@ -5718,8 +5751,7 @@ JSObject * js_InitRegExpClass(JSContext *cx, JSObject *obj) { JSObject *proto = js_InitClass(cx, obj, NULL, &js_RegExpClass, RegExp, 1, - regexp_props, regexp_methods, - regexp_static_props, NULL); + NULL, regexp_methods, regexp_static_props, NULL); if (!proto) return NULL;