зеркало из https://github.com/mozilla/gecko-dev.git
Bug 921631 - Convert CTypes away from using propertyops to using JSNative-backed getters/setters, part 3. r=bholley
--HG-- extra : rebase_source : e88b147e55d6dd1bdd9de34272d347e932ef09b7
This commit is contained in:
Родитель
e57e0ba4ce
Коммит
6c4de76931
|
@ -228,24 +228,28 @@ namespace PointerType {
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace ArrayType {
|
namespace ArrayType {
|
||||||
|
bool IsArrayType(HandleValue v);
|
||||||
|
bool IsArrayOrArrayType(HandleValue v);
|
||||||
|
|
||||||
static bool Create(JSContext* cx, unsigned argc, jsval* vp);
|
static bool Create(JSContext* cx, unsigned argc, jsval* vp);
|
||||||
static bool ConstructData(JSContext* cx, HandleObject obj, const CallArgs& args);
|
static bool ConstructData(JSContext* cx, HandleObject obj, const CallArgs& args);
|
||||||
|
|
||||||
static bool ElementTypeGetter(JSContext* cx, HandleObject obj, HandleId idval,
|
bool ElementTypeGetter(JSContext* cx, JS::CallArgs args);
|
||||||
MutableHandleValue vp);
|
bool LengthGetter(JSContext* cx, JS::CallArgs args);
|
||||||
static bool LengthGetter(JSContext* cx, HandleObject obj, HandleId idval,
|
|
||||||
MutableHandleValue vp);
|
|
||||||
static bool Getter(JSContext* cx, HandleObject obj, HandleId idval, MutableHandleValue vp);
|
static bool Getter(JSContext* cx, HandleObject obj, HandleId idval, MutableHandleValue vp);
|
||||||
static bool Setter(JSContext* cx, HandleObject obj, HandleId idval, bool strict, MutableHandleValue vp);
|
static bool Setter(JSContext* cx, HandleObject obj, HandleId idval, bool strict, MutableHandleValue vp);
|
||||||
static bool AddressOfElement(JSContext* cx, unsigned argc, jsval* vp);
|
static bool AddressOfElement(JSContext* cx, unsigned argc, jsval* vp);
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace StructType {
|
namespace StructType {
|
||||||
|
bool IsStruct(HandleValue v);
|
||||||
|
|
||||||
static bool Create(JSContext* cx, unsigned argc, jsval* vp);
|
static bool Create(JSContext* cx, unsigned argc, jsval* vp);
|
||||||
static bool ConstructData(JSContext* cx, HandleObject obj, const CallArgs& args);
|
static bool ConstructData(JSContext* cx, HandleObject obj, const CallArgs& args);
|
||||||
|
|
||||||
static bool FieldsArrayGetter(JSContext* cx, HandleObject obj, HandleId idval,
|
bool FieldsArrayGetter(JSContext* cx, JS::CallArgs args);
|
||||||
MutableHandleValue vp);
|
|
||||||
static bool FieldGetter(JSContext* cx, HandleObject obj, HandleId idval,
|
static bool FieldGetter(JSContext* cx, HandleObject obj, HandleId idval,
|
||||||
MutableHandleValue vp);
|
MutableHandleValue vp);
|
||||||
static bool FieldSetter(JSContext* cx, HandleObject obj, HandleId idval, bool strict,
|
static bool FieldSetter(JSContext* cx, HandleObject obj, HandleId idval, bool strict,
|
||||||
|
@ -652,11 +656,13 @@ static const JSFunctionSpec sArrayFunction =
|
||||||
JS_FN("ArrayType", ArrayType::Create, 1, CTYPESCTOR_FLAGS);
|
JS_FN("ArrayType", ArrayType::Create, 1, CTYPESCTOR_FLAGS);
|
||||||
|
|
||||||
static const JSPropertySpec sArrayProps[] = {
|
static const JSPropertySpec sArrayProps[] = {
|
||||||
{ "elementType", 0, CTYPESPROP_FLAGS,
|
JS_PSG("elementType",
|
||||||
JSOP_WRAPPER(ArrayType::ElementTypeGetter), JSOP_NULLWRAPPER },
|
(Property<ArrayType::IsArrayType, ArrayType::ElementTypeGetter>::Fun),
|
||||||
{ "length", 0, CTYPESPROP_FLAGS,
|
CTYPESACC_FLAGS),
|
||||||
JSOP_WRAPPER(ArrayType::LengthGetter), JSOP_NULLWRAPPER },
|
JS_PSG("length",
|
||||||
{ 0, 0, 0, JSOP_NULLWRAPPER, JSOP_NULLWRAPPER }
|
(Property<ArrayType::IsArrayOrArrayType, ArrayType::LengthGetter>::Fun),
|
||||||
|
CTYPESACC_FLAGS),
|
||||||
|
JS_PS_END
|
||||||
};
|
};
|
||||||
|
|
||||||
static const JSFunctionSpec sArrayInstanceFunctions[] = {
|
static const JSFunctionSpec sArrayInstanceFunctions[] = {
|
||||||
|
@ -665,18 +671,20 @@ static const JSFunctionSpec sArrayInstanceFunctions[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static const JSPropertySpec sArrayInstanceProps[] = {
|
static const JSPropertySpec sArrayInstanceProps[] = {
|
||||||
{ "length", 0, JSPROP_SHARED | JSPROP_READONLY | JSPROP_PERMANENT,
|
JS_PSG("length",
|
||||||
JSOP_WRAPPER(ArrayType::LengthGetter), JSOP_NULLWRAPPER },
|
(Property<ArrayType::IsArrayOrArrayType, ArrayType::LengthGetter>::Fun),
|
||||||
{ 0, 0, 0, JSOP_NULLWRAPPER, JSOP_NULLWRAPPER }
|
JSPROP_PERMANENT),
|
||||||
|
JS_PS_END
|
||||||
};
|
};
|
||||||
|
|
||||||
static const JSFunctionSpec sStructFunction =
|
static const JSFunctionSpec sStructFunction =
|
||||||
JS_FN("StructType", StructType::Create, 2, CTYPESCTOR_FLAGS);
|
JS_FN("StructType", StructType::Create, 2, CTYPESCTOR_FLAGS);
|
||||||
|
|
||||||
static const JSPropertySpec sStructProps[] = {
|
static const JSPropertySpec sStructProps[] = {
|
||||||
{ "fields", 0, CTYPESPROP_FLAGS,
|
JS_PSG("fields",
|
||||||
JSOP_WRAPPER(StructType::FieldsArrayGetter), JSOP_NULLWRAPPER },
|
(Property<StructType::IsStruct, StructType::FieldsArrayGetter>::Fun),
|
||||||
{ 0, 0, 0, JSOP_NULLWRAPPER, JSOP_NULLWRAPPER }
|
CTYPESACC_FLAGS),
|
||||||
|
JS_PS_END
|
||||||
};
|
};
|
||||||
|
|
||||||
static const JSFunctionSpec sStructFunctions[] = {
|
static const JSFunctionSpec sStructFunctions[] = {
|
||||||
|
@ -4444,35 +4452,50 @@ ArrayType::BuildFFIType(JSContext* cx, JSObject* obj)
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
ArrayType::ElementTypeGetter(JSContext* cx, HandleObject obj, HandleId idval, MutableHandleValue vp)
|
ArrayType::IsArrayType(HandleValue v)
|
||||||
{
|
{
|
||||||
if (!CType::IsCType(obj) || CType::GetTypeCode(obj) != TYPE_array) {
|
if (!v.isObject())
|
||||||
JS_ReportError(cx, "not an ArrayType");
|
|
||||||
return false;
|
return false;
|
||||||
}
|
JSObject* obj = &v.toObject();
|
||||||
|
return CType::IsCType(obj) && CType::GetTypeCode(obj) == TYPE_array;
|
||||||
|
}
|
||||||
|
|
||||||
vp.set(JS_GetReservedSlot(obj, SLOT_ELEMENT_T));
|
bool
|
||||||
JS_ASSERT(!JSVAL_IS_PRIMITIVE(vp));
|
ArrayType::IsArrayOrArrayType(HandleValue v)
|
||||||
|
{
|
||||||
|
if (!v.isObject())
|
||||||
|
return false;
|
||||||
|
JSObject* obj = &v.toObject();
|
||||||
|
|
||||||
|
// Allow both CTypes and CDatas of the ArrayType persuasion by extracting the
|
||||||
|
// CType if we're dealing with a CData.
|
||||||
|
if (CData::IsCData(obj)) {
|
||||||
|
obj = CData::GetCType(obj);
|
||||||
|
}
|
||||||
|
return CType::IsCType(obj) && CType::GetTypeCode(obj) == TYPE_array;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
ArrayType::ElementTypeGetter(JSContext* cx, JS::CallArgs args)
|
||||||
|
{
|
||||||
|
RootedObject obj(cx, &args.thisv().toObject());
|
||||||
|
args.rval().set(JS_GetReservedSlot(obj, SLOT_ELEMENT_T));
|
||||||
|
MOZ_ASSERT(args.rval().isObject());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
ArrayType::LengthGetter(JSContext* cx, HandleObject obj_, HandleId idval, MutableHandleValue vp)
|
ArrayType::LengthGetter(JSContext* cx, JS::CallArgs args)
|
||||||
{
|
{
|
||||||
JSObject *obj = obj_;
|
JSObject *obj = &args.thisv().toObject();
|
||||||
|
|
||||||
// This getter exists for both CTypes and CDatas of the ArrayType persuasion.
|
// This getter exists for both CTypes and CDatas of the ArrayType persuasion.
|
||||||
// If we're dealing with a CData, get the CType from it.
|
// If we're dealing with a CData, get the CType from it.
|
||||||
if (CData::IsCData(obj))
|
if (CData::IsCData(obj))
|
||||||
obj = CData::GetCType(obj);
|
obj = CData::GetCType(obj);
|
||||||
|
|
||||||
if (!CType::IsCType(obj) || CType::GetTypeCode(obj) != TYPE_array) {
|
args.rval().set(JS_GetReservedSlot(obj, SLOT_LENGTH));
|
||||||
JS_ReportError(cx, "not an ArrayType");
|
JS_ASSERT(args.rval().isNumber() || args.rval().isUndefined());
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
vp.set(JS_GetReservedSlot(obj, SLOT_LENGTH));
|
|
||||||
JS_ASSERT(vp.isNumber() || vp.isUndefined());
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5124,33 +5147,39 @@ StructType::BuildFieldsArray(JSContext* cx, JSObject* obj)
|
||||||
return fieldsProp;
|
return fieldsProp;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
/* static */ bool
|
||||||
StructType::FieldsArrayGetter(JSContext* cx, HandleObject obj, HandleId idval, MutableHandleValue vp)
|
StructType::IsStruct(HandleValue v)
|
||||||
{
|
{
|
||||||
if (!CType::IsCType(obj) || CType::GetTypeCode(obj) != TYPE_struct) {
|
if (!v.isObject())
|
||||||
JS_ReportError(cx, "not a StructType");
|
|
||||||
return false;
|
return false;
|
||||||
}
|
JSObject* obj = &v.toObject();
|
||||||
|
return CType::IsCType(obj) && CType::GetTypeCode(obj) == TYPE_struct;
|
||||||
|
}
|
||||||
|
|
||||||
vp.set(JS_GetReservedSlot(obj, SLOT_FIELDS));
|
bool
|
||||||
|
StructType::FieldsArrayGetter(JSContext* cx, JS::CallArgs args)
|
||||||
|
{
|
||||||
|
RootedObject obj(cx, &args.thisv().toObject());
|
||||||
|
|
||||||
|
args.rval().set(JS_GetReservedSlot(obj, SLOT_FIELDS));
|
||||||
|
|
||||||
if (!CType::IsSizeDefined(obj)) {
|
if (!CType::IsSizeDefined(obj)) {
|
||||||
JS_ASSERT(JSVAL_IS_VOID(vp));
|
MOZ_ASSERT(args.rval().isUndefined());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (JSVAL_IS_VOID(vp)) {
|
if (args.rval().isUndefined()) {
|
||||||
// Build the 'fields' array lazily.
|
// Build the 'fields' array lazily.
|
||||||
JSObject* fields = BuildFieldsArray(cx, obj);
|
JSObject* fields = BuildFieldsArray(cx, obj);
|
||||||
if (!fields)
|
if (!fields)
|
||||||
return false;
|
return false;
|
||||||
JS_SetReservedSlot(obj, SLOT_FIELDS, OBJECT_TO_JSVAL(fields));
|
JS_SetReservedSlot(obj, SLOT_FIELDS, OBJECT_TO_JSVAL(fields));
|
||||||
|
|
||||||
vp.setObject(*fields);
|
args.rval().setObject(*fields);
|
||||||
}
|
}
|
||||||
|
|
||||||
JS_ASSERT(!JSVAL_IS_PRIMITIVE(vp) &&
|
MOZ_ASSERT(args.rval().isObject());
|
||||||
JS_IsArrayObject(cx, JSVAL_TO_OBJECT(vp)));
|
MOZ_ASSERT(JS_IsArrayObject(cx, &args.rval().toObject()));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1334,8 +1334,8 @@ function run_type_ctor_class_tests(c, t, t2, props, fns, instanceProps, instance
|
||||||
// Check that the shared properties and functions on 't.prototype.__proto__'
|
// Check that the shared properties and functions on 't.prototype.__proto__'
|
||||||
// (and thus also 't.prototype') throw.
|
// (and thus also 't.prototype') throw.
|
||||||
for each (let p in instanceProps) {
|
for each (let p in instanceProps) {
|
||||||
do_check_throws(function() { t.prototype.__proto__[p]; }, Error);
|
do_check_throws(function() { t.prototype.__proto__[p]; }, TypeError);
|
||||||
do_check_throws(function() { t.prototype[p]; }, Error);
|
do_check_throws(function() { t.prototype[p]; }, TypeError);
|
||||||
}
|
}
|
||||||
for each (let f in instanceFns) {
|
for each (let f in instanceFns) {
|
||||||
do_check_throws(function() { t.prototype.__proto__[f]() }, Error);
|
do_check_throws(function() { t.prototype.__proto__[f]() }, Error);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче