mirror of
https://github.com/servo/servo.git
synced 2025-07-23 07:13:52 +01:00
Merge generic funs to share them across all bindings (fixes #2684)
This commit is contained in:
parent
e7808c526c
commit
a90983553b
5 changed files with 185 additions and 200 deletions
|
@ -6,8 +6,11 @@
|
|||
|
||||
use dom::bindings::codegen::PrototypeList;
|
||||
use dom::bindings::codegen::PrototypeList::MAX_PROTO_CHAIN_LENGTH;
|
||||
use dom::bindings::conversions::{native_from_handleobject, is_dom_class, jsstring_to_str};
|
||||
use dom::bindings::error::{Error, ErrorResult, Fallible, throw_type_error};
|
||||
use dom::bindings::conversions::{is_dom_class, jsstring_to_str};
|
||||
use dom::bindings::conversions::native_from_handleobject;
|
||||
use dom::bindings::conversions::private_from_proto_chain;
|
||||
use dom::bindings::error::{Error, ErrorResult, Fallible, throw_invalid_this};
|
||||
use dom::bindings::error::throw_type_error;
|
||||
use dom::bindings::global::GlobalRef;
|
||||
use dom::bindings::js::Root;
|
||||
use dom::bindings::trace::trace_object;
|
||||
|
@ -24,8 +27,11 @@ use std::ptr;
|
|||
use std::cmp::PartialEq;
|
||||
use std::default::Default;
|
||||
use std::cell::UnsafeCell;
|
||||
use js::glue::UnwrapObject;
|
||||
use js::glue::{IsWrapper, RUST_JSID_IS_INT, RUST_JSID_TO_INT};
|
||||
use js::glue::{CallJitMethodOp, CallJitGetterOp, CallJitSetterOp, IsWrapper};
|
||||
use js::glue::{RUST_FUNCTION_VALUE_TO_JITINFO, RUST_JSID_IS_INT};
|
||||
use js::glue::{RUST_JSID_TO_INT, UnwrapObject};
|
||||
use js::jsapi::{CallArgs, GetGlobalForObjectCrossCompartment, JSJitInfo};
|
||||
use js::jsapi::JS_IsExceptionPending;
|
||||
use js::jsapi::{JS_AlreadyHasOwnProperty, JS_NewFunction, JSTraceOp};
|
||||
use js::jsapi::{JS_DefineProperties, JS_ForwardGetPropertyTo};
|
||||
use js::jsapi::{JS_GetClass, JS_LinkConstructorAndPrototype};
|
||||
|
@ -47,13 +53,12 @@ use js::jsapi::{ObjectOpResult, RootedObject, RootedValue, Heap, MutableHandleOb
|
|||
use js::jsapi::PropertyDefinitionBehavior;
|
||||
use js::jsapi::JSAutoCompartment;
|
||||
use js::jsapi::{DOMCallbacks, JSWrapObjectCallbacks};
|
||||
use js::jsval::JSVal;
|
||||
use js::jsval::{PrivateValue, NullValue};
|
||||
use js::jsval::{Int32Value, UInt32Value, DoubleValue, BooleanValue};
|
||||
use js::jsval::{BooleanValue, DoubleValue, Int32Value, JSVal, NullValue};
|
||||
use js::jsval::{PrivateValue, UInt32Value, UndefinedValue};
|
||||
use js::rust::{GCMethods, ToString};
|
||||
use js::glue::{WrapperNew, GetCrossCompartmentWrapper};
|
||||
use js::{JSPROP_ENUMERATE, JSPROP_READONLY, JSPROP_PERMANENT};
|
||||
use js::JSFUN_CONSTRUCTOR;
|
||||
use js::{JS_ARGV, JS_CALLEE, JSFUN_CONSTRUCTOR, JSPROP_ENUMERATE};
|
||||
use js::{JSPROP_PERMANENT, JSPROP_READONLY};
|
||||
use js;
|
||||
use string_cache::{Atom, Namespace};
|
||||
|
||||
|
@ -670,6 +675,91 @@ pub unsafe fn delete_property_by_id(cx: *mut JSContext, object: HandleObject,
|
|||
JS_DeletePropertyById1(cx, object, id, bp)
|
||||
}
|
||||
|
||||
unsafe fn generic_call(cx: *mut JSContext, argc: libc::c_uint, vp: *mut JSVal,
|
||||
is_lenient: bool,
|
||||
call: unsafe extern fn(*const JSJitInfo, *mut JSContext,
|
||||
HandleObject, *mut libc::c_void, u32,
|
||||
*mut JSVal)
|
||||
-> u8)
|
||||
-> u8 {
|
||||
let args = CallArgs::from_vp(vp, argc);
|
||||
let thisobj = args.thisv();
|
||||
if !thisobj.get().is_null_or_undefined() && !thisobj.get().is_object() {
|
||||
return 0;
|
||||
}
|
||||
let obj = if thisobj.get().is_object() {
|
||||
thisobj.get().to_object()
|
||||
} else {
|
||||
GetGlobalForObjectCrossCompartment(JS_CALLEE(cx, vp).to_object_or_null())
|
||||
};
|
||||
let obj = RootedObject::new(cx, obj);
|
||||
let info = RUST_FUNCTION_VALUE_TO_JITINFO(JS_CALLEE(cx, vp));
|
||||
let proto_id = (*info).protoID;
|
||||
let depth = (*info).depth;
|
||||
let this = match private_from_proto_chain(obj.ptr, proto_id, depth) {
|
||||
Ok(val) => val,
|
||||
Err(()) => {
|
||||
if is_lenient {
|
||||
debug_assert!(JS_IsExceptionPending(cx) == 0);
|
||||
*vp = UndefinedValue();
|
||||
return 1;
|
||||
} else {
|
||||
throw_invalid_this(cx, proto_id);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
};
|
||||
call(info, cx, obj.handle(), this as *mut libc::c_void, argc, vp)
|
||||
}
|
||||
|
||||
/// Generic method of IDL interface.
|
||||
pub unsafe extern fn generic_method(cx: *mut JSContext,
|
||||
argc: libc::c_uint, vp: *mut JSVal)
|
||||
-> u8 {
|
||||
generic_call(cx, argc, vp, false, CallJitMethodOp)
|
||||
}
|
||||
|
||||
/// Generic getter of IDL interface.
|
||||
pub unsafe extern fn generic_getter(cx: *mut JSContext,
|
||||
argc: libc::c_uint, vp: *mut JSVal)
|
||||
-> u8 {
|
||||
generic_call(cx, argc, vp, false, CallJitGetterOp)
|
||||
}
|
||||
|
||||
/// Generic lenient getter of IDL interface.
|
||||
pub unsafe extern fn generic_lenient_getter(cx: *mut JSContext,
|
||||
argc: libc::c_uint,
|
||||
vp: *mut JSVal)
|
||||
-> u8 {
|
||||
generic_call(cx, argc, vp, true, CallJitGetterOp)
|
||||
}
|
||||
|
||||
unsafe extern fn call_setter(info: *const JSJitInfo, cx: *mut JSContext,
|
||||
handle: HandleObject, this: *mut libc::c_void,
|
||||
argc: u32, vp: *mut JSVal)
|
||||
-> u8 {
|
||||
if CallJitSetterOp(info, cx, handle, this, argc, vp) == 0 {
|
||||
return 0;
|
||||
}
|
||||
*vp = UndefinedValue();
|
||||
1
|
||||
}
|
||||
|
||||
/// Generic setter of IDL interface.
|
||||
pub unsafe extern fn generic_setter(cx: *mut JSContext,
|
||||
argc: libc::c_uint, vp: *mut JSVal)
|
||||
-> u8 {
|
||||
generic_call(cx, argc, vp, false, call_setter)
|
||||
}
|
||||
|
||||
/// Generic lenient setter of IDL interface.
|
||||
pub unsafe extern fn generic_lenient_setter(cx: *mut JSContext,
|
||||
argc: libc::c_uint,
|
||||
vp: *mut JSVal)
|
||||
-> u8 {
|
||||
generic_call(cx, argc, vp, true, call_setter)
|
||||
}
|
||||
|
||||
/// Validate a qualified name. See https://dom.spec.whatwg.org/#validate for details.
|
||||
pub fn validate_qualified_name(qualified_name: &str) -> ErrorResult {
|
||||
match xml_name_type(qualified_name) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue