| 
									
										
										
										
											2021-06-22 13:30:48 +02:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * Copyright (c) 2021, Andreas Kling <kling@serenityos.org> | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * SPDX-License-Identifier: BSD-2-Clause | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #pragma once
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-01 12:24:46 +02:00
										 |  |  | #include <LibJS/Runtime/DeclarativeEnvironment.h>
 | 
					
						
							| 
									
										
										
										
											2021-09-24 23:49:24 +02:00
										 |  |  | #include <LibJS/Runtime/ECMAScriptFunctionObject.h>
 | 
					
						
							| 
									
										
										
										
											2021-06-22 13:30:48 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | namespace JS { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-01 12:24:46 +02:00
										 |  |  | class FunctionEnvironment final : public DeclarativeEnvironment { | 
					
						
							|  |  |  |     JS_ENVIRONMENT(FunctionEnvironment, DeclarativeEnvironment); | 
					
						
							| 
									
										
										
										
											2021-06-22 13:30:48 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | public: | 
					
						
							|  |  |  |     enum class ThisBindingStatus : u8 { | 
					
						
							|  |  |  |         Lexical, | 
					
						
							|  |  |  |         Initialized, | 
					
						
							|  |  |  |         Uninitialized, | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-01 12:24:46 +02:00
										 |  |  |     FunctionEnvironment(Environment* parent_scope, HashMap<FlyString, Variable> variables); | 
					
						
							|  |  |  |     virtual ~FunctionEnvironment() override; | 
					
						
							| 
									
										
										
										
											2021-06-22 13:30:48 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     // [[ThisValue]]
 | 
					
						
							|  |  |  |     Value this_value() const { return m_this_value; } | 
					
						
							|  |  |  |     void set_this_value(Value value) { m_this_value = value; } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Not a standard operation.
 | 
					
						
							|  |  |  |     void replace_this_binding(Value this_value) { m_this_value = this_value; } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // [[ThisBindingStatus]]
 | 
					
						
							|  |  |  |     ThisBindingStatus this_binding_status() const { return m_this_binding_status; } | 
					
						
							|  |  |  |     void set_this_binding_status(ThisBindingStatus status) { m_this_binding_status = status; } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // [[FunctionObject]]
 | 
					
						
							| 
									
										
										
										
											2021-09-24 23:49:24 +02:00
										 |  |  |     ECMAScriptFunctionObject& function_object() { return *m_function_object; } | 
					
						
							|  |  |  |     ECMAScriptFunctionObject const& function_object() const { return *m_function_object; } | 
					
						
							|  |  |  |     void set_function_object(ECMAScriptFunctionObject& function) { m_function_object = &function; } | 
					
						
							| 
									
										
										
										
											2021-06-22 13:30:48 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     // [[NewTarget]]
 | 
					
						
							|  |  |  |     Value new_target() const { return m_new_target; } | 
					
						
							|  |  |  |     void set_new_target(Value new_target) { m_new_target = new_target; } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Abstract operations
 | 
					
						
							|  |  |  |     Value get_super_base() const; | 
					
						
							|  |  |  |     bool has_super_binding() const; | 
					
						
							|  |  |  |     virtual bool has_this_binding() const override; | 
					
						
							|  |  |  |     virtual Value get_this_binding(GlobalObject&) const override; | 
					
						
							|  |  |  |     Value bind_this_value(GlobalObject&, Value); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | private: | 
					
						
							| 
									
										
										
										
											2021-07-01 12:24:46 +02:00
										 |  |  |     virtual bool is_function_environment() const override { return true; } | 
					
						
							| 
									
										
										
										
											2021-06-22 13:30:48 +02:00
										 |  |  |     virtual void visit_edges(Visitor&) override; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Value m_this_value; | 
					
						
							|  |  |  |     ThisBindingStatus m_this_binding_status { ThisBindingStatus::Uninitialized }; | 
					
						
							| 
									
										
										
										
											2021-09-24 23:49:24 +02:00
										 |  |  |     ECMAScriptFunctionObject* m_function_object { nullptr }; | 
					
						
							| 
									
										
										
										
											2021-06-22 13:30:48 +02:00
										 |  |  |     Value m_new_target; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | template<> | 
					
						
							| 
									
										
										
										
											2021-07-01 12:24:46 +02:00
										 |  |  | inline bool Environment::fast_is<FunctionEnvironment>() const { return is_function_environment(); } | 
					
						
							| 
									
										
										
										
											2021-06-22 13:30:48 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | } |