зеркало из https://github.com/mozilla/gecko-dev.git
Bug 559250 - encapsulate JSSLOT_{PRIMITIVE,DATE,REGEXP}_* within JSObject. r=brendan.
This commit is contained in:
Родитель
0089afc587
Коммит
e5b1652906
|
@ -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);
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче