Bug 570169 - Part 1, preparation. Rearrange some code. r=gal.

This commit is contained in:
Jason Orendorff 2010-06-16 16:13:01 -05:00
parent 651a2b804e
commit 6472e34dba
8 changed files with 167 additions and 164 deletions

View File

@ -2206,6 +2206,7 @@ class AutoGCRooter {
context->autoGCRooters = down;
}
/* Implemented in jsgc.cpp. */
inline void trace(JSTracer *trc);
#ifdef __GNUC__

View File

@ -44,8 +44,6 @@
#include "jsparse.h"
#include "jsxml.h"
#include "jsobjinlines.h"
inline bool
JSContext::ensureGeneratorStackSpace()
{
@ -193,103 +191,6 @@ class AutoNamespaces : protected AutoGCRooter {
JSXMLArray array;
};
inline void
AutoGCRooter::trace(JSTracer *trc)
{
switch (tag) {
case JSVAL:
JS_SET_TRACING_NAME(trc, "js::AutoValueRooter.val");
js_CallValueTracerIfGCThing(trc, static_cast<AutoValueRooter *>(this)->val);
return;
case SPROP:
static_cast<AutoScopePropertyRooter *>(this)->sprop->trace(trc);
return;
case WEAKROOTS:
static_cast<AutoPreserveWeakRoots *>(this)->savedRoots.mark(trc);
return;
case PARSER:
static_cast<Parser *>(this)->trace(trc);
return;
case SCRIPT:
if (JSScript *script = static_cast<AutoScriptRooter *>(this)->script)
js_TraceScript(trc, script);
return;
case ENUMERATOR:
static_cast<AutoEnumStateRooter *>(this)->trace(trc);
return;
case IDARRAY: {
JSIdArray *ida = static_cast<AutoIdArray *>(this)->idArray;
TraceValues(trc, ida->length, ida->vector, "js::AutoIdArray.idArray");
return;
}
case DESCRIPTORS: {
PropertyDescriptorArray &descriptors =
static_cast<AutoDescriptorArray *>(this)->descriptors;
for (size_t i = 0, len = descriptors.length(); i < len; i++) {
PropertyDescriptor &desc = descriptors[i];
JS_CALL_VALUE_TRACER(trc, desc.pd, "PropertyDescriptor::pd");
JS_CALL_VALUE_TRACER(trc, desc.value, "PropertyDescriptor::value");
JS_CALL_VALUE_TRACER(trc, desc.get, "PropertyDescriptor::get");
JS_CALL_VALUE_TRACER(trc, desc.set, "PropertyDescriptor::set");
js_TraceId(trc, desc.id);
}
return;
}
case DESCRIPTOR : {
AutoDescriptor &desc = *static_cast<AutoDescriptor *>(this);
if (desc.obj)
JS_CALL_OBJECT_TRACER(trc, desc.obj, "Descriptor::obj");
JS_CALL_VALUE_TRACER(trc, desc.value, "Descriptor::value");
if (desc.attrs & JSPROP_GETTER)
JS_CALL_VALUE_TRACER(trc, jsval(desc.getter), "Descriptor::get");
if (desc.attrs & JSPROP_SETTER)
JS_CALL_VALUE_TRACER(trc, jsval(desc.setter), "Descriptor::set");
return;
}
case NAMESPACES: {
JSXMLArray &array = static_cast<AutoNamespaces *>(this)->array;
TraceObjectVector(trc, reinterpret_cast<JSObject **>(array.vector), array.length);
array.cursors->trace(trc);
return;
}
case XML:
js_TraceXML(trc, static_cast<AutoXMLRooter *>(this)->xml);
return;
case OBJECT:
if (JSObject *obj = static_cast<AutoObjectRooter *>(this)->obj) {
JS_SET_TRACING_NAME(trc, "js::AutoObjectRooter.obj");
js_CallGCMarker(trc, obj, JSTRACE_OBJECT);
}
return;
case ID:
JS_SET_TRACING_NAME(trc, "js::AutoIdRooter.val");
js_CallValueTracerIfGCThing(trc, static_cast<AutoIdRooter *>(this)->idval);
return;
case VECTOR: {
js::Vector<jsval, 8> &vector = static_cast<js::AutoValueVector *>(this)->vector;
js::TraceValues(trc, vector.length(), vector.begin(), "js::AutoValueVector.vector");
return;
}
}
JS_ASSERT(tag >= 0);
TraceValues(trc, tag, static_cast<AutoArrayRooter *>(this)->array, "js::AutoArrayRooter.array");
}
}
#endif /* jscntxtinlines_h___ */

View File

@ -255,6 +255,21 @@ JSObject::isFunction() const
return getClass() == &js_FunctionClass;
}
inline bool
JSObject::isCallable()
{
if (isNative())
return isFunction() || getClass()->call;
return !!map->ops->call;
}
static inline bool
js_IsCallable(jsval v)
{
return !JSVAL_IS_PRIMITIVE(v) && JSVAL_TO_OBJECT(v)->isCallable();
}
/*
* NB: jsapi.h and jsobj.h must be included before any call to this macro.
*/

View File

@ -2607,6 +2607,103 @@ JSWeakRoots::mark(JSTracer *trc)
js_CallValueTracerIfGCThing(trc, lastInternalResult);
}
inline void
AutoGCRooter::trace(JSTracer *trc)
{
switch (tag) {
case JSVAL:
JS_SET_TRACING_NAME(trc, "js::AutoValueRooter.val");
js_CallValueTracerIfGCThing(trc, static_cast<AutoValueRooter *>(this)->val);
return;
case SPROP:
static_cast<AutoScopePropertyRooter *>(this)->sprop->trace(trc);
return;
case WEAKROOTS:
static_cast<AutoPreserveWeakRoots *>(this)->savedRoots.mark(trc);
return;
case PARSER:
static_cast<Parser *>(this)->trace(trc);
return;
case SCRIPT:
if (JSScript *script = static_cast<AutoScriptRooter *>(this)->script)
js_TraceScript(trc, script);
return;
case ENUMERATOR:
static_cast<AutoEnumStateRooter *>(this)->trace(trc);
return;
case IDARRAY: {
JSIdArray *ida = static_cast<AutoIdArray *>(this)->idArray;
TraceValues(trc, ida->length, ida->vector, "js::AutoIdArray.idArray");
return;
}
case DESCRIPTORS: {
PropertyDescriptorArray &descriptors =
static_cast<AutoDescriptorArray *>(this)->descriptors;
for (size_t i = 0, len = descriptors.length(); i < len; i++) {
PropertyDescriptor &desc = descriptors[i];
JS_CALL_VALUE_TRACER(trc, desc.pd, "PropertyDescriptor::pd");
JS_CALL_VALUE_TRACER(trc, desc.value, "PropertyDescriptor::value");
JS_CALL_VALUE_TRACER(trc, desc.get, "PropertyDescriptor::get");
JS_CALL_VALUE_TRACER(trc, desc.set, "PropertyDescriptor::set");
js_TraceId(trc, desc.id);
}
return;
}
case DESCRIPTOR : {
AutoDescriptor &desc = *static_cast<AutoDescriptor *>(this);
if (desc.obj)
JS_CALL_OBJECT_TRACER(trc, desc.obj, "Descriptor::obj");
JS_CALL_VALUE_TRACER(trc, desc.value, "Descriptor::value");
if (desc.attrs & JSPROP_GETTER)
JS_CALL_VALUE_TRACER(trc, jsval(desc.getter), "Descriptor::get");
if (desc.attrs & JSPROP_SETTER)
JS_CALL_VALUE_TRACER(trc, jsval(desc.setter), "Descriptor::set");
return;
}
case NAMESPACES: {
JSXMLArray &array = static_cast<AutoNamespaces *>(this)->array;
TraceObjectVector(trc, reinterpret_cast<JSObject **>(array.vector), array.length);
array.cursors->trace(trc);
return;
}
case XML:
js_TraceXML(trc, static_cast<AutoXMLRooter *>(this)->xml);
return;
case OBJECT:
if (JSObject *obj = static_cast<AutoObjectRooter *>(this)->obj) {
JS_SET_TRACING_NAME(trc, "js::AutoObjectRooter.obj");
js_CallGCMarker(trc, obj, JSTRACE_OBJECT);
}
return;
case ID:
JS_SET_TRACING_NAME(trc, "js::AutoIdRooter.val");
js_CallValueTracerIfGCThing(trc, static_cast<AutoIdRooter *>(this)->idval);
return;
case VECTOR: {
js::Vector<jsval, 8> &vector = static_cast<js::AutoValueVector *>(this)->vector;
js::TraceValues(trc, vector.length(), vector.begin(), "js::AutoValueVector.vector");
return;
}
}
JS_ASSERT(tag >= 0);
TraceValues(trc, tag, static_cast<AutoArrayRooter *>(this)->array, "js::AutoArrayRooter.array");
}
void
js_TraceContext(JSTracer *trc, JSContext *acx)
{

View File

@ -52,6 +52,7 @@
#include "jshash.h" /* Added by JSIFY */
#include "jspubtd.h"
#include "jsprvtd.h"
#include "jsvector.h"
namespace js { class AutoDescriptorArray; }
@ -135,6 +136,10 @@ struct PropertyDescriptor {
bool hasConfigurable : 1;
};
namespace js {
typedef Vector<PropertyDescriptor, 1> PropertyDescriptorArray;
}
JS_BEGIN_EXTERN_C
/* For detailed comments on these function pointer types, see jsprvtd.h. */

View File

@ -50,6 +50,7 @@
#include "jsdtracef.h"
#include "jscntxt.h"
#include "jsscopeinlines.h"
inline void
@ -526,25 +527,8 @@ JSObject::unbrand(JSContext *cx)
return true;
}
inline bool
JSObject::isCallable()
{
if (isNative())
return isFunction() || getClass()->call;
return !!map->ops->call;
}
static inline bool
js_IsCallable(jsval v)
{
return !JSVAL_IS_PRIMITIVE(v) && JSVAL_TO_OBJECT(v)->isCallable();
}
namespace js {
typedef Vector<PropertyDescriptor, 1> PropertyDescriptorArray;
class AutoDescriptorArray : private AutoGCRooter
{
public:

View File

@ -980,54 +980,6 @@ JSScope::canProvideEmptyScope(JSObjectOps *ops, JSClass *clasp)
return this->ops == ops && (!emptyScope || emptyScope->clasp == clasp);
}
inline bool
JSScopeProperty::get(JSContext* cx, JSObject* obj, JSObject *pobj, jsval* vp)
{
JS_ASSERT(!JSVAL_IS_NULL(this->id));
JS_ASSERT(!hasDefaultGetter());
if (hasGetterValue()) {
JS_ASSERT(!isMethod());
jsval fval = getterValue();
return js_InternalGetOrSet(cx, obj, id, fval, JSACC_READ, 0, 0, vp);
}
if (isMethod()) {
*vp = methodValue();
JSScope *scope = pobj->scope();
JS_ASSERT(scope->object == pobj);
return scope->methodReadBarrier(cx, this, vp);
}
/*
* |with (it) color;| ends up here, as do XML filter-expressions.
* Avoid exposing the With object to native getters.
*/
if (obj->getClass() == &js_WithClass)
obj = js_UnwrapWithObject(cx, obj);
return getterOp()(cx, obj, SPROP_USERID(this), vp);
}
inline bool
JSScopeProperty::set(JSContext* cx, JSObject* obj, jsval* vp)
{
JS_ASSERT_IF(hasDefaultSetter(), hasGetterValue());
if (attrs & JSPROP_SETTER) {
jsval fval = setterValue();
return js_InternalGetOrSet(cx, obj, id, fval, JSACC_WRITE, 1, vp, vp);
}
if (attrs & JSPROP_GETTER)
return !!js_ReportGetterOnlyAssignment(cx);
/* See the comment in JSScopeProperty::get as to why we check for With. */
if (obj->getClass() == &js_WithClass)
obj = js_UnwrapWithObject(cx, obj);
return setterOp()(cx, obj, SPROP_USERID(this), vp);
}
inline bool
JSScopeProperty::isSharedPermanent() const
{

View File

@ -260,4 +260,52 @@ JSScopeProperty::matchesParamsAfterId(JSPropertyOp agetter, JSPropertyOp asetter
shortid == ashortid;
}
inline bool
JSScopeProperty::get(JSContext* cx, JSObject* obj, JSObject *pobj, jsval* vp)
{
JS_ASSERT(!JSVAL_IS_NULL(this->id));
JS_ASSERT(!hasDefaultGetter());
if (hasGetterValue()) {
JS_ASSERT(!isMethod());
jsval fval = getterValue();
return js_InternalGetOrSet(cx, obj, id, fval, JSACC_READ, 0, 0, vp);
}
if (isMethod()) {
*vp = methodValue();
JSScope *scope = pobj->scope();
JS_ASSERT(scope->object == pobj);
return scope->methodReadBarrier(cx, this, vp);
}
/*
* |with (it) color;| ends up here, as do XML filter-expressions.
* Avoid exposing the With object to native getters.
*/
if (obj->getClass() == &js_WithClass)
obj = js_UnwrapWithObject(cx, obj);
return getterOp()(cx, obj, SPROP_USERID(this), vp);
}
inline bool
JSScopeProperty::set(JSContext* cx, JSObject* obj, jsval* vp)
{
JS_ASSERT_IF(hasDefaultSetter(), hasGetterValue());
if (attrs & JSPROP_SETTER) {
jsval fval = setterValue();
return js_InternalGetOrSet(cx, obj, id, fval, JSACC_WRITE, 1, vp, vp);
}
if (attrs & JSPROP_GETTER)
return !!js_ReportGetterOnlyAssignment(cx);
/* See the comment in JSScopeProperty::get as to why we check for With. */
if (obj->getClass() == &js_WithClass)
obj = js_UnwrapWithObject(cx, obj);
return setterOp()(cx, obj, SPROP_USERID(this), vp);
}
#endif /* jsscopeinlines_h___ */