зеркало из https://github.com/mozilla/gecko-dev.git
Back out a9764c9ec124, d8aac2bd90db, d167f7fbb53e, and ca7b13e02cd5 for not-entirely-trivial build bustage. r=bustage
This commit is contained in:
Родитель
b061d084fb
Коммит
3210d29c48
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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__ */
|
||||
|
|
Загрузка…
Ссылка в новой задаче