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

Make GC work.

  • Loading branch information
jdm committed Apr 23, 2013
commit db5eca476491597e9b29a7acce7333784ca1ca93
@@ -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,72 @@
diff --git a/js/src/jsapi.cpp b/js/src/jsapi.cpp
index 5571fc0..df2fabd 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,13 @@ JS_SetRuntimeThread(JSRuntime *rt)
#endif
}

+extern JS_PUBLIC_API(void)
+JS_SetNativeStackBounds(JSRuntime *rt, uintptr_t stackBase, uintptr_t stackEnd)
+{
+ rt->nativeStackBase = stackBase;
+ rt->nativeStackEnd = stackEnd;
+}
+
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..0edb722 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 stackBase, uintptr_t stackEnd);
+
#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

@@ -32,10 +32,10 @@ extern fn finalize(_fop: *JSFreeOp, obj: *JSObject) {
}
}

pub extern fn trace(tracer: *JSTracer, obj: *JSObject) {
pub extern fn trace(tracer: *mut JSTracer, obj: *JSObject) {
let node = unsafe { unwrap(obj) };

fn trace_node(tracer: *JSTracer, node: Option<AbstractNode>, name: &str) {
fn trace_node(tracer: *mut JSTracer, node: Option<AbstractNode>, name: &str) {
if node.is_none() {
return;
}
@@ -45,7 +45,12 @@ pub extern fn trace(tracer: *JSTracer, obj: *JSObject) {
let wrapper = cache.get_wrapper();
assert!(wrapper.is_not_null());
unsafe {
JS_CallTracer(tracer, wrapper, JSTRACE_OBJECT as u32);
(*tracer).debugPrinter = ptr::null();
(*tracer).debugPrintIndex = -1;
do str::as_c_str(name) |name| {
(*tracer).debugPrintArg = name as *libc::c_void;
JS_CallTracer(cast::transmute(tracer), wrapper, JSTRACE_OBJECT as u32);
}
}
}
error!("tracing %?:", obj as uint);
@@ -290,10 +290,8 @@ static DOM_PROXY_OBJECT_SLOT: uint = js::JSSLOT_PROXY_PRIVATE as uint;
// changes.
static DOM_PROTO_INSTANCE_CLASS_SLOT: u32 = 0;

// All DOM globals must have a slot at DOM_PROTOTYPE_SLOT. We have to
// start at 1 past JSCLASS_GLOBAL_SLOT_COUNT because XPConnect uses
// that one.
pub static DOM_PROTOTYPE_SLOT: u32 = js::JSCLASS_GLOBAL_SLOT_COUNT + 1;
// All DOM globals must have a slot at DOM_PROTOTYPE_SLOT.
pub static DOM_PROTOTYPE_SLOT: u32 = js::JSCLASS_GLOBAL_SLOT_COUNT;

// NOTE: This is baked into the Ion JIT as 0 in codegen for LGetDOMProperty and
// LSetDOMProperty. Those constants need to be changed accordingly if this value
@@ -580,6 +578,10 @@ pub impl WrapperCache {
self.wrapper = wrapper;
}

fn get_rootable(&self) -> **JSObject {
return ptr::addr_of(&self.wrapper);
}

fn new() -> WrapperCache {
WrapperCache {
wrapper: ptr::null()
@@ -16,7 +16,7 @@ use js::crust::{JS_PropertyStub, JS_StrictPropertyStub};
use js::global::jsval_to_rust_str;
use js::glue::bindgen::*;
use js::glue::bindgen::RUST_JSVAL_TO_INT;
use js::jsapi::bindgen::{JS_DefineFunctions};
use js::jsapi::bindgen::{JS_DefineFunctions, JS_GC, JS_GetRuntime};
use js::jsapi::bindgen::{JS_GetReservedSlot, JS_SetReservedSlot};
use js::jsapi::bindgen::{JS_ValueToString};
use js::jsapi::{JSContext, JSVal, JSObject, JSBool, JSFreeOp, JSFunctionSpec};
@@ -31,12 +31,15 @@ extern fn alert(cx: *JSContext, argc: c_uint, vp: *JSVal) -> JSBool {
assert!(argc == 1);
// Abstract this pattern and use it in debug, too?
let jsstr = JS_ValueToString(cx, *ptr::offset(argv, 0));
if jsstr.is_null() {
return 0;
}

(*unwrap(JS_THIS_OBJECT(cx, vp))).payload.alert(jsval_to_rust_str(cx, jsstr));

JS_SET_RVAL(cx, vp, JSVAL_NULL);
return 1;
}
1_i32
}

extern fn setTimeout(cx: *JSContext, argc: c_uint, vp: *JSVal) -> JSBool {
@@ -63,6 +66,14 @@ extern fn close(cx: *JSContext, _argc: c_uint, vp: *JSVal) -> JSBool {
}
}

extern fn gc(cx: *JSContext, _argc: c_uint, _vp: *JSVal) -> JSBool {
unsafe {
let runtime = JS_GetRuntime(cx);
JS_GC(runtime);
return 1;
}
}

unsafe fn unwrap(obj: *JSObject) -> *rust_box<Window> {
let val = JS_GetReservedSlot(obj, 0);
cast::reinterpret_cast(&RUST_JSVAL_TO_PRIVATE(val))
@@ -99,7 +110,14 @@ pub fn init(compartment: @mut Compartment) {
JSFunctionSpec {
name: compartment.add_name(~"close"),
call: JSNativeWrapper { op: close, info: null() },
nargs: 2,
nargs: 0,
flags: 0,
selfHostedName: null()
},
JSFunctionSpec {
name: compartment.add_name(~"_trigger_gc"),
call: JSNativeWrapper { op: gc, info: null() },
nargs: 0,
flags: 0,
selfHostedName: null()
},
@@ -27,9 +27,9 @@ pub fn Document(root: AbstractNode,
};
let compartment = global_content().compartment.get();
do root.with_imm_node |node| {
let wrapper = node.wrapper.get_wrapper();
assert!(wrapper.is_not_null());
unsafe { JS_AddObjectRoot(compartment.cx.ptr, ptr::addr_of(&wrapper)); }
assert!(node.wrapper.get_wrapper().is_not_null());
let rootable = node.wrapper.get_rootable();
unsafe { JS_AddObjectRoot(compartment.cx.ptr, rootable); }
}
document::create(compartment, doc);
doc
@@ -40,9 +40,9 @@ impl Drop for Document {
fn finalize(&self) {
let compartment = global_content().compartment.get();
do self.root.with_imm_node |node| {
let wrapper = node.wrapper.get_wrapper();
assert!(wrapper.is_not_null());
unsafe { JS_RemoveObjectRoot(compartment.cx.ptr, ptr::addr_of(&wrapper)); }
assert!(node.wrapper.get_wrapper().is_not_null());
let rootable = node.wrapper.get_rootable();
unsafe { JS_RemoveObjectRoot(compartment.cx.ptr, rootable); }
}
}
}
@@ -20,13 +20,6 @@ pub struct Element {
attrs: ~[Attr],
}

#[unsafe_destructor]
impl Drop for Element {
fn finalize(&self) {
fail!(~"uh oh");
}
}

#[deriving(Eq)]
pub enum ElementTypeId {
HTMLAnchorElementTypeId,
@@ -1,3 +1,3 @@
div #styled {
#styled {
color: red;
}
@@ -4,6 +4,6 @@
<script src="test_hammer_layout.js"></script>
</head>
<body>
<div id="styled">This text is unstyled.</div>
<div id="">This text is unstyled.</div>
</body>
</html>
@@ -1,17 +1,6 @@
window.setTimeout(function() {
//var divs = document.getElementsByTagName("div");
// divs[0].setAttribute('id', 'styled');
function print_tree(n) {
window.alert(n.nodeType);
//window.alert(n.tagName);
n = n.firstChild;
while (n) {
print_tree(n);
n = n.nextSibling;
}
}
print_tree(document.documentElement);
//window.alert(document.documentElement.tagName);
//window.alert(document.documentElement.firstChild.nodeType);
//window.alert(document.documentElement.firstChild.firstChild.nodeType);
}, 200);
var divs = document.getElementsByTagName("div");
var div = divs[0];
for (var i = 0; i < 1000000; i++) {
div.setAttribute('id', 'styled');
}

ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.