From 67e07fa4e2150a8daeb52b9ec10dbf5f0a92cbcf Mon Sep 17 00:00:00 2001 From: Dan Klishch Date: Sat, 19 Aug 2023 14:14:57 -0400 Subject: [PATCH] JSSpecCompiler: Introduce ControlFlowOperator nodes --- .../CodeGenerators/JSSpecCompiler/AST/AST.h | 49 +++++++++++++++++++ .../JSSpecCompiler/AST/ASTPrinting.cpp | 17 +++++++ .../CodeGenerators/JSSpecCompiler/Forward.h | 9 ++++ 3 files changed, 75 insertions(+) diff --git a/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/AST/AST.h b/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/AST/AST.h index a4111326b6c..2f3eac95ceb 100644 --- a/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/AST/AST.h +++ b/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/AST/AST.h @@ -80,6 +80,7 @@ protected: // ```. class Statement : public Node { }; class Expression : public Node { }; +class ControlFlowOperator : public Statement { }; class ErrorNode : public Expression { public: @@ -96,6 +97,52 @@ protected: inline Tree const error_tree = make_ref_counted(); +class ControlFlowFunctionReturn : public ControlFlowOperator { +public: + ControlFlowFunctionReturn(VariableRef return_value) + : m_return_value(move(return_value)) + { + } + + VariableRef m_return_value; + +protected: + void dump_tree(StringBuilder& builder) override; +}; + +class ControlFlowJump : public ControlFlowOperator { +public: + ControlFlowJump(BasicBlockRef block) + : m_block(block) + { + } + + BasicBlockRef m_block; + +protected: + void dump_tree(StringBuilder& builder) override; +}; + +// This should be invalid enough to crash program on use. +inline NonnullRefPtr const invalid_continuation = make_ref_counted(nullptr); + +class ControlFlowBranch : public ControlFlowOperator { +public: + ControlFlowBranch(Tree condition, BasicBlockRef then, BasicBlockRef else_) + : m_condition(move(condition)) + , m_then(then) + , m_else(else_) + { + } + + Tree m_condition; + BasicBlockRef m_then; + BasicBlockRef m_else; + +protected: + void dump_tree(StringBuilder& builder) override; +}; + class MathematicalConstant : public Expression { public: MathematicalConstant(i64 number) @@ -249,6 +296,8 @@ protected: void dump_tree(StringBuilder& builder) override; }; +// Although assert might seems a good candidate for ControlFlowOperator, we are not interested in +// tracking control flow after a failed assertion. class AssertExpression : public Expression { public: AssertExpression(Tree condition) diff --git a/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/AST/ASTPrinting.cpp b/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/AST/ASTPrinting.cpp index bf324563c6a..fd963a82a62 100644 --- a/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/AST/ASTPrinting.cpp +++ b/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/AST/ASTPrinting.cpp @@ -34,6 +34,23 @@ void ErrorNode::dump_tree(StringBuilder& builder) dump_node(builder, "Error \"{}\"", m_error); } +void ControlFlowFunctionReturn::dump_tree(StringBuilder& builder) +{ + dump_node(builder, "ControlFlowFunctionReturn"); + m_return_value->format_tree(builder); +} + +void ControlFlowJump::dump_tree(StringBuilder& builder) +{ + dump_node(builder, "ControlFlowJump jump={:p}", m_block); +} + +void ControlFlowBranch::dump_tree(StringBuilder& builder) +{ + dump_node(builder, "ControlFlowBranch true={:p} false={:p}", m_then, m_else); + m_condition->format_tree(builder); +} + void MathematicalConstant::dump_tree(StringBuilder& builder) { dump_node(builder, "MathematicalConstant {}", m_number); diff --git a/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/Forward.h b/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/Forward.h index b56b6699e18..1d7d582093b 100644 --- a/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/Forward.h +++ b/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/Forward.h @@ -21,7 +21,11 @@ using Tree = NonnullRefPtr; class Statement; class Expression; class ErrorNode; +class ControlFlowOperator; +class ControlFlowFunctionReturn; +class ControlFlowJump; +class ControlFlowBranch; class MathematicalConstant; class StringLiteral; class BinaryOperation; @@ -38,9 +42,14 @@ class RecordDirectListInitialization; class FunctionCall; class SlotName; class Variable; +using VariableRef = NonnullRefPtr; class FunctionPointer; using FunctionPointerRef = NonnullRefPtr; +// Compiler/ControlFlowGraph.h +class BasicBlock; +using BasicBlockRef = BasicBlock*; + // Compiler/GenericASTPass.h class RecursiveASTVisitor;