Back out a9764c9ec124, d8aac2bd90db, d167f7fbb53e, and ca7b13e02cd5 for not-entirely-trivial build bustage. r=bustage

This commit is contained in:
Jeff Walden 2012-04-24 16:47:28 -07:00
parent c9c6ded92f
commit 27d927a159
3 changed files with 10 additions and 560 deletions

View File

@ -703,14 +703,6 @@ MagicValue(JSWhyMagic why)
return v;
}
static JS_ALWAYS_INLINE Value
NumberValue(float f)
{
Value v;
v.setNumber(f);
return v;
}
static JS_ALWAYS_INLINE Value
NumberValue(double dbl)
{
@ -719,56 +711,6 @@ NumberValue(double dbl)
return v;
}
static JS_ALWAYS_INLINE Value
NumberValue(int8_t i)
{
return Int32Value(i);
}
static JS_ALWAYS_INLINE Value
NumberValue(uint8_t i)
{
return Int32Value(i);
}
static JS_ALWAYS_INLINE Value
NumberValue(int16_t i)
{
return Int32Value(i);
}
static JS_ALWAYS_INLINE Value
NumberValue(uint16_t i)
{
return Int32Value(i);
}
static JS_ALWAYS_INLINE Value
NumberValue(int32_t i)
{
return Int32Value(i);
}
static JS_ALWAYS_INLINE Value
NumberValue(uint32_t i)
{
Value v;
v.setNumber(i);
return v;
}
static JS_ALWAYS_INLINE Value
NumberValue(uint64_t i)
{
MOZ_ASSERT(uint64_t(double(i)) == i, "value creation from uint64_t was lossy");
Value v;
if (i > JSVAL_INT_MAX)
v.setDouble(i);
else
v.setInt32(int32_t(i));
return v;
}
static JS_ALWAYS_INLINE Value
ObjectOrNullValue(JSObject *obj)
{

View File

@ -11,8 +11,6 @@
#include "jsscope.h"
#include "jsobjinlines.h"
#include "js/TemplateLib.h"
#include "Debugger.h"
#include "ObjectImpl.h"
@ -290,63 +288,6 @@ js::ObjectImpl::markChildren(JSTracer *trc)
MarkObjectSlots(trc, obj, 0, obj->slotSpan());
}
bool
DenseElementsHeader::getOwnElement(JSContext *cx, ObjectImpl *obj, uint32_t index, PropDesc *desc)
{
MOZ_ASSERT(this == &obj->elementsHeader());
uint32_t len = initializedLength();
if (index >= len) {
*desc = PropDesc::undefined();
return true;
}
HeapSlot &slot = obj->elements[index];
if (slot.isMagic(JS_ARRAY_HOLE)) {
*desc = PropDesc::undefined();
return true;
}
*desc = PropDesc(slot, PropDesc::Writable, PropDesc::Enumerable, PropDesc::Configurable);
return true;
}
bool
SparseElementsHeader::getOwnElement(JSContext *cx, ObjectImpl *obj, uint32_t index, PropDesc *desc)
{
MOZ_ASSERT(this == &obj->elementsHeader());
MOZ_NOT_REACHED("NYI");
return false;
}
template<typename T>
bool
TypedElementsHeader<T>::getOwnElement(JSContext *cx, ObjectImpl *obj, uint32_t index,
PropDesc *desc)
{
MOZ_ASSERT(this == &obj->elementsHeader());
if (index >= length()) {
*desc = PropDesc::undefined();
return true;
}
*desc = PropDesc(NumberValue(getElement(index)), PropDesc::Writable,
PropDesc::Enumerable, PropDesc::Configurable);
return false;
}
bool
ArrayBufferElementsHeader::getOwnElement(JSContext *cx, ObjectImpl *obj, uint32_t index,
PropDesc *desc)
{
MOZ_ASSERT(this == &obj->elementsHeader());
MOZ_NOT_REACHED("NYI");
return false;
}
bool
SparseElementsHeader::defineElement(JSContext *cx, ObjectImpl *obj, uint32_t index,
const PropDesc &desc, bool shouldThrow, bool *succeeded)
@ -404,7 +345,7 @@ DenseElementsHeader::defineElement(JSContext *cx, ObjectImpl *obj, uint32_t inde
return true;
MOZ_ALWAYS_FALSE(js_ReportValueErrorFlags(cx, JSREPORT_ERROR, JSMSG_OBJECT_NOT_EXTENSIBLE,
JSDVG_IGNORE_STACK,
ObjectValue(*obj),
ObjectValue(*obj->asObjectPtr()),
NULL, NULL, NULL));
return false;
}
@ -452,7 +393,7 @@ TypedElementsHeader<T>::defineElement(JSContext *cx, ObjectImpl *obj,
*succeeded = false;
js_ReportValueErrorFlags(cx, JSREPORT_ERROR, JSMSG_OBJECT_NOT_EXTENSIBLE,
JSDVG_IGNORE_STACK,
ObjectValue(*obj),
ObjectValue(*(JSObject*)obj), // XXX jwalden dodgy cast
NULL, NULL, NULL);
return false;
}
@ -470,133 +411,6 @@ ArrayBufferElementsHeader::defineElement(JSContext *cx, ObjectImpl *obj,
return DefineElement(cx, delegate, index, desc, shouldThrow, succeeded);
}
bool
js::GetOwnElement(JSContext *cx, ObjectImpl *obj, uint32_t index, PropDesc *desc)
{
ElementsHeader &header = obj->elementsHeader();
switch (header.kind()) {
case DenseElements:
return header.asDenseElements().getOwnElement(cx, obj, index, desc);
case SparseElements:
return header.asSparseElements().getOwnElement(cx, obj, index, desc);
case Uint8Elements:
return header.asUint8Elements().getOwnElement(cx, obj, index, desc);
case Int8Elements:
return header.asInt8Elements().getOwnElement(cx, obj, index, desc);
case Uint16Elements:
return header.asUint16Elements().getOwnElement(cx, obj, index, desc);
case Int16Elements:
return header.asInt16Elements().getOwnElement(cx, obj, index, desc);
case Uint32Elements:
return header.asUint32Elements().getOwnElement(cx, obj, index, desc);
case Int32Elements:
return header.asInt32Elements().getOwnElement(cx, obj, index, desc);
case Uint8ClampedElements:
return header.asUint8ClampedElements().getOwnElement(cx, obj, index, desc);
case Float32Elements:
return header.asFloat32Elements().getOwnElement(cx, obj, index, desc);
case Float64Elements:
return header.asFloat64Elements().getOwnElement(cx, obj, index, desc);
case ArrayBufferElements:
return header.asArrayBufferElements().getOwnElement(cx, obj, index, desc);
}
MOZ_NOT_REACHED("bad elements kind!");
return false;
}
bool
js::GetElement(JSContext *cx, ObjectImpl *obj, ObjectImpl *receiver, uint32_t index,
Value *vp)
{
NEW_OBJECT_REPRESENTATION_ONLY();
do {
MOZ_ASSERT(obj);
if (static_cast<JSObject *>(obj)->isProxy()) { // XXX
MOZ_NOT_REACHED("NYI: proxy [[GetP]]");
return false;
}
PropDesc desc;
if (!GetOwnElement(cx, obj, index, &desc))
return false;
/* No property? Recur or bottom out. */
if (desc.isUndefined()) {
obj = obj->getProto();
if (obj)
continue;
vp->setUndefined();
return true;
}
/* If it's a data property, return the value. */
if (desc.isDataDescriptor()) {
*vp = desc.value();
return true;
}
/* If it's an accessor property, call its [[Get]] with the receiver. */
if (desc.isAccessorDescriptor()) {
Value get = desc.getterValue();
if (get.isUndefined()) {
vp->setUndefined();
return true;
}
InvokeArgsGuard args;
if (!cx->stack.pushInvokeArgs(cx, 0, &args))
return false;
/* Push get, receiver, and no args. */
args.calleev() = get;
args.thisv() = ObjectValue(*receiver);
bool ok = Invoke(cx, args);
*vp = args.rval();
return ok;
}
/* Otherwise it's a PropertyOp-based property. XXX handle this! */
MOZ_NOT_REACHED("NYI: handle PropertyOp'd properties here");
return false;
} while (false);
}
bool
js::HasElement(JSContext *cx, ObjectImpl *obj, uint32_t index, bool *found)
{
NEW_OBJECT_REPRESENTATION_ONLY();
do {
MOZ_ASSERT(obj);
if (static_cast<JSObject *>(obj)->isProxy()) { // XXX
MOZ_NOT_REACHED("NYI: proxy [[HasProperty]]");
return false;
}
PropDesc prop;
if (!GetOwnElement(cx, obj, index, &prop))
return false;
if (!prop.isUndefined()) {
*found = true;
return true;
}
obj = obj->getProto();
if (obj)
continue;
*found = false;
return true;
} while (false);
}
bool
js::DefineElement(JSContext *cx, ObjectImpl *obj, uint32_t index, const PropDesc &desc,
bool shouldThrow, bool *succeeded)
@ -647,144 +461,3 @@ js::DefineElement(JSContext *cx, ObjectImpl *obj, uint32_t index, const PropDesc
MOZ_NOT_REACHED("bad elements kind!");
return false;
}
bool
SparseElementsHeader::setElement(JSContext *cx, ObjectImpl *obj, ObjectImpl *receiver,
uint32_t index, const Value &v, bool *succeeded)
{
MOZ_ASSERT(this == &obj->elementsHeader());
MOZ_NOT_REACHED("NYI");
return false;
}
bool
DenseElementsHeader::setElement(JSContext *cx, ObjectImpl *obj, ObjectImpl *receiver,
uint32_t index, const Value &v, bool *succeeded)
{
MOZ_ASSERT(this == &obj->elementsHeader());
MOZ_NOT_REACHED("NYI");
return false;
}
template <typename T>
bool
TypedElementsHeader<T>::setElement(JSContext *cx, ObjectImpl *obj, ObjectImpl *receiver,
uint32_t index, const Value &v, bool *succeeded)
{
MOZ_ASSERT(this == &obj->elementsHeader());
uint32_t len = length();
if (index >= len) {
/*
* Silent ignore is better than an exception here, because at some
* point we may want to support other properties on these objects.
*/
*succeeded = true;
return true;
}
/* Convert the value being set to the element type. */
double d;
if (v.isNumber()) {
d = v.toNumber();
} else if (v.isNull()) {
d = 0.0;
} else if (v.isPrimitive()) {
if (v.isString()) {
if (!ToNumber(cx, v, &d))
return false;
} else if (v.isUndefined()) {
d = js_NaN;
} else {
d = double(v.toBoolean());
}
} else {
// non-primitive assignments become NaN or 0 (for float/int arrays)
d = js_NaN;
}
assign(index, d);
*succeeded = true;
return true;
}
bool
ArrayBufferElementsHeader::setElement(JSContext *cx, ObjectImpl *obj, ObjectImpl *receiver,
uint32_t index, const Value &v, bool *succeeded)
{
MOZ_ASSERT(this == &obj->elementsHeader());
JSObject *delegate = ArrayBufferDelegate(cx, obj);
if (!delegate)
return false;
return SetElement(cx, obj, receiver, index, v, succeeded);
}
bool
js::SetElement(JSContext *cx, ObjectImpl *obj, ObjectImpl *receiver, uint32_t index,
const Value &v, bool *succeeded)
{
NEW_OBJECT_REPRESENTATION_ONLY();
do {
MOZ_ASSERT(obj);
if (static_cast<JSObject *>(obj)->isProxy()) { // XXX
MOZ_NOT_REACHED("NYI: proxy [[SetP]]");
return false;
}
PropDesc ownDesc;
if (!GetOwnElement(cx, obj, index, &ownDesc))
return false;
if (!ownDesc.isUndefined()) {
if (ownDesc.isDataDescriptor()) {
if (!ownDesc.writable()) {
*succeeded = false;
return true;
}
if (receiver == obj) {
PropDesc updateDesc = PropDesc::valueOnly(v);
return DefineElement(cx, receiver, index, updateDesc, false, succeeded);
}
PropDesc newDesc;
return DefineElement(cx, receiver, index, newDesc, false, succeeded);
}
if (ownDesc.isAccessorDescriptor()) {
Value setter = ownDesc.setterValue();
if (setter.isUndefined()) {
*succeeded = false;
return true;
}
InvokeArgsGuard args;
if (!cx->stack.pushInvokeArgs(cx, 1, &args))
return false;
/* Push set, receiver, and v as the sole argument. */
args.calleev() = setter;
args.thisv() = ObjectValue(*receiver);
args[0] = v;
*succeeded = true;
return Invoke(cx, args);
}
MOZ_NOT_REACHED("NYI: setting PropertyOp-based property");
return false;
}
obj = obj->getProto();
if (obj)
continue;
PropDesc newDesc(v, PropDesc::Writable, PropDesc::Enumerable, PropDesc::Configurable);
return DefineElement(cx, receiver, index, newDesc, false, succeeded);
} while (false);
}

