Browse Source

Addition of arguments object (#109)

* testing PR

* making a start to arguments object

* arguments

* finishing arguments for now
pull/91/head
Jason Williams 5 years ago committed by GitHub
parent
commit
821632972b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      benches/fib.rs
  2. 14
      src/lib/exec.rs
  3. 50
      src/lib/js/function.rs
  4. 6
      tests/js/test.js

2
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;

14
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

50
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>) -> 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::<f64>(return_val).unwrap(), 100.0);
}
}

6
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);

Loading…
Cancel
Save