| 
									
										
										
										
											2021-06-03 10:46:30 +02:00
										 |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2024-02-02 10:19:17 +01:00
										 |  |  |  * Copyright (c) 2021-2024, Andreas Kling <kling@serenityos.org> | 
					
						
							| 
									
										
										
										
											2021-06-03 10:46:30 +02:00
										 |  |  |  * | 
					
						
							|  |  |  |  * SPDX-License-Identifier: BSD-2-Clause | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #pragma once
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <AK/Forward.h>
 | 
					
						
							| 
									
										
										
										
											2021-10-25 13:37:02 +02:00
										 |  |  | #include <AK/Span.h>
 | 
					
						
							| 
									
										
										
										
											2023-09-01 16:53:55 +02:00
										 |  |  | #include <LibJS/Bytecode/Executable.h>
 | 
					
						
							| 
									
										
										
										
											2021-06-03 10:46:30 +02:00
										 |  |  | #include <LibJS/Forward.h>
 | 
					
						
							| 
									
										
										
										
											2023-09-01 16:53:55 +02:00
										 |  |  | #include <LibJS/SourceRange.h>
 | 
					
						
							| 
									
										
										
										
											2021-06-03 10:46:30 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-01 14:33:58 +02:00
										 |  |  | #define ENUMERATE_BYTECODE_OPS(O)      \
 | 
					
						
							|  |  |  |     O(Add)                             \ | 
					
						
							| 
									
										
										
										
											2024-02-04 08:00:54 +01:00
										 |  |  |     O(ArrayAppend)                     \ | 
					
						
							| 
									
										
										
										
											2023-08-01 14:33:58 +02:00
										 |  |  |     O(AsyncIteratorClose)              \ | 
					
						
							|  |  |  |     O(Await)                           \ | 
					
						
							|  |  |  |     O(BitwiseAnd)                      \ | 
					
						
							|  |  |  |     O(BitwiseNot)                      \ | 
					
						
							|  |  |  |     O(BitwiseOr)                       \ | 
					
						
							|  |  |  |     O(BitwiseXor)                      \ | 
					
						
							|  |  |  |     O(BlockDeclarationInstantiation)   \ | 
					
						
							|  |  |  |     O(Call)                            \ | 
					
						
							|  |  |  |     O(CallWithArgumentArray)           \ | 
					
						
							| 
									
										
										
										
											2023-11-11 23:19:46 +01:00
										 |  |  |     O(Catch)                           \ | 
					
						
							| 
									
										
										
										
											2023-08-01 14:33:58 +02:00
										 |  |  |     O(ConcatString)                    \ | 
					
						
							|  |  |  |     O(ContinuePendingUnwind)           \ | 
					
						
							|  |  |  |     O(CopyObjectExcludingProperties)   \ | 
					
						
							|  |  |  |     O(CreateLexicalEnvironment)        \ | 
					
						
							|  |  |  |     O(CreateVariable)                  \ | 
					
						
							|  |  |  |     O(Decrement)                       \ | 
					
						
							|  |  |  |     O(DeleteById)                      \ | 
					
						
							|  |  |  |     O(DeleteByIdWithThis)              \ | 
					
						
							|  |  |  |     O(DeleteByValue)                   \ | 
					
						
							|  |  |  |     O(DeleteByValueWithThis)           \ | 
					
						
							|  |  |  |     O(DeleteVariable)                  \ | 
					
						
							|  |  |  |     O(Div)                             \ | 
					
						
							| 
									
										
										
										
											2024-02-04 08:00:54 +01:00
										 |  |  |     O(Dump)                            \ | 
					
						
							|  |  |  |     O(End)                             \ | 
					
						
							| 
									
										
										
										
											2023-08-01 14:33:58 +02:00
										 |  |  |     O(EnterUnwindContext)              \ | 
					
						
							|  |  |  |     O(EnterObjectEnvironment)          \ | 
					
						
							|  |  |  |     O(Exp)                             \ | 
					
						
							|  |  |  |     O(GetById)                         \ | 
					
						
							|  |  |  |     O(GetByIdWithThis)                 \ | 
					
						
							|  |  |  |     O(GetByValue)                      \ | 
					
						
							|  |  |  |     O(GetByValueWithThis)              \ | 
					
						
							|  |  |  |     O(GetCalleeAndThisFromEnvironment) \ | 
					
						
							|  |  |  |     O(GetIterator)                     \ | 
					
						
							| 
									
										
										
										
											2023-12-07 10:44:41 +01:00
										 |  |  |     O(GetObjectFromIteratorRecord)     \ | 
					
						
							| 
									
										
										
										
											2023-08-01 14:33:58 +02:00
										 |  |  |     O(GetMethod)                       \ | 
					
						
							|  |  |  |     O(GetNewTarget)                    \ | 
					
						
							| 
									
										
										
										
											2023-12-07 10:44:41 +01:00
										 |  |  |     O(GetNextMethodFromIteratorRecord) \ | 
					
						
							| 
									
										
										
										
											2023-08-01 14:33:58 +02:00
										 |  |  |     O(GetImportMeta)                   \ | 
					
						
							|  |  |  |     O(GetObjectPropertyIterator)       \ | 
					
						
							|  |  |  |     O(GetPrivateById)                  \ | 
					
						
							|  |  |  |     O(GetVariable)                     \ | 
					
						
							|  |  |  |     O(GetGlobal)                       \ | 
					
						
							|  |  |  |     O(GreaterThan)                     \ | 
					
						
							|  |  |  |     O(GreaterThanEquals)               \ | 
					
						
							|  |  |  |     O(HasPrivateId)                    \ | 
					
						
							|  |  |  |     O(ImportCall)                      \ | 
					
						
							|  |  |  |     O(In)                              \ | 
					
						
							|  |  |  |     O(Increment)                       \ | 
					
						
							|  |  |  |     O(InstanceOf)                      \ | 
					
						
							|  |  |  |     O(IteratorClose)                   \ | 
					
						
							|  |  |  |     O(IteratorNext)                    \ | 
					
						
							|  |  |  |     O(IteratorToArray)                 \ | 
					
						
							|  |  |  |     O(Jump)                            \ | 
					
						
							| 
									
										
										
										
											2024-02-04 08:00:54 +01:00
										 |  |  |     O(JumpIf)                          \ | 
					
						
							| 
									
										
										
										
											2023-08-01 14:33:58 +02:00
										 |  |  |     O(JumpNullish)                     \ | 
					
						
							|  |  |  |     O(JumpUndefined)                   \ | 
					
						
							|  |  |  |     O(LeaveLexicalEnvironment)         \ | 
					
						
							|  |  |  |     O(LeaveUnwindContext)              \ | 
					
						
							|  |  |  |     O(LeftShift)                       \ | 
					
						
							|  |  |  |     O(LessThan)                        \ | 
					
						
							|  |  |  |     O(LessThanEquals)                  \ | 
					
						
							|  |  |  |     O(LooselyEquals)                   \ | 
					
						
							|  |  |  |     O(LooselyInequals)                 \ | 
					
						
							|  |  |  |     O(Mod)                             \ | 
					
						
							| 
									
										
										
										
											2024-02-04 08:00:54 +01:00
										 |  |  |     O(Mov)                             \ | 
					
						
							| 
									
										
										
										
											2023-08-01 14:33:58 +02:00
										 |  |  |     O(Mul)                             \ | 
					
						
							|  |  |  |     O(NewArray)                        \ | 
					
						
							|  |  |  |     O(NewClass)                        \ | 
					
						
							|  |  |  |     O(NewFunction)                     \ | 
					
						
							|  |  |  |     O(NewObject)                       \ | 
					
						
							| 
									
										
										
										
											2023-11-17 22:07:23 +02:00
										 |  |  |     O(NewPrimitiveArray)               \ | 
					
						
							| 
									
										
										
										
											2023-08-01 14:33:58 +02:00
										 |  |  |     O(NewRegExp)                       \ | 
					
						
							|  |  |  |     O(NewTypeError)                    \ | 
					
						
							|  |  |  |     O(Not)                             \ | 
					
						
							| 
									
										
										
										
											2024-02-20 11:45:01 +01:00
										 |  |  |     O(PostfixDecrement)                \ | 
					
						
							|  |  |  |     O(PostfixIncrement)                \ | 
					
						
							| 
									
										
										
										
											2023-08-01 14:33:58 +02:00
										 |  |  |     O(PutById)                         \ | 
					
						
							|  |  |  |     O(PutByIdWithThis)                 \ | 
					
						
							|  |  |  |     O(PutByValue)                      \ | 
					
						
							|  |  |  |     O(PutByValueWithThis)              \ | 
					
						
							|  |  |  |     O(PutPrivateById)                  \ | 
					
						
							|  |  |  |     O(ResolveThisBinding)              \ | 
					
						
							|  |  |  |     O(ResolveSuperBase)                \ | 
					
						
							|  |  |  |     O(Return)                          \ | 
					
						
							|  |  |  |     O(RightShift)                      \ | 
					
						
							|  |  |  |     O(ScheduleJump)                    \ | 
					
						
							|  |  |  |     O(SetVariable)                     \ | 
					
						
							|  |  |  |     O(SetLocal)                        \ | 
					
						
							|  |  |  |     O(StrictlyEquals)                  \ | 
					
						
							|  |  |  |     O(StrictlyInequals)                \ | 
					
						
							|  |  |  |     O(Sub)                             \ | 
					
						
							|  |  |  |     O(SuperCallWithArgumentArray)      \ | 
					
						
							|  |  |  |     O(Throw)                           \ | 
					
						
							|  |  |  |     O(ThrowIfNotObject)                \ | 
					
						
							|  |  |  |     O(ThrowIfNullish)                  \ | 
					
						
							| 
									
										
										
										
											2024-02-04 08:00:54 +01:00
										 |  |  |     O(ThrowIfTDZ)                      \ | 
					
						
							| 
									
										
										
										
											2023-08-01 14:33:58 +02:00
										 |  |  |     O(Typeof)                          \ | 
					
						
							|  |  |  |     O(TypeofVariable)                  \ | 
					
						
							|  |  |  |     O(UnaryMinus)                      \ | 
					
						
							|  |  |  |     O(UnaryPlus)                       \ | 
					
						
							|  |  |  |     O(UnsignedRightShift)              \ | 
					
						
							| 
									
										
										
										
											2021-10-24 14:38:57 +02:00
										 |  |  |     O(Yield) | 
					
						
							| 
									
										
										
										
											2021-06-07 15:12:43 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-03 10:46:30 +02:00
										 |  |  | namespace JS::Bytecode { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-09 16:47:42 +02:00
										 |  |  | class alignas(void*) Instruction { | 
					
						
							| 
									
										
										
										
											2021-06-03 10:46:30 +02:00
										 |  |  | public: | 
					
						
							| 
									
										
										
										
											2021-06-09 06:49:58 +04:30
										 |  |  |     constexpr static bool IsTerminator = false; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-07 15:12:43 +02:00
										 |  |  |     enum class Type { | 
					
						
							|  |  |  | #define __BYTECODE_OP(op) \
 | 
					
						
							|  |  |  |     op, | 
					
						
							|  |  |  |         ENUMERATE_BYTECODE_OPS(__BYTECODE_OP) | 
					
						
							|  |  |  | #undef __BYTECODE_OP
 | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-25 17:59:20 +01:00
										 |  |  |     [[nodiscard]] bool is_terminator() const; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-07 15:12:43 +02:00
										 |  |  |     Type type() const { return m_type; } | 
					
						
							| 
									
										
										
										
											2023-09-13 21:32:51 +02:00
										 |  |  |     size_t length() const { return m_length; } | 
					
						
							| 
									
										
										
										
											2023-12-16 17:49:34 +03:30
										 |  |  |     ByteString to_byte_string(Bytecode::Executable const&) const; | 
					
						
							| 
									
										
										
										
											2022-02-07 14:36:45 +01:00
										 |  |  |     ThrowCompletionOr<void> execute(Bytecode::Interpreter&) const; | 
					
						
							| 
									
										
										
										
											2024-02-25 17:59:20 +01:00
										 |  |  |     void replace_references(BasicBlock const& from, BasicBlock const& to); | 
					
						
							| 
									
										
										
										
											2021-06-07 15:12:43 +02:00
										 |  |  |     static void destroy(Instruction&); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-01 16:53:55 +02:00
										 |  |  |     // FIXME: Find a better way to organize this information
 | 
					
						
							|  |  |  |     void set_source_record(SourceRecord rec) { m_source_record = rec; } | 
					
						
							|  |  |  |     SourceRecord source_record() const { return m_source_record; } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-07 15:12:43 +02:00
										 |  |  | protected: | 
					
						
							| 
									
										
										
										
											2023-09-13 21:32:51 +02:00
										 |  |  |     Instruction(Type type, size_t length) | 
					
						
							| 
									
										
										
										
											2021-06-07 15:12:43 +02:00
										 |  |  |         : m_type(type) | 
					
						
							| 
									
										
										
										
											2023-09-13 21:32:51 +02:00
										 |  |  |         , m_length(length) | 
					
						
							| 
									
										
										
										
											2021-06-07 15:12:43 +02:00
										 |  |  |     { | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-06-03 10:46:30 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-07 15:12:43 +02:00
										 |  |  | private: | 
					
						
							| 
									
										
										
										
											2023-09-01 16:53:55 +02:00
										 |  |  |     SourceRecord m_source_record {}; | 
					
						
							| 
									
										
										
										
											2021-06-07 15:12:43 +02:00
										 |  |  |     Type m_type {}; | 
					
						
							| 
									
										
										
										
											2023-09-13 21:32:51 +02:00
										 |  |  |     size_t m_length {}; | 
					
						
							| 
									
										
										
										
											2021-06-03 10:46:30 +02:00
										 |  |  | }; | 
					
						
							| 
									
										
										
										
											2021-10-25 13:37:02 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | class InstructionStreamIterator { | 
					
						
							|  |  |  | public: | 
					
						
							| 
									
										
										
										
											2023-10-30 22:06:27 +01:00
										 |  |  |     InstructionStreamIterator(ReadonlyBytes bytes, Executable const* executable = nullptr, size_t offset = 0) | 
					
						
							| 
									
										
										
										
											2023-09-26 16:03:42 +02:00
										 |  |  |         : m_begin(bytes.data()) | 
					
						
							|  |  |  |         , m_end(bytes.data() + bytes.size()) | 
					
						
							| 
									
										
										
										
											2023-10-30 22:06:27 +01:00
										 |  |  |         , m_ptr(bytes.data() + offset) | 
					
						
							| 
									
										
										
										
											2023-09-01 16:53:55 +02:00
										 |  |  |         , m_executable(executable) | 
					
						
							| 
									
										
										
										
											2021-10-25 13:37:02 +02:00
										 |  |  |     { | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-26 16:03:42 +02:00
										 |  |  |     size_t offset() const { return m_ptr - m_begin; } | 
					
						
							|  |  |  |     bool at_end() const { return m_ptr >= m_end; } | 
					
						
							| 
									
										
										
										
											2021-10-25 13:37:02 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     Instruction const& operator*() const { return dereference(); } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     ALWAYS_INLINE void operator++() | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2023-09-26 16:03:42 +02:00
										 |  |  |         m_ptr += dereference().length(); | 
					
						
							| 
									
										
										
										
											2021-10-25 13:37:02 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-01 16:53:55 +02:00
										 |  |  |     UnrealizedSourceRange source_range() const; | 
					
						
							|  |  |  |     RefPtr<SourceCode> source_code() const; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-10-03 08:18:10 +02:00
										 |  |  |     Executable const* executable() const { return m_executable; } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-25 13:37:02 +02:00
										 |  |  | private: | 
					
						
							| 
									
										
										
										
											2023-09-26 16:03:42 +02:00
										 |  |  |     Instruction const& dereference() const { return *reinterpret_cast<Instruction const*>(m_ptr); } | 
					
						
							| 
									
										
										
										
											2021-10-25 13:37:02 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-26 16:03:42 +02:00
										 |  |  |     u8 const* m_begin { nullptr }; | 
					
						
							|  |  |  |     u8 const* m_end { nullptr }; | 
					
						
							|  |  |  |     u8 const* m_ptr { nullptr }; | 
					
						
							| 
									
										
										
										
											2023-11-27 13:23:59 +01:00
										 |  |  |     GCPtr<Executable const> m_executable; | 
					
						
							| 
									
										
										
										
											2021-10-25 13:37:02 +02:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-03 10:46:30 +02:00
										 |  |  | } |