#392: Symbol.toStringTag M1114580 (w/o ESClassValue change; w/45ESR boilerplate)
This commit is contained in:
parent
c1f84d6285
commit
3cf6b4057c
|
@ -1327,6 +1327,7 @@ static bool
|
||||||
NPObjWrapper_SetProperty(JSContext *cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id,
|
NPObjWrapper_SetProperty(JSContext *cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id,
|
||||||
JS::MutableHandle<JS::Value> vp, JS::ObjectOpResult &result)
|
JS::MutableHandle<JS::Value> vp, JS::ObjectOpResult &result)
|
||||||
{
|
{
|
||||||
|
MOZ_ASSERT(false, "See bug 1114580, 2f9eb93beee9"); // NYI XXX TenFourFox 392
|
||||||
NPObject *npobj = GetNPObject(cx, obj);
|
NPObject *npobj = GetNPObject(cx, obj);
|
||||||
|
|
||||||
if (!npobj || !npobj->_class || !npobj->_class->hasProperty ||
|
if (!npobj || !npobj->_class || !npobj->_class->hasProperty ||
|
||||||
|
|
|
@ -847,6 +847,10 @@ enum ESClassValue {
|
||||||
ESClass_Boolean, ESClass_RegExp, ESClass_ArrayBuffer, ESClass_SharedArrayBuffer,
|
ESClass_Boolean, ESClass_RegExp, ESClass_ArrayBuffer, ESClass_SharedArrayBuffer,
|
||||||
ESClass_Date, ESClass_Set, ESClass_Map,
|
ESClass_Date, ESClass_Set, ESClass_Map,
|
||||||
|
|
||||||
|
/** Not yet implemented (TenFourFox issue 392). */
|
||||||
|
ESClass_Promise, ESClass_MapIterator, ESClass_SetIterator,
|
||||||
|
ESClass_Arguments, ESClass_Error,
|
||||||
|
|
||||||
/** None of the above. */
|
/** None of the above. */
|
||||||
ESClass_Other
|
ESClass_Other
|
||||||
};
|
};
|
||||||
|
|
|
@ -171,7 +171,8 @@ GlobalObject::initMapIteratorProto(JSContext* cx, Handle<GlobalObject*> global)
|
||||||
RootedPlainObject proto(cx, NewObjectWithGivenProto<PlainObject>(cx, base));
|
RootedPlainObject proto(cx, NewObjectWithGivenProto<PlainObject>(cx, base));
|
||||||
if (!proto)
|
if (!proto)
|
||||||
return false;
|
return false;
|
||||||
if (!JS_DefineFunctions(cx, proto, MapIteratorObject::methods))
|
if (!JS_DefineFunctions(cx, proto, MapIteratorObject::methods) ||
|
||||||
|
!DefineToStringTag(cx, proto, cx->names().MapIterator))
|
||||||
return false;
|
return false;
|
||||||
global->setReservedSlot(MAP_ITERATOR_PROTO, ObjectValue(*proto));
|
global->setReservedSlot(MAP_ITERATOR_PROTO, ObjectValue(*proto));
|
||||||
return true;
|
return true;
|
||||||
|
@ -320,6 +321,10 @@ MapObject::initClass(JSContext* cx, JSObject* obj)
|
||||||
RootedId iteratorId(cx, SYMBOL_TO_JSID(cx->wellKnownSymbols().iterator));
|
RootedId iteratorId(cx, SYMBOL_TO_JSID(cx->wellKnownSymbols().iterator));
|
||||||
if (!JS_DefinePropertyById(cx, proto, iteratorId, funval, 0))
|
if (!JS_DefinePropertyById(cx, proto, iteratorId, funval, 0))
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
|
// Define Map.prototype[@@toStringTag].
|
||||||
|
if (!DefineToStringTag(cx, proto, cx->names().Map))
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
return proto;
|
return proto;
|
||||||
}
|
}
|
||||||
|
@ -897,7 +902,8 @@ GlobalObject::initSetIteratorProto(JSContext* cx, Handle<GlobalObject*> global)
|
||||||
RootedPlainObject proto(cx, NewObjectWithGivenProto<PlainObject>(cx, base));
|
RootedPlainObject proto(cx, NewObjectWithGivenProto<PlainObject>(cx, base));
|
||||||
if (!proto)
|
if (!proto)
|
||||||
return false;
|
return false;
|
||||||
if (!JS_DefineFunctions(cx, proto, SetIteratorObject::methods))
|
if (!JS_DefineFunctions(cx, proto, SetIteratorObject::methods) ||
|
||||||
|
!DefineToStringTag(cx, proto, cx->names().SetIterator))
|
||||||
return false;
|
return false;
|
||||||
global->setReservedSlot(SET_ITERATOR_PROTO, ObjectValue(*proto));
|
global->setReservedSlot(SET_ITERATOR_PROTO, ObjectValue(*proto));
|
||||||
return true;
|
return true;
|
||||||
|
@ -1051,6 +1057,10 @@ SetObject::initClass(JSContext* cx, JSObject* obj)
|
||||||
RootedId iteratorId(cx, SYMBOL_TO_JSID(cx->wellKnownSymbols().iterator));
|
RootedId iteratorId(cx, SYMBOL_TO_JSID(cx->wellKnownSymbols().iterator));
|
||||||
if (!JS_DefinePropertyById(cx, proto, iteratorId, funval, 0))
|
if (!JS_DefinePropertyById(cx, proto, iteratorId, funval, 0))
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
|
// Define Set.prototype[@@toStringTag].
|
||||||
|
if (!DefineToStringTag(cx, proto, cx->names().Set))
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
return proto;
|
return proto;
|
||||||
}
|
}
|
||||||
|
|
|
@ -306,63 +306,141 @@ js::ObjectToSource(JSContext* cx, HandleObject obj)
|
||||||
}
|
}
|
||||||
#endif /* JS_HAS_TOSOURCE */
|
#endif /* JS_HAS_TOSOURCE */
|
||||||
|
|
||||||
JSString*
|
/* ES6 19.1.3.6 (after bug 1114580/TenFourFox issue 392) */
|
||||||
JS_BasicObjectToString(JSContext* cx, HandleObject obj)
|
|
||||||
{
|
|
||||||
// Some classes are really common, don't allocate new strings for them.
|
|
||||||
// The ordering below is based on the measurements in bug 966264.
|
|
||||||
if (obj->is<PlainObject>())
|
|
||||||
return cx->names().objectObject;
|
|
||||||
if (obj->is<StringObject>())
|
|
||||||
return cx->names().objectString;
|
|
||||||
if (obj->is<ArrayObject>())
|
|
||||||
return cx->names().objectArray;
|
|
||||||
if (obj->is<JSFunction>())
|
|
||||||
return cx->names().objectFunction;
|
|
||||||
if (obj->is<NumberObject>())
|
|
||||||
return cx->names().objectNumber;
|
|
||||||
|
|
||||||
const char* className = GetObjectClassName(cx, obj);
|
|
||||||
|
|
||||||
if (strcmp(className, "Window") == 0)
|
|
||||||
return cx->names().objectWindow;
|
|
||||||
|
|
||||||
StringBuffer sb(cx);
|
|
||||||
if (!sb.append("[object ") || !sb.append(className, strlen(className)) ||
|
|
||||||
!sb.append("]"))
|
|
||||||
{
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
return sb.finishString();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ES5 15.2.4.2. Note steps 1 and 2 are errata. */
|
|
||||||
bool
|
bool
|
||||||
js::obj_toString(JSContext* cx, unsigned argc, Value* vp)
|
js::obj_toString(JSContext* cx, unsigned argc, Value* vp)
|
||||||
{
|
{
|
||||||
CallArgs args = CallArgsFromVp(argc, vp);
|
CallArgs args = CallArgsFromVp(argc, vp);
|
||||||
|
|
||||||
/* Step 1. */
|
// Step 1.
|
||||||
if (args.thisv().isUndefined()) {
|
if (args.thisv().isUndefined()) {
|
||||||
args.rval().setString(cx->names().objectUndefined);
|
args.rval().setString(cx->names().objectUndefined);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Step 2. */
|
// Step 2.
|
||||||
if (args.thisv().isNull()) {
|
if (args.thisv().isNull()) {
|
||||||
args.rval().setString(cx->names().objectNull);
|
args.rval().setString(cx->names().objectNull);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Step 3. */
|
// Step 3.
|
||||||
RootedObject obj(cx, ToObject(cx, args.thisv()));
|
RootedObject obj(cx, ToObject(cx, args.thisv()));
|
||||||
if (!obj)
|
if (!obj)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
/* Steps 4-5. */
|
// Step 4.
|
||||||
JSString* str = JS_BasicObjectToString(cx, obj);
|
bool isArray;
|
||||||
|
if (!IsArray(cx, obj, &isArray))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Step 5.
|
||||||
|
RootedString builtinTag(cx);
|
||||||
|
if (isArray) {
|
||||||
|
builtinTag = cx->names().objectArray;
|
||||||
|
} else {
|
||||||
|
// Steps 6-13.
|
||||||
|
ESClassValue cls;
|
||||||
|
if (!GetBuiltinClass(cx, obj, &cls))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
switch (cls) {
|
||||||
|
case ESClass_String:
|
||||||
|
builtinTag = cx->names().objectString;
|
||||||
|
break;
|
||||||
|
case ESClass_Arguments: // NYI XXX
|
||||||
|
builtinTag = cx->names().objectArguments;
|
||||||
|
break;
|
||||||
|
case ESClass_Error: // NYI XXX
|
||||||
|
builtinTag = cx->names().objectError;
|
||||||
|
break;
|
||||||
|
case ESClass_Boolean:
|
||||||
|
builtinTag = cx->names().objectBoolean;
|
||||||
|
break;
|
||||||
|
case ESClass_Number:
|
||||||
|
builtinTag = cx->names().objectNumber;
|
||||||
|
break;
|
||||||
|
case ESClass_Date:
|
||||||
|
builtinTag = cx->names().objectDate;
|
||||||
|
break;
|
||||||
|
case ESClass_RegExp:
|
||||||
|
builtinTag = cx->names().objectRegExp;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (obj->isCallable()) {
|
||||||
|
// Non-standard: Prevent <object> from showing up as Function.
|
||||||
|
RootedObject unwrapped(cx, CheckedUnwrap(obj));
|
||||||
|
if (!unwrapped || !unwrapped->getClass()->isDOMClass())
|
||||||
|
builtinTag = cx->names().objectFunction;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Step 14.
|
||||||
|
// Currently omitted for non-standard fallback.
|
||||||
|
|
||||||
|
// Step 15.
|
||||||
|
RootedValue tag(cx);
|
||||||
|
RootedId toStringTagId(cx, SYMBOL_TO_JSID(cx->wellKnownSymbols().toStringTag));
|
||||||
|
if (!GetProperty(cx, obj, obj, toStringTagId, &tag)) {
|
||||||
|
if (IsProxy(obj)) {
|
||||||
|
// XXX: This is a dirty hack for jit-test/tests/basic/bug807623.js.
|
||||||
|
// Just pass through if the property lookup fails; assume that we
|
||||||
|
// didn't have a tag set in that situation. Proxy::get sets the tag
|
||||||
|
// to undefined for us in that case. TenFourFox issue 392.
|
||||||
|
//
|
||||||
|
// Note that this isn't an issue for current Firefox because
|
||||||
|
// Proxy.create() was removed. We can't do this because of our
|
||||||
|
// backwards compatibility, and other tests also rely on it
|
||||||
|
// currently (see M892903), but fortunately using proper ES6 Proxy
|
||||||
|
// methods works as expected even without this hack:
|
||||||
|
//
|
||||||
|
// var h={}; var p=new Proxy({[Symbol.toStringTag]:"abc"}, h);
|
||||||
|
// print(Object.prototype.toString.call(p)); /* [object abc] */
|
||||||
|
//
|
||||||
|
// Thus, this code path is only entered in the legacy case, which
|
||||||
|
// shouldn't know about @@toStringTag anyway.
|
||||||
|
//
|
||||||
|
RootedValue receiver(cx, ObjectValue(*obj));
|
||||||
|
|
||||||
|
(void)proxy_GetProperty(cx, obj, receiver, toStringTagId, &tag);
|
||||||
|
cx->clearPendingException();
|
||||||
|
} else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 16.
|
||||||
|
if (!tag.isString()) {
|
||||||
|
// Non-standard (bug 1277801): Use ClassName as a fallback in the interim
|
||||||
|
if (!builtinTag) {
|
||||||
|
const char* className = GetObjectClassName(cx, obj);
|
||||||
|
|
||||||
|
StringBuffer sb(cx);
|
||||||
|
if (!sb.append("[object ") || !sb.append(className, strlen(className)) ||
|
||||||
|
!sb.append("]"))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
builtinTag = sb.finishString();
|
||||||
|
if (!builtinTag)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
args.rval().setString(builtinTag);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 17.
|
||||||
|
StringBuffer sb(cx);
|
||||||
|
if (!sb.append("[object ") || !sb.append(tag.toString()) || !sb.append("]"))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
RootedString str(cx, sb.finishString());
|
||||||
|
|
||||||
if (!str)
|
if (!str)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
args.rval().setString(str);
|
args.rval().setString(str);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -79,6 +79,7 @@ SymbolObject::initClass(JSContext* cx, HandleObject obj)
|
||||||
|
|
||||||
if (!LinkConstructorAndPrototype(cx, ctor, proto) ||
|
if (!LinkConstructorAndPrototype(cx, ctor, proto) ||
|
||||||
!DefinePropertiesAndFunctions(cx, proto, properties, methods) ||
|
!DefinePropertiesAndFunctions(cx, proto, properties, methods) ||
|
||||||
|
!DefineToStringTag(cx, proto, cx->names().Symbol) ||
|
||||||
!DefinePropertiesAndFunctions(cx, ctor, nullptr, staticMethods) ||
|
!DefinePropertiesAndFunctions(cx, ctor, nullptr, staticMethods) ||
|
||||||
!GlobalObject::initBuiltinConstructor(cx, global, JSProto_Symbol, ctor, proto))
|
!GlobalObject::initBuiltinConstructor(cx, global, JSProto_Symbol, ctor, proto))
|
||||||
{
|
{
|
||||||
|
|
|
@ -1167,3 +1167,25 @@ function TypedArrayStaticOf(/*...items*/) {
|
||||||
// Step 8.
|
// Step 8.
|
||||||
return newObj;
|
return newObj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ES 2016 draft Mar 25, 2016 22.2.2.4.
|
||||||
|
function TypedArraySpecies() {
|
||||||
|
// Step 1.
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ES 2017 draft June 2, 2016 22.2.3.32
|
||||||
|
function TypedArrayToStringTag() {
|
||||||
|
// Step 1.
|
||||||
|
var O = this;
|
||||||
|
|
||||||
|
// Steps 2-3.
|
||||||
|
if (!IsObject(O) || !IsTypedArray(O))
|
||||||
|
return undefined;
|
||||||
|
|
||||||
|
// Steps 4-6.
|
||||||
|
// Modified to retrieve the [[TypedArrayName]] from the constructor.
|
||||||
|
return _NameForTypedArray(O);
|
||||||
|
}
|
||||||
|
_SetCanonicalName(TypedArrayToStringTag, "get [Symbol.toStringTag]");
|
||||||
|
|
||||||
|
|
|
@ -455,6 +455,8 @@ InitWeakMapClass(JSContext* cx, HandleObject obj, bool defineMembers)
|
||||||
if (defineMembers) {
|
if (defineMembers) {
|
||||||
if (!DefinePropertiesAndFunctions(cx, proto, nullptr, weak_map_methods))
|
if (!DefinePropertiesAndFunctions(cx, proto, nullptr, weak_map_methods))
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
if (!DefineToStringTag(cx, proto, cx->names().WeakMap))
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!GlobalObject::initBuiltinConstructor(cx, global, JSProto_WeakMap, ctor, proto))
|
if (!GlobalObject::initBuiltinConstructor(cx, global, JSProto_WeakMap, ctor, proto))
|
||||||
|
|
|
@ -53,6 +53,7 @@ WeakSetObject::initClass(JSContext* cx, JSObject* obj)
|
||||||
if (!ctor ||
|
if (!ctor ||
|
||||||
!LinkConstructorAndPrototype(cx, ctor, proto) ||
|
!LinkConstructorAndPrototype(cx, ctor, proto) ||
|
||||||
!DefinePropertiesAndFunctions(cx, proto, properties, methods) ||
|
!DefinePropertiesAndFunctions(cx, proto, properties, methods) ||
|
||||||
|
!DefineToStringTag(cx, proto, cx->names().WeakSet) ||
|
||||||
!GlobalObject::initBuiltinConstructor(cx, global, JSProto_WeakSet, ctor, proto))
|
!GlobalObject::initBuiltinConstructor(cx, global, JSProto_WeakSet, ctor, proto))
|
||||||
{
|
{
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
|
@ -13,11 +13,7 @@ assertEq(Map.length, 0);
|
||||||
assertEq(Map.name, "Map");
|
assertEq(Map.name, "Map");
|
||||||
|
|
||||||
assertEq(Object.getPrototypeOf(Map.prototype), Object.prototype);
|
assertEq(Object.getPrototypeOf(Map.prototype), Object.prototype);
|
||||||
assertEq("toStringTag" in Symbol, false,
|
assertEq(Object.prototype.toString.call(Map.prototype), "[object Map]");
|
||||||
"if this fails, congratulations! implement " +
|
|
||||||
"Map.prototype[Symbol.toStringTag] = 'Map' in SpiderMonkey and make " +
|
|
||||||
"the next test check for '[object Map]' again");
|
|
||||||
assertEq(Object.prototype.toString.call(Map.prototype), "[object Object]");
|
|
||||||
assertEq(Object.prototype.toString.call(new Map()), "[object Map]");
|
assertEq(Object.prototype.toString.call(new Map()), "[object Map]");
|
||||||
assertEq(Object.keys(Map.prototype).join(), "");
|
assertEq(Object.keys(Map.prototype).join(), "");
|
||||||
assertEq(Map.prototype.constructor, Map);
|
assertEq(Map.prototype.constructor, Map);
|
||||||
|
|
|
@ -13,11 +13,7 @@ assertEq(Set.length, 0);
|
||||||
assertEq(Set.name, "Set");
|
assertEq(Set.name, "Set");
|
||||||
|
|
||||||
assertEq(Object.getPrototypeOf(Set.prototype), Object.prototype);
|
assertEq(Object.getPrototypeOf(Set.prototype), Object.prototype);
|
||||||
assertEq("toStringTag" in Symbol, false,
|
assertEq(Object.prototype.toString.call(Set.prototype), "[object Set]");
|
||||||
"if this fails, congratulations! implement " +
|
|
||||||
"Set.prototype[Symbol.toStringTag] = 'Set' in SpiderMonkey and make " +
|
|
||||||
"the next test check for '[object Set]' again");
|
|
||||||
assertEq(Object.prototype.toString.call(Set.prototype), "[object Object]");
|
|
||||||
assertEq(Object.prototype.toString.call(new Set()), "[object Set]");
|
assertEq(Object.prototype.toString.call(new Set()), "[object Set]");
|
||||||
assertEq(Object.keys(Set.prototype).join(), "");
|
assertEq(Object.keys(Set.prototype).join(), "");
|
||||||
assertEq(Set.prototype.constructor, Set);
|
assertEq(Set.prototype.constructor, Set);
|
||||||
|
|
|
@ -11,7 +11,7 @@ assertEq(WeakMap.length, 0);
|
||||||
assertEq(WeakMap.name, "WeakMap");
|
assertEq(WeakMap.name, "WeakMap");
|
||||||
|
|
||||||
assertEq(Object.getPrototypeOf(WeakMap.prototype), Object.prototype);
|
assertEq(Object.getPrototypeOf(WeakMap.prototype), Object.prototype);
|
||||||
assertEq(Object.prototype.toString.call(WeakMap.prototype), "[object Object]");
|
assertEq(Object.prototype.toString.call(WeakMap.prototype), "[object WeakMap]");
|
||||||
assertEq(Object.prototype.toString.call(new WeakMap()), "[object WeakMap]");
|
assertEq(Object.prototype.toString.call(new WeakMap()), "[object WeakMap]");
|
||||||
assertEq(Object.keys(WeakMap.prototype).join(), "");
|
assertEq(Object.keys(WeakMap.prototype).join(), "");
|
||||||
assertEq(WeakMap.prototype.constructor, WeakMap);
|
assertEq(WeakMap.prototype.constructor, WeakMap);
|
||||||
|
|
|
@ -11,7 +11,7 @@ assertEq(WeakSet.length, 0);
|
||||||
assertEq(WeakSet.name, "WeakSet");
|
assertEq(WeakSet.name, "WeakSet");
|
||||||
|
|
||||||
assertEq(Object.getPrototypeOf(WeakSet.prototype), Object.prototype);
|
assertEq(Object.getPrototypeOf(WeakSet.prototype), Object.prototype);
|
||||||
assertEq(Object.prototype.toString.call(WeakSet.prototype), "[object Object]");
|
assertEq(Object.prototype.toString.call(WeakSet.prototype), "[object WeakSet]");
|
||||||
assertEq(Object.prototype.toString.call(new WeakSet), "[object WeakSet]");
|
assertEq(Object.prototype.toString.call(new WeakSet), "[object WeakSet]");
|
||||||
assertEq(Object.keys(WeakSet.prototype).length, 0);
|
assertEq(Object.keys(WeakSet.prototype).length, 0);
|
||||||
assertEq(WeakSet.prototype.constructor, WeakSet);
|
assertEq(WeakSet.prototype.constructor, WeakSet);
|
||||||
|
|
|
@ -9,13 +9,9 @@ function test(constructor) {
|
||||||
var iter = new constructor()[Symbol.iterator]();
|
var iter = new constructor()[Symbol.iterator]();
|
||||||
assertDeepEq(Reflect.ownKeys(iter), []);
|
assertDeepEq(Reflect.ownKeys(iter), []);
|
||||||
|
|
||||||
// Iterator prototypes only have a .next property.
|
// Iterator prototypes only have a .next and @@toStringTag property.
|
||||||
// At least until we support @@toStringTag.
|
|
||||||
var proto1 = Object.getPrototypeOf(iter);
|
var proto1 = Object.getPrototypeOf(iter);
|
||||||
|
assertDeepEq(Reflect.ownKeys(proto1), ['next', Symbol.toStringTag]);
|
||||||
var names = Reflect.ownKeys(proto1);
|
|
||||||
names.sort();
|
|
||||||
assertDeepEq(Reflect.ownKeys(proto1), ['next']);
|
|
||||||
|
|
||||||
var desc = Object.getOwnPropertyDescriptor(proto1, 'next');
|
var desc = Object.getOwnPropertyDescriptor(proto1, 'next');
|
||||||
assertEq(desc.configurable, true);
|
assertEq(desc.configurable, true);
|
||||||
|
|
|
@ -12,7 +12,7 @@ dbg.onDebuggerStatement = function (frame) {
|
||||||
assertEq(arr[3].class, "Date");
|
assertEq(arr[3].class, "Date");
|
||||||
assertEq(arr[4].class, "Object");
|
assertEq(arr[4].class, "Object");
|
||||||
assertEq(arr[5].class, "Function");
|
assertEq(arr[5].class, "Function");
|
||||||
assertEq(arr[6].class, "Date");
|
assertEq(arr[6].class, "Object");
|
||||||
hits++;
|
hits++;
|
||||||
};
|
};
|
||||||
g.f(Object.prototype, [], eval, new Date,
|
g.f(Object.prototype, [], eval, new Date,
|
||||||
|
|
|
@ -11,8 +11,8 @@ var p2 = r2.proxy;
|
||||||
assertThrowsInstanceOf(() => ({} instanceof p), TypeError);
|
assertThrowsInstanceOf(() => ({} instanceof p), TypeError);
|
||||||
assertThrowsInstanceOf(() => ({} instanceof p2), TypeError);
|
assertThrowsInstanceOf(() => ({} instanceof p2), TypeError);
|
||||||
|
|
||||||
assertEq(Object.prototype.toString.call(p), "[object Object]");
|
assertThrowsInstanceOf(() => Object.prototype.toString.call(p), TypeError);
|
||||||
assertEq(Object.prototype.toString.call(p2), "[object Function]");
|
assertThrowsInstanceOf(() => Object.prototype.toString.call(p2), TypeError);
|
||||||
|
|
||||||
assertThrowsInstanceOf(() => RegExp.prototype.exec.call(p, ""), TypeError);
|
assertThrowsInstanceOf(() => RegExp.prototype.exec.call(p, ""), TypeError);
|
||||||
assertThrowsInstanceOf(() => RegExp.prototype.exec.call(p2, ""), TypeError);
|
assertThrowsInstanceOf(() => RegExp.prototype.exec.call(p2, ""), TypeError);
|
||||||
|
|
|
@ -4561,6 +4561,7 @@ GetSymbolDescription(HandleSymbol symbol);
|
||||||
macro(match) \
|
macro(match) \
|
||||||
macro(species) \
|
macro(species) \
|
||||||
macro(toPrimitive) \
|
macro(toPrimitive) \
|
||||||
|
macro(toStringTag) \
|
||||||
macro(unscopables)
|
macro(unscopables)
|
||||||
|
|
||||||
enum class SymbolCode : uint32_t {
|
enum class SymbolCode : uint32_t {
|
||||||
|
|
|
@ -1473,7 +1473,9 @@ GlobalObject::initArrayIteratorProto(JSContext* cx, Handle<GlobalObject*> global
|
||||||
|
|
||||||
const Class* cls = &ArrayIteratorPrototypeClass;
|
const Class* cls = &ArrayIteratorPrototypeClass;
|
||||||
RootedObject proto(cx, global->createBlankPrototypeInheriting(cx, cls, iteratorProto));
|
RootedObject proto(cx, global->createBlankPrototypeInheriting(cx, cls, iteratorProto));
|
||||||
if (!proto || !DefinePropertiesAndFunctions(cx, proto, nullptr, array_iterator_methods))
|
if (!proto ||
|
||||||
|
!DefinePropertiesAndFunctions(cx, proto, nullptr, array_iterator_methods) ||
|
||||||
|
!DefineToStringTag(cx, proto, cx->names().ArrayIterator))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
global->setReservedSlot(ARRAY_ITERATOR_PROTO, ObjectValue(*proto));
|
global->setReservedSlot(ARRAY_ITERATOR_PROTO, ObjectValue(*proto));
|
||||||
|
@ -1492,7 +1494,9 @@ GlobalObject::initStringIteratorProto(JSContext* cx, Handle<GlobalObject*> globa
|
||||||
|
|
||||||
const Class* cls = &StringIteratorPrototypeClass;
|
const Class* cls = &StringIteratorPrototypeClass;
|
||||||
RootedObject proto(cx, global->createBlankPrototypeInheriting(cx, cls, iteratorProto));
|
RootedObject proto(cx, global->createBlankPrototypeInheriting(cx, cls, iteratorProto));
|
||||||
if (!proto || !DefinePropertiesAndFunctions(cx, proto, nullptr, string_iterator_methods))
|
if (!proto ||
|
||||||
|
!DefinePropertiesAndFunctions(cx, proto, nullptr, string_iterator_methods) ||
|
||||||
|
!DefineToStringTag(cx, proto, cx->names().StringIterator))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
global->setReservedSlot(STRING_ITERATOR_PROTO, ObjectValue(*proto));
|
global->setReservedSlot(STRING_ITERATOR_PROTO, ObjectValue(*proto));
|
||||||
|
|
|
@ -1647,6 +1647,8 @@ js::InitMathClass(JSContext* cx, HandleObject obj)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
if (!JS_DefineConstDoubles(cx, Math, math_constants))
|
if (!JS_DefineConstDoubles(cx, Math, math_constants))
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
if (!DefineToStringTag(cx, Math, cx->names().Math))
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
obj->as<GlobalObject>().setConstructor(JSProto_Math, ObjectValue(*Math));
|
obj->as<GlobalObject>().setConstructor(JSProto_Math, ObjectValue(*Math));
|
||||||
|
|
||||||
|
|
|
@ -954,6 +954,9 @@ js::InitJSONClass(JSContext* cx, HandleObject obj)
|
||||||
if (!JS_DefineFunctions(cx, JSON, json_static_methods))
|
if (!JS_DefineFunctions(cx, JSON, json_static_methods))
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
|
if (!DefineToStringTag(cx, JSON, cx->names().JSON))
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
global->setConstructor(JSProto_JSON, ObjectValue(*JSON));
|
global->setConstructor(JSProto_JSON, ObjectValue(*JSON));
|
||||||
|
|
||||||
return JSON;
|
return JSON;
|
||||||
|
|
|
@ -1128,12 +1128,9 @@ const char*
|
||||||
ScriptedDirectProxyHandler::className(JSContext* cx, HandleObject proxy) const
|
ScriptedDirectProxyHandler::className(JSContext* cx, HandleObject proxy) const
|
||||||
{
|
{
|
||||||
// Right now the caller is not prepared to handle failures.
|
// Right now the caller is not prepared to handle failures.
|
||||||
RootedObject target(cx, proxy->as<ProxyObject>().target());
|
return BaseProxyHandler::className(cx, proxy);
|
||||||
if (!target)
|
|
||||||
return BaseProxyHandler::className(cx, proxy);
|
|
||||||
|
|
||||||
return GetObjectClassName(cx, target);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
JSString*
|
JSString*
|
||||||
ScriptedDirectProxyHandler::fun_toString(JSContext* cx, HandleObject proxy,
|
ScriptedDirectProxyHandler::fun_toString(JSContext* cx, HandleObject proxy,
|
||||||
unsigned indent) const
|
unsigned indent) const
|
||||||
|
|
|
@ -74,9 +74,7 @@ function TestGeneratorObjectPrototype() {
|
||||||
found_property_names.sort();
|
found_property_names.sort();
|
||||||
|
|
||||||
assertDeepEq(found_property_names, expected_property_names);
|
assertDeepEq(found_property_names, expected_property_names);
|
||||||
|
assertDeepEq(Object.getOwnPropertySymbols(GeneratorObjectPrototype), [Symbol.toStringTag]);
|
||||||
// No symbol properties, at least until we have @@toStringTag.
|
|
||||||
assertEq(Object.getOwnPropertySymbols(GeneratorObjectPrototype).length, 0);
|
|
||||||
}
|
}
|
||||||
TestGeneratorObjectPrototype();
|
TestGeneratorObjectPrototype();
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,158 @@
|
||||||
|
/* Any copyright is dedicated to the Public Domain.
|
||||||
|
* http://creativecommons.org/licenses/publicdomain/ */
|
||||||
|
|
||||||
|
// ES6 19.1.3.6 Object.prototype.toString ( )
|
||||||
|
function testToString() {
|
||||||
|
var tests = [
|
||||||
|
[undefined, "[object Undefined]"],
|
||||||
|
[null, "[object Null]"],
|
||||||
|
[[], "[object Array]"],
|
||||||
|
[new String("abc"), "[object String]"],
|
||||||
|
[(function () {return arguments;})(), "[object Arguments]"],
|
||||||
|
[(function () {"use strict"; return arguments;})(), "[object Arguments]"],
|
||||||
|
[function() {}, "[object Function]"],
|
||||||
|
[new Error("abc"), "[object Error]"],
|
||||||
|
[true, "[object Boolean]"],
|
||||||
|
[5, "[object Number]"],
|
||||||
|
[new Date(), "[object Date]"],
|
||||||
|
[/regexp/, "[object RegExp]"],
|
||||||
|
[{[Symbol.toStringTag]: "abc"}, "[object abc]"],
|
||||||
|
[Object.create(JSON), "[object JSON]"],
|
||||||
|
[Object.create(new Number), "[object Object]"],
|
||||||
|
[Object.create(new Number, {[Symbol.toStringTag]: {value: "abc"}}), "[object abc]"],
|
||||||
|
[(function() { var x = new Number(); x[Symbol.toStringTag] = "abc"; return x; })(), "[object abc]"],
|
||||||
|
[[], "[object Array]"]
|
||||||
|
];
|
||||||
|
|
||||||
|
// Testing if the values are obtained the right way.
|
||||||
|
for (let [value, expected] of tests) {
|
||||||
|
let result = Object.prototype.toString.call(value);
|
||||||
|
assertEq(result, expected);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
testToString();
|
||||||
|
|
||||||
|
function testProxy() {
|
||||||
|
var count = 0;
|
||||||
|
var metaHandler = new Proxy({}, {
|
||||||
|
get(target, property, receiver) {
|
||||||
|
assertEq(property, "get");
|
||||||
|
|
||||||
|
return function(target, property, receiver) {
|
||||||
|
assertEq(property, Symbol.toStringTag);
|
||||||
|
count++;
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
assertEq(Object.prototype.toString.call(new Proxy({}, metaHandler)), "[object Object]")
|
||||||
|
assertEq(Object.prototype.toString.call(new Proxy(new Date, metaHandler)), "[object Object]")
|
||||||
|
assertEq(Object.prototype.toString.call(new Proxy([], metaHandler)), "[object Array]")
|
||||||
|
assertEq(Object.prototype.toString.call(new Proxy(function() {}, metaHandler)), "[object Function]")
|
||||||
|
var {proxy, revoke} = Proxy.revocable({}, metaHandler);
|
||||||
|
revoke();
|
||||||
|
assertThrowsInstanceOf(() => Object.prototype.toString.call(proxy), TypeError);
|
||||||
|
|
||||||
|
assertEq(count, 4);
|
||||||
|
}
|
||||||
|
testProxy();
|
||||||
|
|
||||||
|
// Tests the passed objects toStringTag values and ensures it's
|
||||||
|
// desc is writable: false, enumerable: false, configurable: true
|
||||||
|
function testDefault(object, expected) {
|
||||||
|
let desc = Object.getOwnPropertyDescriptor(object, Symbol.toStringTag);
|
||||||
|
assertEq(desc.value, expected);
|
||||||
|
assertEq(desc.writable, false);
|
||||||
|
assertEq(desc.enumerable, false);
|
||||||
|
assertEq(desc.configurable, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ES6 19.4.3.5 Symbol.prototype [ @@toStringTag ]
|
||||||
|
testDefault(Symbol.prototype, "Symbol");
|
||||||
|
|
||||||
|
// ES6 20.2.1.9 Math [ @@toStringTag ]
|
||||||
|
testDefault(Math, "Math");
|
||||||
|
|
||||||
|
// ES6 21.1.5.2.2 %StringIteratorPrototype% [ @@toStringTag ]
|
||||||
|
testDefault(""[Symbol.iterator]().__proto__, "String Iterator")
|
||||||
|
|
||||||
|
// ES6 22.1.5.2.2 %ArrayIteratorPrototype% [ @@toStringTag ]
|
||||||
|
testDefault([][Symbol.iterator]().__proto__, "Array Iterator")
|
||||||
|
|
||||||
|
// ES6 22.2.3.31 get %TypedArray%.prototype [ @@toStringTag ]
|
||||||
|
function testTypedArray() {
|
||||||
|
let ta = (new Uint8Array(0)).__proto__.__proto__;
|
||||||
|
let desc = Object.getOwnPropertyDescriptor(ta, Symbol.toStringTag);
|
||||||
|
assertEq(desc.enumerable, false);
|
||||||
|
assertEq(desc.configurable, true);
|
||||||
|
assertEq(desc.set, undefined);
|
||||||
|
|
||||||
|
let get = desc.get;
|
||||||
|
assertEq(get.name, "get [Symbol.toStringTag]");
|
||||||
|
assertEq(get.call(3.14), undefined);
|
||||||
|
assertEq(get.call({}), undefined);
|
||||||
|
assertEq(get.call(ta), undefined);
|
||||||
|
|
||||||
|
let types = [
|
||||||
|
Int8Array,
|
||||||
|
Uint8Array,
|
||||||
|
Int16Array,
|
||||||
|
Uint16Array,
|
||||||
|
Int32Array,
|
||||||
|
Uint32Array,
|
||||||
|
Float32Array,
|
||||||
|
Float64Array
|
||||||
|
];
|
||||||
|
|
||||||
|
for (let type of types) {
|
||||||
|
let array = new type(0);
|
||||||
|
assertEq(get.call(array), type.name);
|
||||||
|
assertEq(Object.prototype.toString.call(array), `[object ${type.name}]`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
testTypedArray();
|
||||||
|
|
||||||
|
// ES6 23.1.3.13 Map.prototype [ @@toStringTag ]
|
||||||
|
testDefault(Map.prototype, "Map");
|
||||||
|
|
||||||
|
// ES6 23.1.5.2.2 %MapIteratorPrototype% [ @@toStringTag ]
|
||||||
|
testDefault(new Map()[Symbol.iterator]().__proto__, "Map Iterator")
|
||||||
|
|
||||||
|
// ES6 23.2.3.12 Set.prototype [ @@toStringTag ]
|
||||||
|
testDefault(Set.prototype, "Set");
|
||||||
|
|
||||||
|
// ES6 23.2.5.2.2 %SetIteratorPrototype% [ @@toStringTag ]
|
||||||
|
testDefault(new Set()[Symbol.iterator]().__proto__, "Set Iterator")
|
||||||
|
|
||||||
|
// ES6 23.3.3.6 WeakMap.prototype [ @@toStringTag ]
|
||||||
|
testDefault(WeakMap.prototype, "WeakMap");
|
||||||
|
|
||||||
|
// ES6 23.4.3.5 WeakSet.prototype [ @@toStringTag ]
|
||||||
|
testDefault(WeakSet.prototype, "WeakSet");
|
||||||
|
|
||||||
|
// ES6 24.1.4.4 ArrayBuffer.prototype [ @@toStringTag ]
|
||||||
|
testDefault(ArrayBuffer.prototype, "ArrayBuffer");
|
||||||
|
|
||||||
|
// ES6 24.2.4.21 DataView.prototype[ @@toStringTag ]
|
||||||
|
testDefault(DataView.prototype, "DataView");
|
||||||
|
|
||||||
|
// ES6 24.3.3 JSON [ @@toStringTag ]
|
||||||
|
testDefault(JSON, "JSON");
|
||||||
|
|
||||||
|
// ES6 25.2.3.3 GeneratorFunction.prototype [ @@toStringTag ]
|
||||||
|
testDefault(function* () {}.constructor.prototype, "GeneratorFunction");
|
||||||
|
|
||||||
|
// ES6 25.3.1.5 Generator.prototype [ @@toStringTag ]
|
||||||
|
testDefault(function* () {}().__proto__.__proto__, "Generator");
|
||||||
|
|
||||||
|
// ES6 25.4.5.4 Promise.prototype [ @@toStringTag ]
|
||||||
|
// Not yet implemented!
|
||||||
|
if (typeof Promise !== "undefined")
|
||||||
|
testDefault(Promise.prototype, "Promise");
|
||||||
|
|
||||||
|
// AsyncFunction.prototype [ @@toStringTag ]
|
||||||
|
// Not yet implemented!
|
||||||
|
// testDefault(async function() {}.constructor.prototype, "AsyncFunction");
|
||||||
|
|
||||||
|
reportCompare(true, true);
|
|
@ -82,7 +82,8 @@ if (typeof assertDeepEq === 'undefined') {
|
||||||
assertSameValue(ac, bc, msg);
|
assertSameValue(ac, bc, msg);
|
||||||
switch (ac) {
|
switch (ac) {
|
||||||
case "[object Function]":
|
case "[object Function]":
|
||||||
assertSameValue(Function_toString(a), Function_toString(b), msg);
|
if (typeof isProxy !== "undefined" && !isProxy(a) && !isProxy(b))
|
||||||
|
assertSameValue(Function_toString(a), Function_toString(b), msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1562,7 +1562,7 @@ function test() {
|
||||||
assertEq(Object.prototype.toString.apply(new Float32Array(0)), "[object Float32Array]");
|
assertEq(Object.prototype.toString.apply(new Float32Array(0)), "[object Float32Array]");
|
||||||
assertEq(Object.prototype.toString.apply(new ArrayBuffer()), "[object ArrayBuffer]");
|
assertEq(Object.prototype.toString.apply(new ArrayBuffer()), "[object ArrayBuffer]");
|
||||||
assertEq(Object.prototype.toString.apply(new DataView(view.buffer)), "[object DataView]");
|
assertEq(Object.prototype.toString.apply(new DataView(view.buffer)), "[object DataView]");
|
||||||
assertEq(Object.prototype.toString.apply(DataView.prototype), "[object DataViewPrototype]");
|
assertEq(Object.prototype.toString.apply(DataView.prototype), "[object DataView]");
|
||||||
|
|
||||||
// Technically the spec requires these throw a TypeError -- right now. It's
|
// Technically the spec requires these throw a TypeError -- right now. It's
|
||||||
// not clear this is desirable. Once we implement @@toStringTag we can see
|
// not clear this is desirable. Once we implement @@toStringTag we can see
|
||||||
|
|
|
@ -1650,6 +1650,9 @@ js::InitArrayBufferClass(JSContext* cx, HandleObject obj)
|
||||||
if (!JS_DefineFunctions(cx, arrayBufferProto, ArrayBufferObject::jsfuncs))
|
if (!JS_DefineFunctions(cx, arrayBufferProto, ArrayBufferObject::jsfuncs))
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
|
if (!DefineToStringTag(cx, arrayBufferProto, cx->names().ArrayBuffer))
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
return arrayBufferProto;
|
return arrayBufferProto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
macro(apply, apply, "apply") \
|
macro(apply, apply, "apply") \
|
||||||
macro(arguments, arguments, "arguments") \
|
macro(arguments, arguments, "arguments") \
|
||||||
macro(as, as, "as") \
|
macro(as, as, "as") \
|
||||||
|
macro(ArrayIterator, ArrayIterator, "Array Iterator") \
|
||||||
macro(ArrayIteratorNext, ArrayIteratorNext, "ArrayIteratorNext") \
|
macro(ArrayIteratorNext, ArrayIteratorNext, "ArrayIteratorNext") \
|
||||||
macro(ArrayType, ArrayType, "ArrayType") \
|
macro(ArrayType, ArrayType, "ArrayType") \
|
||||||
macro(ArrayValues, ArrayValues, "ArrayValues") \
|
macro(ArrayValues, ArrayValues, "ArrayValues") \
|
||||||
|
@ -99,6 +100,7 @@
|
||||||
macro(frame, frame, "frame") \
|
macro(frame, frame, "frame") \
|
||||||
macro(from, from, "from") \
|
macro(from, from, "from") \
|
||||||
macro(gcCycleNumber, gcCycleNumber, "gcCycleNumber") \
|
macro(gcCycleNumber, gcCycleNumber, "gcCycleNumber") \
|
||||||
|
macro(Generator, Generator, "Generator") \
|
||||||
macro(GeneratorFunction, GeneratorFunction, "GeneratorFunction") \
|
macro(GeneratorFunction, GeneratorFunction, "GeneratorFunction") \
|
||||||
macro(get, get, "get") \
|
macro(get, get, "get") \
|
||||||
macro(getInternals, getInternals, "getInternals") \
|
macro(getInternals, getInternals, "getInternals") \
|
||||||
|
@ -139,6 +141,7 @@
|
||||||
macro(keys, keys, "keys") \
|
macro(keys, keys, "keys") \
|
||||||
macro(label, label, "label") \
|
macro(label, label, "label") \
|
||||||
macro(lastIndex, lastIndex, "lastIndex") \
|
macro(lastIndex, lastIndex, "lastIndex") \
|
||||||
|
macro(LegacyGenerator, LegacyGenerator, "LegacyGenerator") \
|
||||||
macro(LegacyGeneratorCloseInternal, LegacyGeneratorCloseInternal, "LegacyGeneratorCloseInternal") \
|
macro(LegacyGeneratorCloseInternal, LegacyGeneratorCloseInternal, "LegacyGeneratorCloseInternal") \
|
||||||
macro(length, length, "length") \
|
macro(length, length, "length") \
|
||||||
macro(let, let, "let") \
|
macro(let, let, "let") \
|
||||||
|
@ -148,6 +151,7 @@
|
||||||
macro(locale, locale, "locale") \
|
macro(locale, locale, "locale") \
|
||||||
macro(lookupGetter, lookupGetter, "__lookupGetter__") \
|
macro(lookupGetter, lookupGetter, "__lookupGetter__") \
|
||||||
macro(lookupSetter, lookupSetter, "__lookupSetter__") \
|
macro(lookupSetter, lookupSetter, "__lookupSetter__") \
|
||||||
|
macro(MapIterator, MapIterator, "Map Iterator") \
|
||||||
macro(maximumFractionDigits, maximumFractionDigits, "maximumFractionDigits") \
|
macro(maximumFractionDigits, maximumFractionDigits, "maximumFractionDigits") \
|
||||||
macro(maximumSignificantDigits, maximumSignificantDigits, "maximumSignificantDigits") \
|
macro(maximumSignificantDigits, maximumSignificantDigits, "maximumSignificantDigits") \
|
||||||
macro(message, message, "message") \
|
macro(message, message, "message") \
|
||||||
|
@ -171,15 +175,18 @@
|
||||||
macro(NumberFormat, NumberFormat, "NumberFormat") \
|
macro(NumberFormat, NumberFormat, "NumberFormat") \
|
||||||
macro(NumberFormatFormatGet, NumberFormatFormatGet, "Intl_NumberFormat_format_get") \
|
macro(NumberFormatFormatGet, NumberFormatFormatGet, "Intl_NumberFormat_format_get") \
|
||||||
macro(numeric, numeric, "numeric") \
|
macro(numeric, numeric, "numeric") \
|
||||||
macro(objectArray, objectArray, "[object Array]") \
|
|
||||||
macro(objectFunction, objectFunction, "[object Function]") \
|
|
||||||
macro(objectNull, objectNull, "[object Null]") \
|
|
||||||
macro(objectNumber, objectNumber, "[object Number]") \
|
|
||||||
macro(objectObject, objectObject, "[object Object]") \
|
|
||||||
macro(objects, objects, "objects") \
|
|
||||||
macro(objectString, objectString, "[object String]") \
|
|
||||||
macro(objectUndefined, objectUndefined, "[object Undefined]") \
|
macro(objectUndefined, objectUndefined, "[object Undefined]") \
|
||||||
macro(objectWindow, objectWindow, "[object Window]") \
|
macro(objectNull, objectNull, "[object Null]") \
|
||||||
|
macro(objectArray, objectArray, "[object Array]") \
|
||||||
|
macro(objectString, objectString, "[object String]") \
|
||||||
|
macro(objectArguments, objectArguments, "[object Arguments]") \
|
||||||
|
macro(objectFunction, objectFunction, "[object Function]") \
|
||||||
|
macro(objectError, objectError, "[object Error]") \
|
||||||
|
macro(objectBoolean, objectBoolean, "[object Boolean]") \
|
||||||
|
macro(objectNumber, objectNumber, "[object Number]") \
|
||||||
|
macro(objectDate, objectDate, "[object Date]") \
|
||||||
|
macro(objectRegExp, objectRegExp, "[object RegExp]") \
|
||||||
|
macro(objects, objects, "objects") \
|
||||||
macro(of, of, "of") \
|
macro(of, of, "of") \
|
||||||
macro(offset, offset, "offset") \
|
macro(offset, offset, "offset") \
|
||||||
macro(optimizedOut, optimizedOut, "optimizedOut") \
|
macro(optimizedOut, optimizedOut, "optimizedOut") \
|
||||||
|
@ -204,6 +211,7 @@
|
||||||
macro(scripts, scripts, "scripts") \
|
macro(scripts, scripts, "scripts") \
|
||||||
macro(sensitivity, sensitivity, "sensitivity") \
|
macro(sensitivity, sensitivity, "sensitivity") \
|
||||||
macro(set, set, "set") \
|
macro(set, set, "set") \
|
||||||
|
macro(SetIterator, SetIterator, "Set Iterator") \
|
||||||
macro(shape, shape, "shape") \
|
macro(shape, shape, "shape") \
|
||||||
macro(signMask, signMask, "signMask") \
|
macro(signMask, signMask, "signMask") \
|
||||||
macro(size, size, "size") \
|
macro(size, size, "size") \
|
||||||
|
@ -215,6 +223,7 @@
|
||||||
macro(static, static_, "static") \
|
macro(static, static_, "static") \
|
||||||
macro(sticky, sticky, "sticky") \
|
macro(sticky, sticky, "sticky") \
|
||||||
macro(strings, strings, "strings") \
|
macro(strings, strings, "strings") \
|
||||||
|
macro(StringIterator, StringIterator, "String Iterator") \
|
||||||
macro(StructType, StructType, "StructType") \
|
macro(StructType, StructType, "StructType") \
|
||||||
macro(style, style, "style") \
|
macro(style, style, "style") \
|
||||||
macro(super, super, "super") \
|
macro(super, super, "super") \
|
||||||
|
@ -277,6 +286,7 @@
|
||||||
macro(match, match, "match") \
|
macro(match, match, "match") \
|
||||||
macro(species, species, "species") \
|
macro(species, species, "species") \
|
||||||
macro(toPrimitive, toPrimitive, "toPrimitive") \
|
macro(toPrimitive, toPrimitive, "toPrimitive") \
|
||||||
|
macro(toStringTag, toStringTag, "toStringTag") \
|
||||||
macro(unscopables, unscopables, "unscopables") \
|
macro(unscopables, unscopables, "unscopables") \
|
||||||
/* Same goes for the descriptions of the well-known symbols. */ \
|
/* Same goes for the descriptions of the well-known symbols. */ \
|
||||||
macro(Symbol_hasInstance, Symbol_hasInstance, "Symbol.hasInstance") \
|
macro(Symbol_hasInstance, Symbol_hasInstance, "Symbol.hasInstance") \
|
||||||
|
@ -285,6 +295,7 @@
|
||||||
macro(Symbol_match, Symbol_match, "Symbol.match") \
|
macro(Symbol_match, Symbol_match, "Symbol.match") \
|
||||||
macro(Symbol_species, Symbol_species, "Symbol.species") \
|
macro(Symbol_species, Symbol_species, "Symbol.species") \
|
||||||
macro(Symbol_toPrimitive, Symbol_toPrimitive, "Symbol.toPrimitive") \
|
macro(Symbol_toPrimitive, Symbol_toPrimitive, "Symbol.toPrimitive") \
|
||||||
|
macro(Symbol_toStringTag, Symbol_toStringTag, "Symbol.toStringTag") \
|
||||||
macro(Symbol_unscopables, Symbol_unscopables, "Symbol.unscopables") \
|
macro(Symbol_unscopables, Symbol_unscopables, "Symbol.unscopables") \
|
||||||
/* Function names for properties named by symbols. */ \
|
/* Function names for properties named by symbols. */ \
|
||||||
macro(Symbol_iterator_fun, Symbol_iterator_fun, "[Symbol.iterator]") \
|
macro(Symbol_iterator_fun, Symbol_iterator_fun, "[Symbol.iterator]") \
|
||||||
|
|
|
@ -282,7 +282,14 @@ GlobalObject::initLegacyGeneratorProto(JSContext* cx, Handle<GlobalObject*> glob
|
||||||
RootedObject proto(cx, NewSingletonObjectWithObjectPrototype(cx, global));
|
RootedObject proto(cx, NewSingletonObjectWithObjectPrototype(cx, global));
|
||||||
if (!proto || !proto->setDelegate(cx))
|
if (!proto || !proto->setDelegate(cx))
|
||||||
return false;
|
return false;
|
||||||
|
#if(0)
|
||||||
|
/* XXX: Stub @@toStringTag for legacy generators.
|
||||||
|
TenFourFox issue 392 */
|
||||||
|
if (!DefinePropertiesAndFunctions(cx, proto, nullptr, legacy_generator_methods) ||
|
||||||
|
!DefineToStringTag(cx, proto, cx->names().LegacyGenerator))
|
||||||
|
#else
|
||||||
if (!DefinePropertiesAndFunctions(cx, proto, nullptr, legacy_generator_methods))
|
if (!DefinePropertiesAndFunctions(cx, proto, nullptr, legacy_generator_methods))
|
||||||
|
#endif
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
global->setReservedSlot(LEGACY_GENERATOR_OBJECT_PROTO, ObjectValue(*proto));
|
global->setReservedSlot(LEGACY_GENERATOR_OBJECT_PROTO, ObjectValue(*proto));
|
||||||
|
@ -304,13 +311,15 @@ GlobalObject::initStarGenerators(JSContext* cx, Handle<GlobalObject*> global)
|
||||||
iteratorProto));
|
iteratorProto));
|
||||||
if (!genObjectProto)
|
if (!genObjectProto)
|
||||||
return false;
|
return false;
|
||||||
if (!DefinePropertiesAndFunctions(cx, genObjectProto, nullptr, star_generator_methods))
|
if (!DefinePropertiesAndFunctions(cx, genObjectProto, nullptr, star_generator_methods) ||
|
||||||
|
!DefineToStringTag(cx, genObjectProto, cx->names().Generator))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
RootedObject genFunctionProto(cx, NewSingletonObjectWithFunctionPrototype(cx, global));
|
RootedObject genFunctionProto(cx, NewSingletonObjectWithFunctionPrototype(cx, global));
|
||||||
if (!genFunctionProto || !genFunctionProto->setDelegate(cx))
|
if (!genFunctionProto || !genFunctionProto->setDelegate(cx))
|
||||||
return false;
|
return false;
|
||||||
if (!LinkConstructorAndPrototype(cx, genFunctionProto, genObjectProto))
|
if (!LinkConstructorAndPrototype(cx, genFunctionProto, genObjectProto) ||
|
||||||
|
!DefineToStringTag(cx, genFunctionProto, cx->names().GeneratorFunction))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
RootedValue function(cx, global->getConstructor(JSProto_Function));
|
RootedValue function(cx, global->getConstructor(JSProto_Function));
|
||||||
|
|
|
@ -529,6 +529,14 @@ js::DefinePropertiesAndFunctions(JSContext* cx, HandleObject obj,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
js::DefineToStringTag(JSContext *cx, HandleObject obj, JSAtom* tag)
|
||||||
|
{
|
||||||
|
RootedId toStringTagId(cx, SYMBOL_TO_JSID(cx->wellKnownSymbols().toStringTag));
|
||||||
|
RootedValue tagString(cx, StringValue(tag));
|
||||||
|
return DefineProperty(cx, obj, toStringTagId, tagString, nullptr, nullptr, JSPROP_READONLY);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
GlobalDebuggees_finalize(FreeOp* fop, JSObject* obj)
|
GlobalDebuggees_finalize(FreeOp* fop, JSObject* obj)
|
||||||
{
|
{
|
||||||
|
|
|
@ -905,6 +905,9 @@ DefinePropertiesAndFunctions(JSContext* cx, HandleObject obj,
|
||||||
|
|
||||||
typedef HashSet<GlobalObject*, DefaultHasher<GlobalObject*>, SystemAllocPolicy> GlobalObjectSet;
|
typedef HashSet<GlobalObject*, DefaultHasher<GlobalObject*>, SystemAllocPolicy> GlobalObjectSet;
|
||||||
|
|
||||||
|
extern bool
|
||||||
|
DefineToStringTag(JSContext *cx, HandleObject obj, JSAtom* tag);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Convenience templates to generic constructor and prototype creation functions
|
* Convenience templates to generic constructor and prototype creation functions
|
||||||
* for ClassSpecs.
|
* for ClassSpecs.
|
||||||
|
|
|
@ -40,6 +40,7 @@
|
||||||
#include "vm/String.h"
|
#include "vm/String.h"
|
||||||
#include "vm/TypedArrayCommon.h"
|
#include "vm/TypedArrayCommon.h"
|
||||||
|
|
||||||
|
#include "jsatominlines.h"
|
||||||
#include "jsfuninlines.h"
|
#include "jsfuninlines.h"
|
||||||
#include "jsscriptinlines.h"
|
#include "jsscriptinlines.h"
|
||||||
|
|
||||||
|
@ -1281,6 +1282,23 @@ intrinsic_ConstructorForTypedArray(JSContext* cx, unsigned argc, Value* vp)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
intrinsic_NameForTypedArray(JSContext* cx, unsigned argc, Value* vp)
|
||||||
|
{
|
||||||
|
CallArgs args = CallArgsFromVp(argc, vp);
|
||||||
|
MOZ_ASSERT(args.length() == 1);
|
||||||
|
MOZ_ASSERT(args[0].isObject());
|
||||||
|
|
||||||
|
RootedObject object(cx, &args[0].toObject());
|
||||||
|
MOZ_ASSERT(object->is<TypedArrayObject>());
|
||||||
|
|
||||||
|
JSProtoKey protoKey = StandardProtoKeyOrNull(object);
|
||||||
|
MOZ_ASSERT(protoKey);
|
||||||
|
|
||||||
|
args.rval().setString(ClassName(protoKey, cx));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
intrinsic_HostResolveImportedModule(JSContext* cx, unsigned argc, Value* vp)
|
intrinsic_HostResolveImportedModule(JSContext* cx, unsigned argc, Value* vp)
|
||||||
{
|
{
|
||||||
|
@ -1531,6 +1549,7 @@ static const JSFunctionSpec intrinsic_functions[] = {
|
||||||
JS_FN("AssertionFailed", intrinsic_AssertionFailed, 1,0),
|
JS_FN("AssertionFailed", intrinsic_AssertionFailed, 1,0),
|
||||||
JS_FN("MakeConstructible", intrinsic_MakeConstructible, 2,0),
|
JS_FN("MakeConstructible", intrinsic_MakeConstructible, 2,0),
|
||||||
JS_FN("_ConstructorForTypedArray", intrinsic_ConstructorForTypedArray, 1,0),
|
JS_FN("_ConstructorForTypedArray", intrinsic_ConstructorForTypedArray, 1,0),
|
||||||
|
JS_FN("_NameForTypedArray", intrinsic_NameForTypedArray, 1,0),
|
||||||
JS_FN("DecompileArg", intrinsic_DecompileArg, 2,0),
|
JS_FN("DecompileArg", intrinsic_DecompileArg, 2,0),
|
||||||
JS_FN("RuntimeDefaultLocale", intrinsic_RuntimeDefaultLocale, 0,0),
|
JS_FN("RuntimeDefaultLocale", intrinsic_RuntimeDefaultLocale, 0,0),
|
||||||
JS_FN("LocalTZA", intrinsic_LocalTZA, 0,0),
|
JS_FN("LocalTZA", intrinsic_LocalTZA, 0,0),
|
||||||
|
|
|
@ -832,6 +832,7 @@ TypedArrayObject::protoAccessors[] = {
|
||||||
JS_PSG("buffer", TypedArray_bufferGetter, 0),
|
JS_PSG("buffer", TypedArray_bufferGetter, 0),
|
||||||
JS_PSG("byteLength", TypedArray_byteLengthGetter, 0),
|
JS_PSG("byteLength", TypedArray_byteLengthGetter, 0),
|
||||||
JS_PSG("byteOffset", TypedArray_byteOffsetGetter, 0),
|
JS_PSG("byteOffset", TypedArray_byteOffsetGetter, 0),
|
||||||
|
JS_SELF_HOSTED_SYM_GET(toStringTag, "TypedArrayToStringTag", 0),
|
||||||
JS_PS_END
|
JS_PS_END
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2148,6 +2149,9 @@ DataViewObject::initClass(JSContext* cx)
|
||||||
if (!JS_DefineFunctions(cx, proto, DataViewObject::jsfuncs))
|
if (!JS_DefineFunctions(cx, proto, DataViewObject::jsfuncs))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if (!DefineToStringTag(cx, proto, cx->names().DataView))
|
||||||
|
return false;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Create a helper function to implement the craziness of
|
* Create a helper function to implement the craziness of
|
||||||
* |new DataView(new otherWindow.ArrayBuffer())|, and install it in the
|
* |new DataView(new otherWindow.ArrayBuffer())|, and install it in the
|
||||||
|
|
|
@ -2220,6 +2220,13 @@ XrayWrapper<Base, Traits>::construct(JSContext* cx, HandleObject wrapper, const
|
||||||
return Traits::construct(cx, wrapper, args, Base::singleton);
|
return Traits::construct(cx, wrapper, args, Base::singleton);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename Base, typename Traits>
|
||||||
|
bool
|
||||||
|
XrayWrapper<Base, Traits>::getBuiltinClass(JSContext* cx, JS::HandleObject wrapper, js::ESClassValue* cls) const
|
||||||
|
{
|
||||||
|
return Traits::getBuiltinClass(cx, wrapper, Base::singleton, cls);
|
||||||
|
}
|
||||||
|
|
||||||
template <typename Base, typename Traits>
|
template <typename Base, typename Traits>
|
||||||
const char*
|
const char*
|
||||||
XrayWrapper<Base, Traits>::className(JSContext* cx, HandleObject wrapper) const
|
XrayWrapper<Base, Traits>::className(JSContext* cx, HandleObject wrapper) const
|
||||||
|
|
|
@ -83,6 +83,11 @@ public:
|
||||||
return result.succeed();
|
return result.succeed();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool getBuiltinClass(JSContext* cx, JS::HandleObject wrapper, const js::Wrapper& baseInstance,
|
||||||
|
js::ESClassValue* cls) {
|
||||||
|
return baseInstance.getBuiltinClass(cx, wrapper, cls);
|
||||||
|
}
|
||||||
|
|
||||||
static const char* className(JSContext* cx, JS::HandleObject wrapper, const js::Wrapper& baseInstance) {
|
static const char* className(JSContext* cx, JS::HandleObject wrapper, const js::Wrapper& baseInstance) {
|
||||||
return baseInstance.className(cx, wrapper);
|
return baseInstance.className(cx, wrapper);
|
||||||
}
|
}
|
||||||
|
@ -407,6 +412,12 @@ public:
|
||||||
return JS_WrapObject(cx, protop);
|
return JS_WrapObject(cx, protop);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool getBuiltinClass(JSContext* cx, JS::HandleObject wrapper, const js::Wrapper& baseInstance,
|
||||||
|
js::ESClassValue* cls) {
|
||||||
|
*cls = js::ESClass_Other;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static const char* className(JSContext* cx, JS::HandleObject wrapper, const js::Wrapper& baseInstance) {
|
static const char* className(JSContext* cx, JS::HandleObject wrapper, const js::Wrapper& baseInstance) {
|
||||||
return "Opaque";
|
return "Opaque";
|
||||||
}
|
}
|
||||||
|
@ -473,6 +484,7 @@ class XrayWrapper : public Base {
|
||||||
virtual bool getOwnEnumerablePropertyKeys(JSContext* cx, JS::Handle<JSObject*> wrapper,
|
virtual bool getOwnEnumerablePropertyKeys(JSContext* cx, JS::Handle<JSObject*> wrapper,
|
||||||
JS::AutoIdVector& props) const override;
|
JS::AutoIdVector& props) const override;
|
||||||
|
|
||||||
|
virtual bool getBuiltinClass(JSContext* cx, JS::HandleObject wapper, js::ESClassValue* cls) const override;
|
||||||
virtual const char* className(JSContext* cx, JS::HandleObject proxy) const override;
|
virtual const char* className(JSContext* cx, JS::HandleObject proxy) const override;
|
||||||
|
|
||||||
static const XrayWrapper singleton;
|
static const XrayWrapper singleton;
|
||||||
|
|
|
@ -35,14 +35,6 @@ function do_check_throws(f, type, stack)
|
||||||
do_throw("expected " + type.name + " exception, none thrown", stack);
|
do_throw("expected " + type.name + " exception, none thrown", stack);
|
||||||
}
|
}
|
||||||
|
|
||||||
function do_check_class(obj, classname, stack)
|
|
||||||
{
|
|
||||||
if (!stack)
|
|
||||||
stack = Components.stack.caller;
|
|
||||||
|
|
||||||
do_check_eq(Object.prototype.toString.call(obj), "[object " + classname + "]", stack);
|
|
||||||
}
|
|
||||||
|
|
||||||
function run_test()
|
function run_test()
|
||||||
{
|
{
|
||||||
// Test ctypes.CType and ctypes.CData are set up correctly.
|
// Test ctypes.CType and ctypes.CData are set up correctly.
|
||||||
|
@ -231,10 +223,6 @@ function run_abstract_class_tests()
|
||||||
do_check_throws(function() { ctypes.CType(); }, Error);
|
do_check_throws(function() { ctypes.CType(); }, Error);
|
||||||
do_check_throws(function() { new ctypes.CType() }, Error);
|
do_check_throws(function() { new ctypes.CType() }, Error);
|
||||||
|
|
||||||
// Test that classes and prototypes are set up correctly.
|
|
||||||
do_check_class(ctypes.CType, "Function");
|
|
||||||
do_check_class(ctypes.CType.prototype, "CType");
|
|
||||||
|
|
||||||
do_check_true(ctypes.CType.hasOwnProperty("prototype"));
|
do_check_true(ctypes.CType.hasOwnProperty("prototype"));
|
||||||
do_check_throws(function() { ctypes.CType.prototype(); }, Error);
|
do_check_throws(function() { ctypes.CType.prototype(); }, Error);
|
||||||
do_check_throws(function() { new ctypes.CType.prototype() }, Error);
|
do_check_throws(function() { new ctypes.CType.prototype() }, Error);
|
||||||
|
@ -269,10 +257,6 @@ function run_abstract_class_tests()
|
||||||
do_check_throws(function() { ctypes.CData(); }, Error);
|
do_check_throws(function() { ctypes.CData(); }, Error);
|
||||||
do_check_throws(function() { new ctypes.CData() }, Error);
|
do_check_throws(function() { new ctypes.CData() }, Error);
|
||||||
|
|
||||||
// Test that classes and prototypes are set up correctly.
|
|
||||||
do_check_class(ctypes.CData, "Function");
|
|
||||||
do_check_class(ctypes.CData.prototype, "CData");
|
|
||||||
|
|
||||||
do_check_true(ctypes.CData.__proto__ === ctypes.CType.prototype);
|
do_check_true(ctypes.CData.__proto__ === ctypes.CType.prototype);
|
||||||
do_check_true(ctypes.CData instanceof ctypes.CType);
|
do_check_true(ctypes.CData instanceof ctypes.CType);
|
||||||
|
|
||||||
|
@ -302,10 +286,6 @@ function run_abstract_class_tests()
|
||||||
function run_Int64_tests() {
|
function run_Int64_tests() {
|
||||||
do_check_throws(function() { ctypes.Int64(); }, TypeError);
|
do_check_throws(function() { ctypes.Int64(); }, TypeError);
|
||||||
|
|
||||||
// Test that classes and prototypes are set up correctly.
|
|
||||||
do_check_class(ctypes.Int64, "Function");
|
|
||||||
do_check_class(ctypes.Int64.prototype, "Int64");
|
|
||||||
|
|
||||||
do_check_true(ctypes.Int64.hasOwnProperty("prototype"));
|
do_check_true(ctypes.Int64.hasOwnProperty("prototype"));
|
||||||
do_check_true(ctypes.Int64.prototype.hasOwnProperty("constructor"));
|
do_check_true(ctypes.Int64.prototype.hasOwnProperty("constructor"));
|
||||||
do_check_true(ctypes.Int64.prototype.constructor === ctypes.Int64);
|
do_check_true(ctypes.Int64.prototype.constructor === ctypes.Int64);
|
||||||
|
@ -473,10 +453,6 @@ function run_Int64_tests() {
|
||||||
function run_UInt64_tests() {
|
function run_UInt64_tests() {
|
||||||
do_check_throws(function() { ctypes.UInt64(); }, TypeError);
|
do_check_throws(function() { ctypes.UInt64(); }, TypeError);
|
||||||
|
|
||||||
// Test that classes and prototypes are set up correctly.
|
|
||||||
do_check_class(ctypes.UInt64, "Function");
|
|
||||||
do_check_class(ctypes.UInt64.prototype, "UInt64");
|
|
||||||
|
|
||||||
do_check_true(ctypes.UInt64.hasOwnProperty("prototype"));
|
do_check_true(ctypes.UInt64.hasOwnProperty("prototype"));
|
||||||
do_check_true(ctypes.UInt64.prototype.hasOwnProperty("constructor"));
|
do_check_true(ctypes.UInt64.prototype.hasOwnProperty("constructor"));
|
||||||
do_check_true(ctypes.UInt64.prototype.constructor === ctypes.UInt64);
|
do_check_true(ctypes.UInt64.prototype.constructor === ctypes.UInt64);
|
||||||
|
@ -738,10 +714,6 @@ function offsetof(struct, member) {
|
||||||
// Test the class and prototype hierarchy for a given basic type 't'.
|
// Test the class and prototype hierarchy for a given basic type 't'.
|
||||||
function run_basic_class_tests(t)
|
function run_basic_class_tests(t)
|
||||||
{
|
{
|
||||||
// Test that classes and prototypes are set up correctly.
|
|
||||||
do_check_class(t, "CType");
|
|
||||||
do_check_class(t.prototype, "CData");
|
|
||||||
|
|
||||||
do_check_true(t.__proto__ === ctypes.CType.prototype);
|
do_check_true(t.__proto__ === ctypes.CType.prototype);
|
||||||
do_check_true(t instanceof ctypes.CType);
|
do_check_true(t instanceof ctypes.CType);
|
||||||
|
|
||||||
|
@ -762,7 +734,6 @@ function run_basic_class_tests(t)
|
||||||
|
|
||||||
// Test that an instance 'd' of 't' is a CData.
|
// Test that an instance 'd' of 't' is a CData.
|
||||||
let d = t();
|
let d = t();
|
||||||
do_check_class(d, "CData");
|
|
||||||
do_check_true(d.__proto__ === t.prototype);
|
do_check_true(d.__proto__ === t.prototype);
|
||||||
do_check_true(d instanceof t);
|
do_check_true(d instanceof t);
|
||||||
do_check_true(d.constructor === t);
|
do_check_true(d.constructor === t);
|
||||||
|
@ -1283,10 +1254,6 @@ function run_char16_tests(library, t, name, limits) {
|
||||||
// Test the class and prototype hierarchy for a given type constructor 'c'.
|
// Test the class and prototype hierarchy for a given type constructor 'c'.
|
||||||
function run_type_ctor_class_tests(c, t, t2, props=[], fns=[], instanceProps=[], instanceFns=[], specialProps=[])
|
function run_type_ctor_class_tests(c, t, t2, props=[], fns=[], instanceProps=[], instanceFns=[], specialProps=[])
|
||||||
{
|
{
|
||||||
// Test that classes and prototypes are set up correctly on the type ctor 'c'.
|
|
||||||
do_check_class(c, "Function");
|
|
||||||
do_check_class(c.prototype, "CType");
|
|
||||||
|
|
||||||
do_check_true(c.prototype.__proto__ === ctypes.CType.prototype);
|
do_check_true(c.prototype.__proto__ === ctypes.CType.prototype);
|
||||||
do_check_true(c.prototype instanceof ctypes.CType);
|
do_check_true(c.prototype instanceof ctypes.CType);
|
||||||
do_check_true(c.prototype.constructor === c);
|
do_check_true(c.prototype.constructor === c);
|
||||||
|
@ -1303,15 +1270,9 @@ function run_type_ctor_class_tests(c, t, t2, props=[], fns=[], instanceProps=[],
|
||||||
for (let f of fns)
|
for (let f of fns)
|
||||||
do_check_throws(function() { c.prototype[f](); }, Error);
|
do_check_throws(function() { c.prototype[f](); }, Error);
|
||||||
|
|
||||||
// Test that classes and prototypes are set up correctly on a constructed
|
|
||||||
// type 't'.
|
|
||||||
do_check_class(t, "CType");
|
|
||||||
do_check_class(t.prototype, "CData");
|
|
||||||
|
|
||||||
do_check_true(t.__proto__ === c.prototype);
|
do_check_true(t.__proto__ === c.prototype);
|
||||||
do_check_true(t instanceof c);
|
do_check_true(t instanceof c);
|
||||||
|
|
||||||
do_check_class(t.prototype.__proto__, "CData");
|
|
||||||
// 't.prototype.__proto__' is the common ancestor of all types constructed
|
// 't.prototype.__proto__' is the common ancestor of all types constructed
|
||||||
// from 'c'; while not available from 'c' directly, it should be identically
|
// from 'c'; while not available from 'c' directly, it should be identically
|
||||||
// equal to 't2.prototype.__proto__' where 't2' is a different CType
|
// equal to 't2.prototype.__proto__' where 't2' is a different CType
|
||||||
|
@ -1359,7 +1320,6 @@ function run_type_ctor_class_tests(c, t, t2, props=[], fns=[], instanceProps=[],
|
||||||
// Test that an instance 'd' of 't' is a CData.
|
// Test that an instance 'd' of 't' is a CData.
|
||||||
if (t.__proto__ != ctypes.FunctionType.prototype) {
|
if (t.__proto__ != ctypes.FunctionType.prototype) {
|
||||||
let d = t();
|
let d = t();
|
||||||
do_check_class(d, "CData");
|
|
||||||
do_check_true(d.__proto__ === t.prototype);
|
do_check_true(d.__proto__ === t.prototype);
|
||||||
do_check_true(d instanceof t);
|
do_check_true(d instanceof t);
|
||||||
do_check_true(d.constructor === t);
|
do_check_true(d.constructor === t);
|
||||||
|
|
Loading…
Reference in New Issue