| 
									
										
										
										
											2021-06-22 13:30:48 +02:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * Copyright (c) 2021, Andreas Kling <kling@serenityos.org> | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * SPDX-License-Identifier: BSD-2-Clause | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <LibJS/Interpreter.h>
 | 
					
						
							| 
									
										
										
										
											2021-07-01 12:24:46 +02:00
										 |  |  | #include <LibJS/Runtime/FunctionEnvironment.h>
 | 
					
						
							| 
									
										
										
										
											2021-06-27 21:48:34 +02:00
										 |  |  | #include <LibJS/Runtime/FunctionObject.h>
 | 
					
						
							| 
									
										
										
										
											2021-06-22 13:30:48 +02:00
										 |  |  | #include <LibJS/Runtime/GlobalObject.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | namespace JS { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-01 12:24:46 +02:00
										 |  |  | FunctionEnvironment::FunctionEnvironment(Environment* parent_scope, HashMap<FlyString, Variable> variables) | 
					
						
							|  |  |  |     : DeclarativeEnvironment(variables, parent_scope) | 
					
						
							| 
									
										
										
										
											2021-06-22 13:30:48 +02:00
										 |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-01 12:24:46 +02:00
										 |  |  | FunctionEnvironment::~FunctionEnvironment() | 
					
						
							| 
									
										
										
										
											2021-06-22 13:30:48 +02:00
										 |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-01 12:24:46 +02:00
										 |  |  | void FunctionEnvironment::visit_edges(Visitor& visitor) | 
					
						
							| 
									
										
										
										
											2021-06-22 13:30:48 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     Base::visit_edges(visitor); | 
					
						
							|  |  |  |     visitor.visit(m_this_value); | 
					
						
							|  |  |  |     visitor.visit(m_new_target); | 
					
						
							|  |  |  |     visitor.visit(m_function_object); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // 9.1.1.3.5 GetSuperBase ( ), https://tc39.es/ecma262/#sec-getsuperbase
 | 
					
						
							| 
									
										
										
										
											2021-07-01 12:24:46 +02:00
										 |  |  | Value FunctionEnvironment::get_super_base() const | 
					
						
							| 
									
										
										
										
											2021-06-22 13:30:48 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     VERIFY(m_function_object); | 
					
						
							|  |  |  |     auto home_object = m_function_object->home_object(); | 
					
						
							| 
									
										
										
										
											2021-07-05 12:57:17 +01:00
										 |  |  |     if (!home_object) | 
					
						
							| 
									
										
										
										
											2021-06-22 13:30:48 +02:00
										 |  |  |         return js_undefined(); | 
					
						
							| 
									
										
										
										
											2021-07-05 12:57:17 +01:00
										 |  |  |     return home_object->internal_get_prototype_of(); | 
					
						
							| 
									
										
										
										
											2021-06-22 13:30:48 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // 9.1.1.3.2 HasThisBinding ( ), https://tc39.es/ecma262/#sec-function-environment-records-hasthisbinding
 | 
					
						
							| 
									
										
										
										
											2021-07-01 12:24:46 +02:00
										 |  |  | bool FunctionEnvironment::has_this_binding() const | 
					
						
							| 
									
										
										
										
											2021-06-22 13:30:48 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     if (this_binding_status() == ThisBindingStatus::Lexical) | 
					
						
							|  |  |  |         return false; | 
					
						
							|  |  |  |     return true; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // 9.1.1.3.3 HasSuperBinding ( ), https://tc39.es/ecma262/#sec-function-environment-records-hassuperbinding
 | 
					
						
							| 
									
										
										
										
											2021-07-01 12:24:46 +02:00
										 |  |  | bool FunctionEnvironment::has_super_binding() const | 
					
						
							| 
									
										
										
										
											2021-06-22 13:30:48 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     if (this_binding_status() == ThisBindingStatus::Lexical) | 
					
						
							|  |  |  |         return false; | 
					
						
							| 
									
										
										
										
											2021-07-05 12:57:17 +01:00
										 |  |  |     if (!function_object().home_object()) | 
					
						
							| 
									
										
										
										
											2021-06-22 13:30:48 +02:00
										 |  |  |         return false; | 
					
						
							|  |  |  |     return true; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // 9.1.1.3.4 GetThisBinding ( ), https://tc39.es/ecma262/#sec-function-environment-records-getthisbinding
 | 
					
						
							| 
									
										
										
										
											2021-07-01 12:24:46 +02:00
										 |  |  | Value FunctionEnvironment::get_this_binding(GlobalObject& global_object) const | 
					
						
							| 
									
										
										
										
											2021-06-22 13:30:48 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     VERIFY(has_this_binding()); | 
					
						
							|  |  |  |     if (this_binding_status() == ThisBindingStatus::Uninitialized) { | 
					
						
							|  |  |  |         vm().throw_exception<ReferenceError>(global_object, ErrorType::ThisHasNotBeenInitialized); | 
					
						
							|  |  |  |         return {}; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return m_this_value; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // 9.1.1.3.1 BindThisValue ( V ), https://tc39.es/ecma262/#sec-bindthisvalue
 | 
					
						
							| 
									
										
										
										
											2021-07-01 12:24:46 +02:00
										 |  |  | Value FunctionEnvironment::bind_this_value(GlobalObject& global_object, Value this_value) | 
					
						
							| 
									
										
										
										
											2021-06-22 13:30:48 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2021-06-25 19:36:37 +02:00
										 |  |  |     VERIFY(this_binding_status() != ThisBindingStatus::Lexical); | 
					
						
							| 
									
										
										
										
											2021-06-22 13:30:48 +02:00
										 |  |  |     if (this_binding_status() == ThisBindingStatus::Initialized) { | 
					
						
							|  |  |  |         vm().throw_exception<ReferenceError>(global_object, ErrorType::ThisIsAlreadyInitialized); | 
					
						
							|  |  |  |         return {}; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     m_this_value = this_value; | 
					
						
							|  |  |  |     m_this_binding_status = ThisBindingStatus::Initialized; | 
					
						
							|  |  |  |     return this_value; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } |