| 
									
										
										
										
											2021-06-03 10:46:30 +02:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * Copyright (c) 2021, Andreas Kling <kling@serenityos.org> | 
					
						
							| 
									
										
										
										
											2021-06-07 21:13:37 +01:00
										 |  |  |  * Copyright (c) 2021, Linus Groh <linusg@serenityos.org> | 
					
						
							| 
									
										
										
										
											2021-06-09 18:18:56 +02:00
										 |  |  |  * Copyright (c) 2021, Gunnar Beutner <gbeutner@serenityos.org> | 
					
						
							| 
									
										
										
										
											2021-06-03 10:46:30 +02:00
										 |  |  |  * | 
					
						
							|  |  |  |  * SPDX-License-Identifier: BSD-2-Clause | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-13 15:30:32 -07:00
										 |  |  | #include <AK/HashTable.h>
 | 
					
						
							| 
									
										
										
										
											2021-06-03 10:46:30 +02:00
										 |  |  | #include <LibJS/Bytecode/Interpreter.h>
 | 
					
						
							|  |  |  | #include <LibJS/Bytecode/Op.h>
 | 
					
						
							| 
									
										
										
										
											2021-06-08 23:06:52 +02:00
										 |  |  | #include <LibJS/Runtime/Array.h>
 | 
					
						
							| 
									
										
										
										
											2021-06-08 07:59:25 +02:00
										 |  |  | #include <LibJS/Runtime/BigInt.h>
 | 
					
						
							| 
									
										
										
										
											2021-07-01 12:24:46 +02:00
										 |  |  | #include <LibJS/Runtime/DeclarativeEnvironment.h>
 | 
					
						
							| 
									
										
										
										
											2021-09-24 22:40:38 +02:00
										 |  |  | #include <LibJS/Runtime/ECMAScriptFunctionObject.h>
 | 
					
						
							| 
									
										
										
										
											2021-07-01 12:24:46 +02:00
										 |  |  | #include <LibJS/Runtime/Environment.h>
 | 
					
						
							| 
									
										
										
										
											2021-06-03 18:26:32 +02:00
										 |  |  | #include <LibJS/Runtime/GlobalObject.h>
 | 
					
						
							| 
									
										
										
										
											2021-06-13 13:40:48 -07:00
										 |  |  | #include <LibJS/Runtime/IteratorOperations.h>
 | 
					
						
							| 
									
										
										
										
											2021-06-19 17:17:40 -07:00
										 |  |  | #include <LibJS/Runtime/RegExpObject.h>
 | 
					
						
							| 
									
										
										
										
											2021-06-03 10:46:30 +02:00
										 |  |  | #include <LibJS/Runtime/Value.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-07 15:12:43 +02:00
										 |  |  | namespace JS::Bytecode { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-09 10:02:01 +02:00
										 |  |  | String Instruction::to_string(Bytecode::Executable const& executable) const | 
					
						
							| 
									
										
										
										
											2021-06-07 15:12:43 +02:00
										 |  |  | { | 
					
						
							|  |  |  | #define __BYTECODE_OP(op)       \
 | 
					
						
							|  |  |  |     case Instruction::Type::op: \ | 
					
						
							| 
									
										
										
										
											2021-06-15 18:08:12 +04:30
										 |  |  |         return static_cast<Bytecode::Op::op const&>(*this).to_string_impl(executable); | 
					
						
							| 
									
										
										
										
											2021-06-07 15:12:43 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     switch (type()) { | 
					
						
							|  |  |  |         ENUMERATE_BYTECODE_OPS(__BYTECODE_OP) | 
					
						
							|  |  |  |     default: | 
					
						
							|  |  |  |         VERIFY_NOT_REACHED(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #undef __BYTECODE_OP
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-03 10:46:30 +02:00
										 |  |  | namespace JS::Bytecode::Op { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-15 18:08:12 +04:30
										 |  |  | void Load::execute_impl(Bytecode::Interpreter& interpreter) const | 
					
						
							| 
									
										
										
										
											2021-06-03 10:46:30 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2021-06-07 20:58:36 -07:00
										 |  |  |     interpreter.accumulator() = interpreter.reg(m_src); | 
					
						
							| 
									
										
										
										
											2021-06-03 10:46:30 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-15 18:08:12 +04:30
										 |  |  | void LoadImmediate::execute_impl(Bytecode::Interpreter& interpreter) const | 
					
						
							| 
									
										
										
										
											2021-06-07 22:05:09 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2021-06-07 20:58:36 -07:00
										 |  |  |     interpreter.accumulator() = m_value; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-15 18:08:12 +04:30
										 |  |  | void Store::execute_impl(Bytecode::Interpreter& interpreter) const | 
					
						
							| 
									
										
										
										
											2021-06-07 20:58:36 -07:00
										 |  |  | { | 
					
						
							|  |  |  |     interpreter.reg(m_dst) = interpreter.accumulator(); | 
					
						
							| 
									
										
										
										
											2021-06-07 22:05:09 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-07 23:08:35 +02:00
										 |  |  | static Value abstract_inequals(GlobalObject& global_object, Value src1, Value src2) | 
					
						
							| 
									
										
										
										
											2021-06-03 10:46:30 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2021-09-23 23:46:36 +02:00
										 |  |  |     return Value(!is_loosely_equal(global_object, src1, src2)); | 
					
						
							| 
									
										
										
										
											2021-06-03 10:46:30 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-07 23:08:35 +02:00
										 |  |  | static Value abstract_equals(GlobalObject& global_object, Value src1, Value src2) | 
					
						
							| 
									
										
										
										
											2021-06-03 18:32:33 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2021-09-23 23:46:36 +02:00
										 |  |  |     return Value(is_loosely_equal(global_object, src1, src2)); | 
					
						
							| 
									
										
										
										
											2021-06-03 18:32:33 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-07 23:08:35 +02:00
										 |  |  | static Value typed_inequals(GlobalObject&, Value src1, Value src2) | 
					
						
							| 
									
										
										
										
											2021-06-07 19:17:20 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2021-09-23 23:43:28 +02:00
										 |  |  |     return Value(!is_strictly_equal(src1, src2)); | 
					
						
							| 
									
										
										
										
											2021-06-07 19:17:20 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-07 23:08:35 +02:00
										 |  |  | static Value typed_equals(GlobalObject&, Value src1, Value src2) | 
					
						
							| 
									
										
										
										
											2021-06-07 19:17:20 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2021-09-23 23:43:28 +02:00
										 |  |  |     return Value(is_strictly_equal(src1, src2)); | 
					
						
							| 
									
										
										
										
											2021-06-07 19:17:20 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-07 20:58:36 -07:00
										 |  |  | #define JS_DEFINE_COMMON_BINARY_OP(OpTitleCase, op_snake_case)                            \
 | 
					
						
							| 
									
										
										
										
											2021-06-15 18:08:12 +04:30
										 |  |  |     void OpTitleCase::execute_impl(Bytecode::Interpreter& interpreter) const              \ | 
					
						
							| 
									
										
										
										
											2021-06-07 20:58:36 -07:00
										 |  |  |     {                                                                                     \ | 
					
						
							|  |  |  |         auto lhs = interpreter.reg(m_lhs_reg);                                            \ | 
					
						
							|  |  |  |         auto rhs = interpreter.accumulator();                                             \ | 
					
						
							|  |  |  |         interpreter.accumulator() = op_snake_case(interpreter.global_object(), lhs, rhs); \ | 
					
						
							|  |  |  |     }                                                                                     \ | 
					
						
							| 
									
										
										
										
											2021-06-15 18:08:12 +04:30
										 |  |  |     String OpTitleCase::to_string_impl(Bytecode::Executable const&) const                 \ | 
					
						
							| 
									
										
										
										
											2021-06-07 20:58:36 -07:00
										 |  |  |     {                                                                                     \ | 
					
						
							| 
									
										
										
										
											2021-06-09 11:06:11 +02:00
										 |  |  |         return String::formatted(#OpTitleCase " {}", m_lhs_reg);                          \ | 
					
						
							| 
									
										
										
										
											2021-06-07 23:08:35 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-06-07 21:13:37 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-07 23:08:35 +02:00
										 |  |  | JS_ENUMERATE_COMMON_BINARY_OPS(JS_DEFINE_COMMON_BINARY_OP) | 
					
						
							| 
									
										
										
										
											2021-06-07 21:18:19 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-07 23:08:35 +02:00
										 |  |  | static Value not_(GlobalObject&, Value value) | 
					
						
							| 
									
										
										
										
											2021-06-07 21:13:37 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2021-06-07 23:08:35 +02:00
										 |  |  |     return Value(!value.to_boolean()); | 
					
						
							| 
									
										
										
										
											2021-06-07 21:13:37 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-07 23:08:35 +02:00
										 |  |  | static Value typeof_(GlobalObject& global_object, Value value) | 
					
						
							| 
									
										
										
										
											2021-06-07 19:53:47 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2021-06-07 23:08:35 +02:00
										 |  |  |     return js_string(global_object.vm(), value.typeof()); | 
					
						
							| 
									
										
										
										
											2021-06-07 19:53:47 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-07 20:58:36 -07:00
										 |  |  | #define JS_DEFINE_COMMON_UNARY_OP(OpTitleCase, op_snake_case)                                              \
 | 
					
						
							| 
									
										
										
										
											2021-06-15 18:08:12 +04:30
										 |  |  |     void OpTitleCase::execute_impl(Bytecode::Interpreter& interpreter) const                               \ | 
					
						
							| 
									
										
										
										
											2021-06-07 20:58:36 -07:00
										 |  |  |     {                                                                                                      \ | 
					
						
							|  |  |  |         interpreter.accumulator() = op_snake_case(interpreter.global_object(), interpreter.accumulator()); \ | 
					
						
							|  |  |  |     }                                                                                                      \ | 
					
						
							| 
									
										
										
										
											2021-06-15 18:08:12 +04:30
										 |  |  |     String OpTitleCase::to_string_impl(Bytecode::Executable const&) const                                  \ | 
					
						
							| 
									
										
										
										
											2021-06-07 20:58:36 -07:00
										 |  |  |     {                                                                                                      \ | 
					
						
							|  |  |  |         return #OpTitleCase;                                                                               \ | 
					
						
							| 
									
										
										
										
											2021-06-07 23:08:35 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-06-07 19:53:47 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-07 23:08:35 +02:00
										 |  |  | JS_ENUMERATE_COMMON_UNARY_OPS(JS_DEFINE_COMMON_UNARY_OP) | 
					
						
							| 
									
										
										
										
											2021-06-07 19:53:47 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-15 18:08:12 +04:30
										 |  |  | void NewBigInt::execute_impl(Bytecode::Interpreter& interpreter) const | 
					
						
							| 
									
										
										
										
											2021-06-08 07:59:25 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2021-06-07 20:58:36 -07:00
										 |  |  |     interpreter.accumulator() = js_bigint(interpreter.vm().heap(), m_bigint); | 
					
						
							| 
									
										
										
										
											2021-06-08 07:59:25 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-15 18:08:12 +04:30
										 |  |  | void NewArray::execute_impl(Bytecode::Interpreter& interpreter) const | 
					
						
							| 
									
										
										
										
											2021-06-08 23:06:52 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     Vector<Value> elements; | 
					
						
							|  |  |  |     elements.ensure_capacity(m_element_count); | 
					
						
							|  |  |  |     for (size_t i = 0; i < m_element_count; i++) | 
					
						
							|  |  |  |         elements.append(interpreter.reg(m_elements[i])); | 
					
						
							|  |  |  |     interpreter.accumulator() = Array::create_from(interpreter.global_object(), elements); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-13 14:06:26 -07:00
										 |  |  | void IteratorToArray::execute_impl(Bytecode::Interpreter& interpreter) const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     auto& global_object = interpreter.global_object(); | 
					
						
							|  |  |  |     auto& vm = interpreter.vm(); | 
					
						
							| 
									
										
										
										
											2021-10-12 19:24:57 +01:00
										 |  |  |     auto iterator_or_error = interpreter.accumulator().to_object(global_object); | 
					
						
							|  |  |  |     if (iterator_or_error.is_error()) | 
					
						
							| 
									
										
										
										
											2021-06-13 14:06:26 -07:00
										 |  |  |         return; | 
					
						
							| 
									
										
										
										
											2021-10-12 19:24:57 +01:00
										 |  |  |     auto* iterator = iterator_or_error.release_value(); | 
					
						
							| 
									
										
										
										
											2021-06-13 14:06:26 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-04 01:36:44 +03:00
										 |  |  |     auto array = Array::create(global_object, 0); | 
					
						
							| 
									
										
										
										
											2021-06-13 14:06:26 -07:00
										 |  |  |     size_t index = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     while (true) { | 
					
						
							|  |  |  |         auto iterator_result = iterator_next(*iterator); | 
					
						
							|  |  |  |         if (!iterator_result) | 
					
						
							|  |  |  |             return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         auto complete = iterator_complete(global_object, *iterator_result); | 
					
						
							|  |  |  |         if (vm.exception()) | 
					
						
							|  |  |  |             return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (complete) { | 
					
						
							|  |  |  |             interpreter.accumulator() = array; | 
					
						
							|  |  |  |             return; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         auto value = iterator_value(global_object, *iterator_result); | 
					
						
							|  |  |  |         if (vm.exception()) | 
					
						
							|  |  |  |             return; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-03 01:18:46 +01:00
										 |  |  |         MUST(array->create_data_property_or_throw(index, value)); | 
					
						
							| 
									
										
										
										
											2021-06-13 14:06:26 -07:00
										 |  |  |         index++; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-15 18:08:12 +04:30
										 |  |  | void NewString::execute_impl(Bytecode::Interpreter& interpreter) const | 
					
						
							| 
									
										
										
										
											2021-06-03 18:26:32 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2021-06-09 10:02:01 +02:00
										 |  |  |     interpreter.accumulator() = js_string(interpreter.vm(), interpreter.current_executable().get_string(m_string)); | 
					
						
							| 
									
										
										
										
											2021-06-03 18:26:32 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-15 18:08:12 +04:30
										 |  |  | void NewObject::execute_impl(Bytecode::Interpreter& interpreter) const | 
					
						
							| 
									
										
										
										
											2021-06-04 20:30:23 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2021-06-16 20:52:30 +01:00
										 |  |  |     interpreter.accumulator() = Object::create(interpreter.global_object(), interpreter.global_object().object_prototype()); | 
					
						
							| 
									
										
										
										
											2021-06-07 20:58:36 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-19 17:17:40 -07:00
										 |  |  | void NewRegExp::execute_impl(Bytecode::Interpreter& interpreter) const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     auto source = interpreter.current_executable().get_string(m_source_index); | 
					
						
							|  |  |  |     auto flags = interpreter.current_executable().get_string(m_flags_index); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-22 08:04:31 -04:00
										 |  |  |     interpreter.accumulator() = regexp_create(interpreter.global_object(), js_string(interpreter.vm(), source), js_string(interpreter.vm(), flags)); | 
					
						
							| 
									
										
										
										
											2021-06-19 17:17:40 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-13 15:30:32 -07:00
										 |  |  | void CopyObjectExcludingProperties::execute_impl(Bytecode::Interpreter& interpreter) const | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2021-10-12 19:24:57 +01:00
										 |  |  |     auto from_object_or_error = interpreter.reg(m_from_object).to_object(interpreter.global_object()); | 
					
						
							|  |  |  |     if (from_object_or_error.is_error()) | 
					
						
							| 
									
										
										
										
											2021-06-13 15:30:32 -07:00
										 |  |  |         return; | 
					
						
							| 
									
										
										
										
											2021-10-12 19:24:57 +01:00
										 |  |  |     auto* from_object = from_object_or_error.release_value(); | 
					
						
							| 
									
										
										
										
											2021-06-13 15:30:32 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     auto* to_object = Object::create(interpreter.global_object(), interpreter.global_object().object_prototype()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     HashTable<Value, ValueTraits> excluded_names; | 
					
						
							|  |  |  |     for (size_t i = 0; i < m_excluded_names_count; ++i) { | 
					
						
							|  |  |  |         excluded_names.set(interpreter.reg(m_excluded_names[i])); | 
					
						
							|  |  |  |         if (interpreter.vm().exception()) | 
					
						
							|  |  |  |             return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-29 18:58:03 +01:00
										 |  |  |     auto own_keys_or_error = from_object->internal_own_property_keys(); | 
					
						
							|  |  |  |     if (own_keys_or_error.is_error()) | 
					
						
							| 
									
										
											  
											
												LibJS: Rewrite most of Object for spec compliance :^)
This is a huge patch, I know. In hindsight this perhaps could've been
done slightly more incremental, but I started and then fixed everything
until it worked, and here we are. I tried splitting of some completely
unrelated changes into separate commits, however. Anyway.
This is a rewrite of most of Object, and by extension large parts of
Array, Proxy, Reflect, String, TypedArray, and some other things.
What we already had worked fine for about 90% of things, but getting the
last 10% right proved to be increasingly difficult with the current code
that sort of grew organically and is only very loosely based on the
spec - this became especially obvious when we started fixing a large
number of test262 failures.
Key changes include:
- 1:1 matching function names and parameters of all object-related
  functions, to avoid ambiguity. Previously we had things like put(),
  which the spec doesn't have - as a result it wasn't always clear which
  need to be used.
- Better separation between object abstract operations and internal
  methods - the former are always the same, the latter can be overridden
  (and are therefore virtual). The internal methods (i.e. [[Foo]] in the
  spec) are now prefixed with 'internal_' for clarity - again, it was
  previously not always clear which AO a certain method represents,
  get() could've been both Get and [[Get]] (I don't know which one it
  was closer to right now).
  Note that some of the old names have been kept until all code relying
  on them is updated, but they are now simple wrappers around the
  closest matching standard abstract operation.
- Simplifications of the storage layer: functions that write values to
  storage are now prefixed with 'storage_' to make their purpose clear,
  and as they are not part of the spec they should not contain any steps
  specified by it. Much functionality is now covered by the layers above
  it and was removed (e.g. handling of accessors, attribute checks).
- PropertyAttributes has been greatly simplified, and is being replaced
  by PropertyDescriptor - a concept similar to the current
  implementation, but more aligned with the actual spec. See the commit
  message of the previous commit where it was introduced for details.
- As a bonus, and since I had to look at the spec a whole lot anyway, I
  introduced more inline comments with the exact steps from the spec -
  this makes it super easy to verify correctness.
- East-const all the things.
As a result of all of this, things are much more correct but a bit
slower now. Retaining speed wasn't a consideration at all, I have done
no profiling of the new code - there might be low hanging fruits, which
we can then harvest separately.
Special thanks to Idan for helping me with this by tracking down bugs,
updating everything outside of LibJS to work with these changes (LibWeb,
Spreadsheet, HackStudio), as well as providing countless patches to fix
regressions I introduced - there still are very few (we got it down to
5), but we also get many new passing test262 tests in return. :^)
Co-authored-by: Idan Horowitz <idan.horowitz@gmail.com>
											
										 
											2021-07-04 18:14:16 +01:00
										 |  |  |         return; | 
					
						
							| 
									
										
										
										
											2021-09-29 18:58:03 +01:00
										 |  |  |     auto own_keys = own_keys_or_error.release_value(); | 
					
						
							| 
									
										
										
										
											2021-06-13 15:30:32 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     for (auto& key : own_keys) { | 
					
						
							|  |  |  |         if (!excluded_names.contains(key)) { | 
					
						
							| 
									
										
										
										
											2021-10-16 22:20:23 +03:00
										 |  |  |             auto property_name_or_error = key.to_property_key(interpreter.global_object()); | 
					
						
							|  |  |  |             if (property_name_or_error.is_error()) | 
					
						
							|  |  |  |                 return; | 
					
						
							|  |  |  |             PropertyName property_name = property_name_or_error.release_value(); | 
					
						
							| 
									
										
										
										
											2021-10-02 23:52:27 +01:00
										 |  |  |             auto property_value_or_error = from_object->get(property_name); | 
					
						
							|  |  |  |             if (property_value_or_error.is_error()) | 
					
						
							| 
									
										
										
										
											2021-06-13 15:30:32 -07:00
										 |  |  |                 return; | 
					
						
							| 
									
										
										
										
											2021-10-02 23:52:27 +01:00
										 |  |  |             auto property_value = property_value_or_error.release_value(); | 
					
						
							| 
									
										
										
										
											2021-07-06 02:15:08 +03:00
										 |  |  |             to_object->define_direct_property(property_name, property_value, JS::default_attributes); | 
					
						
							| 
									
										
										
										
											2021-06-13 15:30:32 -07:00
										 |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     interpreter.accumulator() = to_object; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-15 18:08:12 +04:30
										 |  |  | void ConcatString::execute_impl(Bytecode::Interpreter& interpreter) const | 
					
						
							| 
									
										
										
										
											2021-06-07 20:58:36 -07:00
										 |  |  | { | 
					
						
							|  |  |  |     interpreter.reg(m_lhs) = add(interpreter.global_object(), interpreter.reg(m_lhs), interpreter.accumulator()); | 
					
						
							| 
									
										
										
										
											2021-06-04 20:30:23 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-15 18:08:12 +04:30
										 |  |  | void GetVariable::execute_impl(Bytecode::Interpreter& interpreter) const | 
					
						
							| 
									
										
										
										
											2021-06-03 18:26:32 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2021-09-22 12:44:56 +02:00
										 |  |  |     auto& vm = interpreter.vm(); | 
					
						
							|  |  |  |     auto reference = vm.resolve_binding(interpreter.current_executable().get_string(m_identifier)); | 
					
						
							|  |  |  |     if (vm.exception()) | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     interpreter.accumulator() = reference.get_value(interpreter.global_object()); | 
					
						
							| 
									
										
										
										
											2021-06-03 18:26:32 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-15 18:08:12 +04:30
										 |  |  | void SetVariable::execute_impl(Bytecode::Interpreter& interpreter) const | 
					
						
							| 
									
										
										
										
											2021-06-03 18:26:32 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2021-09-22 12:44:56 +02:00
										 |  |  |     auto& vm = interpreter.vm(); | 
					
						
							|  |  |  |     auto reference = vm.resolve_binding(interpreter.current_executable().get_string(m_identifier)); | 
					
						
							|  |  |  |     if (vm.exception()) | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     reference.put_value(interpreter.global_object(), interpreter.accumulator()); | 
					
						
							| 
									
										
										
										
											2021-06-03 18:26:32 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-15 18:08:12 +04:30
										 |  |  | void GetById::execute_impl(Bytecode::Interpreter& interpreter) const | 
					
						
							| 
									
										
										
										
											2021-06-04 21:03:53 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2021-10-12 19:24:57 +01:00
										 |  |  |     auto object_or_error = interpreter.accumulator().to_object(interpreter.global_object()); | 
					
						
							|  |  |  |     if (object_or_error.is_error()) | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     auto* object = object_or_error.release_value(); | 
					
						
							|  |  |  |     auto value_or_error = object->get(interpreter.current_executable().get_string(m_property)); | 
					
						
							|  |  |  |     if (value_or_error.is_error()) | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     interpreter.accumulator() = value_or_error.release_value(); | 
					
						
							| 
									
										
										
										
											2021-06-04 21:03:53 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-15 18:08:12 +04:30
										 |  |  | void PutById::execute_impl(Bytecode::Interpreter& interpreter) const | 
					
						
							| 
									
										
										
										
											2021-06-04 20:47:07 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2021-10-12 19:24:57 +01:00
										 |  |  |     auto object_or_error = interpreter.reg(m_base).to_object(interpreter.global_object()); | 
					
						
							|  |  |  |     if (object_or_error.is_error()) | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     auto* object = object_or_error.release_value(); | 
					
						
							|  |  |  |     MUST(object->set(interpreter.current_executable().get_string(m_property), interpreter.accumulator(), Object::ShouldThrowExceptions::Yes)); | 
					
						
							| 
									
										
										
										
											2021-06-04 20:47:07 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-15 18:08:12 +04:30
										 |  |  | void Jump::execute_impl(Bytecode::Interpreter& interpreter) const | 
					
						
							| 
									
										
										
										
											2021-06-04 12:07:38 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2021-06-09 06:49:58 +04:30
										 |  |  |     interpreter.jump(*m_true_target); | 
					
						
							| 
									
										
										
										
											2021-06-04 12:07:38 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-13 20:40:20 +04:30
										 |  |  | void Jump::replace_references_impl(BasicBlock const& from, BasicBlock const& to) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (m_true_target.has_value() && &m_true_target->block() == &from) | 
					
						
							|  |  |  |         m_true_target = Label { to }; | 
					
						
							|  |  |  |     if (m_false_target.has_value() && &m_false_target->block() == &from) | 
					
						
							|  |  |  |         m_false_target = Label { to }; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-15 18:08:12 +04:30
										 |  |  | void JumpConditional::execute_impl(Bytecode::Interpreter& interpreter) const | 
					
						
							| 
									
										
										
										
											2021-06-04 12:07:38 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2021-06-09 06:49:58 +04:30
										 |  |  |     VERIFY(m_true_target.has_value()); | 
					
						
							|  |  |  |     VERIFY(m_false_target.has_value()); | 
					
						
							| 
									
										
										
										
											2021-06-07 20:58:36 -07:00
										 |  |  |     auto result = interpreter.accumulator(); | 
					
						
							| 
									
										
										
										
											2021-06-07 22:53:33 +02:00
										 |  |  |     if (result.to_boolean()) | 
					
						
							| 
									
										
										
										
											2021-06-09 06:49:58 +04:30
										 |  |  |         interpreter.jump(m_true_target.value()); | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |         interpreter.jump(m_false_target.value()); | 
					
						
							| 
									
										
										
										
											2021-06-04 12:20:44 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-15 18:08:12 +04:30
										 |  |  | void JumpNullish::execute_impl(Bytecode::Interpreter& interpreter) const | 
					
						
							| 
									
										
										
										
											2021-06-08 02:18:47 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2021-06-09 06:49:58 +04:30
										 |  |  |     VERIFY(m_true_target.has_value()); | 
					
						
							|  |  |  |     VERIFY(m_false_target.has_value()); | 
					
						
							| 
									
										
										
										
											2021-06-07 20:58:36 -07:00
										 |  |  |     auto result = interpreter.accumulator(); | 
					
						
							| 
									
										
										
										
											2021-06-09 06:49:58 +04:30
										 |  |  |     if (result.is_nullish()) | 
					
						
							|  |  |  |         interpreter.jump(m_true_target.value()); | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |         interpreter.jump(m_false_target.value()); | 
					
						
							| 
									
										
										
										
											2021-06-08 02:18:47 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-13 12:24:40 -07:00
										 |  |  | void JumpUndefined::execute_impl(Bytecode::Interpreter& interpreter) const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     VERIFY(m_true_target.has_value()); | 
					
						
							|  |  |  |     VERIFY(m_false_target.has_value()); | 
					
						
							|  |  |  |     auto result = interpreter.accumulator(); | 
					
						
							|  |  |  |     if (result.is_undefined()) | 
					
						
							|  |  |  |         interpreter.jump(m_true_target.value()); | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |         interpreter.jump(m_false_target.value()); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-15 18:08:12 +04:30
										 |  |  | void Call::execute_impl(Bytecode::Interpreter& interpreter) const | 
					
						
							| 
									
										
										
										
											2021-06-05 15:15:30 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     auto callee = interpreter.reg(m_callee); | 
					
						
							|  |  |  |     if (!callee.is_function()) { | 
					
						
							|  |  |  |         TODO(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     auto& function = callee.as_function(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     auto this_value = interpreter.reg(m_this_value); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Value return_value; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-10 23:01:49 +02:00
										 |  |  |     if (m_argument_count == 0 && m_type == CallType::Call) { | 
					
						
							| 
									
										
										
										
											2021-09-23 20:56:28 +03:00
										 |  |  |         auto return_value_or_error = interpreter.vm().call(function, this_value); | 
					
						
							|  |  |  |         if (!return_value_or_error.is_error()) | 
					
						
							|  |  |  |             return_value = return_value_or_error.release_value(); | 
					
						
							| 
									
										
										
										
											2021-06-05 15:15:30 +02:00
										 |  |  |     } else { | 
					
						
							|  |  |  |         MarkedValueList argument_values { interpreter.vm().heap() }; | 
					
						
							| 
									
										
										
										
											2021-06-07 15:12:43 +02:00
										 |  |  |         for (size_t i = 0; i < m_argument_count; ++i) { | 
					
						
							|  |  |  |             argument_values.append(interpreter.reg(m_arguments[i])); | 
					
						
							| 
									
										
										
										
											2021-06-05 15:15:30 +02:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2021-09-23 20:56:28 +03:00
										 |  |  |         if (m_type == CallType::Call) { | 
					
						
							|  |  |  |             auto return_value_or_error = interpreter.vm().call(function, this_value, move(argument_values)); | 
					
						
							|  |  |  |             if (!return_value_or_error.is_error()) | 
					
						
							|  |  |  |                 return_value = return_value_or_error.release_value(); | 
					
						
							|  |  |  |         } else { | 
					
						
							| 
									
										
										
										
											2021-06-10 23:17:29 +02:00
										 |  |  |             return_value = interpreter.vm().construct(function, function, move(argument_values)); | 
					
						
							| 
									
										
										
										
											2021-09-23 20:56:28 +03:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2021-06-05 15:15:30 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-07 20:58:36 -07:00
										 |  |  |     interpreter.accumulator() = return_value; | 
					
						
							| 
									
										
										
										
											2021-06-05 15:15:30 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-15 18:08:12 +04:30
										 |  |  | void NewFunction::execute_impl(Bytecode::Interpreter& interpreter) const | 
					
						
							| 
									
										
										
										
											2021-06-05 15:14:09 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     auto& vm = interpreter.vm(); | 
					
						
							| 
									
										
											  
											
												LibJS: Add an optimization to avoid needless arguments object creation
This gives FunctionNode a "might need arguments object" boolean flag and
sets it based on the simplest possible heuristic for this: if we
encounter an identifier called "arguments" or "eval" up to the next
(nested) function declaration or expression, we won't need an arguments
object. Otherwise, we *might* need one - the final decision is made in
the FunctionDeclarationInstantiation AO.
Now, this is obviously not perfect. Even if you avoid eval, something
like `foo.arguments` will still trigger a false positive - but it's a
start and already massively cuts down on needlessly allocated objects,
especially in real-world code that is often minified, and so a full
"arguments" identifier will be an actual arguments object more often
than not.
To illustrate the actual impact of this change, here's the number of
allocated arguments objects during a full test-js run:
Before:
- Unmapped arguments objects: 78765
- Mapped arguments objects: 2455
After:
- Unmapped arguments objects: 18
- Mapped arguments objects: 37
This results in a ~5% speedup of test-js on my Linux host machine, and
about 3.5% on i686 Serenity in QEMU (warm runs, average of 5).
The following microbenchmark (calling an empty function 1M times) runs
25% faster on Linux and 45% on Serenity:
    function foo() {}
    for (var i = 0; i < 1_000_000; ++i)
        foo();
test262 reports no changes in either direction, apart from a speedup :^)
											
										 
											2021-10-05 08:44:58 +01:00
										 |  |  |     interpreter.accumulator() = ECMAScriptFunctionObject::create(interpreter.global_object(), m_function_node.name(), m_function_node.body(), m_function_node.parameters(), m_function_node.function_length(), vm.lexical_environment(), m_function_node.kind(), m_function_node.is_strict_mode(), m_function_node.might_need_arguments_object(), m_function_node.is_arrow_function()); | 
					
						
							| 
									
										
										
										
											2021-06-05 15:14:09 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-15 18:08:12 +04:30
										 |  |  | void Return::execute_impl(Bytecode::Interpreter& interpreter) const | 
					
						
							| 
									
										
										
										
											2021-06-05 15:53:36 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2021-06-07 20:58:36 -07:00
										 |  |  |     interpreter.do_return(interpreter.accumulator().value_or(js_undefined())); | 
					
						
							| 
									
										
										
										
											2021-06-05 15:53:36 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-15 18:08:12 +04:30
										 |  |  | void Increment::execute_impl(Bytecode::Interpreter& interpreter) const | 
					
						
							| 
									
										
										
										
											2021-06-09 11:40:38 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2021-10-16 21:42:32 +03:00
										 |  |  |     auto old_value_or_error = interpreter.accumulator().to_numeric(interpreter.global_object()); | 
					
						
							|  |  |  |     if (old_value_or_error.is_error()) | 
					
						
							| 
									
										
										
										
											2021-06-09 11:40:38 +02:00
										 |  |  |         return; | 
					
						
							| 
									
										
										
										
											2021-10-16 21:42:32 +03:00
										 |  |  |     auto old_value = old_value_or_error.release_value(); | 
					
						
							| 
									
										
										
										
											2021-06-09 11:40:38 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if (old_value.is_number()) | 
					
						
							|  |  |  |         interpreter.accumulator() = Value(old_value.as_double() + 1); | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |         interpreter.accumulator() = js_bigint(interpreter.vm().heap(), old_value.as_bigint().big_integer().plus(Crypto::SignedBigInteger { 1 })); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-15 18:08:12 +04:30
										 |  |  | void Decrement::execute_impl(Bytecode::Interpreter& interpreter) const | 
					
						
							| 
									
										
										
										
											2021-06-09 11:40:38 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2021-10-16 21:42:32 +03:00
										 |  |  |     auto old_value_or_error = interpreter.accumulator().to_numeric(interpreter.global_object()); | 
					
						
							|  |  |  |     if (old_value_or_error.is_error()) | 
					
						
							| 
									
										
										
										
											2021-06-09 11:40:38 +02:00
										 |  |  |         return; | 
					
						
							| 
									
										
										
										
											2021-10-16 21:42:32 +03:00
										 |  |  |     auto old_value = old_value_or_error.release_value(); | 
					
						
							| 
									
										
										
										
											2021-06-09 11:40:38 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if (old_value.is_number()) | 
					
						
							|  |  |  |         interpreter.accumulator() = Value(old_value.as_double() - 1); | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |         interpreter.accumulator() = js_bigint(interpreter.vm().heap(), old_value.as_bigint().big_integer().minus(Crypto::SignedBigInteger { 1 })); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-15 18:08:12 +04:30
										 |  |  | void Throw::execute_impl(Bytecode::Interpreter& interpreter) const | 
					
						
							| 
									
										
										
										
											2021-06-09 18:18:56 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     interpreter.vm().throw_exception(interpreter.global_object(), interpreter.accumulator()); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-15 18:08:12 +04:30
										 |  |  | void EnterUnwindContext::execute_impl(Bytecode::Interpreter& interpreter) const | 
					
						
							| 
									
										
										
										
											2021-06-10 15:04:38 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     interpreter.enter_unwind_context(m_handler_target, m_finalizer_target); | 
					
						
							| 
									
										
										
										
											2021-06-13 20:39:40 +04:30
										 |  |  |     interpreter.jump(m_entry_point); | 
					
						
							| 
									
										
										
										
											2021-06-10 15:04:38 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-13 20:40:20 +04:30
										 |  |  | void EnterUnwindContext::replace_references_impl(BasicBlock const& from, BasicBlock const& to) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (&m_entry_point.block() == &from) | 
					
						
							|  |  |  |         m_entry_point = Label { to }; | 
					
						
							|  |  |  |     if (m_handler_target.has_value() && &m_handler_target->block() == &from) | 
					
						
							|  |  |  |         m_handler_target = Label { to }; | 
					
						
							|  |  |  |     if (m_finalizer_target.has_value() && &m_finalizer_target->block() == &from) | 
					
						
							|  |  |  |         m_finalizer_target = Label { to }; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-15 18:08:12 +04:30
										 |  |  | void LeaveUnwindContext::execute_impl(Bytecode::Interpreter& interpreter) const | 
					
						
							| 
									
										
										
										
											2021-06-10 15:04:38 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     interpreter.leave_unwind_context(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-15 18:08:12 +04:30
										 |  |  | void ContinuePendingUnwind::execute_impl(Bytecode::Interpreter& interpreter) const | 
					
						
							| 
									
										
										
										
											2021-06-10 15:04:38 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     interpreter.continue_pending_unwind(m_resume_target); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-13 20:40:20 +04:30
										 |  |  | void ContinuePendingUnwind::replace_references_impl(BasicBlock const& from, BasicBlock const& to) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (&m_resume_target.block() == &from) | 
					
						
							|  |  |  |         m_resume_target = Label { to }; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-01 12:24:46 +02:00
										 |  |  | void PushDeclarativeEnvironment::execute_impl(Bytecode::Interpreter& interpreter) const | 
					
						
							| 
									
										
										
										
											2021-06-10 22:12:21 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2021-09-22 12:44:56 +02:00
										 |  |  |     auto* environment = interpreter.vm().heap().allocate<DeclarativeEnvironment>(interpreter.global_object(), interpreter.vm().lexical_environment()); | 
					
						
							| 
									
										
										
										
											2021-07-01 12:24:46 +02:00
										 |  |  |     interpreter.vm().running_execution_context().lexical_environment = environment; | 
					
						
							|  |  |  |     interpreter.vm().running_execution_context().variable_environment = environment; | 
					
						
							| 
									
										
										
										
											2021-06-10 22:12:21 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-15 18:08:12 +04:30
										 |  |  | void Yield::execute_impl(Bytecode::Interpreter& interpreter) const | 
					
						
							| 
									
										
										
										
											2021-06-11 01:38:30 +04:30
										 |  |  | { | 
					
						
							|  |  |  |     auto yielded_value = interpreter.accumulator().value_or(js_undefined()); | 
					
						
							| 
									
										
										
										
											2021-06-16 20:52:30 +01:00
										 |  |  |     auto object = JS::Object::create(interpreter.global_object(), nullptr); | 
					
						
							| 
									
										
										
										
											2021-07-06 01:15:50 +03:00
										 |  |  |     object->define_direct_property("result", yielded_value, JS::default_attributes); | 
					
						
							| 
									
										
										
										
											2021-06-11 01:38:30 +04:30
										 |  |  |     if (m_continuation_label.has_value()) | 
					
						
							| 
									
										
										
										
											2021-07-06 01:15:50 +03:00
										 |  |  |         object->define_direct_property("continuation", Value(static_cast<double>(reinterpret_cast<u64>(&m_continuation_label->block()))), JS::default_attributes); | 
					
						
							| 
									
										
										
										
											2021-06-11 01:38:30 +04:30
										 |  |  |     else | 
					
						
							| 
									
										
										
										
											2021-07-06 01:15:50 +03:00
										 |  |  |         object->define_direct_property("continuation", Value(0), JS::default_attributes); | 
					
						
							| 
									
										
										
										
											2021-06-11 01:38:30 +04:30
										 |  |  |     interpreter.do_return(object); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-13 20:40:20 +04:30
										 |  |  | void Yield::replace_references_impl(BasicBlock const& from, BasicBlock const& to) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (m_continuation_label.has_value() && &m_continuation_label->block() == &from) | 
					
						
							|  |  |  |         m_continuation_label = Label { to }; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-15 18:08:12 +04:30
										 |  |  | void GetByValue::execute_impl(Bytecode::Interpreter& interpreter) const | 
					
						
							| 
									
										
										
										
											2021-06-11 00:35:25 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2021-10-12 19:24:57 +01:00
										 |  |  |     auto object_or_error = interpreter.reg(m_base).to_object(interpreter.global_object()); | 
					
						
							|  |  |  |     if (object_or_error.is_error()) | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     auto* object = object_or_error.release_value(); | 
					
						
							| 
									
										
										
										
											2021-10-16 22:20:23 +03:00
										 |  |  |     auto property_key_or_error = interpreter.accumulator().to_property_key(interpreter.global_object()); | 
					
						
							|  |  |  |     if (property_key_or_error.is_error()) | 
					
						
							| 
									
										
										
										
											2021-10-12 19:24:57 +01:00
										 |  |  |         return; | 
					
						
							| 
									
										
										
										
											2021-10-16 22:20:23 +03:00
										 |  |  |     auto value_or_error = object->get(property_key_or_error.release_value()); | 
					
						
							| 
									
										
										
										
											2021-10-12 19:24:57 +01:00
										 |  |  |     if (value_or_error.is_error()) | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     interpreter.accumulator() = value_or_error.release_value(); | 
					
						
							| 
									
										
										
										
											2021-06-11 00:35:25 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-15 18:08:12 +04:30
										 |  |  | void PutByValue::execute_impl(Bytecode::Interpreter& interpreter) const | 
					
						
							| 
									
										
										
										
											2021-06-11 00:35:25 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2021-10-12 19:24:57 +01:00
										 |  |  |     auto object_or_error = interpreter.reg(m_base).to_object(interpreter.global_object()); | 
					
						
							|  |  |  |     if (object_or_error.is_error()) | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     auto* object = object_or_error.release_value(); | 
					
						
							| 
									
										
										
										
											2021-10-16 22:20:23 +03:00
										 |  |  |     auto property_key_or_error = interpreter.reg(m_property).to_property_key(interpreter.global_object()); | 
					
						
							|  |  |  |     if (property_key_or_error.is_error()) | 
					
						
							| 
									
										
										
										
											2021-10-12 19:24:57 +01:00
										 |  |  |         return; | 
					
						
							| 
									
										
										
										
											2021-10-16 22:20:23 +03:00
										 |  |  |     MUST(object->set(property_key_or_error.release_value(), interpreter.accumulator(), Object::ShouldThrowExceptions::Yes)); | 
					
						
							| 
									
										
										
										
											2021-06-11 00:35:25 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-13 13:40:48 -07:00
										 |  |  | void GetIterator::execute_impl(Bytecode::Interpreter& interpreter) const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     interpreter.accumulator() = get_iterator(interpreter.global_object(), interpreter.accumulator()); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void IteratorNext::execute_impl(Bytecode::Interpreter& interpreter) const | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2021-10-12 19:24:57 +01:00
										 |  |  |     auto object_or_error = interpreter.accumulator().to_object(interpreter.global_object()); | 
					
						
							|  |  |  |     if (object_or_error.is_error()) | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     auto* object = object_or_error.release_value(); | 
					
						
							|  |  |  |     interpreter.accumulator() = iterator_next(*object); | 
					
						
							| 
									
										
										
										
											2021-06-13 13:40:48 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void IteratorResultDone::execute_impl(Bytecode::Interpreter& interpreter) const | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2021-10-12 19:24:57 +01:00
										 |  |  |     auto iterator_result_or_error = interpreter.accumulator().to_object(interpreter.global_object()); | 
					
						
							|  |  |  |     if (iterator_result_or_error.is_error()) | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     auto* iterator_result = iterator_result_or_error.release_value(); | 
					
						
							|  |  |  |     interpreter.accumulator() = Value(iterator_complete(interpreter.global_object(), *iterator_result)); | 
					
						
							| 
									
										
										
										
											2021-06-13 13:40:48 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void IteratorResultValue::execute_impl(Bytecode::Interpreter& interpreter) const | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2021-10-12 19:24:57 +01:00
										 |  |  |     auto iterator_result_or_error = interpreter.accumulator().to_object(interpreter.global_object()); | 
					
						
							|  |  |  |     if (iterator_result_or_error.is_error()) | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     auto* iterator_result = iterator_result_or_error.release_value(); | 
					
						
							|  |  |  |     interpreter.accumulator() = iterator_value(interpreter.global_object(), *iterator_result); | 
					
						
							| 
									
										
										
										
											2021-06-13 13:40:48 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-30 15:42:13 -03:00
										 |  |  | void NewClass::execute_impl(Bytecode::Interpreter&) const | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2021-07-01 17:45:45 +02:00
										 |  |  |     (void)m_class_expression; | 
					
						
							| 
									
										
										
										
											2021-06-30 15:42:13 -03:00
										 |  |  |     TODO(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-15 18:08:12 +04:30
										 |  |  | String Load::to_string_impl(Bytecode::Executable const&) const | 
					
						
							| 
									
										
										
										
											2021-06-03 10:46:30 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2021-06-09 11:06:11 +02:00
										 |  |  |     return String::formatted("Load {}", m_src); | 
					
						
							| 
									
										
										
										
											2021-06-03 10:46:30 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-15 18:08:12 +04:30
										 |  |  | String LoadImmediate::to_string_impl(Bytecode::Executable const&) const | 
					
						
							| 
									
										
										
										
											2021-06-07 22:05:09 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2021-06-09 11:06:11 +02:00
										 |  |  |     return String::formatted("LoadImmediate {}", m_value); | 
					
						
							| 
									
										
										
										
											2021-06-07 20:58:36 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-15 18:08:12 +04:30
										 |  |  | String Store::to_string_impl(Bytecode::Executable const&) const | 
					
						
							| 
									
										
										
										
											2021-06-07 20:58:36 -07:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2021-06-09 11:06:11 +02:00
										 |  |  |     return String::formatted("Store {}", m_dst); | 
					
						
							| 
									
										
										
										
											2021-06-07 22:05:09 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-15 18:08:12 +04:30
										 |  |  | String NewBigInt::to_string_impl(Bytecode::Executable const&) const | 
					
						
							| 
									
										
										
										
											2021-06-08 07:59:25 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2021-06-29 17:51:52 +03:00
										 |  |  |     return String::formatted("NewBigInt \"{}\"", m_bigint.to_base(10)); | 
					
						
							| 
									
										
										
										
											2021-06-08 07:59:25 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-15 18:08:12 +04:30
										 |  |  | String NewArray::to_string_impl(Bytecode::Executable const&) const | 
					
						
							| 
									
										
										
										
											2021-06-08 23:06:52 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     StringBuilder builder; | 
					
						
							|  |  |  |     builder.append("NewArray"); | 
					
						
							|  |  |  |     if (m_element_count != 0) { | 
					
						
							| 
									
										
										
										
											2021-06-09 11:06:11 +02:00
										 |  |  |         builder.append(" ["); | 
					
						
							| 
									
										
										
										
											2021-06-08 23:06:52 +02:00
										 |  |  |         for (size_t i = 0; i < m_element_count; ++i) { | 
					
						
							|  |  |  |             builder.appendff("{}", m_elements[i]); | 
					
						
							|  |  |  |             if (i != m_element_count - 1) | 
					
						
							|  |  |  |                 builder.append(','); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         builder.append(']'); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return builder.to_string(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-13 14:06:26 -07:00
										 |  |  | String IteratorToArray::to_string_impl(const Bytecode::Executable&) const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return "IteratorToArray"; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-15 18:08:12 +04:30
										 |  |  | String NewString::to_string_impl(Bytecode::Executable const& executable) const | 
					
						
							| 
									
										
										
										
											2021-06-03 18:26:32 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2021-06-09 10:02:01 +02:00
										 |  |  |     return String::formatted("NewString {} (\"{}\")", m_string, executable.string_table->get(m_string)); | 
					
						
							| 
									
										
										
										
											2021-06-03 18:26:32 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-15 18:08:12 +04:30
										 |  |  | String NewObject::to_string_impl(Bytecode::Executable const&) const | 
					
						
							| 
									
										
										
										
											2021-06-04 20:30:23 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2021-06-07 20:58:36 -07:00
										 |  |  |     return "NewObject"; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-19 17:17:40 -07:00
										 |  |  | String NewRegExp::to_string_impl(Bytecode::Executable const& executable) const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return String::formatted("NewRegExp source:{} (\"{}\") flags:{} (\"{}\")", m_source_index, executable.get_string(m_source_index), m_flags_index, executable.get_string(m_flags_index)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-13 15:30:32 -07:00
										 |  |  | String CopyObjectExcludingProperties::to_string_impl(const Bytecode::Executable&) const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     StringBuilder builder; | 
					
						
							|  |  |  |     builder.appendff("CopyObjectExcludingProperties from:{}", m_from_object); | 
					
						
							|  |  |  |     if (m_excluded_names_count != 0) { | 
					
						
							|  |  |  |         builder.append(" excluding:["); | 
					
						
							|  |  |  |         for (size_t i = 0; i < m_excluded_names_count; ++i) { | 
					
						
							|  |  |  |             builder.appendff("{}", m_excluded_names[i]); | 
					
						
							|  |  |  |             if (i != m_excluded_names_count - 1) | 
					
						
							|  |  |  |                 builder.append(','); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         builder.append(']'); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return builder.to_string(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-15 18:08:12 +04:30
										 |  |  | String ConcatString::to_string_impl(Bytecode::Executable const&) const | 
					
						
							| 
									
										
										
										
											2021-06-07 20:58:36 -07:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2021-06-09 11:06:11 +02:00
										 |  |  |     return String::formatted("ConcatString {}", m_lhs); | 
					
						
							| 
									
										
										
										
											2021-06-04 20:30:23 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-15 18:08:12 +04:30
										 |  |  | String GetVariable::to_string_impl(Bytecode::Executable const& executable) const | 
					
						
							| 
									
										
										
										
											2021-06-03 18:26:32 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2021-06-09 10:02:01 +02:00
										 |  |  |     return String::formatted("GetVariable {} ({})", m_identifier, executable.string_table->get(m_identifier)); | 
					
						
							| 
									
										
										
										
											2021-06-03 18:26:32 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-15 18:08:12 +04:30
										 |  |  | String SetVariable::to_string_impl(Bytecode::Executable const& executable) const | 
					
						
							| 
									
										
										
										
											2021-06-03 18:26:32 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2021-06-09 10:02:01 +02:00
										 |  |  |     return String::formatted("SetVariable {} ({})", m_identifier, executable.string_table->get(m_identifier)); | 
					
						
							| 
									
										
										
										
											2021-06-03 18:26:32 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-15 18:08:12 +04:30
										 |  |  | String PutById::to_string_impl(Bytecode::Executable const& executable) const | 
					
						
							| 
									
										
										
										
											2021-06-04 20:47:07 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2021-06-09 10:02:01 +02:00
										 |  |  |     return String::formatted("PutById base:{}, property:{} ({})", m_base, m_property, executable.string_table->get(m_property)); | 
					
						
							| 
									
										
										
										
											2021-06-04 20:47:07 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-15 18:08:12 +04:30
										 |  |  | String GetById::to_string_impl(Bytecode::Executable const& executable) const | 
					
						
							| 
									
										
										
										
											2021-06-04 21:03:53 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2021-06-09 10:02:01 +02:00
										 |  |  |     return String::formatted("GetById {} ({})", m_property, executable.string_table->get(m_property)); | 
					
						
							| 
									
										
										
										
											2021-06-04 21:03:53 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-15 18:08:12 +04:30
										 |  |  | String Jump::to_string_impl(Bytecode::Executable const&) const | 
					
						
							| 
									
										
										
										
											2021-06-04 12:07:38 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2021-06-09 06:49:58 +04:30
										 |  |  |     if (m_true_target.has_value()) | 
					
						
							|  |  |  |         return String::formatted("Jump {}", *m_true_target); | 
					
						
							|  |  |  |     return String::formatted("Jump <empty>"); | 
					
						
							| 
									
										
										
										
											2021-06-04 12:07:38 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-15 18:08:12 +04:30
										 |  |  | String JumpConditional::to_string_impl(Bytecode::Executable const&) const | 
					
						
							| 
									
										
										
										
											2021-06-04 12:20:44 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2021-06-09 06:49:58 +04:30
										 |  |  |     auto true_string = m_true_target.has_value() ? String::formatted("{}", *m_true_target) : "<empty>"; | 
					
						
							|  |  |  |     auto false_string = m_false_target.has_value() ? String::formatted("{}", *m_false_target) : "<empty>"; | 
					
						
							|  |  |  |     return String::formatted("JumpConditional true:{} false:{}", true_string, false_string); | 
					
						
							| 
									
										
										
										
											2021-06-04 12:20:44 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-15 18:08:12 +04:30
										 |  |  | String JumpNullish::to_string_impl(Bytecode::Executable const&) const | 
					
						
							| 
									
										
										
										
											2021-06-08 02:18:47 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2021-06-09 06:49:58 +04:30
										 |  |  |     auto true_string = m_true_target.has_value() ? String::formatted("{}", *m_true_target) : "<empty>"; | 
					
						
							|  |  |  |     auto false_string = m_false_target.has_value() ? String::formatted("{}", *m_false_target) : "<empty>"; | 
					
						
							|  |  |  |     return String::formatted("JumpNullish null:{} nonnull:{}", true_string, false_string); | 
					
						
							| 
									
										
										
										
											2021-06-08 02:18:47 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-13 12:24:40 -07:00
										 |  |  | String JumpUndefined::to_string_impl(Bytecode::Executable const&) const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     auto true_string = m_true_target.has_value() ? String::formatted("{}", *m_true_target) : "<empty>"; | 
					
						
							|  |  |  |     auto false_string = m_false_target.has_value() ? String::formatted("{}", *m_false_target) : "<empty>"; | 
					
						
							|  |  |  |     return String::formatted("JumpUndefined undefined:{} not undefined:{}", true_string, false_string); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-15 18:08:12 +04:30
										 |  |  | String Call::to_string_impl(Bytecode::Executable const&) const | 
					
						
							| 
									
										
										
										
											2021-06-05 15:15:30 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     StringBuilder builder; | 
					
						
							| 
									
										
										
										
											2021-06-07 20:58:36 -07:00
										 |  |  |     builder.appendff("Call callee:{}, this:{}", m_callee, m_this_value); | 
					
						
							| 
									
										
										
										
											2021-06-07 15:12:43 +02:00
										 |  |  |     if (m_argument_count != 0) { | 
					
						
							| 
									
										
										
										
											2021-06-05 15:15:30 +02:00
										 |  |  |         builder.append(", arguments:["); | 
					
						
							| 
									
										
										
										
											2021-06-07 15:12:43 +02:00
										 |  |  |         for (size_t i = 0; i < m_argument_count; ++i) { | 
					
						
							| 
									
										
										
										
											2021-06-05 15:15:30 +02:00
										 |  |  |             builder.appendff("{}", m_arguments[i]); | 
					
						
							| 
									
										
										
										
											2021-06-07 15:12:43 +02:00
										 |  |  |             if (i != m_argument_count - 1) | 
					
						
							| 
									
										
										
										
											2021-06-05 15:15:30 +02:00
										 |  |  |                 builder.append(','); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         builder.append(']'); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return builder.to_string(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-15 18:08:12 +04:30
										 |  |  | String NewFunction::to_string_impl(Bytecode::Executable const&) const | 
					
						
							| 
									
										
										
										
											2021-06-05 15:14:09 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2021-06-10 00:49:23 +02:00
										 |  |  |     return "NewFunction"; | 
					
						
							| 
									
										
										
										
											2021-06-05 15:14:09 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-30 15:42:13 -03:00
										 |  |  | String NewClass::to_string_impl(Bytecode::Executable const&) const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return "NewClass"; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-15 18:08:12 +04:30
										 |  |  | String Return::to_string_impl(Bytecode::Executable const&) const | 
					
						
							| 
									
										
										
										
											2021-06-05 15:53:36 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     return "Return"; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-15 18:08:12 +04:30
										 |  |  | String Increment::to_string_impl(Bytecode::Executable const&) const | 
					
						
							| 
									
										
										
										
											2021-06-09 11:40:38 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     return "Increment"; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-15 18:08:12 +04:30
										 |  |  | String Decrement::to_string_impl(Bytecode::Executable const&) const | 
					
						
							| 
									
										
										
										
											2021-06-09 11:40:38 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     return "Decrement"; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-15 18:08:12 +04:30
										 |  |  | String Throw::to_string_impl(Bytecode::Executable const&) const | 
					
						
							| 
									
										
										
										
											2021-06-09 18:18:56 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     return "Throw"; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-15 18:08:12 +04:30
										 |  |  | String EnterUnwindContext::to_string_impl(Bytecode::Executable const&) const | 
					
						
							| 
									
										
										
										
											2021-06-10 15:04:38 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     auto handler_string = m_handler_target.has_value() ? String::formatted("{}", *m_handler_target) : "<empty>"; | 
					
						
							|  |  |  |     auto finalizer_string = m_finalizer_target.has_value() ? String::formatted("{}", *m_finalizer_target) : "<empty>"; | 
					
						
							| 
									
										
										
										
											2021-06-13 20:39:40 +04:30
										 |  |  |     return String::formatted("EnterUnwindContext handler:{} finalizer:{} entry:{}", handler_string, finalizer_string, m_entry_point); | 
					
						
							| 
									
										
										
										
											2021-06-10 15:04:38 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-15 18:08:12 +04:30
										 |  |  | String LeaveUnwindContext::to_string_impl(Bytecode::Executable const&) const | 
					
						
							| 
									
										
										
										
											2021-06-10 15:04:38 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     return "LeaveUnwindContext"; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-15 18:08:12 +04:30
										 |  |  | String ContinuePendingUnwind::to_string_impl(Bytecode::Executable const&) const | 
					
						
							| 
									
										
										
										
											2021-06-10 15:04:38 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     return String::formatted("ContinuePendingUnwind resume:{}", m_resume_target); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-01 12:24:46 +02:00
										 |  |  | String PushDeclarativeEnvironment::to_string_impl(const Bytecode::Executable& executable) const | 
					
						
							| 
									
										
										
										
											2021-06-10 22:12:21 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     StringBuilder builder; | 
					
						
							| 
									
										
										
										
											2021-07-01 12:24:46 +02:00
										 |  |  |     builder.append("PushDeclarativeEnvironment"); | 
					
						
							| 
									
										
										
										
											2021-06-10 22:12:21 +02:00
										 |  |  |     if (!m_variables.is_empty()) { | 
					
						
							|  |  |  |         builder.append(" {"); | 
					
						
							|  |  |  |         Vector<String> names; | 
					
						
							|  |  |  |         for (auto& it : m_variables) | 
					
						
							|  |  |  |             names.append(executable.get_string(it.key)); | 
					
						
							|  |  |  |         builder.join(", ", names); | 
					
						
							|  |  |  |         builder.append("}"); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return builder.to_string(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-15 18:08:12 +04:30
										 |  |  | String Yield::to_string_impl(Bytecode::Executable const&) const | 
					
						
							| 
									
										
										
										
											2021-06-11 01:38:30 +04:30
										 |  |  | { | 
					
						
							|  |  |  |     if (m_continuation_label.has_value()) | 
					
						
							|  |  |  |         return String::formatted("Yield continuation:@{}", m_continuation_label->block().name()); | 
					
						
							|  |  |  |     return String::formatted("Yield return"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-15 18:08:12 +04:30
										 |  |  | String GetByValue::to_string_impl(const Bytecode::Executable&) const | 
					
						
							| 
									
										
										
										
											2021-06-11 00:35:25 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     return String::formatted("GetByValue base:{}", m_base); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-15 18:08:12 +04:30
										 |  |  | String PutByValue::to_string_impl(const Bytecode::Executable&) const | 
					
						
							| 
									
										
										
										
											2021-06-11 00:35:25 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     return String::formatted("PutByValue base:{}, property:{}", m_base, m_property); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-13 13:40:48 -07:00
										 |  |  | String GetIterator::to_string_impl(Executable const&) const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return "GetIterator"; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | String IteratorNext::to_string_impl(Executable const&) const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return "IteratorNext"; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | String IteratorResultDone::to_string_impl(Executable const&) const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return "IteratorResultDone"; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | String IteratorResultValue::to_string_impl(Executable const&) const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return "IteratorResultValue"; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-03 10:46:30 +02:00
										 |  |  | } |