mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Backout edecc56b7c80 and ad8aee962832 (bug 697479) for check-jit-test failures
This commit is contained in:
parent
49ab88c8f8
commit
31a749aec3
@ -171,7 +171,6 @@ CPPSRCS = \
|
||||
SemanticAnalysis.cpp \
|
||||
TokenStream.cpp \
|
||||
LifoAlloc.cpp \
|
||||
MapObject.cpp \
|
||||
RegExpObject.cpp \
|
||||
RegExpStatics.cpp \
|
||||
RegExp.cpp \
|
||||
|
@ -1,407 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* vim: set ts=8 sw=4 et tw=99 ft=cpp:
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is SpiderMonkey JavaScript engine.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* the Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2011
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Jason Orendorff <jorendorff@mozilla.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "builtin/MapObject.h"
|
||||
|
||||
#include "jscntxt.h"
|
||||
#include "jsgcmark.h"
|
||||
#include "jsobj.h"
|
||||
|
||||
#include "vm/GlobalObject.h"
|
||||
#include "vm/Stack.h"
|
||||
|
||||
#include "jsobjinlines.h"
|
||||
|
||||
using namespace js;
|
||||
|
||||
static JSObject *
|
||||
InitClass(JSContext *cx, GlobalObject *global, Class *clasp, JSProtoKey key, Native construct,
|
||||
JSFunctionSpec *methods)
|
||||
{
|
||||
JSObject *proto = global->createBlankPrototype(cx, clasp);
|
||||
if (!proto)
|
||||
return NULL;
|
||||
proto->setPrivate(NULL);
|
||||
|
||||
JSAtom *atom = cx->runtime->atomState.classAtoms[key];
|
||||
JSFunction *ctor = global->createConstructor(cx, construct, clasp, atom, 0);
|
||||
if (!ctor ||
|
||||
!LinkConstructorAndPrototype(cx, ctor, proto) ||
|
||||
!DefinePropertiesAndBrand(cx, proto, NULL, methods) ||
|
||||
!DefineConstructorAndPrototype(cx, global, key, ctor, proto))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
return proto;
|
||||
}
|
||||
|
||||
|
||||
/*** HashableValue *******************************************************************************/
|
||||
|
||||
bool
|
||||
HashableValue::setValue(JSContext *cx, const Value &v)
|
||||
{
|
||||
if (v.isString() && v.toString()->isRope()) {
|
||||
/* Flatten this rope so that equals() is infallible. */
|
||||
JSString *str = v.toString()->ensureLinear(cx);
|
||||
if (!str)
|
||||
return false;
|
||||
value = StringValue(str);
|
||||
} else if (v.isDouble()) {
|
||||
jsdouble d = v.toDouble();
|
||||
int32 i;
|
||||
if (JSDOUBLE_IS_INT32(d, &i)) {
|
||||
/* Normalize int32-valued doubles to int32 for faster hashing and testing. */
|
||||
value = Int32Value(i);
|
||||
} else {
|
||||
#ifdef DEBUG
|
||||
/* All NaN values are the same. The bit-pattern must reflect this. */
|
||||
jsval_layout a, b;
|
||||
a.asDouble = d;
|
||||
b.asDouble = JS_CANONICALIZE_NAN(d);
|
||||
JS_ASSERT(a.asBits == b.asBits);
|
||||
#endif
|
||||
value = v;
|
||||
}
|
||||
} else {
|
||||
value = v;
|
||||
}
|
||||
|
||||
JS_ASSERT(value.isUndefined() || value.isNull() || value.isBoolean() ||
|
||||
value.isNumber() || value.isString() || value.isObject());
|
||||
return true;
|
||||
}
|
||||
|
||||
HashNumber
|
||||
HashableValue::hash() const
|
||||
{
|
||||
/*
|
||||
* HashableValue::setValue normalizes values so that the SameValue relation
|
||||
* on HashableValues is the same as the == relationship on
|
||||
* value.data.asBits, except for strings.
|
||||
*/
|
||||
if (value.isString()) {
|
||||
JSLinearString &s = value.toString()->asLinear();
|
||||
return HashChars(s.chars(), s.length());
|
||||
}
|
||||
|
||||
/* Having dispensed with strings, we can just hash asBits. */
|
||||
uint64 u = value.asRawBits();
|
||||
return HashNumber((u >> 3) ^ (u >> (32 + 3)) ^ (u << (32 - 3)));
|
||||
}
|
||||
|
||||
bool
|
||||
HashableValue::equals(const HashableValue &other) const
|
||||
{
|
||||
/* Two HashableValues are equal if they have equal bits or they're equal strings. */
|
||||
bool b = (value.asRawBits() == other.value.asRawBits()) ||
|
||||
(value.isString() &&
|
||||
other.value.isString() &&
|
||||
EqualStrings(&value.toString()->asLinear(),
|
||||
&other.value.toString()->asLinear()));
|
||||
|
||||
#ifdef DEBUG
|
||||
JSBool same;
|
||||
JS_ALWAYS_TRUE(SameValue(NULL, value, other.value, &same));
|
||||
JS_ASSERT(same == b);
|
||||
#endif
|
||||
return b;
|
||||
}
|
||||
|
||||
|
||||
/*** Map *****************************************************************************************/
|
||||
|
||||
Class MapObject::class_ = {
|
||||
"Map",
|
||||
JSCLASS_HAS_PRIVATE |
|
||||
JSCLASS_HAS_CACHED_PROTO(JSProto_Map),
|
||||
JS_PropertyStub, /* addProperty */
|
||||
JS_PropertyStub, /* delProperty */
|
||||
JS_PropertyStub, /* getProperty */
|
||||
JS_StrictPropertyStub, /* setProperty */
|
||||
JS_EnumerateStub,
|
||||
JS_ResolveStub,
|
||||
JS_ConvertStub,
|
||||
finalize,
|
||||
NULL, /* reserved0 */
|
||||
NULL, /* checkAccess */
|
||||
NULL, /* call */
|
||||
NULL, /* construct */
|
||||
NULL, /* xdrObject */
|
||||
NULL, /* hasInstance */
|
||||
mark
|
||||
};
|
||||
|
||||
JSFunctionSpec MapObject::methods[] = {
|
||||
JS_FN("get", get, 1, 0),
|
||||
JS_FN("has", has, 1, 0),
|
||||
JS_FN("set", set, 2, 0),
|
||||
JS_FN("delete", delete_, 1, 0),
|
||||
JS_FS_END
|
||||
};
|
||||
|
||||
JSObject *
|
||||
MapObject::initClass(JSContext *cx, JSObject *obj)
|
||||
{
|
||||
return InitClass(cx, obj->asGlobal(), &class_, JSProto_Map, construct, methods);
|
||||
}
|
||||
|
||||
void
|
||||
MapObject::mark(JSTracer *trc, JSObject *obj)
|
||||
{
|
||||
MapObject *mapobj = static_cast<MapObject *>(obj);
|
||||
if (ValueMap *map = mapobj->getData()) {
|
||||
for (ValueMap::Range r = map->all(); !r.empty(); r.popFront()) {
|
||||
gc::MarkValue(trc, r.front().key, "key");
|
||||
gc::MarkValue(trc, r.front().value, "value");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MapObject::finalize(JSContext *cx, JSObject *obj)
|
||||
{
|
||||
MapObject *mapobj = static_cast<MapObject *>(obj);
|
||||
if (ValueMap *map = mapobj->getData())
|
||||
delete map;
|
||||
}
|
||||
|
||||
JSBool
|
||||
MapObject::construct(JSContext *cx, uintN argc, Value *vp)
|
||||
{
|
||||
JSObject *obj = NewBuiltinClassInstance(cx, &class_);
|
||||
if (!obj)
|
||||
return false;
|
||||
|
||||
ValueMap *map = cx->new_<ValueMap>(cx->runtime);
|
||||
if (!map || !map->init())
|
||||
return false;
|
||||
obj->setPrivate(map);
|
||||
|
||||
CallArgsFromVp(argc, vp).rval().setObject(*obj);
|
||||
return true;
|
||||
}
|
||||
|
||||
#define UNPACK_THIS(T, native, cx, argc, vp, args, data) \
|
||||
CallArgs args = CallArgsFromVp(argc, vp); \
|
||||
if (!args.thisv().isObject() || \
|
||||
!args.thisv().toObject().hasClass(&T::class_)) \
|
||||
{ \
|
||||
return js::HandleNonGenericMethodClassMismatch(cx, args, native, \
|
||||
&T::class_); \
|
||||
} \
|
||||
if (!args.thisv().toObject().getPrivate()) { \
|
||||
ReportIncompatibleMethod(cx, args, &T::class_); \
|
||||
return false; \
|
||||
} \
|
||||
T::Data &data = *static_cast<T &>(args.thisv().toObject()).getData(); \
|
||||
(void) data
|
||||
|
||||
#define THIS_MAP(native, cx, argc, vp, args, map) \
|
||||
UNPACK_THIS(MapObject, native, cx, argc, vp, args, map)
|
||||
|
||||
#define ARG0_KEY(cx, args, key) \
|
||||
HashableValue key; \
|
||||
if (args.length() > 0 && !key.setValue(cx, args[0])) \
|
||||
return false
|
||||
|
||||
JSBool
|
||||
MapObject::get(JSContext *cx, uintN argc, Value *vp)
|
||||
{
|
||||
THIS_MAP(get, cx, argc, vp, args, map);
|
||||
ARG0_KEY(cx, args, key);
|
||||
|
||||
if (ValueMap::Ptr p = map.lookup(key))
|
||||
args.rval() = p->value;
|
||||
else
|
||||
args.rval().setUndefined();
|
||||
return true;
|
||||
}
|
||||
|
||||
JSBool
|
||||
MapObject::has(JSContext *cx, uintN argc, Value *vp)
|
||||
{
|
||||
THIS_MAP(has, cx, argc, vp, args, map);
|
||||
ARG0_KEY(cx, args, key);
|
||||
args.rval().setBoolean(map.lookup(key));
|
||||
return true;
|
||||
}
|
||||
|
||||
JSBool
|
||||
MapObject::set(JSContext *cx, uintN argc, Value *vp)
|
||||
{
|
||||
THIS_MAP(set, cx, argc, vp, args, map);
|
||||
ARG0_KEY(cx, args, key);
|
||||
map.put(key, args.length() > 1 ? args[1] : UndefinedValue());
|
||||
args.rval().setUndefined();
|
||||
return true;
|
||||
}
|
||||
|
||||
JSBool
|
||||
MapObject::delete_(JSContext *cx, uintN argc, Value *vp)
|
||||
{
|
||||
THIS_MAP(delete_, cx, argc, vp, args, map);
|
||||
ARG0_KEY(cx, args, key);
|
||||
ValueMap::Ptr p = map.lookup(key);
|
||||
bool found = p.found();
|
||||
if (found)
|
||||
map.remove(p);
|
||||
args.rval().setBoolean(found);
|
||||
return true;
|
||||
}
|
||||
|
||||
JSObject *
|
||||
js_InitMapClass(JSContext *cx, JSObject *obj)
|
||||
{
|
||||
return MapObject::initClass(cx, obj);
|
||||
}
|
||||
|
||||
|
||||
/*** Set *****************************************************************************************/
|
||||
|
||||
Class SetObject::class_ = {
|
||||
"Set",
|
||||
JSCLASS_HAS_PRIVATE |
|
||||
JSCLASS_HAS_CACHED_PROTO(JSProto_Set),
|
||||
JS_PropertyStub, /* addProperty */
|
||||
JS_PropertyStub, /* delProperty */
|
||||
JS_PropertyStub, /* getProperty */
|
||||
JS_StrictPropertyStub, /* setProperty */
|
||||
JS_EnumerateStub,
|
||||
JS_ResolveStub,
|
||||
JS_ConvertStub,
|
||||
finalize,
|
||||
NULL, /* reserved0 */
|
||||
NULL, /* checkAccess */
|
||||
NULL, /* call */
|
||||
NULL, /* construct */
|
||||
NULL, /* xdrObject */
|
||||
NULL, /* hasInstance */
|
||||
mark
|
||||
};
|
||||
|
||||
JSFunctionSpec SetObject::methods[] = {
|
||||
JS_FN("has", has, 1, 0),
|
||||
JS_FN("add", add, 1, 0),
|
||||
JS_FN("delete", delete_, 1, 0),
|
||||
JS_FS_END
|
||||
};
|
||||
|
||||
JSObject *
|
||||
SetObject::initClass(JSContext *cx, JSObject *obj)
|
||||
{
|
||||
return InitClass(cx, obj->asGlobal(), &class_, JSProto_Set, construct, methods);
|
||||
}
|
||||
|
||||
void
|
||||
SetObject::mark(JSTracer *trc, JSObject *obj)
|
||||
{
|
||||
SetObject *setobj = static_cast<SetObject *>(obj);
|
||||
if (ValueSet *set = setobj->getData()) {
|
||||
for (ValueSet::Range r = set->all(); !r.empty(); r.popFront())
|
||||
gc::MarkValue(trc, r.front(), "key");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SetObject::finalize(JSContext *cx, JSObject *obj)
|
||||
{
|
||||
SetObject *setobj = static_cast<SetObject *>(obj);
|
||||
if (ValueSet *set = setobj->getData())
|
||||
delete set;
|
||||
}
|
||||
|
||||
JSBool
|
||||
SetObject::construct(JSContext *cx, uintN argc, Value *vp)
|
||||
{
|
||||
JSObject *obj = NewBuiltinClassInstance(cx, &class_);
|
||||
if (!obj)
|
||||
return false;
|
||||
|
||||
ValueSet *set = cx->new_<ValueSet>(cx->runtime);
|
||||
if (!set || !set->init())
|
||||
return false;
|
||||
obj->setPrivate(set);
|
||||
|
||||
CallArgsFromVp(argc, vp).rval().setObject(*obj);
|
||||
return true;
|
||||
}
|
||||
|
||||
#define THIS_SET(native, cx, argc, vp, args, set) \
|
||||
UNPACK_THIS(SetObject, native, cx, argc, vp, args, set)
|
||||
|
||||
JSBool
|
||||
SetObject::has(JSContext *cx, uintN argc, Value *vp)
|
||||
{
|
||||
THIS_SET(has, cx, argc, vp, args, set);
|
||||
ARG0_KEY(cx, args, key);
|
||||
args.rval().setBoolean(set.has(key));
|
||||
return true;
|
||||
}
|
||||
|
||||
JSBool
|
||||
SetObject::add(JSContext *cx, uintN argc, Value *vp)
|
||||
{
|
||||
THIS_SET(add, cx, argc, vp, args, set);
|
||||
ARG0_KEY(cx, args, key);
|
||||
if (!set.put(key))
|
||||
return false;
|
||||
args.rval().setUndefined();
|
||||
return true;
|
||||
}
|
||||
|
||||
JSBool
|
||||
SetObject::delete_(JSContext *cx, uintN argc, Value *vp)
|
||||
{
|
||||
THIS_SET(delete_, cx, argc, vp, args, set);
|
||||
ARG0_KEY(cx, args, key);
|
||||
ValueSet::Ptr p = set.lookup(key);
|
||||
bool found = p.found();
|
||||
if (found)
|
||||
set.remove(p);
|
||||
args.rval().setBoolean(found);
|
||||
return true;
|
||||
}
|
||||
|
||||
JSObject *
|
||||
js_InitSetClass(JSContext *cx, JSObject *obj)
|
||||
{
|
||||
return SetObject::initClass(cx, obj);
|
||||
}
|
@ -1,122 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* vim: set ts=8 sw=4 et tw=99 ft=cpp:
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is SpiderMonkey JavaScript engine.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* the Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2011
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Jason Orendorff <jorendorff@mozilla.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef MapObject_h__
|
||||
#define MapObject_h__
|
||||
|
||||
#include "jsapi.h"
|
||||
#include "jscntxt.h"
|
||||
#include "jsobj.h"
|
||||
|
||||
#include "js/HashTable.h"
|
||||
|
||||
namespace js {
|
||||
|
||||
/*
|
||||
* Comparing two ropes for equality can fail. The js::HashTable template
|
||||
* requires infallible hash() and match() operations. Therefore we require
|
||||
* all values to be converted to hashable form before being used as a key
|
||||
* in a Map or Set object.
|
||||
*
|
||||
* All values except ropes are hashable as-is.
|
||||
*/
|
||||
class HashableValue {
|
||||
HeapValue value;
|
||||
|
||||
public:
|
||||
struct Hasher {
|
||||
typedef HashableValue Lookup;
|
||||
static HashNumber hash(const Lookup &v) { return v.hash(); }
|
||||
static bool match(const HashableValue &k, const Lookup &l) { return k.equals(l); }
|
||||
};
|
||||
|
||||
HashableValue() : value(UndefinedValue()) {}
|
||||
|
||||
operator const HeapValue &() const { return value; }
|
||||
bool setValue(JSContext *cx, const Value &v);
|
||||
HashNumber hash() const;
|
||||
bool equals(const HashableValue &other) const;
|
||||
};
|
||||
|
||||
typedef HashMap<HashableValue, HeapValue, HashableValue::Hasher, RuntimeAllocPolicy> ValueMap;
|
||||
typedef HashSet<HashableValue, HashableValue::Hasher, RuntimeAllocPolicy> ValueSet;
|
||||
|
||||
class MapObject : public JSObject {
|
||||
public:
|
||||
static JSObject *initClass(JSContext *cx, JSObject *obj);
|
||||
static Class class_;
|
||||
private:
|
||||
typedef ValueMap Data;
|
||||
static JSFunctionSpec methods[];
|
||||
ValueMap *getData() { return static_cast<ValueMap *>(getPrivate()); }
|
||||
static void mark(JSTracer *trc, JSObject *obj);
|
||||
static void finalize(JSContext *cx, JSObject *obj);
|
||||
static JSBool construct(JSContext *cx, uintN argc, Value *vp);
|
||||
static JSBool get(JSContext *cx, uintN argc, Value *vp);
|
||||
static JSBool has(JSContext *cx, uintN argc, Value *vp);
|
||||
static JSBool set(JSContext *cx, uintN argc, Value *vp);
|
||||
static JSBool delete_(JSContext *cx, uintN argc, Value *vp);
|
||||
};
|
||||
|
||||
class SetObject : public JSObject {
|
||||
public:
|
||||
static JSObject *initClass(JSContext *cx, JSObject *obj);
|
||||
static Class class_;
|
||||
private:
|
||||
typedef ValueSet Data;
|
||||
static JSFunctionSpec methods[];
|
||||
ValueSet *getData() { return static_cast<ValueSet *>(getPrivate()); }
|
||||
static void mark(JSTracer *trc, JSObject *obj);
|
||||
static void finalize(JSContext *cx, JSObject *obj);
|
||||
static JSBool construct(JSContext *cx, uintN argc, Value *vp);
|
||||
static JSBool has(JSContext *cx, uintN argc, Value *vp);
|
||||
static JSBool add(JSContext *cx, uintN argc, Value *vp);
|
||||
static JSBool delete_(JSContext *cx, uintN argc, Value *vp);
|
||||
};
|
||||
|
||||
} /* namespace js */
|
||||
|
||||
extern JSObject *
|
||||
js_InitMapClass(JSContext *cx, JSObject *obj);
|
||||
|
||||
extern JSObject *
|
||||
js_InitSetClass(JSContext *cx, JSObject *obj);
|
||||
|
||||
#endif /* MapObject_h__ */
|
@ -317,27 +317,24 @@ class HeapValue
|
||||
const Value &get() const { return value; }
|
||||
operator const Value &() const { return value; }
|
||||
|
||||
bool isMarkable() const { return value.isMarkable(); }
|
||||
bool isMagic(JSWhyMagic why) const { return value.isMagic(why); }
|
||||
bool isUndefined() const { return value.isUndefined(); }
|
||||
bool isNull() const { return value.isNull(); }
|
||||
bool isBoolean() const { return value.isBoolean(); }
|
||||
bool isObject() const { return value.isObject(); }
|
||||
bool isGCThing() const { return value.isGCThing(); }
|
||||
bool isTrue() const { return value.isTrue(); }
|
||||
bool isFalse() const { return value.isFalse(); }
|
||||
bool isNumber() const { return value.isNumber(); }
|
||||
bool isInt32() const { return value.isInt32(); }
|
||||
bool isString() const { return value.isString(); }
|
||||
bool isObject() const { return value.isObject(); }
|
||||
bool isMagic(JSWhyMagic why) const { return value.isMagic(why); }
|
||||
bool isGCThing() const { return value.isGCThing(); }
|
||||
bool isMarkable() const { return value.isMarkable(); }
|
||||
bool isNull() const { return value.isNull(); }
|
||||
|
||||
bool toBoolean() const { return value.toBoolean(); }
|
||||
double toNumber() const { return value.toNumber(); }
|
||||
int32 toInt32() const { return value.toInt32(); }
|
||||
double toDouble() const { return value.toDouble(); }
|
||||
JSString *toString() const { return value.toString(); }
|
||||
JSObject &toObject() const { return value.toObject(); }
|
||||
JSObject *toObjectOrNull() const { return value.toObjectOrNull(); }
|
||||
void *toGCThing() const { return value.toGCThing(); }
|
||||
double toDouble() const { return value.toDouble(); }
|
||||
int32 toInt32() const { return value.toInt32(); }
|
||||
JSString *toString() const { return value.toString(); }
|
||||
bool toBoolean() const { return value.toBoolean(); }
|
||||
double toNumber() const { return value.toNumber(); }
|
||||
|
||||
JSGCTraceKind gcKind() const { return value.gcKind(); }
|
||||
|
||||
|
@ -1,26 +0,0 @@
|
||||
function referencesVia(from, edge, to) {
|
||||
if (typeof findReferences !== 'function')
|
||||
return true;
|
||||
|
||||
edge = "edge: " + edge;
|
||||
var edges = findReferences(to);
|
||||
if (edge in edges && edges[edge].indexOf(from) != -1)
|
||||
return true;
|
||||
|
||||
// Be nice: make it easy to fix if the edge name has just changed.
|
||||
var alternatives = [];
|
||||
for (var e in edges) {
|
||||
if (edges[e].indexOf(from) != -1)
|
||||
alternatives.push(e);
|
||||
}
|
||||
if (alternatives.length == 0) {
|
||||
print("referent not referred to by referrer after all");
|
||||
} else {
|
||||
print("referent is not referenced via: " + uneval(edge));
|
||||
print("but it is referenced via: " + uneval(alternatives));
|
||||
}
|
||||
print("all incoming edges, from any object:");
|
||||
for (var e in edges)
|
||||
print(e);
|
||||
return false;
|
||||
}
|
@ -82,13 +82,6 @@ test("new WeakMap()", function(w) WeakMap.prototype.has.call(w, {}));
|
||||
test("new WeakMap()", function(w) WeakMap.prototype.get.call(w, {}));
|
||||
test("new WeakMap()", function(w) WeakMap.prototype.delete.call(w, {}));
|
||||
test("new WeakMap()", function(w) WeakMap.prototype.set.call(w, {}));
|
||||
test("new Map()", function(w) Map.prototype.has.call(w, {}));
|
||||
test("new Map()", function(w) Map.prototype.get.call(w, {}));
|
||||
test("new Map()", function(w) Map.prototype.delete.call(w, {}));
|
||||
test("new Map()", function(w) Map.prototype.set.call(w, {}));
|
||||
test("new Set()", function(w) Set.prototype.has.call(w, {}));
|
||||
test("new Set()", function(w) Set.prototype.add.call(w, {}));
|
||||
test("new Set()", function(w) Set.prototype.delete.call(w, {}));
|
||||
|
||||
test("new Int8Array(1)", function(a) Int8Array.prototype.subarray.call(a).toString());
|
||||
test("new Uint8Array(1)", function(a) Uint8Array.prototype.subarray.call(a).toString());
|
||||
|
@ -1,18 +0,0 @@
|
||||
// Map.prototype.delete works whether the key is present or not.
|
||||
|
||||
var m = new Map;
|
||||
var key = {};
|
||||
|
||||
// when the map is new
|
||||
assertEq(m.delete(key), false);
|
||||
assertEq(m.has(key), false);
|
||||
|
||||
// when the key is present
|
||||
assertEq(m.set(key, 'x'), undefined);
|
||||
assertEq(m.delete(key), true);
|
||||
assertEq(m.has(key), false);
|
||||
assertEq(m.get(key), undefined);
|
||||
|
||||
// when the key has already been deleted
|
||||
assertEq(m.delete(key), false);
|
||||
assertEq(m.has(key), false);
|
@ -1,16 +0,0 @@
|
||||
// Check marking through the keys of a Map.
|
||||
|
||||
load(libdir + "referencesVia.js");
|
||||
|
||||
var m = new Map;
|
||||
for (var i = 0; i < 20; i++) {
|
||||
var n = new Map;
|
||||
n.set(m, i);
|
||||
assertEq(referencesVia(n, 'key', m), true);
|
||||
m = n;
|
||||
}
|
||||
|
||||
gc();
|
||||
gc();
|
||||
|
||||
// TODO: walk the chain using for-of to make sure everything is still there
|
@ -1,14 +0,0 @@
|
||||
// Check marking through the values of a Map.
|
||||
|
||||
load(libdir + "referencesVia.js");
|
||||
|
||||
var m = new Map;
|
||||
for (var i = 0; i < 20; i++) {
|
||||
var n = new Map;
|
||||
n.set(i, m);
|
||||
assertEq(referencesVia(n, 'value', m), true);
|
||||
m = n;
|
||||
}
|
||||
|
||||
gc();
|
||||
gc();
|
@ -1,41 +0,0 @@
|
||||
// Map.prototype.get and .has basically work
|
||||
var m = new Map;
|
||||
|
||||
function rope() {
|
||||
var s = "s";
|
||||
for (var i = 0; i < 16; i++)
|
||||
s += s;
|
||||
return s;
|
||||
}
|
||||
|
||||
var keys = [undefined, null, true, false,
|
||||
0, 1, 65535, 65536, 2147483647, 2147483648, 4294967295, 4294967296,
|
||||
-1, -65536, -2147483648,
|
||||
0.5, Math.sqrt(81), Math.PI,
|
||||
Number.MAX_VALUE, -Number.MAX_VALUE, Number.MIN_VALUE, -Number.MIN_VALUE,
|
||||
-0, NaN, Infinity, -Infinity,
|
||||
"", "\0", "a", "ab", "abcdefg", rope(),
|
||||
{}, [], /a*b/, Object.prototype, Object];
|
||||
|
||||
for (var i = 0; i < keys.length; i++) {
|
||||
// without being set
|
||||
var key = keys[i];
|
||||
assertEq(m.has(key), false);
|
||||
assertEq(m.get(key), undefined);
|
||||
|
||||
// after being set
|
||||
var v = {};
|
||||
assertEq(m.set(key, v), undefined);
|
||||
assertEq(m.has(key), true);
|
||||
assertEq(m.get(key), v);
|
||||
|
||||
// after being deleted
|
||||
assertEq(m.delete(key), true);
|
||||
assertEq(m.has(key), false);
|
||||
assertEq(m.get(key), undefined);
|
||||
|
||||
m.set(key, v);
|
||||
}
|
||||
|
||||
for (var i = 0; i < keys.length; i++)
|
||||
assertEq(m.has(keys[i]), true);
|
@ -1,8 +0,0 @@
|
||||
// Maps can hold at least 64K values.
|
||||
|
||||
var N = 1 << 16;
|
||||
var m = new Map;
|
||||
for (var i = 0; i < N; i++)
|
||||
assertEq(m.set(i, i), undefined);
|
||||
for (var i = 0; i < N; i++)
|
||||
assertEq(m.get(i), i);
|
@ -1,15 +0,0 @@
|
||||
// Setting a Map key to undefined, or a missing argument, isn't the same as deleting it.
|
||||
|
||||
var m = new Map;
|
||||
m.set(42, undefined);
|
||||
assertEq(m.has(42), true);
|
||||
assertEq(m.get(42), undefined);
|
||||
|
||||
m.set(42, "wrong");
|
||||
m.set(42);
|
||||
assertEq(m.has(42), true);
|
||||
assertEq(m.get(42), undefined);
|
||||
|
||||
m.set();
|
||||
assertEq(m.has(undefined), true);
|
||||
assertEq(m.get(undefined), undefined);
|
@ -1,33 +0,0 @@
|
||||
// Map surfaces
|
||||
|
||||
var desc = Object.getOwnPropertyDescriptor(this, "Map");
|
||||
assertEq(desc.enumerable, false);
|
||||
assertEq(desc.configurable, true);
|
||||
assertEq(desc.writable, true);
|
||||
|
||||
assertEq(typeof Map, 'function');
|
||||
assertEq(Object.keys(Map).length, 0);
|
||||
assertEq(Map.length, 0);
|
||||
assertEq(Map.name, "Map");
|
||||
|
||||
assertEq(Object.getPrototypeOf(Map.prototype), Object.prototype);
|
||||
assertEq(Object.prototype.toString.call(Map.prototype), "[object Map]");
|
||||
assertEq(Object.prototype.toString.call(new Map), "[object Map]");
|
||||
assertEq(Object.prototype.toString.call(Map()), "[object Map]");
|
||||
assertEq(Object.keys(Map.prototype).join(), "");
|
||||
assertEq(Map.prototype.constructor, Map);
|
||||
|
||||
function checkMethod(name, arity) {
|
||||
var desc = Object.getOwnPropertyDescriptor(Map.prototype, name);
|
||||
assertEq(desc.enumerable, false);
|
||||
assertEq(desc.configurable, true);
|
||||
assertEq(desc.writable, true);
|
||||
assertEq(typeof desc.value, 'function');
|
||||
assertEq(desc.value.name, name);
|
||||
assertEq(desc.value.length, arity);
|
||||
}
|
||||
|
||||
checkMethod("get", 1);
|
||||
checkMethod("has", 1);
|
||||
checkMethod("set", 2);
|
||||
checkMethod("delete", 1);
|
@ -1,23 +0,0 @@
|
||||
// Map methods throw when passed a this-value that isn't a Map.
|
||||
|
||||
load(libdir + "asserts.js");
|
||||
|
||||
function testcase(obj, fn) {
|
||||
assertEq(typeof fn, "function");
|
||||
var args = Array.slice(arguments, 2);
|
||||
assertThrowsInstanceOf(function () { fn.apply(obj, args); }, TypeError);
|
||||
}
|
||||
|
||||
function test(obj) {
|
||||
testcase(obj, Map.prototype.get, "x");
|
||||
testcase(obj, Map.prototype.has, "x");
|
||||
testcase(obj, Map.prototype.set, "x", 1);
|
||||
testcase(obj, Map.prototype.delete, "x");
|
||||
}
|
||||
|
||||
test(Map.prototype);
|
||||
test(Object.create(new Map));
|
||||
test(new Set());
|
||||
test({});
|
||||
test(null);
|
||||
test(undefined);
|
@ -1,14 +0,0 @@
|
||||
// Map methods work when arguments are omitted.
|
||||
|
||||
var m = new Map;
|
||||
assertEq(m.has(), false);
|
||||
assertEq(m.get(), undefined);
|
||||
assertEq(m.delete(), false);
|
||||
assertEq(m.has(), false);
|
||||
assertEq(m.get(), undefined);
|
||||
assertEq(m.set(), undefined);
|
||||
assertEq(m.has(), true);
|
||||
assertEq(m.get(), undefined);
|
||||
assertEq(m.delete(), true);
|
||||
assertEq(m.has(), false);
|
||||
assertEq(m.get(), undefined);
|
@ -1,16 +0,0 @@
|
||||
// Check marking through the elements of a Set.
|
||||
|
||||
load(libdir + "referencesVia.js");
|
||||
|
||||
var s = new Set;
|
||||
for (var i = 0; i < 20; i++) {
|
||||
var t = new Set;
|
||||
t.add(s);
|
||||
assertEq(referencesVia(t, 'key', s), true);
|
||||
s = t;
|
||||
}
|
||||
|
||||
gc();
|
||||
gc();
|
||||
|
||||
// TODO: walk the chain and make sure it's still intact
|
@ -1,8 +0,0 @@
|
||||
// Sets can hold at least 64K values.
|
||||
|
||||
var N = 1 << 16;
|
||||
var s = new Set;
|
||||
for (var i = 0; i < N; i++)
|
||||
assertEq(s.add(i), undefined);
|
||||
for (var i = 0; i < N; i++)
|
||||
assertEq(s.has(i), true);
|
@ -1,32 +0,0 @@
|
||||
// Set surfaces
|
||||
|
||||
var desc = Object.getOwnPropertyDescriptor(this, "Set");
|
||||
assertEq(desc.enumerable, false);
|
||||
assertEq(desc.configurable, true);
|
||||
assertEq(desc.writable, true);
|
||||
|
||||
assertEq(typeof Set, 'function');
|
||||
assertEq(Object.keys(Set).length, 0);
|
||||
assertEq(Set.length, 0);
|
||||
assertEq(Set.name, "Set");
|
||||
|
||||
assertEq(Object.getPrototypeOf(Set.prototype), Object.prototype);
|
||||
assertEq(Object.prototype.toString.call(Set.prototype), "[object Set]");
|
||||
assertEq(Object.prototype.toString.call(new Set), "[object Set]");
|
||||
assertEq(Object.prototype.toString.call(Set()), "[object Set]");
|
||||
assertEq(Object.keys(Set.prototype).join(), "");
|
||||
assertEq(Set.prototype.constructor, Set);
|
||||
|
||||
function checkMethod(name, arity) {
|
||||
var desc = Object.getOwnPropertyDescriptor(Set.prototype, "get");
|
||||
assertEq(desc.enumerable, false);
|
||||
assertEq(desc.configurable, true);
|
||||
assertEq(desc.writable, true);
|
||||
assertEq(typeof desc.value, 'function');
|
||||
assertEq(desc.value.name, name);
|
||||
assertEq(desc.value.length, arity);
|
||||
}
|
||||
|
||||
checkMethod("has", 1);
|
||||
checkMethod("add", 1);
|
||||
checkMethod("delete", 1);
|
@ -1,22 +0,0 @@
|
||||
// Set methods throw when passed a this-value that isn't a Set.
|
||||
|
||||
load(libdir + "asserts.js");
|
||||
|
||||
function testcase(obj, fn) {
|
||||
assertEq(typeof fn, "function");
|
||||
var args = Array.slice(arguments, 2);
|
||||
assertThrowsInstanceOf(function () { fn.apply(obj, args); }, TypeError);
|
||||
}
|
||||
|
||||
function test(obj) {
|
||||
testcase(obj, Set.prototype.has, 12);
|
||||
testcase(obj, Set.prototype.add, 12);
|
||||
testcase(obj, Set.prototype.delete, 12);
|
||||
}
|
||||
|
||||
test(Set.prototype);
|
||||
test(Object.create(new Set));
|
||||
test(new Map());
|
||||
test({});
|
||||
test(null);
|
||||
test(undefined);
|
@ -1,10 +0,0 @@
|
||||
// Set methods work when arguments are omitted.
|
||||
|
||||
var s = new Set;
|
||||
assertEq(s.has(), false);
|
||||
assertEq(s.delete(), false);
|
||||
assertEq(s.has(), false);
|
||||
assertEq(s.add(), undefined);
|
||||
assertEq(s.has(), true);
|
||||
assertEq(s.delete(), true);
|
||||
assertEq(s.has(), false);
|
@ -1,25 +0,0 @@
|
||||
// for-in loops on Maps and Sets enumerate properties.
|
||||
|
||||
var test = function test(obj) {
|
||||
assertEq(Object.keys(obj).length, 0);
|
||||
|
||||
var i = 0, v;
|
||||
for (v in obj)
|
||||
i++;
|
||||
assertEq(i, 0);
|
||||
|
||||
obj.ownProp = 1;
|
||||
assertEq(Object.keys(obj).join(), "ownProp");
|
||||
|
||||
for (v in obj)
|
||||
i++;
|
||||
assertEq(i, 1);
|
||||
assertEq(v, "ownProp");
|
||||
|
||||
delete obj.ownProp;
|
||||
};
|
||||
|
||||
test(Map.prototype);
|
||||
test(new Map);
|
||||
test(Set.prototype);
|
||||
test(new Set);
|
@ -1,37 +0,0 @@
|
||||
// -0 is a distinct key from +0.
|
||||
|
||||
var s = new Set;
|
||||
s.add(-0);
|
||||
assertEq(s.has(0), false);
|
||||
assertEq(s.has(-0), true);
|
||||
|
||||
assertEq(s.delete(0), false);
|
||||
assertEq(s.has(-0), true);
|
||||
|
||||
s.add(0);
|
||||
assertEq(s.delete(-0), true);
|
||||
assertEq(s.has(0), true);
|
||||
assertEq(s.has(-0), false);
|
||||
|
||||
var m = new Map;
|
||||
m.set(-0, 'x');
|
||||
assertEq(m.has(0), false);
|
||||
assertEq(m.get(0), undefined);
|
||||
assertEq(m.has(-0), true);
|
||||
assertEq(m.get(-0), 'x');
|
||||
|
||||
assertEq(m.delete(0), false);
|
||||
assertEq(m.has(-0), true);
|
||||
assertEq(m.get(-0), 'x');
|
||||
|
||||
m.set(0, 'y');
|
||||
assertEq(m.has(0), true);
|
||||
assertEq(m.get(0), 'y');
|
||||
assertEq(m.has(-0), true);
|
||||
assertEq(m.get(-0), 'x');
|
||||
|
||||
assertEq(m.delete(-0), true);
|
||||
assertEq(m.has(0), true);
|
||||
assertEq(m.get(0), 'y');
|
||||
assertEq(m.has(-0), false);
|
||||
assertEq(m.get(-0), undefined);
|
@ -1,28 +0,0 @@
|
||||
// Different representations of the same number or string are treated as the same Map key.
|
||||
|
||||
var m = new Map;
|
||||
var test = function test(a, b) {
|
||||
m.set(a, 'secret');
|
||||
assertEq(m.get(b), 'secret');
|
||||
m.set(b, 'password');
|
||||
assertEq(m.get(a), 'password');
|
||||
|
||||
assertEq(a, b);
|
||||
};
|
||||
|
||||
// Float and integer representations of the same number are the same key.
|
||||
test(9, Math.sqrt(81));
|
||||
|
||||
// Ordinary strings and ropes are the same key.
|
||||
var a = Array(1001).join('x');
|
||||
var b = Array(501).join('x') + Array(501).join('x');
|
||||
test(a, b);
|
||||
|
||||
// Two structurally different ropes with the same characters are the same key.
|
||||
a = "";
|
||||
b = "";
|
||||
for (var i = 0; i < 10; i++) {
|
||||
a = Array(501).join('x') + a;
|
||||
b = b + Array(501).join('x');
|
||||
}
|
||||
test(a, b);
|
@ -1,11 +0,0 @@
|
||||
// Number keys are distinct from string keys that would name the same property.
|
||||
|
||||
var s = new Set;
|
||||
|
||||
s.add(17);
|
||||
assertEq(s.has("17"), false);
|
||||
assertEq(s.has(17), true);
|
||||
s.add("17");
|
||||
assertEq(s.delete(17), true);
|
||||
assertEq(s.has("17"), true);
|
||||
assertEq(s.has(17), false);
|
@ -1,15 +0,0 @@
|
||||
// NaN is equal to itself for the purpose of key lookups.
|
||||
|
||||
var m = new Map;
|
||||
m.set(NaN, "ok");
|
||||
assertEq(m.has(NaN), true);
|
||||
assertEq(m.get(NaN), "ok");
|
||||
assertEq(m.delete(NaN), true);
|
||||
assertEq(m.has(NaN), false);
|
||||
assertEq(m.get(NaN), undefined);
|
||||
|
||||
var s = new Set;
|
||||
s.add(NaN);
|
||||
assertEq(s.has(NaN), true);
|
||||
assertEq(s.delete(NaN), true);
|
||||
assertEq(s.has(NaN), false);
|
@ -83,7 +83,6 @@
|
||||
#include "jstypedarray.h"
|
||||
|
||||
#include "ds/LifoAlloc.h"
|
||||
#include "builtin/MapObject.h"
|
||||
#include "builtin/RegExp.h"
|
||||
#include "frontend/BytecodeCompiler.h"
|
||||
#include "frontend/BytecodeEmitter.h"
|
||||
@ -1724,8 +1723,6 @@ static JSStdName standard_class_atoms[] = {
|
||||
{js_InitJSONClass, EAGER_ATOM_AND_CLASP(JSON)},
|
||||
{js_InitTypedArrayClasses, EAGER_CLASS_ATOM(ArrayBuffer), &js::ArrayBuffer::slowClass},
|
||||
{js_InitWeakMapClass, EAGER_CLASS_ATOM(WeakMap), &js::WeakMapClass},
|
||||
{js_InitMapClass, EAGER_CLASS_ATOM(Map), &js::MapObject::class_},
|
||||
{js_InitSetClass, EAGER_CLASS_ATOM(Set), &js::SetObject::class_},
|
||||
{NULL, 0, NULL, NULL}
|
||||
};
|
||||
|
||||
|
@ -79,7 +79,6 @@
|
||||
#include "jswatchpoint.h"
|
||||
#include "jswrapper.h"
|
||||
|
||||
#include "builtin/MapObject.h"
|
||||
#include "frontend/BytecodeCompiler.h"
|
||||
#include "frontend/BytecodeEmitter.h"
|
||||
#include "frontend/Parser.h"
|
||||
@ -7055,9 +7054,7 @@ js::ReportIncompatibleMethod(JSContext *cx, CallReceiver call, Class *clasp)
|
||||
|
||||
#ifdef DEBUG
|
||||
if (thisv.isObject()) {
|
||||
JS_ASSERT(thisv.toObject().getClass() != clasp ||
|
||||
!thisv.toObject().getProto() ||
|
||||
thisv.toObject().getProto()->getClass() != clasp);
|
||||
JS_ASSERT(thisv.toObject().getClass() != clasp);
|
||||
} else if (thisv.isString()) {
|
||||
JS_ASSERT(clasp != &StringClass);
|
||||
} else if (thisv.isNumber()) {
|
||||
|
@ -92,8 +92,6 @@ JS_PROTO(Uint8ClampedArray, 33, js_InitTypedArrayClasses)
|
||||
JS_PROTO(Proxy, 34, js_InitProxyClass)
|
||||
JS_PROTO(AnyName, 35, js_InitNullClass)
|
||||
JS_PROTO(WeakMap, 36, js_InitWeakMapClass)
|
||||
JS_PROTO(Map, 37, js_InitMapClass)
|
||||
JS_PROTO(Set, 38, js_InitSetClass)
|
||||
|
||||
#undef XML_INIT
|
||||
#undef NAMESPACE_INIT
|
||||
|
@ -45,7 +45,6 @@
|
||||
#include "jsmath.h"
|
||||
#include "json.h"
|
||||
|
||||
#include "builtin/MapObject.h"
|
||||
#include "builtin/RegExp.h"
|
||||
#include "frontend/BytecodeEmitter.h"
|
||||
#include "vm/GlobalObject-inl.h"
|
||||
@ -312,9 +311,7 @@ GlobalObject::initStandardClasses(JSContext *cx)
|
||||
js_InitIteratorClasses(cx, this) &&
|
||||
#endif
|
||||
js_InitDateClass(cx, this) &&
|
||||
js_InitProxyClass(cx, this) &&
|
||||
js_InitMapClass(cx, this) &&
|
||||
js_InitSetClass(cx, this);
|
||||
js_InitProxyClass(cx, this);
|
||||
}
|
||||
|
||||
void
|
||||
|
Loading…
Reference in New Issue
Block a user