mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-23 21:01:08 +00:00
Bug 1366287 - Part 1.0: Define a new BigInt primitive type, with a GDB prettyprinter, Rust binding support, and a new out-of-line TraceKind. (Disabled by default, implemented only incompletely, currently passing --enable-bigint will disable JITs, will be flipped on Eventually once every sub-aspect is in place, Don't Have A Cow, Man.) r=jwalden, r=Ms2ger, r=sfink
--HG-- extra : rebase_source : aa13bd94bc6157ff8134894e3ba2e7a2b53e28d9
This commit is contained in:
parent
dd94407236
commit
de41c625dd
@ -102,13 +102,29 @@ def disable_export_js(value):
|
||||
die('Setting %s is deprecated, use %s instead.',
|
||||
value.format('DISABLE_EXPORT_JS'), suggestion)
|
||||
|
||||
# Experimental BigInt support
|
||||
# =======================================================
|
||||
js_option('--enable-bigint',
|
||||
default=False,
|
||||
help='Enable BigInt')
|
||||
|
||||
@depends('--enable-bigint')
|
||||
def enable_bigint(value):
|
||||
if value:
|
||||
return True
|
||||
|
||||
set_config('ENABLE_BIGINT', enable_bigint)
|
||||
set_define('ENABLE_BIGINT', enable_bigint)
|
||||
|
||||
# JIT support
|
||||
# =======================================================
|
||||
@depends(target)
|
||||
def ion_default(target):
|
||||
@depends(target, '--enable-bigint')
|
||||
def ion_default(target, enable_bigint):
|
||||
if enable_bigint:
|
||||
return False
|
||||
if target.cpu in ('x86', 'x86_64', 'arm', 'aarch64', 'mips32', 'mips64'):
|
||||
return True
|
||||
return False
|
||||
|
||||
js_option('--enable-ion',
|
||||
default=ion_default,
|
||||
|
@ -122,7 +122,7 @@ ToBoolean(HandleValue v)
|
||||
if (v.isSymbol())
|
||||
return true;
|
||||
|
||||
/* The slow path handles strings and objects. */
|
||||
/* The slow path handles strings, BigInts and objects. */
|
||||
return js::ToBooleanSlow(v);
|
||||
}
|
||||
|
||||
|
@ -50,6 +50,7 @@
|
||||
// Expand the given macro D for each public GC pointer.
|
||||
#define FOR_EACH_PUBLIC_GC_POINTER_TYPE(D) \
|
||||
D(JS::Symbol*) \
|
||||
IF_BIGINT(D(JS::BigInt*),) \
|
||||
D(JSAtom*) \
|
||||
D(JSFunction*) \
|
||||
D(JSObject*) \
|
||||
@ -127,6 +128,9 @@ struct GCPointerPolicy
|
||||
}
|
||||
};
|
||||
template <> struct GCPolicy<JS::Symbol*> : public GCPointerPolicy<JS::Symbol*> {};
|
||||
#ifdef ENABLE_BIGINT
|
||||
template <> struct GCPolicy<JS::BigInt*> : public GCPointerPolicy<JS::BigInt*> {};
|
||||
#endif
|
||||
template <> struct GCPolicy<JSAtom*> : public GCPointerPolicy<JSAtom*> {};
|
||||
template <> struct GCPolicy<JSFunction*> : public GCPointerPolicy<JSFunction*> {};
|
||||
template <> struct GCPolicy<JSObject*> : public GCPointerPolicy<JSObject*> {};
|
||||
|
@ -629,6 +629,7 @@ struct UnusedGCThingSizes
|
||||
macro(Other, GCHeapUnused, objectGroup) \
|
||||
macro(Other, GCHeapUnused, string) \
|
||||
macro(Other, GCHeapUnused, symbol) \
|
||||
IF_BIGINT(macro(Other, GCHeapUnused, bigInt),) \
|
||||
macro(Other, GCHeapUnused, jitcode) \
|
||||
macro(Other, GCHeapUnused, scope) \
|
||||
macro(Other, GCHeapUnused, regExpShared)
|
||||
@ -648,6 +649,9 @@ struct UnusedGCThingSizes
|
||||
case JS::TraceKind::Object: object += n; break;
|
||||
case JS::TraceKind::String: string += n; break;
|
||||
case JS::TraceKind::Symbol: symbol += n; break;
|
||||
#ifdef ENABLE_BIGINT
|
||||
case JS::TraceKind::BigInt: bigInt += n; break;
|
||||
#endif
|
||||
case JS::TraceKind::Script: script += n; break;
|
||||
case JS::TraceKind::Shape: shape += n; break;
|
||||
case JS::TraceKind::BaseShape: baseShape += n; break;
|
||||
@ -689,6 +693,8 @@ struct ZoneStats
|
||||
{
|
||||
#define FOR_EACH_SIZE(macro) \
|
||||
macro(Other, GCHeapUsed, symbolsGCHeap) \
|
||||
IF_BIGINT(macro(Other, GCHeapUsed, bigIntsGCHeap),) \
|
||||
IF_BIGINT(macro(Other, MallocHeap, bigIntsMallocHeap),) \
|
||||
macro(Other, GCHeapAdmin, gcHeapArenaAdmin) \
|
||||
macro(Other, GCHeapUsed, lazyScriptsGCHeap) \
|
||||
macro(Other, MallocHeap, lazyScriptsMallocHeap) \
|
||||
|
@ -61,7 +61,10 @@ enum class TraceKind
|
||||
JitCode = 0x1F,
|
||||
LazyScript = 0x2F,
|
||||
Scope = 0x3F,
|
||||
RegExpShared = 0x4F
|
||||
RegExpShared = 0x4F,
|
||||
#ifdef ENABLE_BIGINT
|
||||
BigInt = 0x5F
|
||||
#endif
|
||||
};
|
||||
const static uintptr_t OutOfLineTraceKindMask = 0x07;
|
||||
|
||||
@ -97,6 +100,7 @@ struct MapTypeToTraceKind {
|
||||
D(Shape, js::Shape, true) \
|
||||
D(String, JSString, false) \
|
||||
D(Symbol, JS::Symbol, false) \
|
||||
IF_BIGINT(D(BigInt, JS::BigInt, false),) \
|
||||
D(RegExpShared, js::RegExpShared, true)
|
||||
|
||||
// Map from all public types to their trace kind.
|
||||
|
@ -151,6 +151,9 @@ class JS_PUBLIC_API(CallbackTracer) : public JSTracer
|
||||
virtual void onObjectEdge(JSObject** objp) { onChild(JS::GCCellPtr(*objp)); }
|
||||
virtual void onStringEdge(JSString** strp) { onChild(JS::GCCellPtr(*strp)); }
|
||||
virtual void onSymbolEdge(JS::Symbol** symp) { onChild(JS::GCCellPtr(*symp)); }
|
||||
#ifdef ENABLE_BIGINT
|
||||
virtual void onBigIntEdge(JS::BigInt** bip) { onChild(JS::GCCellPtr(*bip)); }
|
||||
#endif
|
||||
virtual void onScriptEdge(JSScript** scriptp) { onChild(JS::GCCellPtr(*scriptp)); }
|
||||
virtual void onShapeEdge(js::Shape** shapep) {
|
||||
onChild(JS::GCCellPtr(*shapep, JS::TraceKind::Shape));
|
||||
@ -243,6 +246,9 @@ class JS_PUBLIC_API(CallbackTracer) : public JSTracer
|
||||
void dispatchToOnEdge(JSObject** objp) { onObjectEdge(objp); }
|
||||
void dispatchToOnEdge(JSString** strp) { onStringEdge(strp); }
|
||||
void dispatchToOnEdge(JS::Symbol** symp) { onSymbolEdge(symp); }
|
||||
#ifdef ENABLE_BIGINT
|
||||
void dispatchToOnEdge(JS::BigInt** bip) { onBigIntEdge(bip); }
|
||||
#endif
|
||||
void dispatchToOnEdge(JSScript** scriptp) { onScriptEdge(scriptp); }
|
||||
void dispatchToOnEdge(js::Shape** shapep) { onShapeEdge(shapep); }
|
||||
void dispatchToOnEdge(js::ObjectGroup** groupp) { onObjectGroupEdge(groupp); }
|
||||
|
@ -41,6 +41,9 @@ namespace JS {
|
||||
typedef unsigned char Latin1Char;
|
||||
|
||||
class Symbol;
|
||||
#ifdef ENABLE_BIGINT
|
||||
class BigInt;
|
||||
#endif
|
||||
union Value;
|
||||
class Realm;
|
||||
struct Runtime;
|
||||
@ -57,6 +60,9 @@ typedef Handle<JSObject*> HandleObject;
|
||||
typedef Handle<JSScript*> HandleScript;
|
||||
typedef Handle<JSString*> HandleString;
|
||||
typedef Handle<JS::Symbol*> HandleSymbol;
|
||||
#ifdef ENABLE_BIGINT
|
||||
typedef Handle<JS::BigInt*> HandleBigInt;
|
||||
#endif
|
||||
typedef Handle<Value> HandleValue;
|
||||
|
||||
typedef MutableHandle<JSFunction*> MutableHandleFunction;
|
||||
@ -65,6 +71,9 @@ typedef MutableHandle<JSObject*> MutableHandleObject;
|
||||
typedef MutableHandle<JSScript*> MutableHandleScript;
|
||||
typedef MutableHandle<JSString*> MutableHandleString;
|
||||
typedef MutableHandle<JS::Symbol*> MutableHandleSymbol;
|
||||
#ifdef ENABLE_BIGINT
|
||||
typedef MutableHandle<JS::BigInt*> MutableHandleBigInt;
|
||||
#endif
|
||||
typedef MutableHandle<Value> MutableHandleValue;
|
||||
|
||||
typedef Rooted<JSObject*> RootedObject;
|
||||
@ -72,6 +81,9 @@ typedef Rooted<JSFunction*> RootedFunction;
|
||||
typedef Rooted<JSScript*> RootedScript;
|
||||
typedef Rooted<JSString*> RootedString;
|
||||
typedef Rooted<JS::Symbol*> RootedSymbol;
|
||||
#ifdef ENABLE_BIGINT
|
||||
typedef Rooted<JS::BigInt*> RootedBigInt;
|
||||
#endif
|
||||
typedef Rooted<jsid> RootedId;
|
||||
typedef Rooted<JS::Value> RootedValue;
|
||||
|
||||
@ -81,8 +93,17 @@ typedef PersistentRooted<JSObject*> PersistentRootedObject;
|
||||
typedef PersistentRooted<JSScript*> PersistentRootedScript;
|
||||
typedef PersistentRooted<JSString*> PersistentRootedString;
|
||||
typedef PersistentRooted<JS::Symbol*> PersistentRootedSymbol;
|
||||
#ifdef ENABLE_BIGINT
|
||||
typedef PersistentRooted<JS::BigInt*> PersistentRootedBigInt;
|
||||
#endif
|
||||
typedef PersistentRooted<Value> PersistentRootedValue;
|
||||
|
||||
} // namespace JS
|
||||
|
||||
#ifdef ENABLE_BIGINT
|
||||
#define IF_BIGINT(x, y) x
|
||||
#else
|
||||
#define IF_BIGINT(x, y) y
|
||||
#endif
|
||||
|
||||
#endif /* js_TypeDecls_h */
|
||||
|
@ -1056,6 +1056,24 @@ class JS_PUBLIC_API(Concrete<JS::Symbol>) : TracerConcrete<JS::Symbol> {
|
||||
static const char16_t concreteTypeName[];
|
||||
};
|
||||
|
||||
#ifdef ENABLE_BIGINT
|
||||
template<>
|
||||
class JS_PUBLIC_API(Concrete<JS::BigInt>) : TracerConcrete<JS::BigInt> {
|
||||
protected:
|
||||
explicit Concrete(JS::BigInt* ptr) : TracerConcrete(ptr) {}
|
||||
|
||||
public:
|
||||
static void construct(void* storage, JS::BigInt* ptr) {
|
||||
new (storage) Concrete(ptr);
|
||||
}
|
||||
|
||||
Size size(mozilla::MallocSizeOf mallocSizeOf) const override;
|
||||
|
||||
const char16_t* typeName() const override { return concreteTypeName; }
|
||||
static const char16_t concreteTypeName[];
|
||||
};
|
||||
#endif
|
||||
|
||||
template<>
|
||||
class JS_PUBLIC_API(Concrete<JSScript>) : TracerConcreteWithCompartment<JSScript> {
|
||||
protected:
|
||||
|
@ -59,6 +59,9 @@ enum JSValueType : uint8_t
|
||||
JSVAL_TYPE_STRING = 0x06,
|
||||
JSVAL_TYPE_SYMBOL = 0x07,
|
||||
JSVAL_TYPE_PRIVATE_GCTHING = 0x08,
|
||||
#ifdef ENABLE_BIGINT
|
||||
JSVAL_TYPE_BIGINT = 0x09,
|
||||
#endif
|
||||
JSVAL_TYPE_OBJECT = 0x0c,
|
||||
|
||||
/* These never appear in a jsval; they are only provided as an out-of-band value. */
|
||||
@ -82,6 +85,9 @@ JS_ENUM_HEADER(JSValueTag, uint32_t)
|
||||
JSVAL_TAG_STRING = JSVAL_TAG_CLEAR | JSVAL_TYPE_STRING,
|
||||
JSVAL_TAG_SYMBOL = JSVAL_TAG_CLEAR | JSVAL_TYPE_SYMBOL,
|
||||
JSVAL_TAG_PRIVATE_GCTHING = JSVAL_TAG_CLEAR | JSVAL_TYPE_PRIVATE_GCTHING,
|
||||
#ifdef ENABLE_BIGINT
|
||||
JSVAL_TAG_BIGINT = JSVAL_TAG_CLEAR | JSVAL_TYPE_BIGINT,
|
||||
#endif
|
||||
JSVAL_TAG_OBJECT = JSVAL_TAG_CLEAR | JSVAL_TYPE_OBJECT
|
||||
} JS_ENUM_FOOTER(JSValueTag);
|
||||
|
||||
@ -101,6 +107,9 @@ JS_ENUM_HEADER(JSValueTag, uint32_t)
|
||||
JSVAL_TAG_STRING = JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_STRING,
|
||||
JSVAL_TAG_SYMBOL = JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_SYMBOL,
|
||||
JSVAL_TAG_PRIVATE_GCTHING = JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_PRIVATE_GCTHING,
|
||||
#ifdef ENABLE_BIGINT
|
||||
JSVAL_TAG_BIGINT = JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_BIGINT,
|
||||
#endif
|
||||
JSVAL_TAG_OBJECT = JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_OBJECT
|
||||
} JS_ENUM_FOOTER(JSValueTag);
|
||||
|
||||
@ -118,6 +127,9 @@ enum JSValueShiftedTag : uint64_t
|
||||
JSVAL_SHIFTED_TAG_STRING = (((uint64_t)JSVAL_TAG_STRING) << JSVAL_TAG_SHIFT),
|
||||
JSVAL_SHIFTED_TAG_SYMBOL = (((uint64_t)JSVAL_TAG_SYMBOL) << JSVAL_TAG_SHIFT),
|
||||
JSVAL_SHIFTED_TAG_PRIVATE_GCTHING = (((uint64_t)JSVAL_TAG_PRIVATE_GCTHING) << JSVAL_TAG_SHIFT),
|
||||
#ifdef ENABLE_BIGINT
|
||||
JSVAL_SHIFTED_TAG_BIGINT = (((uint64_t)JSVAL_TAG_BIGINT) << JSVAL_TAG_SHIFT),
|
||||
#endif
|
||||
JSVAL_SHIFTED_TAG_OBJECT = (((uint64_t)JSVAL_TAG_OBJECT) << JSVAL_TAG_SHIFT)
|
||||
};
|
||||
|
||||
@ -261,7 +273,7 @@ CanonicalizeNaN(double d)
|
||||
*
|
||||
* - JS::Value has setX() and isX() members for X in
|
||||
*
|
||||
* { Int32, Double, String, Symbol, Boolean, Undefined, Null, Object, Magic }
|
||||
* { Int32, Double, String, Symbol, BigInt, Boolean, Undefined, Null, Object, Magic }
|
||||
*
|
||||
* JS::Value also contains toX() for each of the non-singleton types.
|
||||
*
|
||||
@ -343,6 +355,9 @@ union MOZ_NON_PARAM alignas(8) Value
|
||||
uint32_t boo_; // Don't use |bool| -- it must be four bytes.
|
||||
JSString* str_;
|
||||
JS::Symbol* sym_;
|
||||
#ifdef ENABLE_BIGINT
|
||||
JS::BigInt* bi_;
|
||||
#endif
|
||||
JSObject* obj_;
|
||||
js::gc::Cell* cell_;
|
||||
void* ptr_;
|
||||
@ -454,6 +469,13 @@ union MOZ_NON_PARAM alignas(8) Value
|
||||
asBits_ = bitsFromTagAndPayload(JSVAL_TAG_SYMBOL, PayloadType(sym));
|
||||
}
|
||||
|
||||
#ifdef ENABLE_BIGINT
|
||||
void setBigInt(JS::BigInt* bi) {
|
||||
MOZ_ASSERT(js::gc::IsCellPointerValid(bi));
|
||||
asBits_ = bitsFromTagAndPayload(JSVAL_TAG_BIGINT, PayloadType(bi));
|
||||
}
|
||||
#endif
|
||||
|
||||
void setObject(JSObject& obj) {
|
||||
MOZ_ASSERT(js::gc::IsCellPointerValid(&obj));
|
||||
|
||||
@ -620,6 +642,12 @@ union MOZ_NON_PARAM alignas(8) Value
|
||||
return toTag() == JSVAL_TAG_SYMBOL;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_BIGINT
|
||||
bool isBigInt() const {
|
||||
return toTag() == JSVAL_TAG_BIGINT;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool isObject() const {
|
||||
#if defined(JS_NUNBOX32)
|
||||
return toTag() == JSVAL_TAG_OBJECT;
|
||||
@ -681,6 +709,10 @@ union MOZ_NON_PARAM alignas(8) Value
|
||||
"Value type tags must correspond with JS::TraceKinds.");
|
||||
if (MOZ_UNLIKELY(isPrivateGCThing()))
|
||||
return JS::GCThingTraceKind(toGCThing());
|
||||
#ifdef ENABLE_BIGINT
|
||||
if (MOZ_UNLIKELY(isBigInt()))
|
||||
return JS::TraceKind::BigInt;
|
||||
#endif
|
||||
return JS::TraceKind(toTag() & 0x03);
|
||||
}
|
||||
|
||||
@ -745,6 +777,17 @@ union MOZ_NON_PARAM alignas(8) Value
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef ENABLE_BIGINT
|
||||
JS::BigInt* toBigInt() const {
|
||||
MOZ_ASSERT(isBigInt());
|
||||
#if defined(JS_NUNBOX32)
|
||||
return s_.payload_.bi_;
|
||||
#elif defined(JS_PUNBOX64)
|
||||
return reinterpret_cast<JS::BigInt*>(asBits_ ^ JSVAL_SHIFTED_TAG_BIGINT);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
JSObject& toObject() const {
|
||||
MOZ_ASSERT(isObject());
|
||||
#if defined(JS_NUNBOX32)
|
||||
@ -862,6 +905,10 @@ union MOZ_NON_PARAM alignas(8) Value
|
||||
"Private GC thing Values must not be strings. Make a StringValue instead.");
|
||||
MOZ_ASSERT(JS::GCThingTraceKind(cell) != JS::TraceKind::Symbol,
|
||||
"Private GC thing Values must not be symbols. Make a SymbolValue instead.");
|
||||
#ifdef ENABLE_BIGINT
|
||||
MOZ_ASSERT(JS::GCThingTraceKind(cell) != JS::TraceKind::BigInt,
|
||||
"Private GC thing Values must not be BigInts. Make a BigIntValue instead.");
|
||||
#endif
|
||||
MOZ_ASSERT(JS::GCThingTraceKind(cell) != JS::TraceKind::Object,
|
||||
"Private GC thing Values must not be objects. Make an ObjectValue instead.");
|
||||
|
||||
@ -987,6 +1034,16 @@ SymbolValue(JS::Symbol* sym)
|
||||
return v;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_BIGINT
|
||||
static inline Value
|
||||
BigIntValue(JS::BigInt* bi)
|
||||
{
|
||||
Value v;
|
||||
v.setBigInt(bi);
|
||||
return v;
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline Value
|
||||
BooleanValue(bool boo)
|
||||
{
|
||||
@ -1242,6 +1299,9 @@ class WrappedPtrOperations<JS::Value, Wrapper>
|
||||
bool isDouble() const { return value().isDouble(); }
|
||||
bool isString() const { return value().isString(); }
|
||||
bool isSymbol() const { return value().isSymbol(); }
|
||||
#ifdef ENABLE_BIGINT
|
||||
bool isBigInt() const { return value().isBigInt(); }
|
||||
#endif
|
||||
bool isObject() const { return value().isObject(); }
|
||||
bool isMagic() const { return value().isMagic(); }
|
||||
bool isMagic(JSWhyMagic why) const { return value().isMagic(why); }
|
||||
@ -1257,6 +1317,9 @@ class WrappedPtrOperations<JS::Value, Wrapper>
|
||||
double toDouble() const { return value().toDouble(); }
|
||||
JSString* toString() const { return value().toString(); }
|
||||
JS::Symbol* toSymbol() const { return value().toSymbol(); }
|
||||
#ifdef ENABLE_BIGINT
|
||||
JS::BigInt* toBigInt() const { return value().toBigInt(); }
|
||||
#endif
|
||||
JSObject& toObject() const { return value().toObject(); }
|
||||
JSObject* toObjectOrNull() const { return value().toObjectOrNull(); }
|
||||
gc::Cell* toGCThing() const { return value().toGCThing(); }
|
||||
@ -1294,6 +1357,9 @@ class MutableWrappedPtrOperations<JS::Value, Wrapper> : public WrappedPtrOperati
|
||||
bool setNumber(double d) { return value().setNumber(d); }
|
||||
void setString(JSString* str) { this->value().setString(str); }
|
||||
void setSymbol(JS::Symbol* sym) { this->value().setSymbol(sym); }
|
||||
#ifdef ENABLE_BIGINT
|
||||
void setBigInt(JS::BigInt* bi) { this->value().setBigInt(bi); }
|
||||
#endif
|
||||
void setObject(JSObject& obj) { this->value().setObject(obj); }
|
||||
void setObjectOrNull(JSObject* arg) { this->value().setObjectOrNull(arg); }
|
||||
void setPrivate(void* ptr) { this->value().setPrivate(ptr); }
|
||||
@ -1322,6 +1388,9 @@ class HeapBase<JS::Value, Wrapper> : public WrappedPtrOperations<JS::Value, Wrap
|
||||
void setMagic(JSWhyMagic why) { setBarriered(JS::MagicValue(why)); }
|
||||
void setString(JSString* str) { setBarriered(JS::StringValue(str)); }
|
||||
void setSymbol(JS::Symbol* sym) { setBarriered(JS::SymbolValue(sym)); }
|
||||
#ifdef ENABLE_BIGINT
|
||||
void setBigInt(JS::BigInt* bi) { setBarriered(JS::BigIntValue(bi)); }
|
||||
#endif
|
||||
void setObject(JSObject& obj) { setBarriered(JS::ObjectValue(obj)); }
|
||||
void setPrivateGCThing(js::gc::Cell* cell) { setBarriered(JS::PrivateGCThingValue(cell)); }
|
||||
|
||||
@ -1378,6 +1447,13 @@ DispatchTyped(F f, const JS::Value& val, Args&&... args)
|
||||
MOZ_ASSERT(gc::IsCellPointerValid(sym));
|
||||
return f(sym, mozilla::Forward<Args>(args)...);
|
||||
}
|
||||
#ifdef ENABLE_BIGINT
|
||||
if (val.isBigInt()) {
|
||||
JS::BigInt* bi = val.toBigInt();
|
||||
MOZ_ASSERT(gc::IsCellPointerValid(bi));
|
||||
return f(bi, mozilla::Forward<Args>(args)...);
|
||||
}
|
||||
#endif
|
||||
if (MOZ_UNLIKELY(val.isPrivateGCThing())) {
|
||||
MOZ_ASSERT(gc::IsCellPointerValid(val.toGCThing()));
|
||||
return DispatchTyped(f, val.toGCCellPtr(), mozilla::Forward<Args>(args)...);
|
||||
|
@ -39,6 +39,7 @@ doctest = false
|
||||
debugmozjs = ['mozjs_sys/debugmozjs']
|
||||
promises = ['mozjs_sys/promises']
|
||||
nonzero = []
|
||||
bigint = ['mozjs_sys/bigint']
|
||||
|
||||
[dependencies.mozjs_sys]
|
||||
path = "../src"
|
||||
|
@ -73,6 +73,10 @@ fn build_jsapi_bindings() {
|
||||
.clang_arg("-DJS_DEBUG");
|
||||
}
|
||||
|
||||
if cfg!(feature = "bigint") {
|
||||
builder = builder.clang_arg("-DENABLE_BIGINT");
|
||||
}
|
||||
|
||||
let include_dir = get_mozjs_include_dir();
|
||||
let include_dir = include_dir.to_str()
|
||||
.expect("Path to mozjs include dir should be utf-8");
|
||||
@ -99,6 +103,10 @@ fn build_jsapi_bindings() {
|
||||
builder = builder.whitelist_function(func);
|
||||
}
|
||||
|
||||
if cfg!(feature = "bigint") {
|
||||
builder = builder.whitelist_type("JS::BigInt");
|
||||
}
|
||||
|
||||
for ty in OPAQUE_TYPES {
|
||||
builder = builder.opaque_type(ty);
|
||||
}
|
||||
|
@ -25,6 +25,8 @@ enum ValueTag {
|
||||
UNDEFINED = JSVAL_TAG_MAX_DOUBLE | (JSValueType::JSVAL_TYPE_UNDEFINED as u32),
|
||||
STRING = JSVAL_TAG_MAX_DOUBLE | (JSValueType::JSVAL_TYPE_STRING as u32),
|
||||
SYMBOL = JSVAL_TAG_MAX_DOUBLE | (JSValueType::JSVAL_TYPE_SYMBOL as u32),
|
||||
#[cfg(feature = "bigint")]
|
||||
BIGINT = JSVAL_TAG_MAX_DOUBLE | (JSValueType::JSVAL_TYPE_BIGINT as u32),
|
||||
BOOLEAN = JSVAL_TAG_MAX_DOUBLE | (JSValueType::JSVAL_TYPE_BOOLEAN as u32),
|
||||
MAGIC = JSVAL_TAG_MAX_DOUBLE | (JSValueType::JSVAL_TYPE_MAGIC as u32),
|
||||
NULL = JSVAL_TAG_MAX_DOUBLE | (JSValueType::JSVAL_TYPE_NULL as u32),
|
||||
@ -41,6 +43,8 @@ enum ValueTag {
|
||||
UNDEFINED = JSVAL_TAG_CLEAR as u32 | (JSValueType::JSVAL_TYPE_UNDEFINED as u32),
|
||||
STRING = JSVAL_TAG_CLEAR as u32 | (JSValueType::JSVAL_TYPE_STRING as u32),
|
||||
SYMBOL = JSVAL_TAG_CLEAR as u32 | (JSValueType::JSVAL_TYPE_SYMBOL as u32),
|
||||
#[cfg(feature = "bigint")]
|
||||
BIGINT = JSVAL_TAG_CLEAR as u32 | (JSValueType::JSVAL_TYPE_BIGINT as u32),
|
||||
BOOLEAN = JSVAL_TAG_CLEAR as u32 | (JSValueType::JSVAL_TYPE_BOOLEAN as u32),
|
||||
MAGIC = JSVAL_TAG_CLEAR as u32 | (JSValueType::JSVAL_TYPE_MAGIC as u32),
|
||||
NULL = JSVAL_TAG_CLEAR as u32 | (JSValueType::JSVAL_TYPE_NULL as u32),
|
||||
@ -57,6 +61,8 @@ enum ValueShiftedTag {
|
||||
UNDEFINED = ((ValueTag::UNDEFINED as u64) << JSVAL_TAG_SHIFT),
|
||||
STRING = ((ValueTag::STRING as u64) << JSVAL_TAG_SHIFT),
|
||||
SYMBOL = ((ValueTag::SYMBOL as u64) << JSVAL_TAG_SHIFT),
|
||||
#[cfg(feature = "bigint")]
|
||||
BIGINT = ((ValueTag::BIGINT as u64) << JSVAL_TAG_SHIFT),
|
||||
BOOLEAN = ((ValueTag::BOOLEAN as u64) << JSVAL_TAG_SHIFT),
|
||||
MAGIC = ((ValueTag::MAGIC as u64) << JSVAL_TAG_SHIFT),
|
||||
NULL = ((ValueTag::NULL as u64) << JSVAL_TAG_SHIFT),
|
||||
@ -187,6 +193,23 @@ pub fn PrivateValue(o: *const c_void) -> JS::Value {
|
||||
BuildJSVal(ValueTag::PRIVATE, ptrBits)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
#[cfg(feature = "bigint")]
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
pub fn BigIntValue(b: &JS::BigInt) -> JS::Value {
|
||||
let bits = b as *const JS::BigInt as usize as u64;
|
||||
assert!((bits >> JSVAL_TAG_SHIFT) == 0);
|
||||
BuildJSVal(ValueTag::BIGINT, bits)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
#[cfg(target_pointer_width = "32")]
|
||||
#[inline(always)]
|
||||
pub fn BigIntValue(s: &JS::BigInt) -> JS::Value {
|
||||
let bits = s as *const JS::BigInt as usize as u64;
|
||||
BuildJSVal(ValueTag::BIGINT, bits)
|
||||
}
|
||||
|
||||
impl JS::Value {
|
||||
#[inline(always)]
|
||||
unsafe fn asBits(&self) -> u64 {
|
||||
@ -363,6 +386,24 @@ impl JS::Value {
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
#[cfg(feature = "bigint")]
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
pub fn is_bigint(&self) -> bool {
|
||||
unsafe {
|
||||
(self.asBits() >> JSVAL_TAG_SHIFT) == ValueTag::BIGINT as u64
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
#[cfg(feature = "bigint")]
|
||||
#[cfg(target_pointer_width = "32")]
|
||||
pub fn is_bigint(&self) -> bool {
|
||||
unsafe {
|
||||
(self.asBits() >> 32) == ValueTag::BIGINT as u64
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
pub fn to_boolean(&self) -> bool {
|
||||
|
@ -306,6 +306,12 @@ impl RootKind for *mut JS::Symbol {
|
||||
fn rootKind() -> JS::RootKind { JS::RootKind::Symbol }
|
||||
}
|
||||
|
||||
#[cfg(feature = "bigint")]
|
||||
impl RootKind for *mut JS::BigInt {
|
||||
#[inline(always)]
|
||||
fn rootKind() -> JS::RootKind { JS::RootKind::BigInt }
|
||||
}
|
||||
|
||||
impl RootKind for *mut JSScript {
|
||||
#[inline(always)]
|
||||
fn rootKind() -> JS::RootKind { JS::RootKind::Script }
|
||||
|
@ -8,6 +8,7 @@ build = "build.rs"
|
||||
[features]
|
||||
debugmozjs = []
|
||||
promises = []
|
||||
bigint = []
|
||||
|
||||
[lib]
|
||||
name = "mozjs_sys"
|
||||
|
@ -47,6 +47,9 @@ class PropertyResult;
|
||||
|
||||
enum class SymbolCode: uint32_t;
|
||||
|
||||
#ifdef ENABLE_BIGINT
|
||||
class BigInt;
|
||||
#endif
|
||||
} // namespace JS
|
||||
|
||||
// Do the importing.
|
||||
@ -112,6 +115,9 @@ using JS::RootedObject;
|
||||
using JS::RootedScript;
|
||||
using JS::RootedString;
|
||||
using JS::RootedSymbol;
|
||||
#ifdef ENABLE_BIGINT
|
||||
using JS::RootedBigInt;
|
||||
#endif
|
||||
using JS::RootedValue;
|
||||
|
||||
using JS::PersistentRooted;
|
||||
@ -121,6 +127,9 @@ using JS::PersistentRootedObject;
|
||||
using JS::PersistentRootedScript;
|
||||
using JS::PersistentRootedString;
|
||||
using JS::PersistentRootedSymbol;
|
||||
#ifdef ENABLE_BIGINT
|
||||
using JS::PersistentRootedBigInt;
|
||||
#endif
|
||||
using JS::PersistentRootedValue;
|
||||
|
||||
using JS::Handle;
|
||||
@ -130,6 +139,9 @@ using JS::HandleObject;
|
||||
using JS::HandleScript;
|
||||
using JS::HandleString;
|
||||
using JS::HandleSymbol;
|
||||
#ifdef ENABLE_BIGINT
|
||||
using JS::HandleBigInt;
|
||||
#endif
|
||||
using JS::HandleValue;
|
||||
|
||||
using JS::MutableHandle;
|
||||
@ -139,6 +151,9 @@ using JS::MutableHandleObject;
|
||||
using JS::MutableHandleScript;
|
||||
using JS::MutableHandleString;
|
||||
using JS::MutableHandleSymbol;
|
||||
#ifdef ENABLE_BIGINT
|
||||
using JS::MutableHandleBigInt;
|
||||
#endif
|
||||
using JS::MutableHandleValue;
|
||||
|
||||
using JS::NullHandleValue;
|
||||
@ -157,6 +172,9 @@ using JS::Zone;
|
||||
using JS::Symbol;
|
||||
using JS::SymbolCode;
|
||||
|
||||
#ifdef ENABLE_BIGINT
|
||||
using JS::BigInt;
|
||||
#endif
|
||||
} /* namespace js */
|
||||
|
||||
#endif /* NamespaceImports_h */
|
||||
|
@ -16,11 +16,9 @@ fn main() {
|
||||
env::set_var("MAKEFLAGS", format!("-j{}", num_cpus::get()));
|
||||
env::set_current_dir(&js_src).unwrap();
|
||||
|
||||
let variant = if cfg!(feature = "debugmozjs") {
|
||||
"plaindebug"
|
||||
} else {
|
||||
"plain"
|
||||
};
|
||||
let variant = format!("{}{}",
|
||||
if cfg!(feature = "bigint") { "bigint" } else { "plain" },
|
||||
if cfg!(feature = "debugmozjs") { "debug" } else { "" });
|
||||
|
||||
let python = env::var("PYTHON").unwrap_or("python2.7".into());
|
||||
let mut cmd = Command::new(&python);
|
||||
@ -36,7 +34,7 @@ fn main() {
|
||||
// already exists but wasn't created by autospider.
|
||||
"--dep",
|
||||
"--objdir", &out_dir,
|
||||
variant])
|
||||
&variant])
|
||||
.env("SOURCE", &js_src)
|
||||
.env("PWD", &js_src)
|
||||
.stdout(Stdio::inherit())
|
||||
@ -54,6 +52,10 @@ fn main() {
|
||||
println!("cargo:rustc-link-search=native={}/dist/bin", out_dir);
|
||||
println!("cargo:rustc-link-lib=nspr4");
|
||||
|
||||
if cfg!(feature = "bigint") {
|
||||
println!("cargo:rustc-link-lib=gmp");
|
||||
}
|
||||
|
||||
if target.contains("windows") {
|
||||
println!("cargo:rustc-link-lib=winmm");
|
||||
if target.contains("gnu") {
|
||||
|
@ -1272,6 +1272,12 @@ ArrayJoinDenseKernel(JSContext* cx, SeparatorOp sepOp, HandleNativeObject obj, u
|
||||
* with those as well.
|
||||
*/
|
||||
break;
|
||||
} else if (IF_BIGINT(elem.isBigInt(), false)) {
|
||||
// ToString(bigint) doesn't access bigint.toString or
|
||||
// anything like that, so it can't mutate the array we're
|
||||
// walking through, so it *could* be handled here. We don't
|
||||
// do so yet for reasons of initial-implementation economy.
|
||||
break;
|
||||
} else {
|
||||
MOZ_ASSERT(elem.isMagic(JS_ELEMENTS_HOLE) || elem.isNullOrUndefined());
|
||||
}
|
||||
|
@ -15,6 +15,9 @@
|
||||
|
||||
#include "jit/InlinableNatives.h"
|
||||
#include "util/StringBuffer.h"
|
||||
#ifdef ENABLE_BIGINT
|
||||
#include "vm/BigIntType.h"
|
||||
#endif
|
||||
#include "vm/GlobalObject.h"
|
||||
#include "vm/JSAtom.h"
|
||||
#include "vm/JSContext.h"
|
||||
@ -164,6 +167,10 @@ js::ToBooleanSlow(HandleValue v)
|
||||
{
|
||||
if (v.isString())
|
||||
return v.toString()->length() != 0;
|
||||
#ifdef ENABLE_BIGINT
|
||||
if (v.isBigInt())
|
||||
return v.toBigInt()->toBoolean();
|
||||
#endif
|
||||
|
||||
MOZ_ASSERT(v.isObject());
|
||||
return !EmulatesUndefined(&v.toObject());
|
||||
|
@ -587,6 +587,13 @@ Str(JSContext* cx, const Value& v, StringifyContext* scx)
|
||||
return NumberValueToStringBuffer(cx, v, scx->sb);
|
||||
}
|
||||
|
||||
#ifdef ENABLE_BIGINT
|
||||
if (v.isBigInt()) {
|
||||
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_BIGINT_NOT_SERIALIZABLE);
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Step 10. */
|
||||
MOZ_ASSERT(v.isObject());
|
||||
RootedObject obj(cx, &v.toObject());
|
||||
|
@ -57,7 +57,8 @@ HashableValue::setValue(JSContext* cx, HandleValue v)
|
||||
}
|
||||
|
||||
MOZ_ASSERT(value.isUndefined() || value.isNull() || value.isBoolean() || value.isNumber() ||
|
||||
value.isString() || value.isSymbol() || value.isObject());
|
||||
value.isString() || value.isSymbol() || value.isObject() ||
|
||||
IF_BIGINT(value.isBigInt(), false));
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -77,6 +78,10 @@ HashValue(const Value& v, const mozilla::HashCodeScrambler& hcs)
|
||||
return v.toString()->asAtom().hash();
|
||||
if (v.isSymbol())
|
||||
return v.toSymbol()->hash();
|
||||
#ifdef ENABLE_BIGINT
|
||||
if (v.isBigInt())
|
||||
return v.toBigInt()->hash();
|
||||
#endif
|
||||
if (v.isObject())
|
||||
return hcs.scramble(v.asRawBits());
|
||||
|
||||
@ -96,12 +101,24 @@ HashableValue::operator==(const HashableValue& other) const
|
||||
// Two HashableValues are equal if they have equal bits.
|
||||
bool b = (value.asRawBits() == other.value.asRawBits());
|
||||
|
||||
#ifdef ENABLE_BIGINT
|
||||
// BigInt values are considered equal if they represent the same
|
||||
// integer. This test should use a comparison function that doesn't
|
||||
// require a JSContext once one is defined in the BigInt class.
|
||||
if (!b && (value.isBigInt() && other.value.isBigInt())) {
|
||||
JSContext* cx = TlsContext.get();
|
||||
RootedValue valueRoot(cx, value);
|
||||
RootedValue otherRoot(cx, other.value);
|
||||
SameValue(cx, valueRoot, otherRoot, &b);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
bool same;
|
||||
JSContext* cx = TlsContext.get();
|
||||
RootedValue valueRoot(cx, value);
|
||||
RootedValue otherRoot(cx, other.value);
|
||||
MOZ_ASSERT(SameValue(nullptr, valueRoot, otherRoot, &same));
|
||||
MOZ_ASSERT(SameValue(cx, valueRoot, otherRoot, &same));
|
||||
MOZ_ASSERT(same == b);
|
||||
#endif
|
||||
return b;
|
||||
|
7
js/src/devtools/automation/variants/bigint
Normal file
7
js/src/devtools/automation/variants/bigint
Normal file
@ -0,0 +1,7 @@
|
||||
{
|
||||
"configure-args": "--enable-bigint",
|
||||
"optimize": true,
|
||||
"env": {
|
||||
"JSTESTS_EXTRA_ARGS": "--jitflags=all"
|
||||
}
|
||||
}
|
7
js/src/devtools/automation/variants/bigintdebug
Normal file
7
js/src/devtools/automation/variants/bigintdebug
Normal file
@ -0,0 +1,7 @@
|
||||
{
|
||||
"configure-args": "--enable-bigint",
|
||||
"debug": true,
|
||||
"env": {
|
||||
"JSTESTS_EXTRA_ARGS": "--jitflags=debug"
|
||||
}
|
||||
}
|
@ -64,6 +64,7 @@ namespace gc {
|
||||
D(FAT_INLINE_ATOM, String, js::FatInlineAtom, js::FatInlineAtom, true, false) \
|
||||
D(ATOM, String, js::NormalAtom, js::NormalAtom, true, false) \
|
||||
D(SYMBOL, Symbol, JS::Symbol, JS::Symbol, true, false) \
|
||||
IF_BIGINT(D(BIGINT, BigInt, JS::BigInt, JS::BigInt, true, false),) \
|
||||
D(JITCODE, JitCode, js::jit::JitCode, js::jit::JitCode, false, false) \
|
||||
D(SCOPE, Scope, js::Scope, js::Scope, true, false) \
|
||||
D(REGEXP_SHARED, RegExpShared, js::RegExpShared, js::RegExpShared, true, false)
|
||||
|
@ -190,7 +190,10 @@ AtomMarkingRuntime::markAtomValue(JSContext* cx, const Value& value)
|
||||
markAtom(cx, value.toSymbol());
|
||||
return;
|
||||
}
|
||||
MOZ_ASSERT_IF(value.isGCThing(), value.isObject() || value.isPrivateGCThing());
|
||||
MOZ_ASSERT_IF(value.isGCThing(),
|
||||
value.isObject() ||
|
||||
value.isPrivateGCThing() ||
|
||||
IF_BIGINT(value.isBigInt(), false));
|
||||
}
|
||||
|
||||
void
|
||||
@ -272,7 +275,10 @@ AtomMarkingRuntime::valueIsMarked(Zone* zone, const Value& value)
|
||||
if (value.isSymbol())
|
||||
return atomIsMarked(zone, value.toSymbol());
|
||||
|
||||
MOZ_ASSERT_IF(value.isGCThing(), value.isObject() || value.isPrivateGCThing());
|
||||
MOZ_ASSERT_IF(value.isGCThing(),
|
||||
value.isObject() ||
|
||||
value.isPrivateGCThing() ||
|
||||
IF_BIGINT(value.isBigInt(), false));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -8,6 +8,9 @@
|
||||
#define gc_DeletePolicy_h
|
||||
|
||||
#include "js/TracingAPI.h"
|
||||
#ifdef ENABLE_BIGINT
|
||||
#include "vm/BigIntType.h"
|
||||
#endif
|
||||
|
||||
namespace js {
|
||||
namespace gc {
|
||||
@ -26,6 +29,9 @@ struct ClearEdgesTracer : public JS::CallbackTracer
|
||||
void onObjectEdge(JSObject** objp) override;
|
||||
void onStringEdge(JSString** strp) override;
|
||||
void onSymbolEdge(JS::Symbol** symp) override;
|
||||
#ifdef ENABLE_BIGINT
|
||||
void onBigIntEdge(JS::BigInt** bip) override;
|
||||
#endif
|
||||
void onScriptEdge(JSScript** scriptp) override;
|
||||
void onShapeEdge(js::Shape** shapep) override;
|
||||
void onObjectGroupEdge(js::ObjectGroup** groupp) override;
|
||||
|
@ -224,6 +224,9 @@
|
||||
#include "js/SliceBudget.h"
|
||||
#include "proxy/DeadObjectProxy.h"
|
||||
#include "util/Windows.h"
|
||||
#ifdef ENABLE_BIGINT
|
||||
#include "vm/BigIntType.h"
|
||||
#endif
|
||||
#include "vm/Debugger.h"
|
||||
#include "vm/GeckoProfiler.h"
|
||||
#include "vm/JSAtom.h"
|
||||
@ -495,7 +498,10 @@ static const FinalizePhase BackgroundFinalizePhases[] = {
|
||||
AllocKind::EXTERNAL_STRING,
|
||||
AllocKind::FAT_INLINE_ATOM,
|
||||
AllocKind::ATOM,
|
||||
AllocKind::SYMBOL
|
||||
AllocKind::SYMBOL,
|
||||
#ifdef ENABLE_BIGINT
|
||||
AllocKind::BIGINT
|
||||
#endif
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -8436,6 +8442,10 @@ JS::GCCellPtr::GCCellPtr(const Value& v)
|
||||
ptr = checkedCast(&v.toObject(), JS::TraceKind::Object);
|
||||
else if (v.isSymbol())
|
||||
ptr = checkedCast(v.toSymbol(), JS::TraceKind::Symbol);
|
||||
#ifdef ENABLE_BIGINT
|
||||
else if (v.isBigInt())
|
||||
ptr = checkedCast(v.toBigInt(), JS::TraceKind::BigInt);
|
||||
#endif
|
||||
else if (v.isPrivateGCThing())
|
||||
ptr = checkedCast(v.toGCThing(), v.toGCThing()->getTraceKind());
|
||||
else
|
||||
@ -9138,6 +9148,9 @@ js::gc::ClearEdgesTracer::clearEdge(S** thingp)
|
||||
void js::gc::ClearEdgesTracer::onObjectEdge(JSObject** objp) { clearEdge(objp); }
|
||||
void js::gc::ClearEdgesTracer::onStringEdge(JSString** strp) { clearEdge(strp); }
|
||||
void js::gc::ClearEdgesTracer::onSymbolEdge(JS::Symbol** symp) { clearEdge(symp); }
|
||||
#ifdef ENABLE_BIGINT
|
||||
void js::gc::ClearEdgesTracer::onBigIntEdge(JS::BigInt** bip) { clearEdge(bip); }
|
||||
#endif
|
||||
void js::gc::ClearEdgesTracer::onScriptEdge(JSScript** scriptp) { clearEdge(scriptp); }
|
||||
void js::gc::ClearEdgesTracer::onShapeEdge(js::Shape** shapep) { clearEdge(shapep); }
|
||||
void js::gc::ClearEdgesTracer::onObjectGroupEdge(js::ObjectGroup** groupp) { clearEdge(groupp); }
|
||||
|
@ -11,6 +11,10 @@
|
||||
|
||||
#include "gc/RelocationOverlay.h"
|
||||
|
||||
#ifdef ENABLE_BIGINT
|
||||
#include "vm/BigIntType.h"
|
||||
#endif
|
||||
|
||||
namespace js {
|
||||
namespace gc {
|
||||
|
||||
|
@ -21,6 +21,9 @@
|
||||
#include "js/SliceBudget.h"
|
||||
#include "vm/ArgumentsObject.h"
|
||||
#include "vm/ArrayObject.h"
|
||||
#ifdef ENABLE_BIGINT
|
||||
#include "vm/BigIntType.h"
|
||||
#endif
|
||||
#include "vm/Debugger.h"
|
||||
#include "vm/EnvironmentObject.h"
|
||||
#include "vm/RegExpObject.h"
|
||||
@ -894,6 +897,9 @@ js::GCMarker::markAndTraceChildren(T* thing)
|
||||
namespace js {
|
||||
template <> void GCMarker::traverse(BaseShape* thing) { markAndTraceChildren(thing); }
|
||||
template <> void GCMarker::traverse(JS::Symbol* thing) { markAndTraceChildren(thing); }
|
||||
#ifdef ENABLE_BIGINT
|
||||
template <> void GCMarker::traverse(JS::BigInt* thing) { markAndTraceChildren(thing); }
|
||||
#endif
|
||||
template <> void GCMarker::traverse(RegExpShared* thing) { markAndTraceChildren(thing); }
|
||||
} // namespace js
|
||||
|
||||
@ -1550,6 +1556,14 @@ js::GCMarker::lazilyMarkChildren(ObjectGroup* group)
|
||||
traverseEdge(group, static_cast<JSObject*>(fun));
|
||||
}
|
||||
|
||||
#ifdef ENABLE_BIGINT
|
||||
void
|
||||
JS::BigInt::traceChildren(JSTracer* trc)
|
||||
{
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
struct TraverseObjectFunctor
|
||||
{
|
||||
template <typename T>
|
||||
@ -1694,7 +1708,8 @@ ObjectDenseElementsMayBeMarkable(NativeObject* nobj)
|
||||
return true;
|
||||
|
||||
static const uint32_t flagMask =
|
||||
TYPE_FLAG_STRING | TYPE_FLAG_SYMBOL | TYPE_FLAG_LAZYARGS | TYPE_FLAG_ANYOBJECT;
|
||||
TYPE_FLAG_STRING | TYPE_FLAG_SYMBOL | TYPE_FLAG_LAZYARGS | TYPE_FLAG_ANYOBJECT |
|
||||
IF_BIGINT(TYPE_FLAG_BIGINT, 0);
|
||||
bool mayBeMarkable = typeSet->hasAnyFlag(flagMask) || typeSet->getObjectCount() != 0;
|
||||
|
||||
#ifdef DEBUG
|
||||
@ -1808,7 +1823,13 @@ GCMarker::processMarkStackTop(SliceBudget& budget)
|
||||
}
|
||||
} else if (v.isSymbol()) {
|
||||
traverseEdge(obj, v.toSymbol());
|
||||
} else if (v.isPrivateGCThing()) {
|
||||
}
|
||||
#ifdef ENABLE_BIGINT
|
||||
else if (v.isBigInt()) {
|
||||
traverseEdge(obj, v.toBigInt());
|
||||
}
|
||||
#endif
|
||||
else if (v.isPrivateGCThing()) {
|
||||
// v.toGCCellPtr cannot be inlined, so construct one manually.
|
||||
Cell* cell = v.toGCThing();
|
||||
traverseEdge(obj, JS::GCCellPtr(cell, cell->getTraceKind()));
|
||||
|
@ -109,6 +109,9 @@ struct RewrapTaggedPointer{};
|
||||
DECLARE_REWRAP(JS::Value, JSObject, JS::ObjectOrNullValue, );
|
||||
DECLARE_REWRAP(JS::Value, JSString, JS::StringValue, );
|
||||
DECLARE_REWRAP(JS::Value, JS::Symbol, JS::SymbolValue, );
|
||||
#ifdef ENABLE_BIGINT
|
||||
DECLARE_REWRAP(JS::Value, JS::BigInt, JS::BigIntValue, );
|
||||
#endif
|
||||
DECLARE_REWRAP(jsid, JSString, NON_INTEGER_ATOM_TO_JSID, (JSAtom*));
|
||||
DECLARE_REWRAP(jsid, JS::Symbol, SYMBOL_TO_JSID, );
|
||||
DECLARE_REWRAP(js::TaggedProto, JSObject, js::TaggedProto, );
|
||||
@ -119,7 +122,11 @@ struct IsPrivateGCThingInValue
|
||||
: public mozilla::EnableIf<mozilla::IsBaseOf<Cell, T>::value &&
|
||||
!mozilla::IsBaseOf<JSObject, T>::value &&
|
||||
!mozilla::IsBaseOf<JSString, T>::value &&
|
||||
!mozilla::IsBaseOf<JS::Symbol, T>::value, T>
|
||||
!mozilla::IsBaseOf<JS::Symbol, T>::value
|
||||
#ifdef ENABLE_BIGINT
|
||||
&& !mozilla::IsBaseOf<JS::BigInt, T>::value
|
||||
#endif
|
||||
, T>
|
||||
{
|
||||
static_assert(!mozilla::IsSame<Cell, T>::value && !mozilla::IsSame<TenuredCell, T>::value,
|
||||
"T must not be Cell or TenuredCell");
|
||||
|
@ -16,6 +16,9 @@
|
||||
#include "gc/PublicIterators.h"
|
||||
#include "gc/Zone.h"
|
||||
#include "util/Text.h"
|
||||
#ifdef ENABLE_BIGINT
|
||||
#include "vm/BigIntType.h"
|
||||
#endif
|
||||
#include "vm/JSFunction.h"
|
||||
#include "vm/JSScript.h"
|
||||
#include "vm/Shape.h"
|
||||
@ -396,6 +399,12 @@ JS_GetTraceThingInfo(char* buf, size_t bufsize, JSTracer* trc, void* thing,
|
||||
name = "symbol";
|
||||
break;
|
||||
|
||||
#ifdef ENABLE_BIGINT
|
||||
case JS::TraceKind::BigInt:
|
||||
name = "BigInt";
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
name = "INVALID";
|
||||
break;
|
||||
|
@ -69,6 +69,13 @@ def assert_subprinter_registered(printer, subprinter):
|
||||
"'info pretty-printer' says:\n"
|
||||
"%s" % (printer, subprinter, output))
|
||||
|
||||
enable_bigint = False
|
||||
try:
|
||||
if gdb.lookup_type('JS::BigInt'):
|
||||
enable_bigint = True
|
||||
except:
|
||||
pass
|
||||
|
||||
# Request full stack traces for Python errors.
|
||||
gdb.execute('set python print-stack full')
|
||||
|
||||
|
@ -146,6 +146,15 @@ class JSValueTypeCache(object):
|
||||
self.NULL = get('JSVAL_TYPE_NULL')
|
||||
self.OBJECT = get('JSVAL_TYPE_OBJECT')
|
||||
|
||||
self.enable_bigint = False
|
||||
try:
|
||||
# Looking up the tag will throw an exception if BigInt is not
|
||||
# enabled.
|
||||
self.BIGINT = get('JSVAL_TYPE_BIGINT')
|
||||
self.enable_bigint = True
|
||||
except:
|
||||
pass
|
||||
|
||||
# Let self.magic_names be an array whose i'th element is the name of
|
||||
# the i'th magic value.
|
||||
d = gdb.types.make_enum_dict(gdb.lookup_type('JSWhyMagic'))
|
||||
@ -198,6 +207,8 @@ class JSValue(object):
|
||||
value = self.box.as_address().cast(self.cache.JSObject_ptr_t)
|
||||
elif tag == self.jtc.SYMBOL:
|
||||
value = self.box.as_address().cast(self.cache.JSSymbol_ptr_t)
|
||||
elif self.jtc.enable_bigint and tag == self.jtc.BIGINT:
|
||||
return '$JS::BigIntValue()'
|
||||
else:
|
||||
value = 'unrecognized!'
|
||||
return '$JS::Value(%s)' % (value,)
|
||||
|
@ -1,6 +1,10 @@
|
||||
#include "gdb-tests.h"
|
||||
#include "jsapi.h"
|
||||
|
||||
#ifdef ENABLE_BIGINT
|
||||
#include "vm/BigIntType.h"
|
||||
#endif
|
||||
|
||||
FRAGMENT(jsval, simple) {
|
||||
using namespace JS;
|
||||
|
||||
@ -18,6 +22,9 @@ FRAGMENT(jsval, simple) {
|
||||
RootedString hello(cx, JS_NewStringCopyZ(cx, "Hello!"));
|
||||
RootedValue friendly_string(cx, StringValue(hello));
|
||||
RootedValue symbol(cx, SymbolValue(GetSymbolFor(cx, hello)));
|
||||
#ifdef ENABLE_BIGINT
|
||||
RootedValue bi(cx, BigIntValue(BigInt::create(cx)));
|
||||
#endif
|
||||
|
||||
RootedValue global(cx);
|
||||
global.setObject(*CurrentGlobalOrNull(cx));
|
||||
@ -38,5 +45,8 @@ FRAGMENT(jsval, simple) {
|
||||
use(empty_string);
|
||||
use(friendly_string);
|
||||
use(symbol);
|
||||
#ifdef ENABLE_BIGINT
|
||||
use(bi);
|
||||
#endif
|
||||
use(global);
|
||||
}
|
||||
|
@ -15,5 +15,7 @@ assert_pretty('elements_hole', '$JS::MagicValue(JS_ELEMENTS_HOLE)')
|
||||
assert_pretty('empty_string', '$JS::Value("")')
|
||||
assert_pretty('friendly_string', '$JS::Value("Hello!")')
|
||||
assert_pretty('symbol', '$JS::Value(Symbol.for("Hello!"))')
|
||||
if enable_bigint:
|
||||
assert_pretty('bi', '$JS::BigIntValue()')
|
||||
assert_pretty('global', '$JS::Value((JSObject *) [object global] delegate)')
|
||||
assert_pretty('onehundredthirtysevenonehundredtwentyeighths', '$JS::DoubleValue(1.0703125)')
|
||||
|
@ -647,3 +647,12 @@ MSG_DEF(JSMSG_BAD_RESPONSE_MIME_TYPE, 0, JSEXN_TYPEERR, "Res
|
||||
MSG_DEF(JSMSG_BAD_RESPONSE_CORS_SAME_ORIGIN, 0, JSEXN_TYPEERR, "Response.type must be 'basic', 'cors' or 'default'")
|
||||
MSG_DEF(JSMSG_BAD_RESPONSE_STATUS, 0, JSEXN_TYPEERR, "Response does not have ok status")
|
||||
MSG_DEF(JSMSG_RESPONSE_ALREADY_CONSUMED, 0, JSEXN_TYPEERR, "Response already consumed")
|
||||
|
||||
// BigInt
|
||||
MSG_DEF(JSMSG_BIGINT_TO_NUMBER, 0, JSEXN_TYPEERR, "can't convert BigInt to number")
|
||||
MSG_DEF(JSMSG_NUMBER_TO_BIGINT, 0, JSEXN_RANGEERR, "can't convert non-finite number to BigInt")
|
||||
MSG_DEF(JSMSG_BIGINT_DIVISION_BY_ZERO, 0, JSEXN_RANGEERR, "BigInt division by zero")
|
||||
MSG_DEF(JSMSG_BIGINT_NEGATIVE_EXPONENT, 0, JSEXN_RANGEERR, "BigInt negative exponent")
|
||||
MSG_DEF(JSMSG_BIGINT_INVALID_SYNTAX, 0, JSEXN_SYNTAXERR, "invalid BigInt syntax")
|
||||
MSG_DEF(JSMSG_NOT_BIGINT, 0, JSEXN_TYPEERR, "not a BigInt")
|
||||
MSG_DEF(JSMSG_BIGINT_NOT_SERIALIZABLE, 0, JSEXN_TYPEERR, "BigInt value can't be serialized in JSON")
|
||||
|
@ -1591,9 +1591,21 @@ js::ToNumberSlow(JSContext* cx, HandleValue v_, double* out)
|
||||
return false;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(v.isUndefined());
|
||||
*out = GenericNaN();
|
||||
return true;
|
||||
if (v.isUndefined()) {
|
||||
*out = GenericNaN();
|
||||
return true;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(v.isSymbol() || IF_BIGINT(v.isBigInt(), false));
|
||||
if (!cx->helperThread()) {
|
||||
unsigned errnum = JSMSG_SYMBOL_TO_NUMBER;
|
||||
#ifdef ENABLE_BIGINT
|
||||
if (v.isBigInt())
|
||||
errnum = JSMSG_BIGINT_TO_NUMBER;
|
||||
#endif
|
||||
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, errnum);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -49,6 +49,9 @@ enum JSType {
|
||||
JSTYPE_BOOLEAN, /* boolean */
|
||||
JSTYPE_NULL, /* null */
|
||||
JSTYPE_SYMBOL, /* symbol */
|
||||
#ifdef ENABLE_BIGINT
|
||||
JSTYPE_BIGINT, /* BigInt */
|
||||
#endif
|
||||
JSTYPE_LIMIT
|
||||
};
|
||||
|
||||
|
@ -458,6 +458,11 @@ SOURCES += [
|
||||
'vm/ProfilingStack.cpp',
|
||||
]
|
||||
|
||||
if CONFIG['ENABLE_BIGINT']:
|
||||
SOURCES += [
|
||||
'vm/BigIntType.cpp',
|
||||
]
|
||||
|
||||
if CONFIG['JS_POSIX_NSPR']:
|
||||
UNIFIED_SOURCES += [
|
||||
'vm/PosixNSPR.cpp',
|
||||
|
@ -164,6 +164,14 @@ js::ValueToStringBufferSlow(JSContext* cx, const Value& arg, StringBuffer& sb)
|
||||
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_SYMBOL_TO_STRING);
|
||||
return false;
|
||||
}
|
||||
#ifdef ENABLE_BIGINT
|
||||
if (v.isBigInt()) {
|
||||
JSString* str = BigInt::toString(cx, v.toBigInt());
|
||||
if (!str)
|
||||
return false;
|
||||
return sb.append(str);
|
||||
}
|
||||
#endif
|
||||
MOZ_ASSERT(v.isUndefined());
|
||||
return sb.append(cx->names().undefined);
|
||||
}
|
||||
|
83
js/src/vm/BigIntType.cpp
Normal file
83
js/src/vm/BigIntType.cpp
Normal file
@ -0,0 +1,83 @@
|
||||
/* -*- 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 "vm/BigIntType.h"
|
||||
|
||||
#include "mozilla/FloatingPoint.h"
|
||||
#include "mozilla/HashFunctions.h"
|
||||
|
||||
#include "jsapi.h"
|
||||
|
||||
#include "gc/Allocator.h"
|
||||
#include "gc/Tracer.h"
|
||||
#include "vm/JSContext.h"
|
||||
#include "vm/SelfHosting.h"
|
||||
|
||||
using namespace js;
|
||||
|
||||
BigInt*
|
||||
BigInt::create(JSContext* cx)
|
||||
{
|
||||
BigInt* x = Allocate<BigInt>(cx);
|
||||
if (!x)
|
||||
return nullptr;
|
||||
return x;
|
||||
}
|
||||
|
||||
BigInt*
|
||||
BigInt::copy(JSContext* cx, HandleBigInt x)
|
||||
{
|
||||
BigInt* bi = create(cx);
|
||||
if (!bi)
|
||||
return nullptr;
|
||||
return bi;
|
||||
}
|
||||
|
||||
JSLinearString*
|
||||
BigInt::toString(JSContext* cx, BigInt* x)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
BigInt::finalize(js::FreeOp* fop)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
JSAtom*
|
||||
js::BigIntToAtom(JSContext* cx, BigInt* bi)
|
||||
{
|
||||
JSString* str = BigInt::toString(cx, bi);
|
||||
if (!str)
|
||||
return nullptr;
|
||||
return AtomizeString(cx, str);
|
||||
}
|
||||
|
||||
bool
|
||||
BigInt::toBoolean()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
js::HashNumber
|
||||
BigInt::hash()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t
|
||||
BigInt::sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
JS::ubi::Node::Size
|
||||
JS::ubi::Concrete<BigInt>::size(mozilla::MallocSizeOf mallocSizeOf) const
|
||||
{
|
||||
MOZ_ASSERT(get().isTenured());
|
||||
return js::gc::Arena::thingSize(get().asTenured().getAllocKind());
|
||||
}
|
60
js/src/vm/BigIntType.h
Normal file
60
js/src/vm/BigIntType.h
Normal file
@ -0,0 +1,60 @@
|
||||
/* -*- 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 vm_BigIntType_h
|
||||
#define vm_BigIntType_h
|
||||
|
||||
#include "gc/Barrier.h"
|
||||
#include "gc/GC.h"
|
||||
#include "gc/Heap.h"
|
||||
#include "js/AllocPolicy.h"
|
||||
#include "js/GCHashTable.h"
|
||||
#include "js/RootingAPI.h"
|
||||
#include "js/TypeDecls.h"
|
||||
#include "vm/StringType.h"
|
||||
|
||||
namespace JS {
|
||||
|
||||
class BigInt final : public js::gc::TenuredCell
|
||||
{
|
||||
private:
|
||||
// The minimum allocation size is currently 16 bytes (see
|
||||
// SortedArenaList in gc/ArenaList.h).
|
||||
uint8_t unused_[js::gc::MinCellSize];
|
||||
|
||||
public:
|
||||
// Allocate and initialize a BigInt value
|
||||
static BigInt* create(JSContext* cx);
|
||||
|
||||
static const JS::TraceKind TraceKind = JS::TraceKind::BigInt;
|
||||
|
||||
void traceChildren(JSTracer* trc);
|
||||
|
||||
void finalize(js::FreeOp* fop);
|
||||
|
||||
js::HashNumber hash();
|
||||
|
||||
size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const;
|
||||
|
||||
static JSLinearString* toString(JSContext* cx, BigInt* x);
|
||||
bool toBoolean();
|
||||
|
||||
static BigInt* copy(JSContext* cx, Handle<BigInt*> x);
|
||||
};
|
||||
|
||||
static_assert(sizeof(BigInt) >= js::gc::MinCellSize,
|
||||
"sizeof(BigInt) must be greater than the minimum allocation size");
|
||||
|
||||
} // namespace JS
|
||||
|
||||
namespace js {
|
||||
|
||||
extern JSAtom*
|
||||
BigIntToAtom(JSContext* cx, JS::BigInt* bi);
|
||||
|
||||
} // namespace js
|
||||
|
||||
#endif
|
@ -464,6 +464,7 @@
|
||||
macro(boolean, boolean, "boolean") \
|
||||
macro(null, null, "null") \
|
||||
macro(symbol, symbol, "symbol") \
|
||||
macro(defineDataPropertyIntrinsic, defineDataPropertyIntrinsic, "_DefineDataProperty") \
|
||||
macro(bigint, bigint, "bigint") \
|
||||
macro(defineDataPropertyIntrinsic, defineDataPropertyIntrinsic, "_DefineDataProperty")
|
||||
|
||||
#endif /* vm_CommonPropertyNames_h */
|
||||
|
@ -32,6 +32,9 @@
|
||||
#include "util/StringBuffer.h"
|
||||
#include "vm/AsyncFunction.h"
|
||||
#include "vm/AsyncIteration.h"
|
||||
#ifdef ENABLE_BIGINT
|
||||
#include "vm/BigIntType.h"
|
||||
#endif
|
||||
#include "vm/BytecodeUtil.h"
|
||||
#include "vm/Debugger.h"
|
||||
#include "vm/GeneratorObject.h"
|
||||
@ -969,6 +972,10 @@ js::TypeOfValue(const Value& v)
|
||||
return TypeOfObject(&v.toObject());
|
||||
if (v.isBoolean())
|
||||
return JSTYPE_BOOLEAN;
|
||||
#ifdef ENABLE_BIGINT
|
||||
if (v.isBigInt())
|
||||
return JSTYPE_BIGINT;
|
||||
#endif
|
||||
MOZ_ASSERT(v.isSymbol());
|
||||
return JSTYPE_SYMBOL;
|
||||
}
|
||||
@ -4383,7 +4390,10 @@ js::GetProperty(JSContext* cx, HandleValue v, HandlePropertyName name, MutableHa
|
||||
|
||||
// Optimize common cases like (2).toString() or "foo".valueOf() to not
|
||||
// create a wrapper object.
|
||||
if (v.isPrimitive() && !v.isNullOrUndefined()) {
|
||||
if (v.isPrimitive() &&
|
||||
!v.isNullOrUndefined() &&
|
||||
IF_BIGINT(!v.isBigInt(), true))
|
||||
{
|
||||
NativeObject* proto;
|
||||
if (v.isNumber()) {
|
||||
proto = GlobalObject::getOrCreateNumberPrototype(cx, cx->global());
|
||||
|
@ -636,6 +636,14 @@ ToAtomSlow(JSContext* cx, typename MaybeRooted<Value, allowGC>::HandleType arg)
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
#ifdef ENABLE_BIGINT
|
||||
if (v.isBigInt()) {
|
||||
JSAtom* atom = BigIntToAtom(cx, v.toBigInt());
|
||||
if (!allowGC && !atom)
|
||||
cx->recoverFromOutOfMemory();
|
||||
return atom;
|
||||
}
|
||||
#endif
|
||||
MOZ_ASSERT(v.isUndefined());
|
||||
return cx->names().undefined;
|
||||
}
|
||||
|
@ -121,6 +121,16 @@ JSCompartment::wrap(JSContext* cx, JS::MutableHandleValue vp)
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_BIGINT
|
||||
if (vp.isBigInt()) {
|
||||
JS::RootedBigInt bi(cx, vp.toBigInt());
|
||||
if (!wrap(cx, &bi))
|
||||
return false;
|
||||
vp.setBigInt(bi);
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
MOZ_ASSERT(vp.isObject());
|
||||
|
||||
/*
|
||||
|
@ -345,6 +345,23 @@ JSCompartment::wrap(JSContext* cx, MutableHandleString strp)
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_BIGINT
|
||||
bool
|
||||
JSCompartment::wrap(JSContext* cx, MutableHandleBigInt bi)
|
||||
{
|
||||
MOZ_ASSERT(cx->compartment() == this);
|
||||
|
||||
if (bi->zone() == cx->zone())
|
||||
return true;
|
||||
|
||||
BigInt* copy = BigInt::copy(cx, bi);
|
||||
if (!copy)
|
||||
return false;
|
||||
bi.set(copy);
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool
|
||||
JSCompartment::getNonWrapperObjectForCurrentCompartment(JSContext* cx, MutableHandleObject obj)
|
||||
{
|
||||
|
@ -636,6 +636,9 @@ struct JSCompartment
|
||||
MOZ_MUST_USE inline bool wrap(JSContext* cx, JS::MutableHandleValue vp);
|
||||
|
||||
MOZ_MUST_USE bool wrap(JSContext* cx, js::MutableHandleString strp);
|
||||
#ifdef ENABLE_BIGINT
|
||||
MOZ_MUST_USE bool wrap(JSContext* cx, js::MutableHandle<JS::BigInt*> bi);
|
||||
#endif
|
||||
MOZ_MUST_USE bool wrap(JSContext* cx, JS::MutableHandleObject obj);
|
||||
MOZ_MUST_USE bool wrap(JSContext* cx, JS::MutableHandle<js::PropertyDescriptor> desc);
|
||||
MOZ_MUST_USE bool wrap(JSContext* cx, JS::MutableHandle<JS::GCVector<JS::Value>> vec);
|
||||
|
@ -3251,9 +3251,20 @@ js::PrimitiveToObject(JSContext* cx, const Value& v)
|
||||
return NumberObject::create(cx, v.toNumber());
|
||||
if (v.isBoolean())
|
||||
return BooleanObject::create(cx, v.toBoolean());
|
||||
#ifdef ENABLE_BIGINT
|
||||
if (v.isSymbol()) {
|
||||
RootedSymbol symbol(cx, v.toSymbol());
|
||||
return SymbolObject::create(cx, symbol);
|
||||
}
|
||||
MOZ_ASSERT(v.isBigInt());
|
||||
RootedBigInt bigInt(cx, v.toBigInt());
|
||||
// Return nullptr because BigIntObject has not been defined yet.
|
||||
return nullptr;
|
||||
#else
|
||||
MOZ_ASSERT(v.isSymbol());
|
||||
RootedSymbol symbol(cx, v.toSymbol());
|
||||
return SymbolObject::create(cx, symbol);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -13,6 +13,9 @@
|
||||
#include "jit/BaselineJIT.h"
|
||||
#include "jit/Ion.h"
|
||||
#include "vm/ArrayObject.h"
|
||||
#ifdef ENABLE_BIGINT
|
||||
#include "vm/BigIntType.h"
|
||||
#endif
|
||||
#include "vm/HelperThreads.h"
|
||||
#include "vm/JSCompartment.h"
|
||||
#include "vm/JSObject.h"
|
||||
@ -556,6 +559,15 @@ StatsCellCallback(JSRuntime* rt, void* data, void* thing, JS::TraceKind traceKin
|
||||
zStats->symbolsGCHeap += thingSize;
|
||||
break;
|
||||
|
||||
#ifdef ENABLE_BIGINT
|
||||
case JS::TraceKind::BigInt: {
|
||||
JS::BigInt* bi = static_cast<BigInt*>(thing);
|
||||
zStats->bigIntsGCHeap += thingSize;
|
||||
zStats->bigIntsMallocHeap += bi->sizeOfExcludingThis(rtStats->mallocSizeOf_);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
case JS::TraceKind::BaseShape: {
|
||||
JS::ShapeInfo info; // This zeroes all the sizes.
|
||||
info.shapesGCHeapBase += thingSize;
|
||||
|
@ -2071,7 +2071,15 @@ js::ToStringSlow(JSContext* cx, typename MaybeRooted<Value, allowGC>::HandleType
|
||||
JSMSG_SYMBOL_TO_STRING);
|
||||
}
|
||||
return nullptr;
|
||||
} else {
|
||||
}
|
||||
#ifdef ENABLE_BIGINT
|
||||
else if (v.isBigInt()) {
|
||||
if (!allowGC)
|
||||
return nullptr;
|
||||
str = BigInt::toString(cx, v.toBigInt());
|
||||
}
|
||||
#endif
|
||||
else {
|
||||
MOZ_ASSERT(v.isUndefined());
|
||||
str = cx->names().undefined;
|
||||
}
|
||||
|
@ -190,6 +190,10 @@ PrimitiveTypeFlag(JSValueType type)
|
||||
return TYPE_FLAG_STRING;
|
||||
case JSVAL_TYPE_SYMBOL:
|
||||
return TYPE_FLAG_SYMBOL;
|
||||
#ifdef ENABLE_BIGINT
|
||||
case JSVAL_TYPE_BIGINT:
|
||||
return TYPE_FLAG_BIGINT;
|
||||
#endif
|
||||
case JSVAL_TYPE_MAGIC:
|
||||
return TYPE_FLAG_LAZYARGS;
|
||||
default:
|
||||
@ -215,6 +219,10 @@ TypeFlagPrimitive(TypeFlags flags)
|
||||
return JSVAL_TYPE_STRING;
|
||||
case TYPE_FLAG_SYMBOL:
|
||||
return JSVAL_TYPE_SYMBOL;
|
||||
#ifdef ENABLE_BIGINT
|
||||
case TYPE_FLAG_BIGINT:
|
||||
return JSVAL_TYPE_BIGINT;
|
||||
#endif
|
||||
case TYPE_FLAG_LAZYARGS:
|
||||
return JSVAL_TYPE_MAGIC;
|
||||
default:
|
||||
|
@ -113,6 +113,10 @@ TypeSet::NonObjectTypeString(TypeSet::Type type)
|
||||
return "string";
|
||||
case JSVAL_TYPE_SYMBOL:
|
||||
return "symbol";
|
||||
#ifdef ENABLE_BIGINT
|
||||
case JSVAL_TYPE_BIGINT:
|
||||
return "BigInt";
|
||||
#endif
|
||||
case JSVAL_TYPE_MAGIC:
|
||||
return "lazyargs";
|
||||
default:
|
||||
@ -785,6 +789,10 @@ TypeSet::print(FILE* fp)
|
||||
fprintf(fp, " string");
|
||||
if (flags & TYPE_FLAG_SYMBOL)
|
||||
fprintf(fp, " symbol");
|
||||
#ifdef ENABLE_BIGINT
|
||||
if (flags & TYPE_FLAG_BIGINT)
|
||||
fprintf(fp, " BigInt");
|
||||
#endif
|
||||
if (flags & TYPE_FLAG_LAZYARGS)
|
||||
fprintf(fp, " lazyargs");
|
||||
|
||||
|
@ -60,17 +60,29 @@ enum : uint32_t {
|
||||
TYPE_FLAG_DOUBLE = 0x10,
|
||||
TYPE_FLAG_STRING = 0x20,
|
||||
TYPE_FLAG_SYMBOL = 0x40,
|
||||
TYPE_FLAG_LAZYARGS = 0x80,
|
||||
#ifdef ENABLE_BIGINT
|
||||
TYPE_FLAG_BIGINT = 0x80,
|
||||
TYPE_FLAG_LAZYARGS = 0x100,
|
||||
TYPE_FLAG_ANYOBJECT = 0x200,
|
||||
#else
|
||||
TYPE_FLAG_LAZYARGS = 0x80,
|
||||
TYPE_FLAG_ANYOBJECT = 0x100,
|
||||
#endif
|
||||
|
||||
/* 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_SYMBOL,
|
||||
TYPE_FLAG_SYMBOL |
|
||||
IF_BIGINT(TYPE_FLAG_BIGINT, 0),
|
||||
|
||||
/* Mask/shift for the number of objects in objectSet */
|
||||
#ifdef ENABLE_BIGINT
|
||||
TYPE_FLAG_OBJECT_COUNT_MASK = 0x3c00,
|
||||
TYPE_FLAG_OBJECT_COUNT_SHIFT = 10,
|
||||
#else
|
||||
TYPE_FLAG_OBJECT_COUNT_MASK = 0x3e00,
|
||||
TYPE_FLAG_OBJECT_COUNT_SHIFT = 9,
|
||||
#endif
|
||||
TYPE_FLAG_OBJECT_COUNT_LIMIT = 7,
|
||||
TYPE_FLAG_DOMOBJECT_COUNT_LIMIT =
|
||||
TYPE_FLAG_OBJECT_COUNT_MASK >> TYPE_FLAG_OBJECT_COUNT_SHIFT,
|
||||
@ -79,7 +91,7 @@ enum : uint32_t {
|
||||
TYPE_FLAG_UNKNOWN = 0x00004000,
|
||||
|
||||
/* Mask of normal type flags on a type set. */
|
||||
TYPE_FLAG_BASE_MASK = 0x000041ff,
|
||||
TYPE_FLAG_BASE_MASK = TYPE_FLAG_PRIMITIVE | TYPE_FLAG_LAZYARGS | TYPE_FLAG_ANYOBJECT | TYPE_FLAG_UNKNOWN,
|
||||
|
||||
/* Additional flags for HeapTypeSet sets. */
|
||||
|
||||
@ -110,6 +122,10 @@ enum : uint32_t {
|
||||
};
|
||||
typedef uint32_t TypeFlags;
|
||||
|
||||
static_assert(TYPE_FLAG_PRIMITIVE < TYPE_FLAG_ANYOBJECT &&
|
||||
TYPE_FLAG_LAZYARGS < TYPE_FLAG_ANYOBJECT,
|
||||
"TYPE_FLAG_ANYOBJECT should be greater than primitive type flags");
|
||||
|
||||
/* Flags and other state stored in ObjectGroup::Flags */
|
||||
enum : uint32_t {
|
||||
/* Whether this group is associated with some allocation site. */
|
||||
@ -366,6 +382,9 @@ class TypeSet
|
||||
static inline Type DoubleType() { return Type(JSVAL_TYPE_DOUBLE); }
|
||||
static inline Type StringType() { return Type(JSVAL_TYPE_STRING); }
|
||||
static inline Type SymbolType() { return Type(JSVAL_TYPE_SYMBOL); }
|
||||
#ifdef ENABLE_BIGINT
|
||||
static inline Type BigIntType() { return Type(JSVAL_TYPE_BIGINT); }
|
||||
#endif
|
||||
static inline Type MagicArgType() { return Type(JSVAL_TYPE_MAGIC); }
|
||||
static inline Type AnyObjectType() { return Type(JSVAL_TYPE_OBJECT); }
|
||||
static inline Type UnknownType() { return Type(JSVAL_TYPE_UNKNOWN); }
|
||||
|
@ -22,6 +22,9 @@
|
||||
#include "js/Utility.h"
|
||||
#include "js/Vector.h"
|
||||
#include "util/Text.h"
|
||||
#ifdef ENABLE_BIGINT
|
||||
#include "vm/BigIntType.h"
|
||||
#endif
|
||||
#include "vm/Debugger.h"
|
||||
#include "vm/EnvironmentObject.h"
|
||||
#include "vm/GlobalObject.h"
|
||||
@ -203,7 +206,13 @@ Node::exposeToJS() const
|
||||
v.setString(as<JSString>());
|
||||
} else if (is<JS::Symbol>()) {
|
||||
v.setSymbol(as<JS::Symbol>());
|
||||
} else {
|
||||
}
|
||||
#ifdef ENABLE_BIGINT
|
||||
else if (is<BigInt>()) {
|
||||
v.setBigInt(as<BigInt>());
|
||||
}
|
||||
#endif
|
||||
else {
|
||||
v.setUndefined();
|
||||
}
|
||||
|
||||
@ -315,6 +324,9 @@ template JS::Zone* TracerConcrete<js::ObjectGroup>::zone() const;
|
||||
template JS::Zone* TracerConcrete<js::RegExpShared>::zone() const;
|
||||
template JS::Zone* TracerConcrete<js::Scope>::zone() const;
|
||||
template JS::Zone* TracerConcrete<JS::Symbol>::zone() const;
|
||||
#ifdef ENABLE_BIGINT
|
||||
template JS::Zone* TracerConcrete<BigInt>::zone() const;
|
||||
#endif
|
||||
template JS::Zone* TracerConcrete<JSString>::zone() const;
|
||||
|
||||
template<typename Referent>
|
||||
@ -338,6 +350,9 @@ template UniquePtr<EdgeRange> TracerConcrete<js::ObjectGroup>::edges(JSContext*
|
||||
template UniquePtr<EdgeRange> TracerConcrete<js::RegExpShared>::edges(JSContext* cx, bool wantNames) const;
|
||||
template UniquePtr<EdgeRange> TracerConcrete<js::Scope>::edges(JSContext* cx, bool wantNames) const;
|
||||
template UniquePtr<EdgeRange> TracerConcrete<JS::Symbol>::edges(JSContext* cx, bool wantNames) const;
|
||||
#ifdef ENABLE_BIGINT
|
||||
template UniquePtr<EdgeRange> TracerConcrete<BigInt>::edges(JSContext* cx, bool wantNames) const;
|
||||
#endif
|
||||
template UniquePtr<EdgeRange> TracerConcrete<JSString>::edges(JSContext* cx, bool wantNames) const;
|
||||
|
||||
template<typename Referent>
|
||||
@ -393,6 +408,9 @@ Concrete<JSObject>::jsObjectConstructorName(JSContext* cx, UniqueTwoByteChars& o
|
||||
}
|
||||
|
||||
const char16_t Concrete<JS::Symbol>::concreteTypeName[] = u"JS::Symbol";
|
||||
#ifdef ENABLE_BIGINT
|
||||
const char16_t Concrete<BigInt>::concreteTypeName[] = u"JS::BigInt";
|
||||
#endif
|
||||
const char16_t Concrete<JSScript>::concreteTypeName[] = u"JSScript";
|
||||
const char16_t Concrete<js::LazyScript>::concreteTypeName[] = u"js::LazyScript";
|
||||
const char16_t Concrete<js::jit::JitCode>::concreteTypeName[] = u"js::jit::JitCode";
|
||||
|
Loading…
Reference in New Issue
Block a user