Bug 559250 - encapsulate JSSLOT_{PRIMITIVE,DATE,REGEXP}_* within JSObject. r=brendan.

This commit is contained in:
Nicholas Nethercote 2010-04-14 16:18:03 -07:00
Родитель 0089afc587
Коммит e5b1652906
15 изменённых файлов: 227 добавлений и 92 удалений

Просмотреть файл

@ -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;
}

Просмотреть файл

@ -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);

Просмотреть файл

@ -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;

Просмотреть файл

@ -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);

Просмотреть файл

@ -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;

Просмотреть файл

@ -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;

Просмотреть файл

@ -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);

Просмотреть файл

@ -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;
}

Просмотреть файл

@ -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;

Просмотреть файл

@ -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)

Просмотреть файл

@ -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())) {

Просмотреть файл

@ -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<JSRegExp *>(obj->getPrivate());
clone->setPrivate(re);
js_ClearRegExpLastIndex(clone);
clone->zeroRegExpLastIndex();
HOLD_REGEXP(cx, re);
return clone;
}

Просмотреть файл

@ -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);

Просмотреть файл

@ -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,

Просмотреть файл

@ -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);