From e5b1652906a12646f7d29424b0350bb3d1bc3d8b Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 14 Apr 2010 16:18:03 -0700 Subject: [PATCH] Bug 559250 - encapsulate JSSLOT_{PRIMITIVE,DATE,REGEXP}_* within JSObject. r=brendan. --- js/src/jsbool.cpp | 6 ++- js/src/jsbool.h | 7 +++ js/src/jsdate.cpp | 29 +++++------- js/src/jsdate.h | 6 +++ js/src/jsinterp.cpp | 2 +- js/src/jsnum.cpp | 10 +++-- js/src/jsnum.h | 7 +++ js/src/jsobj.cpp | 4 +- js/src/jsobj.h | 53 +++++++++++++++++++++- js/src/jsobjinlines.h | 101 ++++++++++++++++++++++++++++++++++++++---- js/src/json.cpp | 4 +- js/src/jsregexp.cpp | 55 +++++++++-------------- js/src/jsregexp.h | 10 ----- js/src/jsstr.cpp | 18 ++++---- js/src/jsstr.h | 7 +++ 15 files changed, 227 insertions(+), 92 deletions(-) diff --git a/js/src/jsbool.cpp b/js/src/jsbool.cpp index 6d5a7d9a3e58..b292af2f4098 100644 --- a/js/src/jsbool.cpp +++ b/js/src/jsbool.cpp @@ -54,6 +54,8 @@ #include "jsstr.h" #include "jsvector.h" +#include "jsobjinlines.h" + /* Check pseudo-booleans values. */ JS_STATIC_ASSERT(!(JSVAL_TRUE & JSVAL_HOLE_FLAG)); JS_STATIC_ASSERT(!(JSVAL_FALSE & JSVAL_HOLE_FLAG)); @@ -139,7 +141,7 @@ Boolean(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) if (!JS_IsConstructing(cx)) *rval = bval; else - obj->fslots[JSSLOT_PRIMITIVE_THIS] = bval; + obj->setPrimitiveThis(bval); return true; } @@ -152,7 +154,7 @@ js_InitBooleanClass(JSContext *cx, JSObject *obj) NULL, boolean_methods, NULL, NULL); if (!proto) return NULL; - proto->fslots[JSSLOT_PRIMITIVE_THIS] = JSVAL_FALSE; + proto->setPrimitiveThis(JSVAL_FALSE); return proto; } diff --git a/js/src/jsbool.h b/js/src/jsbool.h index b9f64f49b8f5..4722e12433b2 100644 --- a/js/src/jsbool.h +++ b/js/src/jsbool.h @@ -44,6 +44,7 @@ */ #include "jsapi.h" +#include "jsobj.h" JS_BEGIN_EXTERN_C @@ -67,6 +68,12 @@ JS_BEGIN_EXTERN_C extern JSClass js_BooleanClass; +inline bool +JSObject::isBoolean() const +{ + return getClass() == &js_BooleanClass; +} + extern JSObject * js_InitBooleanClass(JSContext *cx, JSObject *obj); diff --git a/js/src/jsdate.cpp b/js/src/jsdate.cpp index 23379a767775..9f16c8aa40b7 100644 --- a/js/src/jsdate.cpp +++ b/js/src/jsdate.cpp @@ -492,18 +492,9 @@ msFromTime(jsdouble t) * Other Support routines and definitions */ -/* - * We use the first reseved slot to store UTC time, and the second for caching - * the local time. The initial value of the cache entry is NaN. - */ -const uint32 JSSLOT_UTC_TIME = JSSLOT_PRIVATE; -const uint32 JSSLOT_LOCAL_TIME = JSSLOT_PRIVATE + 1; - -const uint32 DATE_RESERVED_SLOTS = 2; - JSClass js_DateClass = { js_Date_str, - JSCLASS_HAS_RESERVED_SLOTS(DATE_RESERVED_SLOTS) | + JSCLASS_HAS_RESERVED_SLOTS(JSObject::DATE_FIXED_RESERVED_SLOTS) | JSCLASS_HAS_CACHED_PROTO(JSProto_Date), JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, NULL, @@ -1212,7 +1203,7 @@ GetUTCTime(JSContext *cx, JSObject *obj, jsval *vp, jsdouble *dp) { if (!JS_InstanceOf(cx, obj, &js_DateClass, vp ? vp + 2 : NULL)) return JS_FALSE; - *dp = *JSVAL_TO_DOUBLE(obj->fslots[JSSLOT_UTC_TIME]); + *dp = *JSVAL_TO_DOUBLE(obj->getDateUTCTime()); return JS_TRUE; } @@ -1221,8 +1212,8 @@ SetDateToNaN(JSContext *cx, JSObject *obj, jsval *vp = NULL) { JS_ASSERT(obj->getClass() == &js_DateClass); - obj->fslots[JSSLOT_LOCAL_TIME] = cx->runtime->NaNValue; - obj->fslots[JSSLOT_UTC_TIME] = cx->runtime->NaNValue; + obj->setDateLocalTime(cx->runtime->NaNValue); + obj->setDateUTCTime(cx->runtime->NaNValue); if (vp) *vp = cx->runtime->NaNValue; } @@ -1235,11 +1226,11 @@ SetUTCTime(JSContext *cx, JSObject *obj, jsdouble t, jsval *vp = NULL) { JS_ASSERT(obj->getClass() == &js_DateClass); - obj->fslots[JSSLOT_LOCAL_TIME] = cx->runtime->NaNValue; - if (!js_NewDoubleInRootedValue(cx, t, &obj->fslots[JSSLOT_UTC_TIME])) + obj->setDateLocalTime(cx->runtime->NaNValue); + if (!js_NewDoubleInRootedValue(cx, t, obj->addressOfDateUTCTime())) return false; if (vp) - *vp = obj->fslots[JSSLOT_UTC_TIME]; + *vp = obj->getDateUTCTime(); return true; } @@ -1253,10 +1244,10 @@ GetAndCacheLocalTime(JSContext *cx, JSObject *obj, jsval *vp, jsdouble *dp) if (!obj || !JS_InstanceOf(cx, obj, &js_DateClass, vp ? vp + 2 : NULL)) return false; - jsval *slotp = &obj->fslots[JSSLOT_LOCAL_TIME]; + jsval *slotp = obj->addressOfDateLocalTime(); jsdouble result = *JSVAL_TO_DOUBLE(*slotp); if (JSDOUBLE_IS_NaN(result)) { - result = *JSVAL_TO_DOUBLE(obj->fslots[JSSLOT_UTC_TIME]); + result = *JSVAL_TO_DOUBLE(obj->getDateUTCTime()); /* if result is NaN, it couldn't be finite. */ if (JSDOUBLE_IS_FINITE(result)) @@ -2213,7 +2204,7 @@ static jsval FASTCALL date_valueOf_tn(JSContext* cx, JSObject* obj, JSString* str) { JS_ASSERT(JS_InstanceOf(cx, obj, &js_DateClass, NULL)); - jsdouble t = *JSVAL_TO_DOUBLE(obj->fslots[JSSLOT_UTC_TIME]); + jsdouble t = *JSVAL_TO_DOUBLE(obj->getDateUTCTime()); JSString* number_str = ATOM_TO_STRING(cx->runtime->atomState.typeAtoms[JSTYPE_NUMBER]); jsval v; diff --git a/js/src/jsdate.h b/js/src/jsdate.h index 238994e2e09f..74339f72fd2f 100644 --- a/js/src/jsdate.h +++ b/js/src/jsdate.h @@ -48,6 +48,12 @@ JS_BEGIN_EXTERN_C extern JSClass js_DateClass; +inline bool +JSObject::isDate() const +{ + return getClass() == &js_DateClass; +} + extern JSObject * js_InitDateClass(JSContext *cx, JSObject *obj); diff --git a/js/src/jsinterp.cpp b/js/src/jsinterp.cpp index 2cfb8c7674d7..24d1a8376359 100644 --- a/js/src/jsinterp.cpp +++ b/js/src/jsinterp.cpp @@ -366,7 +366,7 @@ js_GetPrimitiveThis(JSContext *cx, jsval *vp, JSClass *clasp, jsval *thisvp) obj = JS_THIS_OBJECT(cx, vp); if (!JS_InstanceOf(cx, obj, clasp, vp + 2)) return JS_FALSE; - v = obj->fslots[JSSLOT_PRIMITIVE_THIS]; + v = obj->getPrimitiveThis(); } *thisvp = v; return JS_TRUE; diff --git a/js/src/jsnum.cpp b/js/src/jsnum.cpp index 60d1f359d123..4f233a329b0b 100644 --- a/js/src/jsnum.cpp +++ b/js/src/jsnum.cpp @@ -70,9 +70,11 @@ #include "jsprf.h" #include "jsscope.h" #include "jsstr.h" -#include "jsstrinlines.h" #include "jsvector.h" +#include "jsobjinlines.h" +#include "jsstrinlines.h" + using namespace js; #ifndef JS_HAVE_STDINT_H /* Native support is innocent until proven guilty. */ @@ -288,7 +290,7 @@ Number(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) if (!JS_IsConstructing(cx)) *rval = v; else - obj->fslots[JSSLOT_PRIMITIVE_THIS] = v; + obj->setPrimitiveThis(v); return true; } @@ -526,7 +528,7 @@ num_valueOf(JSContext *cx, uintN argc, jsval *vp) obj = JS_THIS_OBJECT(cx, vp); if (!JS_InstanceOf(cx, obj, &js_NumberClass, vp + 2)) return JS_FALSE; - *vp = obj->fslots[JSSLOT_PRIMITIVE_THIS]; + *vp = obj->getPrimitiveThis(); return JS_TRUE; } @@ -780,7 +782,7 @@ js_InitNumberClass(JSContext *cx, JSObject *obj) NULL, number_methods, NULL, NULL); if (!proto || !(ctor = JS_GetConstructor(cx, proto))) return NULL; - proto->fslots[JSSLOT_PRIMITIVE_THIS] = JSVAL_ZERO; + proto->setPrimitiveThis(JSVAL_ZERO); if (!JS_DefineConstDoubles(cx, ctor, number_constants)) return NULL; diff --git a/js/src/jsnum.h b/js/src/jsnum.h index 86259c796e68..1a0580679ef6 100644 --- a/js/src/jsnum.h +++ b/js/src/jsnum.h @@ -50,6 +50,7 @@ #include "jsstdint.h" #include "jsstr.h" +#include "jsobj.h" /* * JS number (IEEE double) interface. @@ -186,6 +187,12 @@ js_FinishRuntimeNumberState(JSContext *cx); /* Initialize the Number class, returning its prototype object. */ extern JSClass js_NumberClass; +inline bool +JSObject::isNumber() const +{ + return getClass() == &js_NumberClass; +} + extern "C" JSObject * js_InitNumberClass(JSContext *cx, JSObject *obj); diff --git a/js/src/jsobj.cpp b/js/src/jsobj.cpp index 759083b8843f..49b5d8e96dd9 100644 --- a/js/src/jsobj.cpp +++ b/js/src/jsobj.cpp @@ -5351,7 +5351,7 @@ js_DefaultValue(JSContext *cx, JSObject *obj, JSType hint, jsval *vp) if (FUN_FAST_NATIVE(fun) == js_str_toString) { JS_UNLOCK_SCOPE(cx, scope); - *vp = obj->fslots[JSSLOT_PRIMITIVE_THIS]; + *vp = obj->getPrimitiveThis(); return JS_TRUE; } } @@ -6091,7 +6091,7 @@ js_PrimitiveToObject(JSContext *cx, jsval *vp) obj = NewObject(cx, clasp, NULL, NULL); if (!obj) return JS_FALSE; - obj->fslots[JSSLOT_PRIMITIVE_THIS] = *vp; + obj->setPrimitiveThis(*vp); *vp = OBJECT_TO_JSVAL(obj); return JS_TRUE; } diff --git a/js/src/jsobj.h b/js/src/jsobj.h index 9a7b8d86dba5..95cf064890c9 100644 --- a/js/src/jsobj.h +++ b/js/src/jsobj.h @@ -48,6 +48,7 @@ * values, called slots. The map/slot pointer pair is GC'ed, while the map * is reference counted and the slot vector is malloc'ed. */ +#include "jsapi.h" #include "jshash.h" /* Added by JSIFY */ #include "jspubtd.h" #include "jsprvtd.h" @@ -211,8 +212,6 @@ const uint32 JSSLOT_PARENT = 1; */ const uint32 JSSLOT_PRIVATE = 2; -const uint32 JSSLOT_PRIMITIVE_THIS = JSSLOT_PRIVATE; - const uintptr_t JSSLOT_CLASS_MASK_BITS = 3; /* @@ -390,6 +389,17 @@ struct JSObject { : JSVAL_VOID; } + /* + * Primitive-specific getters and setters. + */ + + private: + static const uint32 JSSLOT_PRIMITIVE_THIS = JSSLOT_PRIVATE; + + public: + inline jsval getPrimitiveThis() const; + inline void setPrimitiveThis(jsval pthis); + /* * Array-specific getters and setters (for both dense and slow arrays). */ @@ -449,6 +459,40 @@ struct JSObject { inline jsval getArgsCallee() const; inline void setArgsCallee(jsval callee); + /* + * Date-specific getters and setters. + */ + + private: + // The second slot caches the local time; it's initialized to NaN. + static const uint32 JSSLOT_DATE_UTC_TIME = JSSLOT_PRIVATE; + static const uint32 JSSLOT_DATE_LOCAL_TIME = JSSLOT_PRIVATE + 1; + + public: + static const uint32 DATE_FIXED_RESERVED_SLOTS = 2; + + inline jsval getDateLocalTime() const; + inline jsval *addressOfDateLocalTime(); + inline void setDateLocalTime(jsval pthis); + + inline jsval getDateUTCTime() const; + inline jsval *addressOfDateUTCTime(); + inline void setDateUTCTime(jsval pthis); + + /* + * RegExp-specific getters and setters. + */ + + private: + static const uint32 JSSLOT_REGEXP_LAST_INDEX = JSSLOT_PRIVATE + 1; + + public: + static const uint32 REGEXP_FIXED_RESERVED_SLOTS = 1; + + inline jsval getRegExpLastIndex() const; + inline jsval *addressOfRegExpLastIndex(); + inline void zeroRegExpLastIndex(); + /* * Back to generic stuff. */ @@ -553,6 +597,11 @@ struct JSObject { inline bool isArray() const; inline bool isDenseArray() const; inline bool isSlowArray() const; + inline bool isNumber() const; + inline bool isBoolean() const; + inline bool isString() const; + inline bool isPrimitive() const; + inline bool isDate() const; inline bool isFunction() const; inline bool isRegExp() const; inline bool isXML() const; diff --git a/js/src/jsobjinlines.h b/js/src/jsobjinlines.h index c718b344d6d6..c5e56d53a1f9 100644 --- a/js/src/jsobjinlines.h +++ b/js/src/jsobjinlines.h @@ -41,8 +41,10 @@ #ifndef jsobjinlines_h___ #define jsobjinlines_h___ -#include "jsobj.h" +#include "jsbool.h" +#include "jsdate.h" #include "jsiter.h" +#include "jsobj.h" #include "jsscope.h" #ifdef INCLUDE_MOZILLA_DTRACE @@ -88,6 +90,26 @@ JSObject::setSlotMT(JSContext *cx, uintN slot, jsval value) #endif } +inline bool +JSObject::isPrimitive() const +{ + return isNumber() || isString() || isBoolean(); +} + +inline jsval +JSObject::getPrimitiveThis() const +{ + JS_ASSERT(isPrimitive()); + return fslots[JSSLOT_PRIMITIVE_THIS]; +} + +inline void +JSObject::setPrimitiveThis(jsval pthis) +{ + JS_ASSERT(isPrimitive()); + fslots[JSSLOT_PRIMITIVE_THIS] = pthis; +} + inline void JSObject::staticAssertArrayLengthIsInPrivateSlot() { JS_STATIC_ASSERT(JSSLOT_ARRAY_LENGTH == JSSLOT_PRIVATE); @@ -100,13 +122,6 @@ JSObject::getArrayLength() const return uint32(fslots[JSSLOT_ARRAY_LENGTH]); } -inline uint32 -JSObject::getArrayCount() const -{ - JS_ASSERT(isArray()); - return uint32(fslots[JSSLOT_ARRAY_COUNT]); -} - inline void JSObject::setArrayLength(uint32 length) { @@ -114,6 +129,13 @@ JSObject::setArrayLength(uint32 length) fslots[JSSLOT_ARRAY_LENGTH] = length; } +inline uint32 +JSObject::getArrayCount() const +{ + JS_ASSERT(isArray()); + return uint32(fslots[JSSLOT_ARRAY_COUNT]); +} + inline void JSObject::setArrayCount(uint32 count) { @@ -199,6 +221,69 @@ JSObject::setArgsCallee(jsval callee) fslots[JSSLOT_ARGS_CALLEE] = callee; } +inline jsval +JSObject::getDateLocalTime() const +{ + JS_ASSERT(isDate()); + return fslots[JSSLOT_DATE_LOCAL_TIME]; +} + +inline jsval * +JSObject::addressOfDateLocalTime() +{ + JS_ASSERT(isDate()); + return &fslots[JSSLOT_DATE_LOCAL_TIME]; +} + +inline void +JSObject::setDateLocalTime(jsval time) +{ + JS_ASSERT(isDate()); + fslots[JSSLOT_DATE_LOCAL_TIME] = time; +} + +inline jsval +JSObject::getDateUTCTime() const +{ + JS_ASSERT(isDate()); + return fslots[JSSLOT_DATE_UTC_TIME]; +} + +inline jsval * +JSObject::addressOfDateUTCTime() +{ + JS_ASSERT(isDate()); + return &fslots[JSSLOT_DATE_UTC_TIME]; +} + +inline void +JSObject::setDateUTCTime(jsval time) +{ + JS_ASSERT(isDate()); + fslots[JSSLOT_DATE_UTC_TIME] = time; +} + +inline jsval +JSObject::getRegExpLastIndex() const +{ + JS_ASSERT(isRegExp()); + return fslots[JSSLOT_REGEXP_LAST_INDEX]; +} + +inline jsval * +JSObject::addressOfRegExpLastIndex() +{ + JS_ASSERT(isRegExp()); + return &fslots[JSSLOT_REGEXP_LAST_INDEX]; +} + +inline void +JSObject::zeroRegExpLastIndex() +{ + JS_ASSERT(isRegExp()); + fslots[JSSLOT_REGEXP_LAST_INDEX] = JSVAL_ZERO; +} + inline void JSObject::initSharingEmptyScope(JSClass *clasp, JSObject *proto, JSObject *parent, jsval privateSlotValue) diff --git a/js/src/json.cpp b/js/src/json.cpp index aaeaafe36726..6a4fd5183b7a 100644 --- a/js/src/json.cpp +++ b/js/src/json.cpp @@ -455,7 +455,7 @@ Str(JSContext *cx, jsid id, JSObject *holder, StringifyContext *scx, jsval *vp, if (!JSVAL_IS_PRIMITIVE(*vp)) { JSClass *clasp = JSVAL_TO_OBJECT(*vp)->getClass(); if (clasp == &js_StringClass || clasp == &js_NumberClass) - *vp = JSVAL_TO_OBJECT(*vp)->fslots[JSSLOT_PRIMITIVE_THIS]; + *vp = JSVAL_TO_OBJECT(*vp)->getPrimitiveThis(); } if (JSVAL_IS_STRING(*vp)) { @@ -521,7 +521,7 @@ InitializeGap(JSContext *cx, jsval space, JSCharBuffer &cb) JSObject *obj = JSVAL_TO_OBJECT(space); JSClass *clasp = obj->getClass(); if (clasp == &js_NumberClass || clasp == &js_StringClass) - *gap.addr() = obj->fslots[JSSLOT_PRIMITIVE_THIS]; + *gap.addr() = obj->getPrimitiveThis(); } if (JSVAL_IS_STRING(gap.value())) { diff --git a/js/src/jsregexp.cpp b/js/src/jsregexp.cpp index 3c24aa776e38..4e09ee4517dc 100644 --- a/js/src/jsregexp.cpp +++ b/js/src/jsregexp.cpp @@ -5074,32 +5074,11 @@ out: /************************************************************************/ -static jsdouble -GetRegExpLastIndex(JSObject *obj) -{ - JS_ASSERT(obj->getClass() == &js_RegExpClass); - - jsval v = obj->fslots[JSSLOT_REGEXP_LAST_INDEX]; - if (JSVAL_IS_INT(v)) - return JSVAL_TO_INT(v); - JS_ASSERT(JSVAL_IS_DOUBLE(v)); - return *JSVAL_TO_DOUBLE(v); -} - -static jsval -GetRegExpLastIndexValue(JSObject *obj) -{ - JS_ASSERT(obj->getClass() == &js_RegExpClass); - return obj->fslots[JSSLOT_REGEXP_LAST_INDEX]; -} - static JSBool SetRegExpLastIndex(JSContext *cx, JSObject *obj, jsdouble lastIndex) { - JS_ASSERT(obj->getClass() == &js_RegExpClass); - - return JS_NewNumberValue(cx, lastIndex, - &obj->fslots[JSSLOT_REGEXP_LAST_INDEX]); + JS_ASSERT(obj->isRegExp()); + return JS_NewNumberValue(cx, lastIndex, obj->addressOfRegExpLastIndex()); } static JSBool @@ -5117,7 +5096,7 @@ regexp_getProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp) } slot = JSVAL_TO_INT(id); if (slot == REGEXP_LAST_INDEX) { - *vp = GetRegExpLastIndexValue(obj); + *vp = obj->getRegExpLastIndex(); return JS_TRUE; } @@ -5439,7 +5418,7 @@ js_XDRRegExpObject(JSXDRState *xdr, JSObject **objp) if (!re) return JS_FALSE; obj->setPrivate(re); - js_ClearRegExpLastIndex(obj); + obj->zeroRegExpLastIndex(); *objp = obj; } return JS_TRUE; @@ -5462,7 +5441,7 @@ regexp_trace(JSTracer *trc, JSObject *obj) JSClass js_RegExpClass = { js_RegExp_str, JSCLASS_HAS_PRIVATE | - JSCLASS_HAS_RESERVED_SLOTS(REGEXP_CLASS_FIXED_RESERVED_SLOTS) | + 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, @@ -5651,7 +5630,7 @@ created: JS_LOCK_OBJ(cx, obj); oldre = (JSRegExp *) obj->getPrivate(); obj->setPrivate(re); - js_ClearRegExpLastIndex(obj); + obj->zeroRegExpLastIndex(); JS_UNLOCK_OBJ(cx, obj); if (oldre) js_DestroyRegExp(cx, oldre); @@ -5691,9 +5670,17 @@ regexp_exec_sub(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, /* NB: we must reach out: after this paragraph, in order to drop re. */ HOLD_REGEXP(cx, re); sticky = (re->flags & JSREG_STICKY) != 0; - lastIndex = (re->flags & (JSREG_GLOB | JSREG_STICKY)) - ? GetRegExpLastIndex(obj) - : 0; + if (re->flags & (JSREG_GLOB | JSREG_STICKY)) { + jsval v = obj->getRegExpLastIndex(); + if (JSVAL_IS_INT(v)) { + lastIndex = JSVAL_TO_INT(v); + } else { + JS_ASSERT(JSVAL_IS_DOUBLE(v)); + lastIndex = *JSVAL_TO_DOUBLE(v); + } + } else { + lastIndex = 0; + } JS_UNLOCK_OBJ(cx, obj); /* Now that obj is unlocked, it's safe to (potentially) grab the GC lock. */ @@ -5724,7 +5711,7 @@ regexp_exec_sub(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, } if (lastIndex < 0 || str->length() < lastIndex) { - js_ClearRegExpLastIndex(obj); + obj->zeroRegExpLastIndex(); *rval = JSVAL_NULL; } else { i = (size_t) lastIndex; @@ -5732,7 +5719,7 @@ regexp_exec_sub(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, if (ok && ((re->flags & JSREG_GLOB) || (*rval != JSVAL_NULL && sticky))) { if (*rval == JSVAL_NULL) - js_ClearRegExpLastIndex(obj); + obj->zeroRegExpLastIndex(); else ok = SetRegExpLastIndex(cx, obj, i); } @@ -5850,7 +5837,7 @@ js_NewRegExpObject(JSContext *cx, TokenStream *ts, return NULL; } obj->setPrivate(re); - js_ClearRegExpLastIndex(obj); + obj->zeroRegExpLastIndex(); return obj; } @@ -5865,7 +5852,7 @@ js_CloneRegExpObject(JSContext *cx, JSObject *obj, JSObject *proto) return NULL; JSRegExp *re = static_cast(obj->getPrivate()); clone->setPrivate(re); - js_ClearRegExpLastIndex(clone); + clone->zeroRegExpLastIndex(); HOLD_REGEXP(cx, re); return clone; } diff --git a/js/src/jsregexp.h b/js/src/jsregexp.h index 902208afb7ba..c8ba7232ec91 100644 --- a/js/src/jsregexp.h +++ b/js/src/jsregexp.h @@ -195,16 +195,6 @@ js_XDRRegExpObject(JSXDRState *xdr, JSObject **objp); extern JS_FRIEND_API(JSObject *) JS_FASTCALL js_CloneRegExpObject(JSContext *cx, JSObject *obj, JSObject *proto); -const uint32 JSSLOT_REGEXP_LAST_INDEX = JSSLOT_PRIVATE + 1; -const uint32 REGEXP_CLASS_FIXED_RESERVED_SLOTS = 1; - -static inline void -js_ClearRegExpLastIndex(JSObject *obj) -{ - JS_ASSERT(obj->getClass() == &js_RegExpClass); - obj->fslots[JSSLOT_REGEXP_LAST_INDEX] = JSVAL_ZERO; -} - /* Return whether the given character array contains RegExp meta-characters. */ extern bool js_ContainsRegExpMetaChars(const jschar *chars, size_t length); diff --git a/js/src/jsstr.cpp b/js/src/jsstr.cpp index dcfdec98c499..0f8424300bc2 100644 --- a/js/src/jsstr.cpp +++ b/js/src/jsstr.cpp @@ -77,6 +77,8 @@ #include "jsbit.h" #include "jsvector.h" #include "jsversion.h" + +#include "jsobjinlines.h" #include "jsstrinlines.h" using namespace js; @@ -553,7 +555,7 @@ str_getProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp) if (id == ATOM_KEY(cx->runtime->atomState.lengthAtom)) { if (obj->getClass() == &js_StringClass) { /* Follow ECMA-262 by fetching intrinsic length of our string. */ - v = obj->fslots[JSSLOT_PRIMITIVE_THIS]; + v = obj->getPrimitiveThis(); JS_ASSERT(JSVAL_IS_STRING(v)); str = JSVAL_TO_STRING(v); } else { @@ -578,7 +580,7 @@ str_enumerate(JSContext *cx, JSObject *obj) JSString *str, *str1; size_t i, length; - v = obj->fslots[JSSLOT_PRIMITIVE_THIS]; + v = obj->getPrimitiveThis(); JS_ASSERT(JSVAL_IS_STRING(v)); str = JSVAL_TO_STRING(v); @@ -606,7 +608,7 @@ str_resolve(JSContext *cx, JSObject *obj, jsval id, uintN flags, if (!JSVAL_IS_INT(id) || (flags & JSRESOLVE_ASSIGNING)) return JS_TRUE; - v = obj->fslots[JSSLOT_PRIMITIVE_THIS]; + v = obj->getPrimitiveThis(); JS_ASSERT(JSVAL_IS_STRING(v)); str = JSVAL_TO_STRING(v); @@ -661,7 +663,7 @@ NormalizeThis(JSContext *cx, jsval *vp) if (!JSVAL_IS_PRIMITIVE(vp[1])) { JSObject *obj = JSVAL_TO_OBJECT(vp[1]); if (obj->getClass() == &js_StringClass) { - vp[1] = obj->fslots[JSSLOT_PRIMITIVE_THIS]; + vp[1] = obj->getPrimitiveThis(); return JSVAL_TO_STRING(vp[1]); } } @@ -799,7 +801,7 @@ String_p_toString(JSContext* cx, JSObject* obj) { if (!JS_InstanceOf(cx, obj, &js_StringClass, NULL)) return NULL; - jsval v = obj->fslots[JSSLOT_PRIMITIVE_THIS]; + jsval v = obj->getPrimitiveThis(); JS_ASSERT(JSVAL_IS_STRING(v)); return JSVAL_TO_STRING(v); } @@ -1537,7 +1539,7 @@ DoMatch(JSContext *cx, jsval *vp, JSString *str, const RegExpGuard &g, /* global matching ('g') */ bool testGlobal = flags & TEST_GLOBAL_BIT; if (g.reobj()) - js_ClearRegExpLastIndex(g.reobj()); + g.reobj()->zeroRegExpLastIndex(); for (size_t count = 0, i = 0, length = str->length(); i <= length; ++count) { if (!js_ExecuteRegExp(cx, g.re(), str, &i, testGlobal, vp)) return false; @@ -2956,7 +2958,7 @@ js_String(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) *rval = STRING_TO_JSVAL(str); return JS_TRUE; } - obj->fslots[JSSLOT_PRIMITIVE_THIS] = STRING_TO_JSVAL(str); + obj->setPrimitiveThis(STRING_TO_JSVAL(str)); return JS_TRUE; } @@ -3051,7 +3053,7 @@ js_InitStringClass(JSContext *cx, JSObject *obj) NULL, string_static_methods); if (!proto) return NULL; - proto->fslots[JSSLOT_PRIMITIVE_THIS] = STRING_TO_JSVAL(cx->runtime->emptyString); + proto->setPrimitiveThis(STRING_TO_JSVAL(cx->runtime->emptyString)); if (!js_DefineNativeProperty(cx, proto, ATOM_TO_JSID(cx->runtime->atomState.lengthAtom), JSVAL_VOID, NULL, NULL, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_SHARED, 0, 0, diff --git a/js/src/jsstr.h b/js/src/jsstr.h index 392e1c9f4a5a..e70678f63bf5 100644 --- a/js/src/jsstr.h +++ b/js/src/jsstr.h @@ -53,6 +53,7 @@ #include "jsprvtd.h" #include "jshashtable.h" #include "jslock.h" +#include "jsobj.h" JS_BEGIN_EXTERN_C @@ -473,6 +474,12 @@ JS_ISSPACE(jschar c) /* Initialize the String class, returning its prototype object. */ extern JSClass js_StringClass; +inline bool +JSObject::isString() const +{ + return getClass() == &js_StringClass; +} + extern JSObject * js_InitStringClass(JSContext *cx, JSObject *obj);