mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Backed out 4 changesets (bug 973238) for build bustage on a CLOSED TREE
Backed out changeset cc81a0f56362 (bug 973238) Backed out changeset 472dffac7f21 (bug 973238) Backed out changeset e40e2dbf7d9e (bug 973238) Backed out changeset 2ca44eb13ecf (bug 973238)
This commit is contained in:
parent
e7ac53b704
commit
2e26ebc0fc
@ -822,7 +822,8 @@ js::IsTypedObjectArray(JSObject &obj)
|
||||
|
||||
const Class StructTypeDescr::class_ = {
|
||||
"StructType",
|
||||
JSCLASS_HAS_RESERVED_SLOTS(JS_DESCR_SLOTS),
|
||||
JSCLASS_HAS_RESERVED_SLOTS(JS_DESCR_SLOTS) |
|
||||
JSCLASS_HAS_PRIVATE, // used to store FieldList
|
||||
JS_PropertyStub,
|
||||
JS_DeletePropertyStub,
|
||||
JS_PropertyStub,
|
||||
@ -1483,6 +1484,17 @@ TypedObject::createUnattachedWithClass(JSContext *cx,
|
||||
obj->initReservedSlot(JS_TYPEDOBJ_SLOT_OWNER, NullValue());
|
||||
obj->initReservedSlot(JS_TYPEDOBJ_SLOT_NEXT_VIEW, PrivateValue(nullptr));
|
||||
obj->initReservedSlot(JS_TYPEDOBJ_SLOT_LENGTH, Int32Value(length));
|
||||
obj->initReservedSlot(JS_TYPEDOBJ_SLOT_TYPE_DESCR, ObjectValue(*type));
|
||||
|
||||
// Tag the type object for this instance with the type
|
||||
// representation, if that has not been done already.
|
||||
if (!type->is<SimpleTypeDescr>()) { // FIXME Bug 929651
|
||||
RootedTypeObject typeObj(cx, obj->getType(cx));
|
||||
if (typeObj) {
|
||||
if (!typeObj->addTypedObjectAddendum(cx, type))
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
return static_cast<TypedObject*>(&*obj);
|
||||
}
|
||||
@ -1626,6 +1638,9 @@ ReportTypedObjTypeError(JSContext *cx,
|
||||
/*static*/ void
|
||||
TypedObject::obj_trace(JSTracer *trace, JSObject *object)
|
||||
{
|
||||
gc::MarkSlot(trace, &object->getReservedSlotRef(JS_TYPEDOBJ_SLOT_TYPE_DESCR),
|
||||
"TypedObjectTypeDescr");
|
||||
|
||||
ArrayBufferViewObject::trace(trace, object);
|
||||
|
||||
JS_ASSERT(object->is<TypedObject>());
|
||||
|
@ -655,12 +655,8 @@ class TypedObject : public ArrayBufferViewObject
|
||||
return getReservedSlot(JS_TYPEDOBJ_SLOT_OWNER).toObject().as<ArrayBufferObject>();
|
||||
}
|
||||
|
||||
TypedProto &typedProto() const {
|
||||
return getProto()->as<TypedProto>();
|
||||
}
|
||||
|
||||
TypeDescr &typeDescr() const {
|
||||
return typedProto().typeDescr();
|
||||
return getReservedSlot(JS_TYPEDOBJ_SLOT_TYPE_DESCR).toObject().as<TypeDescr>();
|
||||
}
|
||||
|
||||
uint8_t *typedMem() const {
|
||||
|
@ -28,17 +28,14 @@
|
||||
#define DESCR_STRUCT_FIELD_OFFSETS(obj) \
|
||||
UnsafeGetReservedSlot(obj, JS_DESCR_SLOT_STRUCT_FIELD_OFFSETS)
|
||||
|
||||
// Typed prototype slots
|
||||
|
||||
#define TYPROTO_DESCR(obj) \
|
||||
UnsafeGetReservedSlot(obj, JS_TYPROTO_SLOT_DESCR)
|
||||
|
||||
// Typed object slots
|
||||
|
||||
#define TYPEDOBJ_BYTEOFFSET(obj) \
|
||||
TO_INT32(UnsafeGetReservedSlot(obj, JS_TYPEDOBJ_SLOT_BYTEOFFSET))
|
||||
#define TYPEDOBJ_BYTELENGTH(obj) \
|
||||
TO_INT32(UnsafeGetReservedSlot(obj, JS_TYPEDOBJ_SLOT_BYTELENGTH))
|
||||
#define TYPEDOBJ_TYPE_DESCR(obj) \
|
||||
UnsafeGetReservedSlot(obj, JS_TYPEDOBJ_SLOT_TYPE_DESCR)
|
||||
#define TYPEDOBJ_OWNER(obj) \
|
||||
UnsafeGetReservedSlot(obj, JS_TYPEDOBJ_SLOT_OWNER)
|
||||
#define TYPEDOBJ_LENGTH(obj) \
|
||||
@ -47,10 +44,6 @@
|
||||
#define HAS_PROPERTY(obj, prop) \
|
||||
callFunction(std_Object_hasOwnProperty, obj, prop)
|
||||
|
||||
function TypedObjectTypeDescr(typedObj) {
|
||||
return TYPROTO_DESCR(typedObj.__proto__);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Getting values
|
||||
//
|
||||
@ -199,7 +192,7 @@ function TypedObjectSet(descr, typedObj, offset, fromValue) {
|
||||
// representation as the destination. In that case, we can just do a
|
||||
// memcpy.
|
||||
if (IsObject(fromValue) && ObjectIsTypedObject(fromValue)) {
|
||||
if (!descr.variable && DescrsEquiv(descr, TypedObjectTypeDescr(fromValue))) {
|
||||
if (!descr.variable && DescrsEquiv(descr, TYPEDOBJ_TYPE_DESCR(fromValue))) {
|
||||
if (!TypedObjectIsAttached(fromValue))
|
||||
ThrowError(JSMSG_TYPEDOBJECT_HANDLE_UNATTACHED);
|
||||
|
||||
@ -393,7 +386,7 @@ function FillTypedArrayWithValue(destArray, fromValue) {
|
||||
assert(IsObject(handle) && ObjectIsTypedObject(destArray),
|
||||
"FillTypedArrayWithValue: not typed handle");
|
||||
|
||||
var descr = TypedObjectTypeDescr(destArray);
|
||||
var descr = TYPEDOBJ_TYPE_DESCR(destArray);
|
||||
var length = DESCR_SIZED_ARRAY_LENGTH(descr);
|
||||
if (length === 0)
|
||||
return;
|
||||
@ -447,7 +440,7 @@ function TypedArrayRedimension(newArrayType) {
|
||||
|
||||
// Peel away the outermost array layers from the type of `this` to find
|
||||
// the core element type. In the process, count the number of elements.
|
||||
var oldArrayType = TypedObjectTypeDescr(this);
|
||||
var oldArrayType = TYPEDOBJ_TYPE_DESCR(this);
|
||||
var oldArrayReprKind = DESCR_KIND(oldArrayType);
|
||||
var oldElementType = oldArrayType;
|
||||
var oldElementCount = 1;
|
||||
@ -514,7 +507,7 @@ function X4ToSource() {
|
||||
if (!IsObject(this) || !ObjectIsTypedObject(this))
|
||||
ThrowError(JSMSG_INCOMPATIBLE_PROTO, "X4", "toSource", typeof this);
|
||||
|
||||
var descr = TypedObjectTypeDescr(this);
|
||||
var descr = TYPEDOBJ_TYPE_DESCR(this);
|
||||
|
||||
if (DESCR_KIND(descr) != JS_TYPEREPR_X4_KIND)
|
||||
ThrowError(JSMSG_INCOMPATIBLE_PROTO, "X4", "toSource", typeof this);
|
||||
@ -592,7 +585,7 @@ function StorageOfTypedObject(obj) {
|
||||
// Warning: user exposed!
|
||||
function TypeOfTypedObject(obj) {
|
||||
if (IsObject(obj) && ObjectIsTypedObject(obj))
|
||||
return TypedObjectTypeDescr(obj);
|
||||
return TYPEDOBJ_TYPE_DESCR(obj);
|
||||
|
||||
// Note: Do not create bindings for `Any`, `String`, etc in
|
||||
// Utilities.js, but rather access them through
|
||||
@ -686,7 +679,7 @@ function TypedObjectArrayTypeFrom(a, b, c) {
|
||||
function TypedArrayMap(a, b) {
|
||||
if (!IsObject(this) || !ObjectIsTypedObject(this))
|
||||
return ThrowError(JSMSG_TYPEDOBJECT_BAD_ARGS);
|
||||
var thisType = TypedObjectTypeDescr(this);
|
||||
var thisType = TYPEDOBJ_TYPE_DESCR(this);
|
||||
if (!TypeDescrIsArrayType(thisType))
|
||||
return ThrowError(JSMSG_TYPEDOBJECT_BAD_ARGS);
|
||||
|
||||
@ -706,7 +699,7 @@ function TypedArrayMapPar(a, b) {
|
||||
// when not working with typed objects.
|
||||
if (!IsObject(this) || !ObjectIsTypedObject(this))
|
||||
return callFunction(TypedArrayMap, this, a, b);
|
||||
var thisType = TypedObjectTypeDescr(this);
|
||||
var thisType = TYPEDOBJ_TYPE_DESCR(this);
|
||||
if (!TypeDescrIsArrayType(thisType))
|
||||
return callFunction(TypedArrayMap, this, a, b);
|
||||
|
||||
@ -722,7 +715,7 @@ function TypedArrayReduce(a, b) {
|
||||
// Arguments: func, [initial]
|
||||
if (!IsObject(this) || !ObjectIsTypedObject(this))
|
||||
return ThrowError(JSMSG_TYPEDOBJECT_BAD_ARGS);
|
||||
var thisType = TypedObjectTypeDescr(this);
|
||||
var thisType = TYPEDOBJ_TYPE_DESCR(this);
|
||||
if (!TypeDescrIsArrayType(thisType))
|
||||
return ThrowError(JSMSG_TYPEDOBJECT_BAD_ARGS);
|
||||
|
||||
@ -738,7 +731,7 @@ function TypedArrayScatter(a, b, c, d) {
|
||||
// Arguments: outputArrayType, indices, defaultValue, conflictFunction
|
||||
if (!IsObject(this) || !ObjectIsTypedObject(this))
|
||||
return ThrowError(JSMSG_TYPEDOBJECT_BAD_ARGS);
|
||||
var thisType = TypedObjectTypeDescr(this);
|
||||
var thisType = TYPEDOBJ_TYPE_DESCR(this);
|
||||
if (!TypeDescrIsArrayType(thisType))
|
||||
return ThrowError(JSMSG_TYPEDOBJECT_BAD_ARGS);
|
||||
|
||||
@ -756,7 +749,7 @@ function TypedArrayFilter(func) {
|
||||
// Arguments: predicate
|
||||
if (!IsObject(this) || !ObjectIsTypedObject(this))
|
||||
return ThrowError(JSMSG_TYPEDOBJECT_BAD_ARGS);
|
||||
var thisType = TypedObjectTypeDescr(this);
|
||||
var thisType = TYPEDOBJ_TYPE_DESCR(this);
|
||||
if (!TypeDescrIsArrayType(thisType))
|
||||
return ThrowError(JSMSG_TYPEDOBJECT_BAD_ARGS);
|
||||
|
||||
@ -1139,7 +1132,7 @@ function RedirectPointer(typedObj, offset, outputIsScalar) {
|
||||
// is an overapproximation: users can manually declare opaque
|
||||
// types that nonetheless only contain scalar data.
|
||||
|
||||
typedObj = NewDerivedTypedObject(TypedObjectTypeDescr(typedObj),
|
||||
typedObj = NewDerivedTypedObject(TYPEDOBJ_TYPE_DESCR(typedObj),
|
||||
typedObj, 0);
|
||||
}
|
||||
|
||||
|
@ -99,7 +99,7 @@
|
||||
#define JS_DATAVIEW_SLOTS 4 // Number of slots for data views
|
||||
|
||||
#define JS_TYPEDOBJ_SLOT_LENGTH 4 // Length of array (see (*) below)
|
||||
#define JS_TYPEDARR_SLOT_TYPE 5 // For typed arrays only, type code
|
||||
#define JS_TYPEDOBJ_SLOT_TYPE_DESCR 5 // For typed objects, type descr
|
||||
|
||||
#define JS_TYPEDOBJ_SLOT_DATA 7 // private slot, based on alloc kind
|
||||
#define JS_TYPEDOBJ_SLOTS 6 // Number of slots for typed objs
|
||||
|
@ -1259,6 +1259,8 @@ ScanTypeObject(GCMarker *gcmarker, types::TypeObject *type)
|
||||
if (type->hasNewScript()) {
|
||||
PushMarkStack(gcmarker, type->newScript()->fun);
|
||||
PushMarkStack(gcmarker, type->newScript()->templateObject);
|
||||
} else if (type->hasTypedObject()) {
|
||||
PushMarkStack(gcmarker, type->typedObject()->descrHeapPtr());
|
||||
}
|
||||
|
||||
if (type->interpretedFunction)
|
||||
@ -1284,6 +1286,8 @@ gc::MarkChildren(JSTracer *trc, types::TypeObject *type)
|
||||
if (type->hasNewScript()) {
|
||||
MarkObject(trc, &type->newScript()->fun, "type_new_function");
|
||||
MarkObject(trc, &type->newScript()->templateObject, "type_new_template");
|
||||
} else if (type->hasTypedObject()) {
|
||||
MarkObject(trc, &type->typedObject()->descrHeapPtr(), "type_heap_ptr");
|
||||
}
|
||||
|
||||
if (type->interpretedFunction)
|
||||
|
13
js/src/jit-test/tests/TypedObject/prototypes.js
vendored
13
js/src/jit-test/tests/TypedObject/prototypes.js
vendored
@ -1,12 +1,9 @@
|
||||
// API Surface Test: check that mutating prototypes
|
||||
// of type objects has no effect, and that mutating
|
||||
// the prototypes of typed objects is an error.
|
||||
// of type descriptors has no effect.
|
||||
|
||||
if (!this.hasOwnProperty("TypedObject"))
|
||||
quit();
|
||||
|
||||
load(libdir + "asserts.js");
|
||||
|
||||
var {StructType, uint32, Object, Any, storage, objectType} = TypedObject;
|
||||
|
||||
function main() { // once a C programmer, always a C programmer.
|
||||
@ -15,14 +12,6 @@ function main() { // once a C programmer, always a C programmer.
|
||||
Uints.prototype = {}; // no effect
|
||||
assertEq(p, Uints.prototype);
|
||||
|
||||
var uints = new Uints();
|
||||
assertEq(uints.__proto__, p);
|
||||
assertThrowsInstanceOf(function() uints.__proto__ = {},
|
||||
TypeError);
|
||||
assertThrowsInstanceOf(function() Object.setPrototypeOf(uints, {}),
|
||||
TypeError);
|
||||
assertEq(uints.__proto__, p);
|
||||
|
||||
var Uintss = Uints.array(2);
|
||||
var p = Uintss.prototype;
|
||||
Uintss.prototype = {}; // no effect
|
||||
|
@ -4306,23 +4306,6 @@ CodeGenerator::visitNeuterCheck(LNeuterCheck *lir)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CodeGenerator::visitTypedObjectProto(LTypedObjectProto *lir)
|
||||
{
|
||||
Register obj = ToRegister(lir->object());
|
||||
JS_ASSERT(ToRegister(lir->output()) == ReturnReg);
|
||||
|
||||
// Eventually we ought to inline this helper function for
|
||||
// efficiency, but it's mildly non-trivial since we must reach
|
||||
// into the type object and so on.
|
||||
|
||||
const Register tempReg = ToRegister(lir->temp());
|
||||
masm.setupUnalignedABICall(1, tempReg);
|
||||
masm.passABIArg(obj);
|
||||
masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, TypedObjectProto));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CodeGenerator::visitTypedObjectElements(LTypedObjectElements *lir)
|
||||
{
|
||||
|
@ -171,7 +171,6 @@ class CodeGenerator : public CodeGeneratorSpecific
|
||||
bool visitNeuterCheck(LNeuterCheck *lir);
|
||||
bool visitTypedObjectElements(LTypedObjectElements *lir);
|
||||
bool visitSetTypedObjectOffset(LSetTypedObjectOffset *lir);
|
||||
bool visitTypedObjectProto(LTypedObjectProto *ins);
|
||||
bool visitStringLength(LStringLength *lir);
|
||||
bool visitInitializedLength(LInitializedLength *lir);
|
||||
bool visitSetInitializedLength(LSetInitializedLength *lir);
|
||||
|
@ -10250,20 +10250,14 @@ IonBuilder::typeSetToTypeDescrSet(types::TemporaryTypeSet *types,
|
||||
TypeDescrSetBuilder set;
|
||||
for (uint32_t i = 0; i < types->getObjectCount(); i++) {
|
||||
types::TypeObject *type = types->getTypeObject(i);
|
||||
if (!type)
|
||||
if (!type || type->unknownProperties())
|
||||
return true;
|
||||
|
||||
if (!IsTypedObjectClass(type->clasp()))
|
||||
if (!type->hasTypedObject())
|
||||
return true;
|
||||
|
||||
TaggedProto proto = type->proto();
|
||||
|
||||
// typed objects have immutable prototypes, and they are
|
||||
// always instances of TypedProto
|
||||
JS_ASSERT(proto.isObject() && proto.toObject()->is<TypedProto>());
|
||||
|
||||
TypedProto &typedProto = proto.toObject()->as<TypedProto>();
|
||||
if (!set.insert(&typedProto.typeDescr()))
|
||||
TypeDescr &descr = type->typedObject()->descr();
|
||||
if (!set.insert(&descr))
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -10280,16 +10274,10 @@ IonBuilder::loadTypedObjectType(MDefinition *typedObj)
|
||||
if (typedObj->isNewDerivedTypedObject())
|
||||
return typedObj->toNewDerivedTypedObject()->type();
|
||||
|
||||
MInstruction *proto = MTypedObjectProto::New(alloc(), typedObj);
|
||||
current->add(proto);
|
||||
|
||||
MInstruction *load = MLoadFixedSlot::New(alloc(), proto, JS_TYPROTO_SLOT_DESCR);
|
||||
MInstruction *load = MLoadFixedSlot::New(alloc(), typedObj,
|
||||
JS_TYPEDOBJ_SLOT_TYPE_DESCR);
|
||||
current->add(load);
|
||||
|
||||
MInstruction *unbox = MUnbox::New(alloc(), load, MIRType_Object, MUnbox::Infallible);
|
||||
current->add(unbox);
|
||||
|
||||
return unbox;
|
||||
return load;
|
||||
}
|
||||
|
||||
// Given a typed object `typedObj` and an offset `offset` into that
|
||||
|
@ -3694,25 +3694,6 @@ class LTypedArrayElements : public LInstructionHelper<1, 1, 0>
|
||||
}
|
||||
};
|
||||
|
||||
// Load a typed object's prototype, which is guaranteed to be a
|
||||
// TypedProto object.
|
||||
class LTypedObjectProto : public LCallInstructionHelper<1, 1, 1>
|
||||
{
|
||||
public:
|
||||
LIR_HEADER(TypedObjectProto)
|
||||
|
||||
LTypedObjectProto(const LAllocation &object, const LDefinition &temp1) {
|
||||
setOperand(0, object);
|
||||
setTemp(0, temp1);
|
||||
}
|
||||
const LAllocation *object() {
|
||||
return getOperand(0);
|
||||
}
|
||||
const LDefinition *temp() {
|
||||
return getTemp(0);
|
||||
}
|
||||
};
|
||||
|
||||
// Load a typed array's elements vector.
|
||||
class LTypedObjectElements : public LInstructionHelper<1, 1, 0>
|
||||
{
|
||||
|
@ -250,7 +250,6 @@
|
||||
_(SetArrayLength) \
|
||||
_(TypedArrayLength) \
|
||||
_(TypedArrayElements) \
|
||||
_(TypedObjectProto) \
|
||||
_(TypedObjectElements) \
|
||||
_(SetTypedObjectOffset) \
|
||||
_(StringLength) \
|
||||
|
@ -2361,16 +2361,6 @@ LIRGenerator::visitTypedArrayElements(MTypedArrayElements *ins)
|
||||
return define(new(alloc()) LTypedArrayElements(useRegisterAtStart(ins->object())), ins);
|
||||
}
|
||||
|
||||
bool
|
||||
LIRGenerator::visitTypedObjectProto(MTypedObjectProto *ins)
|
||||
{
|
||||
JS_ASSERT(ins->type() == MIRType_Object);
|
||||
return defineReturn(new(alloc()) LTypedObjectProto(
|
||||
useFixed(ins->object(), CallTempReg0),
|
||||
tempFixed(CallTempReg1)),
|
||||
ins);
|
||||
}
|
||||
|
||||
bool
|
||||
LIRGenerator::visitTypedObjectElements(MTypedObjectElements *ins)
|
||||
{
|
||||
|
@ -182,7 +182,6 @@ class LIRGenerator : public LIRGeneratorSpecific
|
||||
bool visitNeuterCheck(MNeuterCheck *lir);
|
||||
bool visitTypedObjectElements(MTypedObjectElements *ins);
|
||||
bool visitSetTypedObjectOffset(MSetTypedObjectOffset *ins);
|
||||
bool visitTypedObjectProto(MTypedObjectProto *ins);
|
||||
bool visitInitializedLength(MInitializedLength *ins);
|
||||
bool visitSetInitializedLength(MSetInitializedLength *ins);
|
||||
bool visitNot(MNot *ins);
|
||||
|
@ -1617,39 +1617,6 @@ class MNewPar : public MUnaryInstruction
|
||||
}
|
||||
};
|
||||
|
||||
class MTypedObjectProto
|
||||
: public MUnaryInstruction,
|
||||
public SingleObjectPolicy
|
||||
{
|
||||
private:
|
||||
MTypedObjectProto(MDefinition *object)
|
||||
: MUnaryInstruction(object)
|
||||
{
|
||||
setResultType(MIRType_Object);
|
||||
setMovable();
|
||||
}
|
||||
|
||||
public:
|
||||
INSTRUCTION_HEADER(TypedObjectProto)
|
||||
|
||||
static MTypedObjectProto *New(TempAllocator &alloc, MDefinition *object) {
|
||||
return new(alloc) MTypedObjectProto(object);
|
||||
}
|
||||
|
||||
TypePolicy *typePolicy() {
|
||||
return this;
|
||||
}
|
||||
MDefinition *object() const {
|
||||
return getOperand(0);
|
||||
}
|
||||
bool congruentTo(const MDefinition *ins) const {
|
||||
return congruentIfOperandsEqual(ins);
|
||||
}
|
||||
AliasSet getAliasSet() const {
|
||||
return AliasSet::Load(AliasSet::ObjectFields);
|
||||
}
|
||||
};
|
||||
|
||||
// Creates a new derived type object. At runtime, this is just a call
|
||||
// to `BinaryBlock::createDerived()`. That is, the MIR itself does not
|
||||
// compile to particularly optimized code. However, using a distinct
|
||||
|
@ -136,7 +136,6 @@ namespace jit {
|
||||
_(SetArrayLength) \
|
||||
_(TypedArrayLength) \
|
||||
_(TypedArrayElements) \
|
||||
_(TypedObjectProto) \
|
||||
_(TypedObjectElements) \
|
||||
_(SetTypedObjectOffset) \
|
||||
_(InitializedLength) \
|
||||
|
@ -224,7 +224,6 @@ class ParallelSafetyVisitor : public MInstructionVisitor
|
||||
WRITE_GUARDED_OP(SetArrayLength, elements)
|
||||
SAFE_OP(TypedArrayLength)
|
||||
SAFE_OP(TypedArrayElements)
|
||||
SAFE_OP(TypedObjectProto)
|
||||
SAFE_OP(TypedObjectElements)
|
||||
SAFE_OP(SetTypedObjectOffset)
|
||||
SAFE_OP(InitializedLength)
|
||||
|
@ -1155,14 +1155,5 @@ AssertValidValue(JSContext *cx, Value *v)
|
||||
}
|
||||
#endif
|
||||
|
||||
// Definition of the MTypedObjectProto MIR.
|
||||
JSObject *
|
||||
TypedObjectProto(JSObject *obj)
|
||||
{
|
||||
JS_ASSERT(obj->is<TypedObject>());
|
||||
TypedObject &typedObj = obj->as<TypedObject>();
|
||||
return &typedObj.typedProto();
|
||||
}
|
||||
|
||||
} // namespace jit
|
||||
} // namespace js
|
||||
|
@ -690,8 +690,6 @@ void AssertValidStringPtr(JSContext *cx, JSString *str);
|
||||
void AssertValidValue(JSContext *cx, Value *v);
|
||||
#endif
|
||||
|
||||
JSObject *TypedObjectProto(JSObject *obj);
|
||||
|
||||
} // namespace jit
|
||||
} // namespace js
|
||||
|
||||
|
@ -3039,29 +3039,6 @@ TypeObject::markUnknown(ExclusiveContext *cx)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TypeObject::maybeClearNewScriptAddendumOnOOM()
|
||||
{
|
||||
if (!isMarked())
|
||||
return;
|
||||
|
||||
if (!addendum || addendum->kind != TypeObjectAddendum::NewScript)
|
||||
return;
|
||||
|
||||
for (unsigned i = 0; i < getPropertyCount(); i++) {
|
||||
Property *prop = getProperty(i);
|
||||
if (!prop)
|
||||
continue;
|
||||
if (prop->types.definiteProperty())
|
||||
prop->types.setNonDataPropertyIgnoringConstraints();
|
||||
}
|
||||
|
||||
// This method is called during GC sweeping, so there is no write barrier
|
||||
// that needs to be triggered.
|
||||
js_free(addendum);
|
||||
addendum.unsafeSet(nullptr);
|
||||
}
|
||||
|
||||
void
|
||||
TypeObject::clearAddendum(ExclusiveContext *cx)
|
||||
{
|
||||
@ -3086,6 +3063,10 @@ TypeObject::clearAddendum(ExclusiveContext *cx)
|
||||
case TypeObjectAddendum::NewScript:
|
||||
clearNewScriptAddendum(cx);
|
||||
break;
|
||||
|
||||
case TypeObjectAddendum::TypedObject:
|
||||
clearTypedObjectAddendum(cx);
|
||||
break;
|
||||
}
|
||||
|
||||
/* We nullptr out addendum *before* freeing it so the write barrier works. */
|
||||
@ -3200,6 +3181,34 @@ TypeObject::clearNewScriptAddendum(ExclusiveContext *cx)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TypeObject::maybeClearNewScriptAddendumOnOOM()
|
||||
{
|
||||
if (!isMarked())
|
||||
return;
|
||||
|
||||
if (!addendum || addendum->kind != TypeObjectAddendum::NewScript)
|
||||
return;
|
||||
|
||||
for (unsigned i = 0; i < getPropertyCount(); i++) {
|
||||
Property *prop = getProperty(i);
|
||||
if (!prop)
|
||||
continue;
|
||||
if (prop->types.definiteProperty())
|
||||
prop->types.setNonDataPropertyIgnoringConstraints();
|
||||
}
|
||||
|
||||
// This method is called during GC sweeping, so there is no write barrier
|
||||
// that needs to be triggered.
|
||||
js_free(addendum);
|
||||
addendum.unsafeSet(nullptr);
|
||||
}
|
||||
|
||||
void
|
||||
TypeObject::clearTypedObjectAddendum(ExclusiveContext *cx)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
TypeObject::print()
|
||||
{
|
||||
@ -4551,12 +4560,47 @@ TypeScript::printTypes(JSContext *cx, HandleScript script) const
|
||||
}
|
||||
#endif /* DEBUG */
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
// Binary data
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
void
|
||||
TypeObject::setAddendum(TypeObjectAddendum *addendum)
|
||||
{
|
||||
this->addendum = addendum;
|
||||
}
|
||||
|
||||
bool
|
||||
TypeObject::addTypedObjectAddendum(JSContext *cx, Handle<TypeDescr*> descr)
|
||||
{
|
||||
// Type descriptors are always pre-tenured. This is both because
|
||||
// we expect them to live a long time and so that they can be
|
||||
// safely accessed during ion compilation.
|
||||
JS_ASSERT(!IsInsideNursery(cx->runtime(), descr));
|
||||
JS_ASSERT(descr);
|
||||
|
||||
if (flags() & OBJECT_FLAG_ADDENDUM_CLEARED)
|
||||
return true;
|
||||
|
||||
JS_ASSERT(!unknownProperties());
|
||||
|
||||
if (addendum) {
|
||||
JS_ASSERT(hasTypedObject());
|
||||
JS_ASSERT(&typedObject()->descr() == descr);
|
||||
return true;
|
||||
}
|
||||
|
||||
TypeTypedObject *typedObject = js_new<TypeTypedObject>(descr);
|
||||
if (!typedObject)
|
||||
return false;
|
||||
addendum = typedObject;
|
||||
return true;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
// Type object addenda constructor
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
TypeObjectAddendum::TypeObjectAddendum(Kind kind)
|
||||
: kind(kind)
|
||||
{}
|
||||
@ -4565,3 +4609,13 @@ TypeNewScript::TypeNewScript()
|
||||
: TypeObjectAddendum(NewScript)
|
||||
{}
|
||||
|
||||
TypeTypedObject::TypeTypedObject(Handle<TypeDescr*> descr)
|
||||
: TypeObjectAddendum(TypedObject),
|
||||
descr_(descr)
|
||||
{
|
||||
}
|
||||
|
||||
TypeDescr &
|
||||
js::types::TypeTypedObject::descr() {
|
||||
return descr_->as<TypeDescr>();
|
||||
}
|
||||
|
@ -812,11 +812,13 @@ struct Property
|
||||
};
|
||||
|
||||
struct TypeNewScript;
|
||||
struct TypeTypedObject;
|
||||
|
||||
struct TypeObjectAddendum
|
||||
{
|
||||
enum Kind {
|
||||
NewScript
|
||||
NewScript,
|
||||
TypedObject
|
||||
};
|
||||
|
||||
TypeObjectAddendum(Kind kind);
|
||||
@ -832,6 +834,15 @@ struct TypeObjectAddendum
|
||||
return (TypeNewScript*) this;
|
||||
}
|
||||
|
||||
bool isTypedObject() {
|
||||
return kind == TypedObject;
|
||||
}
|
||||
|
||||
TypeTypedObject *asTypedObject() {
|
||||
JS_ASSERT(isTypedObject());
|
||||
return (TypeTypedObject*) this;
|
||||
}
|
||||
|
||||
static inline void writeBarrierPre(TypeObjectAddendum *type);
|
||||
|
||||
static void writeBarrierPost(TypeObjectAddendum *newScript, void *addr) {}
|
||||
@ -888,6 +899,21 @@ struct TypeNewScript : public TypeObjectAddendum
|
||||
static inline void writeBarrierPre(TypeNewScript *newScript);
|
||||
};
|
||||
|
||||
struct TypeTypedObject : public TypeObjectAddendum
|
||||
{
|
||||
private:
|
||||
HeapPtrObject descr_;
|
||||
|
||||
public:
|
||||
TypeTypedObject(Handle<TypeDescr*> descr);
|
||||
|
||||
HeapPtrObject &descrHeapPtr() {
|
||||
return descr_;
|
||||
}
|
||||
|
||||
TypeDescr &descr();
|
||||
};
|
||||
|
||||
/*
|
||||
* Lazy type objects overview.
|
||||
*
|
||||
@ -1001,8 +1027,25 @@ struct TypeObject : gc::BarrieredCell<TypeObject>
|
||||
return addendum->asNewScript();
|
||||
}
|
||||
|
||||
bool hasTypedObject() {
|
||||
return addendum && addendum->isTypedObject();
|
||||
}
|
||||
|
||||
TypeTypedObject *typedObject() {
|
||||
return addendum->asTypedObject();
|
||||
}
|
||||
|
||||
void setAddendum(TypeObjectAddendum *addendum);
|
||||
|
||||
/*
|
||||
* Tag the type object for a binary data type descriptor, instance,
|
||||
* or handle with the type representation of the data it points at.
|
||||
* If this type object is already tagged with a binary data addendum,
|
||||
* this addendum must already be associated with the same TypeRepresentation,
|
||||
* and the method has no effect.
|
||||
*/
|
||||
bool addTypedObjectAddendum(JSContext *cx, Handle<TypeDescr*> descr);
|
||||
|
||||
private:
|
||||
/*
|
||||
* Properties of this object. This may contain JSID_VOID, representing the
|
||||
@ -1114,9 +1157,10 @@ struct TypeObject : gc::BarrieredCell<TypeObject>
|
||||
void markStateChange(ExclusiveContext *cx);
|
||||
void setFlags(ExclusiveContext *cx, TypeObjectFlags flags);
|
||||
void markUnknown(ExclusiveContext *cx);
|
||||
void maybeClearNewScriptAddendumOnOOM();
|
||||
void clearAddendum(ExclusiveContext *cx);
|
||||
void clearNewScriptAddendum(ExclusiveContext *cx);
|
||||
void clearTypedObjectAddendum(ExclusiveContext *cx);
|
||||
void maybeClearNewScriptAddendumOnOOM();
|
||||
bool isPropertyNonData(jsid id);
|
||||
bool isPropertyNonWritable(jsid id);
|
||||
|
||||
|
@ -1224,6 +1224,9 @@ TypeObjectAddendum::writeBarrierPre(TypeObjectAddendum *type)
|
||||
switch (type->kind) {
|
||||
case NewScript:
|
||||
return TypeNewScript::writeBarrierPre(type->asNewScript());
|
||||
|
||||
case TypedObject:
|
||||
return TypeTypedObject::writeBarrierPre(type->asTypedObject());
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -32,7 +32,7 @@ class TypedArrayObject : public ArrayBufferViewObject
|
||||
// Typed array properties stored in slots, beyond those shared by all
|
||||
// ArrayBufferViews.
|
||||
static const size_t LENGTH_SLOT = JS_TYPEDOBJ_SLOT_LENGTH;
|
||||
static const size_t TYPE_SLOT = JS_TYPEDARR_SLOT_TYPE;
|
||||
static const size_t TYPE_SLOT = JS_TYPEDOBJ_SLOT_TYPE_DESCR;
|
||||
static const size_t RESERVED_SLOTS = JS_TYPEDOBJ_SLOTS;
|
||||
static const size_t DATA_SLOT = JS_TYPEDOBJ_SLOT_DATA;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user