From 821632972b352d487bb052770cf47c40104151b5 Mon Sep 17 00:00:00 2001 From: Jason Williams <936006+jasonwilliams@users.noreply.github.com> Date: Wed, 25 Sep 2019 15:32:33 +0100 Subject: [PATCH] Addition of arguments object (#109) * testing PR * making a start to arguments object * arguments * finishing arguments for now --- benches/fib.rs | 2 -- src/lib/exec.rs | 14 +++++++++--- src/lib/js/function.rs | 50 ++++++++++++++++++++++++++++++++++++++++++ tests/js/test.js | 6 +++-- 4 files changed, 65 insertions(+), 7 deletions(-) diff --git a/benches/fib.rs b/benches/fib.rs index 1ef30fbdec..09af95c222 100644 --- a/benches/fib.rs +++ b/benches/fib.rs @@ -2,8 +2,6 @@ extern crate criterion; use boa::exec; -use boa::syntax::lexer::Lexer; -use boa::syntax::parser::Parser; use criterion::black_box; use criterion::Criterion; diff --git a/src/lib/exec.rs b/src/lib/exec.rs index 5e4881d681..19458ce4f6 100644 --- a/src/lib/exec.rs +++ b/src/lib/exec.rs @@ -2,7 +2,7 @@ use crate::{ environment::lexical_environment::{new_function_environment, LexicalEnvironment}, js::{ array, boolean, console, function, - function::{Function, RegularFunction}, + function::{create_unmapped_arguments_object, Function, RegularFunction}, json, math, object, object::{ObjectKind, INSTANCE_PROTOTYPE, PROTOTYPE}, regexp, string, @@ -487,10 +487,18 @@ impl Interpreter { )); for i in 0..data.args.len() { let name = data.args.get(i).unwrap(); - let expr = arguments_list.get(i).unwrap(); + let expr: &Value = arguments_list.get(i).unwrap(); self.environment.create_mutable_binding(name.clone(), false); - self.environment.initialize_binding(name, expr.to_owned()); + self.environment.initialize_binding(name, expr.clone()); } + + // Add arguments object + let arguments_obj = create_unmapped_arguments_object(arguments_list); + self.environment + .create_mutable_binding("arguments".to_string(), false); + self.environment + .initialize_binding("arguments", arguments_obj); + let result = self.run(&data.expr); self.environment.pop(); result diff --git a/src/lib/js/function.rs b/src/lib/js/function.rs index 7737488530..06d219d9ad 100644 --- a/src/lib/js/function.rs +++ b/src/lib/js/function.rs @@ -101,3 +101,53 @@ pub fn init(global: &Value) { let global_ptr = global; global_ptr.set_field_slice("Function", _create()); } + +/// Arguments +/// https://tc39.es/ecma262/#sec-createunmappedargumentsobject +pub fn create_unmapped_arguments_object(arguments_list: Vec) -> Value { + let len = arguments_list.len(); + let mut obj = Object::default(); + obj.set_internal_slot("ParameterMap", Gc::new(ValueData::Undefined)); + // Set length + let mut length = Property::default(); + length = length.writable(true).value(to_value(len)); + // Define length as a property + obj.define_own_property("length".to_string(), length); + let mut index: usize = 0; + while index < len { + let val = arguments_list.get(index).unwrap(); + let mut prop = Property::default(); + prop = prop + .value(val.clone()) + .enumerable(true) + .writable(true) + .configurable(true); + + obj.properties.insert(index.to_string(), prop); + index += 1; + } + + to_value(obj) +} + +#[cfg(test)] +mod tests { + use crate::exec::Executor; + use crate::{forward, forward_val, js::value::from_value}; + + #[test] + fn check_arguments_object() { + let mut engine = Executor::new(); + let init = r#" + function jason(a, b) { + return arguments[0]; + } + const val = jason(100, 6); + "#; + + forward(&mut engine, init); + let return_val = forward_val(&mut engine, "val").expect("value expected"); + assert_eq!(return_val.is_double(), true); + assert_eq!(from_value::(return_val).unwrap(), 100.0); + } +} diff --git a/tests/js/test.js b/tests/js/test.js index 3fbc177066..b895dfad00 100644 --- a/tests/js/test.js +++ b/tests/js/test.js @@ -1,2 +1,4 @@ -let a = "hello world"; -a; +function jason(a, b) { + return arguments[0]; +} +const val = jason(100, 6);