Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Lots of work on bindings #397

Merged
merged 10 commits into from Apr 24, 2013
@@ -0,0 +1,7 @@
Patches live here for submodules that should remain as pristine as possible.
This will allow us to unconditionally update them, then apply necessary
patches as needed.

* mozjs-stack-bounds.diff:
add a public API to overwrite the engine's computed stack bounds for
GC scanning.
@@ -0,0 +1,77 @@
diff --git a/js/src/jsapi.cpp b/js/src/jsapi.cpp
index 5571fc0..7e1e30d 100644
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -735,6 +735,7 @@ JSRuntime::JSRuntime()
#endif
selfHostedGlobal_(NULL),
nativeStackBase(0),
+ nativeStackEnd(0),
nativeStackQuota(0),
interpreterFrames(NULL),
cxCallback(NULL),
@@ -7084,6 +7085,18 @@ JS_SetRuntimeThread(JSRuntime *rt)
#endif
}

+extern JS_PUBLIC_API(void)
+JS_SetNativeStackBounds(JSRuntime *rt, uintptr_t minValue, uintptr_t maxValue)
+{
+#if JS_STACK_GROWTH_DIRECTION < 0
+ rt->nativeStackBase = maxValue;
+ rt->nativeStackEnd = minValue;
+#else
+ rt->nativeStackBase = minValue;
+ rt->nativeStackEnd = maxValue;
+#endif
+}
+
extern JS_NEVER_INLINE JS_PUBLIC_API(void)
JS_AbortIfWrongThread(JSRuntime *rt)
{
diff --git a/js/src/jsapi.h b/js/src/jsapi.h
index c8ab0f0..9ac582e 100644
--- a/js/src/jsapi.h
+++ b/js/src/jsapi.h
@@ -6248,6 +6248,9 @@ JS_ClearRuntimeThread(JSRuntime *rt);
extern JS_PUBLIC_API(void)
JS_SetRuntimeThread(JSRuntime *rt);

+extern JS_PUBLIC_API(void)
+JS_SetNativeStackBounds(JSRuntime *rt, uintptr_t minValue, uintptr_t maxValue);
+
#ifdef __cplusplus
JS_END_EXTERN_C

diff --git a/js/src/jscntxt.h b/js/src/jscntxt.h
index 0bb6d1c..32e016e 100644
--- a/js/src/jscntxt.h
+++ b/js/src/jscntxt.h
@@ -439,6 +439,9 @@ struct JSRuntime : js::RuntimeFriendFields
/* Base address of the native stack for the current thread. */
uintptr_t nativeStackBase;

+ /* Base address of the native stack for the current thread. */
+ uintptr_t nativeStackEnd;
+
/* The native stack size limit that runtime should not exceed. */
size_t nativeStackQuota;

diff --git a/js/src/jsgc.cpp b/js/src/jsgc.cpp
index f5cbc62..eae29da 100644
--- a/js/src/jsgc.cpp
+++ b/js/src/jsgc.cpp
@@ -1177,9 +1177,11 @@ MarkConservativeStackRoots(JSTracer *trc, bool useSavedRoots)
uintptr_t *stackMin, *stackEnd;
#if JS_STACK_GROWTH_DIRECTION > 0
stackMin = rt->nativeStackBase;
- stackEnd = cgcd->nativeStackTop;
+ stackEnd = rt->nativeStackEnd ? reinterpret_cast<uintptr_t*>(rt->nativeStackEnd)
+ : cgcd->nativeStackTop;
#else
- stackMin = cgcd->nativeStackTop + 1;
+ stackMin = rt->nativeStackEnd ? reinterpret_cast<uintptr_t*>(rt->nativeStackEnd)
+ : cgcd->nativeStackTop + 1;
stackEnd = reinterpret_cast<uintptr_t *>(rt->nativeStackBase);
#endif

@@ -151,14 +151,30 @@ pub fn Content(layout_task: LayoutTask,
};

cx.set_cx_private(ptr::to_unsafe_ptr(&*content) as *());
unsafe { task::local_data::local_data_set(global_content_key, cast::transmute(content)); }

content
}

fn global_content_key(_: @Content) {}

pub fn global_content() -> @Content {
unsafe {
return task::local_data::local_data_get(global_content_key).get();
}
}

pub fn task_from_context(cx: *JSContext) -> *mut Content {
JS_GetContextPrivate(cx) as *mut Content
}

#[unsafe_destructor]
impl Drop for Content {
fn finalize(&self) {
unsafe { task::local_data::local_data_pop(global_content_key) };
}
}

#[allow(non_implicitly_copyable_typarams)]
pub impl Content {
fn start(&mut self) {
@@ -185,6 +201,8 @@ pub impl Content {
ParseMsg(url) => {
debug!("content: Received url `%s` to parse", url_to_str(&url));

define_bindings(self.compartment.get());

// Note: we can parse the next document in parallel
// with any previous documents.

@@ -209,8 +227,14 @@ pub impl Content {
let js_scripts = result.js_port.recv();
debug!("js_scripts: %?", js_scripts);

let document = @mut Document(root);
let window = @mut Window(self.control_chan.clone());
let window = Window(self.control_chan.clone(),
self.event_chan.clone(),
ptr::to_mut_unsafe_ptr(&mut *self)); //FIXME store this safely
let document = Document(root, Some(window));

do root.with_mut_node |node| {
node.add_to_doc(document);
}

self.damage.add(MatchSelectorsDamage);
self.relayout(document, &url);
@@ -221,7 +245,6 @@ pub impl Content {

let compartment = self.compartment.expect(~"TODO error checking");
compartment.define_functions(debug_fns);
define_bindings(compartment, document, window);

do vec::consume(js_scripts) |_i, bytes| {
self.cx.evaluate_script(compartment.global_obj, bytes, ~"???", 1u);
@@ -322,7 +345,7 @@ pub impl Content {
}

fn query_layout(&mut self, query: layout_task::LayoutQuery) -> layout_task::LayoutQueryResponse {
self.relayout(self.document.get(), &(copy self.doc_url).get());
//self.relayout(self.document.get(), &(copy self.doc_url).get());
self.join_layout();

let (response_port, response_chan) = comm::stream();
@@ -2,79 +2,54 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use content::content_task::task_from_context;
use dom::bindings::utils::{CacheableWrapper, WrapperCache, BindingObject, OpaqueBindingReference};
use content::content_task::{task_from_context, global_content};
use dom::bindings::utils::{CacheableWrapper, WrapperCache, BindingObject, DerivedWrapper};
use dom::bindings::codegen::ClientRectBinding;
use js::jsapi::{JSObject, JSContext};

pub trait ClientRect {
fn Top(&self) -> f32;
fn Bottom(&self) -> f32;
fn Left(&self) -> f32;
fn Right(&self) -> f32;
fn Width(&self) -> f32;
fn Height(&self) -> f32;
}

pub struct ClientRectImpl {
wrapper: WrapperCache,
top: f32,
bottom: f32,
left: f32,
right: f32,
}

impl ClientRect for ClientRectImpl {
fn Top(&self) -> f32 {
self.top
}

fn Bottom(&self) -> f32 {
self.bottom
}

fn Left(&self) -> f32 {
self.left
}

fn Right(&self) -> f32 {
self.right
}

fn Width(&self) -> f32 {
f32::abs(self.right - self.left)
}

fn Height(&self) -> f32 {
f32::abs(self.bottom - self.top)
use dom::clientrect::ClientRect;
use js::jsapi::{JSObject, JSContext, JSVal};
use js::glue::bindgen::RUST_OBJECT_TO_JSVAL;

pub impl ClientRect {
pub fn init_wrapper(@mut self) {
let content = global_content();
let cx = content.compartment.get().cx.ptr;
let owner = content.window.get();
let cache = owner.get_wrappercache();
let scope = cache.get_wrapper();
self.wrap_object_shared(cx, scope);
}
}

pub fn ClientRect(top: f32, bottom: f32, left: f32, right: f32) -> ClientRectImpl {
ClientRectImpl {
top: top, bottom: bottom, left: left, right: right,
wrapper: WrapperCache::new()
}
}

impl CacheableWrapper for ClientRectImpl {
impl CacheableWrapper for ClientRect {
fn get_wrappercache(&mut self) -> &mut WrapperCache {
unsafe { cast::transmute(&self.wrapper) }
}

fn wrap_object_unique(~self, cx: *JSContext, scope: *JSObject) -> *JSObject {
fn wrap_object_shared(@mut self, cx: *JSContext, scope: *JSObject) -> *JSObject {
let mut unused = false;
ClientRectBinding::Wrap(cx, scope, self, &mut unused)
}
}

fn wrap_object_shared(@self, _cx: *JSContext, _scope: *JSObject) -> *JSObject {
fail!(~"nyi")
impl BindingObject for ClientRect {
fn GetParentObject(&self, cx: *JSContext) -> @mut CacheableWrapper {
let content = task_from_context(cx);
unsafe { (*content).window.get() as @mut CacheableWrapper }
}
}

impl BindingObject for ClientRectImpl {
fn GetParentObject(&self, cx: *JSContext) -> OpaqueBindingReference {
let content = task_from_context(cx);
unsafe { OpaqueBindingReference(Right((*content).window.get() as @CacheableWrapper)) }
impl DerivedWrapper for ClientRect {
fn wrap(&mut self, _cx: *JSContext, _scope: *JSObject, _vp: *mut JSVal) -> i32 {
fail!(~"nyi")
}
}

fn wrap_shared(@mut self, cx: *JSContext, scope: *JSObject, vp: *mut JSVal) -> i32 {
let obj = self.wrap_object_shared(cx, scope);
if obj.is_null() {
return 0;
} else {
unsafe { *vp = RUST_OBJECT_TO_JSVAL(obj) };
return 1;
}
}
}
@@ -2,70 +2,37 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use content::content_task::task_from_context;
use dom::bindings::clientrect::{ClientRect, ClientRectImpl};
use content::content_task::{task_from_context, global_content};
use dom::bindings::codegen::ClientRectListBinding;
use dom::bindings::utils::{WrapperCache, CacheableWrapper, BindingObject, OpaqueBindingReference};
use dom::bindings::utils::{WrapperCache, CacheableWrapper, BindingObject};
use dom::clientrectlist::ClientRectList;
use js::jsapi::{JSObject, JSContext};

pub trait ClientRectList {
fn Length(&self) -> u32;
fn Item(&self, index: u32) -> Option<~ClientRectImpl>;
fn IndexedGetter(&self, index: u32, found: &mut bool) -> Option<~ClientRectImpl>;
}

pub struct ClientRectListImpl {
wrapper: WrapperCache,
rects: ~[(f32, f32, f32, f32)]
}

impl ClientRectList for ClientRectListImpl {
fn Length(&self) -> u32 {
self.rects.len() as u32
}

fn Item(&self, index: u32) -> Option<~ClientRectImpl> {
if index < self.rects.len() as u32 {
let (top, bottom, left, right) = self.rects[index];
Some(~ClientRect(top, bottom, left, right))
} else {
None
}
}

fn IndexedGetter(&self, index: u32, found: &mut bool) -> Option<~ClientRectImpl> {
*found = index < self.rects.len() as u32;
self.Item(index)
}
}

pub impl ClientRectListImpl {
fn new() -> ClientRectListImpl {
ClientRectListImpl {
wrapper: WrapperCache::new(),
rects: ~[(5.6, 80.2, 3.7, 4.8), (800.1, 8001.1, -50.000001, -45.01)]
}
pub impl ClientRectList {
fn init_wrapper(@mut self) {
let content = global_content();
let cx = content.compartment.get().cx.ptr;
let owner = content.window.get();
let cache = owner.get_wrappercache();
let scope = cache.get_wrapper();
self.wrap_object_shared(cx, scope);
}
}

impl CacheableWrapper for ClientRectListImpl {
impl CacheableWrapper for ClientRectList {
fn get_wrappercache(&mut self) -> &mut WrapperCache {
unsafe { cast::transmute(&self.wrapper) }
}

fn wrap_object_unique(~self, cx: *JSContext, scope: *JSObject) -> *JSObject {
fn wrap_object_shared(@mut self, cx: *JSContext, scope: *JSObject) -> *JSObject {
let mut unused = false;
ClientRectListBinding::Wrap(cx, scope, self, &mut unused)
}

fn wrap_object_shared(@self, _cx: *JSContext, _scope: *JSObject) -> *JSObject {
fail!(~"nyi")
}
}

impl BindingObject for ClientRectListImpl {
fn GetParentObject(&self, cx: *JSContext) -> OpaqueBindingReference {
impl BindingObject for ClientRectList {
fn GetParentObject(&self, cx: *JSContext) -> @mut CacheableWrapper {
let content = task_from_context(cx);
unsafe { OpaqueBindingReference(Right((*content).window.get() as @CacheableWrapper)) }
unsafe { (*content).window.get() as @mut CacheableWrapper }
}
}
}
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.