View File

@ -16,7 +16,6 @@
#include "jsval.h"
#include "gc/Barrier.h"
#include "vm/NumericConversions.h"
namespace js {
@ -65,43 +64,12 @@ struct PropDesc {
/* Or maybe this represents a property's absence, and it's undefined. */
bool isUndefined_ : 1;
PropDesc(const Value &v)
: pd_(UndefinedValue()),
value_(v),
get_(UndefinedValue()), set_(UndefinedValue()),
attrs(0),
hasGet_(false), hasSet_(false),
hasValue_(true), hasWritable_(false), hasEnumerable_(false), hasConfigurable_(false),
isUndefined_(false)
{
}
public:
friend class AutoPropDescArrayRooter;
friend void JS::AutoGCRooter::trace(JSTracer *trc);
enum Enumerability { Enumerable = true, NonEnumerable = false };
enum Configurability { Configurable = true, NonConfigurable = false };
enum Writability { Writable = true, NonWritable = false };
PropDesc();
static PropDesc undefined() { return PropDesc(); }
static PropDesc valueOnly(const Value &v) { return PropDesc(v); }
PropDesc(const Value &v, Writability writable,
Enumerability enumerable, Configurability configurable)
: pd_(UndefinedValue()),
value_(v),
get_(UndefinedValue()), set_(UndefinedValue()),
attrs((writable ? 0 : JSPROP_READONLY) |
(enumerable ? JSPROP_ENUMERATE : 0) |
(configurable ? 0 : JSPROP_PERMANENT)),
hasGet_(false), hasSet_(false),
hasValue_(true), hasWritable_(true), hasEnumerable_(true), hasConfigurable_(true),
isUndefined_(false)
{}
/*
* 8.10.5 ToPropertyDescriptor(Obj)
*
@ -126,6 +94,8 @@ struct PropDesc {
void initFromPropertyDescriptor(const PropertyDescriptor &desc);
bool makeObject(JSContext *cx);
void setUndefined() { isUndefined_ = true; }
bool isUndefined() const { return isUndefined_; }
bool hasGet() const { MOZ_ASSERT(!isUndefined()); return hasGet_; }
@ -237,16 +207,11 @@ class Int32ElementsHeader;
class Uint8ClampedElementsHeader;
class Float32ElementsHeader;
class Float64ElementsHeader;
class Uint8ClampedElementsHeader;
class ArrayBufferElementsHeader;
enum ElementsKind {
DenseElements,
SparseElements,
ArrayBufferElements,
/* These typed element types must remain contiguous. */
Uint8Elements,
Int8Elements,
Uint16Elements,
@ -255,14 +220,15 @@ enum ElementsKind {
Int32Elements,
Uint8ClampedElements,
Float32Elements,
Float64Elements
Float64Elements,
ArrayBufferElements
};
class ElementsHeader
{
protected:
uint32_t type;
uint32_t length; /* Array length, ArrayBuffer length, typed array length */
uint32_t length; /* Array length, byte length of ArrayBuffer */
union {
class {
@ -289,7 +255,6 @@ class ElementsHeader
inline bool isDenseElements() const { return kind() == DenseElements; }
inline bool isSparseElements() const { return kind() == SparseElements; }
inline bool isArrayBufferElements() const { return kind() == ArrayBufferElements; }
inline bool isUint8Elements() const { return kind() == Uint8Elements; }
inline bool isInt8Elements() const { return kind() == Int8Elements; }
inline bool isUint16Elements() const { return kind() == Uint16Elements; }
@ -299,10 +264,10 @@ class ElementsHeader
inline bool isUint8ClampedElements() const { return kind() == Uint8ClampedElements; }
inline bool isFloat32Elements() const { return kind() == Float32Elements; }
inline bool isFloat64Elements() const { return kind() == Float64Elements; }
inline bool isArrayBufferElements() const { return kind() == ArrayBufferElements; }
inline DenseElementsHeader & asDenseElements();
inline SparseElementsHeader & asSparseElements();
inline ArrayBufferElementsHeader & asArrayBufferElements();
inline Uint8ElementsHeader & asUint8Elements();
inline Int8ElementsHeader & asInt8Elements();
inline Uint16ElementsHeader & asUint16Elements();
@ -312,6 +277,7 @@ class ElementsHeader
inline Uint8ClampedElementsHeader & asUint8ClampedElements();
inline Float32ElementsHeader & asFloat32Elements();
inline Float64ElementsHeader & asFloat64Elements();
inline ArrayBufferElementsHeader & asArrayBufferElements();
static ElementsHeader * fromElements(HeapSlot *elems) {
return reinterpret_cast<ElementsHeader *>(uintptr_t(elems) - sizeof(ElementsHeader));
@ -338,14 +304,9 @@ class DenseElementsHeader : public ElementsHeader
return ElementsHeader::length;
}
bool getOwnElement(JSContext *cx, ObjectImpl *obj, uint32_t index, PropDesc *desc);
bool defineElement(JSContext *cx, ObjectImpl *obj, uint32_t index, const PropDesc &desc,
bool shouldThrow, bool *succeeded);
bool setElement(JSContext *cx, ObjectImpl *obj, ObjectImpl *receiver, uint32_t index,
const Value &v, bool *succeeded);
private:
inline bool isDenseElements() const MOZ_DELETE;
inline DenseElementsHeader & asDenseElements() MOZ_DELETE;
@ -367,14 +328,9 @@ class SparseElementsHeader : public ElementsHeader
return ElementsHeader::length;
}
bool getOwnElement(JSContext *cx, ObjectImpl *obj, uint32_t index, PropDesc *desc);
bool defineElement(JSContext *cx, ObjectImpl *obj, uint32_t index, const PropDesc &desc,
bool shouldThrow, bool *succeeded);
bool setElement(JSContext *cx, ObjectImpl *obj, ObjectImpl *receiver, uint32_t index,
const Value &v, bool *succeeded);
private:
inline bool isSparseElements() const MOZ_DELETE;
inline SparseElementsHeader & asSparseElements() MOZ_DELETE;
@ -475,107 +431,19 @@ template<> inline const bool TypeIsUint8Clamped<uint8_clamped>() { return true;
template <typename T>
class TypedElementsHeader : public ElementsHeader
{
T getElement(uint32_t index) {
MOZ_ASSERT(index < length());
return reinterpret_cast<T *>(this + 1)[index];
}
inline void assign(uint32_t index, double d);
void setElement(uint32_t index, T value) {
MOZ_ASSERT(index < length());
reinterpret_cast<T *>(this + 1)[index] = value;
}
public:
uint32_t length() const {
MOZ_ASSERT(Uint8Elements <= kind());
MOZ_ASSERT(kind() <= Float64Elements);
uint32_t byteLength() const {
return ElementsHeader::length;
}
bool getOwnElement(JSContext *cx, ObjectImpl *obj, uint32_t index, PropDesc *desc);
bool defineElement(JSContext *cx, ObjectImpl *obj, uint32_t index, const PropDesc &desc,
bool shouldThrow, bool *succeeded);
bool setElement(JSContext *cx, ObjectImpl *obj, ObjectImpl *receiver, uint32_t index,
const Value &v, bool *succeeded);
private:
TypedElementsHeader(const TypedElementsHeader &other) MOZ_DELETE;
void operator=(const TypedElementsHeader &other) MOZ_DELETE;
};
template<typename T> inline void
TypedElementsHeader<T>::assign(uint32_t index, double d)
{
MOZ_NOT_REACHED("didn't specialize for this element type");
}
template<> inline void
TypedElementsHeader<uint8_clamped>::assign(uint32_t index, double d)
{
double i = ToInteger(d);
uint8_t u = (i <= 0)
? 0
: (i >= 255)
? 255
: uint8_t(i);
setElement(index, uint8_clamped(u));
}
template<> inline void
TypedElementsHeader<uint8_t>::assign(uint32_t index, double d)
{
setElement(index, uint8_t(ToUint32(d)));
}
template<> inline void
TypedElementsHeader<int8_t>::assign(uint32_t index, double d)
{
/* FIXME: Casting out-of-range signed integers has undefined behavior! */
setElement(index, int8_t(ToInt32(d)));
}
template<> inline void
TypedElementsHeader<uint16_t>::assign(uint32_t index, double d)
{
setElement(index, uint16_t(ToUint32(d)));
}
template<> inline void
TypedElementsHeader<int16_t>::assign(uint32_t index, double d)
{
/* FIXME: Casting out-of-range signed integers has undefined behavior! */
setElement(index, int16_t(ToInt32(d)));
}
template<> inline void
TypedElementsHeader<uint32_t>::assign(uint32_t index, double d)
{
setElement(index, ToUint32(d));
}
template<> inline void
TypedElementsHeader<int32_t>::assign(uint32_t index, double d)
{
/* FIXME: Casting out-of-range signed integers has undefined behavior! */
setElement(index, int32_t(ToInt32(d)));
}
template<> inline void
TypedElementsHeader<float>::assign(uint32_t index, double d)
{
setElement(index, float(d));
}
template<> inline void
TypedElementsHeader<double>::assign(uint32_t index, double d)
{
setElement(index, d);
}
class Uint8ElementsHeader : public TypedElementsHeader<uint8_t>
{
private:
@ -653,14 +521,9 @@ class Uint8ClampedElementsHeader : public TypedElementsHeader<uint8_clamped>
class ArrayBufferElementsHeader : public ElementsHeader
{
public:
bool getOwnElement(JSContext *cx, ObjectImpl *obj, uint32_t index, PropDesc *desc);
bool defineElement(JSContext *cx, ObjectImpl *obj, uint32_t index, const PropDesc &desc,
bool shouldThrow, bool *succeeded);
bool setElement(JSContext *cx, ObjectImpl *obj, ObjectImpl *receiver, uint32_t index,
const Value &v, bool *succeeded);
private:
inline bool isArrayBufferElements() const MOZ_DELETE;
inline ArrayBufferElementsHeader & asArrayBufferElements() MOZ_DELETE;
@ -823,9 +686,6 @@ struct Shape;
class NewObjectCache;
inline Value
ObjectValue(ObjectImpl &obj);
/*
* ObjectImpl specifies the internal implementation of an object. (In contrast
* JSObject specifies an "external" interface, at the conceptual level of that
@ -912,8 +772,6 @@ class ObjectImpl : public gc::Cell
JSObject * asObjectPtr() { return reinterpret_cast<JSObject *>(this); }
friend inline Value ObjectValue(ObjectImpl &obj);
/* These functions are public, and they should remain public. */
public:
@ -1224,33 +1082,10 @@ class ObjectImpl : public gc::Cell
static size_t offsetOfSlots() { return offsetof(ObjectImpl, slots); }
};
inline Value
ObjectValue(ObjectImpl &obj)
{
Value v;
v.setObject(*obj.asObjectPtr());
return v;
}
bool
GetOwnElement(JSContext *cx, ObjectImpl *obj, uint32_t index, PropDesc *desc);
/* Proposed default [[GetP]](Receiver, P) method. */
extern bool
GetElement(JSContext *cx, ObjectImpl *obj, ObjectImpl *receiver, uint32_t index, Value *vp);
extern bool
DefineElement(JSContext *cx, ObjectImpl *obj, uint32_t index, const PropDesc &desc,
bool shouldThrow, bool *succeeded);
/* Proposed default [[SetP]](Receiver, P, V) method. */
extern bool
SetElement(JSContext *cx, ObjectImpl *obj, ObjectImpl *receiver, uint32_t index, const Value &v,
bool *succeeded);
extern bool
HasElement(JSContext *cx, ObjectImpl *obj, uint32_t index, bool *found);
} /* namespace js */
#endif /* ObjectImpl_h__ */