mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
fix jsiter, convert jsmath
This commit is contained in:
parent
588e08228c
commit
36fb0452a3
@ -3351,6 +3351,8 @@ class Value
|
|||||||
data.dbl = d;
|
data.dbl = d;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void setNumber(double d);
|
||||||
|
|
||||||
double &asDoubleRef() {
|
double &asDoubleRef() {
|
||||||
JS_ASSERT(size_t(&data.dbl) % sizeof(double) == 0);
|
JS_ASSERT(size_t(&data.dbl) % sizeof(double) == 0);
|
||||||
JS_ASSERT(isDouble());
|
JS_ASSERT(isDouble());
|
||||||
@ -3622,6 +3624,7 @@ struct AssertLayoutCompatible
|
|||||||
/* XXX: this is a temporary hack until copying is implicit. */
|
/* XXX: this is a temporary hack until copying is implicit. */
|
||||||
struct CopyableValue : Value
|
struct CopyableValue : Value
|
||||||
{
|
{
|
||||||
|
CopyableValue() {}
|
||||||
CopyableValue(NullTag arg) : Value(arg) {}
|
CopyableValue(NullTag arg) : Value(arg) {}
|
||||||
CopyableValue(UndefinedTag arg) : Value(arg) {}
|
CopyableValue(UndefinedTag arg) : Value(arg) {}
|
||||||
CopyableValue(Int32Tag arg) : Value(arg) {}
|
CopyableValue(Int32Tag arg) : Value(arg) {}
|
||||||
@ -3629,7 +3632,7 @@ struct CopyableValue : Value
|
|||||||
CopyableValue(JSString *arg) : Value(arg) {}
|
CopyableValue(JSString *arg) : Value(arg) {}
|
||||||
CopyableValue(FunObjTag arg) : Value(arg) {}
|
CopyableValue(FunObjTag arg) : Value(arg) {}
|
||||||
CopyableValue(NonFunObjTag arg) : Value(arg) {}
|
CopyableValue(NonFunObjTag arg) : Value(arg) {}
|
||||||
CopyableValue(ObjectTag arg) : Value(arg) {}
|
inline CopyableValue(ObjectTag arg);
|
||||||
CopyableValue(BooleanTag arg) : Value(arg) {}
|
CopyableValue(BooleanTag arg) : Value(arg) {}
|
||||||
CopyableValue(JSWhyMagic arg) : Value(arg) {}
|
CopyableValue(JSWhyMagic arg) : Value(arg) {}
|
||||||
};
|
};
|
||||||
|
@ -2205,7 +2205,8 @@ class AutoGCRooter {
|
|||||||
XML = -10, /* js::AutoXMLRooter */
|
XML = -10, /* js::AutoXMLRooter */
|
||||||
OBJECT = -11, /* js::AutoObjectRooter */
|
OBJECT = -11, /* js::AutoObjectRooter */
|
||||||
ID = -12, /* js::AutoIdRooter */
|
ID = -12, /* js::AutoIdRooter */
|
||||||
VECTOR = -13 /* js::AutoValueVector */
|
VALVECTOR = -13, /* js::AutoValueVector */
|
||||||
|
BOXEDVECTOR = -14 /* js::AutoBoxedWordVector */
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -2985,7 +2986,7 @@ class AutoValueVector : private AutoGCRooter
|
|||||||
public:
|
public:
|
||||||
explicit AutoValueVector(JSContext *cx
|
explicit AutoValueVector(JSContext *cx
|
||||||
JS_GUARD_OBJECT_NOTIFIER_PARAM)
|
JS_GUARD_OBJECT_NOTIFIER_PARAM)
|
||||||
: AutoGCRooter(cx, VECTOR), vector(cx)
|
: AutoGCRooter(cx, VALVECTOR), vector(cx)
|
||||||
{
|
{
|
||||||
JS_GUARD_OBJECT_NOTIFIER_INIT;
|
JS_GUARD_OBJECT_NOTIFIER_INIT;
|
||||||
}
|
}
|
||||||
@ -3023,6 +3024,48 @@ class AutoValueVector : private AutoGCRooter
|
|||||||
JS_DECL_USE_GUARD_OBJECT_NOTIFIER
|
JS_DECL_USE_GUARD_OBJECT_NOTIFIER
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class AutoBoxedWordVector : private AutoGCRooter
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit AutoBoxedWordVector(JSContext *cx
|
||||||
|
JS_GUARD_OBJECT_NOTIFIER_PARAM)
|
||||||
|
: AutoGCRooter(cx, BOXEDVECTOR), vector(cx)
|
||||||
|
{
|
||||||
|
JS_GUARD_OBJECT_NOTIFIER_INIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t length() const { return vector.length(); }
|
||||||
|
|
||||||
|
bool append(jsid id) { return vector.append(id); }
|
||||||
|
|
||||||
|
void popBack() { vector.popBack(); }
|
||||||
|
|
||||||
|
bool resize(size_t newLength) {
|
||||||
|
return vector.resize(newLength);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool reserve(size_t newLength) {
|
||||||
|
return vector.reserve(newLength);
|
||||||
|
}
|
||||||
|
|
||||||
|
jsid operator[](size_t i) { return vector[i]; }
|
||||||
|
jsid operator[](size_t i) const { return vector[i]; }
|
||||||
|
|
||||||
|
const jsid *begin() const { return vector.begin(); }
|
||||||
|
jsid *begin() { return vector.begin(); }
|
||||||
|
|
||||||
|
const jsid *end() const { return vector.end(); }
|
||||||
|
jsid *end() { return vector.end(); }
|
||||||
|
|
||||||
|
jsid back() const { return vector.back(); }
|
||||||
|
|
||||||
|
friend void AutoGCRooter::trace(JSTracer *trc);
|
||||||
|
|
||||||
|
private:
|
||||||
|
Vector<jsboxedword, 8> vector;
|
||||||
|
JS_DECL_USE_GUARD_OBJECT_NOTIFIER
|
||||||
|
};
|
||||||
|
|
||||||
static JS_ALWAYS_INLINE void
|
static JS_ALWAYS_INLINE void
|
||||||
SetValueRangeToUndefined(Value *vec, Value *end)
|
SetValueRangeToUndefined(Value *vec, Value *end)
|
||||||
{
|
{
|
||||||
|
@ -257,11 +257,17 @@ AutoGCRooter::trace(JSTracer *trc)
|
|||||||
CallGCMarkerIfGCThing(trc, static_cast<AutoIdRooter *>(this)->idval);
|
CallGCMarkerIfGCThing(trc, static_cast<AutoIdRooter *>(this)->idval);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case VECTOR: {
|
case VALVECTOR: {
|
||||||
Vector<Value, 8> &vector = static_cast<AutoValueVector *>(this)->vector;
|
Vector<Value, 8> &vector = static_cast<AutoValueVector *>(this)->vector;
|
||||||
TraceValues(trc, vector.length(), vector.begin(), "js::AutoValueVector.vector");
|
TraceValues(trc, vector.length(), vector.begin(), "js::AutoValueVector.vector");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case BOXEDVECTOR: {
|
||||||
|
Vector<jsboxedword, 8> &vector = static_cast<AutoBoxedWordVector *>(this)->vector;
|
||||||
|
TraceBoxedWords(trc, vector.length(), vector.begin(), "js::AutoIdVector.vector");
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
JS_ASSERT(tag >= 0);
|
JS_ASSERT(tag >= 0);
|
||||||
|
@ -1125,6 +1125,87 @@ InvokeConstructor(JSContext *cx, const InvokeArgsGuard &args, JSBool clampReturn
|
|||||||
return JS_TRUE;
|
return JS_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CopyableValue
|
||||||
|
BoxedWordToValue(jsboxedword w)
|
||||||
|
{
|
||||||
|
CopyableValue v;
|
||||||
|
if (JSBOXEDWORD_IS_STRING(w))
|
||||||
|
v.setString(JSBOXEDWORD_TO_STRING(w));
|
||||||
|
else if (JSBOXEDWORD_IS_INT(w))
|
||||||
|
v.setInt32(JSBOXEDWORD_TO_INT(w));
|
||||||
|
else if (JSBOXEDWORD_IS_DOUBLE(w))
|
||||||
|
v.setDouble(*JSBOXEDWORD_TO_DOUBLE(w));
|
||||||
|
else if (JSBOXEDWORD_IS_OBJECT(w))
|
||||||
|
v.setObjectOrNull(JSBOXEDWORD_TO_OBJECT(w));
|
||||||
|
else if (JSBOXEDWORD_IS_VOID(w))
|
||||||
|
v.setUndefined();
|
||||||
|
else
|
||||||
|
v.setBoolean(JSBOXEDWORD_TO_BOOLEAN(w));
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
ValueToBoxedWord(JSContext *cx, const Value *vp, jsboxedword *wp)
|
||||||
|
{
|
||||||
|
int32_t i;
|
||||||
|
if (vp->isInt32() &&
|
||||||
|
INT32_FITS_IN_JSID((i = vp->asInt32()))) {
|
||||||
|
*wp = INT_TO_JSBOXEDWORD(i);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (vp->isString()) {
|
||||||
|
*wp = STRING_TO_JSBOXEDWORD(vp->asString());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (vp->isObjectOrNull()) {
|
||||||
|
*wp = OBJECT_TO_JSBOXEDWORD(vp->asObjectOrNull());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (vp->isBoolean()) {
|
||||||
|
*wp = BOOLEAN_TO_JSBOXEDWORD(vp->asBoolean());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (vp->isUndefined()) {
|
||||||
|
*wp = JSBOXEDWORD_VOID;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
double *dp = js_NewWeaklyRootedDoubleAtom(cx, vp->asDouble());
|
||||||
|
if (!dp)
|
||||||
|
return false;
|
||||||
|
*wp = DOUBLE_TO_JSBOXEDWORD(dp);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Value
|
||||||
|
IdToValue(jsid id)
|
||||||
|
{
|
||||||
|
return BoxedWordToValue(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
ValueToId(JSContext *cx, const Value *vp, jsid *idp)
|
||||||
|
{
|
||||||
|
int32_t i;
|
||||||
|
if (ValueFitsInInt32(*vp, &i) && INT32_FITS_IN_JSID(i)) {
|
||||||
|
*idp = INT_TO_JSID(i);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if JS_HAS_XML_SUPPORT
|
||||||
|
if (vp->isObject()) {
|
||||||
|
Class *clasp = vp->asObject().getClass();
|
||||||
|
if (JS_UNLIKELY(clasp == &js_QNameClass.base ||
|
||||||
|
clasp == &js_AttributeNameClass ||
|
||||||
|
clasp == &js_AnyNameClass)) {
|
||||||
|
*idp = OBJECT_TO_JSID(&vp->asObject());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return js_ValueToStringId(cx, *vp, idp);
|
||||||
|
}
|
||||||
|
|
||||||
} /* namespace js */
|
} /* namespace js */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1279,46 +1360,6 @@ js_GetUpvar(JSContext *cx, uintN level, uintN cookie)
|
|||||||
return vp[slot];
|
return vp[slot];
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
|
||||||
ValueToId(JSContext *cx, const Value *vp, jsid *idp)
|
|
||||||
{
|
|
||||||
int32_t i;
|
|
||||||
if (ValueFitsInInt32(*vp, &i) && INT32_FITS_IN_JSID(i)) {
|
|
||||||
*idp = INT_TO_JSID(i);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if JS_HAS_XML_SUPPORT
|
|
||||||
if (vp->isObject()) {
|
|
||||||
Class *clasp = vp->asObject().getClass();
|
|
||||||
if (JS_UNLIKELY(clasp == &js_QNameClass.base ||
|
|
||||||
clasp == &js_AttributeNameClass ||
|
|
||||||
clasp == &js_AnyNameClass)) {
|
|
||||||
*idp = OBJECT_TO_JSID(&vp->asObject());
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return js_ValueToStringId(cx, *vp, idp);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Normally, js::Value should not be passed by value, but this function should
|
|
||||||
* only be used on cold paths, so ease of use wins out.
|
|
||||||
*/
|
|
||||||
Value
|
|
||||||
IdToValue(jsid id)
|
|
||||||
{
|
|
||||||
if (JSID_IS_INT(id))
|
|
||||||
return CopyableValue(Int32Tag(JSID_TO_INT(id)));
|
|
||||||
else if (JSID_IS_ATOM(id))
|
|
||||||
return CopyableValue(ATOM_TO_STRING(JSID_TO_ATOM(id)));
|
|
||||||
else if (JSID_IS_NULL(id))
|
|
||||||
return CopyableValue(NullTag());
|
|
||||||
return CopyableValue(ObjectTag(*JSID_TO_OBJECT(id)));
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
|
|
||||||
JS_STATIC_INTERPRET JS_REQUIRES_STACK void
|
JS_STATIC_INTERPRET JS_REQUIRES_STACK void
|
||||||
@ -1995,7 +2036,7 @@ IteratorNext(JSContext *cx, JSObject *iterobj, Value *rval)
|
|||||||
if (iterobj->getClass() == &js_IteratorClass.base) {
|
if (iterobj->getClass() == &js_IteratorClass.base) {
|
||||||
NativeIterator *ni = (NativeIterator *) iterobj->getPrivate();
|
NativeIterator *ni = (NativeIterator *) iterobj->getPrivate();
|
||||||
JS_ASSERT(ni->props_cursor < ni->props_end);
|
JS_ASSERT(ni->props_cursor < ni->props_end);
|
||||||
BoxedWordToValue(*ni->props_cursor, rval);
|
rval->copy(BoxedWordToValue(*ni->props_cursor));
|
||||||
if (rval->isString() || (ni->flags & JSITER_FOREACH)) {
|
if (rval->isString() || (ni->flags & JSITER_FOREACH)) {
|
||||||
ni->props_cursor++;
|
ni->props_cursor++;
|
||||||
return true;
|
return true;
|
||||||
|
@ -389,29 +389,18 @@ GetInstancePrivate(JSContext *cx, JSObject *obj, Class *clasp, Value *argv)
|
|||||||
return obj->getPrivate();
|
return obj->getPrivate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern CopyableValue
|
||||||
|
BoxedWordToValue(jsboxedword w);
|
||||||
|
|
||||||
|
extern bool
|
||||||
|
ValueToBoxedWord(JSContext *cx, const Value &v, jsboxedword *w);
|
||||||
|
|
||||||
extern Value
|
extern Value
|
||||||
IdToValue(jsid id);
|
IdToValue(jsid id);
|
||||||
|
|
||||||
extern bool
|
extern bool
|
||||||
ValueToId(JSContext *cx, const Value &v, jsid *idp);
|
ValueToId(JSContext *cx, const Value &v, jsid *idp);
|
||||||
|
|
||||||
inline void
|
|
||||||
BoxedWordToValue(jsboxedword w, Value *vp)
|
|
||||||
{
|
|
||||||
if (JSBOXEDWORD_IS_STRING(w))
|
|
||||||
vp->setString(JSBOXEDWORD_TO_STRING(w));
|
|
||||||
else if (JSBOXEDWORD_IS_INT(w))
|
|
||||||
vp->setInt32(JSBOXEDWORD_TO_INT(w));
|
|
||||||
else if (JSBOXEDWORD_IS_DOUBLE(w))
|
|
||||||
vp->setDouble(*JSBOXEDWORD_TO_DOUBLE(w));
|
|
||||||
else if (JSBOXEDWORD_IS_OBJECT(w))
|
|
||||||
vp->setObjectOrNull(JSBOXEDWORD_TO_OBJECT(w));
|
|
||||||
vp->setBoolean(JSBOXEDWORD_TO_BOOLEAN(w));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
ValueToBoxedWord(JSContext *cx, const Value &v, jsboxedword *w);
|
|
||||||
|
|
||||||
} /* namespace js */
|
} /* namespace js */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -133,7 +133,7 @@ iterator_trace(JSTracer *trc, JSObject *obj)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static inline bool
|
static inline bool
|
||||||
NewKeyValuePair(JSContext *cx, const Value &key, const Value &val, Value *rval)
|
NewKeyValuePair(JSContext *cx, const Value &key, const Value &val, jsboxedword *wp)
|
||||||
{
|
{
|
||||||
Value vec[2];
|
Value vec[2];
|
||||||
vec[0].copy(key);
|
vec[0].copy(key);
|
||||||
@ -143,13 +143,13 @@ NewKeyValuePair(JSContext *cx, const Value &key, const Value &val, Value *rval)
|
|||||||
JSObject *aobj = js_NewArrayObject(cx, 2, vec);
|
JSObject *aobj = js_NewArrayObject(cx, 2, vec);
|
||||||
if (!aobj)
|
if (!aobj)
|
||||||
return false;
|
return false;
|
||||||
rval->setNonFunObj(*aobj);
|
*wp = OBJECT_TO_JSBOXEDWORD(aobj);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool
|
static inline bool
|
||||||
Enumerate(JSContext *cx, JSObject *obj, jsid id, bool enumerable, uintN flags,
|
Enumerate(JSContext *cx, JSObject *obj, jsid id, bool enumerable, uintN flags,
|
||||||
HashSet<jsid>& ht, AutoValueVector& vec)
|
Value *tmpRoot, HashSet<jsid>& ht, AutoBoxedWordVector& vec)
|
||||||
{
|
{
|
||||||
JS_ASSERT(JSID_IS_INT(id) || JSID_IS_ATOM(id));
|
JS_ASSERT(JSID_IS_INT(id) || JSID_IS_ATOM(id));
|
||||||
|
|
||||||
@ -165,27 +165,37 @@ Enumerate(JSContext *cx, JSObject *obj, jsid id, bool enumerable, uintN flags,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (enumerable) {
|
if (enumerable) {
|
||||||
Value idval(IdToValue(id));
|
if (!vec.append(id)) {
|
||||||
if (!vec.append(idval)) {
|
|
||||||
JS_ReportOutOfMemory(cx);
|
JS_ReportOutOfMemory(cx);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (flags & JSITER_FOREACH) {
|
if (flags & JSITER_FOREACH) {
|
||||||
Value *vp = vec.end() - 1;
|
jsboxedword *wp = vec.end() - 1;
|
||||||
if (!obj->getProperty(cx, id, vp))
|
if (!obj->getProperty(cx, id, tmpRoot))
|
||||||
return false;
|
return false;
|
||||||
if (flags & JSITER_KEYVALUE && !NewKeyValuePair(cx, idval, *vp, vp))
|
if (flags & JSITER_KEYVALUE) {
|
||||||
|
if (!NewKeyValuePair(cx, IdToValue(id), *tmpRoot, wp))
|
||||||
return false;
|
return false;
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
* TODO: This is expensive and unnecessary if there are a bunch
|
||||||
|
* of doubles. To fix, we need to change the stored type of
|
||||||
|
* iterators to something fatter than jsboxedword when
|
||||||
|
* iterating in a for-each.
|
||||||
|
*/
|
||||||
|
if (!ValueToBoxedWord(cx, *tmpRoot, wp))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
EnumerateNativeProperties(JSContext *cx, JSObject *obj, uintN flags, HashSet<jsid> &ht,
|
EnumerateNativeProperties(JSContext *cx, JSObject *obj, uintN flags, Value *tmpRoot,
|
||||||
AutoValueVector& props)
|
HashSet<jsid> &ht, AutoBoxedWordVector& props)
|
||||||
{
|
{
|
||||||
AutoValueVector sprops(cx);
|
AutoBoxedWordVector sprops(cx);
|
||||||
|
|
||||||
JS_LOCK_OBJ(cx, obj);
|
JS_LOCK_OBJ(cx, obj);
|
||||||
|
|
||||||
@ -194,7 +204,7 @@ EnumerateNativeProperties(JSContext *cx, JSObject *obj, uintN flags, HashSet<jsi
|
|||||||
for (JSScopeProperty *sprop = scope->lastProperty(); sprop; sprop = sprop->parent) {
|
for (JSScopeProperty *sprop = scope->lastProperty(); sprop; sprop = sprop->parent) {
|
||||||
if (!sprop->id != JSBOXEDWORD_VOID &&
|
if (!sprop->id != JSBOXEDWORD_VOID &&
|
||||||
!sprop->isAlias() &&
|
!sprop->isAlias() &&
|
||||||
!Enumerate(cx, obj, sprop->id, sprop->enumerable(), flags, ht, sprops)) {
|
!Enumerate(cx, obj, sprop->id, sprop->enumerable(), flags, tmpRoot, ht, sprops)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -213,8 +223,8 @@ EnumerateNativeProperties(JSContext *cx, JSObject *obj, uintN flags, HashSet<jsi
|
|||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
EnumerateDenseArrayProperties(JSContext *cx, JSObject *obj, uintN flags, HashSet<jsid> &ht,
|
EnumerateDenseArrayProperties(JSContext *cx, JSObject *obj, uintN flags, Value *tmpRoot,
|
||||||
AutoValueVector& props)
|
HashSet<jsid> &ht, AutoBoxedWordVector& props)
|
||||||
{
|
{
|
||||||
size_t count = obj->getDenseArrayCount();
|
size_t count = obj->getDenseArrayCount();
|
||||||
|
|
||||||
@ -224,7 +234,7 @@ EnumerateDenseArrayProperties(JSContext *cx, JSObject *obj, uintN flags, HashSet
|
|||||||
for (size_t i = 0; i < capacity; ++i, ++vp) {
|
for (size_t i = 0; i < capacity; ++i, ++vp) {
|
||||||
if (!vp->isMagic(JS_ARRAY_HOLE)) {
|
if (!vp->isMagic(JS_ARRAY_HOLE)) {
|
||||||
/* Dense arrays never get so large that i would not fit into an integer id. */
|
/* Dense arrays never get so large that i would not fit into an integer id. */
|
||||||
if (!Enumerate(cx, obj, INT_TO_JSID(i), true, flags, ht, props))
|
if (!Enumerate(cx, obj, INT_TO_JSID(i), true, flags, tmpRoot, ht, props))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -242,7 +252,8 @@ InitNativeIterator(JSContext *cx, JSObject *obj, uintN flags, uint32 *sarray, ui
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
AutoValueVector props(cx);
|
AutoBoxedWordVector props(cx);
|
||||||
|
AutoValueRooter avr(cx);
|
||||||
|
|
||||||
while (obj) {
|
while (obj) {
|
||||||
Class *clasp = obj->getClass();
|
Class *clasp = obj->getClass();
|
||||||
@ -251,17 +262,17 @@ InitNativeIterator(JSContext *cx, JSObject *obj, uintN flags, uint32 *sarray, ui
|
|||||||
!(clasp->flags & JSCLASS_NEW_ENUMERATE)) {
|
!(clasp->flags & JSCLASS_NEW_ENUMERATE)) {
|
||||||
if (!clasp->enumerate(cx, obj))
|
if (!clasp->enumerate(cx, obj))
|
||||||
return false;
|
return false;
|
||||||
if (!EnumerateNativeProperties(cx, obj, flags, ht, props))
|
if (!EnumerateNativeProperties(cx, obj, flags, avr.addr(), ht, props))
|
||||||
return false;
|
return false;
|
||||||
} else if (obj->isDenseArray()) {
|
} else if (obj->isDenseArray()) {
|
||||||
if (!EnumerateDenseArrayProperties(cx, obj, flags, ht, props))
|
if (!EnumerateDenseArrayProperties(cx, obj, flags, avr.addr(), ht, props))
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
Value state;
|
Value state;
|
||||||
if (!obj->enumerate(cx, JSENUMERATE_INIT, &state, NULL))
|
if (!obj->enumerate(cx, JSENUMERATE_INIT, &state, NULL))
|
||||||
return false;
|
return false;
|
||||||
if (state.isMagic(JS_NATIVE_ENUMERATE)) {
|
if (state.isMagic(JS_NATIVE_ENUMERATE)) {
|
||||||
if (!EnumerateNativeProperties(cx, obj, flags, ht, props))
|
if (!EnumerateNativeProperties(cx, obj, flags, avr.addr(), ht, props))
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
while (true) {
|
while (true) {
|
||||||
@ -270,7 +281,7 @@ InitNativeIterator(JSContext *cx, JSObject *obj, uintN flags, uint32 *sarray, ui
|
|||||||
return false;
|
return false;
|
||||||
if (state.isNull())
|
if (state.isNull())
|
||||||
break;
|
break;
|
||||||
if (!Enumerate(cx, obj, id, true, flags, ht, props))
|
if (!Enumerate(cx, obj, id, true, flags, avr.addr(), ht, props))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -285,7 +296,7 @@ InitNativeIterator(JSContext *cx, JSObject *obj, uintN flags, uint32 *sarray, ui
|
|||||||
size_t plength = props.length();
|
size_t plength = props.length();
|
||||||
|
|
||||||
NativeIterator *ni = (NativeIterator *)
|
NativeIterator *ni = (NativeIterator *)
|
||||||
cx->malloc(sizeof(NativeIterator) + plength * sizeof(Value) + slength * sizeof(uint32));
|
cx->malloc(sizeof(NativeIterator) + plength * sizeof(jsboxedword) + slength * sizeof(uint32));
|
||||||
if (!ni) {
|
if (!ni) {
|
||||||
JS_ReportOutOfMemory(cx);
|
JS_ReportOutOfMemory(cx);
|
||||||
return false;
|
return false;
|
||||||
@ -293,7 +304,7 @@ InitNativeIterator(JSContext *cx, JSObject *obj, uintN flags, uint32 *sarray, ui
|
|||||||
ni->props_array = ni->props_cursor = (jsboxedword *) (ni + 1);
|
ni->props_array = ni->props_cursor = (jsboxedword *) (ni + 1);
|
||||||
ni->props_end = ni->props_array + plength;
|
ni->props_end = ni->props_array + plength;
|
||||||
if (plength)
|
if (plength)
|
||||||
memcpy(ni->props_array, props.begin(), plength * sizeof(Value));
|
memcpy(ni->props_array, props.begin(), plength * sizeof(jsboxedword));
|
||||||
ni->shapes_array = (uint32 *) ni->props_end;
|
ni->shapes_array = (uint32 *) ni->props_end;
|
||||||
ni->shapes_length = slength;
|
ni->shapes_length = slength;
|
||||||
ni->shapes_key = key;
|
ni->shapes_key = key;
|
||||||
@ -482,11 +493,10 @@ iterator_next(JSContext *cx, uintN argc, Value *vp)
|
|||||||
|
|
||||||
if (!js_IteratorMore(cx, obj, vp))
|
if (!js_IteratorMore(cx, obj, vp))
|
||||||
return false;
|
return false;
|
||||||
if (vp->isBoolean(false)) {
|
if (!vp->asBoolean()) {
|
||||||
js_ThrowStopIteration(cx);
|
js_ThrowStopIteration(cx);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
JS_ASSERT(vp->isBoolean(true));
|
|
||||||
return js_IteratorNext(cx, obj, vp);
|
return js_IteratorNext(cx, obj, vp);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -647,7 +657,7 @@ js_IteratorNext(JSContext *cx, JSObject *iterobj, Value *rval)
|
|||||||
*/
|
*/
|
||||||
NativeIterator *ni = iterobj->getNativeIterator();
|
NativeIterator *ni = iterobj->getNativeIterator();
|
||||||
JS_ASSERT(ni->props_cursor < ni->props_end);
|
JS_ASSERT(ni->props_cursor < ni->props_end);
|
||||||
BoxedWordToValue(*ni->props_cursor++, rval);
|
rval->copy(BoxedWordToValue(*ni->props_cursor++));
|
||||||
|
|
||||||
if (rval->isString() || (ni->flags & JSITER_FOREACH))
|
if (rval->isString() || (ni->flags & JSITER_FOREACH))
|
||||||
return true;
|
return true;
|
||||||
|
@ -56,7 +56,6 @@
|
|||||||
#include "jsmath.h"
|
#include "jsmath.h"
|
||||||
#include "jsnum.h"
|
#include "jsnum.h"
|
||||||
#include "jslibmath.h"
|
#include "jslibmath.h"
|
||||||
#include "jsobj.h"
|
|
||||||
|
|
||||||
using namespace js;
|
using namespace js;
|
||||||
|
|
||||||
@ -114,67 +113,71 @@ math_abs(JSContext *cx, uintN argc, Value *vp)
|
|||||||
vp->setDouble(js_NaN);
|
vp->setDouble(js_NaN);
|
||||||
return JS_TRUE;
|
return JS_TRUE;
|
||||||
}
|
}
|
||||||
if (!ValueToNumber(cx, vp[2], &x))
|
if (!ValueToNumber(cx, &vp[2], &x))
|
||||||
return JS_FALSE;
|
return JS_FALSE;
|
||||||
z = fabs(x);
|
z = fabs(x);
|
||||||
return js_NewNumberInRootedValue(cx, z, vp);
|
vp->setNumber(z);
|
||||||
|
return JS_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static JSBool
|
static JSBool
|
||||||
math_acos(JSContext *cx, uintN argc, jsval *vp)
|
math_acos(JSContext *cx, uintN argc, Value *vp)
|
||||||
{
|
{
|
||||||
jsdouble x, z;
|
jsdouble x, z;
|
||||||
|
|
||||||
if (argc == 0) {
|
if (argc == 0) {
|
||||||
*vp = cx->runtime->NaNValue;
|
vp->setDouble(js_NaN);
|
||||||
return JS_TRUE;
|
return JS_TRUE;
|
||||||
}
|
}
|
||||||
if (!ValueToNumber(cx, vp[2], &x))
|
if (!ValueToNumber(cx, &vp[2], &x))
|
||||||
return JS_FALSE;
|
return JS_FALSE;
|
||||||
#if defined(SOLARIS) && defined(__GNUC__)
|
#if defined(SOLARIS) && defined(__GNUC__)
|
||||||
if (x < -1 || 1 < x) {
|
if (x < -1 || 1 < x) {
|
||||||
*vp = cx->runtime->NaNValue;
|
vp->setDouble(js_NaN);
|
||||||
return JS_TRUE;
|
return JS_TRUE;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
z = acos(x);
|
z = acos(x);
|
||||||
return js_NewNumberInRootedValue(cx, z, vp);
|
vp->setDouble(z);
|
||||||
|
return JS_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static JSBool
|
static JSBool
|
||||||
math_asin(JSContext *cx, uintN argc, jsval *vp)
|
math_asin(JSContext *cx, uintN argc, Value *vp)
|
||||||
{
|
{
|
||||||
jsdouble x, z;
|
jsdouble x, z;
|
||||||
|
|
||||||
if (argc == 0) {
|
if (argc == 0) {
|
||||||
*vp = cx->runtime->NaNValue;
|
vp->setDouble(js_NaN);
|
||||||
return JS_TRUE;
|
return JS_TRUE;
|
||||||
}
|
}
|
||||||
if (!ValueToNumber(cx, vp[2], &x))
|
if (!ValueToNumber(cx, &vp[2], &x))
|
||||||
return JS_FALSE;
|
return JS_FALSE;
|
||||||
#if defined(SOLARIS) && defined(__GNUC__)
|
#if defined(SOLARIS) && defined(__GNUC__)
|
||||||
if (x < -1 || 1 < x) {
|
if (x < -1 || 1 < x) {
|
||||||
*vp = cx->runtime->NaNValue;
|
vp->setDouble(js_NaN);
|
||||||
return JS_TRUE;
|
return JS_TRUE;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
z = asin(x);
|
z = asin(x);
|
||||||
return js_NewNumberInRootedValue(cx, z, vp);
|
vp->setDouble(z);
|
||||||
|
return JS_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static JSBool
|
static JSBool
|
||||||
math_atan(JSContext *cx, uintN argc, jsval *vp)
|
math_atan(JSContext *cx, uintN argc, Value *vp)
|
||||||
{
|
{
|
||||||
jsdouble x, z;
|
jsdouble x, z;
|
||||||
|
|
||||||
if (argc == 0) {
|
if (argc == 0) {
|
||||||
*vp = cx->runtime->NaNValue;
|
vp->setDouble(js_NaN);
|
||||||
return JS_TRUE;
|
return JS_TRUE;
|
||||||
}
|
}
|
||||||
if (!ValueToNumber(cx, vp[2], &x))
|
if (!ValueToNumber(cx, &vp[2], &x))
|
||||||
return JS_FALSE;
|
return JS_FALSE;
|
||||||
z = atan(x);
|
z = atan(x);
|
||||||
return js_NewNumberInRootedValue(cx, z, vp);
|
vp->setDouble(z);
|
||||||
|
return JS_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline jsdouble JS_FASTCALL
|
static inline jsdouble JS_FASTCALL
|
||||||
@ -208,19 +211,21 @@ math_atan2_kernel(jsdouble x, jsdouble y)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static JSBool
|
static JSBool
|
||||||
math_atan2(JSContext *cx, uintN argc, jsval *vp)
|
math_atan2(JSContext *cx, uintN argc, Value *vp)
|
||||||
{
|
{
|
||||||
jsdouble x, y;
|
jsdouble x, y, z;
|
||||||
|
|
||||||
if (argc <= 1) {
|
if (argc <= 1) {
|
||||||
*vp = cx->runtime->NaNValue;
|
vp->setDouble(js_NaN);
|
||||||
return JS_TRUE;
|
return JS_TRUE;
|
||||||
}
|
}
|
||||||
if (!ValueToNumber(cx, vp[2], &x))
|
if (!ValueToNumber(cx, &vp[2], &x))
|
||||||
return JS_FALSE;
|
return JS_FALSE;
|
||||||
if (!ValueToNumber(cx, vp[3], &y))
|
if (!ValueToNumber(cx, &vp[3], &y))
|
||||||
return JS_FALSE;
|
return JS_FALSE;
|
||||||
return js_NewNumberInRootedValue(cx, math_atan2_kernel (x, y), vp);
|
z = math_atan2_kernel(x, y);
|
||||||
|
vp->setDouble(z);
|
||||||
|
return JS_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline jsdouble JS_FASTCALL
|
static inline jsdouble JS_FASTCALL
|
||||||
@ -234,115 +239,120 @@ math_ceil_kernel(jsdouble x)
|
|||||||
}
|
}
|
||||||
|
|
||||||
JSBool
|
JSBool
|
||||||
js_math_ceil(JSContext *cx, uintN argc, jsval *vp)
|
js_math_ceil(JSContext *cx, uintN argc, Value *vp)
|
||||||
{
|
{
|
||||||
jsdouble x, z;
|
jsdouble x, z;
|
||||||
|
|
||||||
if (argc == 0) {
|
if (argc == 0) {
|
||||||
*vp = cx->runtime->NaNValue;
|
vp->setDouble(js_NaN);
|
||||||
return JS_TRUE;
|
return JS_TRUE;
|
||||||
}
|
}
|
||||||
if (!ValueToNumber(cx, vp[2], &x))
|
if (!ValueToNumber(cx, &vp[2], &x))
|
||||||
return JS_FALSE;
|
return JS_FALSE;
|
||||||
z = math_ceil_kernel(x);
|
z = math_ceil_kernel(x);
|
||||||
return js_NewNumberInRootedValue(cx, z, vp);
|
vp->setNumber(z);
|
||||||
|
return JS_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static JSBool
|
static JSBool
|
||||||
math_cos(JSContext *cx, uintN argc, jsval *vp)
|
math_cos(JSContext *cx, uintN argc, Value *vp)
|
||||||
{
|
{
|
||||||
jsdouble x, z;
|
jsdouble x, z;
|
||||||
|
|
||||||
if (argc == 0) {
|
if (argc == 0) {
|
||||||
*vp = cx->runtime->NaNValue;
|
vp->setDouble(js_NaN);
|
||||||
return JS_TRUE;
|
return JS_TRUE;
|
||||||
}
|
}
|
||||||
if (!ValueToNumber(cx, vp[2], &x))
|
if (!ValueToNumber(cx, &vp[2], &x))
|
||||||
return JS_FALSE;
|
return JS_FALSE;
|
||||||
z = cos(x);
|
z = cos(x);
|
||||||
return js_NewNumberInRootedValue(cx, z, vp);
|
vp->setDouble(z);
|
||||||
|
return JS_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static JSBool
|
static JSBool
|
||||||
math_exp(JSContext *cx, uintN argc, jsval *vp)
|
math_exp(JSContext *cx, uintN argc, Value *vp)
|
||||||
{
|
{
|
||||||
jsdouble x, z;
|
jsdouble x, z;
|
||||||
|
|
||||||
if (argc == 0) {
|
if (argc == 0) {
|
||||||
*vp = cx->runtime->NaNValue;
|
vp->setDouble(js_NaN);
|
||||||
return JS_TRUE;
|
return JS_TRUE;
|
||||||
}
|
}
|
||||||
if (!ValueToNumber(cx, vp[2], &x))
|
if (!ValueToNumber(cx, &vp[2], &x))
|
||||||
return JS_FALSE;
|
return JS_FALSE;
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
if (!JSDOUBLE_IS_NaN(x)) {
|
if (!JSDOUBLE_IS_NaN(x)) {
|
||||||
if (x == js_PositiveInfinity) {
|
if (x == js_PositiveInfinity) {
|
||||||
*vp = cx->runtime->positiveInfinityValue;
|
vp->setDouble(js_PositiveInfinity);
|
||||||
return JS_TRUE;
|
return JS_TRUE;
|
||||||
}
|
}
|
||||||
if (x == js_NegativeInfinity) {
|
if (x == js_NegativeInfinity) {
|
||||||
*vp = JSVAL_ZERO;
|
vp->setInt32(0);
|
||||||
return JS_TRUE;
|
return JS_TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
z = exp(x);
|
z = exp(x);
|
||||||
return js_NewNumberInRootedValue(cx, z, vp);
|
vp->setNumber(z);
|
||||||
|
return JS_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
JSBool
|
JSBool
|
||||||
js_math_floor(JSContext *cx, uintN argc, jsval *vp)
|
js_math_floor(JSContext *cx, uintN argc, Value *vp)
|
||||||
{
|
{
|
||||||
jsdouble x, z;
|
jsdouble x, z;
|
||||||
|
|
||||||
if (argc == 0) {
|
if (argc == 0) {
|
||||||
*vp = cx->runtime->NaNValue;
|
vp->setDouble(js_NaN);
|
||||||
return JS_TRUE;
|
return JS_TRUE;
|
||||||
}
|
}
|
||||||
if (!ValueToNumber(cx, vp[2], &x))
|
if (!ValueToNumber(cx, &vp[2], &x))
|
||||||
return JS_FALSE;
|
return JS_FALSE;
|
||||||
z = floor(x);
|
z = floor(x);
|
||||||
return js_NewNumberInRootedValue(cx, z, vp);
|
vp->setNumber(z);
|
||||||
|
return JS_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static JSBool
|
static JSBool
|
||||||
math_log(JSContext *cx, uintN argc, jsval *vp)
|
math_log(JSContext *cx, uintN argc, Value *vp)
|
||||||
{
|
{
|
||||||
jsdouble x, z;
|
jsdouble x, z;
|
||||||
|
|
||||||
if (argc == 0) {
|
if (argc == 0) {
|
||||||
*vp = cx->runtime->NaNValue;
|
vp->setDouble(js_NaN);
|
||||||
return JS_TRUE;
|
return JS_TRUE;
|
||||||
}
|
}
|
||||||
if (!ValueToNumber(cx, vp[2], &x))
|
if (!ValueToNumber(cx, &vp[2], &x))
|
||||||
return JS_FALSE;
|
return JS_FALSE;
|
||||||
#if defined(SOLARIS) && defined(__GNUC__)
|
#if defined(SOLARIS) && defined(__GNUC__)
|
||||||
if (x < 0) {
|
if (x < 0) {
|
||||||
*vp = cx->runtime->NaNValue;
|
vp->setDouble(js_NaN);
|
||||||
return JS_TRUE;
|
return JS_TRUE;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
z = log(x);
|
z = log(x);
|
||||||
return js_NewNumberInRootedValue(cx, z, vp);
|
vp->setNumber(z);
|
||||||
|
return JS_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
JSBool
|
JSBool
|
||||||
js_math_max(JSContext *cx, uintN argc, jsval *vp)
|
js_math_max(JSContext *cx, uintN argc, Value *vp)
|
||||||
{
|
{
|
||||||
jsdouble x, z = js_NegativeInfinity;
|
jsdouble x, z = js_NegativeInfinity;
|
||||||
jsval *argv;
|
Value *argv;
|
||||||
uintN i;
|
uintN i;
|
||||||
|
|
||||||
if (argc == 0) {
|
if (argc == 0) {
|
||||||
*vp = cx->runtime->negativeInfinityValue;
|
vp->setDouble(js_NegativeInfinity);
|
||||||
return JS_TRUE;
|
return JS_TRUE;
|
||||||
}
|
}
|
||||||
argv = vp + 2;
|
argv = vp + 2;
|
||||||
for (i = 0; i < argc; i++) {
|
for (i = 0; i < argc; i++) {
|
||||||
if (!ValueToNumber(cx, argv[i], &x))
|
if (!ValueToNumber(cx, &argv[i], &x))
|
||||||
return JS_FALSE;
|
return JS_FALSE;
|
||||||
if (JSDOUBLE_IS_NaN(x)) {
|
if (JSDOUBLE_IS_NaN(x)) {
|
||||||
*vp = cx->runtime->NaNValue;
|
vp->setDouble(js_NaN);
|
||||||
return JS_TRUE;
|
return JS_TRUE;
|
||||||
}
|
}
|
||||||
if (x == 0 && x == z) {
|
if (x == 0 && x == z) {
|
||||||
@ -352,26 +362,27 @@ js_math_max(JSContext *cx, uintN argc, jsval *vp)
|
|||||||
z = (x > z) ? x : z;
|
z = (x > z) ? x : z;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return js_NewNumberInRootedValue(cx, z, vp);
|
vp->setNumber(z);
|
||||||
|
return JS_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
JSBool
|
JSBool
|
||||||
js_math_min(JSContext *cx, uintN argc, jsval *vp)
|
js_math_min(JSContext *cx, uintN argc, Value *vp)
|
||||||
{
|
{
|
||||||
jsdouble x, z = js_PositiveInfinity;
|
jsdouble x, z = js_PositiveInfinity;
|
||||||
jsval *argv;
|
Value *argv;
|
||||||
uintN i;
|
uintN i;
|
||||||
|
|
||||||
if (argc == 0) {
|
if (argc == 0) {
|
||||||
*vp = cx->runtime->positiveInfinityValue;
|
vp->setDouble(js_PositiveInfinity);
|
||||||
return JS_TRUE;
|
return JS_TRUE;
|
||||||
}
|
}
|
||||||
argv = vp + 2;
|
argv = vp + 2;
|
||||||
for (i = 0; i < argc; i++) {
|
for (i = 0; i < argc; i++) {
|
||||||
if (!ValueToNumber(cx, argv[i], &x))
|
if (!ValueToNumber(cx, &argv[i], &x))
|
||||||
return JS_FALSE;
|
return JS_FALSE;
|
||||||
if (JSDOUBLE_IS_NaN(x)) {
|
if (JSDOUBLE_IS_NaN(x)) {
|
||||||
*vp = cx->runtime->NaNValue;
|
vp->setDouble(js_NaN);
|
||||||
return JS_TRUE;
|
return JS_TRUE;
|
||||||
}
|
}
|
||||||
if (x == 0 && x == z) {
|
if (x == 0 && x == z) {
|
||||||
@ -381,37 +392,39 @@ js_math_min(JSContext *cx, uintN argc, jsval *vp)
|
|||||||
z = (x < z) ? x : z;
|
z = (x < z) ? x : z;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return js_NewNumberInRootedValue(cx, z, vp);
|
vp->setNumber(z);
|
||||||
|
return JS_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static JSBool
|
static JSBool
|
||||||
math_pow(JSContext *cx, uintN argc, jsval *vp)
|
math_pow(JSContext *cx, uintN argc, Value *vp)
|
||||||
{
|
{
|
||||||
jsdouble x, y, z;
|
jsdouble x, y, z;
|
||||||
|
|
||||||
if (argc <= 1) {
|
if (argc <= 1) {
|
||||||
*vp = cx->runtime->NaNValue;
|
vp->setDouble(js_NaN);
|
||||||
return JS_TRUE;
|
return JS_TRUE;
|
||||||
}
|
}
|
||||||
if (!ValueToNumber(cx, vp[2], &x))
|
if (!ValueToNumber(cx, &vp[2], &x))
|
||||||
return JS_FALSE;
|
return JS_FALSE;
|
||||||
if (!ValueToNumber(cx, vp[3], &y))
|
if (!ValueToNumber(cx, &vp[3], &y))
|
||||||
return JS_FALSE;
|
return JS_FALSE;
|
||||||
/*
|
/*
|
||||||
* Because C99 and ECMA specify different behavior for pow(),
|
* Because C99 and ECMA specify different behavior for pow(),
|
||||||
* we need to wrap the libm call to make it ECMA compliant.
|
* we need to wrap the libm call to make it ECMA compliant.
|
||||||
*/
|
*/
|
||||||
if (!JSDOUBLE_IS_FINITE(y) && (x == 1.0 || x == -1.0)) {
|
if (!JSDOUBLE_IS_FINITE(y) && (x == 1.0 || x == -1.0)) {
|
||||||
*vp = cx->runtime->NaNValue;
|
vp->setDouble(js_NaN);
|
||||||
return JS_TRUE;
|
return JS_TRUE;
|
||||||
}
|
}
|
||||||
/* pow(x, +-0) is always 1, even for x = NaN. */
|
/* pow(x, +-0) is always 1, even for x = NaN. */
|
||||||
if (y == 0) {
|
if (y == 0) {
|
||||||
*vp = JSVAL_ONE;
|
vp->setInt32(1);
|
||||||
return JS_TRUE;
|
return JS_TRUE;
|
||||||
}
|
}
|
||||||
z = pow(x, y);
|
z = pow(x, y);
|
||||||
return js_NewNumberInRootedValue(cx, z, vp);
|
vp->setNumber(z);
|
||||||
|
return JS_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const int64 RNG_MULTIPLIER = 0x5DEECE66DLL;
|
static const int64 RNG_MULTIPLIER = 0x5DEECE66DLL;
|
||||||
@ -460,10 +473,11 @@ random_nextDouble(JSContext *cx)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static JSBool
|
static JSBool
|
||||||
math_random(JSContext *cx, uintN argc, jsval *vp)
|
math_random(JSContext *cx, uintN argc, Value *vp)
|
||||||
{
|
{
|
||||||
jsdouble z = random_nextDouble(cx);
|
jsdouble z = random_nextDouble(cx);
|
||||||
return js_NewNumberInRootedValue(cx, z, vp);
|
vp->setDouble(z);
|
||||||
|
return JS_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined _WIN32 && !defined WINCE && _MSC_VER < 1400
|
#if defined _WIN32 && !defined WINCE && _MSC_VER < 1400
|
||||||
@ -482,70 +496,74 @@ js_copysign(double x, double y)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
JSBool
|
JSBool
|
||||||
js_math_round(JSContext *cx, uintN argc, jsval *vp)
|
js_math_round(JSContext *cx, uintN argc, Value *vp)
|
||||||
{
|
{
|
||||||
jsdouble x, z;
|
jsdouble x, z;
|
||||||
|
|
||||||
if (argc == 0) {
|
if (argc == 0) {
|
||||||
*vp = cx->runtime->NaNValue;
|
vp->setDouble(js_NaN);
|
||||||
return JS_TRUE;
|
return JS_TRUE;
|
||||||
}
|
}
|
||||||
if (!ValueToNumber(cx, vp[2], &x))
|
if (!ValueToNumber(cx, &vp[2], &x))
|
||||||
return JS_FALSE;
|
return JS_FALSE;
|
||||||
z = js_copysign(floor(x + 0.5), x);
|
z = js_copysign(floor(x + 0.5), x);
|
||||||
return js_NewNumberInRootedValue(cx, z, vp);
|
vp->setNumber(z);
|
||||||
|
return JS_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static JSBool
|
static JSBool
|
||||||
math_sin(JSContext *cx, uintN argc, jsval *vp)
|
math_sin(JSContext *cx, uintN argc, Value *vp)
|
||||||
{
|
{
|
||||||
jsdouble x, z;
|
jsdouble x, z;
|
||||||
|
|
||||||
if (argc == 0) {
|
if (argc == 0) {
|
||||||
*vp = cx->runtime->NaNValue;
|
vp->setDouble(js_NaN);
|
||||||
return JS_TRUE;
|
return JS_TRUE;
|
||||||
}
|
}
|
||||||
if (!ValueToNumber(cx, vp[2], &x))
|
if (!ValueToNumber(cx, &vp[2], &x))
|
||||||
return JS_FALSE;
|
return JS_FALSE;
|
||||||
z = sin(x);
|
z = sin(x);
|
||||||
return js_NewNumberInRootedValue(cx, z, vp);
|
vp->setDouble(z);
|
||||||
|
return JS_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static JSBool
|
static JSBool
|
||||||
math_sqrt(JSContext *cx, uintN argc, jsval *vp)
|
math_sqrt(JSContext *cx, uintN argc, Value *vp)
|
||||||
{
|
{
|
||||||
jsdouble x, z;
|
jsdouble x, z;
|
||||||
|
|
||||||
if (argc == 0) {
|
if (argc == 0) {
|
||||||
*vp = cx->runtime->NaNValue;
|
vp->setDouble(js_NaN);
|
||||||
return JS_TRUE;
|
return JS_TRUE;
|
||||||
}
|
}
|
||||||
if (!ValueToNumber(cx, vp[2], &x))
|
if (!ValueToNumber(cx, &vp[2], &x))
|
||||||
return JS_FALSE;
|
return JS_FALSE;
|
||||||
z = sqrt(x);
|
z = sqrt(x);
|
||||||
return js_NewNumberInRootedValue(cx, z, vp);
|
vp->setDouble(z);
|
||||||
|
return JS_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static JSBool
|
static JSBool
|
||||||
math_tan(JSContext *cx, uintN argc, jsval *vp)
|
math_tan(JSContext *cx, uintN argc, Value *vp)
|
||||||
{
|
{
|
||||||
jsdouble x, z;
|
jsdouble x, z;
|
||||||
|
|
||||||
if (argc == 0) {
|
if (argc == 0) {
|
||||||
*vp = cx->runtime->NaNValue;
|
vp->setDouble(js_NaN);
|
||||||
return JS_TRUE;
|
return JS_TRUE;
|
||||||
}
|
}
|
||||||
if (!ValueToNumber(cx, vp[2], &x))
|
if (!ValueToNumber(cx, &vp[2], &x))
|
||||||
return JS_FALSE;
|
return JS_FALSE;
|
||||||
z = tan(x);
|
z = tan(x);
|
||||||
return js_NewNumberInRootedValue(cx, z, vp);
|
vp->setDouble(z);
|
||||||
|
return JS_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if JS_HAS_TOSOURCE
|
#if JS_HAS_TOSOURCE
|
||||||
static JSBool
|
static JSBool
|
||||||
math_toSource(JSContext *cx, uintN argc, jsval *vp)
|
math_toSource(JSContext *cx, uintN argc, Value *vp)
|
||||||
{
|
{
|
||||||
*vp = ATOM_KEY(CLASS_ATOM(cx, Math));
|
vp->setString(ATOM_TO_STRING(CLASS_ATOM(cx, Math)));
|
||||||
return JS_TRUE;
|
return JS_TRUE;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -739,7 +757,7 @@ js_InitMathClass(JSContext *cx, JSObject *obj)
|
|||||||
{
|
{
|
||||||
JSObject *Math;
|
JSObject *Math;
|
||||||
|
|
||||||
Math = JS_NewObject(cx, &js_MathClass, NULL, obj);
|
Math = JS_NewObject(cx, Jsvalify(&js_MathClass), NULL, obj);
|
||||||
if (!Math)
|
if (!Math)
|
||||||
return NULL;
|
return NULL;
|
||||||
if (!JS_DefineProperty(cx, obj, js_Math_str, OBJECT_TO_JSVAL(Math),
|
if (!JS_DefineProperty(cx, obj, js_Math_str, OBJECT_TO_JSVAL(Math),
|
||||||
|
@ -52,18 +52,18 @@ extern void
|
|||||||
js_InitRandom(JSContext *cx);
|
js_InitRandom(JSContext *cx);
|
||||||
|
|
||||||
extern JSBool
|
extern JSBool
|
||||||
js_math_ceil(JSContext *cx, uintN argc, jsval *vp);
|
js_math_ceil(JSContext *cx, uintN argc, js::Value *vp);
|
||||||
|
|
||||||
extern JSBool
|
extern JSBool
|
||||||
js_math_floor(JSContext *cx, uintN argc, jsval *vp);
|
js_math_floor(JSContext *cx, uintN argc, js::Value *vp);
|
||||||
|
|
||||||
extern JSBool
|
extern JSBool
|
||||||
js_math_max(JSContext *cx, uintN argc, jsval *vp);
|
js_math_max(JSContext *cx, uintN argc, js::Value *vp);
|
||||||
|
|
||||||
extern JSBool
|
extern JSBool
|
||||||
js_math_min(JSContext *cx, uintN argc, jsval *vp);
|
js_math_min(JSContext *cx, uintN argc, js::Value *vp);
|
||||||
|
|
||||||
extern JSBool
|
extern JSBool
|
||||||
js_math_round(JSContext *cx, uintN argc, jsval *vp);
|
js_math_round(JSContext *cx, uintN argc, js::Value *vp);
|
||||||
|
|
||||||
#endif /* jsmath_h___ */
|
#endif /* jsmath_h___ */
|
||||||
|
@ -615,6 +615,16 @@ Uint32ToValue(uint32_t u, Value *vp)
|
|||||||
vp->setInt32((int32_t)u);
|
vp->setInt32((int32_t)u);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
JS_ALWAYS_INLINE void
|
||||||
|
Value::setNumber(double d)
|
||||||
|
{
|
||||||
|
int32_t i;
|
||||||
|
if (JSDOUBLE_IS_INT32(d, i))
|
||||||
|
setInt32(i);
|
||||||
|
else
|
||||||
|
setDouble(d);
|
||||||
|
}
|
||||||
|
|
||||||
template<typename T> struct NumberTraits { };
|
template<typename T> struct NumberTraits { };
|
||||||
template<> struct NumberTraits<int32> {
|
template<> struct NumberTraits<int32> {
|
||||||
static JS_ALWAYS_INLINE int32 NaN() { return 0; }
|
static JS_ALWAYS_INLINE int32 NaN() { return 0; }
|
||||||
|
@ -685,6 +685,11 @@ Value::Value(ObjectTag arg)
|
|||||||
data.obj = &arg.obj;
|
data.obj = &arg.obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
JS_ALWAYS_INLINE
|
||||||
|
CopyableValue::CopyableValue(ObjectTag arg)
|
||||||
|
: Value(arg)
|
||||||
|
{}
|
||||||
|
|
||||||
JS_ALWAYS_INLINE
|
JS_ALWAYS_INLINE
|
||||||
Value::Value(ObjectOrNullTag arg)
|
Value::Value(ObjectOrNullTag arg)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user