Backout bug 684110 (08b6eaf6aad0, cf8b35fa1010, 25ee45edabe1, 659f5c7d2cc9, 870f6dd82586 & e1ad65d6a7fd) and bug 684344 (cd1957f6628d) on a CLOSED TREE; a=bustage-fairies

This commit is contained in:
Ed Morley 2011-09-03 03:21:25 +01:00
parent ed615fb8d5
commit 5ad1e0be99
75 changed files with 1010 additions and 740 deletions

View File

@ -2423,7 +2423,7 @@ nsScriptSecurityManager::doGetObjectPrincipal(JSObject *aObj
// avoid wasting time checking properties of their classes etc in
// the loop.
if (jsClass == &js::FunctionClass) {
if (jsClass == &js_FunctionClass) {
aObj = aObj->getParent();
if (!aObj)
@ -2431,7 +2431,7 @@ nsScriptSecurityManager::doGetObjectPrincipal(JSObject *aObj
jsClass = aObj->getClass();
if (jsClass == &js::CallClass) {
if (jsClass == &js_CallClass) {
aObj = aObj->getParent();
if (!aObj)

View File

@ -49,7 +49,7 @@ bool checkObjectFields(JSObject *savedCopy, JSObject *obj)
{
/* Ignore fields which are unstable across GCs. */
CHECK(savedCopy->lastProp == obj->lastProp);
CHECK(savedCopy->getClass() == obj->getClass());
CHECK(savedCopy->clasp == obj->clasp);
CHECK(savedCopy->flags == obj->flags);
CHECK(savedCopy->newType == obj->newType);
CHECK(savedCopy->getProto() == obj->getProto());

View File

@ -1543,7 +1543,7 @@ JS_InitStandardClasses(JSContext *cx, JSObject *obj)
return obj->asGlobal()->initStandardClasses(cx);
}
#define CLASP(name) (&name##Class)
#define CLASP(name) (&js_##name##Class)
#define TYPED_ARRAY_CLASP(type) (&TypedArray::fastClasses[TypedArray::type])
#define EAGER_ATOM(name) ATOM_OFFSET(name), NULL
#define EAGER_CLASS_ATOM(name) CLASS_ATOM_OFFSET(name), NULL
@ -1653,7 +1653,7 @@ static JSStdName standard_class_names[] = {
#endif
/* Typed Arrays */
{js_InitTypedArrayClasses, EAGER_CLASS_ATOM(ArrayBuffer), &ArrayBufferClass},
{js_InitTypedArrayClasses, EAGER_CLASS_ATOM(ArrayBuffer), &js_ArrayBufferClass},
{js_InitTypedArrayClasses, EAGER_CLASS_ATOM(Int8Array), TYPED_ARRAY_CLASP(TYPE_INT8)},
{js_InitTypedArrayClasses, EAGER_CLASS_ATOM(Uint8Array), TYPED_ARRAY_CLASP(TYPE_UINT8)},
{js_InitTypedArrayClasses, EAGER_CLASS_ATOM(Int16Array), TYPED_ARRAY_CLASP(TYPE_INT16)},
@ -2275,7 +2275,7 @@ JS_PrintTraceThingInfo(char *buf, size_t bufsize, JSTracer *trc, void *thing,
{
JSObject *obj = (JSObject *)thing;
Class *clasp = obj->getClass();
if (clasp == &FunctionClass) {
if (clasp == &js_FunctionClass) {
JSFunction *fun = obj->getFunctionPrivate();
if (!fun) {
JS_snprintf(buf, bufsize, "<newborn>");
@ -3064,9 +3064,9 @@ JS_NewObject(JSContext *cx, JSClass *jsclasp, JSObject *proto, JSObject *parent)
Class *clasp = Valueify(jsclasp);
if (!clasp)
clasp = &ObjectClass; /* default class is Object */
clasp = &js_ObjectClass; /* default class is Object */
JS_ASSERT(clasp != &FunctionClass);
JS_ASSERT(clasp != &js_FunctionClass);
JS_ASSERT(!(clasp->flags & JSCLASS_IS_GLOBAL));
if (proto)
@ -3093,9 +3093,9 @@ JS_NewObjectWithGivenProto(JSContext *cx, JSClass *jsclasp, JSObject *proto, JSO
Class *clasp = Valueify(jsclasp);
if (!clasp)
clasp = &ObjectClass; /* default class is Object */
clasp = &js_ObjectClass; /* default class is Object */
JS_ASSERT(clasp != &FunctionClass);
JS_ASSERT(clasp != &js_FunctionClass);
JS_ASSERT(!(clasp->flags & JSCLASS_IS_GLOBAL));
JSObject *obj = NewNonFunction<WithProto::Given>(cx, clasp, proto, parent);
@ -3168,7 +3168,7 @@ JS_ConstructObject(JSContext *cx, JSClass *jsclasp, JSObject *proto, JSObject *p
assertSameCompartment(cx, proto, parent);
Class *clasp = Valueify(jsclasp);
if (!clasp)
clasp = &ObjectClass; /* default class is Object */
clasp = &js_ObjectClass; /* default class is Object */
return js_ConstructObject(cx, clasp, proto, parent, 0, NULL);
}
@ -3180,7 +3180,7 @@ JS_ConstructObjectWithArguments(JSContext *cx, JSClass *jsclasp, JSObject *proto
assertSameCompartment(cx, proto, parent, JSValueArray(argv, argc));
Class *clasp = Valueify(jsclasp);
if (!clasp)
clasp = &ObjectClass; /* default class is Object */
clasp = &js_ObjectClass; /* default class is Object */
return js_ConstructObject(cx, clasp, proto, parent, argc, Valueify(argv));
}
@ -3520,7 +3520,7 @@ JS_DefineObject(JSContext *cx, JSObject *obj, const char *name, JSClass *jsclasp
Class *clasp = Valueify(jsclasp);
if (!clasp)
clasp = &ObjectClass; /* default class is Object */
clasp = &js_ObjectClass; /* default class is Object */
JSObject *nobj = NewObject<WithProto::Class>(cx, clasp, proto, obj);
if (!nobj)
@ -4215,7 +4215,7 @@ JS_CloneFunctionObject(JSContext *cx, JSObject *funobj, JSObject *parent)
JS_ASSERT(parent);
}
if (!funobj->isFunction()) {
if (funobj->getClass() != &js_FunctionClass) {
/*
* We cannot clone this object, so fail (we used to return funobj, bad
* idea, but we changed incompatibly to teach any abusers a lesson!).
@ -4306,7 +4306,7 @@ JS_GetFunctionArity(JSFunction *fun)
JS_PUBLIC_API(JSBool)
JS_ObjectIsFunction(JSContext *cx, JSObject *obj)
{
return obj->isFunction();
return obj->getClass() == &js_FunctionClass;
}
JS_PUBLIC_API(JSBool)

View File

@ -44,7 +44,7 @@
* Array objects begin as "dense" arrays, optimized for index-only property
* access over a vector of slots with high load factor. Array methods
* optimize for denseness by testing that the object's class is
* &ArrayClass, and can then directly manipulate the slots for efficiency.
* &js_ArrayClass, and can then directly manipulate the slots for efficiency.
*
* We track these pieces of metadata for arrays in dense mode:
* - The array's length property as a uint32, accessible with
@ -81,7 +81,7 @@
* known to have no hole values below its initialized length, then it is a
* "packed" array and can be accessed much faster by JIT code.
*
* Arrays are converted to use SlowArrayClass when any of these conditions
* Arrays are converted to use js_SlowArrayClass when any of these conditions
* are met:
* - there are more than MIN_SPARSE_INDEX slots total and the load factor
* (COUNT / capacity) is less than 0.25
@ -93,7 +93,7 @@
* properties in the order they were created. We could instead maintain the
* scope to track property enumeration order, but still use the fast slot
* access. That would have the same memory cost as just using a
* SlowArrayClass, but have the same performance characteristics as a dense
* js_SlowArrayClass, but have the same performance characteristics as a dense
* array for slot accesses, at some cost in code complexity.
*/
#include <stdlib.h>
@ -146,6 +146,13 @@ using namespace js;
using namespace js::gc;
using namespace js::types;
static inline bool
ENSURE_SLOW_ARRAY(JSContext *cx, JSObject *obj)
{
return obj->getClass() == &js_SlowArrayClass ||
obj->makeDenseArraySlow(cx);
}
JSBool
js_GetLengthProperty(JSContext *cx, JSObject *obj, jsuint *lengthp)
{
@ -239,11 +246,14 @@ static JSBool
BigIndexToId(JSContext *cx, JSObject *obj, jsuint index, JSBool createAtom,
jsid *idp)
{
jschar buf[10], *start;
Class *clasp;
JSAtom *atom;
JS_STATIC_ASSERT((jsuint)-1 == 4294967295U);
JS_ASSERT(index > JSID_INT_MAX);
jschar buf[10];
jschar *start = JS_ARRAY_END(buf);
start = JS_ARRAY_END(buf);
do {
--start;
*start = (jschar)('0' + index % 10);
@ -254,11 +264,14 @@ BigIndexToId(JSContext *cx, JSObject *obj, jsuint index, JSBool createAtom,
* Skip the atomization if the class is known to store atoms corresponding
* to big indexes together with elements. In such case we know that the
* array does not have an element at the given index if its atom does not
* exist. Dense arrays don't use atoms for any indexes, though it would be
* rare to see them have a big index in any case.
* exist. Fast arrays (clasp == &js_ArrayClass) don't use atoms for
* any indexes, though it would be rare to see them have a big index
* in any case.
*/
JSAtom *atom;
if (!createAtom && (obj->isSlowArray() || obj->isArguments() || obj->isObject())) {
if (!createAtom &&
((clasp = obj->getClass()) == &js_SlowArrayClass ||
obj->isArguments() ||
clasp == &js_ObjectClass)) {
atom = js_GetExistingStringAtom(cx, start, JS_ARRAY_END(buf) - start);
if (!atom) {
*idp = JSID_VOID;
@ -488,13 +501,13 @@ JSBool JS_FASTCALL
js_EnsureDenseArrayCapacity(JSContext *cx, JSObject *obj, jsint i)
{
#ifdef DEBUG
Class *origObjClasp = obj->getClass();
Class *origObjClasp = obj->clasp;
#endif
jsuint u = jsuint(i);
JSBool ret = (obj->ensureDenseArrayElements(cx, u, 1) == JSObject::ED_OK);
/* Partially check the CallInfo's storeAccSet is correct. */
JS_ASSERT(obj->getClass() == origObjClasp);
JS_ASSERT(obj->clasp == origObjClasp);
return ret;
}
/* This function and its callees do not touch any object's .clasp field. */
@ -976,7 +989,7 @@ array_fix(JSContext *cx, JSObject *obj, bool *success, AutoIdVector *props)
return true;
}
Class js::ArrayClass = {
Class js_ArrayClass = {
"Array",
Class::NON_NATIVE | JSCLASS_HAS_PRIVATE | JSCLASS_HAS_CACHED_PROTO(JSProto_Array),
PropertyStub, /* addProperty */
@ -1011,7 +1024,7 @@ Class js::ArrayClass = {
}
};
Class js::SlowArrayClass = {
Class js_SlowArrayClass = {
"Array",
JSCLASS_HAS_PRIVATE |
JSCLASS_HAS_CACHED_PROTO(JSProto_Array),
@ -1056,7 +1069,7 @@ JSObject::makeDenseArraySlow(JSContext *cx)
/* Create a native scope. */
gc::AllocKind kind = getAllocKind();
if (!InitScopeForObject(cx, this, &SlowArrayClass, getProto()->getNewType(cx), kind))
if (!InitScopeForObject(cx, this, &js_SlowArrayClass, getProto()->getNewType(cx), kind))
return false;
backfillDenseArrayHoles(cx);
@ -1077,7 +1090,7 @@ JSObject::makeDenseArraySlow(JSContext *cx)
JS_ASSERT(!denseArrayHasInlineSlots());
}
capacity = numFixedSlots() + arrayCapacity;
clasp = &SlowArrayClass;
clasp = &js_SlowArrayClass;
/*
* Root all values in the array during conversion, as SlowArrayClass only
@ -1097,7 +1110,7 @@ JSObject::makeDenseArraySlow(JSContext *cx)
setMap(oldMap);
capacity = arrayCapacity;
initializedLength = arrayInitialized;
clasp = &ArrayClass;
clasp = &js_ArrayClass;
return false;
}
@ -1120,7 +1133,7 @@ JSObject::makeDenseArraySlow(JSContext *cx)
setMap(oldMap);
capacity = arrayCapacity;
initializedLength = arrayInitialized;
clasp = &ArrayClass;
clasp = &js_ArrayClass;
return false;
}
@ -1131,7 +1144,7 @@ JSObject::makeDenseArraySlow(JSContext *cx)
/*
* Finally, update class. If |this| is Array.prototype, then js_InitClass
* will create an emptyShape whose class is &SlowArrayClass, to ensure
* will create an emptyShape whose class is &js_SlowArrayClass, to ensure
* that delegating instances can share shapes in the tree rooted at the
* proto's empty shape.
*/
@ -1198,7 +1211,7 @@ array_toSource(JSContext *cx, uintN argc, Value *vp)
if (!obj)
return false;
if (!obj->isArray()) {
ReportIncompatibleMethod(cx, vp, &ArrayClass);
ReportIncompatibleMethod(cx, vp, &js_ArrayClass);
return false;
}
@ -1527,7 +1540,7 @@ InitArrayElements(JSContext *cx, JSObject *obj, jsuint start, jsuint count, Valu
return JS_TRUE;
/* Finish out any remaining elements past the max array index. */
if (obj->isDenseArray() && !obj->makeDenseArraySlow(cx))
if (obj->isDenseArray() && !ENSURE_SLOW_ARRAY(cx, obj))
return JS_FALSE;
JS_ASSERT(start == MAX_ARRAY_INDEX + 1);
@ -3204,12 +3217,12 @@ js_InitArrayClass(JSContext *cx, JSObject *obj)
GlobalObject *global = obj->asGlobal();
JSObject *arrayProto = global->createBlankPrototype(cx, &SlowArrayClass);
JSObject *arrayProto = global->createBlankPrototype(cx, &js_SlowArrayClass);
if (!arrayProto || !AddLengthProperty(cx, arrayProto))
return NULL;
arrayProto->setArrayLength(cx, 0);
JSFunction *ctor = global->createConstructor(cx, js_Array, &ArrayClass,
JSFunction *ctor = global->createConstructor(cx, js_Array, &js_ArrayClass,
CLASS_ATOM(cx, Array), 1);
if (!ctor)
return NULL;
@ -3244,7 +3257,7 @@ NewArray(JSContext *cx, jsuint length, JSObject *proto)
JS_ASSERT_IF(proto, proto->isArray());
gc::AllocKind kind = GuessObjectGCKind(length, true);
JSObject *obj = detail::NewObject<WithProto::Class, false>(cx, &ArrayClass, proto, NULL, kind);
JSObject *obj = detail::NewObject<WithProto::Class, false>(cx, &js_ArrayClass, proto, NULL, kind);
if (!obj)
return NULL;
@ -3333,7 +3346,7 @@ JS_DEFINE_CALLINFO_3(extern, OBJECT, NewDenseUnallocatedArray, CONTEXT, UINT32,
JSObject *
NewSlowEmptyArray(JSContext *cx)
{
JSObject *obj = NewNonFunction<WithProto::Class>(cx, &SlowArrayClass, NULL, NULL);
JSObject *obj = NewNonFunction<WithProto::Class>(cx, &js_SlowArrayClass, NULL, NULL);
if (!obj || !AddLengthProperty(cx, obj))
return NULL;

View File

@ -63,7 +63,7 @@
using namespace js;
using namespace js::types;
Class js::BooleanClass = {
Class js_BooleanClass = {
"Boolean",
JSCLASS_HAS_RESERVED_SLOTS(1) |
JSCLASS_HAS_CACHED_PROTO(JSProto_Boolean),
@ -138,7 +138,7 @@ Boolean(JSContext *cx, uintN argc, Value *vp)
bool b = argc != 0 ? js_ValueToBoolean(argv[0]) : false;
if (IsConstructing(vp)) {
JSObject *obj = NewBuiltinClassInstance(cx, &BooleanClass);
JSObject *obj = NewBuiltinClassInstance(cx, &js_BooleanClass);
if (!obj)
return false;
obj->setPrimitiveThis(BooleanValue(b));
@ -152,7 +152,7 @@ Boolean(JSContext *cx, uintN argc, Value *vp)
JSObject *
js_InitBooleanClass(JSContext *cx, JSObject *obj)
{
JSObject *proto = js_InitClass(cx, obj, NULL, &BooleanClass, Boolean, 1,
JSObject *proto = js_InitClass(cx, obj, NULL, &js_BooleanClass, Boolean, 1,
NULL, boolean_methods, NULL, NULL);
if (!proto)
return NULL;

View File

@ -46,6 +46,14 @@
#include "jsapi.h"
#include "jsobj.h"
extern js::Class js_BooleanClass;
inline bool
JSObject::isBoolean() const
{
return getClass() == &js_BooleanClass;
}
extern JSObject *
js_InitBooleanClass(JSContext *cx, JSObject *obj);

View File

@ -251,7 +251,7 @@ HasProperty(JSContext* cx, JSObject* obj, jsid id)
if (pobj->getOps()->lookupProperty)
return JS_NEITHER;
Class* clasp = pobj->getClass();
if (clasp->resolve != JS_ResolveStub && clasp != &StringClass)
if (clasp->resolve != JS_ResolveStub && clasp != &js_StringClass)
return JS_NEITHER;
}
@ -320,7 +320,7 @@ js_NewNullClosure(JSContext* cx, JSObject* funobj, JSObject* proto, JSObject* pa
if (!closure)
return NULL;
if (!closure->initSharingEmptyShape(cx, &FunctionClass, type, parent,
if (!closure->initSharingEmptyShape(cx, &js_FunctionClass, type, parent,
fun, gc::FINALIZE_OBJECT2)) {
return NULL;
}

View File

@ -84,8 +84,8 @@ enum {
* 'i': an integer argument
* 's': a JSString* argument
* 'o': a JSObject* argument
* 'r': a JSObject* argument that is of class RegExpClass
* 'f': a JSObject* argument that is of class FunctionClass
* 'r': a JSObject* argument that is of class js_RegExpClass
* 'f': a JSObject* argument that is of class js_FunctionClass
* 'v': a value argument: on 32-bit, a Value*, on 64-bit, a jsval
*/
struct JSSpecializedNative {

View File

@ -782,7 +782,7 @@ JSStructuredCloneReader::startRead(Value *vp)
case SCTAG_OBJECT_OBJECT: {
JSObject *obj = (tag == SCTAG_ARRAY_OBJECT)
? NewDenseEmptyArray(context())
: NewBuiltinClassInstance(context(), &ObjectClass);
: NewBuiltinClassInstance(context(), &js_ObjectClass);
if (!obj || !objs.append(ObjectValue(*obj)) ||
!allObjs.append(ObjectValue(*obj)))
return false;

View File

@ -334,10 +334,12 @@ CallJSNativeConstructor(JSContext *cx, js::Native native, const CallArgs &args)
*
* (new Object(Object)) returns the callee.
*/
JS_ASSERT_IF(native != FunctionProxyClass.construct &&
native != CallableObjectClass.construct &&
extern JSBool proxy_Construct(JSContext *, uintN, Value *);
extern JSBool callable_Construct(JSContext *, uintN, Value *);
JS_ASSERT_IF(native != proxy_Construct &&
native != callable_Construct &&
native != js::CallOrConstructBoundFunction &&
(!callee.isFunction() || callee.getFunctionPrivate()->u.n.clasp != &ObjectClass),
(!callee.isFunction() || callee.getFunctionPrivate()->u.n.clasp != &js_ObjectClass),
!args.rval().isPrimitive() && callee != args.rval().toObject());
return true;

View File

@ -247,7 +247,7 @@ JSCompartment::wrap(JSContext *cx, Value *vp)
return true;
/* Translate StopIteration singleton. */
if (obj->isStopIteration())
if (obj->getClass() == &js_StopIterationClass)
return js_FindClassObject(cx, NULL, JSProto_StopIteration, vp);
/* Don't unwrap an outer window proxy. */

View File

@ -503,7 +503,7 @@ date_convert(JSContext *cx, JSObject *obj, JSType hint, Value *vp)
* Other Support routines and definitions
*/
Class js::DateClass = {
Class js_DateClass = {
js_Date_str,
JSCLASS_HAS_RESERVED_SLOTS(JSObject::DATE_CLASS_RESERVED_SLOTS) |
JSCLASS_HAS_CACHED_PROTO(JSProto_Date),
@ -1226,7 +1226,7 @@ GetUTCTime(JSContext *cx, JSObject *obj, Value *vp, jsdouble *dp)
{
if (!obj->isDate()) {
if (vp)
ReportIncompatibleMethod(cx, vp, &DateClass);
ReportIncompatibleMethod(cx, vp, &js_DateClass);
return false;
}
*dp = obj->getDateUTCTime().toNumber();
@ -1408,7 +1408,7 @@ GetAndCacheLocalTime(JSContext *cx, JSObject *obj, Value *vp, jsdouble *time = N
return false;
if (!obj->isDate()) {
if (vp)
ReportIncompatibleMethod(cx, vp, &DateClass);
ReportIncompatibleMethod(cx, vp, &js_DateClass);
return false;
}
@ -1701,7 +1701,7 @@ date_setTime(JSContext *cx, uintN argc, Value *vp)
return false;
if (!obj->isDate()) {
ReportIncompatibleMethod(cx, vp, &DateClass);
ReportIncompatibleMethod(cx, vp, &js_DateClass);
return false;
}
@ -2607,7 +2607,7 @@ js_InitDateClass(JSContext *cx, JSObject *obj)
{
/* set static LocalTZA */
LocalTZA = -(PRMJ_LocalGMTDifference() * msPerSecond);
JSObject *proto = js_InitClass(cx, obj, NULL, &DateClass, js_Date, MAXARGS,
JSObject *proto = js_InitClass(cx, obj, NULL, &js_DateClass, js_Date, MAXARGS,
NULL, date_methods, NULL, date_static_methods);
if (!proto)
return NULL;
@ -2638,7 +2638,7 @@ js_InitDateClass(JSContext *cx, JSObject *obj)
JS_FRIEND_API(JSObject *)
js_NewDateObjectMsec(JSContext *cx, jsdouble msec_time)
{
JSObject *obj = NewBuiltinClassInstance(cx, &DateClass);
JSObject *obj = NewBuiltinClassInstance(cx, &js_DateClass);
if (!obj || !obj->ensureSlots(cx, JSObject::DATE_CLASS_RESERVED_SLOTS))
return NULL;
if (!SetUTCTime(cx, obj, msec_time))

View File

@ -46,6 +46,14 @@
#include "jsobj.h"
extern js::Class js_DateClass;
inline bool
JSObject::isDate() const
{
return getClass() == &js_DateClass;
}
#define HalfTimeDomain 8.64e15
#define TIMECLIP(d) ((JSDOUBLE_IS_FINITE(d) \

View File

@ -2000,7 +2000,7 @@ EmitEnterBlock(JSContext *cx, JSParseNode *pn, JSCodeGenerator *cg)
if (depth < 0)
return false;
uintN base = JSSLOT_FREE(&BlockClass);
uintN base = JSSLOT_FREE(&js_BlockClass);
for (uintN slot = base, limit = base + OBJ_BLOCK_COUNT(cx, blockObj); slot < limit; slot++) {
const Value &v = blockObj->getSlot(slot);
@ -4898,7 +4898,7 @@ JSParseNode::getConstantValue(JSContext *cx, bool strictChecks, Value *vp)
JS_ASSERT((pn_op == JSOP_NEWINIT) && !(pn_xflags & PNX_NONCONST));
gc::AllocKind kind = GuessObjectGCKind(pn_count, false);
JSObject *obj = NewBuiltinClassInstance(cx, &ObjectClass, kind);
JSObject *obj = NewBuiltinClassInstance(cx, &js_ObjectClass, kind);
if (!obj)
return false;
@ -7092,7 +7092,7 @@ js_EmitTree(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn)
JSObject *obj = NULL;
if (!cg->hasSharps() && cg->compileAndGo()) {
gc::AllocKind kind = GuessObjectGCKind(pn->pn_count, false);
obj = NewBuiltinClassInstance(cx, &ObjectClass, kind);
obj = NewBuiltinClassInstance(cx, &js_ObjectClass, kind);
if (!obj)
return JS_FALSE;
}

View File

@ -75,7 +75,7 @@ using namespace js;
using namespace js::gc;
using namespace js::types;
/* Forward declarations for ErrorClass's initializer. */
/* Forward declarations for js_ErrorClass's initializer. */
static JSBool
Exception(JSContext *cx, uintN argc, Value *vp);
@ -89,7 +89,7 @@ static JSBool
exn_resolve(JSContext *cx, JSObject *obj, jsid id, uintN flags,
JSObject **objp);
Class js::ErrorClass = {
Class js_ErrorClass = {
js_Error_str,
JSCLASS_HAS_PRIVATE | JSCLASS_NEW_RESOLVE |
JSCLASS_HAS_CACHED_PROTO(JSProto_Error),
@ -263,99 +263,113 @@ GetStackTraceValueBuffer(JSExnPrivate *priv)
return (jsval *)(priv->stackElems + priv->stackDepth);
}
struct SuppressErrorsGuard
{
JSContext *cx;
JSErrorReporter prevReporter;
JSExceptionState *prevState;
SuppressErrorsGuard(JSContext *cx)
: cx(cx),
prevReporter(JS_SetErrorReporter(cx, NULL)),
prevState(JS_SaveExceptionState(cx))
{}
~SuppressErrorsGuard()
{
JS_RestoreExceptionState(cx, prevState);
JS_SetErrorReporter(cx, prevReporter);
}
};
struct AppendArg {
Vector<Value> &values;
AppendArg(Vector<Value> &values) : values(values) {}
bool operator()(uintN, Value *vp) {
return values.append(*vp);
}
};
static bool
static JSBool
InitExnPrivate(JSContext *cx, JSObject *exnObject, JSString *message,
JSString *filename, uintN lineno, JSErrorReport *report, intN exnType)
{
JS_ASSERT(exnObject->isError());
JS_ASSERT(!exnObject->getPrivate());
JSSecurityCallbacks *callbacks;
CheckAccessOp checkAccess;
JSErrorReporter older;
JSExceptionState *state;
jsid callerid;
size_t stackDepth, valueCount, size;
JSBool overflow;
JSExnPrivate *priv;
JSStackTraceElem *elem;
jsval *values;
JSSecurityCallbacks *callbacks = JS_GetSecurityCallbacks(cx);
CheckAccessOp checkAccess = callbacks
? Valueify(callbacks->checkObjectAccess)
: NULL;
JS_ASSERT(exnObject->getClass() == &js_ErrorClass);
Vector<JSStackTraceElem> frames(cx);
Vector<Value> values(cx);
{
SuppressErrorsGuard seg(cx);
for (FrameRegsIter i(cx); !i.done(); ++i) {
/*
* An exception object stores stack values from 'fp' which may be
* in a different compartment from 'exnObject'. Engine compartment
* invariants require such values to be wrapped. A simpler solution
* is to just cut off the backtrace at compartment boundaries.
* Also, avoid exposing values from different security principals.
*/
StackFrame *fp = i.fp();
if (fp->compartment() != cx->compartment)
/*
* Prepare stack trace data.
*
* Set aside any error reporter for cx and save its exception state
* so we can suppress any checkAccess failures. Such failures should stop
* the backtrace procedure, not result in a failure of this constructor.
*/
callbacks = JS_GetSecurityCallbacks(cx);
checkAccess = callbacks
? Valueify(callbacks->checkObjectAccess)
: NULL;
older = JS_SetErrorReporter(cx, NULL);
state = JS_SaveExceptionState(cx);
callerid = ATOM_TO_JSID(cx->runtime->atomState.callerAtom);
stackDepth = 0;
valueCount = 0;
FrameRegsIter firstPass(cx);
for (; !firstPass.done(); ++firstPass) {
StackFrame *fp = firstPass.fp();
if (fp->compartment() != cx->compartment)
break;
if (fp->isNonEvalFunctionFrame()) {
Value v = NullValue();
if (checkAccess &&
!checkAccess(cx, &fp->callee(), callerid, JSACC_READ, &v)) {
break;
if (checkAccess && fp->isNonEvalFunctionFrame()) {
Value v = NullValue();
jsid callerid = ATOM_TO_JSID(cx->runtime->atomState.callerAtom);
if (!checkAccess(cx, &fp->callee(), callerid, JSACC_READ, &v))
break;
}
if (!frames.growBy(1))
return false;
JSStackTraceElem &frame = frames.back();
if (fp->isNonEvalFunctionFrame()) {
frame.funName = fp->fun()->atom ? fp->fun()->atom : cx->runtime->emptyString;
frame.argc = fp->numActualArgs();
if (!fp->forEachCanonicalActualArg(AppendArg(values)))
return false;
} else {
frame.funName = NULL;
frame.argc = 0;
}
if (fp->isScriptFrame()) {
frame.filename = fp->script()->filename;
frame.ulineno = js_FramePCToLineNumber(cx, fp, i.pc());
} else {
frame.ulineno = 0;
frame.filename = NULL;
}
valueCount += fp->numActualArgs();
}
++stackDepth;
}
JS_RestoreExceptionState(cx, state);
JS_SetErrorReporter(cx, older);
/* Do not need overflow check: the vm stack is already bigger. */
JS_STATIC_ASSERT(sizeof(JSStackTraceElem) <= sizeof(StackFrame));
size_t nbytes = offsetof(JSExnPrivate, stackElems) +
frames.length() * sizeof(JSStackTraceElem) +
values.length() * sizeof(Value);
JSExnPrivate *priv = (JSExnPrivate *)cx->malloc_(nbytes);
size = offsetof(JSExnPrivate, stackElems);
overflow = (stackDepth > ((size_t)-1 - size) / sizeof(JSStackTraceElem));
size += stackDepth * sizeof(JSStackTraceElem);
overflow |= (valueCount > ((size_t)-1 - size) / sizeof(jsval));
size += valueCount * sizeof(jsval);
if (overflow) {
js_ReportAllocationOverflow(cx);
return JS_FALSE;
}
priv = (JSExnPrivate *)cx->malloc_(size);
if (!priv)
return false;
return JS_FALSE;
/*
* We initialize errorReport with a copy of report after setting the
* private slot, to prevent GC accessing a junk value we clear the field
* here.
*/
priv->errorReport = NULL;
priv->message = message;
priv->filename = filename;
priv->lineno = lineno;
priv->stackDepth = stackDepth;
priv->exnType = exnType;
values = GetStackTraceValueBuffer(priv);
elem = priv->stackElems;
for (FrameRegsIter iter(cx); iter != firstPass; ++iter) {
StackFrame *fp = iter.fp();
if (fp->compartment() != cx->compartment)
break;
if (!fp->isNonEvalFunctionFrame()) {
elem->funName = NULL;
elem->argc = 0;
} else {
elem->funName = fp->fun()->atom
? fp->fun()->atom
: cx->runtime->emptyString;
elem->argc = fp->numActualArgs();
fp->forEachCanonicalActualArg(CopyTo(Valueify(values)));
values += elem->argc;
}
elem->ulineno = 0;
elem->filename = NULL;
if (fp->isScriptFrame()) {
elem->filename = fp->script()->filename;
elem->ulineno = js_FramePCToLineNumber(cx, fp, iter.pc());
}
++elem;
}
JS_ASSERT(priv->stackElems + stackDepth == elem);
JS_ASSERT(GetStackTraceValueBuffer(priv) + valueCount == values);
exnObject->setPrivate(priv);
if (report) {
/*
@ -366,28 +380,12 @@ InitExnPrivate(JSContext *cx, JSObject *exnObject, JSString *message,
*/
priv->errorReport = CopyErrorReport(cx, report);
if (!priv->errorReport) {
cx->free_(priv);
return false;
/* The finalizer realeases priv since it is in the private slot. */
return JS_FALSE;
}
} else {
priv->errorReport = NULL;
}
priv->message = message;
priv->filename = filename;
priv->lineno = lineno;
priv->stackDepth = frames.length();
priv->exnType = exnType;
JSStackTraceElem *framesDest = priv->stackElems;
Value *valuesDest = reinterpret_cast<Value *>(framesDest + frames.length());
JS_ASSERT(valuesDest == Valueify(GetStackTraceValueBuffer(priv)));
PodCopy(framesDest, frames.begin(), frames.length());
PodCopy(valuesDest, values.begin(), values.length());
exnObject->setPrivate(priv);
return true;
return JS_TRUE;
}
static inline JSExnPrivate *
@ -431,9 +429,12 @@ exn_trace(JSTracer *trc, JSObject *obj)
static void
exn_finalize(JSContext *cx, JSObject *obj)
{
if (JSExnPrivate *priv = GetExnPrivate(obj)) {
if (JSErrorReport *report = priv->errorReport)
cx->free_(report);
JSExnPrivate *priv;
priv = GetExnPrivate(obj);
if (priv) {
if (priv->errorReport)
cx->free_(priv->errorReport);
cx->free_(priv);
}
}
@ -520,7 +521,7 @@ js_ErrorFromException(JSContext *cx, jsval exn)
if (JSVAL_IS_PRIMITIVE(exn))
return NULL;
obj = JSVAL_TO_OBJECT(exn);
if (!obj->isError())
if (obj->getClass() != &js_ErrorClass)
return NULL;
priv = GetExnPrivate(obj);
if (!priv)
@ -703,8 +704,6 @@ enum {
static JSBool
Exception(JSContext *cx, uintN argc, Value *vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
/*
* ECMA ed. 3, 15.11.1 requires Error, etc., to construct even when
* called as functions, without operator new. But as we do not give
@ -712,28 +711,36 @@ Exception(JSContext *cx, uintN argc, Value *vp)
* NewNativeClassInstance to find the class prototype, we must get the
* class prototype ourselves.
*/
JSObject &callee = vp[0].toObject();
Value protov;
jsid protoAtom = ATOM_TO_JSID(cx->runtime->atomState.classPrototypeAtom);
if (!args.callee().getProperty(cx, protoAtom, &protov))
return false;
if (!callee.getProperty(cx, ATOM_TO_JSID(cx->runtime->atomState.classPrototypeAtom), &protov))
return JS_FALSE;
if (!protov.isObject()) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_BAD_PROTOTYPE, "Error");
return false;
return JS_FALSE;
}
JSObject *errProto = &protov.toObject();
JSObject *obj = NewNativeClassInstance(cx, &ErrorClass, errProto, errProto->getParent());
JSObject *obj = NewNativeClassInstance(cx, &js_ErrorClass, errProto, errProto->getParent());
if (!obj)
return false;
return JS_FALSE;
/*
* If it's a new object of class Exception, then null out the private
* data so that the finalizer doesn't attempt to free it.
*/
if (obj->getClass() == &js_ErrorClass)
obj->setPrivate(NULL);
/* Set the 'message' property. */
Value *argv = vp + 2;
JSString *message;
if (args.argc() != 0 && !args[0].isUndefined()) {
message = js_ValueToString(cx, args[0]);
if (argc != 0 && !argv[0].isUndefined()) {
message = js_ValueToString(cx, argv[0]);
if (!message)
return false;
args[0].setString(message);
return JS_FALSE;
argv[0].setString(message);
} else {
message = NULL;
}
@ -745,16 +752,16 @@ Exception(JSContext *cx, uintN argc, Value *vp)
/* Set the 'fileName' property. */
JSString *filename;
if (args.argc() > 1) {
filename = js_ValueToString(cx, args[1]);
if (argc > 1) {
filename = js_ValueToString(cx, argv[1]);
if (!filename)
return false;
args[1].setString(filename);
return JS_FALSE;
argv[1].setString(filename);
} else {
if (!iter.done()) {
filename = FilenameToString(cx, iter.fp()->script()->filename);
if (!filename)
return false;
return JS_FALSE;
} else {
filename = cx->runtime->emptyString;
}
@ -762,19 +769,21 @@ Exception(JSContext *cx, uintN argc, Value *vp)
/* Set the 'lineNumber' property. */
uint32_t lineno;
if (args.argc() > 2) {
if (!ValueToECMAUint32(cx, args[2], &lineno))
return false;
if (argc > 2) {
if (!ValueToECMAUint32(cx, argv[2], &lineno))
return JS_FALSE;
} else {
lineno = iter.done() ? 0 : js_FramePCToLineNumber(cx, iter.fp(), iter.pc());
}
intN exnType = args.callee().getReservedSlot(JSSLOT_ERROR_EXNTYPE).toInt32();
if (!InitExnPrivate(cx, obj, message, filename, lineno, NULL, exnType))
return false;
intN exnType = callee.getReservedSlot(JSSLOT_ERROR_EXNTYPE).toInt32();
if (obj->getClass() == &js_ErrorClass &&
!InitExnPrivate(cx, obj, message, filename, lineno, NULL, exnType)) {
return JS_FALSE;
}
args.rval().setObject(*obj);
return true;
vp->setObject(*obj);
return JS_TRUE;
}
/*
@ -1010,7 +1019,7 @@ InitErrorClass(JSContext *cx, GlobalObject *global, intN type, JSObject &proto)
{
JSProtoKey key = GetExceptionProtoKey(type);
JSAtom *name = cx->runtime->atomState.classAtoms[key];
JSObject *errorProto = global->createBlankPrototypeInheriting(cx, &ErrorClass, proto);
JSObject *errorProto = global->createBlankPrototypeInheriting(cx, &js_ErrorClass, proto);
if (!errorProto)
return NULL;
@ -1032,7 +1041,7 @@ InitErrorClass(JSContext *cx, GlobalObject *global, intN type, JSObject &proto)
}
/* Create the corresponding constructor. */
JSFunction *ctor = global->createConstructor(cx, Exception, &ErrorClass, name, 1);
JSFunction *ctor = global->createConstructor(cx, Exception, &js_ErrorClass, name, 1);
if (!ctor)
return NULL;
ctor->setReservedSlot(JSSLOT_ERROR_EXNTYPE, Int32Value(int32(type)));
@ -1171,7 +1180,7 @@ js_ErrorToException(JSContext *cx, const char *message, JSErrorReport *reportp,
goto out;
tv[0] = OBJECT_TO_JSVAL(errProto);
errObject = NewNativeClassInstance(cx, &ErrorClass, errProto, errProto->getParent());
errObject = NewNativeClassInstance(cx, &js_ErrorClass, errProto, errProto->getParent());
if (!errObject) {
ok = JS_FALSE;
goto out;
@ -1255,7 +1264,7 @@ js_ReportUncaughtException(JSContext *cx)
}
JSAutoByteString filename;
if (!reportp && exnObject && exnObject->isError()) {
if (!reportp && exnObject && exnObject->getClass() == &js_ErrorClass) {
if (!JS_GetProperty(cx, exnObject, js_message_str, &roots[2]))
return false;
if (JSVAL_IS_STRING(roots[2])) {
@ -1359,7 +1368,7 @@ js_CopyErrorObject(JSContext *cx, JSObject *errobj, JSObject *scope)
JSObject *proto;
if (!js_GetClassPrototype(cx, scope->getGlobal(), GetExceptionProtoKey(copy->exnType), &proto))
return NULL;
JSObject *copyobj = NewNativeClassInstance(cx, &ErrorClass, proto, proto->getParent());
JSObject *copyobj = NewNativeClassInstance(cx, &js_ErrorClass, proto, proto->getParent());
copyobj->setPrivate(copy);
autoFree.p = NULL;
return copyobj;

View File

@ -46,6 +46,14 @@
#include "jsobj.h"
extern js::Class js_ErrorClass;
inline bool
JSObject::isError() const
{
return clasp == &js_ErrorClass;
}
/*
* Initialize the exception constructor/prototype hierarchy.
*/

View File

@ -216,8 +216,8 @@ ArgumentsObject::create(JSContext *cx, uint32 argc, JSObject &callee)
/* Can't fail from here on, so initialize everything in argsobj. */
obj->init(cx, callee.getFunctionPrivate()->inStrictMode()
? &StrictArgumentsObjectClass
: &NormalArgumentsObjectClass,
? &StrictArgumentsObject::jsClass
: &NormalArgumentsObject::jsClass,
type, proto->getParent(), NULL, false);
obj->setMap(emptyArgumentsShape);
@ -686,16 +686,18 @@ args_trace(JSTracer *trc, JSObject *obj)
MaybeMarkGenerator(trc, argsobj);
}
namespace js {
/*
* The classes below collaborate to lazily reflect and synchronize actual
* argument values, argument count, and callee function object stored in a
* StackFrame with their corresponding property values in the frame's
* arguments object.
*/
Class js::NormalArgumentsObjectClass = {
Class NormalArgumentsObject::jsClass = {
"Arguments",
JSCLASS_HAS_PRIVATE | JSCLASS_NEW_RESOLVE |
JSCLASS_HAS_RESERVED_SLOTS(NormalArgumentsObject::RESERVED_SLOTS) |
JSCLASS_HAS_RESERVED_SLOTS(RESERVED_SLOTS) |
JSCLASS_HAS_CACHED_PROTO(JSProto_Object),
PropertyStub, /* addProperty */
args_delProperty,
@ -719,10 +721,10 @@ Class js::NormalArgumentsObjectClass = {
* arguments, so it is represented by a different class while sharing some
* functionality.
*/
Class js::StrictArgumentsObjectClass = {
Class StrictArgumentsObject::jsClass = {
"Arguments",
JSCLASS_HAS_PRIVATE | JSCLASS_NEW_RESOLVE |
JSCLASS_HAS_RESERVED_SLOTS(StrictArgumentsObject::RESERVED_SLOTS) |
JSCLASS_HAS_RESERVED_SLOTS(RESERVED_SLOTS) |
JSCLASS_HAS_CACHED_PROTO(JSProto_Object),
PropertyStub, /* addProperty */
args_delProperty,
@ -741,11 +743,13 @@ Class js::StrictArgumentsObjectClass = {
args_trace
};
}
/*
* A Declarative Environment object stores its active StackFrame pointer in
* its private slot, just as Call and Arguments objects do.
*/
Class js::DeclEnvClass = {
Class js_DeclEnvClass = {
js_Object_str,
JSCLASS_HAS_PRIVATE | JSCLASS_HAS_CACHED_PROTO(JSProto_Object),
PropertyStub, /* addProperty */
@ -807,7 +811,7 @@ NewDeclEnvObject(JSContext *cx, StackFrame *fp)
EmptyShape *emptyDeclEnvShape = EmptyShape::getEmptyDeclEnvShape(cx);
if (!emptyDeclEnvShape)
return NULL;
envobj->init(cx, &DeclEnvClass, &emptyTypeObject, &fp->scopeChain(), fp, false);
envobj->init(cx, &js_DeclEnvClass, &emptyTypeObject, &fp->scopeChain(), fp, false);
envobj->setMap(emptyDeclEnvShape);
return envobj;
@ -948,11 +952,11 @@ js_PutCallObject(StackFrame *fp)
}
}
/* Clear private pointers to fp, which is about to go away. */
/* Clear private pointers to fp, which is about to go away (js_Invoke). */
if (js_IsNamedLambda(fun)) {
JSObject *env = callobj.getParent();
JS_ASSERT(env->isDeclEnv());
JS_ASSERT(env->getClass() == &js_DeclEnvClass);
JS_ASSERT(env->getPrivate() == fp);
env->setPrivate(NULL);
}
@ -1172,7 +1176,7 @@ call_trace(JSTracer *trc, JSObject *obj)
MaybeMarkGenerator(trc, obj);
}
JS_PUBLIC_DATA(Class) js::CallClass = {
JS_PUBLIC_DATA(Class) js_CallClass = {
"Call",
JSCLASS_HAS_PRIVATE |
JSCLASS_HAS_RESERVED_SLOTS(JSObject::CALL_RESERVED_SLOTS) |
@ -1462,7 +1466,7 @@ ResolveInterpretedFunctionPrototype(JSContext *cx, JSObject *obj)
JSObject *objProto;
if (!js_GetClassPrototype(cx, parent, JSProto_Object, &objProto))
return NULL;
JSObject *proto = NewNativeClassInstance(cx, &ObjectClass, objProto, parent);
JSObject *proto = NewNativeClassInstance(cx, &js_ObjectClass, objProto, parent);
if (!proto || !proto->setSingletonType(cx))
return NULL;
@ -1714,7 +1718,7 @@ fun_finalize(JSContext *cx, JSObject *obj)
* does not bloat every instance, only those on which reserved slots are set,
* and those on which ad-hoc properties are defined.
*/
JS_PUBLIC_DATA(Class) js::FunctionClass = {
JS_PUBLIC_DATA(Class) js_FunctionClass = {
js_Function_str,
JSCLASS_HAS_PRIVATE | JSCLASS_NEW_RESOLVE |
JSCLASS_HAS_RESERVED_SLOTS(JSFunction::CLASS_RESERVED_SLOTS) |
@ -1827,7 +1831,7 @@ js_fun_call(JSContext *cx, uintN argc, Value *vp)
Value fval = vp[1];
if (!js_IsCallable(fval)) {
ReportIncompatibleMethod(cx, vp, &FunctionClass);
ReportIncompatibleMethod(cx, vp, &js_FunctionClass);
return false;
}
@ -1864,7 +1868,7 @@ js_fun_apply(JSContext *cx, uintN argc, Value *vp)
/* Step 1. */
Value fval = vp[1];
if (!js_IsCallable(fval)) {
ReportIncompatibleMethod(cx, vp, &FunctionClass);
ReportIncompatibleMethod(cx, vp, &js_FunctionClass);
return false;
}
@ -2073,7 +2077,7 @@ fun_bind(JSContext *cx, uintN argc, Value *vp)
/* Step 2. */
if (!js_IsCallable(thisv)) {
ReportIncompatibleMethod(cx, vp, &FunctionClass);
ReportIncompatibleMethod(cx, vp, &js_FunctionClass);
return false;
}
@ -2366,7 +2370,7 @@ ThrowTypeError(JSContext *cx, uintN argc, Value *vp)
JSObject *
js_InitFunctionClass(JSContext *cx, JSObject *obj)
{
JSObject *proto = js_InitClass(cx, obj, NULL, &FunctionClass, Function, 1,
JSObject *proto = js_InitClass(cx, obj, NULL, &js_FunctionClass, Function, 1,
NULL, function_methods, NULL, NULL);
if (!proto)
return NULL;
@ -2473,7 +2477,7 @@ js_CloneFunctionObject(JSContext *cx, JSFunction *fun, JSObject *parent,
* The cloned function object does not need the extra JSFunction members
* beyond JSObject as it points to fun via the private slot.
*/
clone = NewNativeClassInstance(cx, &FunctionClass, proto, parent);
clone = NewNativeClassInstance(cx, &js_FunctionClass, proto, parent);
if (!clone)
return NULL;

View File

@ -170,7 +170,7 @@ struct JSFunction : public JSObject_Slots2
private:
/*
* FunctionClass reserves two slots, which are free in JSObject::fslots
* js_FunctionClass reserves two slots, which are free in JSObject::fslots
* without requiring dslots allocation. Null closures that can be joined to
* a compiler-created function object use the first one to hold a mutable
* methodAtom() state variable, needed for correct foo.caller handling.
@ -255,6 +255,22 @@ struct JSFunction : public JSObject_Slots2
JS_FN(name, fastcall, nargs, flags)
#endif
extern JS_PUBLIC_DATA(js::Class) js_CallClass;
extern JS_PUBLIC_DATA(js::Class) js_FunctionClass;
extern JS_FRIEND_DATA(js::Class) js_DeclEnvClass;
inline bool
JSObject::isCall() const
{
return getClass() == &js_CallClass;
}
inline bool
JSObject::isFunction() const
{
return getClass() == &js_FunctionClass;
}
inline JSFunction *
JSObject::getFunctionPrivate() const
{
@ -315,7 +331,7 @@ IsNativeFunction(const js::Value &v, Native native)
/*
* When we have an object of a builtin class, we don't quite know what its
* valueOf/toString methods are, since these methods may have been overwritten
* or shadowed. However, we can still do better than the general case by
* or shadowed. However, we can still do better than js_TryMethod by
* hard-coding the necessary properties for us to find the native we expect.
*
* TODO: a per-thread shape-based cache would be faster and simpler.

View File

@ -1572,8 +1572,9 @@ GCMarker::~GCMarker()
}
void
GCMarker::delayMarkingChildren(const Cell *cell)
GCMarker::delayMarkingChildren(const void *thing)
{
const Cell *cell = reinterpret_cast<const Cell *>(thing);
ArenaHeader *aheader = cell->arenaHeader();
if (aheader->getMarkingDelay()->link) {
/* Arena already scheduled to be marked later */

View File

@ -58,10 +58,12 @@
#include "jsfun.h"
#include "jsgcstats.h"
#include "jscell.h"
#include "jsxml.h"
struct JSCompartment;
extern "C" void
js_TraceXML(JSTracer *trc, JSXML* thing);
#if JS_STACK_GROWTH_DIRECTION > 0
# define JS_CHECK_STACK_SIZE(limit, lval) ((jsuword)(lval) < limit)
#else
@ -1511,7 +1513,7 @@ struct GCMarker : public JSTracer {
color = newColor;
}
void delayMarkingChildren(const js::gc::Cell *cell);
void delayMarkingChildren(const void *thing);
void markDelayedChildren();

View File

@ -66,7 +66,7 @@
* MarkString, etc. These functions check if an object is in the compartment
* currently being GCed. If it is, they call PushMarkStack. Roots are pushed
* this way as well as pointers traversed inside trace hooks (for things like
* IteratorClass). It it always valid to call a MarkX function instead of
* js_IteratorClass). It it always valid to call a MarkX function instead of
* PushMarkStack, although it may be slower.
*
* The MarkX functions also handle non-GC object traversal. In this case, they
@ -708,7 +708,7 @@ ScanObject(GCMarker *gcmarker, JSObject *obj)
*/
Class *clasp = obj->getClass();
if (clasp->trace) {
if (clasp == &ArrayClass) {
if (clasp == &js_ArrayClass) {
if (obj->getDenseArrayInitializedLength() > LARGE_OBJECT_CHUNK_SIZE) {
if (!gcmarker->largeStack.push(LargeMarkItem(obj)))
clasp->trace(gcmarker, obj);

View File

@ -4385,7 +4385,7 @@ CheckNewScriptProperties(JSContext *cx, TypeObject *type, JSScript *script)
return;
/* Strawman object to add properties to and watch for duplicates. */
JSObject *baseobj = NewBuiltinClassInstance(cx, &ObjectClass, gc::FINALIZE_OBJECT16);
JSObject *baseobj = NewBuiltinClassInstance(cx, &js_ObjectClass, gc::FINALIZE_OBJECT16);
if (!baseobj) {
if (type->newScript)
type->clearNewScript(cx);

View File

@ -300,7 +300,7 @@ GetScopeChainFull(JSContext *cx, StackFrame *fp, JSObject *blockChain)
* to, but not including, that prototype.
*/
limitClone = &fp->scopeChain();
while (limitClone->isWith())
while (limitClone->getClass() == &js_WithClass)
limitClone = limitClone->getParent();
JS_ASSERT(limitClone);
@ -402,8 +402,10 @@ CallThisObjectHook(JSContext *cx, JSObject *obj, Value *argv)
return thisp;
}
namespace js {
void
js::ReportIncompatibleMethod(JSContext *cx, Value *vp, Class *clasp)
ReportIncompatibleMethod(JSContext *cx, Value *vp, Class *clasp)
{
Value &thisv = vp[1];
@ -411,11 +413,11 @@ js::ReportIncompatibleMethod(JSContext *cx, Value *vp, Class *clasp)
if (thisv.isObject()) {
JS_ASSERT(thisv.toObject().getClass() != clasp);
} else if (thisv.isString()) {
JS_ASSERT(clasp != &StringClass);
JS_ASSERT(clasp != &js_StringClass);
} else if (thisv.isNumber()) {
JS_ASSERT(clasp != &NumberClass);
JS_ASSERT(clasp != &js_NumberClass);
} else if (thisv.isBoolean()) {
JS_ASSERT(clasp != &BooleanClass);
JS_ASSERT(clasp != &js_BooleanClass);
} else {
JS_ASSERT(thisv.isUndefined() || thisv.isNull());
}
@ -446,7 +448,7 @@ js::ReportIncompatibleMethod(JSContext *cx, Value *vp, Class *clasp)
* The alert should display "true".
*/
bool
js::BoxNonStrictThis(JSContext *cx, const CallReceiver &call)
BoxNonStrictThis(JSContext *cx, const CallReceiver &call)
{
/*
* Check for SynthesizeFrame poisoning and fast constructors which
@ -474,6 +476,8 @@ js::BoxNonStrictThis(JSContext *cx, const CallReceiver &call)
return true;
}
}
#if JS_HAS_NO_SUCH_METHOD
const uint32 JSSLOT_FOUND_FUNCTION = 0;
@ -520,8 +524,8 @@ Class js_NoSuchMethodClass = {
* call by name, and args is an Array containing this invocation's actual
* parameters.
*/
bool
js::OnUnknownMethod(JSContext *cx, Value *vp)
JSBool
js_OnUnknownMethod(JSContext *cx, Value *vp)
{
JS_ASSERT(!vp[1].isPrimitive());
@ -582,8 +586,10 @@ NoSuchMethod(JSContext *cx, uintN argc, Value *vp)
#endif /* JS_HAS_NO_SUCH_METHOD */
namespace js {
JS_REQUIRES_STACK bool
js::RunScript(JSContext *cx, JSScript *script, StackFrame *fp)
RunScript(JSContext *cx, JSScript *script, StackFrame *fp)
{
JS_ASSERT(script);
JS_ASSERT(fp == cx->fp());
@ -620,8 +626,8 @@ js::RunScript(JSContext *cx, JSScript *script, StackFrame *fp)
* required arguments, allocate declared local variables, and pop everything
* when done. Then push the return value.
*/
bool
js::InvokeKernel(JSContext *cx, const CallArgs &argsRef, MaybeConstruct construct)
JS_REQUIRES_STACK bool
InvokeKernel(JSContext *cx, const CallArgs &argsRef, MaybeConstruct construct)
{
/* N.B. Must be kept in sync with InvokeSessionGuard::start/invoke */
@ -642,7 +648,7 @@ js::InvokeKernel(JSContext *cx, const CallArgs &argsRef, MaybeConstruct construc
Class *clasp = callee.getClass();
/* Invoke non-functions. */
if (JS_UNLIKELY(clasp != &FunctionClass)) {
if (JS_UNLIKELY(clasp != &js_FunctionClass)) {
#if JS_HAS_NO_SUCH_METHOD
if (JS_UNLIKELY(clasp == &js_NoSuchMethodClass))
return NoSuchMethod(cx, args.argc(), args.base());
@ -661,6 +667,22 @@ js::InvokeKernel(JSContext *cx, const CallArgs &argsRef, MaybeConstruct construc
if (fun->isNative())
return CallJSNative(cx, fun->u.n.native, args);
/* Handle the empty-script special case. */
JSScript *script = fun->script();
if (JS_UNLIKELY(script->isEmpty())) {
if (construct) {
bool newType = cx->typeInferenceEnabled() && cx->fp()->isScriptFrame() &&
UseNewType(cx, cx->fp()->script(), cx->regs().pc);
JSObject *obj = js_CreateThisForFunction(cx, &callee, newType);
if (!obj)
return false;
args.rval().setObject(*obj);
} else {
args.rval().setUndefined();
}
return true;
}
TypeMonitorCall(cx, args, construct);
/* Get pointer to new frame/slots, prepare arguments. */
@ -677,7 +699,7 @@ js::InvokeKernel(JSContext *cx, const CallArgs &argsRef, MaybeConstruct construc
JSBool ok;
{
AutoPreserveEnumerators preserve(cx);
ok = RunScript(cx, fun->script(), fp);
ok = RunScript(cx, script, fp);
}
args.rval() = fp->returnValue();
@ -711,13 +733,13 @@ InvokeSessionGuard::start(JSContext *cx, const Value &calleev, const Value &this
if (!calleev.isObject())
break;
JSObject &callee = calleev.toObject();
if (callee.getClass() != &FunctionClass)
if (callee.getClass() != &js_FunctionClass)
break;
JSFunction *fun = callee.getFunctionPrivate();
if (fun->isNative())
break;
script_ = fun->script();
if (fun->isHeavyweight())
if (fun->isHeavyweight() || script_->isEmpty())
break;
/*
@ -784,8 +806,8 @@ InvokeSessionGuard::start(JSContext *cx, const Value &calleev, const Value &this
}
bool
js::Invoke(JSContext *cx, const Value &thisv, const Value &fval, uintN argc, Value *argv,
Value *rval)
Invoke(JSContext *cx, const Value &thisv, const Value &fval, uintN argc, Value *argv,
Value *rval)
{
LeaveTrace(cx);
@ -817,7 +839,7 @@ js::Invoke(JSContext *cx, const Value &thisv, const Value &fval, uintN argc, Val
}
bool
js::InvokeConstructor(JSContext *cx, const Value &fval, uintN argc, Value *argv, Value *rval)
InvokeConstructor(JSContext *cx, const Value &fval, uintN argc, Value *argv, Value *rval)
{
LeaveTrace(cx);
@ -837,8 +859,8 @@ js::InvokeConstructor(JSContext *cx, const Value &fval, uintN argc, Value *argv,
}
bool
js::InvokeGetterOrSetter(JSContext *cx, JSObject *obj, const Value &fval, uintN argc, Value *argv,
Value *rval)
InvokeGetterOrSetter(JSContext *cx, JSObject *obj, const Value &fval, uintN argc, Value *argv,
Value *rval)
{
LeaveTrace(cx);
@ -880,8 +902,8 @@ InitSharpSlots(JSContext *cx, StackFrame *fp)
#endif
bool
js::ExecuteKernel(JSContext *cx, JSScript *script, JSObject &scopeChain, const Value &thisv,
ExecuteType type, StackFrame *evalInFrame, Value *result)
ExecuteKernel(JSContext *cx, JSScript *script, JSObject &scopeChain, const Value &thisv,
ExecuteType type, StackFrame *evalInFrame, Value *result)
{
JS_ASSERT_IF(evalInFrame, type == EXECUTE_DEBUG);
@ -922,7 +944,7 @@ js::ExecuteKernel(JSContext *cx, JSScript *script, JSObject &scopeChain, const V
}
bool
js::Execute(JSContext *cx, JSScript *script, JSObject &scopeChainArg, Value *rval)
Execute(JSContext *cx, JSScript *script, JSObject &scopeChainArg, Value *rval)
{
/* The scope chain could be anything, so innerize just in case. */
JSObject *scopeChain = &scopeChainArg;
@ -952,7 +974,7 @@ js::Execute(JSContext *cx, JSScript *script, JSObject &scopeChainArg, Value *rva
}
bool
js::CheckRedeclaration(JSContext *cx, JSObject *obj, jsid id, uintN attrs)
CheckRedeclaration(JSContext *cx, JSObject *obj, jsid id, uintN attrs)
{
JSObject *obj2;
JSProperty *prop;
@ -1023,7 +1045,7 @@ js::CheckRedeclaration(JSContext *cx, JSObject *obj, jsid id, uintN attrs)
}
JSBool
js::HasInstance(JSContext *cx, JSObject *obj, const Value *v, JSBool *bp)
HasInstance(JSContext *cx, JSObject *obj, const Value *v, JSBool *bp)
{
Class *clasp = obj->getClass();
if (clasp->hasInstance)
@ -1034,7 +1056,7 @@ js::HasInstance(JSContext *cx, JSObject *obj, const Value *v, JSBool *bp)
}
bool
js::LooselyEqual(JSContext *cx, const Value &lval, const Value &rval, JSBool *result)
LooselyEqual(JSContext *cx, const Value &lval, const Value &rval, JSBool *result)
{
#if JS_HAS_XML_SUPPORT
if (JS_UNLIKELY(lval.isObject() && lval.toObject().isXML()) ||
@ -1105,7 +1127,7 @@ js::LooselyEqual(JSContext *cx, const Value &lval, const Value &rval, JSBool *re
}
bool
js::StrictlyEqual(JSContext *cx, const Value &lref, const Value &rref, JSBool *equal)
StrictlyEqual(JSContext *cx, const Value &lref, const Value &rref, JSBool *equal)
{
Value lval = lref, rval = rref;
if (SameType(lval, rval)) {
@ -1157,7 +1179,7 @@ IsNaN(const Value &v)
}
bool
js::SameValue(JSContext *cx, const Value &v1, const Value &v2, JSBool *same)
SameValue(JSContext *cx, const Value &v1, const Value &v2, JSBool *same)
{
if (IsNegativeZero(v1)) {
*same = IsNegativeZero(v2);
@ -1175,7 +1197,7 @@ js::SameValue(JSContext *cx, const Value &v1, const Value &v2, JSBool *same)
}
JSType
js::TypeOfValue(JSContext *cx, const Value &vref)
TypeOfValue(JSContext *cx, const Value &vref)
{
Value v = vref;
if (v.isNumber())
@ -1192,16 +1214,16 @@ js::TypeOfValue(JSContext *cx, const Value &vref)
return JSTYPE_BOOLEAN;
}
bool
js::InvokeConstructorKernel(JSContext *cx, const CallArgs &argsRef)
JS_REQUIRES_STACK bool
InvokeConstructorKernel(JSContext *cx, const CallArgs &argsRef)
{
JS_ASSERT(!FunctionClass.construct);
JS_ASSERT(!js_FunctionClass.construct);
CallArgs args = argsRef;
if (args.calleev().isObject()) {
JSObject *callee = &args.callee();
Class *clasp = callee->getClass();
if (clasp == &FunctionClass) {
if (clasp == &js_FunctionClass) {
JSFunction *fun = callee->getFunctionPrivate();
if (fun->isConstructor()) {
@ -1233,8 +1255,8 @@ error:
}
bool
js::InvokeConstructorWithGivenThis(JSContext *cx, JSObject *thisobj, const Value &fval,
uintN argc, Value *argv, Value *rval)
InvokeConstructorWithGivenThis(JSContext *cx, JSObject *thisobj, const Value &fval,
uintN argc, Value *argv, Value *rval)
{
LeaveTrace(cx);
@ -1251,7 +1273,7 @@ js::InvokeConstructorWithGivenThis(JSContext *cx, JSObject *thisobj, const Value
Class *clasp = callee.getClass();
JSFunction *fun;
bool ok;
if (clasp == &FunctionClass && (fun = callee.getFunctionPrivate())->isConstructor()) {
if (clasp == &js_FunctionClass && (fun = callee.getFunctionPrivate())->isConstructor()) {
args.thisv().setMagicWithObjectOrNullPayload(thisobj);
Probes::calloutBegin(cx, fun);
ok = CallJSNativeConstructor(cx, fun->u.n.native, args);
@ -1269,7 +1291,7 @@ js::InvokeConstructorWithGivenThis(JSContext *cx, JSObject *thisobj, const Value
}
bool
js::ValueToId(JSContext *cx, const Value &v, jsid *idp)
ValueToId(JSContext *cx, const Value &v, jsid *idp)
{
int32_t i;
if (ValueFitsInInt32(v, &i) && INT_FITS_IN_JSID(i)) {
@ -1290,12 +1312,14 @@ js::ValueToId(JSContext *cx, const Value &v, jsid *idp)
return js_ValueToStringId(cx, v, idp);
}
} /* namespace js */
/*
* Enter the new with scope using an object at sp[-1] and associate the depth
* of the with block with sp + stackIndex.
*/
static bool
EnterWith(JSContext *cx, jsint stackIndex, JSOp op, size_t oplen)
JS_REQUIRES_STACK JSBool
js_EnterWith(JSContext *cx, jsint stackIndex, JSOp op, size_t oplen)
{
StackFrame *fp = cx->fp();
Value *sp = cx->regs().sp;
@ -1329,47 +1353,55 @@ EnterWith(JSContext *cx, jsint stackIndex, JSOp op, size_t oplen)
return JS_TRUE;
}
static void
LeaveWith(JSContext *cx)
JS_REQUIRES_STACK void
js_LeaveWith(JSContext *cx)
{
JSObject *withobj;
withobj = &cx->fp()->scopeChain();
JS_ASSERT(withobj->getClass() == &WithClass);
JS_ASSERT(withobj->getClass() == &js_WithClass);
JS_ASSERT(withobj->getPrivate() == js_FloatingFrameIfGenerator(cx, cx->fp()));
JS_ASSERT(OBJ_BLOCK_DEPTH(cx, withobj) >= 0);
withobj->setPrivate(NULL);
cx->fp()->setScopeChainNoCallObj(*withobj->getParent());
}
bool
js::IsActiveWithOrBlock(JSContext *cx, JSObject &obj, int stackDepth)
JS_REQUIRES_STACK Class *
js_IsActiveWithOrBlock(JSContext *cx, JSObject *obj, int stackDepth)
{
return (obj.isWith() || obj.isBlock()) &&
obj.getPrivate() == js_FloatingFrameIfGenerator(cx, cx->fp()) &&
OBJ_BLOCK_DEPTH(cx, &obj) >= stackDepth;
Class *clasp;
clasp = obj->getClass();
if ((clasp == &js_WithClass || clasp == &js_BlockClass) &&
obj->getPrivate() == js_FloatingFrameIfGenerator(cx, cx->fp()) &&
OBJ_BLOCK_DEPTH(cx, obj) >= stackDepth) {
return clasp;
}
return NULL;
}
/*
* Unwind block and scope chains to match the given depth. The function sets
* fp->sp on return to stackDepth.
*/
bool
js::UnwindScope(JSContext *cx, jsint stackDepth, JSBool normalUnwind)
JS_REQUIRES_STACK JSBool
js_UnwindScope(JSContext *cx, jsint stackDepth, JSBool normalUnwind)
{
Class *clasp;
JS_ASSERT(stackDepth >= 0);
JS_ASSERT(cx->fp()->base() + stackDepth <= cx->regs().sp);
StackFrame *fp = cx->fp();
for (;;) {
JSObject &scopeChain = fp->scopeChain();
if (!IsActiveWithOrBlock(cx, scopeChain, stackDepth))
clasp = js_IsActiveWithOrBlock(cx, &fp->scopeChain(), stackDepth);
if (!clasp)
break;
if (scopeChain.isBlock()) {
if (clasp == &js_BlockClass) {
/* Don't fail until after we've updated all stacks. */
normalUnwind &= js_PutBlockObject(cx, normalUnwind);
} else {
LeaveWith(cx);
js_LeaveWith(cx);
}
}
@ -1377,14 +1409,8 @@ js::UnwindScope(JSContext *cx, jsint stackDepth, JSBool normalUnwind)
return normalUnwind;
}
/*
* Find the results of incrementing or decrementing *vp. For pre-increments,
* both *vp and *vp2 will contain the result on return. For post-increments,
* vp will contain the original value converted to a number and vp2 will get
* the result. Both vp and vp2 must be roots.
*/
static bool
DoIncDec(JSContext *cx, const JSCodeSpec *cs, Value *vp, Value *vp2)
JSBool
js_DoIncDec(JSContext *cx, const JSCodeSpec *cs, Value *vp, Value *vp2)
{
if (cs->format & JOF_POST) {
double d;
@ -1659,7 +1685,7 @@ JS_STATIC_ASSERT(JSOP_INCNAME_LENGTH == JSOP_NAMEDEC_LENGTH);
static inline bool
IteratorMore(JSContext *cx, JSObject *iterobj, bool *cond, Value *rval)
{
if (iterobj->isIterator()) {
if (iterobj->getClass() == &js_IteratorClass) {
NativeIterator *ni = iterobj->getNativeIterator();
if (ni->isKeyIter()) {
*cond = (ni->props_cursor < ni->props_end);
@ -1675,7 +1701,7 @@ IteratorMore(JSContext *cx, JSObject *iterobj, bool *cond, Value *rval)
static inline bool
IteratorNext(JSContext *cx, JSObject *iterobj, Value *rval)
{
if (iterobj->isIterator()) {
if (iterobj->getClass() == &js_IteratorClass) {
NativeIterator *ni = iterobj->getNativeIterator();
if (ni->isKeyIter()) {
JS_ASSERT(ni->props_cursor < ni->props_end);
@ -1707,8 +1733,10 @@ TypeCheckNextBytecode(JSContext *cx, JSScript *script, unsigned n, const FrameRe
#endif
}
JS_NEVER_INLINE bool
js::Interpret(JSContext *cx, StackFrame *entryFrame, InterpMode interpMode)
namespace js {
JS_REQUIRES_STACK JS_NEVER_INLINE bool
Interpret(JSContext *cx, StackFrame *entryFrame, InterpMode interpMode)
{
#ifdef MOZ_TRACEVIS
TraceVisStateObj tvso(cx, S_INTERP);
@ -2343,12 +2371,15 @@ BEGIN_CASE(JSOP_POPN)
OBJ_BLOCK_DEPTH(cx, obj) + OBJ_BLOCK_COUNT(cx, obj)
<= (size_t) (regs.sp - regs.fp()->base()));
for (obj = &regs.fp()->scopeChain(); obj; obj = obj->getParent()) {
if (!obj->isBlock() || !obj->isWith())
Class *clasp = obj->getClass();
if (clasp != &js_BlockClass && clasp != &js_WithClass)
continue;
if (obj->getPrivate() != js_FloatingFrameIfGenerator(cx, regs.fp()))
break;
JS_ASSERT(regs.fp()->base() + OBJ_BLOCK_DEPTH(cx, obj)
+ (obj->isBlock() ? OBJ_BLOCK_COUNT(cx, obj) : 1)
+ ((clasp == &js_BlockClass)
? OBJ_BLOCK_COUNT(cx, obj)
: 1)
<= regs.sp);
}
#endif
@ -2361,7 +2392,7 @@ BEGIN_CASE(JSOP_POPV)
END_CASE(JSOP_POPV)
BEGIN_CASE(JSOP_ENTERWITH)
if (!EnterWith(cx, -1, JSOP_ENTERWITH, JSOP_ENTERWITH_LENGTH))
if (!js_EnterWith(cx, -1, JSOP_ENTERWITH, JSOP_ENTERWITH_LENGTH))
goto error;
/*
@ -2379,7 +2410,7 @@ END_CASE(JSOP_ENTERWITH)
BEGIN_CASE(JSOP_LEAVEWITH)
JS_ASSERT(regs.sp[-1].toObject() == regs.fp()->scopeChain());
regs.sp--;
LeaveWith(cx);
js_LeaveWith(cx);
END_CASE(JSOP_LEAVEWITH)
BEGIN_CASE(JSOP_RETURN)
@ -2420,7 +2451,7 @@ BEGIN_CASE(JSOP_STOP)
inline_return:
{
JS_ASSERT(!regs.fp()->hasImacropc());
JS_ASSERT(!IsActiveWithOrBlock(cx, regs.fp()->scopeChain(), 0));
JS_ASSERT(!js_IsActiveWithOrBlock(cx, &regs.fp()->scopeChain(), 0));
interpReturnOK = ScriptEpilogue(cx, regs.fp(), interpReturnOK);
/* The JIT inlines ScriptEpilogue. */
@ -3499,7 +3530,7 @@ do_incop:
} else {
/* We need an extra root for the result. */
PUSH_NULL();
if (!DoIncDec(cx, cs, &regs.sp[-2], &regs.sp[-1]))
if (!js_DoIncDec(cx, cs, &regs.sp[-2], &regs.sp[-1]))
goto error;
{
@ -3571,7 +3602,7 @@ BEGIN_CASE(JSOP_LOCALINC)
PUSH_INT32(tmp + incr2);
} else {
PUSH_COPY(*vp);
if (!DoIncDec(cx, &js_CodeSpec[op], &regs.sp[-1], vp))
if (!js_DoIncDec(cx, &js_CodeSpec[op], &regs.sp[-1], vp))
goto error;
TypeScript::MonitorOverflow(cx, script, regs.pc);
}
@ -3777,7 +3808,7 @@ BEGIN_CASE(JSOP_CALLPROP)
if (JS_UNLIKELY(rval.isPrimitive()) && regs.sp[-1].isObject()) {
LOAD_ATOM(0, atom);
regs.sp[-2].setString(atom);
if (!OnUnknownMethod(cx, regs.sp - 2))
if (!js_OnUnknownMethod(cx, regs.sp - 2))
goto error;
}
#endif
@ -4053,10 +4084,10 @@ BEGIN_CASE(JSOP_CALLELEM)
#if JS_HAS_NO_SUCH_METHOD
if (JS_UNLIKELY(regs.sp[-2].isPrimitive()) && thisv.isObject()) {
/* For OnUnknownMethod, sp[-2] is the index, and sp[-1] is the object missing it. */
/* For js_OnUnknownMethod, sp[-2] is the index, and sp[-1] is the object missing it. */
regs.sp[-2] = regs.sp[-1];
regs.sp[-1].setObject(*thisObj);
if (!OnUnknownMethod(cx, regs.sp - 2))
if (!js_OnUnknownMethod(cx, regs.sp - 2))
goto error;
} else
#endif
@ -4292,7 +4323,7 @@ BEGIN_CASE(JSOP_CALLNAME)
} else {
shape = (Shape *)prop;
JSObject *normalized = obj;
if (normalized->getClass() == &WithClass && !shape->hasDefaultGetter())
if (normalized->getClass() == &js_WithClass && !shape->hasDefaultGetter())
normalized = js_UnwrapWithObject(cx, normalized);
NATIVE_GET(cx, normalized, obj2, shape, JSGET_METHOD_BARRIER, &rval);
}
@ -4990,7 +5021,7 @@ BEGIN_CASE(JSOP_LAMBDA)
const Value &lref = regs.sp[-1];
JS_ASSERT(lref.isObject());
JSObject *obj2 = &lref.toObject();
JS_ASSERT(obj2->isObject());
JS_ASSERT(obj2->getClass() == &js_ObjectClass);
#endif
fun->setMethodAtom(script->getAtom(GET_FULL_INDEX(pc2 - regs.pc)));
@ -5207,7 +5238,7 @@ BEGIN_CASE(JSOP_NEWINIT)
obj = NewDenseEmptyArray(cx);
} else {
gc::AllocKind kind = GuessObjectGCKind(0, false);
obj = NewBuiltinClassInstance(cx, &ObjectClass, kind);
obj = NewBuiltinClassInstance(cx, &js_ObjectClass, kind);
}
if (!obj)
@ -5793,7 +5824,7 @@ BEGIN_CASE(JSOP_ENDFILTER)
bool cond = !regs.sp[-1].isMagic();
if (cond) {
/* Exit the "with" block left from the previous iteration. */
LeaveWith(cx);
js_LeaveWith(cx);
}
if (!js_StepXMLListFilter(cx, cond))
goto error;
@ -5803,7 +5834,7 @@ BEGIN_CASE(JSOP_ENDFILTER)
* temporaries.
*/
JS_ASSERT(IsXML(regs.sp[-1]));
if (!EnterWith(cx, -2, JSOP_ENDFILTER, JSOP_ENDFILTER_LENGTH))
if (!js_EnterWith(cx, -2, JSOP_ENDFILTER, JSOP_ENDFILTER_LENGTH))
goto error;
regs.sp--;
len = GET_JUMP_OFFSET(regs.pc);
@ -5930,9 +5961,10 @@ BEGIN_CASE(JSOP_ENTERBLOCK)
* static scope.
*/
JSObject *obj2 = &regs.fp()->scopeChain();
while (obj2->isWith())
Class *clasp;
while ((clasp = obj2->getClass()) == &js_WithClass)
obj2 = obj2->getParent();
if (obj2->isBlock() &&
if (clasp == &js_BlockClass &&
obj2->getPrivate() == js_FloatingFrameIfGenerator(cx, regs.fp())) {
JSObject *youngestProto = obj2->getProto();
JS_ASSERT(youngestProto->isStaticBlock());
@ -6197,7 +6229,7 @@ END_CASE(JSOP_ARRAYPUSH)
*/
regs.pc = (script)->main() + tn->start + tn->length;
JSBool ok = UnwindScope(cx, tn->stackDepth, JS_TRUE);
JSBool ok = js_UnwindScope(cx, tn->stackDepth, JS_TRUE);
JS_ASSERT(regs.sp == regs.fp()->base() + tn->stackDepth);
if (!ok) {
/*
@ -6267,12 +6299,12 @@ END_CASE(JSOP_ARRAYPUSH)
forced_return:
/*
* Unwind the scope making sure that interpReturnOK stays false even when
* UnwindScope returns true.
* js_UnwindScope returns true.
*
* When a trap handler returns JSTRAP_RETURN, we jump here with
* interpReturnOK set to true bypassing any finally blocks.
*/
interpReturnOK &= UnwindScope(cx, 0, interpReturnOK || cx->isExceptionPending());
interpReturnOK &= js_UnwindScope(cx, 0, interpReturnOK || cx->isExceptionPending());
JS_ASSERT(regs.sp == regs.fp()->base());
if (entryFrame != regs.fp())
@ -6306,7 +6338,7 @@ END_CASE(JSOP_ARRAYPUSH)
#endif
JS_ASSERT_IF(!regs.fp()->isGeneratorFrame(),
!IsActiveWithOrBlock(cx, regs.fp()->scopeChain(), 0));
!js_IsActiveWithOrBlock(cx, &regs.fp()->scopeChain(), 0));
#ifdef JS_METHODJIT
/*
@ -6326,3 +6358,5 @@ END_CASE(JSOP_ARRAYPUSH)
}
goto error;
}
} /* namespace js */

View File

@ -360,19 +360,34 @@ class InterpreterFrames {
const InterruptEnablerBase &enabler;
};
} /* namespace js */
extern JS_REQUIRES_STACK JSBool
js_EnterWith(JSContext *cx, jsint stackIndex, JSOp op, size_t oplen);
extern JS_REQUIRES_STACK void
js_LeaveWith(JSContext *cx);
/*
* Find the results of incrementing or decrementing *vp. For pre-increments,
* both *vp and *vp2 will contain the result on return. For post-increments,
* vp will contain the original value converted to a number and vp2 will get
* the result. Both vp and vp2 must be roots.
*/
extern JSBool
js_DoIncDec(JSContext *cx, const JSCodeSpec *cs, js::Value *vp, js::Value *vp2);
/*
* Unwind block and scope chains to match the given depth. The function sets
* fp->sp on return to stackDepth.
*/
extern bool
UnwindScope(JSContext *cx, jsint stackDepth, JSBool normalUnwind);
extern JS_REQUIRES_STACK JSBool
js_UnwindScope(JSContext *cx, jsint stackDepth, JSBool normalUnwind);
extern bool
OnUnknownMethod(JSContext *cx, js::Value *vp);
extern JSBool
js_OnUnknownMethod(JSContext *cx, js::Value *vp);
extern bool
IsActiveWithOrBlock(JSContext *cx, JSObject &obj, int stackDepth);
} /* namespace js */
extern JS_REQUIRES_STACK js::Class *
js_IsActiveWithOrBlock(JSContext *cx, JSObject *obj, int stackDepth);
#endif /* jsinterp_h___ */

View File

@ -182,7 +182,7 @@ class PrimitiveBehavior<JSString *> {
public:
static inline bool isType(const Value &v) { return v.isString(); }
static inline JSString *extract(const Value &v) { return v.toString(); }
static inline Class *getClass() { return &StringClass; }
static inline Class *getClass() { return &js_StringClass; }
};
template<>
@ -190,7 +190,7 @@ class PrimitiveBehavior<bool> {
public:
static inline bool isType(const Value &v) { return v.isBoolean(); }
static inline bool extract(const Value &v) { return v.toBoolean(); }
static inline Class *getClass() { return &BooleanClass; }
static inline Class *getClass() { return &js_BooleanClass; }
};
template<>
@ -198,7 +198,7 @@ class PrimitiveBehavior<double> {
public:
static inline bool isType(const Value &v) { return v.isNumber(); }
static inline double extract(const Value &v) { return v.toNumber(); }
static inline Class *getClass() { return &NumberClass; }
static inline Class *getClass() { return &js_NumberClass; }
};
} // namespace detail

View File

@ -90,7 +90,7 @@ static void iterator_finalize(JSContext *cx, JSObject *obj);
static void iterator_trace(JSTracer *trc, JSObject *obj);
static JSObject *iterator_iterator(JSContext *cx, JSObject *obj, JSBool keysonly);
Class js::IteratorClass = {
Class js_IteratorClass = {
"Iterator",
JSCLASS_HAS_PRIVATE |
JSCLASS_CONCURRENT_FINALIZER |
@ -130,7 +130,7 @@ NativeIterator::mark(JSTracer *trc)
static void
iterator_finalize(JSContext *cx, JSObject *obj)
{
JS_ASSERT(obj->isIterator());
JS_ASSERT(obj->getClass() == &js_IteratorClass);
NativeIterator *ni = obj->getNativeIterator();
if (ni) {
@ -418,12 +418,12 @@ NewIteratorObject(JSContext *cx, uintN flags)
EmptyShape *emptyEnumeratorShape = EmptyShape::getEmptyEnumeratorShape(cx);
if (!emptyEnumeratorShape)
return NULL;
obj->init(cx, &IteratorClass, &types::emptyTypeObject, NULL, NULL, false);
obj->init(cx, &js_IteratorClass, &types::emptyTypeObject, NULL, NULL, false);
obj->setMap(emptyEnumeratorShape);
return obj;
}
return NewBuiltinClassInstance(cx, &IteratorClass);
return NewBuiltinClassInstance(cx, &js_IteratorClass);
}
NativeIterator *
@ -571,7 +571,7 @@ GetIterator(JSContext *cx, JSObject *obj, uintN flags, Value *vp)
if (obj) {
/* Enumerate Iterator.prototype directly. */
JSIteratorOp op = obj->getClass()->ext.iteratorObject;
if (op && (obj->getClass() != &IteratorClass || obj->getNativeIterator())) {
if (op && (obj->getClass() != &js_IteratorClass || obj->getNativeIterator())) {
JSObject *iterobj = op(cx, obj, !(flags & JSITER_FOREACH));
if (!iterobj)
return false;
@ -718,8 +718,8 @@ iterator_next(JSContext *cx, uintN argc, Value *vp)
JSObject *obj = ToObject(cx, &vp[1]);
if (!obj)
return false;
if (!obj->isIterator()) {
ReportIncompatibleMethod(cx, vp, &IteratorClass);
if (obj->getClass() != &js_IteratorClass) {
ReportIncompatibleMethod(cx, vp, &js_IteratorClass);
return false;
}
@ -792,7 +792,8 @@ js_CloseIterator(JSContext *cx, JSObject *obj)
{
cx->iterValue.setMagic(JS_NO_ITER_VALUE);
if (obj->isIterator()) {
Class *clasp = obj->getClass();
if (clasp == &js_IteratorClass) {
/* Remove enumerators from the active list, which is a stack. */
NativeIterator *ni = obj->getNativeIterator();
@ -811,7 +812,7 @@ js_CloseIterator(JSContext *cx, JSObject *obj)
}
}
#if JS_HAS_GENERATORS
else if (obj->isGenerator()) {
else if (clasp == &js_GeneratorClass) {
return CloseGenerator(cx, obj);
}
#endif
@ -942,7 +943,7 @@ js_IteratorMore(JSContext *cx, JSObject *iterobj, Value *rval)
{
/* Fast path for native iterators */
NativeIterator *ni = NULL;
if (iterobj->isIterator()) {
if (iterobj->getClass() == &js_IteratorClass) {
/* Key iterators are handled by fast-paths. */
ni = iterobj->getNativeIterator();
if (ni) {
@ -970,7 +971,7 @@ js_IteratorMore(JSContext *cx, JSObject *iterobj, Value *rval)
return false;
if (!Invoke(cx, ObjectValue(*iterobj), *rval, 0, NULL, rval)) {
/* Check for StopIteration. */
if (!cx->isExceptionPending() || !IsStopIteration(cx->getPendingException()))
if (!cx->isExceptionPending() || !js_ValueIsStopIteration(cx->getPendingException()))
return false;
cx->clearPendingException();
@ -999,7 +1000,7 @@ JSBool
js_IteratorNext(JSContext *cx, JSObject *iterobj, Value *rval)
{
/* Fast path for native iterators */
if (iterobj->isIterator()) {
if (iterobj->getClass() == &js_IteratorClass) {
/*
* Implement next directly as all the methods of the native iterator are
* read-only and permanent.
@ -1038,11 +1039,11 @@ js_IteratorNext(JSContext *cx, JSObject *iterobj, Value *rval)
static JSBool
stopiter_hasInstance(JSContext *cx, JSObject *obj, const Value *v, JSBool *bp)
{
*bp = IsStopIteration(*v);
*bp = js_ValueIsStopIteration(*v);
return JS_TRUE;
}
Class js::StopIterationClass = {
Class js_StopIterationClass = {
js_StopIteration_str,
JSCLASS_HAS_CACHED_PROTO(JSProto_StopIteration) |
JSCLASS_FREEZE_PROTO,
@ -1110,7 +1111,7 @@ generator_trace(JSTracer *trc, JSObject *obj)
MarkStackRangeConservatively(trc, fp->slots(), gen->regs.sp);
}
Class js::GeneratorClass = {
Class js_GeneratorClass = {
js_Generator_str,
JSCLASS_HAS_PRIVATE | JSCLASS_HAS_CACHED_PROTO(JSProto_Generator) |
JSCLASS_IS_ANONYMOUS,
@ -1149,7 +1150,7 @@ Class js::GeneratorClass = {
JS_REQUIRES_STACK JSObject *
js_NewGenerator(JSContext *cx)
{
JSObject *obj = NewBuiltinClassInstance(cx, &GeneratorClass);
JSObject *obj = NewBuiltinClassInstance(cx, &js_GeneratorClass);
if (!obj)
return NULL;
@ -1308,7 +1309,7 @@ SendToGenerator(JSContext *cx, JSGeneratorOp op, JSObject *obj,
static JS_REQUIRES_STACK JSBool
CloseGenerator(JSContext *cx, JSObject *obj)
{
JS_ASSERT(obj->isGenerator());
JS_ASSERT(obj->getClass() == &js_GeneratorClass);
JSGenerator *gen = (JSGenerator *) obj->getPrivate();
if (!gen) {
@ -1333,8 +1334,8 @@ generator_op(JSContext *cx, JSGeneratorOp op, Value *vp, uintN argc)
JSObject *obj = ToObject(cx, &vp[1]);
if (!obj)
return JS_FALSE;
if (!obj->isGenerator()) {
ReportIncompatibleMethod(cx, vp, &GeneratorClass);
if (obj->getClass() != &js_GeneratorClass) {
ReportIncompatibleMethod(cx, vp, &js_GeneratorClass);
return JS_FALSE;
}
@ -1425,11 +1426,11 @@ static JSFunctionSpec generator_methods[] = {
static bool
InitIteratorClass(JSContext *cx, GlobalObject *global)
{
JSObject *iteratorProto = global->createBlankPrototype(cx, &IteratorClass);
JSObject *iteratorProto = global->createBlankPrototype(cx, &js_IteratorClass);
if (!iteratorProto)
return false;
JSFunction *ctor = global->createConstructor(cx, Iterator, &IteratorClass,
JSFunction *ctor = global->createConstructor(cx, Iterator, &js_IteratorClass,
CLASS_ATOM(cx, Iterator), 2);
if (!ctor)
return false;
@ -1447,7 +1448,7 @@ static bool
InitGeneratorClass(JSContext *cx, GlobalObject *global)
{
#if JS_HAS_GENERATORS
JSObject *proto = global->createBlankPrototype(cx, &GeneratorClass);
JSObject *proto = global->createBlankPrototype(cx, &js_GeneratorClass);
if (!proto)
return false;
@ -1464,7 +1465,7 @@ InitGeneratorClass(JSContext *cx, GlobalObject *global)
static JSObject *
InitStopIterationClass(JSContext *cx, GlobalObject *global)
{
JSObject *proto = global->createBlankPrototype(cx, &StopIterationClass);
JSObject *proto = global->createBlankPrototype(cx, &js_StopIterationClass);
if (!proto || !proto->freeze(cx))
return NULL;
@ -1472,7 +1473,7 @@ InitStopIterationClass(JSContext *cx, GlobalObject *global)
if (!DefineConstructorAndPrototype(cx, global, JSProto_StopIteration, proto, proto))
return NULL;
MarkStandardClassInitializedNoProto(global, &StopIterationClass);
MarkStandardClassInitializedNoProto(global, &js_StopIterationClass);
return proto;
}

View File

@ -231,16 +231,16 @@ js_LiveFrameIfGenerator(js::StackFrame *fp)
#endif
namespace js {
extern js::Class js_GeneratorClass;
extern js::Class js_IteratorClass;
extern js::Class js_StopIterationClass;
static inline bool
IsStopIteration(const js::Value &v)
js_ValueIsStopIteration(const js::Value &v)
{
return v.isObject() && v.toObject().isStopIteration();
return v.isObject() && v.toObject().getClass() == &js_StopIterationClass;
}
} /* namespace js */
extern JSObject *
js_InitIteratorClasses(JSContext *cx, JSObject *obj);

View File

@ -106,7 +106,7 @@ MathCache::MathCache() {
JS_ASSERT(hash(-0.0) != hash(+0.0));
}
Class js::MathClass = {
Class js_MathClass = {
js_Math_str,
JSCLASS_HAS_CACHED_PROTO(JSProto_Math),
PropertyStub, /* addProperty */
@ -865,7 +865,7 @@ js_IsMathFunction(JSNative native)
JSObject *
js_InitMathClass(JSContext *cx, JSObject *obj)
{
JSObject *Math = NewNonFunction<WithProto::Class>(cx, &MathClass, NULL, obj);
JSObject *Math = NewNonFunction<WithProto::Class>(cx, &js_MathClass, NULL, obj);
if (!Math || !Math->setSingletonType(cx))
return NULL;
@ -879,7 +879,7 @@ js_InitMathClass(JSContext *cx, JSObject *obj)
if (!JS_DefineConstDoubles(cx, Math, math_constants))
return NULL;
MarkStandardClassInitializedNoProto(obj, &MathClass);
MarkStandardClassInitializedNoProto(obj, &js_MathClass);
return Math;
}

View File

@ -82,6 +82,8 @@ class MathCache
* JS math functions.
*/
extern js::Class js_MathClass;
extern JSObject *
js_InitMathClass(JSContext *cx, JSObject *obj);

View File

@ -559,7 +559,7 @@ static JSFunctionSpec number_functions[] = {
JS_FS_END
};
Class js::NumberClass = {
Class js_NumberClass = {
js_Number_str,
JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_HAS_CACHED_PROTO(JSProto_Number),
PropertyStub, /* addProperty */
@ -588,7 +588,7 @@ Number(JSContext *cx, uintN argc, Value *vp)
if (!isConstructing)
return true;
JSObject *obj = NewBuiltinClassInstance(cx, &NumberClass);
JSObject *obj = NewBuiltinClassInstance(cx, &js_NumberClass);
if (!obj)
return false;
obj->setPrimitiveThis(vp[0]);
@ -612,7 +612,7 @@ num_toSource(JSContext *cx, uintN argc, Value *vp)
}
char buf[64];
JS_snprintf(buf, sizeof buf, "(new %s(%s))", NumberClass.name, numStr);
JS_snprintf(buf, sizeof buf, "(new %s(%s))", js_NumberClass.name, numStr);
JSString *str = js_NewStringCopyZ(cx, buf);
if (!str)
return false;
@ -1106,7 +1106,7 @@ js_InitNumberClass(JSContext *cx, JSObject *obj)
/* XXX must do at least once per new thread, so do it per JSContext... */
FIX_FPU();
proto = js_InitClass(cx, obj, NULL, &NumberClass, Number, 1,
proto = js_InitClass(cx, obj, NULL, &js_NumberClass, Number, 1,
NULL, number_methods, NULL, NULL);
if (!proto || !(ctor = JS_GetConstructor(cx, proto)))
return NULL;

View File

@ -160,6 +160,14 @@ FinishRuntimeNumberState(JSRuntime *rt);
} /* namespace js */
/* Initialize the Number class, returning its prototype object. */
extern js::Class js_NumberClass;
inline bool
JSObject::isNumber() const
{
return getClass() == &js_NumberClass;
}
extern JSObject *
js_InitNumberClass(JSContext *cx, JSObject *obj);

View File

@ -115,7 +115,7 @@ using namespace js::types;
JS_FRIEND_DATA(js::Shape) Shape::sharedNonNative(SHAPELESS);
Class js::ObjectClass = {
Class js_ObjectClass = {
js_Object_str,
JSCLASS_HAS_CACHED_PROTO(JSProto_Object),
PropertyStub, /* addProperty */
@ -1800,7 +1800,7 @@ PropDesc::initFromPropertyDescriptor(const PropertyDescriptor &desc)
bool
PropDesc::makeObject(JSContext *cx)
{
JSObject *obj = NewBuiltinClassInstance(cx, &ObjectClass);
JSObject *obj = NewBuiltinClassInstance(cx, &js_ObjectClass);
if (!obj)
return false;
@ -2630,7 +2630,7 @@ obj_create(JSContext *cx, uintN argc, Value *vp)
* Use the callee's global as the parent of the new object to avoid dynamic
* scoping (i.e., using the caller's global).
*/
JSObject *obj = NewNonFunction<WithProto::Given>(cx, &ObjectClass, proto,
JSObject *obj = NewNonFunction<WithProto::Given>(cx, &js_ObjectClass, proto,
vp->toObject().getGlobal());
if (!obj)
return JS_FALSE;
@ -2913,8 +2913,8 @@ js_Object(JSContext *cx, uintN argc, Value *vp)
if (!obj) {
/* Make an object whether this was called with 'new' or not. */
JS_ASSERT(!argc || vp[2].isNull() || vp[2].isUndefined());
gc::AllocKind kind = NewObjectGCKind(cx, &ObjectClass);
obj = NewBuiltinClassInstance(cx, &ObjectClass, kind);
gc::AllocKind kind = NewObjectGCKind(cx, &js_ObjectClass);
obj = NewBuiltinClassInstance(cx, &js_ObjectClass, kind);
if (!obj)
return JS_FALSE;
TypeObject *type = GetTypeCallerInitObject(cx, JSProto_Object);
@ -2966,8 +2966,8 @@ js_CreateThis(JSContext *cx, JSObject *callee)
{
Class *clasp = callee->getClass();
Class *newclasp = &ObjectClass;
if (clasp == &FunctionClass) {
Class *newclasp = &js_ObjectClass;
if (clasp == &js_FunctionClass) {
JSFunction *fun = callee->getFunctionPrivate();
if (fun->isNative() && fun->u.n.clasp)
newclasp = fun->u.n.clasp;
@ -3002,7 +3002,7 @@ CreateThisForFunctionWithType(JSContext *cx, types::TypeObject *type, JSObject *
return res;
}
gc::AllocKind kind = NewObjectGCKind(cx, &ObjectClass);
gc::AllocKind kind = NewObjectGCKind(cx, &js_ObjectClass);
return NewObjectWithType(cx, type, parent, kind);
}
@ -3018,8 +3018,8 @@ js_CreateThisForFunctionWithProto(JSContext *cx, JSObject *callee, JSObject *pro
return NULL;
res = CreateThisForFunctionWithType(cx, type, callee->getParent());
} else {
gc::AllocKind kind = NewObjectGCKind(cx, &ObjectClass);
res = NewNonFunction<WithProto::Class>(cx, &ObjectClass, proto, callee->getParent(), kind);
gc::AllocKind kind = NewObjectGCKind(cx, &js_ObjectClass);
res = NewNonFunction<WithProto::Class>(cx, &js_ObjectClass, proto, callee->getParent(), kind);
}
if (res && cx->typeInferenceEnabled())
@ -3065,8 +3065,8 @@ js_CreateThisForFunction(JSContext *cx, JSObject *callee, bool newType)
JSObject* FASTCALL
js_Object_tn(JSContext* cx, JSObject* proto)
{
JS_ASSERT(!(ObjectClass.flags & JSCLASS_HAS_PRIVATE));
return NewObjectWithClassProto(cx, &ObjectClass, proto, FINALIZE_OBJECT8);
JS_ASSERT(!(js_ObjectClass.flags & JSCLASS_HAS_PRIVATE));
return NewObjectWithClassProto(cx, &js_ObjectClass, proto, FINALIZE_OBJECT8);
}
JS_DEFINE_TRCINFO_1(js_Object,
@ -3078,7 +3078,7 @@ js_InitializerObject(JSContext* cx, JSObject *proto, JSObject *baseobj)
{
if (!baseobj) {
gc::AllocKind kind = GuessObjectGCKind(0, false);
return NewObjectWithClassProto(cx, &ObjectClass, proto, kind);
return NewObjectWithClassProto(cx, &js_ObjectClass, proto, kind);
}
/* :FIXME: bug 637856 new Objects do not have the right type when created on trace. */
@ -3129,8 +3129,8 @@ js_CreateThisFromTrace(JSContext *cx, JSObject *ctor, uintN protoSlot)
return NULL;
}
gc::AllocKind kind = NewObjectGCKind(cx, &ObjectClass);
return NewNativeClassInstance(cx, &ObjectClass, proto, parent, kind);
gc::AllocKind kind = NewObjectGCKind(cx, &js_ObjectClass);
return NewNativeClassInstance(cx, &js_ObjectClass, proto, parent, kind);
}
JS_DEFINE_CALLINFO_3(extern, CONSTRUCTOR_RETRY, js_CreateThisFromTrace, CONTEXT, OBJECT, UINTN, 0,
nanojit::ACCSET_STORE_ANY)
@ -3309,7 +3309,7 @@ with_ThisObject(JSContext *cx, JSObject *obj)
return obj->getWithThis();
}
Class js::WithClass = {
Class js_WithClass = {
"With",
JSCLASS_HAS_PRIVATE | JSCLASS_HAS_RESERVED_SLOTS(2) | JSCLASS_IS_ANONYMOUS,
PropertyStub, /* addProperty */
@ -3359,7 +3359,7 @@ js_NewWithObject(JSContext *cx, JSObject *proto, JSObject *parent, jsint depth)
StackFrame *priv = js_FloatingFrameIfGenerator(cx, cx->fp());
obj->init(cx, &WithClass, type, parent, priv, false);
obj->init(cx, &js_WithClass, type, parent, priv, false);
EmptyShape *emptyWithShape = EmptyShape::getEmptyWithShape(cx);
if (!emptyWithShape)
@ -3393,7 +3393,7 @@ js_NewBlockObject(JSContext *cx)
EmptyShape *emptyBlockShape = EmptyShape::getEmptyBlockShape(cx);
if (!emptyBlockShape)
return NULL;
blockObj->init(cx, &BlockClass, &emptyTypeObject, NULL, NULL, false);
blockObj->init(cx, &js_BlockClass, &emptyTypeObject, NULL, NULL, false);
blockObj->setMap(emptyBlockShape);
return blockObj;
@ -3483,7 +3483,7 @@ block_getProperty(JSContext *cx, JSObject *obj, jsid id, Value *vp)
}
/* Values are in slots immediately following the class-reserved ones. */
JS_ASSERT(obj->getSlot(JSSLOT_FREE(&BlockClass) + index) == *vp);
JS_ASSERT(obj->getSlot(JSSLOT_FREE(&js_BlockClass) + index) == *vp);
return true;
}
@ -3516,7 +3516,7 @@ JSObject::defineBlockVariable(JSContext *cx, jsid id, intN index)
JS_ASSERT(isStaticBlock());
/* Use JSPROP_ENUMERATE to aid the disassembler. */
uint32 slot = JSSLOT_FREE(&BlockClass) + index;
uint32 slot = JSSLOT_FREE(&js_BlockClass) + index;
const Shape *shape = addProperty(cx, id,
block_getProperty, block_setProperty,
slot, JSPROP_ENUMERATE | JSPROP_PERMANENT,
@ -3985,7 +3985,7 @@ js_XDRBlockObject(JSXDRState *xdr, JSObject **objp)
#endif
Class js::BlockClass = {
Class js_BlockClass = {
"Block",
JSCLASS_HAS_PRIVATE | JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_IS_ANONYMOUS,
PropertyStub, /* addProperty */
@ -4000,7 +4000,7 @@ Class js::BlockClass = {
JSObject *
js_InitObjectClass(JSContext *cx, JSObject *obj)
{
JSObject *proto = js_InitClass(cx, obj, NULL, &ObjectClass, js_Object, 1,
JSObject *proto = js_InitClass(cx, obj, NULL, &js_ObjectClass, js_Object, 1,
object_props, object_methods, NULL, object_static_methods);
if (!proto)
return NULL;
@ -4102,10 +4102,10 @@ DefineConstructorAndPrototype(JSContext *cx, JSObject *obj, JSProtoKey key, JSAt
* otherwise-uninitialized global.
*
* 3. NewObject allocating a JSFunction-sized GC-thing when clasp is
* &FunctionClass, not a JSObject-sized (smaller) GC-thing.
* &js_FunctionClass, not a JSObject-sized (smaller) GC-thing.
*
* The JS_NewObjectForGivenProto and JS_NewObject APIs also allow clasp to
* be &FunctionClass (we could break compatibility easily). But fixing
* be &js_FunctionClass (we could break compatibility easily). But fixing
* (3) is not enough without addressing the bootstrapping dependency on (1)
* and (2).
*/
@ -4124,7 +4124,7 @@ DefineConstructorAndPrototype(JSContext *cx, JSObject *obj, JSProtoKey key, JSAt
if (!proto->setSingletonType(cx))
return NULL;
if (clasp == &ArrayClass && !proto->makeDenseArraySlow(cx))
if (clasp == &js_ArrayClass && !proto->makeDenseArraySlow(cx))
return NULL;
TypeObject *type = proto->getNewType(cx);
@ -5098,7 +5098,7 @@ DefineNativeProperty(JSContext *cx, JSObject *obj, jsid id, const Value &value,
if (!shape) {
/* Add a new property, or replace an existing one of the same id. */
if (defineHow & DNP_SET_METHOD) {
JS_ASSERT(clasp == &ObjectClass);
JS_ASSERT(clasp == &js_ObjectClass);
JS_ASSERT(IsFunctionObject(value));
JS_ASSERT(!(attrs & (JSPROP_GETTER | JSPROP_SETTER)));
JS_ASSERT(!getter && !setter);
@ -5400,9 +5400,10 @@ js_FindPropertyHelper(JSContext *cx, jsid id, bool cacheResult, bool global,
if (prop) {
#ifdef DEBUG
if (parent) {
Class *clasp = obj->getClass();
JS_ASSERT(pobj->isNative());
JS_ASSERT(pobj->getClass() == obj->getClass());
if (obj->isBlock()) {
JS_ASSERT(pobj->getClass() == clasp);
if (clasp == &js_BlockClass) {
/*
* A block instance on the scope chain is immutable and
* shares its shape with the compile-time prototype. Thus
@ -6295,9 +6296,9 @@ DefaultValue(JSContext *cx, JSObject *obj, JSType hint, Value *vp)
Class *clasp = obj->getClass();
if (hint == JSTYPE_STRING) {
/* Optimize (new String(...)).toString(). */
if (clasp == &StringClass &&
if (clasp == &js_StringClass &&
ClassMethodIsNative(cx, obj,
&StringClass,
&js_StringClass,
ATOM_TO_JSID(cx->runtime->atomState.toStringAtom),
js_str_toString)) {
*vp = obj->getPrimitiveThis();
@ -6315,12 +6316,12 @@ DefaultValue(JSContext *cx, JSObject *obj, JSType hint, Value *vp)
return true;
} else {
/* Optimize (new String(...)).valueOf(). */
if ((clasp == &StringClass &&
ClassMethodIsNative(cx, obj, &StringClass,
if ((clasp == &js_StringClass &&
ClassMethodIsNative(cx, obj, &js_StringClass,
ATOM_TO_JSID(cx->runtime->atomState.valueOfAtom),
js_str_toString)) ||
(clasp == &NumberClass &&
ClassMethodIsNative(cx, obj, &NumberClass,
(clasp == &js_NumberClass &&
ClassMethodIsNative(cx, obj, &js_NumberClass,
ATOM_TO_JSID(cx->runtime->atomState.valueOfAtom),
js_num_valueOf))) {
*vp = obj->getPrimitiveThis();
@ -6389,7 +6390,7 @@ CheckAccess(JSContext *cx, JSObject *obj, jsid id, JSAccessMode mode,
JSSecurityCallbacks *callbacks;
CheckAccessOp check;
while (JS_UNLIKELY(obj->isWith()))
while (JS_UNLIKELY(obj->getClass() == &js_WithClass))
obj = obj->getProto();
writing = (mode & JSACC_WRITE) != 0;
@ -6541,7 +6542,7 @@ PrimitiveToObject(JSContext *cx, const Value &v)
return StringObject::create(cx, v.toString());
JS_ASSERT(v.isNumber() || v.isBoolean());
Class *clasp = v.isNumber() ? &NumberClass : &BooleanClass;
Class *clasp = v.isNumber() ? &js_NumberClass : &js_BooleanClass;
JSObject *obj = NewBuiltinClassInstance(cx, clasp);
if (!obj)
return NULL;
@ -6939,7 +6940,7 @@ dumpValue(const Value &v)
Class *clasp = obj->getClass();
fprintf(stderr, "<%s%s at %p>",
clasp->name,
(clasp == &ObjectClass) ? "" : " object",
(clasp == &js_ObjectClass) ? "" : " object",
(void *) obj);
} else if (v.isBoolean()) {
if (v.toBoolean())

View File

@ -59,15 +59,11 @@
#include "jsvector.h"
#include "jscell.h"
namespace nanojit { class ValidateWriter; }
namespace js {
class AutoPropDescArrayRooter;
class JSProxyHandler;
class RegExp;
class AutoPropDescArrayRooter;
struct GCMarker;
struct NativeIterator;
namespace mjit { class Compiler; }
@ -288,54 +284,26 @@ js_TypeOf(JSContext *cx, JSObject *obj);
namespace js {
/* ES5 8.12.8. */
extern JSBool
DefaultValue(JSContext *cx, JSObject *obj, JSType hint, Value *vp);
struct NativeIterator;
class RegExp;
extern JS_FRIEND_DATA(Class) AnyNameClass;
extern JS_FRIEND_DATA(Class) AttributeNameClass;
extern JS_FRIEND_DATA(Class) CallClass;
extern JS_FRIEND_DATA(Class) DeclEnvClass;
extern JS_FRIEND_DATA(Class) FunctionClass;
extern JS_FRIEND_DATA(Class) FunctionProxyClass;
extern JS_FRIEND_DATA(Class) NamespaceClass;
extern JS_FRIEND_DATA(Class) OuterWindowProxyClass;
extern JS_FRIEND_DATA(Class) ObjectProxyClass;
extern JS_FRIEND_DATA(Class) QNameClass;
extern JS_FRIEND_DATA(Class) ScriptClass;
extern JS_FRIEND_DATA(Class) XMLClass;
extern Class ArrayClass;
extern Class ArrayBufferClass;
extern Class BlockClass;
extern Class BooleanClass;
extern Class CallableObjectClass;
extern Class DateClass;
extern Class ErrorClass;
extern Class GeneratorClass;
extern Class IteratorClass;
extern Class JSONClass;
extern Class MathClass;
extern Class NumberClass;
extern Class NormalArgumentsObjectClass;
extern Class ObjectClass;
extern Class ProxyClass;
extern Class RegExpClass;
extern Class SlowArrayClass;
extern Class StopIterationClass;
extern Class StringClass;
extern Class StrictArgumentsObjectClass;
extern Class WeakMapClass;
extern Class WithClass;
extern Class XMLFilterClass;
class ArgumentsObject;
class GlobalObject;
class ArgumentsObject;
class NormalArgumentsObject;
class StrictArgumentsObject;
class StringObject;
} /* namespace js */
/* ES5 8.12.8. */
extern JSBool
DefaultValue(JSContext *cx, JSObject *obj, JSType hint, Value *vp);
}
struct JSFunction;
namespace nanojit {
class ValidateWriter;
}
/*
* JSObject struct, with members sized to fit in 32 bytes on 32-bit targets,
@ -408,9 +376,9 @@ struct JSObject : js::gc::Cell {
*/
js::Shape *lastProp;
private:
js::Class *clasp;
private:
inline void setLastProperty(const js::Shape *shape);
inline void removeLastProperty();
@ -502,7 +470,6 @@ struct JSObject : js::gc::Cell {
inline bool isNative() const;
inline bool isNewborn() const;
void setClass(js::Class *c) { clasp = c; }
js::Class *getClass() const { return clasp; }
JSClass *getJSClass() const { return Jsvalify(clasp); }
@ -1231,10 +1198,10 @@ struct JSObject : js::gc::Cell {
/*
* Slots for XML-related classes are as follows:
* - NamespaceClass.base reserves the *_NAME_* and *_NAMESPACE_* slots.
* - QNameClass.base, AttributeNameClass, AnyNameClass reserve
* - js_NamespaceClass.base reserves the *_NAME_* and *_NAMESPACE_* slots.
* - js_QNameClass.base, js_AttributeNameClass, js_AnyNameClass reserve
* the *_NAME_* and *_QNAME_* slots.
* - Others (XMLClass, js_XMLFilterClass) don't reserve any slots.
* - Others (js_XMLClass, js_XMLFilterClass) don't reserve any slots.
*/
private:
static const uint32 JSSLOT_NAME_PREFIX = 0; // shared
@ -1464,57 +1431,43 @@ struct JSObject : js::gc::Cell {
inline bool canHaveMethodBarrier() const;
inline bool isArguments() const { return isNormalArguments() || isStrictArguments(); }
inline bool isArrayBuffer() const { return clasp == &js::ArrayBufferClass; }
inline bool isNormalArguments() const { return clasp == &js::NormalArgumentsObjectClass; }
inline bool isStrictArguments() const { return clasp == &js::StrictArgumentsObjectClass; }
inline bool isArray() const { return isSlowArray() || isDenseArray(); }
inline bool isDenseArray() const { return clasp == &js::ArrayClass; }
inline bool isSlowArray() const { return clasp == &js::SlowArrayClass; }
inline bool isNumber() const { return clasp == &js::NumberClass; }
inline bool isBoolean() const { return clasp == &js::BooleanClass; }
inline bool isString() const { return clasp == &js::StringClass; }
inline bool isPrimitive() const { return isNumber() || isString() || isBoolean(); }
inline bool isDate() const { return clasp == &js::DateClass; }
inline bool isFunction() const { return clasp == &js::FunctionClass; }
inline bool isObject() const { return clasp == &js::ObjectClass; }
inline bool isWith() const { return clasp == &js::WithClass; }
inline bool isBlock() const { return clasp == &js::BlockClass; }
inline bool isStaticBlock() const { return isBlock() && !getProto(); }
inline bool isClonedBlock() const { return isBlock() && !!getProto(); }
inline bool isCall() const { return clasp == &js::CallClass; }
inline bool isDeclEnv() const { return clasp == &js::DeclEnvClass; }
inline bool isRegExp() const { return clasp == &js::RegExpClass; }
inline bool isScript() const { return clasp == &js::ScriptClass; }
inline bool isGenerator() const { return clasp == &js::GeneratorClass; }
inline bool isIterator() const { return clasp == &js::IteratorClass; }
inline bool isStopIteration() const { return clasp == &js::StopIterationClass; }
inline bool isError() const { return clasp == &js::ErrorClass; }
inline bool isXML() const { return clasp == &js::XMLClass; }
inline bool isNamespace() const { return clasp == &js::NamespaceClass; }
inline bool isWeakMap() const { return clasp == &js::WeakMapClass; }
inline bool isFunctionProxy() const { return clasp == &js::FunctionProxyClass; }
inline bool isProxy() const { return isObjectProxy() || isFunctionProxy(); }
inline bool isArguments() const;
inline bool isNormalArguments() const;
inline bool isStrictArguments() const;
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 isObject() const;
inline bool isWith() const;
inline bool isBlock() const;
inline bool isStaticBlock() const;
inline bool isClonedBlock() const;
inline bool isCall() const;
inline bool isRegExp() const;
inline bool isScript() const;
inline bool isError() const;
inline bool isXML() const;
inline bool isXMLId() const;
inline bool isNamespace() const;
inline bool isQName() const;
inline bool isWeakMap() const;
inline bool isXMLId() const {
return clasp == &js::QNameClass || clasp == &js::AttributeNameClass || clasp == &js::AnyNameClass;
}
inline bool isQName() const {
return clasp == &js::QNameClass || clasp == &js::AttributeNameClass || clasp == &js::AnyNameClass;
}
inline bool isObjectProxy() const {
return clasp == &js::ObjectProxyClass || clasp == &js::OuterWindowProxyClass;
}
inline bool isProxy() const;
inline bool isObjectProxy() const;
inline bool isFunctionProxy() const;
inline bool isArrayBuffer() const;
JS_FRIEND_API(bool) isWrapper() const;
bool isCrossCompartmentWrapper() const;
JS_FRIEND_API(JSObject *) unwrap(uintN *flagsp = NULL);
inline void initArrayClass();
/*** For jit compiler: ***/
static size_t offsetOfClassPointer() { return offsetof(JSObject, clasp); }
};
/* Check alignment for any fixed slots allocated after the object. */
@ -1613,8 +1566,42 @@ class ValueArray {
ValueArray(js::Value *v, size_t c) : array(v), length(c) {}
};
extern js::Class js_ArrayClass, js_SlowArrayClass, js_ArrayBufferClass;
inline bool
JSObject::isDenseArray() const
{
return getClass() == &js_ArrayClass;
}
inline bool
JSObject::isSlowArray() const
{
return getClass() == &js_SlowArrayClass;
}
inline bool
JSObject::isArray() const
{
return isDenseArray() || isSlowArray();
}
inline bool
JSObject::isArrayBuffer() const
{
return getClass() == &js_ArrayBufferClass;
}
extern js::Class js_ObjectClass;
extern js::Class js_WithClass;
extern js::Class js_BlockClass;
inline bool JSObject::isObject() const { return getClass() == &js_ObjectClass; }
inline bool JSObject::isWith() const { return getClass() == &js_WithClass; }
inline bool JSObject::isBlock() const { return getClass() == &js_BlockClass; }
/*
* Block scope object macros. The slots reserved by BlockClass are:
* Block scope object macros. The slots reserved by js_BlockClass are:
*
* private StackFrame * active frame pointer or null
* JSSLOT_BLOCK_DEPTH int depth of block slots in frame
@ -1838,6 +1825,9 @@ extern JSBool
js_DefineOwnProperty(JSContext *cx, JSObject *obj, jsid id,
const js::Value &descriptor, JSBool *bp);
extern JS_FRIEND_DATA(js::Class) js_CallClass;
extern JS_FRIEND_DATA(js::Class) js_DeclEnvClass;
namespace js {
/*
@ -1906,9 +1896,9 @@ IsCacheableNonGlobalScope(JSObject *obj)
JS_ASSERT(obj->getParent());
js::Class *clasp = obj->getClass();
bool cacheable = (clasp == &CallClass ||
clasp == &BlockClass ||
clasp == &DeclEnvClass);
bool cacheable = (clasp == &js_CallClass ||
clasp == &js_BlockClass ||
clasp == &js_DeclEnvClass);
JS_ASSERT_IF(cacheable, !obj->getOps()->lookupProperty);
return cacheable;

View File

@ -198,7 +198,7 @@ JSObject::finalize(JSContext *cx)
inline void
JSObject::initCall(JSContext *cx, const js::Bindings &bindings, JSObject *parent)
{
init(cx, &js::CallClass, &js::types::emptyTypeObject, parent, NULL, false);
init(cx, &js_CallClass, &js::types::emptyTypeObject, parent, NULL, false);
lastProp = bindings.lastShape();
/*
@ -218,7 +218,7 @@ JSObject::initCall(JSContext *cx, const js::Bindings &bindings, JSObject *parent
inline void
JSObject::initClonedBlock(JSContext *cx, js::types::TypeObject *type, js::StackFrame *frame)
{
init(cx, &js::BlockClass, type, NULL, frame, false);
init(cx, &js_BlockClass, type, NULL, frame, false);
/* Cloned blocks copy their prototype's map; it had better be shareable. */
JS_ASSERT(!getProto()->inDictionaryMode() || getProto()->lastProp->frozen());
@ -382,6 +382,12 @@ JSObject::canHaveMethodBarrier() const
return isObject() || isFunction() || isPrimitive() || isDate();
}
inline bool
JSObject::isPrimitive() const
{
return isNumber() || isString() || isBoolean();
}
inline const js::Value &
JSObject::getPrimitiveThis() const
{
@ -905,7 +911,7 @@ JSObject::init(JSContext *cx, js::Class *aclasp, js::types::TypeObject *type,
clasp = aclasp;
flags = capacity << FIXED_SLOTS_SHIFT;
JS_ASSERT(denseArray == (aclasp == &js::ArrayClass));
JS_ASSERT(denseArray == (aclasp == &js_ArrayClass));
#ifdef DEBUG
/*
@ -1162,10 +1168,22 @@ js_IsCallable(const js::Value &v)
return v.isObject() && v.toObject().isCallable();
}
inline bool
JSObject::isStaticBlock() const
{
return isBlock() && !getProto();
}
inline bool
JSObject::isClonedBlock() const
{
return isBlock() && !!getProto();
}
inline JSObject *
js_UnwrapWithObject(JSContext *cx, JSObject *withobj)
{
JS_ASSERT(withobj->isWith());
JS_ASSERT(withobj->getClass() == &js_WithClass);
return withobj->getProto();
}
@ -1301,7 +1319,7 @@ NewNativeClassInstance(JSContext *cx, Class *clasp, JSObject *proto,
* Default parent to the parent of the prototype, which was set from
* the parent of the prototype's constructor.
*/
bool denseArray = (clasp == &ArrayClass);
bool denseArray = (clasp == &js_ArrayClass);
obj->init(cx, clasp, type, parent, NULL, denseArray);
JS_ASSERT(type->canProvideEmptyShape(clasp));
@ -1469,7 +1487,7 @@ NewObject(JSContext *cx, js::Class *clasp, JSObject *proto, JSObject *parent,
*/
obj->init(cx, clasp, type,
(!parent && proto) ? proto->getParent() : parent,
NULL, clasp == &ArrayClass);
NULL, clasp == &js_ArrayClass);
if (clasp->isNative()) {
if (!InitScopeForObject(cx, obj, clasp, type, kind)) {
@ -1492,14 +1510,14 @@ NewFunction(JSContext *cx, js::GlobalObject &global)
JSObject *proto;
if (!js_GetClassPrototype(cx, &global, JSProto_Function, &proto))
return NULL;
return detail::NewObject<WithProto::Given, true>(cx, &FunctionClass, proto, &global,
return detail::NewObject<WithProto::Given, true>(cx, &js_FunctionClass, proto, &global,
gc::FINALIZE_OBJECT2);
}
static JS_ALWAYS_INLINE JSObject *
NewFunction(JSContext *cx, JSObject *parent)
{
return detail::NewObject<WithProto::Class, true>(cx, &FunctionClass, NULL, parent,
return detail::NewObject<WithProto::Class, true>(cx, &js_FunctionClass, NULL, parent,
gc::FINALIZE_OBJECT2);
}
@ -1524,7 +1542,7 @@ static JS_ALWAYS_INLINE JSObject *
NewObject(JSContext *cx, js::Class *clasp, JSObject *proto, JSObject *parent,
gc::AllocKind kind)
{
if (clasp == &FunctionClass)
if (clasp == &js_FunctionClass)
return detail::NewObject<withProto, true>(cx, clasp, proto, parent, kind);
return detail::NewObject<withProto, false>(cx, clasp, proto, parent, kind);
}
@ -1546,7 +1564,7 @@ NewObjectWithType(JSContext *cx, types::TypeObject *type, JSObject *parent, gc::
{
JS_ASSERT(type == type->proto->newType);
if (CanBeFinalizedInBackground(kind, &ObjectClass))
if (CanBeFinalizedInBackground(kind, &js_ObjectClass))
kind = GetBackgroundAllocKind(kind);
JSObject* obj = js_NewGCObject(cx, kind);
@ -1557,11 +1575,11 @@ NewObjectWithType(JSContext *cx, types::TypeObject *type, JSObject *parent, gc::
* Default parent to the parent of the prototype, which was set from
* the parent of the prototype's constructor.
*/
obj->init(cx, &ObjectClass, type,
obj->init(cx, &js_ObjectClass, type,
(!parent && type->proto) ? type->proto->getParent() : parent,
NULL, false);
if (!InitScopeForObject(cx, obj, &ObjectClass, type, kind)) {
if (!InitScopeForObject(cx, obj, &js_ObjectClass, type, kind)) {
obj = NULL;
goto out;
}
@ -1595,9 +1613,9 @@ GuessObjectGCKind(size_t numSlots, bool isArray)
static inline gc::AllocKind
NewObjectGCKind(JSContext *cx, js::Class *clasp)
{
if (clasp == &ArrayClass || clasp == &SlowArrayClass)
if (clasp == &js_ArrayClass || clasp == &js_SlowArrayClass)
return gc::FINALIZE_OBJECT8;
if (clasp == &FunctionClass)
if (clasp == &js_FunctionClass)
return gc::FINALIZE_OBJECT2;
return gc::FINALIZE_OBJECT4;
}
@ -1628,10 +1646,10 @@ NewObjectWithClassProto(JSContext *cx, Class *clasp, JSObject *proto,
static inline JSObject *
CopyInitializerObject(JSContext *cx, JSObject *baseobj, types::TypeObject *type)
{
JS_ASSERT(baseobj->getClass() == &ObjectClass);
JS_ASSERT(baseobj->getClass() == &js_ObjectClass);
JS_ASSERT(!baseobj->inDictionaryMode());
JSObject *obj = NewBuiltinClassInstance(cx, &ObjectClass, baseobj->getAllocKind());
JSObject *obj = NewBuiltinClassInstance(cx, &js_ObjectClass, baseobj->getAllocKind());
if (!obj || !obj->ensureSlots(cx, baseobj->numSlots()))
return NULL;

View File

@ -74,7 +74,7 @@ using namespace js;
using namespace js::gc;
using namespace js::types;
Class js::JSONClass = {
Class js_JSONClass = {
js_JSON_str,
JSCLASS_HAS_CACHED_PROTO(JSProto_JSON),
PropertyStub, /* addProperty */
@ -344,17 +344,17 @@ PreprocessValue(JSContext *cx, JSObject *holder, jsid key, Value *vp, StringifyC
if (vp->isObject()) {
JSObject *obj = &vp->toObject();
Class *clasp = obj->getClass();
if (clasp == &NumberClass) {
if (clasp == &js_NumberClass) {
double d;
if (!ToNumber(cx, *vp, &d))
return false;
vp->setNumber(d);
} else if (clasp == &StringClass) {
} else if (clasp == &js_StringClass) {
JSString *str = js_ValueToString(cx, *vp);
if (!str)
return false;
vp->setString(str);
} else if (clasp == &BooleanClass) {
} else if (clasp == &js_BooleanClass) {
*vp = obj->getPrimitiveThis();
JS_ASSERT(vp->isBoolean());
}
@ -725,7 +725,7 @@ js_Stringify(JSContext *cx, Value *vp, JSObject *replacer, Value space, StringBu
}
/* Step 9. */
JSObject *wrapper = NewBuiltinClassInstance(cx, &ObjectClass);
JSObject *wrapper = NewBuiltinClassInstance(cx, &js_ObjectClass);
if (!wrapper)
return false;
@ -856,7 +856,7 @@ static bool
Revive(JSContext *cx, const Value &reviver, Value *vp)
{
JSObject *obj = NewBuiltinClassInstance(cx, &ObjectClass);
JSObject *obj = NewBuiltinClassInstance(cx, &js_ObjectClass);
if (!obj)
return false;
@ -910,7 +910,7 @@ static JSFunctionSpec json_static_methods[] = {
JSObject *
js_InitJSONClass(JSContext *cx, JSObject *obj)
{
JSObject *JSON = NewNonFunction<WithProto::Class>(cx, &JSONClass, NULL, obj);
JSObject *JSON = NewNonFunction<WithProto::Class>(cx, &js_JSONClass, NULL, obj);
if (!JSON || !JSON->setSingletonType(cx))
return NULL;
@ -921,7 +921,7 @@ js_InitJSONClass(JSContext *cx, JSObject *obj)
if (!JS_DefineFunctions(cx, JSON, json_static_methods))
return NULL;
MarkStandardClassInitializedNoProto(obj, &JSONClass);
MarkStandardClassInitializedNoProto(obj, &js_JSONClass);
return JSON;
}

View File

@ -46,6 +46,8 @@
#define JSON_MAX_DEPTH 2048
#define JSON_PARSER_BUFSIZE 1024
extern js::Class js_JSONClass;
extern JSObject *
js_InitJSONClass(JSContext *cx, JSObject *obj);

View File

@ -634,7 +634,7 @@ JSONParser::parse(Value *vp)
}
case ObjectOpen: {
JSObject *obj = NewBuiltinClassInstance(cx, &ObjectClass);
JSObject *obj = NewBuiltinClassInstance(cx, &js_ObjectClass);
if (!obj || !valueStack.append(ObjectValue(*obj)))
return false;
token = advanceAfterObjectOpen();

View File

@ -366,7 +366,7 @@ ToDisassemblySource(JSContext *cx, jsval v, JSAutoByteString *bytes)
JSObject *obj = JSVAL_TO_OBJECT(v);
Class *clasp = obj->getClass();
if (clasp == &BlockClass) {
if (clasp == &js_BlockClass) {
char *source = JS_sprintf_append(NULL, "depth %d {", OBJ_BLOCK_DEPTH(cx, obj));
if (!source)
return false;
@ -393,7 +393,7 @@ ToDisassemblySource(JSContext *cx, jsval v, JSAutoByteString *bytes)
return true;
}
if (clasp == &FunctionClass) {
if (clasp == &js_FunctionClass) {
JSFunction *fun = obj->getFunctionPrivate();
JSString *str = JS_DecompileFunction(cx, fun, JS_DONT_PRETTY_PRINT);
if (!str)
@ -401,7 +401,7 @@ ToDisassemblySource(JSContext *cx, jsval v, JSAutoByteString *bytes)
return bytes->encode(cx, str);
}
if (clasp == &RegExpClass) {
if (clasp == &js_RegExpClass) {
AutoValueRooter tvr(cx);
if (!js_regexp_toString(cx, obj, tvr.addr()))
return false;

View File

@ -354,13 +354,13 @@ Probes::resizeHeap(JSCompartment *compartment, size_t oldSize, size_t newSize)
#ifdef INCLUDE_MOZILLA_DTRACE
static const char *ObjectClassname(JSObject *obj) {
if (!obj)
if (! obj)
return "(null object)";
Class *clasp = obj->getClass();
if (!clasp)
if (! clasp)
return "(null)";
const char *class_name = clasp->name;
if (!class_name)
if (! class_name)
return "(null class name)";
return class_name;
}

View File

@ -57,6 +57,8 @@
using namespace js;
using namespace js::gc;
namespace js {
static inline const Value &
GetCall(JSObject *proxy) {
JS_ASSERT(proxy->isFunctionProxy());
@ -411,7 +413,7 @@ ValueToBool(JSContext *cx, const Value &v, bool *bp)
return true;
}
static bool
bool
ArrayToIdVector(JSContext *cx, const Value &array, AutoIdVector &props)
{
JS_ASSERT(props.length() == 0);
@ -1025,7 +1027,7 @@ proxy_TypeOf(JSContext *cx, JSObject *proxy)
return JSProxy::typeOf(cx, proxy);
}
JS_FRIEND_DATA(Class) js::ObjectProxyClass = {
JS_FRIEND_API(Class) ObjectProxyClass = {
"Proxy",
Class::NON_NATIVE | JSCLASS_HAS_RESERVED_SLOTS(3),
PropertyStub, /* addProperty */
@ -1060,7 +1062,7 @@ JS_FRIEND_DATA(Class) js::ObjectProxyClass = {
}
};
JS_FRIEND_DATA(Class) js::OuterWindowProxyClass = {
JS_FRIEND_API(Class) OuterWindowProxyClass = {
"Proxy",
Class::NON_NATIVE | JSCLASS_HAS_RESERVED_SLOTS(3),
PropertyStub, /* addProperty */
@ -1100,7 +1102,7 @@ JS_FRIEND_DATA(Class) js::OuterWindowProxyClass = {
}
};
static JSBool
JSBool
proxy_Call(JSContext *cx, uintN argc, Value *vp)
{
JSObject *proxy = &JS_CALLEE(cx, vp).toObject();
@ -1108,7 +1110,7 @@ proxy_Call(JSContext *cx, uintN argc, Value *vp)
return JSProxy::call(cx, proxy, argc, vp);
}
static JSBool
JSBool
proxy_Construct(JSContext *cx, uintN argc, Value *vp)
{
JSObject *proxy = &JS_CALLEE(cx, vp).toObject();
@ -1117,7 +1119,7 @@ proxy_Construct(JSContext *cx, uintN argc, Value *vp)
return ok;
}
JS_FRIEND_DATA(Class) js::FunctionProxyClass = {
JS_FRIEND_API(Class) FunctionProxyClass = {
"Proxy",
Class::NON_NATIVE | JSCLASS_HAS_RESERVED_SLOTS(5),
PropertyStub, /* addProperty */
@ -1133,7 +1135,7 @@ JS_FRIEND_DATA(Class) js::FunctionProxyClass = {
proxy_Call,
proxy_Construct,
NULL, /* xdrObject */
FunctionClass.hasInstance,
js_FunctionClass.hasInstance,
proxy_TraceFunction, /* trace */
JS_NULL_CLASS_EXT,
{
@ -1153,7 +1155,7 @@ JS_FRIEND_DATA(Class) js::FunctionProxyClass = {
};
JS_FRIEND_API(JSObject *)
js::NewProxyObject(JSContext *cx, JSProxyHandler *handler, const Value &priv, JSObject *proto,
NewProxyObject(JSContext *cx, JSProxyHandler *handler, const Value &priv, JSObject *proto,
JSObject *parent, JSObject *call, JSObject *construct)
{
JS_ASSERT_IF(proto, cx->compartment == proto->compartment());
@ -1309,6 +1311,8 @@ static JSFunctionSpec static_methods[] = {
JS_FS_END
};
extern Class CallableObjectClass;
static const uint32 JSSLOT_CALLABLE_CALL = 0;
static const uint32 JSSLOT_CALLABLE_CONSTRUCT = 1;
@ -1351,7 +1355,7 @@ callable_Construct(JSContext *cx, uintN argc, Value *vp)
return false;
}
JSObject *newobj = NewNativeClassInstance(cx, &ObjectClass, proto, proto->getParent());
JSObject *newobj = NewNativeClassInstance(cx, &js_ObjectClass, proto, proto->getParent());
if (!newobj)
return false;
@ -1372,7 +1376,7 @@ callable_Construct(JSContext *cx, uintN argc, Value *vp)
return ok;
}
Class js::CallableObjectClass = {
Class CallableObjectClass = {
"Function",
JSCLASS_HAS_RESERVED_SLOTS(2),
PropertyStub, /* addProperty */
@ -1390,7 +1394,7 @@ Class js::CallableObjectClass = {
};
JS_FRIEND_API(JSBool)
js::FixProxy(JSContext *cx, JSObject *proxy, JSBool *bp)
FixProxy(JSContext *cx, JSObject *proxy, JSBool *bp)
{
if (OperationInProgress(cx, proxy)) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_BAD_PROXY_FIX);
@ -1411,7 +1415,7 @@ js::FixProxy(JSContext *cx, JSObject *proxy, JSBool *bp)
JSObject *proto = proxy->getProto();
JSObject *parent = proxy->getParent();
Class *clasp = proxy->isFunctionProxy() ? &CallableObjectClass : &ObjectClass;
Class *clasp = proxy->isFunctionProxy() ? &CallableObjectClass : &js_ObjectClass;
/*
* Make a blank object from the recipe fix provided to us. This must have
@ -1444,7 +1448,9 @@ js::FixProxy(JSContext *cx, JSObject *proxy, JSBool *bp)
return true;
}
Class js::ProxyClass = {
}
Class js_ProxyClass = {
"Proxy",
JSCLASS_HAS_CACHED_PROTO(JSProto_Proxy),
PropertyStub, /* addProperty */
@ -1459,7 +1465,7 @@ Class js::ProxyClass = {
JS_FRIEND_API(JSObject *)
js_InitProxyClass(JSContext *cx, JSObject *obj)
{
JSObject *module = NewNonFunction<WithProto::Class>(cx, &ProxyClass, NULL, obj);
JSObject *module = NewNonFunction<WithProto::Class>(cx, &js_ProxyClass, NULL, obj);
if (!module || !module->setSingletonType(cx))
return NULL;
@ -1470,7 +1476,7 @@ js_InitProxyClass(JSContext *cx, JSObject *obj)
if (!JS_DefineFunctions(cx, module, static_methods))
return NULL;
MarkStandardClassInitializedNoProto(obj, &ProxyClass);
MarkStandardClassInitializedNoProto(obj, &js_ProxyClass);
return module;
}

View File

@ -142,6 +142,30 @@ const uint32 JSSLOT_PROXY_EXTRA = 2;
const uint32 JSSLOT_PROXY_CALL = 3;
const uint32 JSSLOT_PROXY_CONSTRUCT = 4;
extern JS_FRIEND_API(js::Class) ObjectProxyClass;
extern JS_FRIEND_API(js::Class) FunctionProxyClass;
extern JS_FRIEND_API(js::Class) OuterWindowProxyClass;
extern js::Class CallableObjectClass;
}
inline bool
JSObject::isObjectProxy() const
{
return getClass() == &js::ObjectProxyClass ||
getClass() == &js::OuterWindowProxyClass;
}
inline bool
JSObject::isFunctionProxy() const
{
return getClass() == &js::FunctionProxyClass;
}
inline bool
JSObject::isProxy() const
{
return isObjectProxy() || isFunctionProxy();
}
inline js::JSProxyHandler *
@ -193,6 +217,8 @@ FixProxy(JSContext *cx, JSObject *proxy, JSBool *bp);
JS_BEGIN_EXTERN_C
extern js::Class js_ProxyClass;
extern JS_FRIEND_API(JSObject *)
js_InitProxyClass(JSContext *cx, JSObject *obj);

View File

@ -323,7 +323,7 @@ class NodeBuilder
}
bool newObject(JSObject **dst) {
JSObject *nobj = NewNonFunction<WithProto::Class>(cx, &ObjectClass, NULL, NULL);
JSObject *nobj = NewNonFunction<WithProto::Class>(cx, &js_ObjectClass, NULL, NULL);
if (!nobj)
return false;
@ -633,7 +633,7 @@ NodeBuilder::newNode(ASTType type, TokenPos *pos, JSObject **dst)
Value tv;
JSObject *node = NewNonFunction<WithProto::Class>(cx, &ObjectClass, NULL, NULL);
JSObject *node = NewNonFunction<WithProto::Class>(cx, &js_ObjectClass, NULL, NULL);
if (!node ||
!setNodeLoc(node, pos) ||
!atomValue(nodeTypeNames[type], &tv) ||
@ -3238,7 +3238,7 @@ JS_BEGIN_EXTERN_C
JS_PUBLIC_API(JSObject *)
JS_InitReflect(JSContext *cx, JSObject *obj)
{
JSObject *Reflect = NewNonFunction<WithProto::Class>(cx, &ObjectClass, NULL, obj);
JSObject *Reflect = NewNonFunction<WithProto::Class>(cx, &js_ObjectClass, NULL, obj);
if (!Reflect || !Reflect->setSingletonType(cx))
return NULL;

View File

@ -141,10 +141,11 @@ SwapObjectRegExp(JSContext *cx, JSObject *obj, AlreadyIncRefed<RegExp> newRegExp
JSObject * JS_FASTCALL
js_CloneRegExpObject(JSContext *cx, JSObject *obj, JSObject *proto)
{
JS_ASSERT(obj->isRegExp());
JS_ASSERT(proto->isRegExp());
JS_ASSERT(obj->getClass() == &js_RegExpClass);
JS_ASSERT(proto);
JS_ASSERT(proto->getClass() == &js_RegExpClass);
JSObject *clone = NewNativeClassInstance(cx, &RegExpClass, proto, proto->getParent());
JSObject *clone = NewNativeClassInstance(cx, &js_RegExpClass, proto, proto->getParent());
if (!clone)
return NULL;
@ -431,7 +432,7 @@ js_XDRRegExpObject(JSXDRState *xdr, JSObject **objp)
if (!JS_XDRString(xdr, &source) || !JS_XDRUint32(xdr, &flagsword))
return false;
if (xdr->mode == JSXDR_DECODE) {
JSObject *obj = NewBuiltinClassInstance(xdr->cx, &RegExpClass);
JSObject *obj = NewBuiltinClassInstance(xdr->cx, &js_RegExpClass);
if (!obj)
return false;
obj->clearParent();
@ -459,7 +460,7 @@ js_XDRRegExpObject(JSXDRState *xdr, JSObject **objp)
#endif /* !JS_HAS_XDR */
Class js::RegExpClass = {
js::Class js_RegExpClass = {
js_RegExp_str,
JSCLASS_HAS_PRIVATE |
JSCLASS_HAS_RESERVED_SLOTS(JSObject::REGEXP_CLASS_RESERVED_SLOTS) |
@ -489,7 +490,7 @@ JSBool
js_regexp_toString(JSContext *cx, JSObject *obj, Value *vp)
{
if (!obj->isRegExp()) {
ReportIncompatibleMethod(cx, vp, &RegExpClass);
ReportIncompatibleMethod(cx, vp, &js_RegExpClass);
return false;
}
@ -608,7 +609,7 @@ ExecuteRegExp(JSContext *cx, ExecType execType, uintN argc, Value *vp)
if (!obj)
return false;
if (!obj->isRegExp()) {
ReportIncompatibleMethod(cx, vp, &RegExpClass);
ReportIncompatibleMethod(cx, vp, &js_RegExpClass);
return false;
}
@ -702,7 +703,7 @@ CompileRegExpAndSwap(JSContext *cx, JSObject *obj, uintN argc, Value *argv, Valu
return SwapRegExpInternals(cx, obj, rval, cx->runtime->emptyString);
Value sourceValue = argv[0];
if (sourceValue.isObject() && sourceValue.toObject().isRegExp()) {
if (sourceValue.isObject() && sourceValue.toObject().getClass() == &js_RegExpClass) {
/*
* If we get passed in a RegExp object we return a new object with the
* same RegExp (internal matcher program) guts.
@ -758,7 +759,7 @@ regexp_compile(JSContext *cx, uintN argc, Value *vp)
if (!obj)
return false;
if (!obj->isRegExp()) {
ReportIncompatibleMethod(cx, vp, &RegExpClass);
ReportIncompatibleMethod(cx, vp, &js_RegExpClass);
return false;
}
@ -783,7 +784,7 @@ regexp_construct(JSContext *cx, uintN argc, Value *vp)
}
}
JSObject *obj = NewBuiltinClassInstance(cx, &RegExpClass);
JSObject *obj = NewBuiltinClassInstance(cx, &js_RegExpClass);
if (!obj)
return false;
@ -808,7 +809,7 @@ js_InitRegExpClass(JSContext *cx, JSObject *obj)
GlobalObject *global = obj->asGlobal();
JSObject *proto = global->createBlankPrototype(cx, &RegExpClass);
JSObject *proto = global->createBlankPrototype(cx, &js_RegExpClass);
if (!proto)
return NULL;
@ -830,7 +831,7 @@ js_InitRegExpClass(JSContext *cx, JSObject *obj)
if (!DefinePropertiesAndBrand(cx, proto, NULL, regexp_methods))
return NULL;
JSFunction *ctor = global->createConstructor(cx, regexp_construct, &RegExpClass,
JSFunction *ctor = global->createConstructor(cx, regexp_construct, &js_RegExpClass,
CLASS_ATOM(cx, RegExp), 2);
if (!ctor)
return NULL;

View File

@ -52,6 +52,8 @@
#include "jsdhash.h"
#endif
extern js::Class js_RegExpClass;
namespace js {
class RegExpStatics
@ -386,6 +388,12 @@ JSObject::setRegExpSticky(bool sticky)
namespace js { class AutoStringRooter; }
inline bool
JSObject::isRegExp() const
{
return getClass() == &js_RegExpClass;
}
extern JS_FRIEND_API(JSBool)
js_ObjectIsRegExp(JSObject *obj);

View File

@ -448,7 +448,7 @@ RegExp::createObjectNoStatics(JSContext *cx, const jschar *chars, size_t length,
AlreadyIncRefed<RegExp> re = RegExp::create(cx, str, flags, ts);
if (!re)
return NULL;
JSObject *obj = NewBuiltinClassInstance(cx, &RegExpClass);
JSObject *obj = NewBuiltinClassInstance(cx, &js_RegExpClass);
if (!obj || !obj->initRegExp(cx, re.get())) {
re->decref(cx);
return NULL;

View File

@ -288,7 +288,7 @@ Shape::get(JSContext* cx, JSObject *receiver, JSObject* obj, JSObject *pobj, js:
* |with (it) color;| ends up here, as do XML filter-expressions.
* Avoid exposing the With object to native getters.
*/
if (obj->isWith())
if (obj->getClass() == &js_WithClass)
obj = js_UnwrapWithObject(cx, obj);
return js::CallJSPropertyOp(cx, getterOp(), receiver, SHAPE_USERID(this), vp);
}
@ -307,7 +307,7 @@ Shape::set(JSContext* cx, JSObject* obj, bool strict, js::Value* vp) const
return js_ReportGetterOnlyAssignment(cx);
/* See the comment in js::Shape::get as to why we check for With. */
if (obj->isWith())
if (obj->getClass() == &js_WithClass)
obj = js_UnwrapWithObject(cx, obj);
return js::CallJSPropertyOpSetter(cx, setterOp(), obj, SHAPE_USERID(this), strict, vp);
}
@ -364,37 +364,37 @@ EmptyShape::EmptyShape(JSCompartment *comp, js::Class *aclasp)
/* static */ inline EmptyShape *
EmptyShape::getEmptyArgumentsShape(JSContext *cx)
{
return ensure(cx, &NormalArgumentsObjectClass, &cx->compartment->emptyArgumentsShape);
return ensure(cx, &NormalArgumentsObject::jsClass, &cx->compartment->emptyArgumentsShape);
}
/* static */ inline EmptyShape *
EmptyShape::getEmptyBlockShape(JSContext *cx)
{
return ensure(cx, &BlockClass, &cx->compartment->emptyBlockShape);
return ensure(cx, &js_BlockClass, &cx->compartment->emptyBlockShape);
}
/* static */ inline EmptyShape *
EmptyShape::getEmptyCallShape(JSContext *cx)
{
return ensure(cx, &CallClass, &cx->compartment->emptyCallShape);
return ensure(cx, &js_CallClass, &cx->compartment->emptyCallShape);
}
/* static */ inline EmptyShape *
EmptyShape::getEmptyDeclEnvShape(JSContext *cx)
{
return ensure(cx, &DeclEnvClass, &cx->compartment->emptyDeclEnvShape);
return ensure(cx, &js_DeclEnvClass, &cx->compartment->emptyDeclEnvShape);
}
/* static */ inline EmptyShape *
EmptyShape::getEmptyEnumeratorShape(JSContext *cx)
{
return ensure(cx, &IteratorClass, &cx->compartment->emptyEnumeratorShape);
return ensure(cx, &js_IteratorClass, &cx->compartment->emptyEnumeratorShape);
}
/* static */ inline EmptyShape *
EmptyShape::getEmptyWithShape(JSContext *cx)
{
return ensure(cx, &WithClass, &cx->compartment->emptyWithShape);
return ensure(cx, &js_WithClass, &cx->compartment->emptyWithShape);
}
} /* namespace js */

View File

@ -668,9 +668,9 @@ js_XDRScript(JSXDRState *xdr, JSScript **scriptp)
uint32 isBlock;
if (xdr->mode == JSXDR_ENCODE) {
Class *clasp = (*objp)->getClass();
JS_ASSERT(clasp == &FunctionClass ||
clasp == &BlockClass);
isBlock = (clasp == &BlockClass) ? 1 : 0;
JS_ASSERT(clasp == &js_FunctionClass ||
clasp == &js_BlockClass);
isBlock = (clasp == &js_BlockClass) ? 1 : 0;
}
if (!JS_XDRUint32(xdr, &isBlock))
goto error;
@ -778,7 +778,7 @@ script_trace(JSTracer *trc, JSObject *obj)
}
}
Class js::ScriptClass = {
Class js_ScriptClass = {
"Script",
JSCLASS_HAS_PRIVATE |
JSCLASS_HAS_CACHED_PROTO(JSProto_Object),
@ -1387,7 +1387,7 @@ js_NewScriptObject(JSContext *cx, JSScript *script)
{
JS_ASSERT(!script->u.object);
JSObject *obj = NewNonFunction<WithProto::Class>(cx, &ScriptClass, NULL, NULL);
JSObject *obj = NewNonFunction<WithProto::Class>(cx, &js_ScriptClass, NULL, NULL);
if (!obj)
return NULL;
obj->setPrivate(script);

View File

@ -552,7 +552,7 @@ struct JSScript : public js::gc::Cell {
union {
/*
* A script object of class ScriptClass, to ensure the script is GC'd.
* A script object of class js_ScriptClass, to ensure the script is GC'd.
* - All scripts returned by JSAPI functions (JS_CompileScript,
* JS_CompileFile, etc.) have these objects.
* - Function scripts never have script objects; such scripts are owned
@ -843,6 +843,7 @@ StackDepth(JSScript *script)
} \
JS_END_MACRO
extern JS_FRIEND_DATA(js::Class) js_ScriptClass;
extern JSObject *
js_InitScriptClass(JSContext *cx, JSObject *obj);
@ -965,6 +966,12 @@ js_CloneScript(JSContext *cx, JSScript *script);
extern JSBool
js_XDRScript(JSXDRState *xdr, JSScript **scriptp);
inline bool
JSObject::isScript() const
{
return getClass() == &js_ScriptClass;
}
inline JSScript *
JSObject::getScript() const
{

View File

@ -153,7 +153,7 @@ JSScript::getRegExp(size_t index)
JSObjectArray *arr = regexps();
JS_ASSERT((uint32) index < arr->length);
JSObject *obj = arr->vector[index];
JS_ASSERT(obj->isRegExp());
JS_ASSERT(obj->getClass() == &js_RegExpClass);
return obj;
}

View File

@ -384,7 +384,7 @@ str_resolve(JSContext *cx, JSObject *obj, jsid id, uintN flags,
return JS_TRUE;
}
Class js::StringClass = {
Class js_StringClass = {
js_String_str,
JSCLASS_HAS_RESERVED_SLOTS(StringObject::RESERVED_SLOTS) |
JSCLASS_NEW_RESOLVE | JSCLASS_HAS_CACHED_PROTO(JSProto_String),
@ -401,7 +401,7 @@ Class js::StringClass = {
* Returns a JSString * for the |this| value associated with vp, or throws a
* TypeError if |this| is null or undefined. This algorithm is the same as
* calling CheckObjectCoercible(this), then returning ToString(this), as all
* String.prototype.* methods do (other than toString and valueOf).
* String.prototype.* methods do.
*/
static JS_ALWAYS_INLINE JSString *
ThisToStringForStringProto(JSContext *cx, Value *vp)
@ -413,9 +413,9 @@ ThisToStringForStringProto(JSContext *cx, Value *vp)
if (vp[1].isObject()) {
JSObject *obj = &vp[1].toObject();
if (obj->isString() &&
if (obj->getClass() == &js_StringClass &&
ClassMethodIsNative(cx, obj,
&StringClass,
&js_StringClass,
ATOM_TO_JSID(cx->runtime->atomState.toStringAtom),
js_str_toString))
{
@ -3191,12 +3191,12 @@ js_InitStringClass(JSContext *cx, JSObject *obj)
GlobalObject *global = obj->asGlobal();
JSObject *proto = global->createBlankPrototype(cx, &StringClass);
JSObject *proto = global->createBlankPrototype(cx, &js_StringClass);
if (!proto || !proto->asString()->init(cx, cx->runtime->emptyString))
return NULL;
/* Now create the String function. */
JSFunction *ctor = global->createConstructor(cx, js_String, &StringClass,
JSFunction *ctor = global->createConstructor(cx, js_String, &js_StringClass,
CLASS_ATOM(cx, String), 1);
if (!ctor)
return NULL;

View File

@ -101,6 +101,14 @@ extern JSSubString js_EmptySubString;
#define JS7_ISLET(c) ((c) < 128 && isalpha(c))
/* Initialize the String class, returning its prototype object. */
extern js::Class js_StringClass;
inline bool
JSObject::isString() const
{
return getClass() == &js_StringClass;
}
extern JSObject *
js_InitStringClass(JSContext *cx, JSObject *obj);

View File

@ -9832,9 +9832,9 @@ TraceRecorder::unbox_object(Address addr, LIns* tag_ins, JSValueType type, VMSid
guard(true, w.name(w.eqi(tag_ins, w.nameImmui(JSVAL_TAG_OBJECT)), "isObj"), exit);
LIns *payload_ins = w.ldiValuePayload(addr);
if (type == JSVAL_TYPE_FUNOBJ)
guardClass(payload_ins, &FunctionClass, exit, LOAD_NORMAL);
guardClass(payload_ins, &js_FunctionClass, exit, LOAD_NORMAL);
else
guardNotClass(payload_ins, &FunctionClass, exit, LOAD_NORMAL);
guardNotClass(payload_ins, &js_FunctionClass, exit, LOAD_NORMAL);
return payload_ins;
}
@ -9985,9 +9985,9 @@ TraceRecorder::unbox_object(LIns* v_ins, JSValueType type, VMSideExit* exit)
exit);
v_ins = unpack_ptr(v_ins);
if (type == JSVAL_TYPE_FUNOBJ)
guardClass(v_ins, &FunctionClass, exit, LOAD_NORMAL);
guardClass(v_ins, &js_FunctionClass, exit, LOAD_NORMAL);
else
guardNotClass(v_ins, &FunctionClass, exit, LOAD_NORMAL);
guardNotClass(v_ins, &js_FunctionClass, exit, LOAD_NORMAL);
return v_ins;
}
@ -10194,13 +10194,13 @@ TraceRecorder::guardNotClass(LIns* obj_ins, Class* clasp, VMSideExit* exit, Load
JS_REQUIRES_STACK void
TraceRecorder::guardDenseArray(LIns* obj_ins, ExitType exitType)
{
guardClass(obj_ins, &ArrayClass, snapshot(exitType), LOAD_NORMAL);
guardClass(obj_ins, &js_ArrayClass, snapshot(exitType), LOAD_NORMAL);
}
JS_REQUIRES_STACK void
TraceRecorder::guardDenseArray(LIns* obj_ins, VMSideExit* exit)
{
guardClass(obj_ins, &ArrayClass, exit, LOAD_NORMAL);
guardClass(obj_ins, &js_ArrayClass, exit, LOAD_NORMAL);
}
JS_REQUIRES_STACK bool
@ -11065,7 +11065,7 @@ TraceRecorder::getClassPrototype(JSObject* ctor, LIns*& proto_ins)
JS_ASSERT(!pval.isPrimitive());
JSObject *proto = &pval.toObject();
JS_ASSERT(!proto->isDenseArray());
JS_ASSERT_IF(clasp != &ArrayClass, proto->getNewType(cx)->emptyShapes[0]->getClass() == clasp);
JS_ASSERT_IF(clasp != &js_ArrayClass, proto->getNewType(cx)->emptyShapes[0]->getClass() == clasp);
proto_ins = w.immpObjGC(proto);
return RECORD_CONTINUE;
@ -11608,15 +11608,15 @@ TraceRecorder::callNative(uintN argc, JSOp mode)
LIns* this_ins;
if (mode == JSOP_NEW) {
Class* clasp = fun->u.n.clasp;
JS_ASSERT(clasp != &SlowArrayClass);
JS_ASSERT(clasp != &js_SlowArrayClass);
if (!clasp)
clasp = &ObjectClass;
clasp = &js_ObjectClass;
JS_ASSERT(((jsuword) clasp & 3) == 0);
// Abort on |new Function|. (FIXME: This restriction might not
// unnecessary now that the constructor creates the new function object
// itself.)
if (clasp == &FunctionClass)
if (clasp == &js_FunctionClass)
RETURN_STOP("new Function");
if (!IsFastTypedArrayClass(clasp) && !clasp->isNative())
@ -12494,7 +12494,7 @@ TraceRecorder::recordInitPropertyOp(jsbytecode op)
Value& l = stackval(-2);
JSObject* obj = &l.toObject();
LIns* obj_ins = get(&l);
JS_ASSERT(obj->getClass() == &ObjectClass);
JS_ASSERT(obj->getClass() == &js_ObjectClass);
Value& v = stackval(-1);
LIns* v_ins = get(&v);
@ -12769,7 +12769,7 @@ GetPropertyWithNativeGetter(JSContext* cx, JSObject* obj, Shape* shape, Value* v
// Shape::get contains a special case for With objects. We can elide it
// here because With objects are, we claim, never on the operand stack
// while recording.
JS_ASSERT(obj->getClass() != &WithClass);
JS_ASSERT(obj->getClass() != &js_WithClass);
vp->setUndefined();
if (!shape->getterOp()(cx, obj, SHAPE_USERID(shape), vp)) {
@ -14823,8 +14823,8 @@ TraceRecorder::record_JSOP_MOREITER()
* ni->flags (nor do we in unboxNextValue), because the different iteration
* type will guarantee a different entry typemap.
*/
if (iterobj->hasClass(&IteratorClass)) {
guardClass(iterobj_ins, &IteratorClass, snapshot(BRANCH_EXIT), LOAD_NORMAL);
if (iterobj->hasClass(&js_IteratorClass)) {
guardClass(iterobj_ins, &js_IteratorClass, snapshot(BRANCH_EXIT), LOAD_NORMAL);
NativeIterator *ni = (NativeIterator *) iterobj->getPrivate();
if (ni->isKeyIter()) {
@ -14837,7 +14837,7 @@ TraceRecorder::record_JSOP_MOREITER()
return ARECORD_CONTINUE;
}
} else {
guardNotClass(iterobj_ins, &IteratorClass, snapshot(BRANCH_EXIT), LOAD_NORMAL);
guardNotClass(iterobj_ins, &js_IteratorClass, snapshot(BRANCH_EXIT), LOAD_NORMAL);
}
enterDeepBailCall();
@ -14922,8 +14922,8 @@ TraceRecorder::unboxNextValue(Value &iterobj_val, LIns* &v_ins)
JSObject *iterobj = &iterobj_val.toObject();
LIns* iterobj_ins = get(&iterobj_val);
if (iterobj->hasClass(&IteratorClass)) {
guardClass(iterobj_ins, &IteratorClass, snapshot(BRANCH_EXIT), LOAD_NORMAL);
if (iterobj->hasClass(&js_IteratorClass)) {
guardClass(iterobj_ins, &js_IteratorClass, snapshot(BRANCH_EXIT), LOAD_NORMAL);
NativeIterator *ni = (NativeIterator *) iterobj->getPrivate();
LIns *ni_ins = w.ldpObjPrivate(iterobj_ins);
@ -14966,7 +14966,7 @@ TraceRecorder::unboxNextValue(Value &iterobj_val, LIns* &v_ins)
return ARECORD_CONTINUE;
}
} else {
guardNotClass(iterobj_ins, &IteratorClass, snapshot(BRANCH_EXIT), LOAD_NORMAL);
guardNotClass(iterobj_ins, &js_IteratorClass, snapshot(BRANCH_EXIT), LOAD_NORMAL);
}
@ -16340,7 +16340,7 @@ TraceRecorder::record_JSOP_LENGTH()
guardDenseArray(obj_ins, BRANCH_EXIT);
} else {
JS_ASSERT(obj->isSlowArray());
guardClass(obj_ins, &SlowArrayClass, snapshot(BRANCH_EXIT), LOAD_NORMAL);
guardClass(obj_ins, &js_SlowArrayClass, snapshot(BRANCH_EXIT), LOAD_NORMAL);
}
v_ins = w.lduiObjPrivate(obj_ins);
if (obj->getArrayLength() <= JSVAL_INT_MAX) {

View File

@ -186,7 +186,7 @@ static JSObject *
DelegateObject(JSContext *cx, JSObject *obj)
{
if (!obj->getPrivate()) {
JSObject *delegate = NewNonFunction<WithProto::Given>(cx, &ObjectClass, obj->getProto(), NULL);
JSObject *delegate = NewNonFunction<WithProto::Given>(cx, &js_ObjectClass, obj->getProto(), NULL);
obj->setPrivate(delegate);
return delegate;
}
@ -212,7 +212,7 @@ ArrayBuffer::create(JSContext *cx, int32 nbytes)
JS_ASSERT(obj->getClass() == &ArrayBuffer::slowClass);
obj->setSharedNonNativeMap();
obj->setClass(&ArrayBufferClass);
obj->clasp = &js_ArrayBufferClass;
/*
* The first 8 bytes hold the length.
@ -980,7 +980,7 @@ class TypedArrayTemplate
JS_ASSERT(obj->getClass() == slowClass());
obj->setSharedNonNativeMap();
obj->setClass(fastClass());
obj->clasp = fastClass();
// FIXME Bug 599008: make it ok to call preventExtensions here.
obj->flags |= JSObject::NOT_EXTENSIBLE;
@ -1694,7 +1694,7 @@ Class ArrayBuffer::slowClass = {
FinalizeStub
};
Class js::ArrayBufferClass = {
Class js_ArrayBufferClass = {
"ArrayBuffer",
JSCLASS_HAS_PRIVATE |
Class::NON_NATIVE |
@ -1902,7 +1902,7 @@ InitArrayBufferClass(JSContext *cx, GlobalObject *global)
return NULL;
JSFunction *ctor =
global->createConstructor(cx, ArrayBuffer::class_constructor, &ArrayBufferClass,
global->createConstructor(cx, ArrayBuffer::class_constructor, &js_ArrayBufferClass,
CLASS_ATOM(cx, ArrayBuffer), 1);
if (!ctor)
return NULL;
@ -1953,7 +1953,7 @@ JS_FRIEND_API(JSBool)
js_IsArrayBuffer(JSObject *obj)
{
JS_ASSERT(obj);
return obj->isArrayBuffer();
return obj->getClass() == &js_ArrayBufferClass;
}
namespace js {

View File

@ -78,6 +78,12 @@ WeakMapBase::sweepAll(JSTracer *tracer)
} /* namespace js */
bool
JSObject::isWeakMap() const
{
return getClass() == &WeakMapClass;
}
typedef WeakMap<JSObject *, Value> ObjectValueMap;
static ObjectValueMap *
@ -258,7 +264,9 @@ WeakMap_construct(JSContext *cx, uintN argc, Value *vp)
return true;
}
Class js::WeakMapClass = {
namespace js {
Class WeakMapClass = {
"WeakMap",
JSCLASS_HAS_PRIVATE |
JSCLASS_HAS_CACHED_PROTO(JSProto_WeakMap),
@ -279,6 +287,8 @@ Class js::WeakMapClass = {
WeakMap_mark
};
}
static JSFunctionSpec weak_map_methods[] = {
JS_FN("has", WeakMap_has, 1, 0),
JS_FN("get", WeakMap_get, 2, 0),

View File

@ -317,6 +317,9 @@ class DefaultMarkPolicy<JSObject *, JSObject *> {
//
typedef DefaultMarkPolicy<JSObject *, JSObject *> CrossCompartmentMarkPolicy;
// The class of JavaScript WeakMap objects.
extern Class WeakMapClass;
}
extern JSObject *

View File

@ -632,7 +632,7 @@ CanReify(Value *vp)
{
JSObject *obj;
return vp->isObject() &&
(obj = &vp->toObject())->getClass() == &IteratorClass &&
(obj = &vp->toObject())->getClass() == &js_IteratorClass &&
(obj->getNativeIterator()->flags & JSITER_ENUMERATE);
}

View File

@ -153,7 +153,7 @@ IsDeclared(const JSObject *obj)
{
jsval v;
JS_ASSERT(obj->getClass() == &NamespaceClass);
JS_ASSERT(obj->getClass() == &js_NamespaceClass);
v = obj->getNamespaceDeclared();
JS_ASSERT(JSVAL_IS_VOID(v) || v == JSVAL_TRUE);
return v == JSVAL_TRUE;
@ -197,9 +197,9 @@ NewBuiltinClassInstanceXML(JSContext *cx, Class *clasp)
* Namespace class and library functions.
*/
DEFINE_GETTER(NamePrefix_getter,
if (obj->getClass() == &NamespaceClass) *vp = obj->getNamePrefixVal())
if (obj->getClass() == &js_NamespaceClass) *vp = obj->getNamePrefixVal())
DEFINE_GETTER(NameURI_getter,
if (obj->getClass() == &NamespaceClass) *vp = obj->getNameURIVal())
if (obj->getClass() == &js_NamespaceClass) *vp = obj->getNameURIVal())
static JSBool
namespace_equality(JSContext *cx, JSObject *obj, const Value *v, JSBool *bp)
@ -208,13 +208,13 @@ namespace_equality(JSContext *cx, JSObject *obj, const Value *v, JSBool *bp)
JS_ASSERT(v->isObjectOrNull());
obj2 = v->toObjectOrNull();
*bp = (!obj2 || obj2->getClass() != &NamespaceClass)
*bp = (!obj2 || obj2->getClass() != &js_NamespaceClass)
? JS_FALSE
: EqualStrings(obj->getNameURI(), obj2->getNameURI());
return JS_TRUE;
}
JS_FRIEND_DATA(Class) js::NamespaceClass = {
JS_FRIEND_DATA(Class) js_NamespaceClass = {
"Namespace",
JSCLASS_HAS_RESERVED_SLOTS(JSObject::NAMESPACE_CLASS_RESERVED_SLOTS) |
JSCLASS_HAS_CACHED_PROTO(JSProto_Namespace),
@ -258,7 +258,7 @@ namespace_toString(JSContext *cx, uintN argc, Value *vp)
if (!obj)
return JS_FALSE;
if (!obj->isNamespace()) {
ReportIncompatibleMethod(cx, vp, &NamespaceClass);
ReportIncompatibleMethod(cx, vp, &js_NamespaceClass);
return JS_FALSE;
}
*vp = Valueify(obj->getNameURIVal());
@ -275,7 +275,7 @@ NewXMLNamespace(JSContext *cx, JSLinearString *prefix, JSLinearString *uri, JSBo
{
JSObject *obj;
obj = NewBuiltinClassInstanceXML(cx, &NamespaceClass);
obj = NewBuiltinClassInstanceXML(cx, &js_NamespaceClass);
if (!obj)
return NULL;
JS_ASSERT(JSVAL_IS_VOID(obj->getNamePrefixVal()));
@ -299,10 +299,10 @@ NewXMLNamespace(JSContext *cx, JSLinearString *prefix, JSLinearString *uri, JSBo
* QName class and library functions.
*/
DEFINE_GETTER(QNameNameURI_getter,
if (obj->getClass() == &QNameClass)
if (obj->getClass() == &js_QNameClass)
*vp = JSVAL_IS_VOID(obj->getNameURIVal()) ? JSVAL_NULL : obj->getNameURIVal())
DEFINE_GETTER(QNameLocalName_getter,
if (obj->getClass() == &QNameClass)
if (obj->getClass() == &js_QNameClass)
*vp = obj->getQNameLocalNameVal())
static JSBool
@ -324,13 +324,13 @@ qname_equality(JSContext *cx, JSObject *qn, const Value *v, JSBool *bp)
JSObject *obj2;
obj2 = v->toObjectOrNull();
*bp = (!obj2 || obj2->getClass() != &QNameClass)
*bp = (!obj2 || obj2->getClass() != &js_QNameClass)
? JS_FALSE
: qname_identity(qn, obj2);
return JS_TRUE;
}
JS_FRIEND_DATA(Class) js::QNameClass = {
JS_FRIEND_DATA(Class) js_QNameClass = {
"QName",
JSCLASS_HAS_RESERVED_SLOTS(JSObject::QNAME_CLASS_RESERVED_SLOTS) |
JSCLASS_HAS_CACHED_PROTO(JSProto_QName),
@ -364,7 +364,7 @@ JS_FRIEND_DATA(Class) js::QNameClass = {
* qname_toString method, and therefore are exposed as constructable objects
* in this implementation.
*/
JS_FRIEND_DATA(Class) js::AttributeNameClass = {
JS_FRIEND_DATA(Class) js_AttributeNameClass = {
js_AttributeName_str,
JSCLASS_HAS_RESERVED_SLOTS(JSObject::QNAME_CLASS_RESERVED_SLOTS) |
JSCLASS_IS_ANONYMOUS,
@ -378,7 +378,7 @@ JS_FRIEND_DATA(Class) js::AttributeNameClass = {
FinalizeStub
};
JS_FRIEND_DATA(Class) js::AnyNameClass = {
JS_FRIEND_DATA(Class) js_AnyNameClass = {
js_AnyName_str,
JSCLASS_HAS_RESERVED_SLOTS(JSObject::QNAME_CLASS_RESERVED_SLOTS) |
JSCLASS_IS_ANONYMOUS,
@ -422,7 +422,7 @@ ConvertQNameToString(JSContext *cx, JSObject *obj)
if (!str)
return NULL;
if (obj->getClass() == &AttributeNameClass) {
if (obj->getClass() == &js_AttributeNameClass) {
JS::Anchor<JSString *> anchor(str);
size_t length = str->length();
jschar *chars = (jschar *) cx->malloc_((length + 2) * sizeof(jschar));
@ -453,7 +453,7 @@ qname_toString(JSContext *cx, uintN argc, Value *vp)
return false;
if (!obj->isQName()) {
ReportIncompatibleMethod(cx, vp, &QNameClass);
ReportIncompatibleMethod(cx, vp, &js_QNameClass);
return false;
}
@ -497,7 +497,7 @@ static JSObject *
NewXMLQName(JSContext *cx, JSLinearString *uri, JSLinearString *prefix,
JSAtom *localName)
{
JSObject *obj = NewBuiltinClassInstanceXML(cx, &QNameClass);
JSObject *obj = NewBuiltinClassInstanceXML(cx, &js_QNameClass);
if (!obj)
return NULL;
if (!InitXMLQName(cx, obj, uri, prefix, localName))
@ -514,7 +514,7 @@ NewXMLAttributeName(JSContext *cx, JSLinearString *uri, JSLinearString *prefix,
* exposed to scripts.
*/
JSObject *parent = GetGlobalForScopeChain(cx);
JSObject *obj = NewNonFunction<WithProto::Given>(cx, &AttributeNameClass, NULL, parent);
JSObject *obj = NewNonFunction<WithProto::Given>(cx, &js_AttributeNameClass, NULL, parent);
if (!obj)
return NULL;
JS_ASSERT(obj->isQName());
@ -534,13 +534,13 @@ js_ConstructXMLQNameObject(JSContext *cx, const Value &nsval, const Value &lnval
* production, step 2.
*/
if (nsval.isObject() &&
nsval.toObject().getClass() == &AnyNameClass) {
nsval.toObject().getClass() == &js_AnyNameClass) {
argv[0].setNull();
} else {
argv[0] = nsval;
}
argv[1] = lnval;
return js_ConstructObject(cx, &QNameClass, NULL, NULL, 2, argv);
return js_ConstructObject(cx, &js_QNameClass, NULL, NULL, 2, argv);
}
static JSBool
@ -616,8 +616,8 @@ NamespaceHelper(JSContext *cx, JSObject *obj, intN argc, jsval *argv,
if (!JSVAL_IS_PRIMITIVE(urival)) {
uriobj = JSVAL_TO_OBJECT(urival);
clasp = uriobj->getClass();
isNamespace = (clasp == &NamespaceClass);
isQName = (clasp == &QNameClass);
isNamespace = (clasp == &js_NamespaceClass);
isQName = (clasp == &js_QNameClass);
}
}
@ -629,7 +629,7 @@ NamespaceHelper(JSContext *cx, JSObject *obj, intN argc, jsval *argv,
return JS_TRUE;
}
obj = NewBuiltinClassInstanceXML(cx, &NamespaceClass);
obj = NewBuiltinClassInstanceXML(cx, &js_NamespaceClass);
if (!obj)
return JS_FALSE;
}
@ -732,7 +732,7 @@ QNameHelper(JSContext *cx, JSObject *obj, intN argc, jsval *argv, jsval *rval)
nameval = argv[argc > 1];
isQName =
!JSVAL_IS_PRIMITIVE(nameval) &&
JSVAL_TO_OBJECT(nameval)->getClass() == &QNameClass;
JSVAL_TO_OBJECT(nameval)->getClass() == &js_QNameClass;
}
if (!obj) {
@ -744,7 +744,7 @@ QNameHelper(JSContext *cx, JSObject *obj, intN argc, jsval *argv, jsval *rval)
}
/* Create and return a new QName object exactly as if constructed. */
obj = NewBuiltinClassInstanceXML(cx, &QNameClass);
obj = NewBuiltinClassInstanceXML(cx, &js_QNameClass);
if (!obj)
return JS_FALSE;
}
@ -782,7 +782,7 @@ QNameHelper(JSContext *cx, JSObject *obj, intN argc, jsval *argv, jsval *rval)
return JS_FALSE;
JS_ASSERT(!JSVAL_IS_PRIMITIVE(nsval));
JS_ASSERT(JSVAL_TO_OBJECT(nsval)->getClass() ==
&NamespaceClass);
&js_NamespaceClass);
}
if (JSVAL_IS_NULL(nsval)) {
@ -799,8 +799,8 @@ QNameHelper(JSContext *cx, JSObject *obj, intN argc, jsval *argv, jsval *rval)
isNamespace = isQName = JS_FALSE;
if (!JSVAL_IS_PRIMITIVE(nsval)) {
obj2 = JSVAL_TO_OBJECT(nsval);
isNamespace = (obj2->getClass() == &NamespaceClass);
isQName = (obj2->getClass() == &QNameClass);
isNamespace = (obj2->getClass() == &js_NamespaceClass);
isQName = (obj2->getClass() == &js_QNameClass);
}
#ifdef __GNUC__ /* suppress bogus gcc warnings */
else obj2 = NULL;
@ -1852,9 +1852,9 @@ ToXML(JSContext *cx, jsval v)
JS_ASSERT(0);
}
if (clasp != &StringClass &&
clasp != &NumberClass &&
clasp != &BooleanClass) {
if (clasp != &js_StringClass &&
clasp != &js_NumberClass &&
clasp != &js_BooleanClass) {
goto bad;
}
}
@ -1933,9 +1933,9 @@ ToXMLList(JSContext *cx, jsval v)
JS_ASSERT(0);
}
if (clasp != &StringClass &&
clasp != &NumberClass &&
clasp != &BooleanClass) {
if (clasp != &js_StringClass &&
clasp != &js_NumberClass &&
clasp != &js_BooleanClass) {
goto bad;
}
}
@ -2230,7 +2230,7 @@ GetNamespace(JSContext *cx, JSObject *qn, const JSXMLArray *inScopeNSes)
if (!match) {
argv[0] = prefix ? STRING_TO_JSVAL(prefix) : JSVAL_VOID;
argv[1] = STRING_TO_JSVAL(uri);
ns = js_ConstructObject(cx, &NamespaceClass, NULL, NULL,
ns = js_ConstructObject(cx, &js_NamespaceClass, NULL, NULL,
2, Valueify(argv));
if (!ns)
return NULL;
@ -2783,16 +2783,16 @@ ToAttributeName(JSContext *cx, jsval v)
obj = JSVAL_TO_OBJECT(v);
clasp = obj->getClass();
if (clasp == &AttributeNameClass)
if (clasp == &js_AttributeNameClass)
return obj;
if (clasp == &QNameClass) {
if (clasp == &js_QNameClass) {
qn = obj;
uri = qn->getNameURI();
prefix = qn->getNamePrefix();
name = qn->getQNameLocalName();
} else {
if (clasp == &AnyNameClass) {
if (clasp == &js_AnyNameClass) {
name = cx->runtime->atomState.starAtom;
} else {
if (!js_ValueToAtom(cx, Valueify(v), &name))
@ -2853,9 +2853,9 @@ ToXMLName(JSContext *cx, jsval v, jsid *funidp)
obj = JSVAL_TO_OBJECT(v);
clasp = obj->getClass();
if (clasp == &AttributeNameClass || clasp == &QNameClass)
if (clasp == &js_AttributeNameClass || clasp == &js_QNameClass)
goto out;
if (clasp == &AnyNameClass) {
if (clasp == &js_AnyNameClass) {
name = cx->runtime->atomState.starAtom;
goto construct;
}
@ -2894,7 +2894,7 @@ ToXMLName(JSContext *cx, jsval v, jsid *funidp)
construct:
v = STRING_TO_JSVAL(name);
obj = js_ConstructObject(cx, &QNameClass, NULL, NULL, 1, Valueify(&v));
obj = js_ConstructObject(cx, &js_QNameClass, NULL, NULL, 1, Valueify(&v));
if (!obj)
return NULL;
@ -3207,7 +3207,7 @@ DescendantsHelper(JSContext *cx, JSXML *xml, JSObject *nameqn, JSXML *list)
JS_CHECK_RECURSION(cx, return JS_FALSE);
if (xml->xml_class == JSXML_CLASS_ELEMENT &&
nameqn->getClass() == &AttributeNameClass) {
nameqn->getClass() == &js_AttributeNameClass) {
for (i = 0, n = xml->xml_attrs.length; i < n; i++) {
attr = XMLARRAY_MEMBER(&xml->xml_attrs, i, JSXML);
if (attr && MatchAttrName(nameqn, attr)) {
@ -3221,7 +3221,7 @@ DescendantsHelper(JSContext *cx, JSXML *xml, JSObject *nameqn, JSXML *list)
kid = XMLARRAY_MEMBER(&xml->xml_kids, i, JSXML);
if (!kid)
continue;
if (nameqn->getClass() != &AttributeNameClass &&
if (nameqn->getClass() != &js_AttributeNameClass &&
MatchElemName(nameqn, kid)) {
if (!Append(cx, list, kid))
return JS_FALSE;
@ -3670,7 +3670,7 @@ GetNamedProperty(JSContext *cx, JSXML *xml, JSObject* nameqn, JSXML *list)
}
}
} else if (xml->xml_class == JSXML_CLASS_ELEMENT) {
attrs = (nameqn->getClass() == &AttributeNameClass);
attrs = (nameqn->getClass() == &js_AttributeNameClass);
if (attrs) {
array = &xml->xml_attrs;
matcher = MatchAttrName;
@ -3921,7 +3921,7 @@ PutProperty(JSContext *cx, JSObject *obj, jsid id, JSBool strict, jsval *vp)
goto bad;
} else {
nameobj = targetprop;
if (nameobj->getClass() == &AttributeNameClass) {
if (nameobj->getClass() == &js_AttributeNameClass) {
/*
* 2(c)(iii)(1-3).
* Note that rxml can't be null here, because target
@ -4017,7 +4017,7 @@ PutProperty(JSContext *cx, JSObject *obj, jsid id, JSBool strict, jsval *vp)
parent = kid->parent;
if (kid->xml_class == JSXML_CLASS_ATTRIBUTE) {
nameobj = kid->name;
if (nameobj->getClass() != &AttributeNameClass) {
if (nameobj->getClass() != &js_AttributeNameClass) {
nameobj = NewXMLAttributeName(cx, nameobj->getNameURI(), nameobj->getNamePrefix(),
nameobj->getQNameLocalName());
if (!nameobj)
@ -4224,7 +4224,7 @@ PutProperty(JSContext *cx, JSObject *obj, jsid id, JSBool strict, jsval *vp)
if (!ok)
goto out;
if (nameobj->getClass() == &AttributeNameClass) {
if (nameobj->getClass() == &js_AttributeNameClass) {
/* 7(a). */
if (!js_IsXMLName(cx, OBJECT_TO_JSVAL(nameobj)))
goto out;
@ -4477,7 +4477,7 @@ ResolveValue(JSContext *cx, JSXML *list, JSXML **result)
return JS_TRUE;
}
if (targetprop->getClass() == &AttributeNameClass) {
if (targetprop->getClass() == &js_AttributeNameClass) {
*result = NULL;
return JS_TRUE;
}
@ -4533,7 +4533,7 @@ HasNamedProperty(JSXML *xml, JSObject *nameqn)
}
if (xml->xml_class == JSXML_CLASS_ELEMENT) {
if (nameqn->getClass() == &AttributeNameClass) {
if (nameqn->getClass() == &js_AttributeNameClass) {
array = &xml->xml_attrs;
matcher = MatchAttrName;
} else {
@ -4572,7 +4572,7 @@ HasFunctionProperty(JSContext *cx, JSObject *obj, jsid funid, JSBool *found)
JSProperty *prop;
JSXML *xml;
JS_ASSERT(obj->getClass() == &XMLClass);
JS_ASSERT(obj->getClass() == &js_XMLClass);
if (!js_LookupProperty(cx, obj, funid, &pobj, &prop))
return false;
@ -4818,7 +4818,7 @@ xml_deleteProperty(JSContext *cx, JSObject *obj, jsid id, Value *rval, JSBool st
return js_DeleteProperty(cx, obj, funid, rval, false);
DeleteNamedProperty(cx, xml, nameqn,
nameqn->getClass() == &AttributeNameClass);
nameqn->getClass() == &js_AttributeNameClass);
}
/*
@ -5112,7 +5112,7 @@ out:
return ok;
}
JS_FRIEND_DATA(Class) js::XMLClass = {
JS_FRIEND_DATA(Class) js_XMLClass = {
js_XML_str,
JSCLASS_HAS_PRIVATE |
JSCLASS_HAS_CACHED_PROTO(JSProto_XML),
@ -5162,7 +5162,7 @@ StartNonListXMLMethod(JSContext *cx, jsval *vp, JSObject **objp)
if (!*objp)
return NULL;
if (!(*objp)->isXML()) {
ReportIncompatibleMethod(cx, Valueify(vp), &XMLClass);
ReportIncompatibleMethod(cx, Valueify(vp), &js_XMLClass);
return NULL;
}
xml = (JSXML *) (*objp)->getPrivate();
@ -5196,7 +5196,7 @@ StartNonListXMLMethod(JSContext *cx, jsval *vp, JSObject **objp)
if (!obj) \
return JS_FALSE; \
if (!obj->isXML()) { \
ReportIncompatibleMethod(cx, Valueify(vp), &XMLClass); \
ReportIncompatibleMethod(cx, Valueify(vp), &js_XMLClass); \
return JS_FALSE; \
} \
JSXML *xml = (JSXML *)obj->getPrivate(); \
@ -5683,7 +5683,7 @@ xml_hasOwnProperty(JSContext *cx, uintN argc, jsval *vp)
if (!obj)
return JS_FALSE;
if (!obj->isXML()) {
ReportIncompatibleMethod(cx, Valueify(vp), &XMLClass);
ReportIncompatibleMethod(cx, Valueify(vp), &js_XMLClass);
return JS_FALSE;
}
@ -6480,13 +6480,13 @@ xml_setName(JSContext *cx, uintN argc, jsval *vp)
} else {
name = vp[2];
if (!JSVAL_IS_PRIMITIVE(name) &&
JSVAL_TO_OBJECT(name)->getClass() == &QNameClass &&
JSVAL_TO_OBJECT(name)->getClass() == &js_QNameClass &&
!(nameqn = JSVAL_TO_OBJECT(name))->getNameURI()) {
name = vp[2] = nameqn->getQNameLocalNameVal();
}
}
nameqn = js_ConstructObject(cx, &QNameClass, NULL, NULL, 1, Valueify(&name));
nameqn = js_ConstructObject(cx, &js_QNameClass, NULL, NULL, 1, Valueify(&name));
if (!nameqn)
return JS_FALSE;
@ -6588,7 +6588,7 @@ xml_setNamespace(JSContext *cx, uintN argc, jsval *vp)
if (!xml)
return JS_FALSE;
ns = js_ConstructObject(cx, &NamespaceClass, NULL, obj,
ns = js_ConstructObject(cx, &js_NamespaceClass, NULL, obj,
argc == 0 ? 0 : 1, Valueify(vp + 2));
if (!ns)
return JS_FALSE;
@ -6597,7 +6597,7 @@ xml_setNamespace(JSContext *cx, uintN argc, jsval *vp)
qnargv[0] = OBJECT_TO_JSVAL(ns);
qnargv[1] = OBJECT_TO_JSVAL(xml->name);
qn = js_ConstructObject(cx, &QNameClass, NULL, NULL, 2, Valueify(qnargv));
qn = js_ConstructObject(cx, &js_QNameClass, NULL, NULL, 2, Valueify(qnargv));
if (!qn)
return JS_FALSE;
@ -6925,7 +6925,7 @@ XML(JSContext *cx, uintN argc, Value *vp)
if (IsConstructing(vp) && !JSVAL_IS_PRIMITIVE(v)) {
vobj = JSVAL_TO_OBJECT(v);
clasp = vobj->getClass();
if (clasp == &XMLClass ||
if (clasp == &js_XMLClass ||
(clasp->flags & JSCLASS_DOCUMENT_OBSERVER)) {
copy = DeepCopy(cx, xml, NULL, 0);
if (!copy)
@ -7071,7 +7071,7 @@ NewXMLObject(JSContext *cx, JSXML *xml)
JSObject *obj;
JSObject *parent = GetGlobalForScopeChain(cx);
obj = NewNonFunction<WithProto::Class>(cx, &XMLClass, NULL, parent);
obj = NewNonFunction<WithProto::Class>(cx, &js_XMLClass, NULL, parent);
if (!obj)
return NULL;
obj->setPrivate(xml);
@ -7103,7 +7103,7 @@ js_InitNamespaceClass(JSContext *cx, JSObject *obj)
GlobalObject *global = obj->asGlobal();
JSObject *namespaceProto = global->createBlankPrototype(cx, &NamespaceClass);
JSObject *namespaceProto = global->createBlankPrototype(cx, &js_NamespaceClass);
if (!namespaceProto)
return NULL;
JSFlatString *empty = cx->runtime->emptyString;
@ -7112,7 +7112,7 @@ js_InitNamespaceClass(JSContext *cx, JSObject *obj)
namespaceProto->syncSpecialEquality();
const uintN NAMESPACE_CTOR_LENGTH = 2;
JSFunction *ctor = global->createConstructor(cx, Namespace, &NamespaceClass,
JSFunction *ctor = global->createConstructor(cx, Namespace, &js_NamespaceClass,
CLASS_ATOM(cx, Namespace),
NAMESPACE_CTOR_LENGTH);
if (!ctor)
@ -7137,7 +7137,7 @@ js_InitQNameClass(JSContext *cx, JSObject *obj)
GlobalObject *global = obj->asGlobal();
JSObject *qnameProto = global->createBlankPrototype(cx, &QNameClass);
JSObject *qnameProto = global->createBlankPrototype(cx, &js_QNameClass);
if (!qnameProto)
return NULL;
JSAtom *empty = cx->runtime->emptyString;
@ -7146,7 +7146,7 @@ js_InitQNameClass(JSContext *cx, JSObject *obj)
qnameProto->syncSpecialEquality();
const uintN QNAME_CTOR_LENGTH = 2;
JSFunction *ctor = global->createConstructor(cx, QName, &QNameClass,
JSFunction *ctor = global->createConstructor(cx, QName, &js_QNameClass,
CLASS_ATOM(cx, QName), QNAME_CTOR_LENGTH);
if (!ctor)
return NULL;
@ -7170,7 +7170,7 @@ js_InitXMLClass(JSContext *cx, JSObject *obj)
GlobalObject *global = obj->asGlobal();
JSObject *xmlProto = global->createBlankPrototype(cx, &XMLClass);
JSObject *xmlProto = global->createBlankPrototype(cx, &js_XMLClass);
if (!xmlProto)
return NULL;
JSXML *xml = js_NewXML(cx, JSXML_CLASS_TEXT);
@ -7186,7 +7186,7 @@ js_InitXMLClass(JSContext *cx, JSObject *obj)
}
const uintN XML_CTOR_LENGTH = 1;
JSFunction *ctor = global->createConstructor(cx, XML, &XMLClass, CLASS_ATOM(cx, XML),
JSFunction *ctor = global->createConstructor(cx, XML, &js_XMLClass, CLASS_ATOM(cx, XML),
XML_CTOR_LENGTH);
if (!ctor)
return NULL;
@ -7293,7 +7293,7 @@ js_GetDefaultXMLNamespace(JSContext *cx, jsval *vp)
obj = NULL;
for (tmp = scopeChain; tmp; tmp = tmp->getParent()) {
Class *clasp = tmp->getClass();
if (clasp == &BlockClass || clasp == &WithClass)
if (clasp == &js_BlockClass || clasp == &js_WithClass)
continue;
if (!tmp->getProperty(cx, JS_DEFAULT_XML_NAMESPACE_ID, Valueify(&v)))
return JS_FALSE;
@ -7304,7 +7304,7 @@ js_GetDefaultXMLNamespace(JSContext *cx, jsval *vp)
obj = tmp;
}
ns = js_ConstructObject(cx, &NamespaceClass, NULL, obj, 0, NULL);
ns = js_ConstructObject(cx, &js_NamespaceClass, NULL, obj, 0, NULL);
if (!ns)
return JS_FALSE;
v = OBJECT_TO_JSVAL(ns);
@ -7322,7 +7322,7 @@ js_SetDefaultXMLNamespace(JSContext *cx, const Value &v)
Value argv[2];
argv[0].setString(cx->runtime->emptyString);
argv[1] = v;
JSObject *ns = js_ConstructObject(cx, &NamespaceClass, NULL, NULL, 2, argv);
JSObject *ns = js_ConstructObject(cx, &js_NamespaceClass, NULL, NULL, 2, argv);
if (!ns)
return JS_FALSE;
@ -7407,7 +7407,7 @@ js_GetAnyName(JSContext *cx, jsid *idp)
JSObject *global = cx->hasfp() ? cx->fp()->scopeChain().getGlobal() : cx->globalObject;
Value v = global->getReservedSlot(JSProto_AnyName);
if (v.isUndefined()) {
JSObject *obj = NewNonFunction<WithProto::Given>(cx, &AnyNameClass, NULL, global);
JSObject *obj = NewNonFunction<WithProto::Given>(cx, &js_AnyNameClass, NULL, global);
if (!obj)
return false;
@ -7439,15 +7439,15 @@ js_FindXMLProperty(JSContext *cx, const Value &nameval, JSObject **objp, jsid *i
JS_ASSERT(nameval.isObject());
nameobj = &nameval.toObject();
if (nameobj->getClass() == &AnyNameClass) {
if (nameobj->getClass() == &js_AnyNameClass) {
v = STRING_TO_JSVAL(cx->runtime->atomState.starAtom);
nameobj = js_ConstructObject(cx, &QNameClass, NULL, NULL, 1,
nameobj = js_ConstructObject(cx, &js_QNameClass, NULL, NULL, 1,
Valueify(&v));
if (!nameobj)
return JS_FALSE;
} else {
JS_ASSERT(nameobj->getClass() == &AttributeNameClass ||
nameobj->getClass() == &QNameClass);
JS_ASSERT(nameobj->getClass() == &js_AttributeNameClass ||
nameobj->getClass() == &js_QNameClass);
}
qn = nameobj;
@ -7458,7 +7458,7 @@ js_FindXMLProperty(JSContext *cx, const Value &nameval, JSObject **objp, jsid *i
do {
/* Skip any With object that can wrap XML. */
target = obj;
while (target->getClass() == &WithClass) {
while (target->getClass() == &js_WithClass) {
proto = target->getProto();
if (!proto)
break;

View File

@ -219,12 +219,48 @@ js_NewXMLObject(JSContext *cx, JSXMLClass xml_class);
extern JSObject *
js_GetXMLObject(JSContext *cx, JSXML *xml);
extern JS_FRIEND_DATA(js::Class) js_XMLClass;
extern JS_FRIEND_DATA(js::Class) js_NamespaceClass;
extern JS_FRIEND_DATA(js::Class) js_QNameClass;
extern JS_FRIEND_DATA(js::Class) js_AttributeNameClass;
extern JS_FRIEND_DATA(js::Class) js_AnyNameClass;
extern js::Class js_XMLFilterClass;
/*
* Methods to test whether an object or a value is of type "xml" (per typeof).
*/
inline bool
JSObject::isXML() const
{
return getClass() == &js_XMLClass;
}
inline bool
JSObject::isXMLId() const
{
js::Class *clasp = getClass();
return clasp == &js_QNameClass ||
clasp == &js_AttributeNameClass ||
clasp == &js_AnyNameClass;
}
#define VALUE_IS_XML(v) (!JSVAL_IS_PRIMITIVE(v) && JSVAL_TO_OBJECT(v)->isXML())
inline bool
JSObject::isNamespace() const
{
return getClass() == &js_NamespaceClass;
}
inline bool
JSObject::isQName() const
{
js::Class* clasp = getClass();
return clasp == &js_QNameClass ||
clasp == &js_AttributeNameClass ||
clasp == &js_AnyNameClass;
}
static inline bool
IsXML(const js::Value &v)
{

View File

@ -204,8 +204,8 @@ static const JSC::MacroAssembler::RegisterID JSParamReg_Argc = JSC::SparcRegist
}
Jump testFunction(Condition cond, RegisterID fun) {
return branchPtr(cond, Address(fun, JSObject::offsetOfClassPointer()),
ImmPtr(&FunctionClass));
return branchPtr(cond, Address(fun, offsetof(JSObject, clasp)),
ImmPtr(&js_FunctionClass));
}
/*
@ -811,7 +811,7 @@ static const JSC::MacroAssembler::RegisterID JSParamReg_Argc = JSC::SparcRegist
}
void loadObjClass(RegisterID objReg, RegisterID destReg) {
loadPtr(Address(objReg, JSObject::offsetOfClassPointer()), destReg);
loadPtr(Address(objReg, offsetof(JSObject, clasp)), destReg);
}
Jump testClass(Condition cond, RegisterID claspReg, js::Class *clasp) {
@ -819,7 +819,7 @@ static const JSC::MacroAssembler::RegisterID JSParamReg_Argc = JSC::SparcRegist
}
Jump testObjClass(Condition cond, RegisterID objReg, js::Class *clasp) {
return branchPtr(cond, Address(objReg, JSObject::offsetOfClassPointer()), ImmPtr(clasp));
return branchPtr(cond, Address(objReg, offsetof(JSObject, clasp)), ImmPtr(clasp));
}
void branchValue(Condition cond, RegisterID reg, int32 value, RegisterID result)
@ -1289,7 +1289,7 @@ static const JSC::MacroAssembler::RegisterID JSParamReg_Argc = JSC::SparcRegist
}
storePtr(ImmPtr(templateObject->lastProp), Address(result, offsetof(JSObject, lastProp)));
storePtr(ImmPtr(templateObject->getClass()), Address(result, JSObject::offsetOfClassPointer()));
storePtr(ImmPtr(templateObject->clasp), Address(result, offsetof(JSObject, clasp)));
store32(Imm32(templateObject->flags), Address(result, offsetof(JSObject, flags)));
store32(Imm32(templateObject->objShape), Address(result, offsetof(JSObject, objShape)));
storePtr(ImmPtr(templateObject->newType), Address(result, offsetof(JSObject, newType)));

View File

@ -5594,7 +5594,7 @@ mjit::Compiler::iterNext()
frame.unpinReg(reg);
/* Test clasp */
Jump notFast = masm.testObjClass(Assembler::NotEqual, reg, &IteratorClass);
Jump notFast = masm.testObjClass(Assembler::NotEqual, reg, &js_IteratorClass);
stubcc.linkExit(notFast, Uses(1));
/* Get private from iter obj. */
@ -5648,7 +5648,7 @@ mjit::Compiler::iterMore(jsbytecode *target)
RegisterID tempreg = frame.allocReg();
/* Test clasp */
Jump notFast = masm.testObjClass(Assembler::NotEqual, reg, &IteratorClass);
Jump notFast = masm.testObjClass(Assembler::NotEqual, reg, &js_IteratorClass);
stubcc.linkExitForBranch(notFast);
/* Get private from iter obj. */
@ -5687,7 +5687,7 @@ mjit::Compiler::iterEnd()
frame.unpinReg(reg);
/* Test clasp */
Jump notIterator = masm.testObjClass(Assembler::NotEqual, reg, &IteratorClass);
Jump notIterator = masm.testObjClass(Assembler::NotEqual, reg, &js_IteratorClass);
stubcc.linkExit(notIterator, Uses(1));
/* Get private from iter obj. */

View File

@ -1570,7 +1570,7 @@ mjit::Compiler::jsop_setelem(bool popGuaranteed)
ic.slowPathStart = stubcc.syncExit(Uses(3));
// Guard obj is a dense array.
ic.claspGuard = masm.testObjClass(Assembler::NotEqual, ic.objReg, &ArrayClass);
ic.claspGuard = masm.testObjClass(Assembler::NotEqual, ic.objReg, &js_ArrayClass);
stubcc.linkExitDirect(ic.claspGuard, ic.slowPathStart);
// Guard in range of initialized length.
@ -2120,7 +2120,7 @@ mjit::Compiler::jsop_getelem(bool isCall)
}
// Guard on the clasp.
ic.claspGuard = masm.testObjClass(Assembler::NotEqual, ic.objReg, &ArrayClass);
ic.claspGuard = masm.testObjClass(Assembler::NotEqual, ic.objReg, &js_ArrayClass);
stubcc.linkExitDirect(ic.claspGuard, ic.slowPathStart);
Int32Key key = id->isConstant()

View File

@ -115,7 +115,7 @@ top:
jsbytecode *pc = script->main() + tn->start + tn->length;
cx->regs().pc = pc;
JSBool ok = UnwindScope(cx, tn->stackDepth, JS_TRUE);
JSBool ok = js_UnwindScope(cx, tn->stackDepth, JS_TRUE);
JS_ASSERT(cx->regs().sp == fp->base() + tn->stackDepth);
switch (tn->kind) {
@ -178,7 +178,7 @@ static void
InlineReturn(VMFrame &f)
{
JS_ASSERT(f.fp() != f.entryfp);
JS_ASSERT(!IsActiveWithOrBlock(f.cx, f.fp()->scopeChain(), 0));
JS_ASSERT(!js_IsActiveWithOrBlock(f.cx, &f.fp()->scopeChain(), 0));
f.cx->stack.popInlineFrame(f.regs);
DebugOnly<JSOp> op = js_GetOpcode(f.cx, f.fp()->script(), f.regs.pc);
@ -603,7 +603,7 @@ js_InternalThrow(VMFrame &f)
// and epilogues. RunTracer(), Interpret(), and Invoke() all
// rely on this property.
JS_ASSERT(!f.fp()->finishedInInterpreter());
UnwindScope(cx, 0, cx->isExceptionPending());
js_UnwindScope(cx, 0, cx->isExceptionPending());
ScriptEpilogue(f.cx, f.fp(), false);
// Don't remove the last frame, this is the responsibility of
@ -782,7 +782,7 @@ HandleErrorInExcessFrame(VMFrame &f, StackFrame *stopFp, bool searchedTopmostFra
break;
/* Unwind and return. */
returnOK &= UnwindScope(cx, 0, returnOK || cx->isExceptionPending());
returnOK &= bool(js_UnwindScope(cx, 0, returnOK || cx->isExceptionPending()));
returnOK = ScriptEpilogue(cx, fp, returnOK);
InlineReturn(f);
}

View File

@ -775,7 +775,7 @@ class CallCompiler : public BaseCompiler
RegisterID t0 = tempRegs.takeAnyReg().reg();
/* Guard that it's actually a function object. */
Jump claspGuard = masm.testObjClass(Assembler::NotEqual, ic.funObjReg, &FunctionClass);
Jump claspGuard = masm.testObjClass(Assembler::NotEqual, ic.funObjReg, &js_FunctionClass);
/* Guard that it's the same function. */
JSFunction *fun = obj->getFunctionPrivate();

View File

@ -323,7 +323,7 @@ class SetPropCompiler : public PICStubCompiler
return error();
}
JS_ASSERT_IF(!shape->hasDefaultSetter(), obj->isCall());
JS_ASSERT_IF(!shape->hasDefaultSetter(), obj->getClass() == &js_CallClass);
MaybeJump skipOver;
@ -914,8 +914,8 @@ class GetPropCompiler : public PICStubCompiler
Assembler masm;
masm.loadObjClass(pic.objReg, pic.shapeReg);
Jump isDense = masm.testClass(Assembler::Equal, pic.shapeReg, &ArrayClass);
Jump notArray = masm.testClass(Assembler::NotEqual, pic.shapeReg, &SlowArrayClass);
Jump isDense = masm.testClass(Assembler::Equal, pic.shapeReg, &js_ArrayClass);
Jump notArray = masm.testClass(Assembler::NotEqual, pic.shapeReg, &js_SlowArrayClass);
isDense.linkTo(masm.label(), &masm);
masm.load32(Address(pic.objReg, offsetof(JSObject, privateData)), pic.objReg);
@ -1494,7 +1494,7 @@ class ScopeNameCompiler : public PICStubCompiler
* tree in ComputeImplicitThis.
*/
if (pic.kind == ic::PICInfo::CALLNAME) {
JS_ASSERT(obj->isCall());
JS_ASSERT(obj->getClass() == &js_CallClass);
Value *thisVp = &cx->regs().sp[1];
Address thisSlot(JSFrameReg, StackFrame::offsetOfFixed(thisVp - cx->fp()->slots()));
masm.storeValue(UndefinedValue(), thisSlot);
@ -1597,7 +1597,7 @@ class ScopeNameCompiler : public PICStubCompiler
if (obj != getprop.holder)
return disable("property is on proto of a scope object");
if (obj->isCall())
if (obj->getClass() == &js_CallClass)
return generateCallStub(obj);
LookupStatus status = getprop.testForGet();
@ -1641,7 +1641,7 @@ class ScopeNameCompiler : public PICStubCompiler
const Shape *shape = getprop.shape;
JSObject *normalized = obj;
if (obj->isWith() && !shape->hasDefaultGetter())
if (obj->getClass() == &js_WithClass && !shape->hasDefaultGetter())
normalized = js_UnwrapWithObject(cx, obj);
NATIVE_GET(cx, normalized, holder, shape, JSGET_METHOD_BARRIER, vp, return false);
if (thisvp)
@ -2049,7 +2049,7 @@ ic::CallProp(VMFrame &f, ic::PICInfo *pic)
#if JS_HAS_NO_SUCH_METHOD
if (JS_UNLIKELY(rval.isPrimitive()) && regs.sp[-1].isObject()) {
regs.sp[-2].setString(JSID_TO_STRING(id));
if (!OnUnknownMethod(cx, regs.sp - 2))
if (!js_OnUnknownMethod(cx, regs.sp - 2))
THROW();
}
#endif
@ -2805,7 +2805,7 @@ ic::CallElement(VMFrame &f, ic::GetElementIC *ic)
if (JS_UNLIKELY(f.regs.sp[-2].isPrimitive()) && thisv.isObject()) {
f.regs.sp[-2] = f.regs.sp[-1];
f.regs.sp[-1].setObject(*thisObj);
if (!OnUnknownMethod(cx, f.regs.sp - 2))
if (!js_OnUnknownMethod(cx, f.regs.sp - 2))
THROW();
} else
#endif

View File

@ -389,7 +389,7 @@ NameOp(VMFrame &f, JSObject *obj, bool callname)
} else {
shape = (Shape *)prop;
JSObject *normalized = obj;
if (normalized->isWith() && !shape->hasDefaultGetter())
if (normalized->getClass() == &js_WithClass && !shape->hasDefaultGetter())
normalized = js_UnwrapWithObject(cx, normalized);
NATIVE_GET(cx, normalized, obj2, shape, JSGET_METHOD_BARRIER, &rval, return NULL);
}
@ -552,7 +552,7 @@ stubs::CallElem(VMFrame &f)
if (JS_UNLIKELY(regs.sp[-2].isPrimitive()) && thisv.isObject()) {
regs.sp[-2] = regs.sp[-1];
regs.sp[-1].setObject(*thisObj);
if (!OnUnknownMethod(cx, regs.sp - 2))
if (!js_OnUnknownMethod(cx, regs.sp - 2))
THROW();
} else
#endif
@ -1351,7 +1351,7 @@ stubs::NewInitObject(VMFrame &f, JSObject *baseobj)
if (!baseobj) {
gc::AllocKind kind = GuessObjectGCKind(0, false);
JSObject *obj = NewBuiltinClassInstance(cx, &ObjectClass, kind);
JSObject *obj = NewBuiltinClassInstance(cx, &js_ObjectClass, kind);
if (!obj)
THROW();
if (type)
@ -1740,7 +1740,7 @@ stubs::CallProp(VMFrame &f, JSAtom *origAtom)
#if JS_HAS_NO_SUCH_METHOD
if (JS_UNLIKELY(rval.isPrimitive()) && regs.sp[-1].isObject()) {
regs.sp[-2].setString(origAtom);
if (!OnUnknownMethod(cx, regs.sp - 2))
if (!js_OnUnknownMethod(cx, regs.sp - 2))
THROW();
}
#endif
@ -2016,9 +2016,10 @@ stubs::EnterBlock(VMFrame &f, JSObject *obj)
* static scope.
*/
JSObject *obj2 = &fp->scopeChain();
while (obj2->isWith())
Class *clasp;
while ((clasp = obj2->getClass()) == &js_WithClass)
obj2 = obj2->getParent();
if (obj2->isBlock() &&
if (clasp == &js_BlockClass &&
obj2->getPrivate() == js_FloatingFrameIfGenerator(cx, fp)) {
JSObject *youngestProto = obj2->getProto();
JS_ASSERT(youngestProto->isStaticBlock());
@ -2048,7 +2049,7 @@ stubs::LeaveBlock(VMFrame &f, JSObject *blockChain)
*/
JSObject *obj = &fp->scopeChain();
if (obj->getProto() == blockChain) {
JS_ASSERT(obj->isBlock());
JS_ASSERT(obj->getClass() == &js_BlockClass);
if (!js_PutBlockObject(cx, JS_TRUE))
THROW();
}

View File

@ -1560,9 +1560,9 @@ ValueToScript(JSContext *cx, jsval v)
JSObject *obj = JSVAL_TO_OBJECT(v);
JSClass *clasp = JS_GET_CLASS(cx, obj);
if (clasp == Jsvalify(&ScriptClass)) {
if (clasp == Jsvalify(&js_ScriptClass)) {
script = (JSScript *) JS_GetPrivate(cx, obj);
} else if (clasp == Jsvalify(&GeneratorClass)) {
} else if (clasp == Jsvalify(&js_GeneratorClass)) {
JSGenerator *gen = (JSGenerator *) JS_GetPrivate(cx, obj);
fun = gen->floatingFrame()->fun();
script = fun->script();
@ -1620,8 +1620,8 @@ GetTrapArgs(JSContext *cx, uintN argc, jsval *argv, JSScript **scriptp,
v = argv[0];
intarg = 0;
if (!JSVAL_IS_PRIMITIVE(v) &&
(JS_GET_CLASS(cx, JSVAL_TO_OBJECT(v)) == Jsvalify(&FunctionClass) ||
JS_GET_CLASS(cx, JSVAL_TO_OBJECT(v)) == Jsvalify(&ScriptClass))) {
(JS_GET_CLASS(cx, JSVAL_TO_OBJECT(v)) == Jsvalify(&js_FunctionClass) ||
JS_GET_CLASS(cx, JSVAL_TO_OBJECT(v)) == Jsvalify(&js_ScriptClass))) {
script = ValueToScript(cx, v);
if (!script)
return JS_FALSE;

View File

@ -368,12 +368,12 @@ class ReferenceFinder {
JSObject *object = static_cast<JSObject *>(cell);
/* Certain classes of object are for internal use only. */
if (object->isBlock() ||
object->isCall() ||
object->isWith() ||
object->isDeclEnv()) {
JSClass *clasp = JS_GET_CLASS(context, object);
if (clasp == Jsvalify(&js_BlockClass) ||
clasp == Jsvalify(&js_CallClass) ||
clasp == Jsvalify(&js_WithClass) ||
clasp == Jsvalify(&js_DeclEnvClass))
return JSVAL_VOID;
}
/* Internal function objects should also not be revealed. */
if (JS_ObjectIsFunction(context, object) && IsInternalFunctionObject(object))

View File

@ -479,7 +479,7 @@ class Writer
}
nj::LIns *ldpObjClasp(nj::LIns *obj, nj::LoadQual loadQual) const {
return name(lir->insLoad(nj::LIR_ldp, obj, JSObject::offsetOfClassPointer(), ACCSET_OBJ_CLASP,
return name(lir->insLoad(nj::LIR_ldp, obj, offsetof(JSObject, clasp), ACCSET_OBJ_CLASP,
loadQual),
"clasp");
}

View File

@ -151,7 +151,7 @@ class ArgumentsObject : public ::JSObject
static const uint32 INITIAL_LENGTH_SLOT = 0;
static const uint32 DATA_SLOT = 1;
public:
protected:
static const uint32 RESERVED_SLOTS = 2;
private:
@ -240,6 +240,8 @@ class ArgumentsObject : public ::JSObject
*/
class NormalArgumentsObject : public ArgumentsObject
{
static js::Class jsClass;
friend bool JSObject::isNormalArguments() const;
friend struct EmptyShape; // for EmptyShape::getEmptyArgumentsShape
friend ArgumentsObject *
@ -264,6 +266,8 @@ class NormalArgumentsObject : public ArgumentsObject
*/
class StrictArgumentsObject : public ArgumentsObject
{
static js::Class jsClass;
friend bool JSObject::isStrictArguments() const;
friend ArgumentsObject *
ArgumentsObject::create(JSContext *cx, uint32 argc, JSObject &callee);
@ -271,6 +275,12 @@ class StrictArgumentsObject : public ArgumentsObject
} // namespace js
inline bool
JSObject::isNormalArguments() const
{
return getClass() == &js::NormalArgumentsObject::jsClass;
}
js::NormalArgumentsObject *
JSObject::asNormalArguments()
{
@ -278,6 +288,12 @@ JSObject::asNormalArguments()
return reinterpret_cast<js::NormalArgumentsObject *>(this);
}
inline bool
JSObject::isStrictArguments() const
{
return getClass() == &js::StrictArgumentsObject::jsClass;
}
js::StrictArgumentsObject *
JSObject::asStrictArguments()
{
@ -285,6 +301,12 @@ JSObject::asStrictArguments()
return reinterpret_cast<js::StrictArgumentsObject *>(this);
}
inline bool
JSObject::isArguments() const
{
return isNormalArguments() || isStrictArguments();
}
js::ArgumentsObject *
JSObject::asArguments()
{

View File

@ -347,9 +347,9 @@ JS_STATIC_ASSERT(uintN(JSSLOT_DEBUGFRAME_OWNER) == uintN(JSSLOT_DEBUGSCRIPT_OWNE
Debugger *
Debugger::fromChildJSObject(JSObject *obj)
{
JS_ASSERT(obj->getClass() == &DebuggerFrame_class ||
obj->getClass() == &DebuggerObject_class ||
obj->getClass() == &DebuggerScript_class);
JS_ASSERT(obj->clasp == &DebuggerFrame_class ||
obj->clasp == &DebuggerObject_class ||
obj->clasp == &DebuggerScript_class);
JSObject *dbgobj = &obj->getReservedSlot(JSSLOT_DEBUGOBJECT_OWNER).toObject();
return fromJSObject(dbgobj);
}
@ -523,9 +523,9 @@ Debugger::unwrapDebuggeeValue(JSContext *cx, Value *vp)
assertSameCompartment(cx, object, *vp);
if (vp->isObject()) {
JSObject *dobj = &vp->toObject();
if (dobj->getClass() != &DebuggerObject_class) {
if (dobj->clasp != &DebuggerObject_class) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_NOT_EXPECTED_TYPE,
"Debugger", "Debugger.Object", dobj->getClass()->name);
"Debugger", "Debugger.Object", dobj->clasp->name);
return false;
}
@ -587,7 +587,7 @@ Debugger::newCompletionValue(AutoCompartment &ac, bool ok, Value val, Value *vp)
return true;
}
JSObject *obj = NewBuiltinClassInstance(cx, &ObjectClass);
JSObject *obj = NewBuiltinClassInstance(cx, &js_ObjectClass);
if (!obj ||
!wrapDebuggeeValue(cx, &val) ||
!DefineNativeProperty(cx, obj, key, val, PropertyStub, StrictPropertyStub,
@ -1479,7 +1479,7 @@ Debugger::unwrapDebuggeeArgument(JSContext *cx, const Value &v)
*/
JSObject *obj = NonNullObject(cx, v);
if (obj) {
if (obj->getClass() == &DebuggerObject_class) {
if (obj->clasp == &DebuggerObject_class) {
Value rv = v;
if (!unwrapDebuggeeValue(cx, &rv))
return NULL;
@ -1977,7 +1977,7 @@ DebuggerScript_check(JSContext *cx, const Value &v, const char *clsname, const c
return NULL;
}
JSObject *thisobj = &v.toObject();
if (thisobj->getClass() != &DebuggerScript_class) {
if (thisobj->clasp != &DebuggerScript_class) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_INCOMPATIBLE_PROTO,
clsname, fnname, thisobj->getClass()->name);
return NULL;
@ -2947,7 +2947,7 @@ DebuggerFrameEval(JSContext *cx, uintN argc, Value *vp, EvalBindingsMode mode)
/* If evalWithBindings, create the inner scope object. */
if (mode == WithBindings) {
/* TODO - Should probably create a With object here. */
scobj = NewNonFunction<WithProto::Given>(cx, &ObjectClass, NULL, scobj);
scobj = NewNonFunction<WithProto::Given>(cx, &js_ObjectClass, NULL, scobj);
if (!scobj)
return false;
for (size_t i = 0; i < keys.length(); i++) {
@ -3040,7 +3040,7 @@ DebuggerObject_checkThis(JSContext *cx, const CallArgs &args, const char *fnname
return NULL;
}
JSObject *thisobj = &args.thisv().toObject();
if (thisobj->getClass() != &DebuggerObject_class) {
if (thisobj->clasp != &DebuggerObject_class) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_INCOMPATIBLE_PROTO,
"Debugger.Object", fnname, thisobj->getClass()->name);
return NULL;
@ -3098,7 +3098,7 @@ static JSBool
DebuggerObject_getClass(JSContext *cx, uintN argc, Value *vp)
{
THIS_DEBUGOBJECT_REFERENT(cx, argc, vp, "get class", args, refobj);
const char *s = refobj->getClass()->name;
const char *s = refobj->clasp->name;
JSAtom *str = js_Atomize(cx, s, strlen(s));
if (!str)
return false;

View File

@ -227,8 +227,8 @@ GlobalObject::createConstructor(JSContext *cx, Native ctor, Class *clasp, JSAtom
static JSObject *
CreateBlankProto(JSContext *cx, Class *clasp, JSObject &proto, GlobalObject &global)
{
JS_ASSERT(clasp != &ObjectClass);
JS_ASSERT(clasp != &FunctionClass);
JS_ASSERT(clasp != &js_ObjectClass);
JS_ASSERT(clasp != &js_FunctionClass);
JSObject *blankProto = NewNonFunction<WithProto::Given>(cx, clasp, &proto, &global);
if (!blankProto || !blankProto->setSingletonType(cx))
@ -300,7 +300,7 @@ GlobalObject::getDebuggers()
Value debuggers = getReservedSlot(DEBUGGERS);
if (debuggers.isUndefined())
return NULL;
JS_ASSERT(debuggers.toObject().getClass() == &GlobalDebuggees_class);
JS_ASSERT(debuggers.toObject().clasp == &GlobalDebuggees_class);
return (DebuggerVector *) debuggers.toObject().getPrivate();
}

View File

@ -358,7 +358,7 @@ StackFrame::callObj() const
JS_ASSERT_IF(isNonEvalFunctionFrame() || isStrictEvalFrame(), hasCallObj());
JSObject *pobj = &scopeChain();
while (JS_UNLIKELY(!pobj->isCall())) {
while (JS_UNLIKELY(pobj->getClass() != &js_CallClass)) {
JS_ASSERT(IsCacheableNonGlobalScope(pobj) || pobj->isWith());
pobj = pobj->getParent();
}

View File

@ -152,7 +152,7 @@ StackFrame::stealFrameAndSlots(Value *vp, StackFrame *otherfp,
otherfp->flags_ &= ~HAS_CALL_OBJ;
if (js_IsNamedLambda(fun())) {
JSObject *env = obj.getParent();
JS_ASSERT(env->isDeclEnv());
JS_ASSERT(env->getClass() == &js_DeclEnvClass);
env->setPrivate(this);
}
}

View File

@ -55,7 +55,7 @@ namespace js {
inline StringObject *
StringObject::create(JSContext *cx, JSString *str)
{
JSObject *obj = NewBuiltinClassInstance(cx, &StringClass);
JSObject *obj = NewBuiltinClassInstance(cx, &js_StringClass);
if (!obj)
return NULL;
StringObject *strobj = obj->asString();
@ -67,8 +67,8 @@ StringObject::create(JSContext *cx, JSString *str)
inline StringObject *
StringObject::createWithProto(JSContext *cx, JSString *str, JSObject &proto)
{
JS_ASSERT(gc::FINALIZE_OBJECT2 == gc::GetGCObjectKind(JSCLASS_RESERVED_SLOTS(&StringClass)));
JSObject *obj = NewObjectWithClassProto(cx, &StringClass, &proto, gc::FINALIZE_OBJECT2);
JS_ASSERT(gc::FINALIZE_OBJECT2 == gc::GetGCObjectKind(JSCLASS_RESERVED_SLOTS(&js_StringClass)));
JSObject *obj = NewObjectWithClassProto(cx, &js_StringClass, &proto, gc::FINALIZE_OBJECT2);
if (!obj)
return NULL;
StringObject *strobj = obj->asString();

View File

@ -808,7 +808,7 @@ nsXPConnect::Traverse(void *p, nsCycleCollectionTraversalCallback &cb)
JS_snprintf(name, sizeof(name), "JS Object (%s - %s)",
clazz->name, si->GetJSClass()->name);
}
else if(clazz == &js::ScriptClass)
else if(clazz == &js_ScriptClass)
{
JSScript* script = (JSScript*) xpc_GetJSPrivate(obj);
if(script->filename)
@ -822,7 +822,7 @@ nsXPConnect::Traverse(void *p, nsCycleCollectionTraversalCallback &cb)
JS_snprintf(name, sizeof(name), "JS Object (Script)");
}
}
else if(clazz == &js::FunctionClass)
else if(clazz == &js_FunctionClass)
{
JSFunction* fun = (JSFunction*) xpc_GetJSPrivate(obj);
JSString* str = JS_GetFunctionId(fun);