Bug 1055472 - Part 13: Make the ArrayBuffer constructor properly subclassable. (r=Waldo)

This commit is contained in:
Eric Faust 2015-11-13 18:22:22 -08:00
parent d830569df2
commit 3f478a674a
4 changed files with 28 additions and 5 deletions

View File

@ -696,6 +696,15 @@ NewObjectWithClassProto(ExclusiveContext* cx, HandleObject proto,
return obj ? &obj->as<T>() : nullptr;
}
template <class T>
inline T*
NewObjectWithClassProto(ExclusiveContext* cx, HandleObject proto, gc::AllocKind allocKind,
NewObjectKind newKind = GenericObject)
{
JSObject* obj = NewObjectWithClassProto(cx, &T::class_, proto, allocKind, newKind);
return obj ? &obj->as<T>() : nullptr;
}
/*
* Create a native instance of the given class with parent and proto set
* according to the context's active global.

View File

@ -36,6 +36,7 @@ testBuiltin(Map);
testBuiltin(Set);
testBuiltin(WeakMap);
testBuiltin(WeakSet);
testBuiltin(ArrayBuffer);
`;

View File

@ -476,7 +476,12 @@ ArrayBufferObject::class_constructor(JSContext* cx, unsigned argc, Value* vp)
return false;
}
JSObject* bufobj = create(cx, uint32_t(nbytes));
RootedObject proto(cx);
RootedObject newTarget(cx, &args.newTarget().toObject());
if (!GetPrototypeFromConstructor(cx, newTarget, &proto))
return false;
JSObject* bufobj = create(cx, uint32_t(nbytes), proto);
if (!bufobj)
return false;
args.rval().setObject(*bufobj);
@ -785,6 +790,7 @@ ArrayBufferObject::setFlags(uint32_t flags)
ArrayBufferObject*
ArrayBufferObject::create(JSContext* cx, uint32_t nbytes, BufferContents contents,
OwnsState ownsState /* = OwnsData */,
HandleObject proto /* = nullptr */,
NewObjectKind newKind /* = GenericObject */)
{
MOZ_ASSERT_IF(contents.kind() == MAPPED, contents);
@ -825,7 +831,8 @@ ArrayBufferObject::create(JSContext* cx, uint32_t nbytes, BufferContents content
gc::AllocKind allocKind = GetGCObjectKind(nslots);
AutoSetNewObjectMetadata metadata(cx);
Rooted<ArrayBufferObject*> obj(cx, NewBuiltinClassInstance<ArrayBufferObject>(cx, allocKind, newKind));
Rooted<ArrayBufferObject*> obj(cx,
NewObjectWithClassProto<ArrayBufferObject>(cx, proto, allocKind, newKind));
if (!obj) {
if (allocated)
js_free(contents.data());
@ -848,9 +855,11 @@ ArrayBufferObject::create(JSContext* cx, uint32_t nbytes, BufferContents content
ArrayBufferObject*
ArrayBufferObject::create(JSContext* cx, uint32_t nbytes,
HandleObject proto /* = nullptr */,
NewObjectKind newKind /* = GenericObject */)
{
return create(cx, nbytes, BufferContents::createPlain(nullptr));
return create(cx, nbytes, BufferContents::createPlain(nullptr),
OwnsState::OwnsData, proto);
}
JSObject*
@ -1388,7 +1397,8 @@ JS_NewArrayBufferWithContents(JSContext* cx, size_t nbytes, void* data)
MOZ_ASSERT_IF(!data, nbytes == 0);
ArrayBufferObject::BufferContents contents =
ArrayBufferObject::BufferContents::create<ArrayBufferObject::PLAIN>(data);
return ArrayBufferObject::create(cx, nbytes, contents, ArrayBufferObject::OwnsData, TenuredObject);
return ArrayBufferObject::create(cx, nbytes, contents, ArrayBufferObject::OwnsData,
/* proto = */ nullptr, TenuredObject);
}
JS_FRIEND_API(bool)
@ -1453,7 +1463,8 @@ JS_NewMappedArrayBufferWithContents(JSContext* cx, size_t nbytes, void* data)
MOZ_ASSERT(data);
ArrayBufferObject::BufferContents contents =
ArrayBufferObject::BufferContents::create<ArrayBufferObject::MAPPED>(data);
return ArrayBufferObject::create(cx, nbytes, contents, ArrayBufferObject::OwnsData, TenuredObject);
return ArrayBufferObject::create(cx, nbytes, contents, ArrayBufferObject::OwnsData,
/* proto = */ nullptr, TenuredObject);
}
JS_PUBLIC_API(void*)

View File

@ -218,8 +218,10 @@ class ArrayBufferObject : public ArrayBufferObjectMaybeShared
static ArrayBufferObject* create(JSContext* cx, uint32_t nbytes,
BufferContents contents,
OwnsState ownsState = OwnsData,
HandleObject proto = nullptr,
NewObjectKind newKind = GenericObject);
static ArrayBufferObject* create(JSContext* cx, uint32_t nbytes,
HandleObject proto = nullptr,
NewObjectKind newKind = GenericObject);
static JSObject* createSlice(JSContext* cx, Handle<ArrayBufferObject*> arrayBuffer,