hphp/runtime/vm/jit/ir-builder.cpp
/*
 * This is called when each instruction is generated during initial IR
 * creation.
 *
 * This function inspects the instruction and prepares it for potentially being
 * inserted to the instruction stream.  It then calls optimizeInst, which may
 * or may not insert it depending on a variety of factors.
 */
This is called when each instruction is generated during initial IR
creation.

This function inspects the instruction and prepares it for potentially being
inserted to the instruction stream.  It then calls optimizeInst, which may
or may not insert it depending on a variety of factors.
This is called when each instruction is generated during initial IR creation . This function inspects the instruction and prepares it for potentially being inserted to the instruction stream . It then calls optimizeInst which may or may not insert it depending on a variety of factors .
SSATmp* IRBuilder::prepareInst(IRInstruction* inst) {
  if (inst->mayRaiseError() && inst->taken()) {
    FTRACE(1, "{}: asserting about catch block\n",
      inst->toString());
    always_assert_flog(
      m_exnStack.sp == sp(),
      "catch block would have had a mismatched stack pointer:\n"
      "     inst: {}\n"
      "       sp: {}\n"
      " expected: {}\n",
      inst->toString(),
      sp()->toString(),
      m_exnStack.sp->toString()
    );
  }
  if (inst->mayRaiseError() && !inst->taken()) {
    FTRACE(1, "{}: creating {}catch block\n",
      inst->toString(),
      m_catchCreator ? "custom " : "");
    always_assert_flog(
      m_exnStack.sp == sp(),
      "catch block would have had a mismatched stack pointer:\n"
      "     inst: {}\n"
      "       sp: {}\n"
      " expected: {}\n",
      inst->toString(),
      sp()->toString(),
      m_exnStack.sp->toString()
    );
    inst->setTaken(
      m_catchCreator
        ? m_catchCreator()
        : create_catch_block(*this, m_exnStack, m_curMarker)
    );
  }
  if (inst->mayRaiseError()) {
    assert(inst->taken() && inst->taken()->isCatch());
  }
  return optimizeInst(inst, CloneFlag::Yes, nullptr, folly::none);
}
SSATmp * IRBuilder :: prepareInst ( IRInstruction * inst ) { if ( inst -> mayRaiseError ( ) && inst -> taken ( ) ) { FTRACE ( 1 , " \n " , inst -> toString ( ) ) ; always_assert_flog ( m_exnStack . sp == sp ( ) , " \n " " \n " " \n " " \n " , inst -> toString ( ) , sp ( ) -> toString ( ) , m_exnStack . sp -> toString ( ) ) ; } if ( inst -> mayRaiseError ( ) && ! inst -> taken ( ) ) { FTRACE ( 1 , " \n " , inst -> toString ( ) , m_catchCreator ? " " : " " ) ; always_assert_flog ( m_exnStack . sp == sp ( ) , " \n " " \n " " \n " " \n " , inst -> toString ( ) , sp ( ) -> toString ( ) , m_exnStack . sp -> toString ( ) ) ; inst -> setTaken ( m_catchCreator ? m_catchCreator ( ) : create_catch_block ( * this , m_exnStack , m_curMarker ) ) ; } if ( inst -> mayRaiseError ( ) ) { assert ( inst -> taken ( ) && inst -> taken ( ) -> isCatch ( ) ) ; } return optimizeInst ( inst , CloneFlag :: Yes , nullptr , folly :: none ) ; }
This is called when each instruction is generated during initial IR
 creation.
This is called when each instruction is generated during initial IR creation .
/*
     * This assertion means you manually created a catch block, but didn't put
     * an exceptionStackBoundary after an update to the stack.  Even if you're
     * manually creating catches we require this just to make sure you're not
     * doing it on accident.
     */ /*
     * If you hit this assertion, you're gen'ing an IR instruction that can
     * throw after gen'ing one that could write to the evaluation stack.  This
     * is usually not what HHBC opcodes do, and could be a bug.  See the
     * documentation for exceptionStackBoundary in the header for more
     * information.
     */