From 8b32522ffa46d861eeb13069bd9c311e0df556d4 Mon Sep 17 00:00:00 2001 From: Jason Williams Date: Wed, 15 Apr 2020 19:21:10 +0100 Subject: [PATCH] implement this --- .../declarative_environment_record.rs | 4 +++ .../environment/environment_record_trait.rs | 3 ++ .../function_environment_record.rs | 30 +++++++++---------- .../environment/global_environment_record.rs | 8 ++--- boa/src/environment/lexical_environment.rs | 5 ++++ .../environment/object_environment_record.rs | 4 +++ boa/src/exec/mod.rs | 4 +++ 7 files changed, 39 insertions(+), 19 deletions(-) diff --git a/boa/src/environment/declarative_environment_record.rs b/boa/src/environment/declarative_environment_record.rs index 5b36143d8fb..f8ce882f971 100644 --- a/boa/src/environment/declarative_environment_record.rs +++ b/boa/src/environment/declarative_environment_record.rs @@ -149,6 +149,10 @@ impl EnvironmentRecordTrait for DeclarativeEnvironmentRecord { false } + fn get_this_binding(&self) -> Value { + Gc::new(ValueData::Undefined) + } + fn has_super_binding(&self) -> bool { false } diff --git a/boa/src/environment/environment_record_trait.rs b/boa/src/environment/environment_record_trait.rs index f2166289e1b..297ecb2215d 100644 --- a/boa/src/environment/environment_record_trait.rs +++ b/boa/src/environment/environment_record_trait.rs @@ -60,6 +60,9 @@ pub trait EnvironmentRecordTrait: Debug + Trace + Finalize { /// Return true if it does and false if it does not. fn has_this_binding(&self) -> bool; + /// Return the `this` binding from the environment + fn get_this_binding(&self) -> Value; + /// Determine if an Environment Record establishes a super method binding. /// Return true if it does and false if it does not. fn has_super_binding(&self) -> bool; diff --git a/boa/src/environment/function_environment_record.rs b/boa/src/environment/function_environment_record.rs index e7027372f6d..71dcd4faf6c 100644 --- a/boa/src/environment/function_environment_record.rs +++ b/boa/src/environment/function_environment_record.rs @@ -74,21 +74,6 @@ impl FunctionEnvironmentRecord { } } } - - pub fn get_this_binding(&self) -> Value { - match self.this_binding_status { - BindingStatus::Lexical => { - // TODO: change this when error handling comes into play - panic!("There is no this for a lexical function record"); - } - BindingStatus::Uninitialized => { - // TODO: change this when error handling comes into play - panic!("Reference Error: Unitialised binding for this function"); - } - - BindingStatus::Initialized => self.this_value.clone(), - } - } } impl EnvironmentRecordTrait for FunctionEnvironmentRecord { @@ -115,6 +100,21 @@ impl EnvironmentRecordTrait for FunctionEnvironmentRecord { ); } + fn get_this_binding(&self) -> Value { + match self.this_binding_status { + BindingStatus::Lexical => { + // TODO: change this when error handling comes into play + panic!("There is no this for a lexical function record"); + } + BindingStatus::Uninitialized => { + // TODO: change this when error handling comes into play + panic!("Reference Error: Unitialised binding for this function"); + } + + BindingStatus::Initialized => self.this_value.clone(), + } + } + fn create_immutable_binding(&mut self, name: String, strict: bool) -> bool { if self.env_rec.contains_key(&name) { // TODO: change this when error handling comes into play diff --git a/boa/src/environment/global_environment_record.rs b/boa/src/environment/global_environment_record.rs index 079c69a9293..7f79566c2e1 100644 --- a/boa/src/environment/global_environment_record.rs +++ b/boa/src/environment/global_environment_record.rs @@ -28,10 +28,6 @@ pub struct GlobalEnvironmentRecord { } impl GlobalEnvironmentRecord { - pub fn get_this_binding(&self) -> Value { - self.global_this_binding.clone() - } - pub fn has_var_declaration(&self, name: &str) -> bool { self.var_names.contains(name) } @@ -96,6 +92,10 @@ impl GlobalEnvironmentRecord { } impl EnvironmentRecordTrait for GlobalEnvironmentRecord { + fn get_this_binding(&self) -> Value { + self.global_this_binding.clone() + } + fn has_binding(&self, name: &str) -> bool { if self.declarative_record.has_binding(name) { return true; diff --git a/boa/src/environment/lexical_environment.rs b/boa/src/environment/lexical_environment.rs index 487820f4aaf..21b181bee2a 100644 --- a/boa/src/environment/lexical_environment.rs +++ b/boa/src/environment/lexical_environment.rs @@ -113,6 +113,11 @@ impl LexicalEnvironment { .get_global_object() } + pub fn get_this_binding(&self) -> Value { + let env = self.environment_stack.get(0).expect("").borrow(); + env.get_this_binding() + } + pub fn create_mutable_binding(&mut self, name: String, deletion: bool, scope: VariableScope) { match scope { VariableScope::Block => self diff --git a/boa/src/environment/object_environment_record.rs b/boa/src/environment/object_environment_record.rs index 43b9f8349ec..6c7f73ee307 100644 --- a/boa/src/environment/object_environment_record.rs +++ b/boa/src/environment/object_environment_record.rs @@ -87,6 +87,10 @@ impl EnvironmentRecordTrait for ObjectEnvironmentRecord { false } + fn get_this_binding(&self) -> Value { + Gc::new(ValueData::Undefined) + } + fn has_super_binding(&self) -> bool { false } diff --git a/boa/src/exec/mod.rs b/boa/src/exec/mod.rs index f5e4deb83aa..7725a8d2d59 100644 --- a/boa/src/exec/mod.rs +++ b/boa/src/exec/mod.rs @@ -659,6 +659,10 @@ impl Executor for Interpreter { // TODO: for now we can do nothing but return the value as-is self.run(node) } + Node::This => { + // Will either return `this` binding or undefined + Ok(self.realm.environment.get_this_binding()) + } ref i => unimplemented!("{}", i), } }