void emit_finish_func(const php::Func& func, FuncEmitter& fe, const EmitBcInfo& info) { if (info.containsCalls) fe.containsCalls = true;; for (auto& fpi : info.fpiRegions) { auto& e = fe.addFPIEnt(); e.m_fpushOff = fpi.fpushOff; e.m_fcallOff = fpi.fcallOff; e.m_fpOff = fpi.fpDelta; } emit_locals_and_params(fe, func, info); emit_ehent_tree(fe, func, info); fe.userAttributes = func.userAttributes; fe.retUserType = func.returnUserType; fe.originalFilename = func.originalFilename; fe.isClosureBody = func.isClosureBody; fe.isAsync = func.isAsync; fe.isGenerator = func.isGenerator; fe.isPairGenerator = func.isPairGenerator; if (func.nativeInfo) { fe.returnType = func.nativeInfo->returnType; } fe.retTypeConstraint = func.retTypeConstraint; fe.maxStackCells = info.maxStackDepth + fe.numLocals() + fe.numIterators() * kNumIterCells + info.maxFpiDepth * kNumActRecCells; fe.finish(fe.ue().bcPos(), false /* load */); fe.ue().recordFunction(&fe); }
void emit_finish_func(const php::Func& func, FuncEmitter& fe, const EmitBcInfo& info) { fe.setMaxStackCells( info.maxStackDepth + fe.numLocals() + info.maxFpiDepth * kNumActRecCells ); if (info.containsCalls) fe.setContainsCalls(); for (auto& fpi : info.fpiRegions) { auto& e = fe.addFPIEnt(); e.m_fpushOff = fpi.fpushOff; e.m_fcallOff = fpi.fcallOff; e.m_fpOff = fpi.fpDelta; } emit_locals_and_params(fe, func, info); emit_ehent_tree(fe, func, info); fe.setUserAttributes(func.userAttributes); fe.setReturnUserType(func.returnUserType); fe.setOriginalFilename(func.originalFilename); fe.setIsClosureBody(func.isClosureBody); fe.setIsGenerator(func.isGeneratorBody); fe.setIsGeneratorFromClosure(func.isGeneratorFromClosure); fe.setIsPairGenerator(func.isPairGenerator); fe.setGeneratorBodyName(func.generatorBodyName); fe.setIsAsync(func.isAsync); fe.finish(fe.ue().bcPos(), false /* load */); fe.ue().recordFunction(&fe); }
void FuncRepoProxy::GetFuncsStmt ::get(UnitEmitter& ue) { RepoTxn txn(m_repo); if (!prepared()) { std::stringstream ssSelect; ssSelect << "SELECT funcSn,preClassId,name,top,extraData " "FROM " << m_repo.table(m_repoId, "Func") << " WHERE unitSn == @unitSn ORDER BY funcSn ASC;"; txn.prepare(*this, ssSelect.str()); } RepoTxnQuery query(txn, *this); query.bindInt64("@unitSn", ue.m_sn); do { query.step(); if (query.row()) { int funcSn; /**/ query.getInt(0, funcSn); Id preClassId; /**/ query.getId(1, preClassId); StringData* name; /**/ query.getStaticString(2, name); bool top; /**/ query.getBool(3, top); BlobDecoder extraBlob = /**/ query.getBlob(4); FuncEmitter* fe; if (preClassId < 0) { fe = ue.newFuncEmitter(name); } else { PreClassEmitter* pce = ue.pce(preClassId); fe = ue.newMethodEmitter(name, pce); bool added UNUSED = pce->addMethod(fe); assert(added); } assert(fe->sn() == funcSn); fe->top = top; fe->serdeMetaData(extraBlob); if (!SystemLib::s_inited && !fe->isPseudoMain()) { assert(fe->attrs & AttrBuiltin); if (preClassId < 0) { assert(fe->attrs & AttrPersistent); assert(fe->attrs & AttrUnique); assert(fe->attrs & AttrSkipFrame); } } fe->setEHTabIsSorted(); fe->finish(fe->past, true); ue.recordFunction(fe); } } while (!query.done()); txn.commit(); }
std::unique_ptr<UnitEmitter> createFatalUnit(StringData* filename, const MD5& md5, FatalOp /*op*/, StringData* err) { auto ue = std::make_unique<UnitEmitter>(md5); ue->m_filepath = filename; ue->initMain(1, 1); ue->emitOp(OpString); ue->emitInt32(ue->mergeLitstr(err)); ue->emitOp(OpFatal); ue->emitByte(static_cast<uint8_t>(FatalOp::Runtime)); FuncEmitter* fe = ue->getMain(); fe->maxStackCells = 1; // XXX line numbers are bogus fe->finish(ue->bcPos(), false); ue->recordFunction(fe); return ue; }