Load scripts in workers.

This commit is contained in:
Ms2ger 2014-07-15 17:32:52 +02:00
parent 7b7303e6bc
commit b11440750b
3 changed files with 52 additions and 19 deletions

View file

@ -10,8 +10,12 @@ use dom::eventtarget::EventTarget;
use dom::eventtarget::WorkerGlobalScopeTypeId;
use dom::workerglobalscope::DedicatedGlobalScope;
use dom::workerglobalscope::WorkerGlobalScope;
use script_task::ScriptTask;
use js::jsapi::JSContext;
use js::rust::Cx;
use std::rc::Rc;
#[deriving(Encodable)]
pub struct DedicatedWorkerGlobalScope {
@ -29,6 +33,12 @@ impl DedicatedWorkerGlobalScope {
let scope = box DedicatedWorkerGlobalScope::new_inherited();
DedicatedWorkerGlobalScopeBinding::Wrap(cx, scope)
}
pub fn init() -> (Rc<Cx>, Temporary<DedicatedWorkerGlobalScope>) {
let (_js_runtime, js_context) = ScriptTask::new_rt_and_cx();
let global = DedicatedWorkerGlobalScope::new(js_context.ptr);
(js_context, global)
}
}
pub trait DedicatedWorkerGlobalScopeMethods {

View file

@ -4,10 +4,13 @@
use dom::bindings::error::{Fallible, Security, Syntax};
use dom::bindings::global::GlobalRef;
use dom::bindings::js::Temporary;
use dom::bindings::js::{Temporary, RootCollection};
use dom::bindings::utils::{Reflectable, Reflector};
use dom::dedicatedworkerglobalscope::DedicatedWorkerGlobalScope;
use dom::eventtarget::EventTarget;
use script_task::StackRootTLS;
use servo_net::resource_task::load_whole_resource;
use servo_util::str::DOMString;
use servo_util::url::try_parse_url;
@ -27,8 +30,27 @@ impl Worker {
};
let name = format!("Web Worker at {}", worker_url);
let resource_task = global.page().resource_task.deref().clone();
TaskBuilder::new().named(name).spawn(proc() {
println!("Spawned!");
let roots = RootCollection::new();
let _stack_roots_tls = StackRootTLS::new(&roots);
let (filename, source) = match load_whole_resource(&resource_task, worker_url.clone()) {
Err(_) => {
println!("error loading script {}", worker_url);
return;
}
Ok((metadata, bytes)) => {
(metadata.final_url, String::from_utf8(bytes).unwrap())
}
};
let (cx, global) = DedicatedWorkerGlobalScope::init();
let global = global.root();
match cx.evaluate_script(global.reflector().get_jsobject(), source, filename.to_str(), 1) {
Ok(_) => (),
Err(_) => println!("evaluate_script failed")
}
});
Err(Security)
}

View file

@ -115,10 +115,10 @@ impl ScriptChan {
}
}
struct StackRootTLS;
pub struct StackRootTLS;
impl StackRootTLS {
fn new(roots: &RootCollection) -> StackRootTLS {
pub fn new(roots: &RootCollection) -> StackRootTLS {
StackRoots.replace(Some(roots as *RootCollection));
StackRootTLS
}
@ -210,6 +210,21 @@ impl ScriptTask {
window_size: WindowSizeData)
-> Rc<ScriptTask> {
let (js_runtime, js_context) = ScriptTask::new_rt_and_cx();
unsafe {
// JS_SetWrapObjectCallbacks clobbers the existing wrap callback,
// and JSCompartment::wrap crashes if that happens. The only way
// to retrieve the default callback is as the result of
// JS_SetWrapObjectCallbacks, which is why we call it twice.
let callback = JS_SetWrapObjectCallbacks((*js_runtime).ptr,
None,
Some(wrap_for_same_compartment),
None);
JS_SetWrapObjectCallbacks((*js_runtime).ptr,
callback,
Some(wrap_for_same_compartment),
Some(pre_wrap));
}
let page = Page::new(id, None, layout_chan, window_size,
resource_task.clone(),
constellation_chan.clone(),
@ -231,26 +246,12 @@ impl ScriptTask {
})
}
fn new_rt_and_cx() -> (js::rust::rt, Rc<Cx>) {
pub fn new_rt_and_cx() -> (js::rust::rt, Rc<Cx>) {
let js_runtime = js::rust::rt();
assert!({
let ptr: *mut JSRuntime = (*js_runtime).ptr;
ptr.is_not_null()
});
unsafe {
// JS_SetWrapObjectCallbacks clobbers the existing wrap callback,
// and JSCompartment::wrap crashes if that happens. The only way
// to retrieve the default callback is as the result of
// JS_SetWrapObjectCallbacks, which is why we call it twice.
let callback = JS_SetWrapObjectCallbacks((*js_runtime).ptr,
None,
Some(wrap_for_same_compartment),
None);
JS_SetWrapObjectCallbacks((*js_runtime).ptr,
callback,
Some(wrap_for_same_compartment),
Some(pre_wrap));
}
let js_context = js_runtime.cx();
assert!({