mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-03-01 13:57:32 +00:00
Bug 645416, part 5 - Add the Symbol constructor and Symbol wrapper objects. r=efaust.
This exposes a new primitive type to scripts for the first time since JavaScript first shipped in Netscape 2, over 13 years ago. The tests focus on identity, equality, and being able to pass a symbol around as a value. Of course the point of symbols is that they can be property keys, but that will have to wait for a later patch in this series. --HG-- extra : rebase_source : c22cf4b774cca8e7c9f6c757079e054a6eb0f307
This commit is contained in:
parent
c755dc4354
commit
db7aa8370b
@ -78,6 +78,7 @@ var ecmaGlobals =
|
||||
{name: "SIMD", nightly: true},
|
||||
"StopIteration",
|
||||
"String",
|
||||
"Symbol",
|
||||
"SyntaxError",
|
||||
{name: "TypedObject", nightly: true},
|
||||
"TypeError",
|
||||
|
109
js/src/builtin/SymbolObject.cpp
Normal file
109
js/src/builtin/SymbolObject.cpp
Normal file
@ -0,0 +1,109 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* vim: set ts=8 sts=4 et sw=4 tw=99:
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "builtin/SymbolObject.h"
|
||||
|
||||
#include "jsobjinlines.h"
|
||||
|
||||
#include "vm/Symbol-inl.h"
|
||||
|
||||
using namespace js;
|
||||
|
||||
const Class SymbolObject::class_ = {
|
||||
"Symbol",
|
||||
JSCLASS_HAS_RESERVED_SLOTS(RESERVED_SLOTS) | JSCLASS_HAS_CACHED_PROTO(JSProto_Symbol),
|
||||
JS_PropertyStub, /* addProperty */
|
||||
JS_DeletePropertyStub, /* delProperty */
|
||||
JS_PropertyStub, /* getProperty */
|
||||
JS_StrictPropertyStub, /* setProperty */
|
||||
JS_EnumerateStub,
|
||||
JS_ResolveStub,
|
||||
JS_ConvertStub
|
||||
};
|
||||
|
||||
SymbolObject *
|
||||
SymbolObject::create(JSContext *cx, JS::Symbol *symbol)
|
||||
{
|
||||
JSObject *obj = NewBuiltinClassInstance(cx, &class_);
|
||||
if (!obj)
|
||||
return nullptr;
|
||||
SymbolObject &symobj = obj->as<SymbolObject>();
|
||||
symobj.setPrimitiveValue(symbol);
|
||||
return &symobj;
|
||||
}
|
||||
|
||||
const JSPropertySpec SymbolObject::properties[] = {
|
||||
JS_PS_END
|
||||
};
|
||||
|
||||
const JSFunctionSpec SymbolObject::methods[] = {
|
||||
JS_FS_END
|
||||
};
|
||||
|
||||
const JSFunctionSpec SymbolObject::staticMethods[] = {
|
||||
JS_FS_END
|
||||
};
|
||||
|
||||
JSObject *
|
||||
SymbolObject::initClass(JSContext *cx, HandleObject obj)
|
||||
{
|
||||
Rooted<GlobalObject*> global(cx, &obj->as<GlobalObject>());
|
||||
|
||||
// This uses &JSObject::class_ because: "The Symbol prototype object is an
|
||||
// ordinary object. It is not a Symbol instance and does not have a
|
||||
// [[SymbolData]] internal slot." (ES6 rev 24, 19.4.3)
|
||||
RootedObject proto(cx, global->createBlankPrototype(cx, &JSObject::class_));
|
||||
if (!proto)
|
||||
return nullptr;
|
||||
|
||||
RootedFunction ctor(cx, global->createConstructor(cx, construct,
|
||||
ClassName(JSProto_Symbol, cx), 1));
|
||||
if (!ctor ||
|
||||
!LinkConstructorAndPrototype(cx, ctor, proto) ||
|
||||
!DefinePropertiesAndFunctions(cx, proto, properties, methods) ||
|
||||
!DefinePropertiesAndFunctions(cx, ctor, nullptr, staticMethods) ||
|
||||
!GlobalObject::initBuiltinConstructor(cx, global, JSProto_Symbol, ctor, proto))
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
return proto;
|
||||
}
|
||||
|
||||
// ES6 rev 24 (2014 Apr 27) 19.4.1.1 and 19.4.1.2
|
||||
bool
|
||||
SymbolObject::construct(JSContext *cx, unsigned argc, Value *vp)
|
||||
{
|
||||
// According to a note in the draft standard, "Symbol has ordinary
|
||||
// [[Construct]] behaviour but the definition of its @@create method causes
|
||||
// `new Symbol` to throw a TypeError exception." We do not support @@create
|
||||
// yet, so just throw a TypeError.
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
if (args.isConstructing()) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_NOT_CONSTRUCTOR, "Symbol");
|
||||
return false;
|
||||
}
|
||||
|
||||
// steps 1-3
|
||||
RootedString desc(cx);
|
||||
if (!args.get(0).isUndefined()) {
|
||||
desc = ToString(cx, args.get(0));
|
||||
if (!desc)
|
||||
return false;
|
||||
}
|
||||
|
||||
// step 4
|
||||
RootedSymbol symbol(cx, JS::Symbol::new_(cx, desc));
|
||||
if (!symbol)
|
||||
return false;
|
||||
args.rval().setSymbol(symbol);
|
||||
return true;
|
||||
}
|
||||
|
||||
JSObject *
|
||||
js_InitSymbolClass(JSContext *cx, HandleObject obj)
|
||||
{
|
||||
return SymbolObject::initClass(cx, obj);
|
||||
}
|
55
js/src/builtin/SymbolObject.h
Normal file
55
js/src/builtin/SymbolObject.h
Normal file
@ -0,0 +1,55 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* vim: set ts=8 sts=4 et sw=4 tw=99:
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef builtin_SymbolObject_h
|
||||
#define builtin_SymbolObject_h
|
||||
|
||||
#include "jsobj.h"
|
||||
|
||||
#include "vm/Symbol.h"
|
||||
|
||||
namespace js {
|
||||
|
||||
class SymbolObject : public JSObject
|
||||
{
|
||||
/* Stores this Symbol object's [[PrimitiveValue]]. */
|
||||
static const unsigned PRIMITIVE_VALUE_SLOT = 0;
|
||||
|
||||
public:
|
||||
static const unsigned RESERVED_SLOTS = 1;
|
||||
|
||||
static const Class class_;
|
||||
|
||||
static JSObject *initClass(JSContext *cx, js::HandleObject obj);
|
||||
|
||||
/*
|
||||
* Creates a new Symbol object boxing the given primitive Symbol. The
|
||||
* object's [[Prototype]] is determined from context.
|
||||
*/
|
||||
static SymbolObject *create(JSContext *cx, JS::Symbol *symbol);
|
||||
|
||||
JS::Symbol *unbox() const {
|
||||
return getFixedSlot(PRIMITIVE_VALUE_SLOT).toSymbol();
|
||||
}
|
||||
|
||||
private:
|
||||
inline void setPrimitiveValue(JS::Symbol *symbol) {
|
||||
setFixedSlot(PRIMITIVE_VALUE_SLOT, SymbolValue(symbol));
|
||||
}
|
||||
|
||||
static bool construct(JSContext *cx, unsigned argc, Value *vp);
|
||||
|
||||
static const JSPropertySpec properties[];
|
||||
static const JSFunctionSpec methods[];
|
||||
static const JSFunctionSpec staticMethods[];
|
||||
};
|
||||
|
||||
} /* namespace js */
|
||||
|
||||
extern JSObject *
|
||||
js_InitSymbolClass(JSContext *cx, js::HandleObject obj);
|
||||
|
||||
#endif /* builtin_SymbolObject_h */
|
@ -17,6 +17,7 @@ check(false);
|
||||
check(1);
|
||||
check(NaN);
|
||||
check("ok");
|
||||
check(Symbol("ok"));
|
||||
|
||||
// A Debugger.Object that belongs to a different Debugger object is invalid.
|
||||
var g = newGlobal();
|
||||
|
@ -1,4 +1,4 @@
|
||||
// env.find() finds noneumerable properties in with statements.
|
||||
// env.find() finds nonenumerable properties in with statements.
|
||||
|
||||
var g = newGlobal();
|
||||
var dbg = Debugger(g);
|
||||
|
@ -237,6 +237,7 @@ enum MIRType
|
||||
MIRType_Double,
|
||||
MIRType_Float32,
|
||||
MIRType_String,
|
||||
MIRType_Symbol,
|
||||
MIRType_Object,
|
||||
MIRType_MagicOptimizedArguments, // JS_OPTIMIZED_ARGUMENTS magic value.
|
||||
MIRType_MagicOptimizedOut, // JS_OPTIMIZED_OUT magic value.
|
||||
|
@ -47,6 +47,7 @@
|
||||
#include "builtin/Intl.h"
|
||||
#include "builtin/MapObject.h"
|
||||
#include "builtin/RegExp.h"
|
||||
#include "builtin/SymbolObject.h"
|
||||
#ifdef ENABLE_BINARYDATA
|
||||
#include "builtin/SIMD.h"
|
||||
#include "builtin/TypedObject.h"
|
||||
|
@ -1971,6 +1971,8 @@ js::ReportIncompatibleMethod(JSContext *cx, CallReceiver call, const Class *clas
|
||||
JS_ASSERT(clasp != &NumberObject::class_);
|
||||
} else if (thisv.isBoolean()) {
|
||||
JS_ASSERT(clasp != &BooleanObject::class_);
|
||||
} else if (thisv.isSymbol()) {
|
||||
JS_ASSERT(clasp != &SymbolObject::class_);
|
||||
} else {
|
||||
JS_ASSERT(thisv.isUndefined() || thisv.isNull());
|
||||
}
|
||||
|
@ -178,6 +178,8 @@ types::TypeString(Type type)
|
||||
return "float";
|
||||
case JSVAL_TYPE_STRING:
|
||||
return "string";
|
||||
case JSVAL_TYPE_SYMBOL:
|
||||
return "symbol";
|
||||
case JSVAL_TYPE_MAGIC:
|
||||
return "lazyargs";
|
||||
default:
|
||||
@ -332,6 +334,8 @@ TypeSet::mightBeMIRType(jit::MIRType type)
|
||||
return baseFlags() & TYPE_FLAG_DOUBLE;
|
||||
case jit::MIRType_String:
|
||||
return baseFlags() & TYPE_FLAG_STRING;
|
||||
case jit::MIRType_Symbol:
|
||||
return baseFlags() & TYPE_FLAG_SYMBOL;
|
||||
case jit::MIRType_MagicOptimizedArguments:
|
||||
return baseFlags() & TYPE_FLAG_LAZYARGS;
|
||||
case jit::MIRType_MagicHole:
|
||||
@ -1324,6 +1328,8 @@ GetMIRTypeFromTypeFlags(TypeFlags flags)
|
||||
return jit::MIRType_Double;
|
||||
case TYPE_FLAG_STRING:
|
||||
return jit::MIRType_String;
|
||||
case TYPE_FLAG_SYMBOL:
|
||||
return jit::MIRType_Symbol;
|
||||
case TYPE_FLAG_LAZYARGS:
|
||||
return jit::MIRType_MagicOptimizedArguments;
|
||||
case TYPE_FLAG_ANYOBJECT:
|
||||
|
@ -377,30 +377,32 @@ public:
|
||||
|
||||
/* Flags and other state stored in TypeSet::flags */
|
||||
enum MOZ_ENUM_TYPE(uint32_t) {
|
||||
TYPE_FLAG_UNDEFINED = 0x1,
|
||||
TYPE_FLAG_NULL = 0x2,
|
||||
TYPE_FLAG_BOOLEAN = 0x4,
|
||||
TYPE_FLAG_INT32 = 0x8,
|
||||
TYPE_FLAG_DOUBLE = 0x10,
|
||||
TYPE_FLAG_STRING = 0x20,
|
||||
TYPE_FLAG_LAZYARGS = 0x40,
|
||||
TYPE_FLAG_ANYOBJECT = 0x80,
|
||||
TYPE_FLAG_UNDEFINED = 0x1,
|
||||
TYPE_FLAG_NULL = 0x2,
|
||||
TYPE_FLAG_BOOLEAN = 0x4,
|
||||
TYPE_FLAG_INT32 = 0x8,
|
||||
TYPE_FLAG_DOUBLE = 0x10,
|
||||
TYPE_FLAG_STRING = 0x20,
|
||||
TYPE_FLAG_SYMBOL = 0x40,
|
||||
TYPE_FLAG_LAZYARGS = 0x80,
|
||||
TYPE_FLAG_ANYOBJECT = 0x100,
|
||||
|
||||
/* Mask containing all primitives */
|
||||
TYPE_FLAG_PRIMITIVE = TYPE_FLAG_UNDEFINED | TYPE_FLAG_NULL | TYPE_FLAG_BOOLEAN |
|
||||
TYPE_FLAG_INT32 | TYPE_FLAG_DOUBLE | TYPE_FLAG_STRING,
|
||||
TYPE_FLAG_INT32 | TYPE_FLAG_DOUBLE | TYPE_FLAG_STRING |
|
||||
TYPE_FLAG_SYMBOL,
|
||||
|
||||
/* Mask/shift for the number of objects in objectSet */
|
||||
TYPE_FLAG_OBJECT_COUNT_MASK = 0x1f00,
|
||||
TYPE_FLAG_OBJECT_COUNT_SHIFT = 8,
|
||||
TYPE_FLAG_OBJECT_COUNT_MASK = 0x3e00,
|
||||
TYPE_FLAG_OBJECT_COUNT_SHIFT = 9,
|
||||
TYPE_FLAG_OBJECT_COUNT_LIMIT =
|
||||
TYPE_FLAG_OBJECT_COUNT_MASK >> TYPE_FLAG_OBJECT_COUNT_SHIFT,
|
||||
|
||||
/* Whether the contents of this type set are totally unknown. */
|
||||
TYPE_FLAG_UNKNOWN = 0x00002000,
|
||||
TYPE_FLAG_UNKNOWN = 0x00004000,
|
||||
|
||||
/* Mask of normal type flags on a type set. */
|
||||
TYPE_FLAG_BASE_MASK = 0x000020ff,
|
||||
TYPE_FLAG_BASE_MASK = 0x000041ff,
|
||||
|
||||
/* Additional flags for HeapTypeSet sets. */
|
||||
|
||||
@ -409,10 +411,10 @@ enum MOZ_ENUM_TYPE(uint32_t) {
|
||||
* differently from a plain data property, other than making the property
|
||||
* non-writable.
|
||||
*/
|
||||
TYPE_FLAG_NON_DATA_PROPERTY = 0x00004000,
|
||||
TYPE_FLAG_NON_DATA_PROPERTY = 0x00008000,
|
||||
|
||||
/* Whether the property has ever been made non-writable. */
|
||||
TYPE_FLAG_NON_WRITABLE_PROPERTY = 0x00008000,
|
||||
TYPE_FLAG_NON_WRITABLE_PROPERTY = 0x00010000,
|
||||
|
||||
/*
|
||||
* Whether the property is definitely in a particular slot on all objects
|
||||
@ -423,8 +425,8 @@ enum MOZ_ENUM_TYPE(uint32_t) {
|
||||
* If the property is definite, mask and shift storing the slot + 1.
|
||||
* Otherwise these bits are clear.
|
||||
*/
|
||||
TYPE_FLAG_DEFINITE_MASK = 0xffff0000,
|
||||
TYPE_FLAG_DEFINITE_SHIFT = 16
|
||||
TYPE_FLAG_DEFINITE_MASK = 0xfffe0000,
|
||||
TYPE_FLAG_DEFINITE_SHIFT = 17
|
||||
};
|
||||
typedef uint32_t TypeFlags;
|
||||
|
||||
|
@ -13,6 +13,7 @@
|
||||
|
||||
#include "mozilla/PodOperations.h"
|
||||
|
||||
#include "builtin/SymbolObject.h"
|
||||
#include "vm/ArrayObject.h"
|
||||
#include "vm/BooleanObject.h"
|
||||
#include "vm/NumberObject.h"
|
||||
@ -162,6 +163,8 @@ PrimitiveTypeFlag(JSValueType type)
|
||||
return TYPE_FLAG_DOUBLE;
|
||||
case JSVAL_TYPE_STRING:
|
||||
return TYPE_FLAG_STRING;
|
||||
case JSVAL_TYPE_SYMBOL:
|
||||
return TYPE_FLAG_SYMBOL;
|
||||
case JSVAL_TYPE_MAGIC:
|
||||
return TYPE_FLAG_LAZYARGS;
|
||||
default:
|
||||
@ -185,6 +188,8 @@ TypeFlagPrimitive(TypeFlags flags)
|
||||
return JSVAL_TYPE_DOUBLE;
|
||||
case TYPE_FLAG_STRING:
|
||||
return JSVAL_TYPE_STRING;
|
||||
case TYPE_FLAG_SYMBOL:
|
||||
return JSVAL_TYPE_SYMBOL;
|
||||
case TYPE_FLAG_LAZYARGS:
|
||||
return JSVAL_TYPE_MAGIC;
|
||||
default:
|
||||
@ -331,6 +336,8 @@ GetClassForProtoKey(JSProtoKey key)
|
||||
return &BooleanObject::class_;
|
||||
case JSProto_String:
|
||||
return &StringObject::class_;
|
||||
case JSProto_Symbol:
|
||||
return &SymbolObject::class_;
|
||||
case JSProto_RegExp:
|
||||
return &RegExpObject::class_;
|
||||
|
||||
|
@ -38,6 +38,7 @@
|
||||
|
||||
#include "builtin/Eval.h"
|
||||
#include "builtin/Object.h"
|
||||
#include "builtin/SymbolObject.h"
|
||||
#include "frontend/BytecodeCompiler.h"
|
||||
#include "gc/Marking.h"
|
||||
#include "jit/AsmJSModule.h"
|
||||
@ -243,6 +244,8 @@ js::InformalValueTypeName(const Value &v)
|
||||
return v.toObject().getClass()->name;
|
||||
if (v.isString())
|
||||
return "string";
|
||||
if (v.isSymbol())
|
||||
return "symbol";
|
||||
if (v.isNumber())
|
||||
return "number";
|
||||
if (v.isBoolean())
|
||||
@ -5642,12 +5645,13 @@ js::PrimitiveToObject(JSContext *cx, const Value &v)
|
||||
}
|
||||
if (v.isNumber())
|
||||
return NumberObject::create(cx, v.toNumber());
|
||||
|
||||
JS_ASSERT(v.isBoolean());
|
||||
return BooleanObject::create(cx, v.toBoolean());
|
||||
if (v.isBoolean())
|
||||
return BooleanObject::create(cx, v.toBoolean());
|
||||
JS_ASSERT(v.isSymbol());
|
||||
return SymbolObject::create(cx, v.toSymbol());
|
||||
}
|
||||
|
||||
/* Callers must handle the already-object case . */
|
||||
/* Callers must handle the already-object case. */
|
||||
JSObject *
|
||||
js::ToObjectSlow(JSContext *cx, HandleValue val, bool reportScanStack)
|
||||
{
|
||||
|
@ -97,11 +97,12 @@
|
||||
real(Map, 33, js_InitMapClass, OCLASP(Map)) \
|
||||
real(Set, 34, js_InitSetClass, OCLASP(Set)) \
|
||||
real(DataView, 35, js_InitDataViewClass, OCLASP(DataView)) \
|
||||
IF_SAB(real,imaginary)(SharedArrayBuffer, 36, js_InitSharedArrayBufferClass, &js::SharedArrayBufferObject::protoClass) \
|
||||
IF_INTL(real,imaginary) (Intl, 37, js_InitIntlClass, CLASP(Intl)) \
|
||||
IF_BDATA(real,imaginary)(TypedObject, 38, js_InitTypedObjectModuleObject, OCLASP(TypedObjectModule)) \
|
||||
imaginary(GeneratorFunction, 39, js_InitIteratorClasses, dummy) \
|
||||
IF_BDATA(real,imaginary)(SIMD, 40, js_InitSIMDClass, OCLASP(SIMD)) \
|
||||
real(Symbol, 36, js_InitSymbolClass, &js::SymbolObject::class_) \
|
||||
IF_SAB(real,imaginary)(SharedArrayBuffer, 37, js_InitSharedArrayBufferClass, &js::SharedArrayBufferObject::protoClass) \
|
||||
IF_INTL(real,imaginary) (Intl, 38, js_InitIntlClass, CLASP(Intl)) \
|
||||
IF_BDATA(real,imaginary)(TypedObject, 39, js_InitTypedObjectModuleObject, OCLASP(TypedObjectModule)) \
|
||||
imaginary(GeneratorFunction, 40, js_InitIteratorClasses, dummy) \
|
||||
IF_BDATA(real,imaginary)(SIMD, 41, js_InitSIMDClass, OCLASP(SIMD)) \
|
||||
|
||||
#define JS_FOR_EACH_PROTOTYPE(macro) JS_FOR_PROTOTYPES(macro,macro)
|
||||
|
||||
|
@ -102,6 +102,7 @@ UNIFIED_SOURCES += [
|
||||
'builtin/Object.cpp',
|
||||
'builtin/Profilers.cpp',
|
||||
'builtin/SIMD.cpp',
|
||||
'builtin/SymbolObject.cpp',
|
||||
'builtin/TestingFunctions.cpp',
|
||||
'builtin/TypedObject.cpp',
|
||||
'devtools/sharkctl.cpp',
|
||||
|
0
js/src/tests/ecma_6/Symbol/browser.js
Normal file
0
js/src/tests/ecma_6/Symbol/browser.js
Normal file
9
js/src/tests/ecma_6/Symbol/constructor.js
Normal file
9
js/src/tests/ecma_6/Symbol/constructor.js
Normal file
@ -0,0 +1,9 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/licenses/publicdomain/ */
|
||||
|
||||
// More tests will be added here when Symbol.prototype.toString is added.
|
||||
|
||||
assertEq(Object.getPrototypeOf(Symbol.prototype), Object.prototype);
|
||||
|
||||
if (typeof reportCompare === "function")
|
||||
reportCompare(0, 0);
|
25
js/src/tests/ecma_6/Symbol/equality.js
Normal file
25
js/src/tests/ecma_6/Symbol/equality.js
Normal file
@ -0,0 +1,25 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/licenses/publicdomain/ */
|
||||
|
||||
// Several distinct Symbol values.
|
||||
var symbols = [
|
||||
Symbol(),
|
||||
Symbol("Symbol.iterator"),
|
||||
Symbol("Symbol.iterator") // distinct new symbol with the same description
|
||||
];
|
||||
|
||||
// Distinct symbols are never equal to each other, even if they have the same
|
||||
// description.
|
||||
for (var i = 0; i < symbols.length; i++) {
|
||||
for (var j = i; j < symbols.length; j++) {
|
||||
var expected = (i === j);
|
||||
assertEq(symbols[i] == symbols[j], expected);
|
||||
assertEq(symbols[i] != symbols[j], !expected);
|
||||
assertEq(symbols[i] === symbols[j], expected);
|
||||
assertEq(symbols[i] !== symbols[j], !expected);
|
||||
assertEq(Object.is(symbols[i], symbols[j]), expected);
|
||||
}
|
||||
}
|
||||
|
||||
if (typeof reportCompare === "function")
|
||||
reportCompare(0, 0);
|
17
js/src/tests/ecma_6/Symbol/errors.js
Normal file
17
js/src/tests/ecma_6/Symbol/errors.js
Normal file
@ -0,0 +1,17 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/licenses/publicdomain/ */
|
||||
|
||||
// Section numbers cite ES6 rev 24 (2014 April 27).
|
||||
|
||||
var sym = Symbol();
|
||||
|
||||
// 7.2.2 IsCallable
|
||||
assertThrowsInstanceOf(() => sym(), TypeError);
|
||||
assertThrowsInstanceOf(() => Function.prototype.call.call(sym), TypeError);
|
||||
|
||||
// 7.2.5 IsConstructor
|
||||
assertThrowsInstanceOf(() => new sym(), TypeError);
|
||||
assertThrowsInstanceOf(() => new Symbol(), TypeError);
|
||||
|
||||
if (typeof reportCompare === "function")
|
||||
reportCompare(0, 0);
|
0
js/src/tests/ecma_6/Symbol/shell.js
Normal file
0
js/src/tests/ecma_6/Symbol/shell.js
Normal file
25
js/src/tests/ecma_6/Symbol/surfaces.js
Normal file
25
js/src/tests/ecma_6/Symbol/surfaces.js
Normal file
@ -0,0 +1,25 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/licenses/publicdomain/ */
|
||||
|
||||
// Test superficial properties of the Symbol constructor and prototype.
|
||||
|
||||
var desc = Object.getOwnPropertyDescriptor(this, "Symbol");
|
||||
assertEq(desc.configurable, true);
|
||||
assertEq(desc.enumerable, false);
|
||||
assertEq(desc.writable, true);
|
||||
assertEq(typeof Symbol, "function");
|
||||
assertEq(Symbol.length, 1);
|
||||
|
||||
desc = Object.getOwnPropertyDescriptor(Symbol, "prototype");
|
||||
assertEq(desc.configurable, false);
|
||||
assertEq(desc.enumerable, false);
|
||||
assertEq(desc.writable, false);
|
||||
|
||||
assertEq(Symbol.prototype.constructor, Symbol);
|
||||
desc = Object.getOwnPropertyDescriptor(Symbol.prototype, "constructor");
|
||||
assertEq(desc.configurable, true);
|
||||
assertEq(desc.enumerable, false);
|
||||
assertEq(desc.writable, true);
|
||||
|
||||
if (typeof reportCompare === "function")
|
||||
reportCompare(0, 0);
|
8
js/src/tests/ecma_6/Symbol/typeof.js
Normal file
8
js/src/tests/ecma_6/Symbol/typeof.js
Normal file
@ -0,0 +1,8 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/licenses/publicdomain/ */
|
||||
|
||||
assertEq(typeof Symbol(), "symbol");
|
||||
assertEq(typeof Symbol("ponies"), "symbol");
|
||||
|
||||
if (typeof reportCompare === "function")
|
||||
reportCompare(0, 0);
|
@ -23,6 +23,7 @@
|
||||
#include "builtin/Object.h"
|
||||
#include "builtin/RegExp.h"
|
||||
#include "builtin/SIMD.h"
|
||||
#include "builtin/SymbolObject.h"
|
||||
#include "builtin/TypedObject.h"
|
||||
#include "vm/HelperThreads.h"
|
||||
#include "vm/PIC.h"
|
||||
@ -317,7 +318,6 @@ GlobalObject::createConstructor(JSContext *cx, Native ctor, JSAtom *nameArg, uns
|
||||
static JSObject *
|
||||
CreateBlankProto(JSContext *cx, const Class *clasp, JSObject &proto, GlobalObject &global)
|
||||
{
|
||||
JS_ASSERT(clasp != &JSObject::class_);
|
||||
JS_ASSERT(clasp != &JSFunction::class_);
|
||||
|
||||
RootedObject blankProto(cx, NewObjectWithGivenProto(cx, clasp, &proto, &global, SingletonObject));
|
||||
|
@ -661,32 +661,31 @@ js::HasInstance(JSContext *cx, HandleObject obj, HandleValue v, bool *bp)
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
EqualGivenSameType(JSContext *cx, const Value &lval, const Value &rval, bool *equal)
|
||||
{
|
||||
MOZ_ASSERT(SameType(lval, rval));
|
||||
|
||||
if (lval.isString())
|
||||
return EqualStrings(cx, lval.toString(), rval.toString(), equal);
|
||||
if (lval.isDouble()) {
|
||||
*equal = (lval.toDouble() == rval.toDouble());
|
||||
return true;
|
||||
}
|
||||
if (lval.isGCThing()) { // objects or symbols
|
||||
*equal = (lval.toGCThing() == rval.toGCThing());
|
||||
return true;
|
||||
}
|
||||
*equal = lval.payloadAsRawUint32() == rval.payloadAsRawUint32();
|
||||
MOZ_ASSERT_IF(lval.isUndefined(), *equal);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
js::LooselyEqual(JSContext *cx, const Value &lval, const Value &rval, bool *result)
|
||||
{
|
||||
if (SameType(lval, rval)) {
|
||||
if (lval.isString()) {
|
||||
JSString *l = lval.toString();
|
||||
JSString *r = rval.toString();
|
||||
return EqualStrings(cx, l, r, result);
|
||||
}
|
||||
|
||||
if (lval.isDouble()) {
|
||||
double l = lval.toDouble(), r = rval.toDouble();
|
||||
*result = (l == r);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (lval.isObject()) {
|
||||
JSObject *l = &lval.toObject();
|
||||
JSObject *r = &rval.toObject();
|
||||
*result = l == r;
|
||||
return true;
|
||||
}
|
||||
|
||||
*result = lval.payloadAsRawUint32() == rval.payloadAsRawUint32();
|
||||
return true;
|
||||
}
|
||||
if (SameType(lval, rval))
|
||||
return EqualGivenSameType(cx, lval, rval, result);
|
||||
|
||||
if (lval.isNullOrUndefined()) {
|
||||
*result = rval.isNullOrUndefined() ||
|
||||
@ -724,24 +723,8 @@ bool
|
||||
js::StrictlyEqual(JSContext *cx, const Value &lref, const Value &rref, bool *equal)
|
||||
{
|
||||
Value lval = lref, rval = rref;
|
||||
if (SameType(lval, rval)) {
|
||||
if (lval.isString())
|
||||
return EqualStrings(cx, lval.toString(), rval.toString(), equal);
|
||||
if (lval.isDouble()) {
|
||||
*equal = (lval.toDouble() == rval.toDouble());
|
||||
return true;
|
||||
}
|
||||
if (lval.isObject()) {
|
||||
*equal = lval.toObject() == rval.toObject();
|
||||
return true;
|
||||
}
|
||||
if (lval.isUndefined()) {
|
||||
*equal = true;
|
||||
return true;
|
||||
}
|
||||
*equal = lval.payloadAsRawUint32() == rval.payloadAsRawUint32();
|
||||
return true;
|
||||
}
|
||||
if (SameType(lval, rval))
|
||||
return EqualGivenSameType(cx, lval, rval, equal);
|
||||
|
||||
if (lval.isDouble() && rval.isInt32()) {
|
||||
double ld = lval.toDouble();
|
||||
|
Loading…
x
Reference in New Issue
Block a user