mirror of
https://github.com/roytam1/UXP.git
synced 2026-05-26 14:54:25 +00:00
Issue #1240 - Part 1 - Define a new BigInt primitive type. Based on https://bugzilla.mozilla.org/show_bug.cgi?id=1366287 Part 1.0. However leaving out the --enable-bigint changes.
This commit is contained in:
@@ -120,7 +120,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);
|
||||
}
|
||||
|
||||
|
||||
@@ -47,6 +47,7 @@
|
||||
// Expand the given macro D for each public GC pointer.
|
||||
#define FOR_EACH_PUBLIC_GC_POINTER_TYPE(D) \
|
||||
D(JS::Symbol*) \
|
||||
D(JS::BigInt*) \
|
||||
D(JSAtom*) \
|
||||
D(JSFunction*) \
|
||||
D(JSObject*) \
|
||||
@@ -125,6 +126,7 @@ struct GCPointerPolicy
|
||||
}
|
||||
};
|
||||
template <> struct GCPolicy<JS::Symbol*> : public GCPointerPolicy<JS::Symbol*> {};
|
||||
template <> struct GCPolicy<JS::BigInt*> : public GCPointerPolicy<JS::BigInt*> {};
|
||||
template <> struct GCPolicy<JSAtom*> : public GCPointerPolicy<JSAtom*> {};
|
||||
template <> struct GCPolicy<JSFunction*> : public GCPointerPolicy<JSFunction*> {};
|
||||
template <> struct GCPolicy<JSObject*> : public GCPointerPolicy<JSObject*> {};
|
||||
|
||||
@@ -580,6 +580,7 @@ struct UnusedGCThingSizes
|
||||
macro(Other, GCHeapUnused, objectGroup) \
|
||||
macro(Other, GCHeapUnused, string) \
|
||||
macro(Other, GCHeapUnused, symbol) \
|
||||
macro(Other, GCHeapUnused, bigInt) \
|
||||
macro(Other, GCHeapUnused, jitcode) \
|
||||
macro(Other, GCHeapUnused, scope) \
|
||||
macro(Other, GCHeapUnused, regExpShared)
|
||||
@@ -599,6 +600,7 @@ struct UnusedGCThingSizes
|
||||
case JS::TraceKind::Object: object += n; break;
|
||||
case JS::TraceKind::String: string += n; break;
|
||||
case JS::TraceKind::Symbol: symbol += n; break;
|
||||
case JS::TraceKind::BigInt: bigInt += n; break;
|
||||
case JS::TraceKind::Script: script += n; break;
|
||||
case JS::TraceKind::Shape: shape += n; break;
|
||||
case JS::TraceKind::BaseShape: baseShape += n; break;
|
||||
@@ -640,6 +642,8 @@ struct ZoneStats
|
||||
{
|
||||
#define FOR_EACH_SIZE(macro) \
|
||||
macro(Other, GCHeapUsed, symbolsGCHeap) \
|
||||
macro(Other, GCHeapUsed, bigIntsGCHeap) \
|
||||
macro(Other, MallocHeap, bigIntsMallocHeap) \
|
||||
macro(Other, GCHeapAdmin, gcHeapArenaAdmin) \
|
||||
macro(Other, GCHeapUsed, lazyScriptsGCHeap) \
|
||||
macro(Other, MallocHeap, lazyScriptsMallocHeap) \
|
||||
|
||||
@@ -60,7 +60,8 @@ enum class TraceKind
|
||||
JitCode = 0x1F,
|
||||
LazyScript = 0x2F,
|
||||
Scope = 0x3F,
|
||||
RegExpShared = 0x4F
|
||||
RegExpShared = 0x4F,
|
||||
BigInt = 0x5F
|
||||
};
|
||||
const static uintptr_t OutOfLineTraceKindMask = 0x07;
|
||||
static_assert(uintptr_t(JS::TraceKind::BaseShape) & OutOfLineTraceKindMask, "mask bits are set");
|
||||
@@ -91,6 +92,7 @@ struct MapTypeToTraceKind {
|
||||
D(Shape, js::Shape, true) \
|
||||
D(String, JSString, false) \
|
||||
D(Symbol, JS::Symbol, false) \
|
||||
D(BigInt, JS::BigInt, false) \
|
||||
D(RegExpShared, js::RegExpShared, true)
|
||||
|
||||
// Map from all public types to their trace kind.
|
||||
|
||||
@@ -141,6 +141,7 @@ 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)); }
|
||||
virtual void onBigIntEdge(JS::BigInt** bip) { onChild(JS::GCCellPtr(*bip)); }
|
||||
virtual void onScriptEdge(JSScript** scriptp) { onChild(JS::GCCellPtr(*scriptp)); }
|
||||
virtual void onShapeEdge(js::Shape** shapep) {
|
||||
onChild(JS::GCCellPtr(*shapep, JS::TraceKind::Shape));
|
||||
@@ -226,6 +227,7 @@ 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); }
|
||||
void dispatchToOnEdge(JS::BigInt** bip) { onBigIntEdge(bip); }
|
||||
void dispatchToOnEdge(JSScript** scriptp) { onScriptEdge(scriptp); }
|
||||
void dispatchToOnEdge(js::Shape** shapep) { onShapeEdge(shapep); }
|
||||
void dispatchToOnEdge(js::ObjectGroup** groupp) { onObjectGroupEdge(groupp); }
|
||||
|
||||
@@ -39,6 +39,7 @@ namespace JS {
|
||||
typedef unsigned char Latin1Char;
|
||||
|
||||
class Symbol;
|
||||
class BigInt;
|
||||
class Value;
|
||||
template <typename T> class Handle;
|
||||
template <typename T> class MutableHandle;
|
||||
@@ -53,6 +54,7 @@ typedef Handle<JSObject*> HandleObject;
|
||||
typedef Handle<JSScript*> HandleScript;
|
||||
typedef Handle<JSString*> HandleString;
|
||||
typedef Handle<JS::Symbol*> HandleSymbol;
|
||||
typedef Handle<JS::BigInt*> HandleBigInt;
|
||||
typedef Handle<Value> HandleValue;
|
||||
typedef Handle<StackGCVector<Value>> HandleValueVector;
|
||||
|
||||
@@ -62,6 +64,7 @@ typedef MutableHandle<JSObject*> MutableHandleObject;
|
||||
typedef MutableHandle<JSScript*> MutableHandleScript;
|
||||
typedef MutableHandle<JSString*> MutableHandleString;
|
||||
typedef MutableHandle<JS::Symbol*> MutableHandleSymbol;
|
||||
typedef MutableHandle<JS::BigInt*> MutableHandleBigInt;
|
||||
typedef MutableHandle<Value> MutableHandleValue;
|
||||
typedef MutableHandle<StackGCVector<Value>> MutableHandleValueVector;
|
||||
|
||||
@@ -70,6 +73,7 @@ typedef Rooted<JSFunction*> RootedFunction;
|
||||
typedef Rooted<JSScript*> RootedScript;
|
||||
typedef Rooted<JSString*> RootedString;
|
||||
typedef Rooted<JS::Symbol*> RootedSymbol;
|
||||
typedef Rooted<JS::BigInt*> RootedBigInt;
|
||||
typedef Rooted<jsid> RootedId;
|
||||
typedef Rooted<JS::Value> RootedValue;
|
||||
|
||||
@@ -81,6 +85,7 @@ typedef PersistentRooted<JSObject*> PersistentRootedObject;
|
||||
typedef PersistentRooted<JSScript*> PersistentRootedScript;
|
||||
typedef PersistentRooted<JSString*> PersistentRootedString;
|
||||
typedef PersistentRooted<JS::Symbol*> PersistentRootedSymbol;
|
||||
typedef PersistentRooted<JS::BigInt*> PersistentRootedBigInt;
|
||||
typedef PersistentRooted<Value> PersistentRootedValue;
|
||||
|
||||
|
||||
|
||||
@@ -1056,6 +1056,22 @@ class JS_PUBLIC_API(Concrete<JS::Symbol>) : TracerConcrete<JS::Symbol> {
|
||||
static const char16_t concreteTypeName[];
|
||||
};
|
||||
|
||||
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[];
|
||||
};
|
||||
|
||||
template<>
|
||||
class JS_PUBLIC_API(Concrete<JSScript>) : TracerConcreteWithCompartment<JSScript> {
|
||||
protected:
|
||||
|
||||
+40
-1
@@ -56,6 +56,7 @@ JS_ENUM_HEADER(JSValueType, uint8_t)
|
||||
JSVAL_TYPE_STRING = 0x06,
|
||||
JSVAL_TYPE_SYMBOL = 0x07,
|
||||
JSVAL_TYPE_PRIVATE_GCTHING = 0x08,
|
||||
JSVAL_TYPE_BIGINT = 0x09,
|
||||
JSVAL_TYPE_OBJECT = 0x0c,
|
||||
|
||||
/* These never appear in a jsval; they are only provided as an out-of-band value. */
|
||||
@@ -80,6 +81,7 @@ JS_ENUM_HEADER(JSValueTag, uint32_t)
|
||||
JSVAL_TAG_BOOLEAN = JSVAL_TAG_CLEAR | JSVAL_TYPE_BOOLEAN,
|
||||
JSVAL_TAG_MAGIC = JSVAL_TAG_CLEAR | JSVAL_TYPE_MAGIC,
|
||||
JSVAL_TAG_OBJECT = JSVAL_TAG_CLEAR | JSVAL_TYPE_OBJECT,
|
||||
JSVAL_TAG_BIGINT = JSVAL_TAG_CLEAR | JSVAL_TYPE_BIGINT,
|
||||
JSVAL_TAG_PRIVATE_GCTHING = JSVAL_TAG_CLEAR | JSVAL_TYPE_PRIVATE_GCTHING
|
||||
} JS_ENUM_FOOTER(JSValueTag);
|
||||
|
||||
@@ -100,6 +102,7 @@ JS_ENUM_HEADER(JSValueTag, uint32_t)
|
||||
JSVAL_TAG_BOOLEAN = JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_BOOLEAN,
|
||||
JSVAL_TAG_MAGIC = JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_MAGIC,
|
||||
JSVAL_TAG_OBJECT = JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_OBJECT,
|
||||
JSVAL_TAG_BIGINT = JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_BIGINT,
|
||||
JSVAL_TAG_PRIVATE_GCTHING = JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_PRIVATE_GCTHING
|
||||
} JS_ENUM_FOOTER(JSValueTag);
|
||||
|
||||
@@ -117,6 +120,7 @@ JS_ENUM_HEADER(JSValueShiftedTag, uint64_t)
|
||||
JSVAL_SHIFTED_TAG_BOOLEAN = (((uint64_t)JSVAL_TAG_BOOLEAN) << JSVAL_TAG_SHIFT),
|
||||
JSVAL_SHIFTED_TAG_MAGIC = (((uint64_t)JSVAL_TAG_MAGIC) << JSVAL_TAG_SHIFT),
|
||||
JSVAL_SHIFTED_TAG_OBJECT = (((uint64_t)JSVAL_TAG_OBJECT) << JSVAL_TAG_SHIFT),
|
||||
JSVAL_SHIFTED_TAG_BIGINT = (((uint64_t)JSVAL_TAG_BIGINT) << JSVAL_TAG_SHIFT),
|
||||
JSVAL_SHIFTED_TAG_PRIVATE_GCTHING = (((uint64_t)JSVAL_TAG_PRIVATE_GCTHING) << JSVAL_TAG_SHIFT)
|
||||
} JS_ENUM_FOOTER(JSValueShiftedTag);
|
||||
|
||||
@@ -275,7 +279,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.
|
||||
*
|
||||
@@ -370,6 +374,11 @@ class MOZ_NON_PARAM alignas(8) Value
|
||||
data.asBits = bitsFromTagAndPayload(JSVAL_TAG_SYMBOL, PayloadType(sym));
|
||||
}
|
||||
|
||||
void setBigInt(JS::BigInt* bi) {
|
||||
MOZ_ASSERT(uintptr_t(bi) > 0x1000);
|
||||
data.asBits = bitsFromTagAndPayload(JSVAL_TAG_BIGINT, PayloadType(bi));
|
||||
}
|
||||
|
||||
void setObject(JSObject& obj) {
|
||||
MOZ_ASSERT(uintptr_t(&obj) > 0x1000 || uintptr_t(&obj) == 0x48);
|
||||
#if defined(JS_PUNBOX64)
|
||||
@@ -519,6 +528,10 @@ class MOZ_NON_PARAM alignas(8) Value
|
||||
return toTag() == JSVAL_TAG_SYMBOL;
|
||||
}
|
||||
|
||||
bool isBigInt() const {
|
||||
return toTag() == JSVAL_TAG_BIGINT;
|
||||
}
|
||||
|
||||
bool isObject() const {
|
||||
#if defined(JS_NUNBOX32)
|
||||
return toTag() == JSVAL_TAG_OBJECT;
|
||||
@@ -583,6 +596,8 @@ class MOZ_NON_PARAM alignas(8) Value
|
||||
"Value type tags must correspond with JS::TraceKinds.");
|
||||
if (MOZ_UNLIKELY(isPrivateGCThing()))
|
||||
return JS::GCThingTraceKind(toGCThing());
|
||||
if (MOZ_UNLIKELY(isBigInt()))
|
||||
return JS::TraceKind::BigInt;
|
||||
return JS::TraceKind(toTag() & 0x03);
|
||||
}
|
||||
|
||||
@@ -647,6 +662,15 @@ class MOZ_NON_PARAM alignas(8) Value
|
||||
#endif
|
||||
}
|
||||
|
||||
JS::BigInt* toBigInt() const {
|
||||
MOZ_ASSERT(isBigInt());
|
||||
#if defined(JS_NUNBOX32)
|
||||
return data.s.payload.bi;
|
||||
#elif defined(JS_PUNBOX64)
|
||||
return reinterpret_cast<JS::BigInt*>(data.asBits & JSVAL_SHIFTED_TAG_BIGINT);
|
||||
#endif
|
||||
}
|
||||
|
||||
JSObject& toObject() const {
|
||||
MOZ_ASSERT(isObject());
|
||||
#if defined(JS_NUNBOX32)
|
||||
@@ -759,6 +783,8 @@ class 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.");
|
||||
MOZ_ASSERT(JS::GCThingTraceKind(cell) != JS::TraceKind::BigInt,
|
||||
"Private GC thing Values must not be BigInts. Make a BigIntValue instead.");
|
||||
MOZ_ASSERT(JS::GCThingTraceKind(cell) != JS::TraceKind::Object,
|
||||
"Private GC thing Values must not be objects. Make an ObjectValue instead.");
|
||||
|
||||
@@ -811,6 +837,7 @@ class MOZ_NON_PARAM alignas(8) Value
|
||||
uint32_t boo; // Don't use |bool| -- it must be four bytes.
|
||||
JSString* str;
|
||||
JS::Symbol* sym;
|
||||
JS::BigInt* bi;
|
||||
JSObject* obj;
|
||||
js::gc::Cell* cell;
|
||||
void* ptr;
|
||||
@@ -866,6 +893,7 @@ class MOZ_NON_PARAM alignas(8) Value
|
||||
uint32_t boo; // Don't use |bool| -- it must be four bytes.
|
||||
JSString* str;
|
||||
JS::Symbol* sym;
|
||||
JS::BigInt* bi;
|
||||
JSObject* obj;
|
||||
js::gc::Cell* cell;
|
||||
void* ptr;
|
||||
@@ -1097,6 +1125,14 @@ SymbolValue(JS::Symbol* sym)
|
||||
return v;
|
||||
}
|
||||
|
||||
static inline Value
|
||||
BigIntValue(JS::BigInt* bi)
|
||||
{
|
||||
Value v;
|
||||
v.setBigInt(bi);
|
||||
return v;
|
||||
}
|
||||
|
||||
static inline Value
|
||||
BooleanValue(bool boo)
|
||||
{
|
||||
@@ -1365,6 +1401,7 @@ class WrappedPtrOperations<JS::Value, Wrapper>
|
||||
bool isDouble() const { return value().isDouble(); }
|
||||
bool isString() const { return value().isString(); }
|
||||
bool isSymbol() const { return value().isSymbol(); }
|
||||
bool isBigInt() const { return value().isBigInt(); }
|
||||
bool isObject() const { return value().isObject(); }
|
||||
bool isMagic() const { return value().isMagic(); }
|
||||
bool isMagic(JSWhyMagic why) const { return value().isMagic(why); }
|
||||
@@ -1380,6 +1417,7 @@ class WrappedPtrOperations<JS::Value, Wrapper>
|
||||
double toDouble() const { return value().toDouble(); }
|
||||
JSString* toString() const { return value().toString(); }
|
||||
JS::Symbol* toSymbol() const { return value().toSymbol(); }
|
||||
JS::BigInt* toBigInt() const { return value().toBigInt(); }
|
||||
JSObject& toObject() const { return value().toObject(); }
|
||||
JSObject* toObjectOrNull() const { return value().toObjectOrNull(); }
|
||||
gc::Cell* toGCThing() const { return value().toGCThing(); }
|
||||
@@ -1421,6 +1459,7 @@ class MutableWrappedPtrOperations<JS::Value, Wrapper> : public WrappedPtrOperati
|
||||
void setNumber(double d) { set(JS::NumberValue(d)); }
|
||||
void setString(JSString* str) { set(JS::StringValue(str)); }
|
||||
void setSymbol(JS::Symbol* sym) { set(JS::SymbolValue(sym)); }
|
||||
void setBigInt(JS::BigInt* bi) { set(JS::BigIntValue(bi)); }
|
||||
void setObject(JSObject& obj) { set(JS::ObjectValue(obj)); }
|
||||
void setObjectOrNull(JSObject* arg) { set(JS::ObjectOrNullValue(arg)); }
|
||||
void setPrivate(void* ptr) { set(JS::PrivateValue(ptr)); }
|
||||
|
||||
@@ -50,6 +50,7 @@ class PropertyResult;
|
||||
class Symbol;
|
||||
enum class SymbolCode: uint32_t;
|
||||
|
||||
class BigInt;
|
||||
} // namespace JS
|
||||
|
||||
// Do the importing.
|
||||
@@ -122,6 +123,7 @@ using JS::RootedObject;
|
||||
using JS::RootedScript;
|
||||
using JS::RootedString;
|
||||
using JS::RootedSymbol;
|
||||
using JS::RootedBigInt;
|
||||
using JS::RootedValue;
|
||||
|
||||
using JS::PersistentRooted;
|
||||
@@ -131,6 +133,7 @@ using JS::PersistentRootedObject;
|
||||
using JS::PersistentRootedScript;
|
||||
using JS::PersistentRootedString;
|
||||
using JS::PersistentRootedSymbol;
|
||||
using JS::PersistentRootedBigInt;
|
||||
using JS::PersistentRootedValue;
|
||||
|
||||
using JS::Handle;
|
||||
@@ -140,6 +143,7 @@ using JS::HandleObject;
|
||||
using JS::HandleScript;
|
||||
using JS::HandleString;
|
||||
using JS::HandleSymbol;
|
||||
using JS::HandleBigInt;
|
||||
using JS::HandleValue;
|
||||
|
||||
using JS::MutableHandle;
|
||||
@@ -149,6 +153,7 @@ using JS::MutableHandleObject;
|
||||
using JS::MutableHandleScript;
|
||||
using JS::MutableHandleString;
|
||||
using JS::MutableHandleSymbol;
|
||||
using JS::MutableHandleBigInt;
|
||||
using JS::MutableHandleValue;
|
||||
|
||||
using JS::NullHandleValue;
|
||||
@@ -166,6 +171,7 @@ using JS::Zone;
|
||||
using JS::Symbol;
|
||||
using JS::SymbolCode;
|
||||
|
||||
using JS::BigInt;
|
||||
} /* namespace js */
|
||||
|
||||
#endif /* NamespaceImports_h */
|
||||
|
||||
@@ -61,7 +61,7 @@ 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() || value.isBigInt());
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -81,6 +81,8 @@ HashValue(const Value& v, const mozilla::HashCodeScrambler& hcs)
|
||||
return v.toString()->asAtom().hash();
|
||||
if (v.isSymbol())
|
||||
return v.toSymbol()->hash();
|
||||
if (v.isBigInt())
|
||||
return v.toBigInt()->hash();
|
||||
if (v.isObject())
|
||||
return hcs.scramble(v.asRawBits());
|
||||
|
||||
@@ -100,6 +102,16 @@ HashableValue::operator==(const HashableValue& other) const
|
||||
// Two HashableValues are equal if they have equal bits.
|
||||
bool b = (value.asRawBits() == other.value.asRawBits());
|
||||
|
||||
// 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())) {
|
||||
JS::RootingContext* rcx = GetJSContextFromMainThread();
|
||||
RootedValue valueRoot(rcx, value);
|
||||
RootedValue otherRoot(rcx, other.value);
|
||||
SameValue(nullptr, valueRoot, otherRoot, &b);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
bool same;
|
||||
JS::RootingContext* rcx = GetJSContextFromMainThread();
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include "gc/Zone.h"
|
||||
#include "vm/HelperThreads.h"
|
||||
#include "vm/Runtime.h"
|
||||
#include "vm/BigIntType.h"
|
||||
|
||||
namespace js {
|
||||
namespace gc {
|
||||
@@ -71,6 +72,7 @@ struct MovingTracer : JS::CallbackTracer
|
||||
void onObjectEdge(JSObject** objp) override;
|
||||
void onShapeEdge(Shape** shapep) override;
|
||||
void onStringEdge(JSString** stringp) override;
|
||||
void onBigIntEdge(JS::BigInt** bip) override;
|
||||
void onScriptEdge(JSScript** scriptp) override;
|
||||
void onLazyScriptEdge(LazyScript** lazyp) override;
|
||||
void onBaseShapeEdge(BaseShape** basep) override;
|
||||
|
||||
@@ -113,6 +113,7 @@ enum class AllocKind {
|
||||
FAT_INLINE_ATOM,
|
||||
ATOM,
|
||||
SYMBOL,
|
||||
BIGINT,
|
||||
JITCODE,
|
||||
SCOPE,
|
||||
REGEXP_SHARED,
|
||||
@@ -153,6 +154,7 @@ enum class AllocKind {
|
||||
D(FAT_INLINE_ATOM, String, js::FatInlineAtom, js::FatInlineAtom) \
|
||||
D(ATOM, String, js::NormalAtom, js::NormalAtom) \
|
||||
D(SYMBOL, Symbol, JS::Symbol, JS::Symbol) \
|
||||
D(BIGINT, BigInt, JS::BigInt, JS::BigInt) \
|
||||
D(JITCODE, JitCode, js::jit::JitCode, js::jit::JitCode) \
|
||||
D(SCOPE, Scope, js::Scope, js::Scope) \
|
||||
D(REGEXP_SHARED, RegExpShared, js::RegExpShared, js::RegExpShared)
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include "js/SliceBudget.h"
|
||||
#include "vm/ArgumentsObject.h"
|
||||
#include "vm/ArrayObject.h"
|
||||
#include "vm/BigIntType.h"
|
||||
#include "vm/Debugger.h"
|
||||
#include "vm/EnvironmentObject.h"
|
||||
#include "vm/Scope.h"
|
||||
@@ -875,6 +876,7 @@ js::GCMarker::markAndTraceChildren(T* thing)
|
||||
namespace js {
|
||||
template <> void GCMarker::traverse(BaseShape* thing) { markAndTraceChildren(thing); }
|
||||
template <> void GCMarker::traverse(JS::Symbol* thing) { markAndTraceChildren(thing); }
|
||||
template <> void GCMarker::traverse(JS::BigInt* thing) { markAndTraceChildren(thing); }
|
||||
template <> void GCMarker::traverse(RegExpShared* thing) { markAndTraceChildren(thing); }
|
||||
} // namespace js
|
||||
|
||||
@@ -1458,6 +1460,12 @@ js::GCMarker::lazilyMarkChildren(ObjectGroup* group)
|
||||
traverseEdge(group, static_cast<JSObject*>(fun));
|
||||
}
|
||||
|
||||
void
|
||||
JS::BigInt::traceChildren(JSTracer* trc)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
struct TraverseObjectFunctor
|
||||
{
|
||||
template <typename T>
|
||||
@@ -1704,6 +1712,8 @@ GCMarker::processMarkStackTop(SliceBudget& budget)
|
||||
}
|
||||
} else if (v.isSymbol()) {
|
||||
traverseEdge(obj, v.toSymbol());
|
||||
} else if (v.isBigInt()) {
|
||||
traverseEdge(obj, v.toBigInt());
|
||||
} else if (v.isPrivateGCThing()) {
|
||||
traverseEdge(obj, v.toGCCellPtr());
|
||||
}
|
||||
|
||||
+3
-1
@@ -425,6 +425,7 @@ struct RewrapTaggedPointer{};
|
||||
DECLARE_REWRAP(JS::Value, JSObject, JS::ObjectOrNullValue, );
|
||||
DECLARE_REWRAP(JS::Value, JSString, JS::StringValue, );
|
||||
DECLARE_REWRAP(JS::Value, JS::Symbol, JS::SymbolValue, );
|
||||
DECLARE_REWRAP(JS::Value, JS::BigInt, JS::BigIntValue, );
|
||||
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, );
|
||||
@@ -435,7 +436,8 @@ 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 &&
|
||||
!mozilla::IsBaseOf<JS::BigInt, T>::value, T>
|
||||
{
|
||||
static_assert(!mozilla::IsSame<Cell, T>::value && !mozilla::IsSame<TenuredCell, T>::value,
|
||||
"T must not be Cell or TenuredCell");
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "gc/Marking.h"
|
||||
#include "gc/Zone.h"
|
||||
|
||||
#include "vm/BigIntType.h"
|
||||
#include "vm/Shape.h"
|
||||
#include "vm/Symbol.h"
|
||||
|
||||
@@ -319,6 +320,10 @@ JS_GetTraceThingInfo(char* buf, size_t bufsize, JSTracer* trc, void* thing,
|
||||
name = "symbol";
|
||||
break;
|
||||
|
||||
case JS::TraceKind::BigInt:
|
||||
name = "BigInt";
|
||||
break;
|
||||
|
||||
case JS::TraceKind::BaseShape:
|
||||
name = "base_shape";
|
||||
break;
|
||||
|
||||
@@ -165,6 +165,15 @@ class jsvalTypeCache(object):
|
||||
self.NULL = d['JSVAL_TYPE_NULL']
|
||||
self.OBJECT = d['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'))
|
||||
@@ -206,6 +215,8 @@ class jsval_layout(object):
|
||||
value = self.box.as_address().cast(self.cache.JSString_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()'
|
||||
elif tag == self.jtc.NULL:
|
||||
return 'JSVAL_NULL'
|
||||
elif tag == self.jtc.OBJECT:
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
#include "gdb-tests.h"
|
||||
#include "jsapi.h"
|
||||
|
||||
#include "vm/BigIntType.h"
|
||||
|
||||
FRAGMENT(jsval, simple) {
|
||||
using namespace JS;
|
||||
|
||||
@@ -17,6 +19,7 @@ FRAGMENT(jsval, simple) {
|
||||
RootedString hello(cx, JS_NewStringCopyZ(cx, "Hello!"));
|
||||
RootedValue friendly_string(cx, StringValue(hello));
|
||||
RootedValue symbol(cx, SymbolValue(GetSymbolFor(cx, hello)));
|
||||
RootedValue bi(cx, BigIntValue(BigInt::create(cx)));
|
||||
|
||||
RootedValue global(cx);
|
||||
global.setObject(*CurrentGlobalOrNull(cx));
|
||||
@@ -36,5 +39,6 @@ FRAGMENT(jsval, simple) {
|
||||
(void) empty_string;
|
||||
(void) friendly_string;
|
||||
(void) symbol;
|
||||
(void) bi;
|
||||
(void) global;
|
||||
}
|
||||
|
||||
@@ -14,5 +14,7 @@ assert_pretty('elements_hole', '$jsmagic(JS_ELEMENTS_HOLE)')
|
||||
assert_pretty('empty_string', '$jsval("")')
|
||||
assert_pretty('friendly_string', '$jsval("Hello!")')
|
||||
assert_pretty('symbol', '$jsval(Symbol.for("Hello!"))')
|
||||
if enable_bigint:
|
||||
assert_pretty('bi', '$JS::BigIntValue()')
|
||||
assert_pretty('global', '$jsval((JSObject *) [object global] delegate)')
|
||||
assert_pretty('onehundredthirtysevenonehundredtwentyeighths', '$jsval(1.0703125)')
|
||||
|
||||
@@ -619,3 +619,12 @@ MSG_DEF(JSMSG_FOR_AWAIT_NOT_OF, 0, JSEXN_TYPEERR, "'for await' loop shoul
|
||||
MSG_DEF(JSMSG_NOT_AN_ASYNC_GENERATOR, 0, JSEXN_TYPEERR, "Not an async generator")
|
||||
MSG_DEF(JSMSG_NOT_AN_ASYNC_ITERATOR, 0, JSEXN_TYPEERR, "Not an async from sync iterator")
|
||||
MSG_DEF(JSMSG_GET_ASYNC_ITER_RETURNED_PRIMITIVE, 0, JSEXN_TYPEERR, "[Symbol.asyncIterator]() returned a non-object value")
|
||||
|
||||
// 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")
|
||||
|
||||
@@ -1099,6 +1099,12 @@ ArrayJoinDenseKernel(JSContext* cx, SeparatorOp sepOp, HandleObject obj, uint32_
|
||||
* with those as well.
|
||||
*/
|
||||
break;
|
||||
} else if (elem.isBigInt()) {
|
||||
// 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());
|
||||
}
|
||||
|
||||
@@ -28,6 +28,8 @@
|
||||
|
||||
#include "vm/String-inl.h"
|
||||
|
||||
#include "vm/BigIntType.h"
|
||||
|
||||
using namespace js;
|
||||
using namespace js::gc;
|
||||
|
||||
@@ -484,6 +486,12 @@ ToAtomSlow(ExclusiveContext* cx, typename MaybeRooted<Value, allowGC>::HandleTyp
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
if (v.isBigInt()) {
|
||||
JSAtom* atom = BigIntToAtom(cx, v.toBigInt());
|
||||
if (!allowGC && !atom)
|
||||
cx->recoverFromOutOfMemory();
|
||||
return atom;
|
||||
}
|
||||
MOZ_ASSERT(v.isUndefined());
|
||||
return cx->names().undefined;
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include "vm/GlobalObject.h"
|
||||
#include "vm/ProxyObject.h"
|
||||
#include "vm/StringBuffer.h"
|
||||
#include "vm/BigIntType.h"
|
||||
|
||||
#include "vm/BooleanObject-inl.h"
|
||||
|
||||
@@ -170,6 +171,8 @@ js::ToBooleanSlow(HandleValue v)
|
||||
{
|
||||
if (v.isString())
|
||||
return v.toString()->length() != 0;
|
||||
if (v.isBigInt())
|
||||
return v.toBigInt()->toBoolean();
|
||||
|
||||
MOZ_ASSERT(v.isObject());
|
||||
return !EmulatesUndefined(&v.toObject());
|
||||
|
||||
@@ -339,6 +339,21 @@ JSCompartment::wrap(JSContext* cx, MutableHandleString strp)
|
||||
return true;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
bool
|
||||
JSCompartment::getNonWrapperObjectForCurrentCompartment(JSContext* cx, MutableHandleObject obj)
|
||||
{
|
||||
|
||||
@@ -583,6 +583,7 @@ struct JSCompartment
|
||||
MOZ_MUST_USE inline bool wrap(JSContext* cx, JS::MutableHandleValue vp);
|
||||
|
||||
MOZ_MUST_USE bool wrap(JSContext* cx, js::MutableHandleString strp);
|
||||
MOZ_MUST_USE bool wrap(JSContext* cx, js::MutableHandle<JS::BigInt*> bi);
|
||||
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);
|
||||
|
||||
@@ -79,6 +79,14 @@ JSCompartment::wrap(JSContext* cx, JS::MutableHandleValue vp)
|
||||
return true;
|
||||
}
|
||||
|
||||
if (vp.isBigInt()) {
|
||||
JS::RootedBigInt bi(cx, vp.toBigInt());
|
||||
if (!wrap(cx, &bi))
|
||||
return false;
|
||||
vp.setBigInt(bi);
|
||||
return true;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(vp.isObject());
|
||||
|
||||
/*
|
||||
|
||||
+6
-1
@@ -222,6 +222,7 @@
|
||||
#include "jit/JitcodeMap.h"
|
||||
#include "js/SliceBudget.h"
|
||||
#include "proxy/DeadObjectProxy.h"
|
||||
#include "vm/BigIntType.h"
|
||||
#include "vm/Debugger.h"
|
||||
#include "vm/ProxyObject.h"
|
||||
#include "vm/Shape.h"
|
||||
@@ -371,7 +372,8 @@ static const FinalizePhase BackgroundFinalizePhases[] = {
|
||||
AllocKind::STRING,
|
||||
AllocKind::FAT_INLINE_ATOM,
|
||||
AllocKind::ATOM,
|
||||
AllocKind::SYMBOL
|
||||
AllocKind::SYMBOL,
|
||||
AllocKind::BIGINT
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -1986,6 +1988,7 @@ MovingTracer::updateEdge(T** thingp)
|
||||
void MovingTracer::onObjectEdge(JSObject** objp) { updateEdge(objp); }
|
||||
void MovingTracer::onShapeEdge(Shape** shapep) { updateEdge(shapep); }
|
||||
void MovingTracer::onStringEdge(JSString** stringp) { updateEdge(stringp); }
|
||||
void MovingTracer::onBigIntEdge(JS::BigInt** bip) { updateEdge(bip); }
|
||||
void MovingTracer::onScriptEdge(JSScript** scriptp) { updateEdge(scriptp); }
|
||||
void MovingTracer::onLazyScriptEdge(LazyScript** lazyp) { updateEdge(lazyp); }
|
||||
void MovingTracer::onBaseShapeEdge(BaseShape** basep) { updateEdge(basep); }
|
||||
@@ -6557,6 +6560,8 @@ JS::GCCellPtr::GCCellPtr(const Value& v)
|
||||
ptr = checkedCast(&v.toObject(), JS::TraceKind::Object);
|
||||
else if (v.isSymbol())
|
||||
ptr = checkedCast(v.toSymbol(), JS::TraceKind::Symbol);
|
||||
else if (v.isBigInt())
|
||||
ptr = checkedCast(v.toBigInt(), JS::TraceKind::BigInt);
|
||||
else if (v.isPrivateGCThing())
|
||||
ptr = checkedCast(v.toGCThing(), v.toGCThing()->getTraceKind());
|
||||
else
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "threading/ConditionVariable.h"
|
||||
#include "threading/Thread.h"
|
||||
#include "vm/NativeObject.h"
|
||||
#include "vm/BigIntType.h"
|
||||
|
||||
namespace js {
|
||||
|
||||
@@ -119,6 +120,7 @@ IsNurseryAllocable(AllocKind kind)
|
||||
false, /* AllocKind::FAT_INLINE_ATOM */
|
||||
false, /* AllocKind::ATOM */
|
||||
false, /* AllocKind::SYMBOL */
|
||||
false, /* AllocKind::BIGINT */
|
||||
false, /* AllocKind::JITCODE */
|
||||
false, /* AllocKind::SCOPE */
|
||||
false, /* AllocKind::REGEXP_SHARED */
|
||||
@@ -158,6 +160,7 @@ IsBackgroundFinalized(AllocKind kind)
|
||||
true, /* AllocKind::FAT_INLINE_ATOM */
|
||||
true, /* AllocKind::ATOM */
|
||||
true, /* AllocKind::SYMBOL */
|
||||
true, /* AllocKind::BIGINT */
|
||||
false, /* AllocKind::JITCODE */
|
||||
true, /* AllocKind::SCOPE */
|
||||
true, /* AllocKind::REGEXP_SHARED */
|
||||
|
||||
+13
-3
@@ -1452,9 +1452,19 @@ js::ToNumberSlow(ExclusiveContext* 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() || v.isBigInt());
|
||||
if (cx->isJSContext()) {
|
||||
unsigned errnum = JSMSG_SYMBOL_TO_NUMBER;
|
||||
if (v.isBigInt())
|
||||
errnum = JSMSG_BIGINT_TO_NUMBER;
|
||||
JS_ReportErrorNumberASCII(cx->asJSContext(), GetErrorMessage, nullptr, errnum);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(bool)
|
||||
|
||||
+8
-3
@@ -3104,9 +3104,14 @@ js::PrimitiveToObject(JSContext* cx, const Value& v)
|
||||
return NumberObject::create(cx, v.toNumber());
|
||||
if (v.isBoolean())
|
||||
return BooleanObject::create(cx, v.toBoolean());
|
||||
MOZ_ASSERT(v.isSymbol());
|
||||
RootedSymbol symbol(cx, v.toSymbol());
|
||||
return SymbolObject::create(cx, symbol);
|
||||
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;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -626,6 +626,11 @@ Str(JSContext* cx, const Value& v, StringifyContext* scx)
|
||||
return NumberValueToStringBuffer(cx, v, scx->sb);
|
||||
}
|
||||
|
||||
if (v.isBigInt()) {
|
||||
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_BIGINT_NOT_SERIALIZABLE);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Step 10. */
|
||||
MOZ_ASSERT(v.isObject());
|
||||
RootedObject obj(cx, &v.toObject());
|
||||
|
||||
@@ -80,6 +80,7 @@ enum JSType {
|
||||
JSTYPE_BOOLEAN, /* boolean */
|
||||
JSTYPE_NULL, /* null */
|
||||
JSTYPE_SYMBOL, /* symbol */
|
||||
JSTYPE_BIGINT, /* BigInt */
|
||||
JSTYPE_LIMIT
|
||||
};
|
||||
|
||||
|
||||
@@ -3734,6 +3734,10 @@ js::ToStringSlow(ExclusiveContext* cx, typename MaybeRooted<Value, allowGC>::Han
|
||||
JSMSG_SYMBOL_TO_STRING);
|
||||
}
|
||||
return nullptr;
|
||||
} else if (v.isBigInt()) {
|
||||
if (!allowGC)
|
||||
return nullptr;
|
||||
str = BigInt::toString(cx, v.toBigInt());
|
||||
} else {
|
||||
MOZ_ASSERT(v.isUndefined());
|
||||
str = cx->names().undefined;
|
||||
|
||||
@@ -392,6 +392,7 @@ SOURCES += [
|
||||
'jsdtoa.cpp',
|
||||
'jsmath.cpp',
|
||||
'jsutil.cpp',
|
||||
'vm/BigIntType.cpp',
|
||||
'vm/Initialization.cpp',
|
||||
]
|
||||
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* 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 "jscntxt.h"
|
||||
|
||||
#include "gc/Allocator.h"
|
||||
#include "gc/Tracer.h"
|
||||
#include "vm/SelfHosting.h"
|
||||
|
||||
using namespace js;
|
||||
|
||||
BigInt*
|
||||
BigInt::create(js::ExclusiveContext* cx)
|
||||
{
|
||||
BigInt* x = Allocate<BigInt>(cx);
|
||||
if (!x)
|
||||
return nullptr;
|
||||
return x;
|
||||
}
|
||||
|
||||
BigInt*
|
||||
BigInt::copy(js::ExclusiveContext* cx, HandleBigInt x)
|
||||
{
|
||||
BigInt* bi = create(cx);
|
||||
if (!bi)
|
||||
return nullptr;
|
||||
return bi;
|
||||
}
|
||||
|
||||
JSLinearString*
|
||||
BigInt::toString(ExclusiveContext* cx, BigInt* x)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
BigInt::finalize(js::FreeOp* fop)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
JSAtom*
|
||||
js::BigIntToAtom(ExclusiveContext* 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());
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* 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/Marking.h"
|
||||
#include "gc/Heap.h"
|
||||
#include "js/GCHashTable.h"
|
||||
#include "js/RootingAPI.h"
|
||||
#include "js/TypeDecls.h"
|
||||
#include "vm/String.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_[16 + (16 % js::gc::CellSize)];
|
||||
|
||||
public:
|
||||
// Allocate and initialize a BigInt value
|
||||
static BigInt* create(js::ExclusiveContext* 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(js::ExclusiveContext* cx, BigInt* x);
|
||||
bool toBoolean();
|
||||
|
||||
static BigInt* copy(js::ExclusiveContext* cx, Handle<BigInt*> x);
|
||||
};
|
||||
|
||||
static_assert(sizeof(BigInt) >= js::gc::CellSize,
|
||||
"sizeof(BigInt) must be greater than the minimum allocation size");
|
||||
|
||||
} // namespace JS
|
||||
|
||||
namespace js {
|
||||
|
||||
extern JSAtom*
|
||||
BigIntToAtom(ExclusiveContext* cx, JS::BigInt* bi);
|
||||
|
||||
} // namespace js
|
||||
|
||||
#endif
|
||||
@@ -424,5 +424,6 @@
|
||||
macro(boolean, boolean, "boolean") \
|
||||
macro(null, null, "null") \
|
||||
macro(symbol, symbol, "symbol") \
|
||||
macro(bigint, bigint, "bigint") \
|
||||
|
||||
#endif /* vm_CommonPropertyNames_h */
|
||||
|
||||
@@ -40,6 +40,7 @@
|
||||
#include "jit/IonAnalysis.h"
|
||||
#include "vm/AsyncFunction.h"
|
||||
#include "vm/AsyncIteration.h"
|
||||
#include "vm/BigIntType.h"
|
||||
#include "vm/Debugger.h"
|
||||
#include "vm/EqualityOperations.h" // js::StrictlyEqual
|
||||
#include "vm/GeneratorObject.h"
|
||||
@@ -812,6 +813,8 @@ js::TypeOfValue(const Value& v)
|
||||
return TypeOfObject(&v.toObject());
|
||||
if (v.isBoolean())
|
||||
return JSTYPE_BOOLEAN;
|
||||
if (v.isBigInt())
|
||||
return JSTYPE_BIGINT;
|
||||
MOZ_ASSERT(v.isSymbol());
|
||||
return JSTYPE_SYMBOL;
|
||||
}
|
||||
@@ -4222,7 +4225,8 @@ 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() && !v.isBigInt())
|
||||
{
|
||||
NativeObject* proto;
|
||||
if (v.isNumber()) {
|
||||
proto = GlobalObject::getOrCreateNumberPrototype(cx, cx->global());
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "jit/BaselineJIT.h"
|
||||
#include "jit/Ion.h"
|
||||
#include "vm/ArrayObject.h"
|
||||
#include "vm/BigIntType.h"
|
||||
#include "vm/Runtime.h"
|
||||
#include "vm/Shape.h"
|
||||
#include "vm/String.h"
|
||||
@@ -546,6 +547,13 @@ StatsCellCallback(JSRuntime* rt, void* data, void* thing, JS::TraceKind traceKin
|
||||
zStats->symbolsGCHeap += thingSize;
|
||||
break;
|
||||
|
||||
case JS::TraceKind::BigInt: {
|
||||
JS::BigInt* bi = static_cast<BigInt*>(thing);
|
||||
zStats->bigIntsGCHeap += thingSize;
|
||||
zStats->bigIntsMallocHeap += bi->sizeOfExcludingThis(rtStats->mallocSizeOf_);
|
||||
break;
|
||||
}
|
||||
|
||||
case JS::TraceKind::BaseShape: {
|
||||
JS::ShapeInfo info; // This zeroes all the sizes.
|
||||
info.shapesGCHeapBase += thingSize;
|
||||
|
||||
@@ -170,6 +170,12 @@ js::ValueToStringBufferSlow(JSContext* cx, const Value& arg, StringBuffer& sb)
|
||||
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_SYMBOL_TO_STRING);
|
||||
return false;
|
||||
}
|
||||
if (v.isBigInt()) {
|
||||
JSString* str = BigInt::toString(cx, v.toBigInt());
|
||||
if (!str)
|
||||
return false;
|
||||
return sb.append(str);
|
||||
}
|
||||
MOZ_ASSERT(v.isUndefined());
|
||||
return sb.append(cx->names().undefined);
|
||||
}
|
||||
|
||||
@@ -213,6 +213,8 @@ PrimitiveTypeFlag(JSValueType type)
|
||||
return TYPE_FLAG_STRING;
|
||||
case JSVAL_TYPE_SYMBOL:
|
||||
return TYPE_FLAG_SYMBOL;
|
||||
case JSVAL_TYPE_BIGINT:
|
||||
return TYPE_FLAG_BIGINT;
|
||||
case JSVAL_TYPE_MAGIC:
|
||||
return TYPE_FLAG_LAZYARGS;
|
||||
default:
|
||||
@@ -238,6 +240,8 @@ TypeFlagPrimitive(TypeFlags flags)
|
||||
return JSVAL_TYPE_STRING;
|
||||
case TYPE_FLAG_SYMBOL:
|
||||
return JSVAL_TYPE_SYMBOL;
|
||||
case TYPE_FLAG_BIGINT:
|
||||
return JSVAL_TYPE_BIGINT;
|
||||
case TYPE_FLAG_LAZYARGS:
|
||||
return JSVAL_TYPE_MAGIC;
|
||||
default:
|
||||
|
||||
@@ -111,6 +111,8 @@ TypeSet::NonObjectTypeString(TypeSet::Type type)
|
||||
return "string";
|
||||
case JSVAL_TYPE_SYMBOL:
|
||||
return "symbol";
|
||||
case JSVAL_TYPE_BIGINT:
|
||||
return "BigInt";
|
||||
case JSVAL_TYPE_MAGIC:
|
||||
return "lazyargs";
|
||||
default:
|
||||
@@ -755,6 +757,8 @@ TypeSet::print(FILE* fp)
|
||||
fprintf(fp, " string");
|
||||
if (flags & TYPE_FLAG_SYMBOL)
|
||||
fprintf(fp, " symbol");
|
||||
if (flags & TYPE_FLAG_BIGINT)
|
||||
fprintf(fp, " BigInt");
|
||||
if (flags & TYPE_FLAG_LAZYARGS)
|
||||
fprintf(fp, " lazyargs");
|
||||
|
||||
|
||||
@@ -59,17 +59,18 @@ enum : uint32_t {
|
||||
TYPE_FLAG_DOUBLE = 0x10,
|
||||
TYPE_FLAG_STRING = 0x20,
|
||||
TYPE_FLAG_SYMBOL = 0x40,
|
||||
TYPE_FLAG_LAZYARGS = 0x80,
|
||||
TYPE_FLAG_ANYOBJECT = 0x100,
|
||||
TYPE_FLAG_BIGINT = 0x80,
|
||||
TYPE_FLAG_LAZYARGS = 0x100,
|
||||
TYPE_FLAG_ANYOBJECT = 0x200,
|
||||
|
||||
/* 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 |TYPE_FLAG_BIGINT,
|
||||
|
||||
/* Mask/shift for the number of objects in objectSet */
|
||||
TYPE_FLAG_OBJECT_COUNT_MASK = 0x3e00,
|
||||
TYPE_FLAG_OBJECT_COUNT_SHIFT = 9,
|
||||
TYPE_FLAG_OBJECT_COUNT_MASK = 0x3c00,
|
||||
TYPE_FLAG_OBJECT_COUNT_SHIFT = 10,
|
||||
TYPE_FLAG_OBJECT_COUNT_LIMIT = 7,
|
||||
TYPE_FLAG_DOMOBJECT_COUNT_LIMIT =
|
||||
TYPE_FLAG_OBJECT_COUNT_MASK >> TYPE_FLAG_OBJECT_COUNT_SHIFT,
|
||||
@@ -78,7 +79,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. */
|
||||
|
||||
@@ -109,6 +110,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 +371,7 @@ 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); }
|
||||
static inline Type BigIntType() { return Type(JSVAL_TYPE_BIGINT); }
|
||||
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); }
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include "js/TypeDecls.h"
|
||||
#include "js/Utility.h"
|
||||
#include "js/Vector.h"
|
||||
#include "vm/BigIntType.h"
|
||||
#include "vm/Debugger.h"
|
||||
#include "vm/EnvironmentObject.h"
|
||||
#include "vm/GlobalObject.h"
|
||||
@@ -202,7 +203,11 @@ Node::exposeToJS() const
|
||||
v.setString(as<JSString>());
|
||||
} else if (is<JS::Symbol>()) {
|
||||
v.setSymbol(as<JS::Symbol>());
|
||||
} else {
|
||||
}
|
||||
else if (is<BigInt>()) {
|
||||
v.setBigInt(as<BigInt>());
|
||||
}
|
||||
else {
|
||||
v.setUndefined();
|
||||
}
|
||||
|
||||
@@ -314,6 +319,7 @@ 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;
|
||||
template JS::Zone* TracerConcrete<BigInt>::zone() const;
|
||||
template JS::Zone* TracerConcrete<JSString>::zone() const;
|
||||
|
||||
template<typename Referent>
|
||||
@@ -337,6 +343,7 @@ 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;
|
||||
template UniquePtr<EdgeRange> TracerConcrete<BigInt>::edges(JSContext* cx, bool wantNames) const;
|
||||
template UniquePtr<EdgeRange> TracerConcrete<JSString>::edges(JSContext* cx, bool wantNames) const;
|
||||
|
||||
template<typename Referent>
|
||||
@@ -392,6 +399,7 @@ Concrete<JSObject>::jsObjectConstructorName(JSContext* cx, UniqueTwoByteChars& o
|
||||
}
|
||||
|
||||
const char16_t Concrete<JS::Symbol>::concreteTypeName[] = u"JS::Symbol";
|
||||
const char16_t Concrete<BigInt>::concreteTypeName[] = u"JS::BigInt";
|
||||
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";
|
||||
|
||||
Reference in New Issue
Block a user