1 // Copyright 2016-2021 Doug Moen 2 // Licensed under the Apache License, version 2.0 3 // See accompanying file LICENSE or https://www.apache.org/licenses/LICENSE-2.0 4 5 #ifndef LIBCURV_SC_FRAME_H 6 #define LIBCURV_SC_FRAME_H 7 8 #include <ostream> 9 #include <libcurv/sc_type.h> 10 #include <libcurv/module.h> 11 #include <libcurv/tail_array.h> 12 13 namespace curv { 14 15 struct Context; 16 struct SC_Compiler; 17 struct Phrase; 18 struct Function; 19 20 /// An SSA variable used during SC code generation. 21 struct SC_Value 22 { 23 unsigned index; 24 SC_Type type; 25 SC_ValueSC_Value26 SC_Value(unsigned i, SC_Type t) : index(i), type(t) {} SC_ValueSC_Value27 SC_Value() noexcept {} 28 }; 29 30 /// print the GLSL variable name 31 inline std::ostream& operator<<(std::ostream& out, SC_Value v) 32 { 33 out << "r" << v.index; 34 return out; 35 } 36 37 struct SC_Frame_Base; 38 using SC_Frame = Tail_Array<SC_Frame_Base>; 39 40 /// A function call frame used by the Shape Compiler. 41 /// 42 /// The SC compilation process is a kind of abstract evaluation. 43 /// That's really clear when you see that SC_Frame is isomorphic to Frame, 44 /// with local slot Values replaced by SC_Values. 45 struct SC_Frame_Base 46 { 47 SC_Compiler& sc_; 48 49 /// The root frame has a context pointer, which points to the shape 50 /// expression that is being compiled. Used for printing a stack trace. 51 const Context* root_context_; 52 53 /// Frames are linked into a stack. This is metadata used for printing 54 /// a stack trace and by the debugger. It is not used during evaluation. 55 SC_Frame* parent_frame_; 56 57 /// If this is a function call frame, then call_phrase_ is the source code 58 /// for the function call. If it is a frame for a reactive value expression, 59 /// then it's source code for the expression. Otherwise it's nullptr. 60 /// If not null, then the phrase creates a stack trace entry. 61 Shared<const Phrase> call_phrase_; 62 63 // If this is a function call frame, then `func_` is the function that 64 // was called. Otherwise, nullptr. Used to print stack traces. 65 Shared<const Function> func_; 66 67 /// Slot array containing the values of nonlocal bindings. 68 /// 69 /// This is: 70 /// * the slot array of a Closure value, for a function call frame 71 /// * nullptr, for a call to a builtin function. 72 Module* nonlocals_; 73 74 // Tail array, containing the slots used for local bindings: 75 // function arguments, block bindings and other local, temporary values. 76 using value_type = SC_Value; 77 size_t size_; 78 value_type array_[0]; 79 80 SC_Value& operator[](size_t i) 81 { 82 assert(i < size_); 83 return array_[i]; 84 } 85 SC_Frame_BaseSC_Frame_Base86 SC_Frame_Base( 87 SC_Compiler& sc, 88 const Context* cx, 89 SC_Frame* parent, 90 Shared<const Function> func, 91 Shared<const Phrase> src) 92 : 93 sc_(sc), 94 root_context_(cx), 95 parent_frame_(parent), 96 call_phrase_(move(src)), 97 func_(move(func)), 98 nonlocals_(nullptr) 99 {} 100 }; 101 102 } // namespace 103 #endif // header guard 104