static IMG_VOID ImportUndefinedLabels(PUSEASM_CONTEXT psContext, IMG_PUINT32 puBaseInst) /***************************************************************************** FUNCTION : ImportUndefinedLabels PURPOSE : Check for undefined labels in the program. PARAMETERS : RETURNS : Nothing. *****************************************************************************/ { LABEL_CONTEXT* psLabelContext; IMG_UINT32 i; psLabelContext = (LABEL_CONTEXT*)psContext->pvLabelState; if (psLabelContext != NULL) { for (i = 0; i < psLabelContext->uLabelReferenceCount; i++) { IMG_UINT32 uOffset; uOffset = (psLabelContext->psLabelReferences[i].puOffset - puBaseInst) / 2; if (!UseAssemblerAddImportedLabel(psLabelContext->psLabelReferences[i].uLabel, psLabelContext->psLabelReferences[i].uOp, uOffset, psLabelContext->psLabelReferences[i].psInst->pszSourceFile, psLabelContext->psLabelReferences[i].psInst->uSourceLine, psLabelContext->psLabelReferences[i].bSyncEnd)) { IMG_PCHAR pcLabelName; pcLabelName = psContext->pfnGetLabelName(psContext->pvContext, psLabelContext->psLabelReferences[i].uLabel); AssemblerError(psContext->pvContext, psLabelContext->psLabelReferences[i].psInst, "Label '%s' is not defined", pcLabelName); } } } }
std::unique_ptr<UnitEmitter> compile( const char* filename, const MD5& md5, folly::StringPiece code, const Native::FuncTable& nativeFuncs, bool forDebuggerEval, AsmCallbacks* callbacks ) { if (!isRunning()) { start(); } std::string prog; std::unique_ptr<Unit> u; try { m_compilations++; StructuredLogEntry log; log.setStr("filename", filename); int64_t t = logTime(log, 0, nullptr, true); writeProgram(filename, md5, code, forDebuggerEval); t = logTime(log, t, "send_source"); prog = readResult(&log); t = logTime(log, t, "receive_hhas"); auto ue = assemble_string(prog.data(), prog.length(), filename, md5, nativeFuncs, false /* swallow errors */, callbacks ); logTime(log, t, "assemble_hhas"); if (RuntimeOption::EvalLogExternCompilerPerf) { StructuredLog::log("hhvm_detailed_frontend_performance", log); } return ue; } catch (CompileException& ex) { stop(); if (m_options.verboseErrors) { Logger::FError("ExternCompiler Error: {}", ex.what()); } throw; } catch (CompilerFatal& ex) { // this catch is here so we don't fall into the std::runtime_error one throw; } catch (FatalErrorException&) { // we want these to propagate out of the compiler throw; } catch (AssemblerUnserializationError& ex) { // This (probably) has nothing to do with the php/hhas, so don't do the // verbose error handling we have in the AssemblerError case. throw; } catch (AssemblerError& ex) { if (m_options.verboseErrors) { auto const msg = folly::sformat( "{}\n" "========== PHP Source ==========\n" "{}\n" "========== ExternCompiler Result ==========\n" "{}\n", ex.what(), code, prog); Logger::FError("ExternCompiler Generated a bad unit: {}", msg); // Throw the extended message to ensure the fataling unit contains the // additional context throw AssemblerError(msg); } throw; } catch (std::runtime_error& ex) { if (m_options.verboseErrors) { Logger::FError("ExternCompiler Runtime Error: {}", ex.what()); } throw; } }