diff --git a/global.rs b/global.rs deleted file mode 100644 index adcbd70b5..000000000 --- a/global.rs +++ /dev/null @@ -1,198 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * 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/. */ - -#![doc = " - -Handy functions for creating class objects and so forth. - -"] - -use libc::{c_uint, c_void}; -use std::str::raw::from_c_str; -use std::cast::transmute; -use std::ptr::null; -use jsapi; -use jsapi::{JSClass, JSContext, JSFunctionSpec, JSBool, JSNativeWrapper, JS_EnumerateStub}; -use jsapi::{JS_EncodeString, JS_free, JS_ValueToBoolean, JS_ValueToString, JS_ConvertStub}; -use jsapi::{JS_ReportError, JS_ValueToSource, JS_GC, JS_GetRuntime, JS_PropertyStub}; -use jsapi::{JS_StrictPropertyStub, JS_ResolveStub}; -use jsfriendapi::JSJitInfo; -use jsval::{JSVal, UndefinedValue}; -use JSCLASS_IS_GLOBAL; -use JSCLASS_HAS_RESERVED_SLOTS; -use JSCLASS_RESERVED_SLOTS_MASK; -use JSCLASS_RESERVED_SLOTS_SHIFT; -use JSCLASS_GLOBAL_SLOT_COUNT; -use JS_ARGV; -use JS_SET_RVAL; - -static global_name: [i8, ..7] = ['g' as i8, 'l' as i8, 'o' as i8, 'b' as i8, 'a' as i8, 'l' as i8, 0 as i8]; -pub static BASIC_GLOBAL: JSClass = JSClass { - name: &global_name as *i8, - flags: JSCLASS_IS_GLOBAL | (((JSCLASS_GLOBAL_SLOT_COUNT + 1) & JSCLASS_RESERVED_SLOTS_MASK) << JSCLASS_RESERVED_SLOTS_SHIFT), - addProperty: Some(JS_PropertyStub), - delProperty: Some(JS_PropertyStub), - getProperty: Some(JS_PropertyStub), - setProperty: Some(JS_StrictPropertyStub), - enumerate: Some(JS_EnumerateStub), - resolve: Some(JS_ResolveStub), - convert: Some(JS_ConvertStub), - finalize: None, - checkAccess: None, - call: None, - hasInstance: None, - construct: None, - trace: None, - reserved: (0 as *c_void, 0 as *c_void, 0 as *c_void, 0 as *c_void, 0 as *c_void, // 05 - 0 as *c_void, 0 as *c_void, 0 as *c_void, 0 as *c_void, 0 as *c_void, // 10 - 0 as *c_void, 0 as *c_void, 0 as *c_void, 0 as *c_void, 0 as *c_void, // 15 - 0 as *c_void, 0 as *c_void, 0 as *c_void, 0 as *c_void, 0 as *c_void, // 20 - 0 as *c_void, 0 as *c_void, 0 as *c_void, 0 as *c_void, 0 as *c_void, // 25 - 0 as *c_void, 0 as *c_void, 0 as *c_void, 0 as *c_void, 0 as *c_void, // 30 - 0 as *c_void, 0 as *c_void, 0 as *c_void, 0 as *c_void, 0 as *c_void, // 35 - 0 as *c_void, 0 as *c_void, 0 as *c_void, 0 as *c_void, 0 as *c_void) // 40 -}; - -pub fn basic_class(name: &'static str) -> JSClass { - JSClass { - name: name.as_ptr() as *i8, - flags: JSCLASS_IS_GLOBAL | JSCLASS_HAS_RESERVED_SLOTS(JSCLASS_GLOBAL_SLOT_COUNT + 1), - addProperty: Some(JS_PropertyStub), - delProperty: Some(JS_PropertyStub), - getProperty: Some(JS_PropertyStub), - setProperty: Some(JS_StrictPropertyStub), - enumerate: Some(JS_EnumerateStub), - resolve: Some(JS_ResolveStub), - convert: Some(JS_ConvertStub), - finalize: None, - checkAccess: None, - call: None, - hasInstance: None, - construct: None, - trace: None, - reserved: (null(), null(), null(), null(), null(), // 05 - null(), null(), null(), null(), null(), // 10 - null(), null(), null(), null(), null(), // 15 - null(), null(), null(), null(), null(), // 20 - null(), null(), null(), null(), null(), // 25 - null(), null(), null(), null(), null(), // 30 - null(), null(), null(), null(), null(), // 35 - null(), null(), null(), null(), null()) // 40 - } -} - -pub fn global_class() -> JSClass { - basic_class("global") -} - -pub unsafe fn jsval_to_rust_str(cx: *JSContext, vp: *jsapi::JSString) -> ~str { - if vp.is_null() { - ~"" - } else { - let bytes = JS_EncodeString(cx, vp); - let s = from_c_str(bytes); - JS_free(cx, transmute(bytes)); - s - } -} - -pub extern fn debug(cx: *JSContext, argc: c_uint, vp: *mut JSVal) -> JSBool { - unsafe { - let argv = JS_ARGV(cx, &*vp); - for i in range(0, argc as int) { - let jsstr = JS_ValueToString(cx, *argv.offset(i)); - debug!("{:s}", jsval_to_rust_str(cx, jsstr)); - } - JS_SET_RVAL(cx, &*vp, UndefinedValue()); - return 1_i32; - } -} - -pub extern fn gc(cx: *JSContext, _argc: c_uint, vp: *mut JSVal) -> JSBool { - unsafe { - JS_GC(JS_GetRuntime(cx)); - JS_SET_RVAL(cx, &*vp, UndefinedValue()); - return 1; - } -} - - -pub extern fn assert(cx: *JSContext, argc: c_uint, vp: *mut JSVal) -> JSBool { - unsafe { - let argv = JS_ARGV(cx, &*vp); - - let argument = match argc { - 0 => UndefinedValue(), - _ => *argv.offset(0) - }; - - let result = 0; - if JS_ValueToBoolean(cx, argument, &result) == 0 { - return 0_i32; - } - - if result == 0 { - // This operation can fail, but that is not critical. - let source = JS_ValueToSource(cx, argument); - let msg = format!("JavaScript assertion failed: {:s} is falsy!", - jsval_to_rust_str(cx, source)); - - debug!("{:s}", msg); - msg.to_c_str().with_ref(|buf| { - JS_ReportError(cx, buf); - }); - return 0_i32; - } - - JS_SET_RVAL(cx, &*vp, UndefinedValue()); - return 1_i32; - } -} - -static debug_name: [i8, ..6] = ['d' as i8, 'e' as i8, 'b' as i8, 'u' as i8, 'g' as i8, 0 as i8]; -static assert_name: [i8, ..7] = ['a' as i8, 's' as i8, 's' as i8, 'e' as i8, 'r' as i8, 't' as i8, 0 as i8]; -static gc_name: [i8, ..3] = ['g' as i8, 'c' as i8, 0 as i8]; - -pub static DEBUG_FNS: &'static [JSFunctionSpec] = &[ - JSFunctionSpec { - name: &debug_name as *i8, - call: JSNativeWrapper { - op: Some(debug), - info: 0 as *JSJitInfo - }, - nargs: 0, - flags: 0, - selfHostedName: 0 as *i8 - }, - JSFunctionSpec { - name: &assert_name as *i8, - call: JSNativeWrapper { - op: Some(assert), - info: 0 as *JSJitInfo - }, - nargs: 0, - flags: 0, - selfHostedName: 0 as *i8 - }, - JSFunctionSpec { - name: &gc_name as *i8, - call: JSNativeWrapper { - op: Some(gc), - info: 0 as *JSJitInfo - }, - nargs: 0, - flags: 0, - selfHostedName: 0 as *i8 - }, - JSFunctionSpec { - name: 0 as *i8, - call: JSNativeWrapper { - op: None, - info: 0 as *JSJitInfo, - }, - nargs: 0, - flags: 0, - selfHostedName: 0 as *i8 - } -]; diff --git a/js.rc b/js.rc index b7da9165e..2659b6662 100644 --- a/js.rc +++ b/js.rc @@ -21,15 +21,11 @@ extern crate serialize; use libc::c_uint; use libc::types::common::c99::uint32_t; -use std::cast; -use std::ptr::null; -use std::result::{Result, Ok, Err}; use jsapi::{JSBool, JSContext, JSPropertyOp, JSStrictPropertyOp, JSEnumerateOp, JSObject, jsid, JSResolveOp, JSConvertOp, JSFinalizeOp, JSTraceOp, JSProto_LIMIT, JSHandleObject, JSCheckAccessOp, JSNative, JSHasInstanceOp}; use jsapi::JS_ComputeThis; use jsval::JSVal; -use rust::jsobj; // These are just macros in jsapi.h pub use JS_NewRuntime = jsapi::JS_Init; @@ -45,7 +41,6 @@ pub use jsfriendapi::JSJitInfo; pub mod jsapi; pub mod linkhack; pub mod rust; -pub mod global; pub mod glue; pub mod trace; pub mod jsval; @@ -110,20 +105,13 @@ pub fn JSCLASS_HAS_RESERVED_SLOTS(n: c_uint) -> c_uint { (n & JSCLASS_RESERVED_SLOTS_MASK) << JSCLASS_RESERVED_SLOTS_SHIFT } -pub fn result(n: JSBool) -> Result<(),()> { - if n != ERR {Ok(())} else {Err(())} -} -pub fn result_obj(o: jsobj) -> Result { - if o.deref().ptr != null() {Ok(o)} else {Err(())} -} - #[inline(always)] pub unsafe fn JS_ARGV(_cx: *JSContext, vp: *JSVal) -> *JSVal { vp.offset(2) } pub unsafe fn JS_SET_RVAL(_cx: *JSContext, vp: *JSVal, v: JSVal) { - let vp: *mut JSVal = cast::transmute(vp); + let vp = vp as *mut JSVal; *vp = v; } diff --git a/rust.rs b/rust.rs index ecf756388..70332efb2 100644 --- a/rust.rs +++ b/rust.rs @@ -17,11 +17,7 @@ use JSOPTION_VAROBJFIX; use JSOPTION_METHODJIT; use JSOPTION_TYPE_INFERENCE; use ERR; -use std::ptr::null; -use result; -use result_obj; use std::str::raw::from_c_str; -use std::cast; use green::task::GreenTask; // ___________________________________________________________________________ @@ -60,7 +56,6 @@ impl RtUtils for rc::Rc { } } -// FIXME: Is this safe once we have more than one stack segment? extern fn gc_callback(rt: *JSRuntime, _status: JSGCStatus) { use std::rt::local::Local; use std::rt::task::Task; @@ -105,43 +100,6 @@ pub fn new_context(ptr: *JSContext, rt: rt) -> rc::Rc { }) } -pub trait CxUtils { - fn rooted_obj(&self, obj: *JSObject) -> jsobj; - fn new_compartment(&self, globcls: *JSClass) -> Result,()>; - fn new_compartment_with_global(&self, global: *JSObject) -> Result,()>; -} - -impl CxUtils for rc::Rc { - fn rooted_obj(&self, obj: *JSObject) -> jsobj { - let cxptr = self.deref().ptr; - let jsobj = rc::Rc::new(jsobj_rsrc {cx: self.clone(), cxptr: cxptr, ptr: obj}); - unsafe { - JS_AddObjectRoot(cxptr, &jsobj.deref().ptr); - } - jsobj - } - - fn new_compartment(&self, globcls: *JSClass) -> Result,()> { - unsafe { - let ptr = self.deref().ptr; - let globobj = JS_NewGlobalObject(ptr, globcls, null()); - result(JS_InitStandardClasses(ptr, globobj)).and_then(|_ok| { - Ok(rc::Rc::new(Compartment { - cx: self.clone(), - global_obj: globobj, - })) - }) - } - } - - fn new_compartment_with_global(&self, global: *JSObject) -> Result,()> { - Ok(rc::Rc::new(Compartment { - cx: self.clone(), - global_obj: global, - })) - } -} - impl Cx { pub fn set_default_options_and_version(&self) { self.set_options(JSOPTION_VAROBJFIX | JSOPTION_METHODJIT | @@ -195,28 +153,12 @@ impl Cx { } }) } - - pub unsafe fn get_cx_private(&self) -> *() { - cast::transmute(JS_GetContextPrivate(self.ptr)) - } - - pub unsafe fn set_cx_private(&self, data: *()) { - JS_SetContextPrivate(self.ptr, cast::transmute(data)); - } - - pub unsafe fn get_obj_private(&self, obj: *JSObject) -> *() { - cast::transmute(JS_GetPrivate(obj)) - } - - pub unsafe fn set_obj_private(&self, obj: *JSObject, data: *()) { - JS_SetPrivate(obj, cast::transmute(data)); - } } pub extern 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 fname = if fnptr.is_not_null() {from_c_str(fnptr)} else {"none".to_owned()}; let lineno = (*report).lineno; let msg = from_c_str(msg); error!("Error at {:s}:{}: {:s}\n", fname, lineno, msg); @@ -232,108 +174,10 @@ pub fn with_compartment(cx: *JSContext, object: *JSObject, cb: || -> R) -> R } } -// ___________________________________________________________________________ -// compartment - -pub struct Compartment { - pub cx: rc::Rc, - pub global_obj: *JSObject, -} - -impl Compartment { - pub fn define_functions(&self, specvec: &'static [JSFunctionSpec]) -> Result<(),()> { - unsafe { - result(JS_DefineFunctions(self.cx.deref().ptr, - self.global_obj, - specvec.as_ptr())) - } - } - pub fn define_properties(&self, specvec: &'static [JSPropertySpec]) -> Result<(),()> { - unsafe { - result(JS_DefineProperties(self.cx.deref().ptr, - self.global_obj, - specvec.as_ptr())) - } - } - pub fn define_property(&self, - name: &'static str, - value: JSVal, - getter: JSPropertyOp, setter: JSStrictPropertyOp, - attrs: c_uint) - -> Result<(),()> { - unsafe { - name.to_c_str().with_ref(|name| { - result(JS_DefineProperty(self.cx.deref().ptr, - self.global_obj, - name, - value, - Some(getter), - Some(setter), - attrs)) - }) - } - } - pub fn new_object(&self, classptr: *JSClass, proto: *JSObject, parent: *JSObject) - -> Result { - unsafe { - let obj = self.cx.rooted_obj(JS_NewObject(self.cx.deref().ptr, classptr, proto, parent)); - result_obj(obj) - } - } -} - -// ___________________________________________________________________________ -// objects - -pub type jsobj = rc::Rc; - -pub struct jsobj_rsrc { - cx: rc::Rc, - cxptr: *JSContext, - pub ptr: *JSObject, -} - -#[unsafe_destructor] -impl Drop for jsobj_rsrc { - fn drop(&mut self) { - unsafe { - JS_RemoveObjectRoot(self.cxptr, &self.ptr); - } - } -} - -impl jsobj_rsrc { - pub fn new_object(&self, cx: rc::Rc, cxptr: *JSContext, ptr: *JSObject) -> jsobj { - return rc::Rc::new(jsobj_rsrc { - cx: cx, - cxptr: cxptr, - ptr: ptr - }) - } -} - -// ___________________________________________________________________________ -// random utilities - -pub trait to_jsstr { - fn to_jsstr(self, cx: rc::Rc) -> *JSString; -} - -impl to_jsstr for ~str { - fn to_jsstr(self, cx: rc::Rc) -> *JSString { - unsafe { - let cbuf = cast::transmute(self.as_ptr()); - JS_NewStringCopyN(cx.deref().ptr, cbuf, self.len() as size_t) - } - } -} - #[cfg(test)] pub mod test { use super::rt; - use super::{CxUtils, RtUtils}; - use super::super::global; - use super::super::jsapi::{JS_GC, JS_GetRuntime}; + use super::RtUtils; #[test] pub fn dummy() { @@ -341,14 +185,6 @@ pub mod test { let cx = rt.cx(); cx.deref().set_default_options_and_version(); cx.deref().set_logging_error_reporter(); - cx.new_compartment(&global::BASIC_GLOBAL).and_then(|comp| { - unsafe { JS_GC(JS_GetRuntime(cx.deref().ptr)); } - - comp.deref().define_functions(global::DEBUG_FNS); - - let s = ~"debug(22);"; - cx.deref().evaluate_script(comp.deref().global_obj, s, ~"test", 1u) - }); } }