Quellcode durchsuchen

LibJS: Don't generate useless jumps for if statement

If statements without an else clause generated jumps to the next
instruction, this commit fixes the if statement generation so that it
dosen't produce them anymore.

This is an example of JS code that generates the useless jumps
(a => if(a){}) ();
samu698 vor 9 Monaten
Ursprung
Commit
7865fbfe6d
1 geänderte Dateien mit 9 neuen und 14 gelöschten Zeilen
  1. 9 14
      Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp

+ 9 - 14
Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp

@@ -2330,7 +2330,8 @@ Bytecode::CodeGenerationErrorOr<Optional<ScopedOperand>> IfStatement::generate_b
 
     auto& true_block = generator.make_block();
     auto& false_block = generator.make_block();
-    auto& end_block = generator.make_block();
+    // NOTE: if there is no 'else' block the end block is the same as the false block
+    auto& end_block = m_alternate ? generator.make_block() : false_block;
 
     Optional<ScopedOperand> completion;
     if (generator.must_propagate_completion()) {
@@ -2347,25 +2348,19 @@ Bytecode::CodeGenerationErrorOr<Optional<ScopedOperand>> IfStatement::generate_b
     generator.switch_to_basic_block(true_block);
     auto consequent = TRY(m_consequent->generate_bytecode(generator, completion));
     if (!generator.is_current_block_terminated()) {
-        if (generator.must_propagate_completion()) {
-            if (consequent.has_value())
-                generator.emit<Bytecode::Op::Mov>(*completion, *consequent);
-        }
+        if (generator.must_propagate_completion() && consequent.has_value())
+            generator.emit<Bytecode::Op::Mov>(*completion, *consequent);
         generator.emit<Bytecode::Op::Jump>(Bytecode::Label { end_block });
     }
 
-    generator.switch_to_basic_block(false_block);
-
-    Optional<ScopedOperand> alternate;
     if (m_alternate) {
-        alternate = TRY(m_alternate->generate_bytecode(generator, completion));
-    }
-    if (!generator.is_current_block_terminated()) {
-        if (generator.must_propagate_completion()) {
-            if (alternate.has_value())
+        generator.switch_to_basic_block(false_block);
+        auto alternate = TRY(m_alternate->generate_bytecode(generator, completion));
+        if (!generator.is_current_block_terminated()) {
+            if (generator.must_propagate_completion() && alternate.has_value())
                 generator.emit<Bytecode::Op::Mov>(*completion, *alternate);
+            generator.emit<Bytecode::Op::Jump>(Bytecode::Label { end_block });
         }
-        generator.emit<Bytecode::Op::Jump>(Bytecode::Label { end_block });
     }
 
     generator.switch_to_basic_block(end_block);