diff --git a/src/lib/exec.rs b/src/lib/exec.rs index 107b0824f7..d438a0537d 100644 --- a/src/lib/exec.rs +++ b/src/lib/exec.rs @@ -9,6 +9,7 @@ use syntax::ast::constant::Const; use syntax::ast::expr::{Expr, ExprDef}; use syntax::ast::op::{BinOp, BitOp, CompOp, LogOp, NumOp, UnaryOp}; /// A variable scope +#[derive(Trace, Finalize, Clone, Debug)] pub struct Scope { /// The value of `this` in the scope pub this: Value, @@ -25,7 +26,7 @@ pub trait Executor { /// Resolve the global variable `name` fn get_global(&self, name: String) -> Value; /// Create a new scope and return it - fn make_scope(&mut self, this: Value) -> &Scope; + fn make_scope(&mut self, this: Value) -> Scope; /// Destroy the current scope fn destroy_scope(&mut self) -> Scope; /// Run an expression @@ -75,13 +76,13 @@ impl Executor for Interpreter { self.global.borrow().get_field(name) } - fn make_scope(&mut self, this: Value) -> &Scope { + fn make_scope(&mut self, this: Value) -> Scope { let scope = Scope { this: this, vars: ValueData::new_obj(None), }; - self.scopes.push(scope); - &scope + self.scopes.push(scope.clone()); + scope } fn destroy_scope(&mut self) -> Scope { @@ -94,7 +95,7 @@ impl Executor for Interpreter { ExprDef::ConstExpr(Const::Undefined) => Ok(Gc::new(ValueData::Undefined)), ExprDef::ConstExpr(Const::Num(num)) => Ok(to_value(num)), ExprDef::ConstExpr(Const::Int(num)) => Ok(to_value(num)), - ExprDef::ConstExpr(Const::String(str)) => Ok(to_value(str)), + ExprDef::ConstExpr(Const::String(ref str)) => Ok(to_value(str.to_owned())), ExprDef::ConstExpr(Const::Bool(val)) => Ok(to_value(val)), ExprDef::ConstExpr(Const::RegExp(_, _, _)) => Ok(to_value(None::<()>)), ExprDef::BlockExpr(ref es) => { @@ -115,7 +116,7 @@ impl Executor for Interpreter { match *vars_ptr.clone() { ValueData::Object(ref obj) => match obj.borrow().get(name) { Some(v) => { - val = v.value; + val = v.value.clone(); break; } None => (), diff --git a/src/lib/js/array.rs b/src/lib/js/array.rs index 00d3744b30..5457daf53b 100644 --- a/src/lib/js/array.rs +++ b/src/lib/js/array.rs @@ -4,7 +4,7 @@ use js::value::{to_value, ResultValue, Value, ValueData}; /// Create a new array pub fn make_array(this: Value, _: Value, _: Vec) -> ResultValue { - let this_ptr = *this; + let this_ptr = this.clone(); this_ptr.set_field_slice("length", to_value(0i32)); Ok(Gc::new(ValueData::Undefined)) } diff --git a/src/lib/js/console.rs b/src/lib/js/console.rs index 1d4e6c8487..352153c403 100644 --- a/src/lib/js/console.rs +++ b/src/lib/js/console.rs @@ -5,8 +5,10 @@ use std::iter::FromIterator; use time::{now, strftime}; /// Print a javascript value to the standard output stream pub fn log(_: Value, _: Value, args: Vec) -> ResultValue { - let args: Vec = - FromIterator::from_iter(args.iter().map(|x| from_value::(*x).unwrap())); + let args: Vec = FromIterator::from_iter( + args.iter() + .map(|x| from_value::(x.clone()).unwrap()), + ); println!("{}: {}", strftime("%X", &now()).unwrap(), args.join(" ")); Ok(Gc::new(ValueData::Undefined)) } diff --git a/src/lib/js/error.rs b/src/lib/js/error.rs index 315882b417..68123ac65c 100644 --- a/src/lib/js/error.rs +++ b/src/lib/js/error.rs @@ -19,13 +19,11 @@ pub fn to_string(this: Value, _: Value, _: Vec) -> ResultValue { /// Create a new `Error` object pub fn _create(global: Value) -> Value { let prototype = ValueData::new_obj(Some(global)); - let prototype_ptr = prototype; - prototype_ptr.set_field_slice("message", to_value("")); - prototype_ptr.set_field_slice("name", to_value("Error")); - prototype_ptr.set_field_slice("toString", to_value(to_string as NativeFunctionData)); + prototype.set_field_slice("message", to_value("")); + prototype.set_field_slice("name", to_value("Error")); + prototype.set_field_slice("toString", to_value(to_string as NativeFunctionData)); let error = to_value(make_error as NativeFunctionData); - let error_ptr = error; - error_ptr.set_field_slice(PROTOTYPE, prototype); + error.set_field_slice(PROTOTYPE, prototype); error } /// Initialise the global object with the `Error` object diff --git a/src/lib/js/object.rs b/src/lib/js/object.rs index 8202e51f58..ef010db999 100644 --- a/src/lib/js/object.rs +++ b/src/lib/js/object.rs @@ -114,24 +114,23 @@ pub fn has_own_prop(this: Value, _: Value, args: Vec) -> ResultValue { /// Create a new `Object` object pub fn _create(global: Value) -> Value { let object = to_value(make_object as NativeFunctionData); - let object_ptr = object; let prototype = ValueData::new_obj(Some(global)); prototype.set_field_slice( "hasOwnProperty", to_value(has_own_prop as NativeFunctionData), ); prototype.set_field_slice("toString", to_value(to_string as NativeFunctionData)); - object_ptr.set_field_slice("length", to_value(1i32)); - object_ptr.set_field_slice(PROTOTYPE, prototype); - object_ptr.set_field_slice( + object.set_field_slice("length", to_value(1i32)); + object.set_field_slice(PROTOTYPE, prototype); + object.set_field_slice( "setPrototypeOf", to_value(set_proto_of as NativeFunctionData), ); - object_ptr.set_field_slice( + object.set_field_slice( "getPrototypeOf", to_value(get_proto_of as NativeFunctionData), ); - object_ptr.set_field_slice( + object.set_field_slice( "defineProperty", to_value(define_prop as NativeFunctionData), ); diff --git a/src/lib/js/value.rs b/src/lib/js/value.rs index 7d5c260c8f..c9251e3bf4 100644 --- a/src/lib/js/value.rs +++ b/src/lib/js/value.rs @@ -218,8 +218,10 @@ impl ValueData { } ValueData::Function(ref func) => { match *func.borrow_mut().deref_mut() { - Function::NativeFunc(ref mut f) => f.object.insert(field.clone(), prop), - Function::RegularFunc(ref mut f) => f.object.insert(field.clone(), prop), + Function::NativeFunc(ref mut f) => f.object.insert(field.clone(), prop.clone()), + Function::RegularFunc(ref mut f) => { + f.object.insert(field.clone(), prop.clone()) + } }; } _ => (), @@ -309,8 +311,8 @@ impl Display for ValueData { "{}", match v { _ if v.is_nan() => "NaN".to_string(), - std::f64::INFINITY => "Infinity".to_string(), - std::f64::NEG_INFINITY => "-Infinity".to_string(), + _ if v.is_infinite() && v.is_sign_negative() => "-Infinity".to_string(), + _ if v.is_infinite() => "Infinity".to_string(), _ => v.to_string(), } ),