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:
Jeff Walden 2013-09-12 15:45:42 -07:00
Родитель e57e0ba4ce
Коммит 6c4de76931
2 изменённых файлов: 74 добавлений и 45 удалений

Просмотреть файл

@ -228,24 +228,28 @@ namespace PointerType {
}
namespace ArrayType {
bool IsArrayType(HandleValue v);
bool IsArrayOrArrayType(HandleValue v);
static bool Create(JSContext* cx, unsigned argc, jsval* vp);
static bool ConstructData(JSContext* cx, HandleObject obj, const CallArgs& args);
static bool ElementTypeGetter(JSContext* cx, HandleObject obj, HandleId idval,
MutableHandleValue vp);
static bool LengthGetter(JSContext* cx, HandleObject obj, HandleId idval,
MutableHandleValue vp);
bool ElementTypeGetter(JSContext* cx, JS::CallArgs args);
bool LengthGetter(JSContext* cx, JS::CallArgs args);
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 AddressOfElement(JSContext* cx, unsigned argc, jsval* vp);
}
namespace StructType {
bool IsStruct(HandleValue v);
static bool Create(JSContext* cx, unsigned argc, jsval* vp);
static bool ConstructData(JSContext* cx, HandleObject obj, const CallArgs& args);
static bool FieldsArrayGetter(JSContext* cx, HandleObject obj, HandleId idval,
MutableHandleValue vp);
bool FieldsArrayGetter(JSContext* cx, JS::CallArgs args);
static bool FieldGetter(JSContext* cx, HandleObject obj, HandleId idval,
MutableHandleValue vp);
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);
static const JSPropertySpec sArrayProps[] = {
{ "elementType", 0, CTYPESPROP_FLAGS,
JSOP_WRAPPER(ArrayType::ElementTypeGetter), JSOP_NULLWRAPPER },
{ "length", 0, CTYPESPROP_FLAGS,
JSOP_WRAPPER(ArrayType::LengthGetter), JSOP_NULLWRAPPER },
{ 0, 0, 0, JSOP_NULLWRAPPER, JSOP_NULLWRAPPER }
JS_PSG("elementType",
(Property<ArrayType::IsArrayType, ArrayType::ElementTypeGetter>::Fun),
CTYPESACC_FLAGS),
JS_PSG("length",
(Property<ArrayType::IsArrayOrArrayType, ArrayType::LengthGetter>::Fun),
CTYPESACC_FLAGS),
JS_PS_END
};
static const JSFunctionSpec sArrayInstanceFunctions[] = {
@ -665,18 +671,20 @@ static const JSFunctionSpec sArrayInstanceFunctions[] = {
};
static const JSPropertySpec sArrayInstanceProps[] = {
{ "length", 0, JSPROP_SHARED | JSPROP_READONLY | JSPROP_PERMANENT,
JSOP_WRAPPER(ArrayType::LengthGetter), JSOP_NULLWRAPPER },
{ 0, 0, 0, JSOP_NULLWRAPPER, JSOP_NULLWRAPPER }
JS_PSG("length",
(Property<ArrayType::IsArrayOrArrayType, ArrayType::LengthGetter>::Fun),
JSPROP_PERMANENT),
JS_PS_END
};
static const JSFunctionSpec sStructFunction =
JS_FN("StructType", StructType::Create, 2, CTYPESCTOR_FLAGS);
static const JSPropertySpec sStructProps[] = {
{ "fields", 0, CTYPESPROP_FLAGS,
JSOP_WRAPPER(StructType::FieldsArrayGetter), JSOP_NULLWRAPPER },
{ 0, 0, 0, JSOP_NULLWRAPPER, JSOP_NULLWRAPPER }
JS_PSG("fields",
(Property<StructType::IsStruct, StructType::FieldsArrayGetter>::Fun),
CTYPESACC_FLAGS),
JS_PS_END
};
static const JSFunctionSpec sStructFunctions[] = {
@ -4444,35 +4452,50 @@ ArrayType::BuildFFIType(JSContext* cx, JSObject* obj)
}
bool
ArrayType::ElementTypeGetter(JSContext* cx, HandleObject obj, HandleId idval, MutableHandleValue vp)
ArrayType::IsArrayType(HandleValue v)
{
if (!CType::IsCType(obj) || CType::GetTypeCode(obj) != TYPE_array) {
JS_ReportError(cx, "not an ArrayType");
if (!v.isObject())
return false;
}
JSObject* obj = &v.toObject();
return CType::IsCType(obj) && CType::GetTypeCode(obj) == TYPE_array;
}
vp.set(JS_GetReservedSlot(obj, SLOT_ELEMENT_T));
JS_ASSERT(!JSVAL_IS_PRIMITIVE(vp));
bool
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;
}
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.
// If we're dealing with a CData, get the CType from it.
if (CData::IsCData(obj))
obj = CData::GetCType(obj);
if (!CType::IsCType(obj) || CType::GetTypeCode(obj) != TYPE_array) {
JS_ReportError(cx, "not an ArrayType");
return false;
}
vp.set(JS_GetReservedSlot(obj, SLOT_LENGTH));
JS_ASSERT(vp.isNumber() || vp.isUndefined());
args.rval().set(JS_GetReservedSlot(obj, SLOT_LENGTH));
JS_ASSERT(args.rval().isNumber() || args.rval().isUndefined());
return true;
}
@ -5124,33 +5147,39 @@ StructType::BuildFieldsArray(JSContext* cx, JSObject* obj)
return fieldsProp;
}
bool
StructType::FieldsArrayGetter(JSContext* cx, HandleObject obj, HandleId idval, MutableHandleValue vp)
/* static */ bool
StructType::IsStruct(HandleValue v)
{
if (!CType::IsCType(obj) || CType::GetTypeCode(obj) != TYPE_struct) {
JS_ReportError(cx, "not a StructType");
if (!v.isObject())
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)) {
JS_ASSERT(JSVAL_IS_VOID(vp));
MOZ_ASSERT(args.rval().isUndefined());
return true;
}
if (JSVAL_IS_VOID(vp)) {
if (args.rval().isUndefined()) {
// Build the 'fields' array lazily.
JSObject* fields = BuildFieldsArray(cx, obj);
if (!fields)
return false;
JS_SetReservedSlot(obj, SLOT_FIELDS, OBJECT_TO_JSVAL(fields));
vp.setObject(*fields);
args.rval().setObject(*fields);
}
JS_ASSERT(!JSVAL_IS_PRIMITIVE(vp) &&
JS_IsArrayObject(cx, JSVAL_TO_OBJECT(vp)));
MOZ_ASSERT(args.rval().isObject());
MOZ_ASSERT(JS_IsArrayObject(cx, &args.rval().toObject()));
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__'
// (and thus also 't.prototype') throw.
for each (let p in instanceProps) {
do_check_throws(function() { t.prototype.__proto__[p]; }, Error);
do_check_throws(function() { t.prototype[p]; }, Error);
do_check_throws(function() { t.prototype.__proto__[p]; }, TypeError);
do_check_throws(function() { t.prototype[p]; }, TypeError);
}
for each (let f in instanceFns) {
do_check_throws(function() { t.prototype.__proto__[f]() }, Error);