Merge pull request #2668 from Ms2ger/CreateInterfaceObjects-failures

Handle JSAPI OOM failures by task failure as soon as possible.
This commit is contained in:
Josh Matthews 2014-06-20 09:28:59 +01:00
commit 9eff8b458f
2 changed files with 31 additions and 64 deletions

View file

@ -1877,10 +1877,8 @@ class CGCreateInterfaceObjectsMethod(CGAbstractMethod):
# if we don't need to create anything, why are we generating this? # if we don't need to create anything, why are we generating this?
assert needInterfaceObject or needInterfacePrototypeObject assert needInterfaceObject or needInterfacePrototypeObject
getParentProto = ("let parentProto: *mut JSObject = %s;\n" + getParentProto = ("let parentProto: *mut JSObject = %s;\n"
"if parentProto.is_null() {\n" + "assert!(parentProto.is_not_null());\n") % getParentProto
" return ptr::mut_null();\n" +
"}\n") % getParentProto
if self.descriptor.interface.ctor(): if self.descriptor.interface.ctor():
constructHook = CONSTRUCT_HOOK_NAME constructHook = CONSTRUCT_HOOK_NAME
@ -1953,6 +1951,7 @@ class CGGetPerInterfaceObject(CGAbstractMethod):
let cachedObject: *mut JSObject = *protoOrIfaceArray.offset(%s as int); let cachedObject: *mut JSObject = *protoOrIfaceArray.offset(%s as int);
if cachedObject.is_null() { if cachedObject.is_null() {
let tmp: *mut JSObject = CreateInterfaceObjects(aCx, aGlobal, aReceiver); let tmp: *mut JSObject = CreateInterfaceObjects(aCx, aGlobal, aReceiver);
assert!(tmp.is_not_null());
*protoOrIfaceArray.offset(%s as int) = tmp; *protoOrIfaceArray.offset(%s as int) = tmp;
tmp tmp
} else { } else {

View file

@ -230,9 +230,6 @@ pub fn CreateInterfaceObjects2(cx: *mut JSContext, global: *mut JSObject, receiv
proto = CreateInterfacePrototypeObject(cx, global, protoProto, proto = CreateInterfacePrototypeObject(cx, global, protoProto,
protoClass, methods, protoClass, methods,
properties, constants); properties, constants);
if proto.is_null() {
return ptr::mut_null();
}
unsafe { unsafe {
JS_SetReservedSlot(proto, DOM_PROTO_INSTANCE_CLASS_SLOT, JS_SetReservedSlot(proto, DOM_PROTO_INSTANCE_CLASS_SLOT,
@ -247,9 +244,6 @@ pub fn CreateInterfaceObjects2(cx: *mut JSContext, global: *mut JSObject, receiv
constructor, ctorNargs, proto, constructor, ctorNargs, proto,
staticMethods, constants, s) staticMethods, constants, s)
}); });
if interface.is_null() {
return ptr::mut_null();
}
} }
if protoClass.is_not_null() { if protoClass.is_not_null() {
@ -268,52 +262,40 @@ fn CreateInterfaceObject(cx: *mut JSContext, global: *mut JSObject, receiver: *m
unsafe { unsafe {
let fun = JS_NewFunction(cx, constructorNative, ctorNargs, let fun = JS_NewFunction(cx, constructorNative, ctorNargs,
JSFUN_CONSTRUCTOR, global, name); JSFUN_CONSTRUCTOR, global, name);
if fun.is_null() { assert!(fun.is_not_null());
return ptr::mut_null();
}
let constructor = JS_GetFunctionObject(fun); let constructor = JS_GetFunctionObject(fun);
assert!(constructor.is_not_null()); assert!(constructor.is_not_null());
match staticMethods { match staticMethods {
Some(staticMethods) => { Some(staticMethods) => DefineMethods(cx, constructor, staticMethods),
if !DefineMethods(cx, constructor, staticMethods) {
return ptr::mut_null();
}
},
_ => (), _ => (),
} }
match constants { match constants {
Some(constants) => { Some(constants) => DefineConstants(cx, constructor, constants),
if !DefineConstants(cx, constructor, constants) {
return ptr::mut_null();
}
},
_ => (), _ => (),
} }
if proto.is_not_null() && JS_LinkConstructorAndPrototype(cx, constructor, proto) == 0 { if proto.is_not_null() {
return ptr::mut_null(); assert!(JS_LinkConstructorAndPrototype(cx, constructor, proto) != 0);
} }
let mut alreadyDefined = 0; let mut alreadyDefined = 0;
if JS_AlreadyHasOwnProperty(cx, receiver, name, &mut alreadyDefined) == 0 { assert!(JS_AlreadyHasOwnProperty(cx, receiver, name, &mut alreadyDefined) != 0);
return ptr::mut_null();
}
if alreadyDefined == 0 && if alreadyDefined == 0 {
JS_DefineProperty(cx, receiver, name, ObjectValue(&*constructor), assert!(JS_DefineProperty(cx, receiver, name,
None, None, 0) == 0 { ObjectValue(&*constructor),
return ptr::mut_null(); None, None, 0) != 0);
} }
return constructor; return constructor;
} }
} }
fn DefineConstants(cx: *mut JSContext, obj: *mut JSObject, constants: &'static [ConstantSpec]) -> bool { fn DefineConstants(cx: *mut JSContext, obj: *mut JSObject, constants: &'static [ConstantSpec]) {
constants.iter().all(|spec| { for spec in constants.iter() {
let jsval = match spec.value { let jsval = match spec.value {
NullVal => NullValue(), NullVal => NullValue(),
IntVal(i) => Int32Value(i), IntVal(i) => Int32Value(i),
@ -323,23 +305,23 @@ fn DefineConstants(cx: *mut JSContext, obj: *mut JSObject, constants: &'static [
VoidVal => UndefinedValue(), VoidVal => UndefinedValue(),
}; };
unsafe { unsafe {
JS_DefineProperty(cx, obj, spec.name.as_ptr() as *libc::c_char, assert!(JS_DefineProperty(cx, obj, spec.name.as_ptr() as *libc::c_char,
jsval, None, None, jsval, None, None,
JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_ENUMERATE | JSPROP_READONLY |
JSPROP_PERMANENT) != 0 JSPROP_PERMANENT) != 0);
} }
})
}
fn DefineMethods(cx: *mut JSContext, obj: *mut JSObject, methods: &'static [JSFunctionSpec]) -> bool {
unsafe {
JS_DefineFunctions(cx, obj, methods.as_ptr()) != 0
} }
} }
fn DefineProperties(cx: *mut JSContext, obj: *mut JSObject, properties: &'static [JSPropertySpec]) -> bool { fn DefineMethods(cx: *mut JSContext, obj: *mut JSObject, methods: &'static [JSFunctionSpec]) {
unsafe { unsafe {
JS_DefineProperties(cx, obj, properties.as_ptr()) != 0 assert!(JS_DefineFunctions(cx, obj, methods.as_ptr()) != 0);
}
}
fn DefineProperties(cx: *mut JSContext, obj: *mut JSObject, properties: &'static [JSPropertySpec]) {
unsafe {
assert!(JS_DefineProperties(cx, obj, properties.as_ptr()) != 0);
} }
} }
@ -350,34 +332,20 @@ fn CreateInterfacePrototypeObject(cx: *mut JSContext, global: *mut JSObject,
constants: Option<&'static [ConstantSpec]>) -> *mut JSObject { constants: Option<&'static [ConstantSpec]>) -> *mut JSObject {
unsafe { unsafe {
let ourProto = JS_NewObjectWithUniqueType(cx, protoClass, parentProto, global); let ourProto = JS_NewObjectWithUniqueType(cx, protoClass, parentProto, global);
if ourProto.is_null() { assert!(ourProto.is_not_null());
return ptr::mut_null();
}
match methods { match methods {
Some(methods) => { Some(methods) => DefineMethods(cx, ourProto, methods),
if !DefineMethods(cx, ourProto, methods) {
return ptr::mut_null();
}
},
_ => (), _ => (),
} }
match properties { match properties {
Some(properties) => { Some(properties) => DefineProperties(cx, ourProto, properties),
if !DefineProperties(cx, ourProto, properties) {
return ptr::mut_null();
}
},
_ => (), _ => (),
} }
match constants { match constants {
Some(constants) => { Some(constants) => DefineConstants(cx, ourProto, constants),
if !DefineConstants(cx, ourProto, constants) {
return ptr::mut_null();
}
},
_ => (), _ => (),
} }