Serenity Operating System
at hosted 192 lines 6.0 kB view raw
1/* 2 * Copyright (c) 2020, Andreas Kling <kling@serenityos.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, this 9 * list of conditions and the following disclaimer. 10 * 11 * 2. Redistributions in binary form must reproduce the above copyright notice, 12 * this list of conditions and the following disclaimer in the documentation 13 * and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 21 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 22 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 23 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 */ 26 27#pragma once 28 29#include <AK/FlyString.h> 30#include <AK/HashMap.h> 31#include <AK/String.h> 32#include <AK/Vector.h> 33#include <LibJS/Forward.h> 34#include <LibJS/Heap/Heap.h> 35#include <LibJS/Runtime/Exception.h> 36#include <LibJS/Runtime/Value.h> 37 38namespace JS { 39 40enum class ScopeType { 41 None, 42 Function, 43 Block, 44 Try, 45 Breakable, 46 Continuable, 47}; 48 49struct Variable { 50 Value value; 51 DeclarationKind declaration_kind; 52}; 53 54struct ScopeFrame { 55 ScopeType type; 56 NonnullRefPtr<ScopeNode> scope_node; 57 HashMap<FlyString, Variable> variables; 58}; 59 60struct CallFrame { 61 Value this_value; 62 Vector<Value> arguments; 63}; 64 65struct Argument { 66 FlyString name; 67 Value value; 68}; 69 70typedef Vector<Argument, 8> ArgumentVector; 71 72class Interpreter { 73public: 74 template<typename GlobalObjectType, typename... Args> 75 static NonnullOwnPtr<Interpreter> create(Args&&... args) 76 { 77 auto interpreter = adopt_own(*new Interpreter); 78 interpreter->m_global_object = interpreter->heap().allocate<GlobalObjectType>(forward<Args>(args)...); 79 return interpreter; 80 } 81 82 ~Interpreter(); 83 84 Value run(const Statement&, ArgumentVector = {}, ScopeType = ScopeType::Block); 85 86 GlobalObject& global_object(); 87 const GlobalObject& global_object() const; 88 89 Heap& heap() { return m_heap; } 90 91 void unwind(ScopeType type) { m_unwind_until = type; } 92 void stop_unwind() { m_unwind_until = ScopeType::None; } 93 bool should_unwind_until(ScopeType type) const { return m_unwind_until == type; } 94 bool should_unwind() const { return m_unwind_until != ScopeType::None; } 95 96 Optional<Value> get_variable(const FlyString& name); 97 void set_variable(const FlyString& name, Value, bool first_assignment = false); 98 void declare_variable(const FlyString& name, DeclarationKind); 99 100 void gather_roots(Badge<Heap>, HashTable<Cell*>&); 101 102 void enter_scope(const ScopeNode&, ArgumentVector, ScopeType); 103 void exit_scope(const ScopeNode&); 104 105 Value call(Function*, Value this_value = {}, const Vector<Value>& arguments = {}); 106 107 CallFrame& push_call_frame() 108 { 109 m_call_stack.append({ js_undefined(), {} }); 110 return m_call_stack.last(); 111 } 112 void pop_call_frame() { m_call_stack.take_last(); } 113 const CallFrame& call_frame() { return m_call_stack.last(); } 114 115 size_t argument_count() const 116 { 117 if (m_call_stack.is_empty()) 118 return 0; 119 return m_call_stack.last().arguments.size(); 120 } 121 122 Value argument(size_t index) const 123 { 124 if (m_call_stack.is_empty()) 125 return {}; 126 auto& arguments = m_call_stack.last().arguments; 127 return index < arguments.size() ? arguments[index] : js_undefined(); 128 } 129 130 Value this_value() const 131 { 132 if (m_call_stack.is_empty()) 133 return m_global_object; 134 return m_call_stack.last().this_value; 135 } 136 137 Shape* empty_object_shape() { return m_empty_object_shape; } 138 139 Object* string_prototype() { return m_string_prototype; } 140 Object* object_prototype() { return m_object_prototype; } 141 Object* array_prototype() { return m_array_prototype; } 142 Object* error_prototype() { return m_error_prototype; } 143 Object* date_prototype() { return m_date_prototype; } 144 Object* function_prototype() { return m_function_prototype; } 145 Object* number_prototype() { return m_number_prototype; } 146 Object* boolean_prototype() { return m_boolean_prototype; } 147 148 Exception* exception() { return m_exception; } 149 void clear_exception() { m_exception = nullptr; } 150 151 template<typename T, typename... Args> 152 Value throw_exception(Args&&... args) 153 { 154 return throw_exception(heap().allocate<T>(forward<Args>(args)...)); 155 } 156 157 Value throw_exception(Exception*); 158 Value throw_exception(Value value) 159 { 160 return throw_exception(heap().allocate<Exception>(value)); 161 } 162 163 Value last_value() const { return m_last_value; } 164 165private: 166 Interpreter(); 167 168 Heap m_heap; 169 170 Value m_last_value; 171 172 Vector<ScopeFrame> m_scope_stack; 173 Vector<CallFrame> m_call_stack; 174 175 Shape* m_empty_object_shape { nullptr }; 176 177 Object* m_global_object { nullptr }; 178 Object* m_string_prototype { nullptr }; 179 Object* m_object_prototype { nullptr }; 180 Object* m_array_prototype { nullptr }; 181 Object* m_error_prototype { nullptr }; 182 Object* m_date_prototype { nullptr }; 183 Object* m_function_prototype { nullptr }; 184 Object* m_number_prototype { nullptr }; 185 Object* m_boolean_prototype { nullptr }; 186 187 Exception* m_exception { nullptr }; 188 189 ScopeType m_unwind_until { ScopeType::None }; 190}; 191 192}