initial integration of spidermonkey into servo

This commit is contained in:
Niko Matsakis 2012-05-24 14:15:59 -07:00
parent adc6d3701d
commit 5c31f3d45e
3 changed files with 75 additions and 35 deletions

View file

@ -1,9 +1,12 @@
import jsapi::*;
import jsapi::bindgen::*;
import spidermonkey::*;
import spidermonkey::jsapi::*;
import spidermonkey::jsapi::bindgen::*;
import ptr::{null, addr_of};
import result::{result, ok, err, extensions};
import libc::c_char;
import name_pool::{name_pool, methods};
import str::unsafe::from_c_str;
import io::writer_util;
export rt;
export methods;
@ -58,6 +61,23 @@ impl methods for cx {
jsobj
}
fn set_default_options_and_version() {
self.set_options(JSOPTION_VAROBJFIX | JSOPTION_METHODJIT);
self.set_version(JSVERSION_LATEST);
}
fn set_options(v: jsuint) {
JS_SetOptions(self.ptr, v);
}
fn set_version(v: i32) {
JS_SetVersion(self.ptr, v);
}
fn set_error_reporter(reportfn: *u8) {
JS_SetErrorReporter(self.ptr, reportfn);
}
fn new_compartment(globclsfn: fn(name_pool) -> JSClass) -> result<compartment,()> {
let np = name_pool();
let globcls = @globclsfn(np);
@ -67,9 +87,11 @@ impl methods for cx {
&*globcls as *JSClass,
null());
result(JS_InitStandardClasses(self.ptr, globobj)).chain { |_ok|
ok({name_pool: np,
global_class: globcls,
global_obj: self.rooted_obj(globobj)})
ok(@{cx: self,
name_pool: np,
global_class: globcls,
mut global_funcs: [],
global_obj: self.rooted_obj(globobj)})
}
}
@ -79,7 +101,7 @@ impl methods for cx {
str::as_c_str(filename) { |filename_cstr|
let bytes_ptr = bytes_ptr as *c_char;
let v: jsval = 0_u64;
#debug["Evaluating script from %s", filename];
#debug["Evaluating script from %s with bytes %?", filename, bytes];
if JS_EvaluateScript(self.ptr, glob.ptr,
bytes_ptr, bytes.len() as uintN,
filename_cstr, line_num as uintN,
@ -100,12 +122,24 @@ impl methods for cx {
// ___________________________________________________________________________
// compartment
type compartment = {
type compartment = @{
cx: cx,
name_pool: name_pool,
global_class: @JSClass,
mut global_funcs: [@[JSFunctionSpec]],
global_obj: jsobj
};
impl methods for compartment {
fn define_functions(specfn: fn(name_pool) -> [JSFunctionSpec]) -> result<(),()> {
let specvec = @specfn(self.name_pool);
self.global_funcs += [specvec];
vec::as_buf(*specvec) { |specs|
result(JS_DefineFunctions(self.cx.ptr, self.global_obj.ptr, specs))
}
}
}
// ___________________________________________________________________________
// objects
@ -118,18 +152,29 @@ resource jsobj_rsrc(self: {cx: cx, cxptr: *JSContext, ptr: *JSObject}) {
#[cfg(test)]
mod test {
crust fn reportError(_cx: *JSContext,
msg: *c_char,
report: *JSErrorReport) {
unsafe {
let fnptr = (*report).filename;
let fname = if fnptr.is_not_null() {from_c_str(fnptr)} else {"none"};
let lineno = (*report).lineno;
let msg = from_c_str(msg);
#error["Error at %s:%?: %s\n", fname, lineno, msg];
}
}
#[test]
fn dummy() {
let rt = rt();
let cx = rt.cx();
let gc = jsglobal::global_class();
cx.new_global(gc).chain {
|glob|
str::as_bytes("print(\"1\");") {
|bytes|
cx.evaluate_script(glob, bytes, "test", 1u)
};
ok(())
cx.set_default_options_and_version();
cx.set_error_reporter(reportError);
cx.new_compartment(jsglobal::global_class).chain { |comp|
comp.define_functions(jsglobal::global_fns);
let bytes = str::bytes("debug(22);");
cx.evaluate_script(comp.global_obj, bytes, "test", 1u)
};
}

View file

@ -1,23 +1,19 @@
// Definition for the global object that we use:
import jsapi::*;
import jsapi::bindgen::*;
import spidermonkey::*;
import spidermonkey::jsapi::*;
import spidermonkey::jsapi::bindgen::*;
import ptr::null;
import jsutil::*;
import name_pool::{name_pool, methods};
crust fn PropertyStub(++arg0: *JSContext,
++arg1: *JSObject,
++arg2: jsid,
++arg3: *jsval) -> JSBool {
// Can't use spidermonkey::crust::* versions due to Rust #2440
crust fn PropertyStub(++arg0: *JSContext, ++arg1: *JSObject, ++arg2: jsid, ++arg3: *jsval) -> JSBool {
JS_PropertyStub(arg0, arg1, arg2, arg3)
}
crust fn StrictPropertyStub(++arg0: *JSContext,
++arg1: *JSObject,
++arg2: jsid,
++arg3: JSBool,
++arg4: *jsval) -> JSBool {
crust fn StrictPropertyStub(++arg0: *JSContext, ++arg1: *JSObject, ++arg2: jsid, ++arg3: JSBool, ++arg4: *jsval) -> JSBool {
JS_StrictPropertyStub(arg0, arg1, arg2, arg3, arg4)
}
@ -67,9 +63,11 @@ fn global_class(np: name_pool) -> JSClass {
null(), null(), null(), null(), null())} // 40
}
crust fn print(cx: *JSContext, argc: uintN, vp: *jsval) {
crust fn debug(cx: *JSContext, argc: uintN, vp: *jsval) {
import io::writer_util;
#debug["debug() called with %? arguments", argc];
unsafe {
let argv = JS_ARGV(cx, vp);
uint::range(0u, argc as uint) { |i|
@ -77,16 +75,15 @@ crust fn print(cx: *JSContext, argc: uintN, vp: *jsval) {
let bytes = JS_EncodeString(cx, jsstr);
let str = str::unsafe::from_c_str(bytes);
JS_free(cx, unsafe::reinterpret_cast(bytes));
io::stdout().write_str(str);
io::stdout().write_str("\n");
#debug["%s", str];
}
JS_SET_RVAL(cx, vp, JSVAL_NULL);
}
}
fn global_fns(np: name_pool) -> [JSFunctionSpec] {
[{name: np.add("print"),
call: print,
[{name: np.add("debug"),
call: debug,
nargs: 0_u16,
flags: 0_u16}]
}
}

View file

@ -9,11 +9,9 @@
use std;
use sdl;
use azure;
use js;
use spidermonkey (name = "js");
use harfbuzz;
import js::jsapi;
mod dom {
mod base;
mod rcu;