| 
									
										
										
										
											2021-06-03 10:46:30 +02:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * Copyright (c) 2021, Andreas Kling <kling@serenityos.org> | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * SPDX-License-Identifier: BSD-2-Clause | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #pragma once
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <AK/Forward.h>
 | 
					
						
							| 
									
										
										
										
											2021-10-25 13:37:02 +02:00
										 |  |  | #include <AK/Span.h>
 | 
					
						
							| 
									
										
										
										
											2021-06-03 10:46:30 +02:00
										 |  |  | #include <LibJS/Forward.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-01 12:24:46 +02:00
										 |  |  | #define ENUMERATE_BYTECODE_OPS(O)    \
 | 
					
						
							|  |  |  |     O(Add)                           \ | 
					
						
							| 
									
										
										
										
											2022-09-09 15:23:02 +02:00
										 |  |  |     O(Append)                        \ | 
					
						
							| 
									
										
										
										
											2021-10-24 14:38:57 +02:00
										 |  |  |     O(BitwiseAnd)                    \ | 
					
						
							|  |  |  |     O(BitwiseNot)                    \ | 
					
						
							|  |  |  |     O(BitwiseOr)                     \ | 
					
						
							|  |  |  |     O(BitwiseXor)                    \ | 
					
						
							|  |  |  |     O(Call)                          \ | 
					
						
							|  |  |  |     O(ConcatString)                  \ | 
					
						
							|  |  |  |     O(ContinuePendingUnwind)         \ | 
					
						
							|  |  |  |     O(CopyObjectExcludingProperties) \ | 
					
						
							| 
									
										
										
										
											2022-02-12 19:48:45 +03:30
										 |  |  |     O(CreateEnvironment)             \ | 
					
						
							|  |  |  |     O(CreateVariable)                \ | 
					
						
							| 
									
										
										
										
											2021-10-24 14:38:57 +02:00
										 |  |  |     O(Decrement)                     \ | 
					
						
							| 
									
										
										
										
											2022-03-27 19:50:09 +01:00
										 |  |  |     O(DeleteById)                    \ | 
					
						
							|  |  |  |     O(DeleteByValue)                 \ | 
					
						
							|  |  |  |     O(DeleteVariable)                \ | 
					
						
							| 
									
										
										
										
											2021-07-01 12:24:46 +02:00
										 |  |  |     O(Div)                           \ | 
					
						
							| 
									
										
										
										
											2021-10-24 14:38:57 +02:00
										 |  |  |     O(EnterUnwindContext)            \ | 
					
						
							| 
									
										
										
										
											2022-03-13 16:01:18 +03:30
										 |  |  |     O(EnterObjectEnvironment)        \ | 
					
						
							| 
									
										
										
										
											2021-07-01 12:24:46 +02:00
										 |  |  |     O(Exp)                           \ | 
					
						
							| 
									
										
										
										
											2021-11-10 22:22:26 +03:30
										 |  |  |     O(FinishUnwind)                  \ | 
					
						
							| 
									
										
										
										
											2021-10-24 14:38:57 +02:00
										 |  |  |     O(GetById)                       \ | 
					
						
							|  |  |  |     O(GetByValue)                    \ | 
					
						
							|  |  |  |     O(GetIterator)                   \ | 
					
						
							| 
									
										
										
										
											2022-03-19 19:40:21 +00:00
										 |  |  |     O(GetNewTarget)                  \ | 
					
						
							| 
									
										
										
										
											2022-03-18 20:18:19 +03:30
										 |  |  |     O(GetObjectPropertyIterator)     \ | 
					
						
							| 
									
										
										
										
											2021-10-24 14:38:57 +02:00
										 |  |  |     O(GetVariable)                   \ | 
					
						
							| 
									
										
										
										
											2021-07-01 12:24:46 +02:00
										 |  |  |     O(GreaterThan)                   \ | 
					
						
							|  |  |  |     O(GreaterThanEquals)             \ | 
					
						
							| 
									
										
										
										
											2021-10-24 14:38:57 +02:00
										 |  |  |     O(In)                            \ | 
					
						
							|  |  |  |     O(Increment)                     \ | 
					
						
							|  |  |  |     O(InstanceOf)                    \ | 
					
						
							|  |  |  |     O(IteratorNext)                  \ | 
					
						
							|  |  |  |     O(IteratorResultDone)            \ | 
					
						
							|  |  |  |     O(IteratorResultValue)           \ | 
					
						
							|  |  |  |     O(IteratorToArray)               \ | 
					
						
							|  |  |  |     O(Jump)                          \ | 
					
						
							|  |  |  |     O(JumpConditional)               \ | 
					
						
							|  |  |  |     O(JumpNullish)                   \ | 
					
						
							|  |  |  |     O(JumpUndefined)                 \ | 
					
						
							| 
									
										
										
										
											2022-02-12 19:48:45 +03:30
										 |  |  |     O(LeaveEnvironment)              \ | 
					
						
							| 
									
										
										
										
											2021-10-24 14:38:57 +02:00
										 |  |  |     O(LeaveUnwindContext)            \ | 
					
						
							|  |  |  |     O(LeftShift)                     \ | 
					
						
							| 
									
										
										
										
											2021-07-01 12:24:46 +02:00
										 |  |  |     O(LessThan)                      \ | 
					
						
							|  |  |  |     O(LessThanEquals)                \ | 
					
						
							| 
									
										
										
										
											2021-10-24 14:38:57 +02:00
										 |  |  |     O(Load)                          \ | 
					
						
							|  |  |  |     O(LoadImmediate)                 \ | 
					
						
							| 
									
										
										
										
											2021-09-24 00:06:10 +02:00
										 |  |  |     O(LooselyEquals)                 \ | 
					
						
							| 
									
										
										
										
											2021-10-24 14:38:57 +02:00
										 |  |  |     O(LooselyInequals)               \ | 
					
						
							|  |  |  |     O(Mod)                           \ | 
					
						
							|  |  |  |     O(Mul)                           \ | 
					
						
							| 
									
										
										
										
											2021-07-01 12:24:46 +02:00
										 |  |  |     O(NewArray)                      \ | 
					
						
							| 
									
										
										
										
											2021-10-24 14:38:57 +02:00
										 |  |  |     O(NewBigInt)                     \ | 
					
						
							|  |  |  |     O(NewClass)                      \ | 
					
						
							|  |  |  |     O(NewFunction)                   \ | 
					
						
							| 
									
										
										
										
											2021-07-01 12:24:46 +02:00
										 |  |  |     O(NewObject)                     \ | 
					
						
							|  |  |  |     O(NewRegExp)                     \ | 
					
						
							| 
									
										
										
										
											2021-10-24 14:38:57 +02:00
										 |  |  |     O(NewString)                     \ | 
					
						
							|  |  |  |     O(Not)                           \ | 
					
						
							|  |  |  |     O(PushDeclarativeEnvironment)    \ | 
					
						
							| 
									
										
										
										
											2021-07-01 12:24:46 +02:00
										 |  |  |     O(PutById)                       \ | 
					
						
							|  |  |  |     O(PutByValue)                    \ | 
					
						
							| 
									
										
										
										
											2021-10-24 14:43:00 +02:00
										 |  |  |     O(ResolveThisBinding)            \ | 
					
						
							| 
									
										
										
										
											2021-07-01 12:24:46 +02:00
										 |  |  |     O(Return)                        \ | 
					
						
							|  |  |  |     O(RightShift)                    \ | 
					
						
							| 
									
										
										
										
											2021-10-24 14:38:57 +02:00
										 |  |  |     O(SetVariable)                   \ | 
					
						
							|  |  |  |     O(Store)                         \ | 
					
						
							|  |  |  |     O(StrictlyEquals)                \ | 
					
						
							|  |  |  |     O(StrictlyInequals)              \ | 
					
						
							|  |  |  |     O(Sub)                           \ | 
					
						
							| 
									
										
										
										
											2022-08-30 18:03:02 +02:00
										 |  |  |     O(SuperCall)                     \ | 
					
						
							| 
									
										
										
										
											2021-07-01 12:24:46 +02:00
										 |  |  |     O(Throw)                         \ | 
					
						
							| 
									
										
										
										
											2021-10-24 14:38:57 +02:00
										 |  |  |     O(Typeof)                        \ | 
					
						
							| 
									
										
										
										
											2022-06-11 23:12:22 +01:00
										 |  |  |     O(TypeofVariable)                \ | 
					
						
							| 
									
										
										
										
											2021-10-24 14:38:57 +02:00
										 |  |  |     O(UnaryMinus)                    \ | 
					
						
							|  |  |  |     O(UnaryPlus)                     \ | 
					
						
							|  |  |  |     O(UnsignedRightShift)            \ | 
					
						
							|  |  |  |     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
 | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-13 20:40:20 +04:30
										 |  |  |     bool is_terminator() const; | 
					
						
							| 
									
										
										
										
											2021-06-07 15:12:43 +02:00
										 |  |  |     Type type() const { return m_type; } | 
					
						
							|  |  |  |     size_t length() const; | 
					
						
							| 
									
										
										
										
											2021-06-09 10:02:01 +02:00
										 |  |  |     String to_string(Bytecode::Executable const&) const; | 
					
						
							| 
									
										
										
										
											2022-02-07 14:36:45 +01:00
										 |  |  |     ThrowCompletionOr<void> execute(Bytecode::Interpreter&) const; | 
					
						
							| 
									
										
										
										
											2021-06-13 20:40:20 +04:30
										 |  |  |     void replace_references(BasicBlock const&, BasicBlock const&); | 
					
						
							| 
									
										
										
										
											2021-06-07 15:12:43 +02:00
										 |  |  |     static void destroy(Instruction&); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | protected: | 
					
						
							|  |  |  |     explicit Instruction(Type type) | 
					
						
							|  |  |  |         : m_type(type) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-06-03 10:46:30 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-07 15:12:43 +02:00
										 |  |  | private: | 
					
						
							|  |  |  |     Type m_type {}; | 
					
						
							| 
									
										
										
										
											2021-06-03 10:46:30 +02:00
										 |  |  | }; | 
					
						
							| 
									
										
										
										
											2021-10-25 13:37:02 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | class InstructionStreamIterator { | 
					
						
							|  |  |  | public: | 
					
						
							|  |  |  |     explicit InstructionStreamIterator(ReadonlyBytes bytes) | 
					
						
							|  |  |  |         : m_bytes(bytes) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     size_t offset() const { return m_offset; } | 
					
						
							|  |  |  |     bool at_end() const { return m_offset >= m_bytes.size(); } | 
					
						
							|  |  |  |     void jump(size_t offset) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         VERIFY(offset <= m_bytes.size()); | 
					
						
							|  |  |  |         m_offset = offset; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Instruction const& operator*() const { return dereference(); } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     ALWAYS_INLINE void operator++() | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         VERIFY(!at_end()); | 
					
						
							|  |  |  |         m_offset += dereference().length(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | private: | 
					
						
							|  |  |  |     Instruction const& dereference() const { return *reinterpret_cast<Instruction const*>(m_bytes.data() + offset()); } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     ReadonlyBytes m_bytes; | 
					
						
							|  |  |  |     size_t m_offset { 0 }; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-03 10:46:30 +02:00
										 |  |  | } |