mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-27 14:52:16 +00:00
Bug 1730843 - Part 1 - Add support for empty R&T based on objects r=jandem
This is an alternative implementation to D87232. I didn't implement object wrappers for these new primitive-like-objects yet, so `typeof Object(rec)` is currently `"record"` and not `"object"`. Differential Revision: https://phabricator.services.mozilla.com/D125644
This commit is contained in:
parent
7a7e49b72a
commit
ded6c32e63
@ -133,10 +133,30 @@ def static_js(value):
|
||||
set_define("MOZ_STATIC_JS", static_js)
|
||||
|
||||
|
||||
# Enable records and tuples
|
||||
# ===================================================
|
||||
option(
|
||||
"--enable-record-tuple",
|
||||
default=False,
|
||||
help="Enable records and tuples (and disables JIT)",
|
||||
)
|
||||
|
||||
|
||||
@depends("--enable-record-tuple")
|
||||
def enable_record_tuple(value):
|
||||
if value:
|
||||
return True
|
||||
|
||||
|
||||
set_config("ENABLE_RECORD_TUPLE", enable_record_tuple)
|
||||
set_define("ENABLE_RECORD_TUPLE", enable_record_tuple)
|
||||
|
||||
# JIT support
|
||||
# =======================================================
|
||||
@depends(target)
|
||||
def jit_default(target):
|
||||
@depends(target, "--enable-record-tuple")
|
||||
def jit_default(target, enable_record_tuple):
|
||||
if enable_record_tuple:
|
||||
return False
|
||||
if target.cpu in ("x86", "x86_64", "arm", "aarch64", "mips32", "mips64"):
|
||||
return True
|
||||
return False
|
||||
|
@ -814,6 +814,11 @@ enum class ESClass {
|
||||
BigInt,
|
||||
Function, // Note: Only JSFunction objects.
|
||||
|
||||
#ifdef ENABLE_RECORD_TUPLE
|
||||
Record,
|
||||
Tuple,
|
||||
#endif
|
||||
|
||||
/** None of the above. */
|
||||
Other
|
||||
};
|
||||
|
@ -133,7 +133,9 @@
|
||||
REAL(FinalizationRegistry, OCLASP(FinalizationRegistry)) \
|
||||
REAL(WeakRef, OCLASP(WeakRef)) \
|
||||
REAL(Iterator, OCLASP(Iterator)) \
|
||||
REAL(AsyncIterator, OCLASP(AsyncIterator))
|
||||
REAL(AsyncIterator, OCLASP(AsyncIterator)) \
|
||||
IF_RECORD_TUPLE(REAL(Record, (&RecordType::class_))) \
|
||||
IF_RECORD_TUPLE(REAL(Tuple, (&TupleType::class_)))
|
||||
|
||||
#define JS_FOR_PROTOTYPES(REAL, IMAGINARY) \
|
||||
JS_FOR_PROTOTYPES_(REAL, IMAGINARY, IF_INTL(REAL, IMAGINARY), \
|
||||
|
@ -48,6 +48,10 @@ typedef unsigned char Latin1Char;
|
||||
|
||||
class JS_PUBLIC_API Symbol;
|
||||
class JS_PUBLIC_API BigInt;
|
||||
#ifdef ENABLE_RECORD_TUPLE
|
||||
class JS_PUBLIC_API RecordType;
|
||||
class JS_PUBLIC_API TupleType;
|
||||
#endif
|
||||
class JS_PUBLIC_API Value;
|
||||
|
||||
class JS_PUBLIC_API Compartment;
|
||||
@ -127,4 +131,15 @@ using MutableHandleVector = MutableHandle<StackGCVector<T>>;
|
||||
|
||||
using jsid = JS::PropertyKey;
|
||||
|
||||
#ifdef ENABLE_RECORD_TUPLE
|
||||
// This takes 1 or 2 parameters. ... is just used so that
|
||||
// it's possible to omit the comma when passing a single
|
||||
// param:
|
||||
// IF_RECORD_TUPLE(doThis)
|
||||
// IF_RECORD_TUPLE(doThis, elseThis)
|
||||
# define IF_RECORD_TUPLE(x, ...) x
|
||||
#else
|
||||
# define IF_RECORD_TUPLE(x, ...) __VA_ARGS__
|
||||
#endif
|
||||
|
||||
#endif /* js_TypeDecls_h */
|
||||
|
@ -52,6 +52,9 @@ enum JSValueType : uint8_t {
|
||||
JSVAL_TYPE_SYMBOL = 0x07,
|
||||
JSVAL_TYPE_PRIVATE_GCTHING = 0x08,
|
||||
JSVAL_TYPE_BIGINT = 0x09,
|
||||
#ifdef ENABLE_RECORD_TUPLE
|
||||
JSVAL_TYPE_EXTENDED_PRIMITIVE = 0x0b,
|
||||
#endif
|
||||
JSVAL_TYPE_OBJECT = 0x0c,
|
||||
|
||||
// This type never appears in a Value; it's only an out-of-band value.
|
||||
@ -70,9 +73,12 @@ enum class ValueType : uint8_t {
|
||||
Symbol = JSVAL_TYPE_SYMBOL,
|
||||
PrivateGCThing = JSVAL_TYPE_PRIVATE_GCTHING,
|
||||
BigInt = JSVAL_TYPE_BIGINT,
|
||||
#ifdef ENABLE_RECORD_TUPLE
|
||||
ExtendedPrimitive = JSVAL_TYPE_EXTENDED_PRIMITIVE,
|
||||
#endif
|
||||
Object = JSVAL_TYPE_OBJECT,
|
||||
};
|
||||
}
|
||||
} // namespace JS
|
||||
|
||||
static_assert(sizeof(JSValueType) == 1,
|
||||
"compiler typed enum support is apparently buggy");
|
||||
@ -90,6 +96,10 @@ enum JSValueTag : uint32_t {
|
||||
JSVAL_TAG_SYMBOL = JSVAL_TAG_CLEAR | JSVAL_TYPE_SYMBOL,
|
||||
JSVAL_TAG_PRIVATE_GCTHING = JSVAL_TAG_CLEAR | JSVAL_TYPE_PRIVATE_GCTHING,
|
||||
JSVAL_TAG_BIGINT = JSVAL_TAG_CLEAR | JSVAL_TYPE_BIGINT,
|
||||
# ifdef ENABLE_RECORD_TUPLE
|
||||
JSVAL_TAG_EXTENDED_PRIMITIVE =
|
||||
JSVAL_TAG_CLEAR | JSVAL_TYPE_EXTENDED_PRIMITIVE,
|
||||
# endif
|
||||
JSVAL_TAG_OBJECT = JSVAL_TAG_CLEAR | JSVAL_TYPE_OBJECT
|
||||
};
|
||||
|
||||
@ -109,6 +119,10 @@ enum JSValueTag : uint32_t {
|
||||
JSVAL_TAG_SYMBOL = JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_SYMBOL,
|
||||
JSVAL_TAG_PRIVATE_GCTHING = JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_PRIVATE_GCTHING,
|
||||
JSVAL_TAG_BIGINT = JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_BIGINT,
|
||||
# ifdef ENABLE_RECORD_TUPLE
|
||||
JSVAL_TAG_EXTENDED_PRIMITIVE =
|
||||
JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_EXTENDED_PRIMITIVE,
|
||||
# endif
|
||||
JSVAL_TAG_OBJECT = JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_OBJECT
|
||||
};
|
||||
|
||||
@ -130,6 +144,10 @@ enum JSValueShiftedTag : uint64_t {
|
||||
JSVAL_SHIFTED_TAG_PRIVATE_GCTHING =
|
||||
(uint64_t(JSVAL_TAG_PRIVATE_GCTHING) << JSVAL_TAG_SHIFT),
|
||||
JSVAL_SHIFTED_TAG_BIGINT = (uint64_t(JSVAL_TAG_BIGINT) << JSVAL_TAG_SHIFT),
|
||||
# ifdef ENABLE_RECORD_TUPLE
|
||||
JSVAL_SHIFTED_TAG_EXTENDED_PRIMITIVE =
|
||||
(uint64_t(JSVAL_TYPE_EXTENDED_PRIMITIVE) << JSVAL_TAG_SHIFT),
|
||||
# endif
|
||||
JSVAL_SHIFTED_TAG_OBJECT = (uint64_t(JSVAL_TAG_OBJECT) << JSVAL_TAG_SHIFT)
|
||||
};
|
||||
|
||||
@ -273,6 +291,7 @@ enum JSWhyMagic {
|
||||
|
||||
namespace js {
|
||||
static inline JS::Value PoisonedObjectValue(uintptr_t poison);
|
||||
extern bool IsExtendedPrimitive(JSObject& obj);
|
||||
} // namespace js
|
||||
|
||||
namespace JS {
|
||||
@ -488,10 +507,23 @@ class alignas(8) Value {
|
||||
|
||||
void setObject(JSObject& obj) {
|
||||
MOZ_ASSERT(js::gc::IsCellPointerValid(&obj));
|
||||
#ifdef ENABLE_RECORD_TUPLE
|
||||
MOZ_ASSERT(!js::IsExtendedPrimitive(obj));
|
||||
#endif
|
||||
setObjectNoCheck(&obj);
|
||||
MOZ_ASSERT(&toObject() == &obj);
|
||||
}
|
||||
|
||||
#ifdef ENABLE_RECORD_TUPLE
|
||||
void setExtendedPrimitive(JSObject& obj) {
|
||||
MOZ_ASSERT(js::gc::IsCellPointerValid(&obj));
|
||||
MOZ_ASSERT(js::IsExtendedPrimitive(obj));
|
||||
asBits_ =
|
||||
bitsFromTagAndPayload(JSVAL_TAG_EXTENDED_PRIMITIVE, PayloadType(&obj));
|
||||
MOZ_ASSERT(&toExtendedPrimitive() == &obj);
|
||||
}
|
||||
#endif
|
||||
|
||||
private:
|
||||
void setObjectNoCheck(JSObject* obj) {
|
||||
asBits_ = bitsFromTagAndPayload(JSVAL_TAG_OBJECT, PayloadType(obj));
|
||||
@ -668,6 +700,16 @@ class alignas(8) Value {
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef ENABLE_RECORD_TUPLE
|
||||
bool isExtendedPrimitive() const {
|
||||
return toTag() == JSVAL_TAG_EXTENDED_PRIMITIVE;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool hasObjectPayload() const {
|
||||
return isObject() || IF_RECORD_TUPLE(isExtendedPrimitive(), false);
|
||||
}
|
||||
|
||||
bool isPrimitive() const {
|
||||
#if defined(JS_NUNBOX32)
|
||||
return uint32_t(toTag()) < uint32_t(detail::ValueUpperExclPrimitiveTag);
|
||||
@ -797,6 +839,24 @@ class alignas(8) Value {
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef ENABLE_RECORD_TUPLE
|
||||
JSObject& toExtendedPrimitive() const {
|
||||
MOZ_ASSERT(isExtendedPrimitive());
|
||||
# if defined(JS_PUNBOX64)
|
||||
MOZ_ASSERT((asBits_ & detail::ValueGCThingPayloadMask) != 0);
|
||||
# endif
|
||||
return *unboxGCPointer<JSObject, JSVAL_TAG_EXTENDED_PRIMITIVE>();
|
||||
}
|
||||
#endif
|
||||
|
||||
JSObject& getObjectPayload() const {
|
||||
#ifdef ENABLE_RECORD_TUPLE
|
||||
return isExtendedPrimitive() ? toExtendedPrimitive() : toObject();
|
||||
#else
|
||||
return toObject();
|
||||
#endif
|
||||
}
|
||||
|
||||
js::gc::Cell* toGCThing() const {
|
||||
MOZ_ASSERT(isGCThing());
|
||||
#if defined(JS_NUNBOX32)
|
||||
@ -1005,6 +1065,14 @@ static inline Value ObjectValue(JSObject& obj) {
|
||||
return v;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_RECORD_TUPLE
|
||||
static inline Value ExtendedPrimitiveValue(JSObject& obj) {
|
||||
Value v;
|
||||
v.setExtendedPrimitive(obj);
|
||||
return v;
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline Value MagicValue(JSWhyMagic why) {
|
||||
Value v;
|
||||
v.setMagic(why);
|
||||
@ -1143,6 +1211,10 @@ class WrappedPtrOperations<JS::Value, Wrapper> {
|
||||
bool isSymbol() const { return value().isSymbol(); }
|
||||
bool isBigInt() const { return value().isBigInt(); }
|
||||
bool isObject() const { return value().isObject(); }
|
||||
#ifdef ENABLE_RECORD_TUPLE
|
||||
bool isExtendedPrimitive() const { return value().isExtendedPrimitive(); }
|
||||
#endif
|
||||
bool hasObjectPayload() const { return value().hasObjectPayload(); }
|
||||
bool isMagic() const { return value().isMagic(); }
|
||||
bool isMagic(JSWhyMagic why) const { return value().isMagic(why); }
|
||||
bool isGCThing() const { return value().isGCThing(); }
|
||||
@ -1162,6 +1234,12 @@ class WrappedPtrOperations<JS::Value, Wrapper> {
|
||||
JS::BigInt* toBigInt() const { return value().toBigInt(); }
|
||||
JSObject& toObject() const { return value().toObject(); }
|
||||
JSObject* toObjectOrNull() const { return value().toObjectOrNull(); }
|
||||
#ifdef ENABLE_RECORD_TUPLE
|
||||
JSObject& toExtendedPrimitive() const {
|
||||
return value().toExtendedPrimitive();
|
||||
}
|
||||
#endif
|
||||
JSObject& getObjectPayload() const { return value().getObjectPayload(); }
|
||||
JS::GCCellPtr toGCCellPtr() const { return value().toGCCellPtr(); }
|
||||
gc::Cell* toGCThing() const { return value().toGCThing(); }
|
||||
JS::TraceKind traceKind() const { return value().traceKind(); }
|
||||
@ -1211,6 +1289,11 @@ class MutableWrappedPtrOperations<JS::Value, Wrapper>
|
||||
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)); }
|
||||
#ifdef ENABLE_RECORD_TUPLE
|
||||
void setExtendedPrimitive(JSObject& obj) {
|
||||
return set(JS::ExtendedPrimitiveValue(obj));
|
||||
}
|
||||
#endif
|
||||
void setPrivate(void* ptr) { set(JS::PrivateValue(ptr)); }
|
||||
void setPrivateUint32(uint32_t ui) { set(JS::PrivateUint32Value(ui)); }
|
||||
void setPrivateGCThing(js::gc::Cell* cell) {
|
||||
@ -1239,8 +1322,11 @@ auto MapGCThingTyped(const JS::Value& val, F&& f) {
|
||||
MOZ_ASSERT(gc::IsCellPointerValid(str));
|
||||
return mozilla::Some(f(str));
|
||||
}
|
||||
#ifdef ENABLE_RECORD_TUPLE
|
||||
case JS::ValueType::ExtendedPrimitive:
|
||||
#endif
|
||||
case JS::ValueType::Object: {
|
||||
JSObject* obj = &val.toObject();
|
||||
JSObject* obj = &val.getObjectPayload();
|
||||
MOZ_ASSERT(gc::IsCellPointerValid(obj));
|
||||
return mozilla::Some(f(obj));
|
||||
}
|
||||
|
@ -50,6 +50,9 @@ using JS::NullValue;
|
||||
using JS::NumberValue;
|
||||
using JS::ObjectOrNullValue;
|
||||
using JS::ObjectValue;
|
||||
#ifdef ENABLE_RECORD_TUPLE
|
||||
using JS::ExtendedPrimitiveValue;
|
||||
#endif
|
||||
using JS::PrivateGCThingValue;
|
||||
using JS::PrivateUint32Value;
|
||||
using JS::PrivateValue;
|
||||
@ -148,6 +151,11 @@ using JS::Zone;
|
||||
|
||||
using JS::BigInt;
|
||||
|
||||
#ifdef ENABLE_RECORD_TUPLE
|
||||
using JS::RecordType;
|
||||
using JS::TupleType;
|
||||
#endif
|
||||
|
||||
} /* namespace js */
|
||||
|
||||
#endif /* NamespaceImports_h */
|
||||
|
@ -265,7 +265,7 @@ bool AtomMarkingRuntime::valueIsMarked(Zone* zone, const Value& value) {
|
||||
return atomIsMarked(zone, value.toSymbol());
|
||||
}
|
||||
|
||||
MOZ_ASSERT_IF(value.isGCThing(), value.isObject() ||
|
||||
MOZ_ASSERT_IF(value.isGCThing(), value.hasObjectPayload() ||
|
||||
value.isPrivateGCThing() ||
|
||||
value.isBigInt());
|
||||
return true;
|
||||
|
@ -2139,6 +2139,9 @@ AttachDecision GetPropIRGenerator::tryAttachPrimitive(ValOperandId valId,
|
||||
case ValueType::Undefined:
|
||||
case ValueType::Magic:
|
||||
return AttachDecision::NoAction;
|
||||
#ifdef ENABLE_RECORD_TUPLE
|
||||
case ValueType::ExtendedPrimitive:
|
||||
#endif
|
||||
case ValueType::Object:
|
||||
case ValueType::PrivateGCThing:
|
||||
MOZ_CRASH("unexpected type");
|
||||
@ -7836,6 +7839,9 @@ AttachDecision CallIRGenerator::tryAttachObjectIs(HandleFunction callee) {
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_RECORD_TUPLE
|
||||
case ValueType::ExtendedPrimitive:
|
||||
#endif
|
||||
case JS::ValueType::Double:
|
||||
case JS::ValueType::Magic:
|
||||
case JS::ValueType::PrivateGCThing:
|
||||
@ -8049,6 +8055,9 @@ AttachDecision CallIRGenerator::tryAttachSetHas(HandleFunction callee) {
|
||||
break;
|
||||
}
|
||||
|
||||
# ifdef ENABLE_RECORD_TUPLE
|
||||
case ValueType::ExtendedPrimitive:
|
||||
# endif
|
||||
case ValueType::Magic:
|
||||
case ValueType::PrivateGCThing:
|
||||
MOZ_CRASH("Unexpected type");
|
||||
@ -8133,6 +8142,9 @@ AttachDecision CallIRGenerator::tryAttachMapHas(HandleFunction callee) {
|
||||
break;
|
||||
}
|
||||
|
||||
# ifdef ENABLE_RECORD_TUPLE
|
||||
case ValueType::ExtendedPrimitive:
|
||||
# endif
|
||||
case ValueType::Magic:
|
||||
case ValueType::PrivateGCThing:
|
||||
MOZ_CRASH("Unexpected type");
|
||||
@ -8217,6 +8229,9 @@ AttachDecision CallIRGenerator::tryAttachMapGet(HandleFunction callee) {
|
||||
break;
|
||||
}
|
||||
|
||||
# ifdef ENABLE_RECORD_TUPLE
|
||||
case ValueType::ExtendedPrimitive:
|
||||
# endif
|
||||
case ValueType::Magic:
|
||||
case ValueType::PrivateGCThing:
|
||||
MOZ_CRASH("Unexpected type");
|
||||
|
@ -1908,6 +1908,9 @@ bool CacheIRCompiler::emitGuardNonDoubleType(ValOperandId inputId,
|
||||
case ValueType::Magic:
|
||||
case ValueType::PrivateGCThing:
|
||||
case ValueType::Object:
|
||||
#ifdef ENABLE_RECORD_TUPLE
|
||||
case ValueType::ExtendedPrimitive:
|
||||
#endif
|
||||
MOZ_CRASH("unexpected type");
|
||||
}
|
||||
|
||||
|
@ -13056,6 +13056,10 @@ void CodeGenerator::emitTypeOfIsObject(MTypeOfIs* mir, Register obj,
|
||||
case JSTYPE_BOOLEAN:
|
||||
case JSTYPE_SYMBOL:
|
||||
case JSTYPE_BIGINT:
|
||||
#ifdef ENABLE_RECORD_TUPLE
|
||||
case JSTYPE_RECORD:
|
||||
case JSTYPE_TUPLE:
|
||||
#endif
|
||||
case JSTYPE_LIMIT:
|
||||
MOZ_CRASH("Primitive type");
|
||||
}
|
||||
@ -13114,6 +13118,10 @@ void CodeGenerator::visitTypeOfIsNonPrimitiveV(LTypeOfIsNonPrimitiveV* lir) {
|
||||
case JSTYPE_BOOLEAN:
|
||||
case JSTYPE_SYMBOL:
|
||||
case JSTYPE_BIGINT:
|
||||
#ifdef ENABLE_RECORD_TUPLE
|
||||
case JSTYPE_RECORD:
|
||||
case JSTYPE_TUPLE:
|
||||
#endif
|
||||
case JSTYPE_LIMIT:
|
||||
MOZ_CRASH("Primitive type");
|
||||
}
|
||||
@ -13167,6 +13175,10 @@ void CodeGenerator::visitTypeOfIsPrimitive(LTypeOfIsPrimitive* lir) {
|
||||
case JSTYPE_UNDEFINED:
|
||||
case JSTYPE_OBJECT:
|
||||
case JSTYPE_FUNCTION:
|
||||
#ifdef ENABLE_RECORD_TUPLE
|
||||
case JSTYPE_RECORD:
|
||||
case JSTYPE_TUPLE:
|
||||
#endif
|
||||
case JSTYPE_LIMIT:
|
||||
MOZ_CRASH("Non-primitive type");
|
||||
}
|
||||
|
@ -1330,6 +1330,10 @@ void LIRGenerator::visitTypeOfIs(MTypeOfIs* ins) {
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_RECORD_TUPLE
|
||||
case JSTYPE_RECORD:
|
||||
case JSTYPE_TUPLE:
|
||||
#endif
|
||||
case JSTYPE_LIMIT:
|
||||
break;
|
||||
}
|
||||
|
@ -1342,6 +1342,10 @@ void MTypeOfIs::printOpcode(GenericPrinter& out) const {
|
||||
case JSTYPE_BIGINT:
|
||||
name = "bigint";
|
||||
break;
|
||||
# ifdef ENABLE_RECORD_TUPLE
|
||||
case JSTYPE_RECORD:
|
||||
case JSTYPE_TUPLE:
|
||||
# endif
|
||||
case JSTYPE_LIMIT:
|
||||
MOZ_CRASH("Unexpected type");
|
||||
}
|
||||
@ -3832,6 +3836,9 @@ static JSType TypeOfName(JSLinearString* str) {
|
||||
static constexpr std::array types = {
|
||||
JSTYPE_UNDEFINED, JSTYPE_OBJECT, JSTYPE_FUNCTION, JSTYPE_STRING,
|
||||
JSTYPE_NUMBER, JSTYPE_BOOLEAN, JSTYPE_SYMBOL, JSTYPE_BIGINT,
|
||||
#ifdef ENABLE_RECORD_TUPLE
|
||||
JSTYPE_RECORD, JSTYPE_TUPLE,
|
||||
#endif
|
||||
};
|
||||
static_assert(types.size() == JSTYPE_LIMIT);
|
||||
|
||||
@ -3941,6 +3948,11 @@ bool MCompare::tryFoldTypeOf(bool* result) {
|
||||
case JSTYPE_LIMIT:
|
||||
*result = (jsop() == JSOp::StrictNe || jsop() == JSOp::Ne);
|
||||
return true;
|
||||
#ifdef ENABLE_RECORD_TUPLE
|
||||
case JSTYPE_RECORD:
|
||||
case JSTYPE_TUPLE:
|
||||
MOZ_CRASH("Records and Tuples are not supported yet.");
|
||||
#endif
|
||||
}
|
||||
|
||||
return false;
|
||||
|
@ -1037,6 +1037,9 @@ bool WarpCacheIRTranspiler::emitGuardNonDoubleType(ValOperandId inputId,
|
||||
case ValueType::Magic:
|
||||
case ValueType::PrivateGCThing:
|
||||
case ValueType::Object:
|
||||
#ifdef ENABLE_RECORD_TUPLE
|
||||
case ValueType::ExtendedPrimitive:
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -778,8 +778,8 @@ const char* js::ValueToSourceForError(JSContext* cx, HandleValue val,
|
||||
}
|
||||
|
||||
JSStringBuilder sb(cx);
|
||||
if (val.isObject()) {
|
||||
RootedObject valObj(cx, val.toObjectOrNull());
|
||||
if (val.hasObjectPayload()) {
|
||||
RootedObject valObj(cx, &val.getObjectPayload());
|
||||
ESClass cls;
|
||||
if (!JS::GetBuiltinClass(cx, valObj, &cls)) {
|
||||
return "<<error determining class of value>>";
|
||||
@ -791,6 +791,12 @@ const char* js::ValueToSourceForError(JSContext* cx, HandleValue val,
|
||||
s = "the array buffer ";
|
||||
} else if (JS_IsArrayBufferViewObject(valObj)) {
|
||||
s = "the typed array ";
|
||||
#ifdef ENABLE_RECORD_TUPLE
|
||||
} else if (cls == ESClass::Record) {
|
||||
s = "the record ";
|
||||
} else if (cls == ESClass::Tuple) {
|
||||
s = "the tuple ";
|
||||
#endif
|
||||
} else {
|
||||
s = "the object ";
|
||||
}
|
||||
|
@ -42,6 +42,10 @@
|
||||
#include "vm/Realm.h"
|
||||
#include "vm/StringObject.h"
|
||||
#include "vm/WrapperObject.h"
|
||||
#ifdef ENABLE_RECORD_TUPLE
|
||||
# include "vm/RecordType.h"
|
||||
# include "vm/TupleType.h"
|
||||
#endif
|
||||
|
||||
#include "vm/Compartment-inl.h" // JS::Compartment::wrap
|
||||
#include "vm/JSObject-inl.h"
|
||||
@ -259,6 +263,12 @@ JS_PUBLIC_API bool JS::GetBuiltinClass(JSContext* cx, HandleObject obj,
|
||||
*cls = ESClass::Error;
|
||||
} else if (obj->is<BigIntObject>()) {
|
||||
*cls = ESClass::BigInt;
|
||||
#ifdef ENABLE_RECORD_TUPLE
|
||||
} else if (obj->is<RecordType>()) {
|
||||
*cls = ESClass::Record;
|
||||
} else if (obj->is<TupleType>()) {
|
||||
*cls = ESClass::Tuple;
|
||||
#endif
|
||||
} else if (obj->is<JSFunction>()) {
|
||||
*cls = ESClass::Function;
|
||||
} else {
|
||||
|
@ -40,6 +40,10 @@ enum JSType {
|
||||
JSTYPE_BOOLEAN, /* boolean */
|
||||
JSTYPE_SYMBOL, /* symbol */
|
||||
JSTYPE_BIGINT, /* BigInt */
|
||||
#ifdef ENABLE_RECORD_TUPLE
|
||||
JSTYPE_RECORD, /* record */
|
||||
JSTYPE_TUPLE, /* tuple */
|
||||
#endif
|
||||
JSTYPE_LIMIT
|
||||
};
|
||||
|
||||
|
@ -470,6 +470,13 @@ SOURCES += [
|
||||
"vm/ProfilingStack.cpp",
|
||||
]
|
||||
|
||||
if CONFIG["ENABLE_RECORD_TUPLE"]:
|
||||
UNIFIED_SOURCES += [
|
||||
"vm/RecordTupleBoxShared.cpp",
|
||||
"vm/RecordType.cpp",
|
||||
"vm/TupleType.cpp",
|
||||
]
|
||||
|
||||
if CONFIG["JS_HAS_INTL_API"]:
|
||||
UNIFIED_SOURCES += [
|
||||
"builtin/intl/Collator.cpp",
|
||||
|
0
js/src/tests/non262/Record/browser.js
Normal file
0
js/src/tests/non262/Record/browser.js
Normal file
14
js/src/tests/non262/Record/constructor.js
Normal file
14
js/src/tests/non262/Record/constructor.js
Normal file
@ -0,0 +1,14 @@
|
||||
// |reftest| skip-if(!this.hasOwnProperty("Record"))
|
||||
|
||||
assertThrowsInstanceOf(
|
||||
() => new Record(),
|
||||
TypeError,
|
||||
"Record is not a constructor"
|
||||
);
|
||||
|
||||
assertEq(typeof Record(), "record");
|
||||
//assertEq(typeof Object(Record()), "record");
|
||||
assertEq(Record() instanceof Record, false);
|
||||
//assertThrowsInstanceOf(() => Object(Record()) instanceof Record, TypeError);
|
||||
|
||||
if (typeof reportCompare === "function") reportCompare(0, 0);
|
0
js/src/tests/non262/Record/shell.js
Normal file
0
js/src/tests/non262/Record/shell.js
Normal file
0
js/src/tests/non262/Tuple/browser.js
Normal file
0
js/src/tests/non262/Tuple/browser.js
Normal file
14
js/src/tests/non262/Tuple/constructor.js
Normal file
14
js/src/tests/non262/Tuple/constructor.js
Normal file
@ -0,0 +1,14 @@
|
||||
// |reftest| skip-if(!this.hasOwnProperty("Tuple"))
|
||||
|
||||
assertThrowsInstanceOf(
|
||||
() => new Tuple(),
|
||||
TypeError,
|
||||
"Tuple is not a constructor"
|
||||
);
|
||||
|
||||
assertEq(typeof Tuple(), "tuple");
|
||||
//assertEq(typeof Object(Tuple()), "tuple");
|
||||
assertEq(Tuple() instanceof Tuple, false);
|
||||
//assertEq(Object(Tuple()) instanceof Tuple, true);
|
||||
|
||||
if (typeof reportCompare === "function") reportCompare(0, 0);
|
0
js/src/tests/non262/Tuple/shell.js
Normal file
0
js/src/tests/non262/Tuple/shell.js
Normal file
@ -363,10 +363,12 @@
|
||||
MACRO_(objectNull, objectNull, "[object Null]") \
|
||||
MACRO_(objectNumber, objectNumber, "[object Number]") \
|
||||
MACRO_(objectObject, objectObject, "[object Object]") \
|
||||
IF_RECORD_TUPLE(MACRO_(objectRecord, objectRecord, "[object Record]")) \
|
||||
MACRO_(objectRegExp, objectRegExp, "[object RegExp]") \
|
||||
MACRO_(objects, objects, "objects") \
|
||||
MACRO_(objectString, objectString, "[object String]") \
|
||||
MACRO_(objectSymbol, objectSymbol, "[object Symbol]") \
|
||||
IF_RECORD_TUPLE(MACRO_(objectTuple, objectTuple, "[object Tuple]")) \
|
||||
MACRO_(objectUndefined, objectUndefined, "[object Undefined]") \
|
||||
MACRO_(Object_valueOf, Object_valueOf, "Object_valueOf") \
|
||||
MACRO2(of, of, "of") \
|
||||
@ -568,7 +570,9 @@
|
||||
MACRO_(number, number, "number") \
|
||||
MACRO_(boolean, boolean, "boolean") \
|
||||
MACRO_(symbol, symbol, "symbol") \
|
||||
MACRO_(bigint, bigint, "bigint")
|
||||
MACRO_(bigint, bigint, "bigint") \
|
||||
IF_RECORD_TUPLE(MACRO_(record, record, "record")) \
|
||||
IF_RECORD_TUPLE(MACRO_(tuple, tuple, "tuple"))
|
||||
|
||||
#define PROPERTY_NAME_IGNORE(IDPART, ID, TEXT)
|
||||
|
||||
|
@ -65,6 +65,10 @@
|
||||
#include "vm/SelfHosting.h"
|
||||
#include "vm/StringObject.h"
|
||||
#include "wasm/WasmJS.h"
|
||||
#ifdef ENABLE_RECORD_TUPLE
|
||||
# include "vm/RecordType.h"
|
||||
# include "vm/TupleType.h"
|
||||
#endif
|
||||
|
||||
#include "gc/FreeOp-inl.h"
|
||||
#include "vm/JSObject-inl.h"
|
||||
@ -150,6 +154,10 @@ bool GlobalObject::skipDeselectedConstructor(JSContext* cx, JSProtoKey key) {
|
||||
case JSProto_AsyncFunction:
|
||||
case JSProto_GeneratorFunction:
|
||||
case JSProto_AsyncGeneratorFunction:
|
||||
#ifdef ENABLE_RECORD_TUPLE
|
||||
case JSProto_Record:
|
||||
case JSProto_Tuple:
|
||||
#endif
|
||||
return false;
|
||||
|
||||
case JSProto_WebAssembly:
|
||||
|
@ -543,6 +543,24 @@ class GlobalObject : public NativeObject {
|
||||
return &global->getPrototype(JSProto_BigInt);
|
||||
}
|
||||
|
||||
#ifdef ENABLE_RECORD_TUPLE
|
||||
static JSObject* getOrCreateRecordPrototype(JSContext* cx,
|
||||
Handle<GlobalObject*> global) {
|
||||
if (!ensureConstructor(cx, global, JSProto_Record)) {
|
||||
return nullptr;
|
||||
}
|
||||
return &global->getPrototype(JSProto_Record);
|
||||
}
|
||||
|
||||
static JSObject* getOrCreateTuplePrototype(JSContext* cx,
|
||||
Handle<GlobalObject*> global) {
|
||||
if (!ensureConstructor(cx, global, JSProto_Tuple)) {
|
||||
return nullptr;
|
||||
}
|
||||
return &global->getPrototype(JSProto_Tuple);
|
||||
}
|
||||
#endif
|
||||
|
||||
static JSObject* getOrCreatePromisePrototype(JSContext* cx,
|
||||
Handle<GlobalObject*> global) {
|
||||
if (!ensureConstructor(cx, global, JSProto_Promise)) {
|
||||
|
@ -63,6 +63,10 @@
|
||||
#include "vm/StringType.h"
|
||||
#include "vm/ThrowMsgKind.h" // ThrowMsgKind
|
||||
#include "vm/TraceLogging.h"
|
||||
#ifdef ENABLE_RECORD_TUPLE
|
||||
# include "vm/RecordType.h"
|
||||
# include "vm/TupleType.h"
|
||||
#endif
|
||||
|
||||
#include "builtin/Boolean-inl.h"
|
||||
#include "debugger/DebugAPI-inl.h"
|
||||
@ -811,6 +815,10 @@ bool js::HasInstance(JSContext* cx, HandleObject obj, HandleValue v, bool* bp) {
|
||||
}
|
||||
|
||||
JSType js::TypeOfObject(JSObject* obj) {
|
||||
#ifdef ENABLE_RECORD_TUPLE
|
||||
MOZ_ASSERT(!js::IsExtendedPrimitive(*obj));
|
||||
#endif
|
||||
|
||||
AutoUnsafeCallWithABI unsafe;
|
||||
if (EmulatesUndefined(obj)) {
|
||||
return JSTYPE_UNDEFINED;
|
||||
@ -821,6 +829,20 @@ JSType js::TypeOfObject(JSObject* obj) {
|
||||
return JSTYPE_OBJECT;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_RECORD_TUPLE
|
||||
JSType TypeOfExtendedPrimitive(JSObject* obj) {
|
||||
MOZ_ASSERT(js::IsExtendedPrimitive(*obj));
|
||||
|
||||
if (obj->is<RecordType>()) {
|
||||
return JSTYPE_RECORD;
|
||||
}
|
||||
if (obj->is<TupleType>()) {
|
||||
return JSTYPE_TUPLE;
|
||||
}
|
||||
MOZ_CRASH("Unknown ExtendedPrimitive");
|
||||
}
|
||||
#endif
|
||||
|
||||
JSType js::TypeOfValue(const Value& v) {
|
||||
switch (v.type()) {
|
||||
case ValueType::Double:
|
||||
@ -834,6 +856,10 @@ JSType js::TypeOfValue(const Value& v) {
|
||||
return JSTYPE_UNDEFINED;
|
||||
case ValueType::Object:
|
||||
return TypeOfObject(&v.toObject());
|
||||
#ifdef ENABLE_RECORD_TUPLE
|
||||
case ValueType::ExtendedPrimitive:
|
||||
return TypeOfExtendedPrimitive(&v.toExtendedPrimitive());
|
||||
#endif
|
||||
case ValueType::Boolean:
|
||||
return JSTYPE_BOOLEAN;
|
||||
case ValueType::BigInt:
|
||||
@ -1252,6 +1278,13 @@ again:
|
||||
REGS.sp++->setObjectOrNull(obj); \
|
||||
cx->debugOnlyCheck(REGS.sp[-1]); \
|
||||
} while (0)
|
||||
#ifdef ENABLE_RECORD_TUPLE
|
||||
# define PUSH_EXTENDED_PRIMITIVE(obj) \
|
||||
do { \
|
||||
REGS.sp++->setExtendedPrimitive(obj); \
|
||||
cx->debugOnlyCheck(REGS.sp[-1]); \
|
||||
} while (0)
|
||||
#endif
|
||||
#define PUSH_MAGIC(magic) REGS.sp++->setMagic(magic)
|
||||
#define POP_COPY_TO(v) (v) = *--REGS.sp
|
||||
#define POP_RETURN_VALUE() REGS.fp()->setReturnValue(*--REGS.sp)
|
||||
@ -4505,7 +4538,8 @@ bool js::GetProperty(JSContext* cx, HandleValue v, HandlePropertyName name,
|
||||
|
||||
// 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_RECORD_TUPLE(!v.isExtendedPrimitive(), true)) {
|
||||
JSObject* proto;
|
||||
|
||||
switch (v.type()) {
|
||||
@ -4525,6 +4559,9 @@ bool js::GetProperty(JSContext* cx, HandleValue v, HandlePropertyName name,
|
||||
case ValueType::BigInt:
|
||||
proto = GlobalObject::getOrCreateBigIntPrototype(cx, cx->global());
|
||||
break;
|
||||
#ifdef ENABLE_RECORD_TUPLE
|
||||
case ValueType::ExtendedPrimitive:
|
||||
#endif
|
||||
case ValueType::Undefined:
|
||||
case ValueType::Null:
|
||||
case ValueType::Magic:
|
||||
|
@ -66,6 +66,10 @@
|
||||
#include "vm/WellKnownAtom.h" // js_*_str
|
||||
#include "vm/WrapperObject.h"
|
||||
#include "wasm/AsmJS.h"
|
||||
#ifdef ENABLE_RECORD_TUPLE
|
||||
# include "vm/RecordType.h"
|
||||
# include "vm/TupleType.h"
|
||||
#endif
|
||||
|
||||
#include "debugger/DebugAPI-inl.h"
|
||||
#include "vm/FrameIter-inl.h" // js::FrameIter::unaliasedForEachActual
|
||||
@ -2216,6 +2220,11 @@ void js::ReportIncompatibleMethod(JSContext* cx, const CallArgs& args,
|
||||
!thisv.toObject().staticPrototype() ||
|
||||
thisv.toObject().staticPrototype()->getClass() != clasp);
|
||||
break;
|
||||
# ifdef ENABLE_RECORD_TUPLE
|
||||
case ValueType::ExtendedPrimitive:
|
||||
MOZ_CRASH("ExtendedPrimitive is not supported yet");
|
||||
break;
|
||||
# endif
|
||||
case ValueType::String:
|
||||
MOZ_ASSERT(clasp != &StringObject::class_);
|
||||
break;
|
||||
|
@ -63,6 +63,10 @@
|
||||
#include "vm/Shape.h"
|
||||
#include "vm/TypedArrayObject.h"
|
||||
#include "vm/WellKnownAtom.h" // js_*_str
|
||||
#ifdef ENABLE_RECORD_TUPLE
|
||||
# include "vm/RecordType.h"
|
||||
# include "vm/TupleType.h"
|
||||
#endif
|
||||
|
||||
#include "builtin/Boolean-inl.h"
|
||||
#include "gc/Marking-inl.h"
|
||||
@ -131,7 +135,10 @@ JS_PUBLIC_API const char* JS::InformalValueTypeName(const Value& v) {
|
||||
case ValueType::BigInt:
|
||||
return "bigint";
|
||||
case ValueType::Object:
|
||||
return v.toObject().getClass()->name;
|
||||
#ifdef ENABLE_RECORD_TUPLE
|
||||
case ValueType::ExtendedPrimitive:
|
||||
#endif
|
||||
return v.getObjectPayload().getClass()->name;
|
||||
case ValueType::Magic:
|
||||
return "magic";
|
||||
case ValueType::PrivateGCThing:
|
||||
@ -2442,6 +2449,11 @@ JSObject* js::PrimitiveToObject(JSContext* cx, const Value& v) {
|
||||
RootedBigInt bigInt(cx, v.toBigInt());
|
||||
return BigIntObject::create(cx, bigInt);
|
||||
}
|
||||
#ifdef ENABLE_RECORD_TUPLE
|
||||
case ValueType::ExtendedPrimitive: {
|
||||
MOZ_CRASH("ExtendedPrimitive is not supported yet");
|
||||
}
|
||||
#endif
|
||||
case ValueType::Undefined:
|
||||
case ValueType::Null:
|
||||
case ValueType::Magic:
|
||||
@ -2470,6 +2482,16 @@ JSProtoKey js::PrimitiveToProtoKey(JSContext* cx, const Value& v) {
|
||||
return JSProto_Symbol;
|
||||
case ValueType::BigInt:
|
||||
return JSProto_BigInt;
|
||||
#ifdef ENABLE_RECORD_TUPLE
|
||||
case ValueType::ExtendedPrimitive:
|
||||
if (v.toExtendedPrimitive().is<TupleType>()) {
|
||||
return JSProto_Tuple;
|
||||
}
|
||||
if (v.toExtendedPrimitive().is<RecordType>()) {
|
||||
return JSProto_Null;
|
||||
}
|
||||
MOZ_CRASH("Unsupported ExtendedPrimitive");
|
||||
#endif
|
||||
case ValueType::Undefined:
|
||||
case ValueType::Null:
|
||||
case ValueType::Magic:
|
||||
@ -2710,6 +2732,13 @@ static void dumpValue(const Value& v, js::GenericPrinter& out) {
|
||||
(void*)obj);
|
||||
}
|
||||
break;
|
||||
# ifdef ENABLE_RECORD_TUPLE
|
||||
case ValueType::ExtendedPrimitive: {
|
||||
JSObject* obj = &v.toExtendedPrimitive();
|
||||
out.printf("<%s at %p>", obj->getClass()->name, (void*)obj);
|
||||
break;
|
||||
}
|
||||
# endif
|
||||
case ValueType::Boolean:
|
||||
if (v.toBoolean()) {
|
||||
out.put("true");
|
||||
|
23
js/src/vm/RecordTupleBoxShared.cpp
Normal file
23
js/src/vm/RecordTupleBoxShared.cpp
Normal file
@ -0,0 +1,23 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* vim: set ts=8 sts=2 et sw=2 tw=80:
|
||||
* 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_RecordTupleBoxShared_h
|
||||
#define vm_RecordTupleBoxShared_h
|
||||
|
||||
#include "vm/RecordTupleBoxShared.h"
|
||||
|
||||
#include "vm/RecordType.h"
|
||||
#include "vm/TupleType.h"
|
||||
|
||||
namespace js {
|
||||
|
||||
bool IsExtendedPrimitive(JSObject& obj) {
|
||||
return obj.is<RecordType>() || obj.is<TupleType>();
|
||||
}
|
||||
|
||||
} // namespace js
|
||||
|
||||
#endif
|
19
js/src/vm/RecordTupleBoxShared.h
Normal file
19
js/src/vm/RecordTupleBoxShared.h
Normal file
@ -0,0 +1,19 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* vim: set ts=8 sts=2 et sw=2 tw=80:
|
||||
* 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_RecordTupleBoxShared_h
|
||||
#define vm_RecordTupleBoxShared_h
|
||||
|
||||
#include "js/ErrorReport.h"
|
||||
#include "js/TypeDecls.h"
|
||||
|
||||
namespace js {
|
||||
|
||||
bool IsExtendedPrimitive(JSObject& obj);
|
||||
|
||||
} // namespace js
|
||||
|
||||
#endif
|
55
js/src/vm/RecordType.cpp
Normal file
55
js/src/vm/RecordType.cpp
Normal file
@ -0,0 +1,55 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* vim: set ts=8 sts=4 et sw=4 tw=99:
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "vm/RecordType.h"
|
||||
|
||||
#include "vm/JSContext.h"
|
||||
#include "vm/JSObject-inl.h"
|
||||
|
||||
using namespace js;
|
||||
|
||||
static bool RecordConstructor(JSContext* cx, unsigned argc, Value* vp);
|
||||
|
||||
const JSClass RecordType::class_ = {"record", 0, JS_NULL_CLASS_OPS,
|
||||
&RecordType::classSpec_};
|
||||
|
||||
const ClassSpec RecordType::classSpec_ = {
|
||||
GenericCreateConstructor<RecordConstructor, 1, gc::AllocKind::FUNCTION>,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr};
|
||||
|
||||
RecordType* RecordType::create(JSContext* cx) {
|
||||
Rooted<TaggedProto> proto(cx, TaggedProto(nullptr));
|
||||
return NewObjectWithGivenTaggedProto<RecordType>(cx, proto);
|
||||
}
|
||||
|
||||
// Record and Record proposal section 9.2.1
|
||||
static bool RecordConstructor(JSContext* cx, unsigned argc, Value* vp) {
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
|
||||
// Step 1.
|
||||
if (args.isConstructing()) {
|
||||
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
|
||||
JSMSG_NOT_CONSTRUCTOR, "Record");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (args.length() > 0) {
|
||||
MOZ_CRASH("Only empty records are supoprted.");
|
||||
return false;
|
||||
}
|
||||
|
||||
RecordType* rec = RecordType::create(cx);
|
||||
if (!rec) {
|
||||
return false;
|
||||
}
|
||||
|
||||
args.rval().setExtendedPrimitive(*rec);
|
||||
return true;
|
||||
}
|
24
js/src/vm/RecordType.h
Normal file
24
js/src/vm/RecordType.h
Normal file
@ -0,0 +1,24 @@
|
||||
/* -*- 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_RecordType_h
|
||||
#define vm_RecordType_h
|
||||
|
||||
#include "vm/NativeObject.h"
|
||||
|
||||
namespace JS {
|
||||
|
||||
class RecordType final : public js::NativeObject {
|
||||
public:
|
||||
static const js::ClassSpec classSpec_;
|
||||
static const JSClass class_;
|
||||
|
||||
static RecordType* create(JSContext* cx);
|
||||
};
|
||||
|
||||
} // namespace JS
|
||||
|
||||
#endif
|
@ -45,6 +45,10 @@
|
||||
#include "vm/JSContext-inl.h"
|
||||
#include "vm/JSObject-inl.h"
|
||||
#include "vm/Realm-inl.h"
|
||||
#ifdef ENABLE_RECORD_TUPLE
|
||||
# include "vm/RecordType.h"
|
||||
# include "vm/TupleType.h"
|
||||
#endif
|
||||
|
||||
using namespace js;
|
||||
|
||||
@ -2109,7 +2113,13 @@ JSString* js::ToStringSlow(
|
||||
}
|
||||
RootedBigInt i(cx, v.toBigInt());
|
||||
str = BigInt::toString<CanGC>(cx, i, 10);
|
||||
} else {
|
||||
}
|
||||
#ifdef ENABLE_RECORD_TUPLE
|
||||
else if (arg.isExtendedPrimitive()) {
|
||||
MOZ_CRASH("Records and Tuples are not supported yet.");
|
||||
}
|
||||
#endif
|
||||
else {
|
||||
MOZ_ASSERT(v.isUndefined());
|
||||
str = cx->names().undefined;
|
||||
}
|
||||
|
@ -1846,6 +1846,12 @@ bool JSStructuredCloneWriter::startWrite(HandleValue v) {
|
||||
case ESClass::Function:
|
||||
break;
|
||||
|
||||
#ifdef ENABLE_RECORD_TUPLE
|
||||
case ESClass::Record:
|
||||
case ESClass::Tuple:
|
||||
MOZ_CRASH("Record and Tuple are not supported");
|
||||
#endif
|
||||
|
||||
case ESClass::Other: {
|
||||
if (obj->canUnwrapAs<TypedArrayObject>()) {
|
||||
return writeTypedArray(obj);
|
||||
|
@ -36,6 +36,10 @@
|
||||
#include "vm/StaticStrings.h" // StaticStrings
|
||||
#include "vm/StringType.h" // NewStringCopy{N,Z}, ToString
|
||||
#include "vm/SymbolType.h" // Symbol
|
||||
#ifdef ENABLE_RECORD_TUPLE
|
||||
# include "vm/RecordType.h"
|
||||
# include "vm/TupleType.h"
|
||||
#endif
|
||||
|
||||
#include "vm/JSContext-inl.h" // JSContext::check
|
||||
#include "vm/JSObject-inl.h" // IsCallable
|
||||
@ -162,6 +166,12 @@ JSString* js::ValueToSource(JSContext* cx, HandleValue v) {
|
||||
return ConcatStrings<CanGC>(cx, str, n);
|
||||
}
|
||||
|
||||
#ifdef ENABLE_RECORD_TUPLE
|
||||
case ValueType::ExtendedPrimitive: {
|
||||
MOZ_CRASH("ExtendedPrimitive is not supported yet");
|
||||
}
|
||||
#endif
|
||||
|
||||
case JS::ValueType::Object: {
|
||||
RootedValue fval(cx);
|
||||
RootedObject obj(cx, &v.toObject());
|
||||
|
69
js/src/vm/TupleType.cpp
Normal file
69
js/src/vm/TupleType.cpp
Normal file
@ -0,0 +1,69 @@
|
||||
/* -*- 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/TupleType.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"
|
||||
|
||||
#include "vm/JSObject-inl.h"
|
||||
|
||||
using namespace js;
|
||||
|
||||
static bool TupleConstructor(JSContext* cx, unsigned argc, Value* vp);
|
||||
|
||||
const JSClass TupleType::class_ = {"tuple", 0, JS_NULL_CLASS_OPS,
|
||||
&TupleType::classSpec_};
|
||||
|
||||
const JSClass TupleType::protoClass_ = {
|
||||
"Tuple.prototype", JSCLASS_HAS_CACHED_PROTO(JSProto_Tuple),
|
||||
JS_NULL_CLASS_OPS, &TupleType::classSpec_};
|
||||
|
||||
const ClassSpec TupleType::classSpec_ = {
|
||||
GenericCreateConstructor<TupleConstructor, 1, gc::AllocKind::FUNCTION>,
|
||||
GenericCreatePrototype<TupleType>,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr};
|
||||
|
||||
TupleType* TupleType::create(JSContext* cx) {
|
||||
Rooted<TaggedProto> proto(cx, TaggedProto(nullptr));
|
||||
return NewObjectWithGivenTaggedProto<TupleType>(cx, proto);
|
||||
}
|
||||
|
||||
// Record and Tuple proposal section 9.2.1
|
||||
static bool TupleConstructor(JSContext* cx, unsigned argc, Value* vp) {
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
|
||||
// Step 1.
|
||||
if (args.isConstructing()) {
|
||||
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
|
||||
JSMSG_NOT_CONSTRUCTOR, "Tuple");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (args.length() > 0) {
|
||||
MOZ_CRASH("Only empty tuples are supported");
|
||||
return false;
|
||||
}
|
||||
|
||||
TupleType* tup = TupleType::create(cx);
|
||||
if (!tup) {
|
||||
return false;
|
||||
}
|
||||
|
||||
args.rval().setExtendedPrimitive(*tup);
|
||||
return true;
|
||||
}
|
25
js/src/vm/TupleType.h
Normal file
25
js/src/vm/TupleType.h
Normal file
@ -0,0 +1,25 @@
|
||||
/* -*- 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_TupleType_h
|
||||
#define vm_TupleType_h
|
||||
|
||||
#include "vm/NativeObject.h"
|
||||
|
||||
namespace JS {
|
||||
|
||||
class TupleType final : public js::NativeObject {
|
||||
public:
|
||||
static const js::ClassSpec classSpec_;
|
||||
static const JSClass class_;
|
||||
static const JSClass protoClass_;
|
||||
|
||||
static TupleType* create(JSContext* cx);
|
||||
};
|
||||
|
||||
} // namespace JS
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user