void add_frame_variables(php::Func& func, const FuncEmitter& fe) { for (auto& param : fe.params) { func.params.push_back( php::Param { param.defaultValue, NoBlockId, param.typeConstraint, param.userType, param.phpCode, param.userAttributes, param.builtinType, param.byRef, param.byRef, param.variadic } ); } func.locals.reserve(fe.numLocals()); for (LocalId id = 0; id < fe.numLocals(); ++id) { func.locals.push_back({nullptr, id, false}); } for (auto& kv : fe.localNameMap()) { func.locals[kv.second].name = kv.first; } func.numIters = fe.numIterators(); func.staticLocals.reserve(fe.staticVars.size()); for (auto& sv : fe.staticVars) { func.staticLocals.push_back( php::StaticLocalInfo { sv.name, sv.phpCode } ); } }
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 add_frame_variables(php::Func& func, const FuncEmitter& fe) { for (auto& param : fe.params()) { func.params.push_back( php::Param { param.defaultValue(), nullptr, param.typeConstraint(), param.userType(), param.phpCode(), param.userAttributes(), param.builtinType(), param.ref(), param.isVariadic() } ); } func.locals.resize(fe.numLocals()); for (size_t id = 0; id < func.locals.size(); ++id) { auto& loc = func.locals[id]; loc = folly::make_unique<php::Local>(); loc->id = id; loc->name = nullptr; } for (auto& kv : fe.localNameMap()) { func.locals[kv.second]->name = kv.first; } func.iters.resize(fe.numIterators()); for (uint32_t i = 0; i < func.iters.size(); ++i) { func.iters[i] = folly::make_unique<php::Iter>(); func.iters[i]->id = i; } func.staticLocals.reserve(fe.svInfo().size()); for (auto& sv : fe.svInfo()) { func.staticLocals.push_back( php::StaticLocalInfo { sv.name, sv.phpCode } ); } }