Comparar commits
37 Commits
HHVM-2.3.3
...
HHVM-2.2
| Autor | SHA1 | Data | |
|---|---|---|---|
| 30b0fc0026 | |||
| 4f78c7de03 | |||
| d6a8578e34 | |||
| 085f510c23 | |||
| 1e1eac2a0e | |||
| 565465d580 | |||
| 38be2694ae | |||
| d87b7c84fb | |||
| a8b31881f6 | |||
| bd49a4ac26 | |||
| c33c344f99 | |||
| ec3d41f15f | |||
| afc63c1ab6 | |||
| b10c2021e2 | |||
| d04d9ec022 | |||
| 5a4db6875a | |||
| 251b5d78b4 | |||
| d2ca7292fb | |||
| ebb9f3cadd | |||
| b9d8d0ff47 | |||
| 73f16bc03b | |||
| 540cac6ec2 | |||
| c20fcce91b | |||
| 922a61dad5 | |||
| a568ad1a07 | |||
| 5815d21518 | |||
| 757c1414f5 | |||
| a1745fb58b | |||
| 20f0306dd3 | |||
| 8121dbb0d3 | |||
| 1177492d76 | |||
| 23cd8e033e | |||
| 6050afa844 | |||
| 98a2c6ede2 | |||
| e766a8a4ac | |||
| 5b7366968a | |||
| 2d963c4ffb |
@@ -21,7 +21,7 @@ CHECK_C_SOURCE_RUNS("#include <dlfcn.h>
|
||||
void testfunc() {}
|
||||
int main() {
|
||||
testfunc();
|
||||
return dyslm(0, "_testfunc") != (void*)0;
|
||||
return dyslm(0, \"_testfunc\") != (void*)0;
|
||||
}" LIBDL_NEEDS_UNDERSCORE)
|
||||
|
||||
mark_as_advanced(LIBDL_INCLUDE_DIRS LIBDL_LIBRARIES LIBDL_NEEDS_UNDERSCORE)
|
||||
|
||||
@@ -77,8 +77,29 @@ function(embed_systemlib TARGET DEST SOURCE)
|
||||
ARGS "--add-section" "systemlib=${SOURCE}" ${DEST}
|
||||
COMMENT "Embedding systemlib.php in ${TARGET}")
|
||||
endif()
|
||||
# Add the systemlib file to the "LINK_DEPENDS" for the systemlib, this will cause it
|
||||
# to be relinked and the systemlib re-embedded
|
||||
set_property(TARGET ${TARGET} APPEND PROPERTY LINK_DEPENDS ${SOURCE})
|
||||
endfunction(embed_systemlib)
|
||||
|
||||
# Custom install function that doesn't relink, instead it uses chrpath to change it, if
|
||||
# it's available, otherwise, it leaves the chrpath alone
|
||||
function(HHVM_INSTALL TARGET DEST)
|
||||
get_target_property(LOC ${TARGET} LOCATION)
|
||||
get_target_property(TY ${TARGET} TYPE)
|
||||
if (FOUND_CHRPATH)
|
||||
get_target_property(RPATH ${TARGET} INSTALL_RPATH)
|
||||
if (NOT RPATH STREQUAL "RPATH-NOTFOUND")
|
||||
if (RPATH STREQUAL "")
|
||||
install(CODE "execute_process(COMMAND \"${CHRPATH}\" \"-d\" \"${LOC}\" ERROR_QUIET)")
|
||||
else()
|
||||
install(CODE "execute_process(COMMAND \"${CHRPATH}\" \"-r\" \"${RPATH}\" \"${LOC}\" ERROR_QUIET)")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
install(CODE "FILE(INSTALL DESTINATION \"\${CMAKE_INSTALL_PREFIX}/${DEST}\" TYPE ${TY} FILES \"${LOC}\")")
|
||||
endfunction(HHVM_INSTALL)
|
||||
|
||||
function(HHVM_EXTENSION EXTNAME)
|
||||
list(REMOVE_AT ARGV 0)
|
||||
add_library(${EXTNAME} SHARED ${ARGV})
|
||||
|
||||
@@ -25,6 +25,15 @@ IF(NOT DEFINED CMAKE_PREFIX_PATH)
|
||||
message(STATUS "CMAKE_PREFIX_PATH was missing, proceeding anyway")
|
||||
endif()
|
||||
|
||||
# Look for the chrpath tool so we can warn if it's not there
|
||||
find_program(CHRPATH chrpath)
|
||||
IF (CHRPATH STREQUAL "CHRPATH-NOTFOUND")
|
||||
SET(FOUND_CHRPATH OFF)
|
||||
message(WARNING "chrpath not found, rpath will not be stripped from installed binaries")
|
||||
else()
|
||||
SET(FOUND_CHRPATH ON)
|
||||
endif()
|
||||
|
||||
LIST(APPEND CMAKE_PREFIX_PATH "$ENV{CMAKE_PREFIX_PATH}")
|
||||
|
||||
if(APPLE)
|
||||
|
||||
@@ -1994,12 +1994,6 @@ bool EmitterVisitor::visit(ConstructPtr node) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
void EmitterVisitor::emitFatal(Emitter& e, const char* message) {
|
||||
const StringData* msg = makeStaticString(message);
|
||||
e.String(msg);
|
||||
e.Fatal(0);
|
||||
}
|
||||
|
||||
bool EmitterVisitor::visitImpl(ConstructPtr node) {
|
||||
if (!node) return false;
|
||||
|
||||
@@ -2013,8 +2007,8 @@ bool EmitterVisitor::visitImpl(ConstructPtr node) {
|
||||
return false;
|
||||
|
||||
case Statement::KindOfTypedefStatement: {
|
||||
emitFatal(e, "Type statements are currently only allowed at "
|
||||
"the top-level");
|
||||
emitMakeUnitFatal(e, "Type statements are currently only allowed at "
|
||||
"the top-level");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -2029,8 +2023,7 @@ bool EmitterVisitor::visitImpl(ConstructPtr node) {
|
||||
if (bs->getDepth() > 1) {
|
||||
msg << "s";
|
||||
}
|
||||
e.String(makeStaticString(msg.str()));
|
||||
e.Fatal(0);
|
||||
emitMakeUnitFatal(e, msg.str().c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -3158,7 +3151,9 @@ bool EmitterVisitor::visitImpl(ConstructPtr node) {
|
||||
if (p->getScalarValue(v)) {
|
||||
assert(v.isString());
|
||||
StringData* msg = makeStaticString(v.toString());
|
||||
throw IncludeTimeFatalException(call, "%s", msg->data());
|
||||
auto exn = IncludeTimeFatalException(call, "%s", msg->data());
|
||||
exn.setParseFatal(call->isParseFatalFunction());
|
||||
throw exn;
|
||||
}
|
||||
not_reached();
|
||||
}
|
||||
@@ -4750,15 +4745,14 @@ void EmitterVisitor::emitUnset(Emitter& e,
|
||||
case StackSym::LG: e.CGetL(m_evalStack.getLoc(i)); // fall through
|
||||
case StackSym::CG: e.UnsetG(); break;
|
||||
case StackSym::LS: // fall through
|
||||
case StackSym::CS:
|
||||
case StackSym::CS: {
|
||||
assert(exp);
|
||||
e.String(
|
||||
makeStaticString("Attempt to unset static property " +
|
||||
exp->getText())
|
||||
);
|
||||
e.Fatal(0);
|
||||
break;
|
||||
|
||||
std::ostringstream s;
|
||||
s << "Attempt to unset static property " << exp->getText();
|
||||
emitMakeUnitFatal(e, s.str().c_str());
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
unexpectedStackSym(sym, "emitUnset");
|
||||
break;
|
||||
@@ -5879,10 +5873,10 @@ void EmitterVisitor::emitMethodPrologue(Emitter& e, MethodStatementPtr meth) {
|
||||
}
|
||||
|
||||
if (funcScope->isAbstract()) {
|
||||
StringData* msg = makeStaticString(
|
||||
"Cannot call abstract method " + meth->getOriginalFullName() + "()");
|
||||
e.String(msg);
|
||||
e.Fatal(1);
|
||||
std::ostringstream s;
|
||||
s << "Cannot call abstract method " << meth->getOriginalFullName() << "()";
|
||||
emitMakeUnitFatal(e, s.str().c_str(),
|
||||
FatalKind::Runtime, true /* skipFrame */);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7182,10 +7176,13 @@ void EmitterVisitor::emitRestoreErrorReporting(Emitter& e, Id oldLevelLoc) {
|
||||
dontRollback.set(e);
|
||||
}
|
||||
|
||||
void EmitterVisitor::emitMakeUnitFatal(Emitter& e, const std::string& msg) {
|
||||
StringData* sd = makeStaticString(msg);
|
||||
void EmitterVisitor::emitMakeUnitFatal(Emitter& e,
|
||||
const char* msg,
|
||||
FatalKind k /* = FatalKind::Runtime */,
|
||||
bool skipFrame /* = false */) {
|
||||
const StringData* sd = makeStaticString(msg);
|
||||
e.String(sd);
|
||||
e.Fatal(0);
|
||||
e.Fatal(uint8_t(k), uint8_t(skipFrame));
|
||||
}
|
||||
|
||||
void EmitterVisitor::addFunclet(Thunklet* body, Label* entry) {
|
||||
@@ -7453,7 +7450,8 @@ static UnitEmitter* emitHHBCUnitEmitter(AnalysisResultPtr ar, FileScopePtr fsp,
|
||||
EmitterVisitor fev(*ue);
|
||||
Emitter emitter(ex.m_node, *ue, fev);
|
||||
FuncFinisher ff(&fev, emitter, ue->getMain());
|
||||
fev.emitMakeUnitFatal(emitter, ex.getMessage());
|
||||
auto kind = ex.m_parseFatal ? FatalKind::Parse : FatalKind::Runtime;
|
||||
fev.emitMakeUnitFatal(emitter, ex.getMessage().c_str(), kind);
|
||||
}
|
||||
return ue;
|
||||
}
|
||||
@@ -7906,14 +7904,12 @@ static void batchCommit(std::vector<UnitEmitter*>& ues) {
|
||||
}
|
||||
|
||||
// Clean up.
|
||||
for (std::vector<UnitEmitter*>::const_iterator it = ues.begin();
|
||||
it != ues.end(); ++it) {
|
||||
UnitEmitter* ue = *it;
|
||||
// Commit units individually if an error occurred during batch commit.
|
||||
if (err) {
|
||||
repo.commitUnit(ue, UnitOrigin::File);
|
||||
}
|
||||
delete ue;
|
||||
for (auto ue : ues) {
|
||||
// Commit units individually if an error occurred during batch commit.
|
||||
if (err) {
|
||||
repo.commitUnit(ue, UnitOrigin::File);
|
||||
}
|
||||
delete ue;
|
||||
}
|
||||
ues.clear();
|
||||
}
|
||||
|
||||
@@ -374,12 +374,14 @@ public:
|
||||
class IncludeTimeFatalException : public Exception {
|
||||
public:
|
||||
ConstructPtr m_node;
|
||||
bool m_parseFatal;
|
||||
IncludeTimeFatalException(ConstructPtr node, const char* fmt, ...)
|
||||
: Exception(), m_node(node) {
|
||||
: Exception(), m_node(node), m_parseFatal(false) {
|
||||
va_list ap; va_start(ap, fmt); format(fmt, ap); va_end(ap);
|
||||
}
|
||||
virtual ~IncludeTimeFatalException() throw() {}
|
||||
EXCEPTION_COMMON_IMPL(IncludeTimeFatalException);
|
||||
void setParseFatal(bool b = true) { m_parseFatal = b; }
|
||||
};
|
||||
|
||||
void pushIterScope(Id id, IterKind kind) {
|
||||
@@ -513,9 +515,6 @@ private:
|
||||
int defI;
|
||||
};
|
||||
|
||||
private:
|
||||
void emitFatal(Emitter& e, const char* message);
|
||||
|
||||
private:
|
||||
static const size_t kMinStringSwitchCases = 8;
|
||||
UnitEmitter& m_ue;
|
||||
@@ -687,7 +686,10 @@ public:
|
||||
int vLocalId);
|
||||
void emitForeach(Emitter& e, ForEachStatementPtr fe);
|
||||
void emitRestoreErrorReporting(Emitter& e, Id oldLevelLoc);
|
||||
void emitMakeUnitFatal(Emitter& e, const std::string& message);
|
||||
void emitMakeUnitFatal(Emitter& e,
|
||||
const char* msg,
|
||||
FatalKind k = FatalKind::Runtime,
|
||||
bool skipFrame = false);
|
||||
|
||||
void addFunclet(Thunklet* body, Label* entry);
|
||||
void emitFunclets(Emitter& e);
|
||||
|
||||
@@ -73,8 +73,7 @@ FunctionScopePtr FileScope::setTree(AnalysisResultConstPtr ar,
|
||||
return createPseudoMain(ar);
|
||||
}
|
||||
|
||||
void FileScope::cleanupForError(AnalysisResultConstPtr ar,
|
||||
int line, const string &msg) {
|
||||
void FileScope::cleanupForError(AnalysisResultConstPtr ar) {
|
||||
for (StringToClassScopePtrVecMap::const_iterator iter = m_classes.begin();
|
||||
iter != m_classes.end(); ++iter) {
|
||||
BOOST_FOREACH(ClassScopePtr cls, iter->second) {
|
||||
@@ -90,8 +89,16 @@ void FileScope::cleanupForError(AnalysisResultConstPtr ar,
|
||||
StringToClassScopePtrVecMap().swap(m_classes);
|
||||
m_pseudoMain.reset();
|
||||
m_tree.reset();
|
||||
}
|
||||
|
||||
template <class Meth>
|
||||
void makeFatalMeth(FileScope& file,
|
||||
AnalysisResultConstPtr ar,
|
||||
const std::string& msg,
|
||||
int line,
|
||||
Meth meth) {
|
||||
LocationPtr loc(new Location());
|
||||
loc->file = m_fileName.c_str();
|
||||
loc->file = file.getName().c_str();
|
||||
loc->first(line, 0);
|
||||
loc->last(line, 0);
|
||||
BlockScopePtr scope;
|
||||
@@ -100,16 +107,30 @@ void FileScope::cleanupForError(AnalysisResultConstPtr ar,
|
||||
SimpleFunctionCallPtr e(
|
||||
new SimpleFunctionCall(scope, loc, "throw_fatal", false, args,
|
||||
ExpressionPtr()));
|
||||
e->setThrowFatal();
|
||||
meth(e);
|
||||
ExpStatementPtr exp(new ExpStatement(scope, loc, e));
|
||||
StatementListPtr stmts(new StatementList(scope, loc));
|
||||
stmts->addElement(exp);
|
||||
|
||||
FunctionScopePtr fs = setTree(ar, stmts);
|
||||
fs->setOuterScope(shared_from_this());
|
||||
FunctionScopePtr fs = file.setTree(ar, stmts);
|
||||
fs->setOuterScope(file.shared_from_this());
|
||||
fs->getStmt()->resetScope(fs);
|
||||
fs->getStmt()->setLocation(loc);
|
||||
setOuterScope(const_cast<AnalysisResult*>(ar.get())->shared_from_this());
|
||||
file.setOuterScope(const_cast<AnalysisResult*>(ar.get())->shared_from_this());
|
||||
}
|
||||
|
||||
void FileScope::makeFatal(AnalysisResultConstPtr ar,
|
||||
const std::string& msg,
|
||||
int line) {
|
||||
auto meth = [](SimpleFunctionCallPtr e) { e->setThrowFatal(); };
|
||||
makeFatalMeth(*this, ar, msg, line, meth);
|
||||
}
|
||||
|
||||
void FileScope::makeParseFatal(AnalysisResultConstPtr ar,
|
||||
const std::string& msg,
|
||||
int line) {
|
||||
auto meth = [](SimpleFunctionCallPtr e) { e->setThrowParseFatal(); };
|
||||
makeFatalMeth(*this, ar, msg, line, meth);
|
||||
}
|
||||
|
||||
bool FileScope::addFunction(AnalysisResultConstPtr ar,
|
||||
|
||||
@@ -107,8 +107,11 @@ public:
|
||||
* are the only functions a parser calls upon analysis results.
|
||||
*/
|
||||
FunctionScopePtr setTree(AnalysisResultConstPtr ar, StatementListPtr tree);
|
||||
void cleanupForError(AnalysisResultConstPtr ar,
|
||||
int line, const std::string &msg);
|
||||
void cleanupForError(AnalysisResultConstPtr ar);
|
||||
void makeFatal(AnalysisResultConstPtr ar,
|
||||
const std::string& msg, int line);
|
||||
void makeParseFatal(AnalysisResultConstPtr ar,
|
||||
const std::string& msg, int line);
|
||||
|
||||
bool addFunction(AnalysisResultConstPtr ar, FunctionScopePtr funcScope);
|
||||
bool addClass(AnalysisResultConstPtr ar, ClassScopePtr classScope);
|
||||
|
||||
@@ -42,7 +42,13 @@ public:
|
||||
void setValid() { m_valid = true; }
|
||||
void setFromCompiler() { m_fromCompiler = true; }
|
||||
void setThrowFatal() { m_type = FunType::ThrowFatal; }
|
||||
int isFatalFunction() const { return m_type == FunType::ThrowFatal; }
|
||||
void setThrowParseFatal() { m_type = FunType::ThrowParseFatal; }
|
||||
bool isParseFatalFunction() const {
|
||||
return m_type == FunType::ThrowParseFatal;
|
||||
}
|
||||
bool isFatalFunction() const {
|
||||
return isParseFatalFunction() || m_type == FunType::ThrowFatal;
|
||||
}
|
||||
int isStaticCompact() const { return m_type == FunType::StaticCompact; }
|
||||
|
||||
// define(<literal-string>, <scalar>);
|
||||
@@ -93,6 +99,7 @@ protected:
|
||||
GetDefinedVars,
|
||||
FBCallUserFuncSafe,
|
||||
ThrowFatal,
|
||||
ThrowParseFatal,
|
||||
ClassAlias,
|
||||
};
|
||||
|
||||
|
||||
@@ -96,7 +96,7 @@
|
||||
#ifdef yyerror
|
||||
#undef yyerror
|
||||
#endif
|
||||
#define yyerror(loc,p,msg) p->fatal(loc,msg)
|
||||
#define yyerror(loc,p,msg) p->parseFatal(loc,msg)
|
||||
|
||||
#ifdef YYLLOC_DEFAULT
|
||||
# undef YYLLOC_DEFAULT
|
||||
|
||||
@@ -174,10 +174,16 @@ bool Parser::parse() {
|
||||
"Parse error: %s",
|
||||
errString().c_str());
|
||||
}
|
||||
} catch (ParseTimeFatalException &e) {
|
||||
m_file->cleanupForError(m_ar, e.m_line, e.getMessage());
|
||||
return true;
|
||||
} catch (const ParseTimeFatalException& e) {
|
||||
m_file->cleanupForError(m_ar);
|
||||
if (e.m_parseFatal) {
|
||||
m_file->makeParseFatal(m_ar, e.getMessage(), e.m_line);
|
||||
} else {
|
||||
m_file->makeFatal(m_ar, e.getMessage(), e.m_line);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void Parser::error(const char* fmt, ...) {
|
||||
@@ -190,9 +196,16 @@ void Parser::error(const char* fmt, ...) {
|
||||
fatal(&m_loc, msg.c_str());
|
||||
}
|
||||
|
||||
void Parser::fatal(Location *loc, const char *msg) {
|
||||
throw ParseTimeFatalException(loc->file, loc->line0,
|
||||
"%s", msg);
|
||||
void Parser::parseFatal(const Location* loc, const char* msg) {
|
||||
// we can't use loc->file, as the bison parser doesn't track that in YYLTYPE
|
||||
auto file = m_file->getName().c_str();
|
||||
auto exn = ParseTimeFatalException(file, loc->line0, "%s", msg);
|
||||
exn.setParseFatal();
|
||||
throw exn;
|
||||
}
|
||||
|
||||
void Parser::fatal(const Location* loc, const char* msg) {
|
||||
throw ParseTimeFatalException(loc->file, loc->line0, "%s", msg);
|
||||
}
|
||||
|
||||
string Parser::errString() {
|
||||
|
||||
@@ -26,24 +26,26 @@
|
||||
#include "hphp/compiler/expression/scalar_expression.h"
|
||||
#include "hphp/compiler/statement/statement.h"
|
||||
#include "hphp/compiler/statement/statement_list.h"
|
||||
#include "hphp/util/logger.h"
|
||||
|
||||
#ifdef HPHP_PARSER_NS
|
||||
#undef HPHP_PARSER_NS
|
||||
#endif
|
||||
#define HPHP_PARSER_NS Compiler
|
||||
|
||||
#define LOG_PARSE_ERROR(file, line, fmt, args...) \
|
||||
HPHP::Logger::Error( \
|
||||
"HipHop Fatal error: " fmt " in %s on line %d", \
|
||||
##args, \
|
||||
(file), \
|
||||
(line) \
|
||||
)
|
||||
|
||||
#ifdef HPHP_PARSER_ERROR
|
||||
#undef HPHP_PARSER_ERROR
|
||||
#endif
|
||||
#define HPHP_PARSER_ERROR(fmt, p, args...) \
|
||||
do { \
|
||||
if (HPHP::Option::WholeProgram) { \
|
||||
HPHP::Logger::Error(fmt " %s", ##args, (p)->getMessage(true).c_str()); \
|
||||
} \
|
||||
throw HPHP::ParseTimeFatalException((p)->file(), (p)->line1(), \
|
||||
fmt, ##args); \
|
||||
} while (0)
|
||||
|
||||
#define HPHP_PARSER_ERROR(fmt, p, args...) \
|
||||
throw HPHP::ParseTimeFatalException((p)->file(), (p)->line1(), fmt, ##args)
|
||||
|
||||
namespace HPHP {
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
@@ -125,7 +127,8 @@ public:
|
||||
virtual bool enableFinallyStatement();
|
||||
IMPLEMENT_XHP_ATTRIBUTES;
|
||||
|
||||
virtual void fatal(Location *loc, const char *msg);
|
||||
virtual void fatal(const Location* loc, const char* msg);
|
||||
virtual void parseFatal(const Location* loc, const char* msg);
|
||||
std::string errString();
|
||||
|
||||
// result
|
||||
|
||||
@@ -1158,13 +1158,15 @@ Exit [C] -> [C:Null]
|
||||
set the exit status to 0, push null onto the stack, and then it will
|
||||
terminate execution.
|
||||
|
||||
Fatal <skip frame> [C] -> []
|
||||
Fatal <error kind> <skip frame> [C] -> []
|
||||
|
||||
Fatal. This instruction throws a fatal error using $1 as the error message.
|
||||
If $1 is not a string, this instruction throws a fatal error with an error
|
||||
message that indicates that the error message was not a string.
|
||||
Setting %1 to 0 will include the full backtrace.
|
||||
Setting %1 to 1 will make the backtrace not include the topmost frame. This
|
||||
Setting %1 to 0 will throw a runtime fatal error.
|
||||
Setting %1 to 1 will throw a parse fatal error.
|
||||
Setting %2 to 0 will include the full backtrace.
|
||||
Setting %2 to 1 will make the backtrace not include the topmost frame. This
|
||||
is useful when fatalling from functions that shouldn't be seen from userland.
|
||||
|
||||
|
||||
|
||||
@@ -7,4 +7,4 @@ target_link_libraries(hhvm ${HHVM_LINK_LIBRARIES})
|
||||
embed_systemlib(hhvm "${CMAKE_CURRENT_SOURCE_DIR}/hhvm" ${HPHP_HOME}/bin/systemlib.php)
|
||||
add_dependencies(hhvm systemlib)
|
||||
|
||||
install(TARGETS hhvm DESTINATION bin)
|
||||
HHVM_INSTALL(hhvm bin)
|
||||
|
||||
@@ -132,6 +132,17 @@ void ProcessInit() {
|
||||
|
||||
SystemLib::s_unit = compile_string(slib.c_str(), slib.size(),
|
||||
"systemlib.php");
|
||||
|
||||
const StringData* msg;
|
||||
int line;
|
||||
if (SystemLib::s_unit->compileTimeFatal(msg, line)) {
|
||||
Logger::Error("An error has been introduced into the systemlib, "
|
||||
"but we cannot give you a file and line number right now.");
|
||||
Logger::Error("Check all of your changes to hphp/system/php");
|
||||
Logger::Error("HipHop Parse Error: %s", msg->data());
|
||||
_exit(1);
|
||||
}
|
||||
|
||||
if (!hhas.empty()) {
|
||||
SystemLib::s_hhas_unit = compile_string(hhas.c_str(), hhas.size(),
|
||||
"systemlib.hhas");
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
#ifdef yyerror
|
||||
#undef yyerror
|
||||
#endif
|
||||
#define yyerror(loc,p,msg) p->fatal(loc,msg)
|
||||
#define yyerror(loc,p,msg) p->parseFatal(loc,msg)
|
||||
|
||||
#ifdef YYLLOC_DEFAULT
|
||||
# undef YYLLOC_DEFAULT
|
||||
|
||||
@@ -100,7 +100,8 @@ public:
|
||||
void setRuleLocation(Location *loc) {
|
||||
m_loc = *loc;
|
||||
}
|
||||
virtual void fatal(Location *loc, const char *msg) {}
|
||||
virtual void fatal(const Location* loc, const char* msg) {}
|
||||
virtual void parseFatal(const Location* loc, const char* msg) {}
|
||||
|
||||
void pushFuncLocation();
|
||||
LocationPtr popFuncLocation();
|
||||
|
||||
@@ -389,7 +389,12 @@ struct Parser : ParserBase {
|
||||
#define X(...)
|
||||
//#define X(...) traceCb(__FUNCTION__,## __VA_ARGS__)
|
||||
|
||||
void fatal(Location* loc, const char* msg) {
|
||||
void fatal(const Location* loc, const char* msg) {
|
||||
throw std::runtime_error(folly::format(
|
||||
"{}:{}: {}", m_fileName, m_loc.line0, msg).str());
|
||||
}
|
||||
|
||||
void parseFatal(const Location* loc, const char* msg) {
|
||||
throw std::runtime_error(folly::format(
|
||||
"{}:{}: {}", m_fileName, m_loc.line0, msg).str());
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ namespace HPHP {
|
||||
// ArrayInit
|
||||
|
||||
HOT_FUNC
|
||||
ArrayInit::ArrayInit(ssize_t n)
|
||||
ArrayInit::ArrayInit(size_t n)
|
||||
#ifdef DEBUG
|
||||
: m_addCount(0)
|
||||
, m_expectedCount(n)
|
||||
@@ -37,7 +37,7 @@ ArrayInit::ArrayInit(ssize_t n)
|
||||
}
|
||||
|
||||
HOT_FUNC
|
||||
ArrayInit::ArrayInit(ssize_t n, MapInit)
|
||||
ArrayInit::ArrayInit(size_t n, MapInit)
|
||||
: m_data(HphpArray::MakeReserve(n))
|
||||
#ifdef DEBUG
|
||||
, m_addCount(0)
|
||||
|
||||
@@ -27,9 +27,9 @@ namespace HPHP {
|
||||
struct ArrayInit {
|
||||
enum MapInit { mapInit };
|
||||
|
||||
explicit ArrayInit(ssize_t n);
|
||||
explicit ArrayInit(size_t n);
|
||||
|
||||
ArrayInit(ssize_t n, MapInit);
|
||||
ArrayInit(size_t n, MapInit);
|
||||
|
||||
ArrayInit(ArrayInit&& other)
|
||||
: m_data(other.m_data)
|
||||
|
||||
@@ -1198,6 +1198,11 @@ bool AutoloadHandler::autoloadType(const String& name) {
|
||||
*/
|
||||
bool AutoloadHandler::invokeHandler(const String& className,
|
||||
bool forceSplStack /* = false */) {
|
||||
|
||||
if (className.empty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!m_map.isNull()) {
|
||||
ClassExistsChecker ce;
|
||||
Result res = loadFromMap(className, s_class, true, ce);
|
||||
|
||||
@@ -24,16 +24,19 @@ int ExitException::ExitCode = 0;
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ExtendedException::ExtendedException() : Exception() {
|
||||
m_silent = false;
|
||||
computeBacktrace();
|
||||
}
|
||||
|
||||
ExtendedException::ExtendedException(const std::string &msg) {
|
||||
m_msg = msg;
|
||||
m_silent = false;
|
||||
computeBacktrace();
|
||||
}
|
||||
|
||||
ExtendedException::ExtendedException(SkipFrame, const std::string &msg) {
|
||||
m_msg = msg;
|
||||
m_silent = false;
|
||||
computeBacktrace(true);
|
||||
}
|
||||
|
||||
@@ -42,6 +45,7 @@ ExtendedException::ExtendedException(const char *fmt, ...) {
|
||||
va_start(ap, fmt);
|
||||
format(fmt, ap);
|
||||
va_end(ap);
|
||||
m_silent = false;
|
||||
computeBacktrace();
|
||||
}
|
||||
|
||||
|
||||
@@ -34,12 +34,16 @@ public:
|
||||
ExtendedException(SkipFrame frame, const std::string &msg);
|
||||
ExtendedException(const char *fmt, ...) ATTRIBUTE_PRINTF(2,3);
|
||||
Array getBackTrace() const;
|
||||
// a silent exception does not have its exception message logged
|
||||
bool isSilent() const { return m_silent; }
|
||||
void setSilent(bool s = true) { m_silent = s; }
|
||||
virtual ~ExtendedException() throw() {}
|
||||
EXCEPTION_COMMON_IMPL(ExtendedException);
|
||||
protected:
|
||||
ArrayHolder m_btp;
|
||||
private:
|
||||
void computeBacktrace(bool skipFrame = false);
|
||||
bool m_silent;
|
||||
};
|
||||
|
||||
class Assertion : public ExtendedException {
|
||||
@@ -140,8 +144,11 @@ public:
|
||||
virtual ~ParseTimeFatalException() throw() {}
|
||||
EXCEPTION_COMMON_IMPL(ParseTimeFatalException);
|
||||
|
||||
void setParseFatal(bool b = true) { m_parseFatal = b; }
|
||||
|
||||
std::string m_file;
|
||||
int m_line;
|
||||
bool m_parseFatal;
|
||||
};
|
||||
|
||||
class FatalErrorException : public ExtendedException {
|
||||
|
||||
@@ -550,10 +550,10 @@ void BaseExecutionContext::onShutdownPostSend() {
|
||||
bool BaseExecutionContext::errorNeedsHandling(int errnum,
|
||||
bool callUserHandler,
|
||||
ErrorThrowMode mode) {
|
||||
if (m_throwAllErrors) throw errnum;
|
||||
if (mode != ErrorThrowMode::Never ||
|
||||
(getErrorReportingLevel() & errnum) != 0 ||
|
||||
RuntimeOption::NoSilencer) {
|
||||
if (m_throwAllErrors) {
|
||||
throw errnum;
|
||||
}
|
||||
if (mode != ErrorThrowMode::Never || errorNeedsLogging(errnum)) {
|
||||
return true;
|
||||
}
|
||||
if (callUserHandler) {
|
||||
@@ -565,6 +565,10 @@ bool BaseExecutionContext::errorNeedsHandling(int errnum,
|
||||
return false;
|
||||
}
|
||||
|
||||
bool BaseExecutionContext::errorNeedsLogging(int errnum) {
|
||||
return RuntimeOption::NoSilencer || (getErrorReportingLevel() & errnum) != 0;
|
||||
}
|
||||
|
||||
class ErrorStateHelper {
|
||||
public:
|
||||
ErrorStateHelper(BaseExecutionContext *context,
|
||||
@@ -585,15 +589,15 @@ const StaticString
|
||||
s_file("file"),
|
||||
s_line("line");
|
||||
|
||||
void BaseExecutionContext::handleError(const std::string &msg,
|
||||
void BaseExecutionContext::handleError(const std::string& msg,
|
||||
int errnum,
|
||||
bool callUserHandler,
|
||||
ErrorThrowMode mode,
|
||||
const std::string &prefix,
|
||||
const std::string& prefix,
|
||||
bool skipFrame /* = false */) {
|
||||
SYNC_VM_REGS_SCOPED();
|
||||
|
||||
ErrorState newErrorState = ErrorState::ErrorRaised;
|
||||
auto newErrorState = ErrorState::ErrorRaised;
|
||||
switch (getErrorState()) {
|
||||
case ErrorState::ErrorRaised:
|
||||
case ErrorState::ErrorRaisedByUserHandler:
|
||||
@@ -604,12 +608,11 @@ void BaseExecutionContext::handleError(const std::string &msg,
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
ErrorStateHelper esh(this, newErrorState);
|
||||
ExtendedException ee = skipFrame ?
|
||||
auto const ee = skipFrame ?
|
||||
ExtendedException(ExtendedException::SkipFrame::skipFrame, msg) :
|
||||
ExtendedException(msg);
|
||||
Array bt = ee.getBackTrace();
|
||||
|
||||
recordLastError(ee, errnum);
|
||||
bool handled = false;
|
||||
if (callUserHandler) {
|
||||
@@ -618,22 +621,22 @@ void BaseExecutionContext::handleError(const std::string &msg,
|
||||
if (mode == ErrorThrowMode::Always ||
|
||||
(mode == ErrorThrowMode::IfUnhandled && !handled)) {
|
||||
DEBUGGER_ATTACHED_ONLY(phpDebuggerErrorHook(msg));
|
||||
throw FatalErrorException(msg, bt);
|
||||
auto exn = FatalErrorException(msg, ee.getBackTrace());
|
||||
exn.setSilent(!errorNeedsLogging(errnum));
|
||||
throw exn;
|
||||
}
|
||||
if (!handled &&
|
||||
(RuntimeOption::NoSilencer ||
|
||||
(getErrorReportingLevel() & errnum) != 0)) {
|
||||
DEBUGGER_ATTACHED_ONLY(phpDebuggerErrorHook(msg));
|
||||
if (!handled && errorNeedsLogging(errnum)) {
|
||||
DEBUGGER_ATTACHED_ONLY(phpDebuggerErrorHook(ee.getMessage()));
|
||||
String file = empty_string;
|
||||
int line = 0;
|
||||
if (RuntimeOption::InjectedStackTrace) {
|
||||
Array bt = ee.getBackTrace();
|
||||
if (!bt.empty()) {
|
||||
Array top = bt.rvalAt(0).toArray();
|
||||
if (top.exists(s_file)) file = top.rvalAt(s_file).toString();
|
||||
if (top.exists(s_line)) line = top.rvalAt(s_line).toInt64();
|
||||
}
|
||||
}
|
||||
|
||||
Logger::Log(Logger::LogError, prefix.c_str(), ee, file.c_str(), line);
|
||||
}
|
||||
}
|
||||
@@ -652,8 +655,7 @@ bool BaseExecutionContext::callUserErrorHandler(const Exception &e, int errnum,
|
||||
int errline = 0;
|
||||
String errfile;
|
||||
Array backtrace;
|
||||
const ExtendedException *ee = dynamic_cast<const ExtendedException*>(&e);
|
||||
if (ee) {
|
||||
if (auto const ee = dynamic_cast<const ExtendedException*>(&e)) {
|
||||
Array arr = ee->getBackTrace();
|
||||
if (!arr.isNull()) {
|
||||
backtrace = arr;
|
||||
@@ -690,9 +692,10 @@ bool BaseExecutionContext::onFatalError(const Exception &e) {
|
||||
recordLastError(e);
|
||||
String file = empty_string;
|
||||
int line = 0;
|
||||
bool silenced = false;
|
||||
if (RuntimeOption::InjectedStackTrace) {
|
||||
const ExtendedException *ee = dynamic_cast<const ExtendedException *>(&e);
|
||||
if (ee) {
|
||||
if (auto const ee = dynamic_cast<const ExtendedException *>(&e)) {
|
||||
silenced = ee->isSilent();
|
||||
Array bt = ee->getBackTrace();
|
||||
if (!bt.empty()) {
|
||||
Array top = bt.rvalAt(0).toArray();
|
||||
@@ -701,7 +704,8 @@ bool BaseExecutionContext::onFatalError(const Exception &e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (RuntimeOption::AlwaysLogUnhandledExceptions) {
|
||||
// need to silence even with the AlwaysLogUnhandledExceptions flag set
|
||||
if (!silenced && RuntimeOption::AlwaysLogUnhandledExceptions) {
|
||||
Logger::Log(Logger::LogError, "HipHop Fatal error: ", e,
|
||||
file.c_str(), line);
|
||||
}
|
||||
@@ -710,7 +714,7 @@ bool BaseExecutionContext::onFatalError(const Exception &e) {
|
||||
int errnum = static_cast<int>(ErrorConstants::ErrorModes::FATAL_ERROR);
|
||||
handled = callUserErrorHandler(e, errnum, true);
|
||||
}
|
||||
if (!handled && !RuntimeOption::AlwaysLogUnhandledExceptions) {
|
||||
if (!handled && !silenced && !RuntimeOption::AlwaysLogUnhandledExceptions) {
|
||||
Logger::Log(Logger::LogError, "HipHop Fatal error: ", e,
|
||||
file.c_str(), line);
|
||||
}
|
||||
|
||||
@@ -287,6 +287,7 @@ public:
|
||||
bool errorNeedsHandling(int errnum,
|
||||
bool callUserHandler,
|
||||
ErrorThrowMode mode);
|
||||
bool errorNeedsLogging(int errnum);
|
||||
void handleError(const std::string &msg,
|
||||
int errnum,
|
||||
bool callUserHandler,
|
||||
@@ -600,7 +601,8 @@ public:
|
||||
HPHP::Unit* unit = 0);
|
||||
bool evalUnit(HPHP::Unit* unit, PC& pc, int funcType);
|
||||
void invokeUnit(TypedValue* retval, HPHP::Unit* unit);
|
||||
HPHP::Unit* compileEvalString(StringData* code);
|
||||
HPHP::Unit* compileEvalString(StringData* code,
|
||||
const char* evalFilename = nullptr);
|
||||
const String& createFunction(const String& args, const String& code);
|
||||
bool evalPHPDebugger(TypedValue* retval, StringData *code, int frame);
|
||||
void enterDebuggerDummyEnv();
|
||||
@@ -633,7 +635,7 @@ public:
|
||||
VMParserFrame* parserFrame = nullptr,
|
||||
bool ignoreArgs = false,
|
||||
int limit = 0);
|
||||
VarEnv* getVarEnv();
|
||||
VarEnv* getVarEnv(int frame = 0);
|
||||
void setVar(StringData* name, TypedValue* v, bool ref);
|
||||
Array getLocalDefinedVariables(int frame);
|
||||
HPHP::PCFilter* m_breakPointFilter;
|
||||
|
||||
@@ -118,13 +118,22 @@ char *string_to_case(const char *s, int len, int (*tocase)(int));
|
||||
char *string_to_case_first(const char *s, int len, int (*tocase)(int));
|
||||
char *string_to_case_words(const char *s, int len, int (*tocase)(int));
|
||||
|
||||
#define string_to_upper(s,len) string_to_case((s), (len), toupper)
|
||||
#define string_to_upper_first(s, len) string_to_case_first((s), (len), toupper)
|
||||
#define string_to_upper_words(s, len) string_to_case_words((s), (len), toupper)
|
||||
// Use lambdas wrapping the ctype.h functions because of linker weirdness on
|
||||
// OS X Mavericks.
|
||||
|
||||
#define string_to_lower(s,len) string_to_case((s), (len), tolower)
|
||||
#define string_to_lower_first(s, len) string_to_case_first((s), (len), tolower)
|
||||
#define string_to_lower_words(s, len) string_to_case_words((s), (len), tolower)
|
||||
#define string_to_upper(s,len) \
|
||||
string_to_case((s), (len), [] (int i) -> int { return toupper(i); })
|
||||
#define string_to_upper_first(s, len) \
|
||||
string_to_case_first((s), (len), [] (int i) -> int { return toupper(i); })
|
||||
#define string_to_upper_words(s, len) \
|
||||
string_to_case_words((s), (len), [] (int i) -> int { return toupper(i); })
|
||||
|
||||
#define string_to_lower(s,len) \
|
||||
string_to_case((s), (len), [] (int i) -> int { return tolower(i); })
|
||||
#define string_to_lower_first(s, len) \
|
||||
string_to_case_first((s), (len), [] (int i) -> int { return tolower(i); })
|
||||
#define string_to_lower_words(s, len) \
|
||||
string_to_case_words((s), (len), [] (int i) -> int { return tolower(i); })
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@@ -210,8 +210,8 @@ extern void *MALLOC(size_t);
|
||||
|
||||
#if defined(IEEE_LITTLE_ENDIAN) + defined(IEEE_BIG_ENDIAN) + defined(VAX) + \
|
||||
defined(IBM) != 1
|
||||
Exactly one of IEEE_LITTLE_ENDIAN IEEE_BIG_ENDIAN, VAX, or
|
||||
IBM should be defined.
|
||||
#error Exactly one of IEEE_LITTLE_ENDIAN, IEEE_BIG_ENDIAN, VAX, or IBM \
|
||||
should be defined.
|
||||
#endif
|
||||
|
||||
typedef union {
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
#include "hphp/runtime/debugger/cmd/cmd_global.h"
|
||||
#include "hphp/runtime/debugger/cmd/cmd_variable.h"
|
||||
#include "hphp/runtime/base/hphp-system.h"
|
||||
|
||||
namespace HPHP { namespace Eval {
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
@@ -30,6 +31,7 @@ void CmdGlobal::sendImpl(DebuggerThriftBuffer &thrift) {
|
||||
void CmdGlobal::recvImpl(DebuggerThriftBuffer &thrift) {
|
||||
DebuggerCommand::recvImpl(thrift);
|
||||
thrift.read(m_globals);
|
||||
if (m_version == 1) m_version = 2;
|
||||
}
|
||||
|
||||
void CmdGlobal::help(DebuggerClient &client) {
|
||||
@@ -62,13 +64,22 @@ void CmdGlobal::onClient(DebuggerClient &client) {
|
||||
if (cmd->m_globals.empty()) {
|
||||
client.info("(no global variable was found)");
|
||||
} else {
|
||||
m_globals = cmd->m_globals;
|
||||
CmdVariable::PrintVariables(client, cmd->m_globals, true, text);
|
||||
CmdVariable::PrintVariables(client, cmd->m_globals, -1,
|
||||
text, cmd->m_version);
|
||||
}
|
||||
}
|
||||
|
||||
bool CmdGlobal::onServer(DebuggerProxy &proxy) {
|
||||
m_globals = CmdVariable::GetGlobalVariables();
|
||||
if (m_version == 2) {
|
||||
// Remove the values before sending to client.
|
||||
ArrayInit ret(m_globals->size());
|
||||
Variant v;
|
||||
for (ArrayIter iter(m_globals); iter; ++iter) {
|
||||
ret.add(iter.first().toString(), v);
|
||||
}
|
||||
m_globals = ret.toArray();
|
||||
}
|
||||
return proxy.sendToClient(this);
|
||||
}
|
||||
|
||||
|
||||
@@ -25,7 +25,9 @@ namespace HPHP { namespace Eval {
|
||||
DECLARE_BOOST_TYPES(CmdGlobal);
|
||||
class CmdGlobal : public DebuggerCommand {
|
||||
public:
|
||||
CmdGlobal() : DebuggerCommand(KindOfGlobal) {}
|
||||
CmdGlobal() : DebuggerCommand(KindOfGlobal) {
|
||||
m_version = 1;
|
||||
}
|
||||
|
||||
virtual void help(DebuggerClient &client);
|
||||
|
||||
|
||||
@@ -158,7 +158,7 @@ bool CmdList::listFileRange(DebuggerClient &client,
|
||||
const StaticString
|
||||
s_methods("methods"),
|
||||
s_file("file"),
|
||||
s_line1("line2"),
|
||||
s_line1("line1"),
|
||||
s_line2("line2");
|
||||
|
||||
// Sends an Info command to the server to retrieve source location
|
||||
@@ -278,6 +278,9 @@ void CmdList::onClient(DebuggerClient &client) {
|
||||
} else {
|
||||
if (!DebuggerClient::IsValidNumber(arg)) {
|
||||
if (m_file.empty()) {
|
||||
if (client.argCount() == 1 && listFunctionOrClass(client)) {
|
||||
return;
|
||||
}
|
||||
m_file = arg;
|
||||
m_line1 = 1;
|
||||
m_line2 = DebuggerClient::CodeBlockSize;
|
||||
@@ -320,12 +323,9 @@ void CmdList::onClient(DebuggerClient &client) {
|
||||
}
|
||||
}
|
||||
|
||||
if (listFileRange(client, line, charFocus0, lineFocus1, charFocus1)) {
|
||||
return;
|
||||
} else if (client.argCount() != 1 || !listFunctionOrClass(client)) {
|
||||
client.error(
|
||||
"Unable to read specified function, class or source file location.");
|
||||
return;
|
||||
if (!listFileRange(client, line, charFocus0, lineFocus1, charFocus1)) {
|
||||
client.error(
|
||||
"Unable to read specified function, class or source file location.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -350,7 +350,8 @@ bool CmdList::onServer(DebuggerProxy &proxy) {
|
||||
}
|
||||
}
|
||||
RuntimeOption::WarningFrequency = savedWarningFrequency;
|
||||
if (!m_code.toBoolean() && m_file == "systemlib.php") {
|
||||
if (!m_code.toBoolean() &&
|
||||
m_file.find("systemlib.php") == m_file.length() - 13) {
|
||||
m_code = SystemLib::s_source;
|
||||
}
|
||||
return proxy.sendToClient((DebuggerCommand*)this);
|
||||
|
||||
@@ -43,6 +43,8 @@ void CmdStep::onBeginInterrupt(DebuggerProxy &proxy, CmdInterrupt &interrupt) {
|
||||
// Step doesn't care about this interrupt... we just stay the course and
|
||||
// keep stepping.
|
||||
if (interrupt.getInterruptType() == ExceptionHandler) return;
|
||||
// Don't step into generated functions, keep looking.
|
||||
if (interrupt.getSite()->getLine0() == 0) return;
|
||||
m_complete = (decCount() == 0);
|
||||
if (!m_complete) {
|
||||
installLocationFilterForLine(interrupt.getSite());
|
||||
|
||||
@@ -31,6 +31,10 @@ void CmdVariable::sendImpl(DebuggerThriftBuffer &thrift) {
|
||||
thrift.write(sdata);
|
||||
}
|
||||
thrift.write(m_global);
|
||||
if (m_version == 2) {
|
||||
thrift.write(m_varName);
|
||||
thrift.write(m_filter);
|
||||
}
|
||||
}
|
||||
|
||||
void CmdVariable::recvImpl(DebuggerThriftBuffer &thrift) {
|
||||
@@ -39,13 +43,20 @@ void CmdVariable::recvImpl(DebuggerThriftBuffer &thrift) {
|
||||
{
|
||||
String sdata;
|
||||
thrift.read(sdata);
|
||||
if (DebuggerWireHelpers::WireUnserialize(sdata, m_variables) !=
|
||||
DebuggerWireHelpers::NoError) {
|
||||
auto error = DebuggerWireHelpers::WireUnserialize(sdata, m_variables);
|
||||
if (error != DebuggerWireHelpers::NoError) {
|
||||
m_variables = null_array;
|
||||
m_wireError = sdata;
|
||||
if (error != DebuggerWireHelpers::HitLimit || m_version == 0) {
|
||||
// Unexpected error. Log it.
|
||||
m_wireError = sdata;
|
||||
}
|
||||
}
|
||||
}
|
||||
thrift.read(m_global);
|
||||
if (m_version == 2) {
|
||||
thrift.read(m_varName);
|
||||
thrift.read(m_filter);
|
||||
}
|
||||
}
|
||||
|
||||
void CmdVariable::help(DebuggerClient &client) {
|
||||
@@ -72,6 +83,26 @@ void CmdVariable::PrintVariable(DebuggerClient &client, const String& varName) {
|
||||
auto charCount = client.getDebuggerClientShortPrintCharCount();
|
||||
cmd.m_frame = client.getFrame();
|
||||
CmdVariablePtr rcmd = client.xend<CmdVariable>(&cmd);
|
||||
if (rcmd->m_version == 2) {
|
||||
// Using the new protocol. rcmd contains a list of variables only.
|
||||
// Fetch value of varName only, so that we can recover nicely when its
|
||||
// value is too large to serialize.
|
||||
cmd.m_varName = varName;
|
||||
cmd.m_variables.reset();
|
||||
cmd.m_version = 2;
|
||||
rcmd = client.xend<CmdVariable>(&cmd);
|
||||
if (rcmd->m_variables.empty()) {
|
||||
// Perhaps the value is too large? See recvImpl.
|
||||
// Retry the command with version 1, in which case values are omitted.
|
||||
cmd.m_version = 1;
|
||||
rcmd = client.xend<CmdVariable>(&cmd);
|
||||
if (!rcmd->m_variables.empty()) {
|
||||
// It's there without values, and gone with values, so it is too large.
|
||||
client.output("...(omitted)");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!rcmd->m_variables.empty()) {
|
||||
for (ArrayIter iter(rcmd->m_variables); iter; ++iter) {
|
||||
String name = iter.first().toString();
|
||||
@@ -94,21 +125,61 @@ void CmdVariable::PrintVariable(DebuggerClient &client, const String& varName) {
|
||||
}
|
||||
|
||||
const StaticString s_http_response_header("http_response_header");
|
||||
const StaticString s_omitted("...(omitted)");
|
||||
|
||||
|
||||
void CmdVariable::PrintVariables(DebuggerClient &client, CArrRef variables,
|
||||
bool global, const String& text) {
|
||||
int frame, const String& text, int version) {
|
||||
bool global = frame == -1; // I.e. we were called from CmdGlobal, or the
|
||||
//client's current frame is the global frame, according to OnServer
|
||||
bool system = true;
|
||||
int i = 0;
|
||||
bool found = false;
|
||||
for (ArrayIter iter(variables); iter; ++iter) {
|
||||
String name = iter.first().toString();
|
||||
String value = DebuggerClient::FormatVariable(iter.second(), 200);
|
||||
if (!text.empty()) {
|
||||
String fullvalue = DebuggerClient::FormatVariable(iter.second(), -1);
|
||||
if (name.find(text, 0, false) >= 0 ||
|
||||
fullvalue.find(text, 0, false) >= 0) {
|
||||
String value;
|
||||
if (version == 2) {
|
||||
// Using the new protocol, so variables contain only names.
|
||||
// Fetch the value separately.
|
||||
CmdVariable cmd;
|
||||
cmd.m_frame = frame;
|
||||
cmd.m_variables = null_array;
|
||||
cmd.m_varName = name;
|
||||
cmd.m_filter = text;
|
||||
cmd.m_version = 2;
|
||||
auto rcmd = client.xend<CmdVariable>(&cmd);
|
||||
if (!rcmd->m_variables.empty()) {
|
||||
value = DebuggerClient::FormatVariable(rcmd->m_variables[name], 200);
|
||||
found = true;
|
||||
} else if (text.empty()) {
|
||||
// Not missing because filtered out, assume the value is too large.
|
||||
value = s_omitted;
|
||||
found = true;
|
||||
} else {
|
||||
if (name.find(text, 0, false) >= 0) {
|
||||
// Server should have matched it.
|
||||
// Assume missing because value is too large.
|
||||
value = s_omitted;
|
||||
found = true;
|
||||
} else {
|
||||
// The variable was filtered out on the server, using text.
|
||||
// Or it was just too large. Either way we let skip over it.
|
||||
continue;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
value = DebuggerClient::FormatVariable(iter.second(), 200);
|
||||
}
|
||||
if (version == 0 && !text.empty()) {
|
||||
if (name.find(text, 0, false) >= 0) {
|
||||
client.print("%s = %s", name.data(), value.data());
|
||||
found = true;
|
||||
} else {
|
||||
String fullvalue = DebuggerClient::FormatVariable(value, -1);
|
||||
if (fullvalue.find(text, 0, false) >= 0) {
|
||||
client.print("%s = %s", name.data(), value.data());
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (global && system) {
|
||||
@@ -117,7 +188,7 @@ void CmdVariable::PrintVariables(DebuggerClient &client, CArrRef variables,
|
||||
client.output("$%s = %s", name.data(), value.data());
|
||||
}
|
||||
|
||||
// we knew this is the last system global
|
||||
// we know s_http_response_header is the last system global
|
||||
if (global && name == s_http_response_header) {
|
||||
client.output("%s", "");
|
||||
system = false;
|
||||
@@ -153,8 +224,8 @@ void CmdVariable::onClient(DebuggerClient &client) {
|
||||
if (cmd->m_variables.empty()) {
|
||||
client.info("(no variable was defined)");
|
||||
} else {
|
||||
m_variables = cmd->m_variables;
|
||||
PrintVariables(client, cmd->m_variables, cmd->m_global, text);
|
||||
PrintVariables(client, cmd->m_variables, cmd->m_global ? -1 : m_frame,
|
||||
text, cmd->m_version);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -167,7 +238,48 @@ Array CmdVariable::GetGlobalVariables() {
|
||||
}
|
||||
|
||||
bool CmdVariable::onServer(DebuggerProxy &proxy) {
|
||||
m_variables = g_vmContext->getLocalDefinedVariables(m_frame);
|
||||
if (m_frame < 0) {
|
||||
m_variables = g_vmContext->m_globalVarEnv->getDefinedVariables();
|
||||
m_global = true;
|
||||
} else {
|
||||
m_variables = g_vmContext->getLocalDefinedVariables(m_frame);
|
||||
m_global = g_vmContext->getVarEnv(m_frame) == g_vmContext->m_globalVarEnv;
|
||||
}
|
||||
if (m_global) {
|
||||
m_variables.remove(s_GLOBALS);
|
||||
}
|
||||
if (m_version == 1) {
|
||||
// Remove the values before sending to client.
|
||||
ArrayInit ret(m_variables->size());
|
||||
Variant v;
|
||||
for (ArrayIter iter(m_variables); iter; ++iter) {
|
||||
ret.add(iter.first().toString(), v);
|
||||
}
|
||||
m_variables = ret.toArray();
|
||||
m_version = 2;
|
||||
} else if (m_version == 2) {
|
||||
// Remove entries that do not match a non empty m_varName.
|
||||
if (!m_varName.empty()) {
|
||||
ArrayInit ret(1);
|
||||
ret.add(m_varName, m_variables[m_varName]);
|
||||
m_variables = ret.toArray();
|
||||
}
|
||||
// Remove entries whose name or contents do not match a non empty m_filter
|
||||
if (!m_filter.empty()) {
|
||||
ArrayInit ret(1);
|
||||
for (ArrayIter iter(m_variables); iter; ++iter) {
|
||||
String name = iter.first().toString();
|
||||
if (name.find(m_filter, 0, false) < 0) {
|
||||
String fullvalue = DebuggerClient::FormatVariable(iter.second(), -1);
|
||||
if (fullvalue.find(m_filter, 0, false) < 0) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
ret.add(name, iter.second());
|
||||
}
|
||||
m_variables = ret.toArray();
|
||||
}
|
||||
}
|
||||
return proxy.sendToClient(this);
|
||||
}
|
||||
|
||||
|
||||
@@ -28,10 +28,14 @@ public:
|
||||
static Array GetGlobalVariables();
|
||||
static void PrintVariable(DebuggerClient &client, const String& varName);
|
||||
static void PrintVariables(DebuggerClient &client, CArrRef variables,
|
||||
bool global, const String& text);
|
||||
int frame, const String& text, int version);
|
||||
|
||||
public:
|
||||
CmdVariable() : DebuggerCommand(KindOfVariable) {}
|
||||
CmdVariable() : DebuggerCommand(KindOfVariable) {
|
||||
m_frame = 0;
|
||||
m_version = 1;
|
||||
m_global = false;
|
||||
}
|
||||
|
||||
virtual void help(DebuggerClient &client);
|
||||
|
||||
@@ -45,7 +49,9 @@ protected:
|
||||
private:
|
||||
int m_frame;
|
||||
Array m_variables;
|
||||
bool m_global;
|
||||
bool m_global; // Set true by onServer if it used g_vmContext->m_globalVarEnv
|
||||
String m_varName;
|
||||
String m_filter;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -490,6 +490,10 @@ static void object_set(Variant &var, const String& key, CVarRef value,
|
||||
|
||||
static void attach_zval(json_parser *json, const String& key,
|
||||
int assoc) {
|
||||
if (json->the_top < 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
Variant &root = json->the_zstack[json->the_top - 1];
|
||||
Variant &child = json->the_zstack[json->the_top];
|
||||
int up_mode = json->the_stack[json->the_top - 1];
|
||||
|
||||
@@ -1,3 +1,19 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| HipHop for PHP |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 2010-2013 Facebook, Inc. (http://www.facebook.com) |
|
||||
| Copyright (c) 1997-2010 The PHP Group |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to version 3.01 of the PHP license, |
|
||||
| that is bundled with this package in the file LICENSE, and is |
|
||||
| available through the world-wide-web at the following url: |
|
||||
| http://www.php.net/license/3_01.txt |
|
||||
| If you did not receive a copy of the PHP license and are unable to |
|
||||
| obtain it through the world-wide-web, please send a note to |
|
||||
| license@php.net so we can mail you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
#ifndef VARIANTCONTROLLER_H
|
||||
#define VARIANTCONTROLLER_H
|
||||
|
||||
|
||||
@@ -51,48 +51,51 @@ static bool ctype(CVarRef v, int (*iswhat)(int)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Use lambdas wrapping the ctype.h functions because of linker weirdness on
|
||||
// OS X Mavericks.
|
||||
|
||||
bool f_ctype_alnum(CVarRef text) {
|
||||
return ctype(text, isalnum);
|
||||
return ctype(text, [] (int i) -> int { return isalnum(i); });
|
||||
}
|
||||
|
||||
bool f_ctype_alpha(CVarRef text) {
|
||||
return ctype(text, isalpha);
|
||||
return ctype(text, [] (int i) -> int { return isalpha(i); });
|
||||
}
|
||||
|
||||
bool f_ctype_cntrl(CVarRef text) {
|
||||
return ctype(text, iscntrl);
|
||||
return ctype(text, [] (int i) -> int { return iscntrl(i); });
|
||||
}
|
||||
|
||||
bool f_ctype_digit(CVarRef text) {
|
||||
return ctype(text, isdigit);
|
||||
return ctype(text, [] (int i) -> int { return isdigit(i); });
|
||||
}
|
||||
|
||||
bool f_ctype_graph(CVarRef text) {
|
||||
return ctype(text, isgraph);
|
||||
return ctype(text, [] (int i) -> int { return isgraph(i); });
|
||||
}
|
||||
|
||||
bool f_ctype_lower(CVarRef text) {
|
||||
return ctype(text, islower);
|
||||
return ctype(text, [] (int i) -> int { return islower(i); });
|
||||
}
|
||||
|
||||
bool f_ctype_print(CVarRef text) {
|
||||
return ctype(text, isprint);
|
||||
return ctype(text, [] (int i) -> int { return isprint(i); });
|
||||
}
|
||||
|
||||
bool f_ctype_punct(CVarRef text) {
|
||||
return ctype(text, ispunct);
|
||||
return ctype(text, [] (int i) -> int { return ispunct(i); });
|
||||
}
|
||||
|
||||
bool f_ctype_space(CVarRef text) {
|
||||
return ctype(text, isspace);
|
||||
return ctype(text, [] (int i) -> int { return isspace(i); });
|
||||
}
|
||||
|
||||
bool f_ctype_upper(CVarRef text) {
|
||||
return ctype(text, isupper);
|
||||
return ctype(text, [] (int i) -> int { return isupper(i); });
|
||||
}
|
||||
|
||||
bool f_ctype_xdigit(CVarRef text) {
|
||||
return ctype(text, isxdigit);
|
||||
return ctype(text, [] (int i) -> int { return isxdigit(i); });
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -1162,9 +1162,8 @@ static void appendOrphan(XmlNodeSet &orphans, xmlNodePtr node) {
|
||||
}
|
||||
}
|
||||
|
||||
static void removeOrphan(XmlNodeSet &orphans, xmlNodePtr node) {
|
||||
static void removeOrphanIfNeeded(XmlNodeSet &orphans, xmlNodePtr node) {
|
||||
if (node) {
|
||||
assert(orphans.find(node) != orphans.end());
|
||||
orphans.erase(node);
|
||||
}
|
||||
}
|
||||
@@ -1954,6 +1953,7 @@ Variant c_DOMNode::t_appendchild(CObjRef newnode) {
|
||||
c_DOMNode *newdomnode = newnode.getTyped<c_DOMNode>();
|
||||
xmlNodePtr child = newdomnode->m_node;
|
||||
xmlNodePtr new_child = NULL;
|
||||
|
||||
if (dom_node_is_read_only(nodep) ||
|
||||
(child->parent != NULL && dom_node_is_read_only(child->parent))) {
|
||||
php_dom_throw_error(NO_MODIFICATION_ALLOWED_ERR, doc()->m_stricterror);
|
||||
@@ -2014,7 +2014,7 @@ Variant c_DOMNode::t_appendchild(CObjRef newnode) {
|
||||
}
|
||||
}
|
||||
if (newdomnode->doc().get()) {
|
||||
removeOrphan(*newdomnode->doc()->m_orphans, newdomnode->m_node);
|
||||
removeOrphanIfNeeded(*newdomnode->doc()->m_orphans, newdomnode->m_node);
|
||||
}
|
||||
dom_reconcile_ns(nodep->doc, new_child);
|
||||
return create_node_object(new_child, doc(), false);
|
||||
@@ -2094,6 +2094,7 @@ Variant c_DOMNode::t_insertbefore(CObjRef newnode,
|
||||
xmlNodePtr child = domchildnode->m_node;
|
||||
xmlNodePtr new_child = NULL;
|
||||
int stricterror = doc()->m_stricterror;
|
||||
|
||||
if (dom_node_is_read_only(parentp) ||
|
||||
(child->parent != NULL && dom_node_is_read_only(child->parent))) {
|
||||
php_dom_throw_error(NO_MODIFICATION_ALLOWED_ERR, stricterror);
|
||||
@@ -2207,7 +2208,7 @@ Variant c_DOMNode::t_insertbefore(CObjRef newnode,
|
||||
return false;
|
||||
}
|
||||
if (domchildnode->doc().get()) {
|
||||
removeOrphan(*domchildnode->doc()->m_orphans, domchildnode->m_node);
|
||||
removeOrphanIfNeeded(*domchildnode->doc()->m_orphans, domchildnode->m_node);
|
||||
}
|
||||
dom_reconcile_ns(parentp->doc, new_child);
|
||||
return create_node_object(new_child, doc(), false);
|
||||
|
||||
@@ -7111,6 +7111,8 @@ static int exif_process_IFD_in_TIFF(image_info_type *ImageInfo,
|
||||
}
|
||||
if (exif_file_sections_realloc(ImageInfo, sn, ifd_size)) {
|
||||
return 0;
|
||||
} else {
|
||||
end = (char*)ImageInfo->file.list[sn].data + dir_size;
|
||||
}
|
||||
/* read values not stored in directory itself */
|
||||
snData = ImageInfo->infile->read(ifd_size-dir_size);
|
||||
@@ -7175,8 +7177,8 @@ static int exif_process_IFD_in_TIFF(image_info_type *ImageInfo,
|
||||
}
|
||||
} else {
|
||||
if (!exif_process_IFD_TAG(ImageInfo, (char*)dir_entry,
|
||||
(char*)ImageInfo->file.list[sn].data + ifd_size,
|
||||
(char*)(ImageInfo->file.list[sn].data-dir_offset),
|
||||
(char*)(ImageInfo->file.list[sn].data + ifd_size),
|
||||
ifd_size, 0, section_index, 0, tag_table)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -991,10 +991,10 @@ Variant f_http_response_code(int response_code /* = 0 */) {
|
||||
|
||||
Array f_headers_list() {
|
||||
Transport *transport = g_context->getTransport();
|
||||
Array ret = Array::Create();
|
||||
if (transport) {
|
||||
HeaderMap headers;
|
||||
transport->getResponseHeaders(headers);
|
||||
Array ret;
|
||||
for (HeaderMap::const_iterator iter = headers.begin();
|
||||
iter != headers.end(); ++iter) {
|
||||
const vector<string> &values = iter->second;
|
||||
@@ -1002,9 +1002,8 @@ Array f_headers_list() {
|
||||
ret.append(String(iter->first + ": " + values[i]));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
return Array();
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool f_headers_sent(VRefParam file /* = null */, VRefParam line /* = null */) {
|
||||
|
||||
@@ -1231,7 +1231,7 @@ new_session:
|
||||
|
||||
/* Unconditionally destroy existing arrays -- possible dirty data */
|
||||
GlobalVariables *g = get_global_variables();
|
||||
g->add(s__SESSION, Array::Create(), false);
|
||||
g->set(s__SESSION, Array::Create(), false);
|
||||
|
||||
PS(invalid_session_id) = false;
|
||||
String value;
|
||||
|
||||
@@ -18,13 +18,14 @@
|
||||
#define incl_HPHP_ICU_MATCHER_H_
|
||||
|
||||
#include <boost/scoped_ptr.hpp>
|
||||
#include <unicode/regex.h>
|
||||
|
||||
// Avoid dragging in the icu namespace.
|
||||
#ifndef U_USING_ICU_NAMESPACE
|
||||
#define U_USING_ICU_NAMESPACE 0
|
||||
#endif
|
||||
|
||||
#include <unicode/regex.h>
|
||||
|
||||
namespace HPHP {
|
||||
// Wrapper class around icu::RegexMatcher that provides a default constructor
|
||||
// so that it can be used in thread-local storage.
|
||||
|
||||
@@ -18,13 +18,14 @@
|
||||
#define incl_HPHP_ICU_TRANSLITERATOR_H_
|
||||
|
||||
#include <boost/scoped_ptr.hpp>
|
||||
#include <unicode/translit.h>
|
||||
|
||||
// Avoid dragging in the icu namespace.
|
||||
#ifndef U_USING_ICU_NAMESPACE
|
||||
#define U_USING_ICU_NAMESPACE 0
|
||||
#endif
|
||||
|
||||
#include <unicode/translit.h>
|
||||
|
||||
namespace HPHP {
|
||||
// Wrapper class around icu::Transliterator that provides a default constructor
|
||||
// so that it can be used in thread-local storage.
|
||||
|
||||
@@ -22,13 +22,13 @@
|
||||
#include <vector>
|
||||
#include <boost/scoped_ptr.hpp>
|
||||
|
||||
#include <unicode/rbbi.h> // icu
|
||||
|
||||
// Avoid dragging in the icu namespace.
|
||||
#ifndef U_USING_ICU_NAMESPACE
|
||||
#define U_USING_ICU_NAMESPACE 0
|
||||
#endif
|
||||
|
||||
#include <unicode/rbbi.h> // icu
|
||||
|
||||
namespace HPHP {
|
||||
|
||||
typedef icu::RuleBasedBreakIterator BreakIterator;
|
||||
|
||||
@@ -919,8 +919,8 @@ bool PDOMySqlStatement::executer() {
|
||||
return false;
|
||||
}
|
||||
|
||||
my_ulonglong row_count = mysql_affected_rows(m_server);
|
||||
if (row_count == (my_ulonglong)-1) {
|
||||
my_ulonglong affected_count = mysql_affected_rows(m_server);
|
||||
if (affected_count == (my_ulonglong)-1) {
|
||||
/* we either have a query that returned a result set or an error occured
|
||||
lets see if we have access to a result set */
|
||||
if (!m_conn->buffered()) {
|
||||
@@ -938,6 +938,9 @@ bool PDOMySqlStatement::executer() {
|
||||
m_fields = mysql_fetch_fields(m_result);
|
||||
|
||||
}
|
||||
else {
|
||||
row_count = affected_count;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -99,6 +99,7 @@ const StaticString
|
||||
s__GET("_GET"),
|
||||
s__POST("_POST"),
|
||||
s__REQUEST("_REQUEST"),
|
||||
s__SESSION("_SESSION"),
|
||||
s__ENV("_ENV"),
|
||||
s__COOKIE("_COOKIE"),
|
||||
s_HTTP_RAW_POST_DATA("HTTP_RAW_POST_DATA"),
|
||||
@@ -127,6 +128,17 @@ const StaticString
|
||||
s_DOCUMENT_ROOT("DOCUMENT_ROOT"),
|
||||
s_THREAD_TYPE("THREAD_TYPE");
|
||||
|
||||
static auto const s_arraysToClear = {
|
||||
s__SERVER,
|
||||
s__GET,
|
||||
s__POST,
|
||||
s__FILES,
|
||||
s__REQUEST,
|
||||
s__SESSION,
|
||||
s__ENV,
|
||||
s__COOKIE,
|
||||
};
|
||||
|
||||
/**
|
||||
* PHP has "EGPCS" processing order of these global variables, and this
|
||||
* order is important in preparing $_REQUEST that needs to know which to
|
||||
@@ -135,9 +147,16 @@ const StaticString
|
||||
void HttpProtocol::PrepareSystemVariables(Transport *transport,
|
||||
const RequestURI &r,
|
||||
const SourceRootInfo &sri) {
|
||||
GlobalVariables *g = get_global_variables();
|
||||
const VirtualHost *vhost = VirtualHost::GetCurrent();
|
||||
|
||||
GlobalVariables* g = get_global_variables();
|
||||
Variant emptyArr(HphpArray::GetStaticEmptyArray());
|
||||
for (auto& key : s_arraysToClear) {
|
||||
g->remove(key.get(), false);
|
||||
g->set(key.get(), emptyArr, false);
|
||||
}
|
||||
g->set(s_HTTP_RAW_POST_DATA, empty_string, false);
|
||||
|
||||
Variant& server = g->getRef(s__SERVER);
|
||||
server.set(s_REQUEST_START_TIME, time(nullptr));
|
||||
|
||||
|
||||
@@ -285,14 +285,15 @@ void HttpServer::run() {
|
||||
if (m_stopReason) {
|
||||
Logger::Warning("Server stopping with reason: %s\n", m_stopReason);
|
||||
}
|
||||
removePid();
|
||||
Logger::Info("page server stopped");
|
||||
}
|
||||
|
||||
onServerShutdown(); // dangling server already started here
|
||||
time_t t0 = time(0);
|
||||
if (RuntimeOption::ServerPort) {
|
||||
m_pageServer->stop();
|
||||
m_pageServer->waitForJobs();
|
||||
removePid();
|
||||
m_pageServer->closePort();
|
||||
}
|
||||
time_t t1 = time(0);
|
||||
if (!m_danglings.empty() && RuntimeOption::ServerDanglingWait > 0) {
|
||||
@@ -472,14 +473,31 @@ bool HttpServer::startServer(bool pageServer) {
|
||||
|
||||
HttpClient http;
|
||||
string url = "http://";
|
||||
url += RuntimeOption::ServerIP;
|
||||
if (!RuntimeOption::ServerIP.empty()) {
|
||||
url += RuntimeOption::ServerIP;
|
||||
} else {
|
||||
url += "localhost";
|
||||
}
|
||||
url += ":";
|
||||
url += lexical_cast<string>(RuntimeOption::AdminServerPort);
|
||||
url += "/stop";
|
||||
StringBuffer response;
|
||||
http.get(url.c_str(), response);
|
||||
|
||||
sleep(1);
|
||||
if (!RuntimeOption::AdminPasswords.empty()) {
|
||||
for (auto it = RuntimeOption::AdminPasswords.begin();
|
||||
it != RuntimeOption::AdminPasswords.end();
|
||||
++it) {
|
||||
string passUrl = url + "?auth=" + *it;
|
||||
StringBuffer response;
|
||||
http.get(passUrl.c_str(), response);
|
||||
sleep(1);
|
||||
}
|
||||
} else {
|
||||
if (!RuntimeOption::AdminPassword.empty()) {
|
||||
url += "?auth=" + RuntimeOption::AdminPassword;
|
||||
}
|
||||
StringBuffer response;
|
||||
http.get(url.c_str(), response);
|
||||
sleep(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -136,8 +136,10 @@ int LibEventServer::getLibEventConnectionCount() {
|
||||
void LibEventServer::start() {
|
||||
if (getStatus() == RunStatus::RUNNING) return;
|
||||
|
||||
if (getAcceptSocket() != 0) {
|
||||
throw FailedToListenException(m_address, m_port);
|
||||
if (m_server != nullptr) {
|
||||
if (getAcceptSocket() != 0) {
|
||||
throw FailedToListenException(m_address, m_port);
|
||||
}
|
||||
}
|
||||
|
||||
if (m_server_ssl != nullptr && m_accept_sock_ssl != -2) {
|
||||
@@ -200,7 +202,7 @@ void LibEventServer::dispatch() {
|
||||
}
|
||||
}
|
||||
|
||||
void LibEventServer::stop() {
|
||||
void LibEventServer::waitForJobs() {
|
||||
Lock lock(m_mutex);
|
||||
if (getStatus() != RunStatus::RUNNING || m_server == nullptr) return;
|
||||
|
||||
@@ -249,11 +251,18 @@ void LibEventServer::stop() {
|
||||
// an error occured but we're in shutdown already, so ignore
|
||||
}
|
||||
m_dispatcherThread.waitForEnd();
|
||||
}
|
||||
|
||||
void LibEventServer::closePort() {
|
||||
evhttp_free(m_server);
|
||||
m_server = nullptr;
|
||||
}
|
||||
|
||||
void LibEventServer::stop() {
|
||||
waitForJobs();
|
||||
closePort();
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// SSL handling
|
||||
|
||||
|
||||
@@ -107,6 +107,8 @@ public:
|
||||
// implementing Server
|
||||
virtual void start();
|
||||
virtual void waitForEnd();
|
||||
virtual void waitForJobs();
|
||||
virtual void closePort();
|
||||
virtual void stop();
|
||||
virtual int getActiveWorker() {
|
||||
return m_dispatcher.getActiveWorker();
|
||||
|
||||
@@ -204,6 +204,16 @@ public:
|
||||
*/
|
||||
virtual void waitForEnd() = 0;
|
||||
|
||||
/*
|
||||
* Stop accepting new connections and finish ongoing requests.
|
||||
*/
|
||||
virtual void waitForJobs() = 0;
|
||||
|
||||
/*
|
||||
* Close the port this server is listening on.
|
||||
*/
|
||||
virtual void closePort() = 0;
|
||||
|
||||
/**
|
||||
* Gracefully stop this web server. We will stop accepting new connections
|
||||
* and finish ongoing requests without being interrupted in the middle of
|
||||
|
||||
@@ -118,6 +118,12 @@ void VirtualHost::initRuntimeOption(Hdf overwrite) {
|
||||
m_runtimeOption.requestTimeoutSeconds = requestTimeoutSeconds;
|
||||
m_runtimeOption.maxPostSize = maxPostSize;
|
||||
m_runtimeOption.uploadMaxFileSize = uploadMaxFileSize;
|
||||
|
||||
m_documentRoot = RuntimeOption::SourceRoot + m_pathTranslation;
|
||||
if (!m_documentRoot.empty() &&
|
||||
m_documentRoot[m_documentRoot.length() - 1] == '/') {
|
||||
m_documentRoot = m_documentRoot.substr(0, m_documentRoot.length() - 1);
|
||||
}
|
||||
}
|
||||
|
||||
void VirtualHost::addAllowedDirectories(const std::vector<std::string>& dirs) {
|
||||
@@ -150,7 +156,6 @@ void VirtualHost::init(Hdf vh) {
|
||||
const char *pattern = vh["Pattern"].get("");
|
||||
const char *pathTranslation = vh["PathTranslation"].get("");
|
||||
Hdf overwrite = vh["overwrite"];
|
||||
initRuntimeOption(overwrite);
|
||||
|
||||
if (prefix) m_prefix = prefix;
|
||||
if (pattern) {
|
||||
@@ -166,13 +171,9 @@ void VirtualHost::init(Hdf vh) {
|
||||
m_pathTranslation += '/';
|
||||
}
|
||||
}
|
||||
m_disabled = vh["Disabled"].getBool(false);
|
||||
initRuntimeOption(overwrite);
|
||||
|
||||
m_documentRoot = RuntimeOption::SourceRoot + m_pathTranslation;
|
||||
if (!m_documentRoot.empty() &&
|
||||
m_documentRoot[m_documentRoot.length() - 1] == '/') {
|
||||
m_documentRoot = m_documentRoot.substr(0, m_documentRoot.length() - 1);
|
||||
}
|
||||
m_disabled = vh["Disabled"].getBool(false);
|
||||
|
||||
Hdf rewriteRules = vh["RewriteRules"];
|
||||
for (Hdf hdf = rewriteRules.firstChild(); hdf.exists(); hdf = hdf.next()) {
|
||||
|
||||
@@ -1971,6 +1971,8 @@ UnitEmitter* assemble_string(const char*code, int codeLen,
|
||||
ue->emitOp(OpString);
|
||||
ue->emitInt32(ue->mergeLitstr(makeStaticString(e.what())));
|
||||
ue->emitOp(OpFatal);
|
||||
ue->emitByte(uint8_t(FatalKind::Runtime));
|
||||
ue->emitByte(false /* skipFrame */);
|
||||
FuncEmitter* fe = ue->getMain();
|
||||
fe->setMaxStackCells(kNumActRecCells + 1);
|
||||
// XXX line numbers are bogus
|
||||
|
||||
@@ -67,6 +67,7 @@
|
||||
#include "hphp/runtime/base/extended-logger.h"
|
||||
#include "hphp/runtime/base/tracer.h"
|
||||
#include "hphp/runtime/base/memory-profile.h"
|
||||
#include "hphp/runtime/base/runtime-error.h"
|
||||
|
||||
#include "hphp/system/systemlib.h"
|
||||
#include "hphp/runtime/ext/ext_collections.h"
|
||||
@@ -203,6 +204,7 @@ Transl::Translator* tx() {
|
||||
|
||||
#define DECODE_LA(var) DECODE_IVA(var)
|
||||
#define DECODE_IA(var) DECODE_IVA(var)
|
||||
#define DECODE_OA(var) DECODE(unsigned char, var)
|
||||
|
||||
#define DECODE_ITER_LIST(typeList, idList, vecLen) \
|
||||
DECODE(int32_t, vecLen); \
|
||||
@@ -1258,10 +1260,14 @@ Array VMExecutionContext::getCallerInfo() {
|
||||
return result;
|
||||
}
|
||||
|
||||
VarEnv* VMExecutionContext::getVarEnv() {
|
||||
VarEnv* VMExecutionContext::getVarEnv(int frame) {
|
||||
VMRegAnchor _;
|
||||
|
||||
ActRec* fp = getFP();
|
||||
for (; frame > 0; --frame) {
|
||||
if (!fp) break;
|
||||
fp = getPrevVMState(fp);
|
||||
}
|
||||
if (UNLIKELY(!fp)) return NULL;
|
||||
if (fp->skipFrame()) {
|
||||
fp = getPrevVMState(fp);
|
||||
@@ -2513,13 +2519,19 @@ typedef RankedCHM<StringData*, HPHP::Unit*,
|
||||
StringDataHashCompare,
|
||||
RankEvaledUnits> EvaledUnitsMap;
|
||||
static EvaledUnitsMap s_evaledUnits;
|
||||
Unit* VMExecutionContext::compileEvalString(StringData* code) {
|
||||
Unit* VMExecutionContext::compileEvalString(
|
||||
StringData* code,
|
||||
const char* evalFilename /* = nullptr */) {
|
||||
EvaledUnitsMap::accessor acc;
|
||||
// Promote this to a static string; otherwise it may get swept
|
||||
// across requests.
|
||||
code = makeStaticString(code);
|
||||
if (s_evaledUnits.insert(acc, code)) {
|
||||
acc->second = compile_string(code->data(), code->size());
|
||||
acc->second = compile_string(
|
||||
code->data(),
|
||||
code->size(),
|
||||
evalFilename
|
||||
);
|
||||
}
|
||||
return acc->second;
|
||||
}
|
||||
@@ -3951,7 +3963,8 @@ OPTBLD_INLINE void VMExecutionContext::iopFatal(PC& pc) {
|
||||
NEXT();
|
||||
TypedValue* top = m_stack.topTV();
|
||||
std::string msg;
|
||||
DECODE_IVA(skipFrame);
|
||||
DECODE_OA(kind_char);
|
||||
DECODE_OA(skipFrame);
|
||||
if (IS_STRING_TYPE(top->m_type)) {
|
||||
msg = top->m_data.pstr->data();
|
||||
} else {
|
||||
@@ -6301,9 +6314,32 @@ OPTBLD_INLINE void VMExecutionContext::iopEval(PC& pc) {
|
||||
Cell* c1 = m_stack.topC();
|
||||
String code(prepareKey(c1));
|
||||
String prefixedCode = concat("<?php ", code);
|
||||
Unit* unit = compileEvalString(prefixedCode.get());
|
||||
if (unit == nullptr) {
|
||||
raise_error("Syntax error in eval()");
|
||||
|
||||
auto evalFilename = std::string();
|
||||
Util::string_printf(
|
||||
evalFilename,
|
||||
"%s(%d) : eval()'d code",
|
||||
getContainingFileName().data(),
|
||||
getLine()
|
||||
);
|
||||
Unit* unit = compileEvalString(prefixedCode.get(), evalFilename.c_str());
|
||||
|
||||
const StringData* msg;
|
||||
int line = 0;
|
||||
|
||||
if (unit->parseFatal(msg, line)) {
|
||||
int errnum = static_cast<int>(ErrorConstants::ErrorModes::WARNING);
|
||||
if (errorNeedsLogging(errnum)) {
|
||||
// manual call to Logger instead of logError as we need to use
|
||||
// evalFileName and line as the exception doesn't track the eval()
|
||||
Logger::Error(
|
||||
"HipHop Fatal error: %s in %s on line %d",
|
||||
msg->data(),
|
||||
evalFilename.c_str(),
|
||||
line
|
||||
);
|
||||
}
|
||||
return;
|
||||
}
|
||||
m_stack.popC();
|
||||
evalUnit(unit, pc, EventHook::Eval);
|
||||
|
||||
@@ -45,6 +45,6 @@ extern int register_gdb_hook(char *symfile_addr,
|
||||
uint64_t symfile_size, DwarfChunk* d);
|
||||
extern void unregister_gdb_chunk(DwarfChunk* d);
|
||||
|
||||
extern void __jit_debug_register_code();
|
||||
extern "C" void __jit_debug_register_code();
|
||||
|
||||
#endif
|
||||
|
||||
@@ -14,6 +14,8 @@
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
#include "hphp/runtime/vm/debug/gdb-jit.h"
|
||||
|
||||
/* __jit_debug_regiser_code() needs to be defined in a separate file
|
||||
* from the one it is called from. Otherwise gcc notices that it is empty,
|
||||
* and optimizes away the call. This prevents gdb from trapping updates to
|
||||
|
||||
@@ -311,6 +311,8 @@ enum IterKind {
|
||||
KindOfCIter = 2,
|
||||
};
|
||||
|
||||
enum class FatalKind : uint8_t { Parse = 0, Runtime };
|
||||
|
||||
// Each of the setop ops maps to a binary bytecode op. We have reasons
|
||||
// for using distinct bitwise representations, though. This macro records
|
||||
// their correspondence for mapping either direction.
|
||||
@@ -404,7 +406,7 @@ enum SetOpOp {
|
||||
O(Print, NA, ONE(CV), ONE(CV), NF) \
|
||||
O(Clone, NA, ONE(CV), ONE(CV), NF) \
|
||||
O(Exit, NA, ONE(CV), ONE(CV), NF) \
|
||||
O(Fatal, ONE(IVA), ONE(CV), NOV, CF_TF) \
|
||||
O(Fatal, TWO(OA,OA), ONE(CV), NOV, CF_TF) \
|
||||
O(Jmp, ONE(BA), NOV, NOV, CF_TF) \
|
||||
O(JmpZ, ONE(BA), ONE(CV), NOV, CF) \
|
||||
O(JmpNZ, ONE(BA), ONE(CV), NOV, CF) \
|
||||
|
||||
@@ -373,7 +373,7 @@ void sinkIncRefs(IRTrace* trace, IRUnit& unit, DceState& state) {
|
||||
assert(state[inst].countConsumed());
|
||||
}
|
||||
}
|
||||
if (inst->op() == DecRefNZ) {
|
||||
if (inst->op() == DecRefNZ && !state[inst].isDead()) {
|
||||
IRInstruction* srcInst = inst->src(0)->inst();
|
||||
if (state[srcInst].isDead()) {
|
||||
state[inst].setDead();
|
||||
|
||||
@@ -3455,12 +3455,14 @@ bool isSupportedAGet(SSATmp* classSrc, const StringData* clsName) {
|
||||
}
|
||||
|
||||
void HhbcTranslator::emitAGet(SSATmp* classSrc, const StringData* clsName) {
|
||||
auto const catchBlock = makeCatch();
|
||||
|
||||
if (classSrc->isA(Type::Str)) {
|
||||
push(gen(LdCls, classSrc, cns(curClass())));
|
||||
push(gen(LdCls, catchBlock, classSrc, cns(curClass())));
|
||||
} else if (classSrc->isA(Type::Obj)) {
|
||||
push(gen(LdObjClass, classSrc));
|
||||
} else if (clsName) {
|
||||
push(gen(LdCls, cns(clsName), cns(curClass())));
|
||||
push(gen(LdCls, catchBlock, cns(clsName), cns(curClass())));
|
||||
} else {
|
||||
not_reached();
|
||||
}
|
||||
|
||||
@@ -313,6 +313,7 @@ RegionDescPtr selectTraceletLegacy(const RegionContext& rCtx,
|
||||
for (auto cni = callee.m_instrStream.first; cni; cni = cni->next) {
|
||||
assert(cSk == cni->source);
|
||||
assert(cni->op() == OpRetC ||
|
||||
cni->op() == OpRetV ||
|
||||
cni->op() == OpContRetC ||
|
||||
cni->op() == OpNativeImpl ||
|
||||
!instrIsNonCallControlFlow(cni->op()));
|
||||
|
||||
@@ -1,3 +1,18 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| HipHop for PHP |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 2010-2013 Facebook, Inc. (http://www.facebook.com) |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to version 3.01 of the PHP license, |
|
||||
| that is bundled with this package in the file LICENSE, and is |
|
||||
| available through the world-wide-web at the following url: |
|
||||
| http://www.php.net/license/3_01.txt |
|
||||
| If you did not receive a copy of the PHP license and are unable to |
|
||||
| obtain it through the world-wide-web, please send a note to |
|
||||
| license@php.net so we can mail you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
#include "hphp/vixl/a64/macro-assembler-a64.h"
|
||||
|
||||
|
||||
@@ -538,7 +538,7 @@ SSATmp* Simplifier::simplifyLdCls(IRInstruction* inst) {
|
||||
return cns(cls);
|
||||
}
|
||||
}
|
||||
return gen(LdClsCached, clsName);
|
||||
return gen(LdClsCached, inst->taken(), clsName);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -312,7 +312,8 @@ TCA TranslatorX64::retranslateOpt(TransID transId, bool align) {
|
||||
if (nTrans >= RuntimeOption::EvalJitMaxTranslations + 1) return nullptr;
|
||||
}
|
||||
|
||||
m_mode = TransOptimize;
|
||||
m_mode = TransLive;
|
||||
SCOPE_EXIT { m_mode = TransInvalid; };
|
||||
auto translArgs = TranslArgs(sk, align).transId(transId);
|
||||
if (setFuncBody) translArgs.setFuncBody();
|
||||
|
||||
@@ -1050,6 +1051,7 @@ void TranslatorX64::regeneratePrologue(TransID prologueTransId) {
|
||||
// Regenerate the prologue.
|
||||
func->resetPrologue(nArgs);
|
||||
m_mode = TransPrologue;
|
||||
SCOPE_EXIT { m_mode = TransInvalid; };
|
||||
TCA start = funcPrologue(func, nArgs);
|
||||
func->setPrologue(nArgs, start);
|
||||
|
||||
@@ -2343,7 +2345,16 @@ TranslatorX64::translateWork(const TranslArgs& args) {
|
||||
FTRACE(1, "trying irTranslateTracelet\n");
|
||||
assertCleanState();
|
||||
if (m_mode == TransOptimize) {
|
||||
m_mode = TransLive;
|
||||
if (sk.getFuncId() == liveFunc()->getFuncId() &&
|
||||
liveUnit()->contains(vmpc()) &&
|
||||
sk.offset() == liveUnit()->offsetOf(vmpc())) {
|
||||
m_mode = TransLive;
|
||||
tp = analyze(sk);
|
||||
} else {
|
||||
m_mode = TransInterp;
|
||||
traceFree();
|
||||
break;
|
||||
}
|
||||
}
|
||||
result = translateTracelet(t);
|
||||
|
||||
|
||||
@@ -1374,7 +1374,7 @@ bool outputIsPredicted(SrcKey startSk,
|
||||
assert(iInfo.out == Stack1 || inst.op() == OpSetM);
|
||||
auto dt = predictOutputs(startSk, &inst);
|
||||
if (dt != KindOfAny) {
|
||||
inst.outPred = Type(dt);
|
||||
inst.outPred = Type(dt, dt == KindOfRef ? KindOfAny : KindOfNone);
|
||||
} else {
|
||||
doPrediction = false;
|
||||
}
|
||||
|
||||
@@ -111,7 +111,7 @@
|
||||
#define HHVM_NAMED_STATIC_ME(cn,fn,mimpl) Native::registerBuiltinFunction(\
|
||||
makeStaticString(#cn "::" #fn), \
|
||||
mimpl)
|
||||
#define HHVM_STATIC_ME(cn,fn) HHVM_NAMED_STATIC_FE(cn,fn,HHVM_STATIC_MN(cn,fn))
|
||||
#define HHVM_STATIC_ME(cn,fn) HHVM_NAMED_STATIC_ME(cn,fn,HHVM_STATIC_MN(cn,fn))
|
||||
|
||||
namespace HPHP { namespace Native {
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -264,11 +264,13 @@ Unit* build_native_class_unit(const HhbcExtClassInfo* builtinClasses,
|
||||
return g_hphp_build_native_class_unit(builtinClasses, numBuiltinClasses);
|
||||
}
|
||||
|
||||
Unit* compile_string(const char* s, size_t sz, const char* fname) {
|
||||
Unit* compile_string(const char* s,
|
||||
size_t sz,
|
||||
const char* fname /* = nullptr */) {
|
||||
MD5 md5;
|
||||
int out_len;
|
||||
|
||||
char * md5str = string_md5(s, sz, false, out_len);
|
||||
char* md5str = string_md5(s, sz, false, out_len);
|
||||
md5 = MD5(md5str);
|
||||
free(md5str);
|
||||
|
||||
|
||||
@@ -64,7 +64,7 @@ public:
|
||||
* Soft type hints: triggers warning, but never fatals
|
||||
* E.g. "@int"
|
||||
*/
|
||||
Soft = 0x16,
|
||||
Soft = 0x10,
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
@@ -493,6 +493,20 @@ bool Unit::compileTimeFatal(const StringData*& msg, int& line) const {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Unit::parseFatal(const StringData*& msg, int& line) const {
|
||||
if (!compileTimeFatal(msg, line)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const Opcode* pc = getMain()->getEntry();
|
||||
|
||||
// two opcodes + String's ID
|
||||
pc += sizeof(Id) + 2;
|
||||
|
||||
auto kind_char = *pc;
|
||||
return kind_char == uint8_t(FatalKind::Parse);
|
||||
}
|
||||
|
||||
class FrameRestore {
|
||||
public:
|
||||
explicit FrameRestore(const PreClass* preClass) {
|
||||
|
||||
@@ -439,6 +439,9 @@ struct Unit {
|
||||
Offset offsetOf(const Op* op) const {
|
||||
return offsetOf(reinterpret_cast<const Opcode*>(op));
|
||||
}
|
||||
bool contains(const Opcode* op) const {
|
||||
return op >= m_bc && op <= m_bc + m_bclen;
|
||||
}
|
||||
|
||||
const StringData* filepath() const {
|
||||
assert(m_filepath);
|
||||
@@ -599,6 +602,7 @@ struct Unit {
|
||||
Attr typeAttrs);
|
||||
|
||||
bool compileTimeFatal(const StringData*& msg, int& line) const;
|
||||
bool parseFatal(const StringData*& msg, int& line) const;
|
||||
const TypedValue *getMainReturn() const {
|
||||
assert(isMergeOnly());
|
||||
return &m_mainReturn;
|
||||
|
||||
@@ -525,6 +525,17 @@ bool FuncChecker::checkImmediates(const char* name, const Op* instr) {
|
||||
case OpBareThis:
|
||||
if (op > 1) ok = false;
|
||||
break;
|
||||
case OpFatal:
|
||||
switch (static_cast<FatalKind>(op)) {
|
||||
default: {
|
||||
error("invalid error kind for Fatal: %d\n", op);
|
||||
ok = false;
|
||||
}
|
||||
case FatalKind::Parse:
|
||||
case FatalKind::Runtime:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}}
|
||||
|
||||
@@ -1805,7 +1805,7 @@
|
||||
},
|
||||
{
|
||||
"name": "HPHP_VERSION",
|
||||
"value": "2.1.0"
|
||||
"value": "2.2.0"
|
||||
},
|
||||
{
|
||||
"name": "HTML_ENTITIES",
|
||||
|
||||
@@ -885,6 +885,17 @@ function run_single_test_suite(string $fw_name, string $summary_file,
|
||||
"Establishing baseline with gray dots...\n", !$csv_only);
|
||||
}
|
||||
|
||||
/******************************
|
||||
* YII SPECIFIC
|
||||
******************************/
|
||||
if ($fw_name === "yii") {
|
||||
$files = glob($install_root."/tests/assets/*/CAssetManagerTest.php");
|
||||
foreach ($files as $file) {
|
||||
verbose("Removing $file\n", $verbose);
|
||||
unlink($file);
|
||||
}
|
||||
}
|
||||
|
||||
/*************************************
|
||||
* Run the test suite
|
||||
************************************/
|
||||
@@ -900,7 +911,15 @@ function run_single_test_suite(string $fw_name, string $summary_file,
|
||||
$process = proc_open($run_command, $descriptorspec, $pipes, $test_path, null);
|
||||
if (is_resource($process)) {
|
||||
fclose($pipes[0]);
|
||||
$r = array($pipes[1]);
|
||||
$w = null;
|
||||
$e = null;
|
||||
while (!(feof($pipes[1]))) {
|
||||
if (stream_select($r, $w, $e, $timeout) === false) {
|
||||
$error_information .= "TEST TIMEOUT OCCURRED.";
|
||||
$error_information .= " Last line read was: ".$line;
|
||||
break;
|
||||
}
|
||||
$line = fgets($pipes[1]);
|
||||
$line = preg_replace(PHPUnitPatterns::$color_escape_code_pattern,
|
||||
"", $line);
|
||||
|
||||
@@ -48,7 +48,7 @@
|
||||
.default_ctor;
|
||||
.method [public abstract] abs_method {
|
||||
String "Pure virtual method called"
|
||||
Fatal 1
|
||||
Fatal 1 1
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
|
||||
wtf:
|
||||
String "unknown property"
|
||||
Fatal 0
|
||||
Fatal 0 0
|
||||
}
|
||||
|
||||
.method [public] 86sinit(&$props) {
|
||||
|
||||
+42
-42
@@ -3,7 +3,7 @@ boolean(1) & integer(42) = integer(0)
|
||||
boolean(1) & double(24.1987) = integer(0)
|
||||
boolean(1) & string(str) = integer(0)
|
||||
boolean(1) & array(Array) = integer(1)
|
||||
HipHop Notice: Object of class c could not be converted to int
|
||||
HipHop Notice: Object of class c could not be converted to int in %s(%d) : eval()'d code on line %d
|
||||
boolean(1) & object(c) = integer(1)
|
||||
boolean(1) & NULL() = integer(0)
|
||||
integer(42) & boolean(1) = integer(0)
|
||||
@@ -11,7 +11,7 @@ integer(42) & integer(42) = integer(42)
|
||||
integer(42) & double(24.1987) = integer(8)
|
||||
integer(42) & string(str) = integer(0)
|
||||
integer(42) & array(Array) = integer(0)
|
||||
HipHop Notice: Object of class c could not be converted to int
|
||||
HipHop Notice: Object of class c could not be converted to int in %s(%d) : eval()'d code on line %d
|
||||
integer(42) & object(c) = integer(0)
|
||||
integer(42) & NULL() = integer(0)
|
||||
double(24.1987) & boolean(1) = integer(0)
|
||||
@@ -19,7 +19,7 @@ double(24.1987) & integer(42) = integer(8)
|
||||
double(24.1987) & double(24.1987) = integer(24)
|
||||
double(24.1987) & string(str) = integer(0)
|
||||
double(24.1987) & array(Array) = integer(0)
|
||||
HipHop Notice: Object of class c could not be converted to int
|
||||
HipHop Notice: Object of class c could not be converted to int in %s(%d) : eval()'d code on line %d
|
||||
double(24.1987) & object(c) = integer(0)
|
||||
double(24.1987) & NULL() = integer(0)
|
||||
string(str) & boolean(1) = integer(0)
|
||||
@@ -27,7 +27,7 @@ string(str) & integer(42) = integer(0)
|
||||
string(str) & double(24.1987) = integer(0)
|
||||
string(str) & string(str) = string(str)
|
||||
string(str) & array(Array) = integer(0)
|
||||
HipHop Notice: Object of class c could not be converted to int
|
||||
HipHop Notice: Object of class c could not be converted to int in %s(%d) : eval()'d code on line %d
|
||||
string(str) & object(c) = integer(0)
|
||||
string(str) & NULL() = integer(0)
|
||||
array(Array) & boolean(1) = integer(1)
|
||||
@@ -35,30 +35,30 @@ array(Array) & integer(42) = integer(0)
|
||||
array(Array) & double(24.1987) = integer(0)
|
||||
array(Array) & string(str) = integer(0)
|
||||
array(Array) & array(Array) = integer(1)
|
||||
HipHop Notice: Object of class c could not be converted to int
|
||||
HipHop Notice: Object of class c could not be converted to int in %s(%d) : eval()'d code on line %d
|
||||
array(Array) & object(c) = integer(1)
|
||||
array(Array) & NULL() = integer(0)
|
||||
HipHop Notice: Object of class c could not be converted to int
|
||||
HipHop Notice: Object of class c could not be converted to int in %s(%d) : eval()'d code on line %d
|
||||
object(c) & boolean(1) = integer(1)
|
||||
HipHop Notice: Object of class c could not be converted to int
|
||||
HipHop Notice: Object of class c could not be converted to int in %s(%d) : eval()'d code on line %d
|
||||
object(c) & integer(42) = integer(0)
|
||||
HipHop Notice: Object of class c could not be converted to int
|
||||
HipHop Notice: Object of class c could not be converted to int in %s(%d) : eval()'d code on line %d
|
||||
object(c) & double(24.1987) = integer(0)
|
||||
HipHop Notice: Object of class c could not be converted to int
|
||||
HipHop Notice: Object of class c could not be converted to int in %s(%d) : eval()'d code on line %d
|
||||
object(c) & string(str) = integer(0)
|
||||
HipHop Notice: Object of class c could not be converted to int
|
||||
HipHop Notice: Object of class c could not be converted to int in %s(%d) : eval()'d code on line %d
|
||||
object(c) & array(Array) = integer(1)
|
||||
HipHop Notice: Object of class c could not be converted to int
|
||||
HipHop Notice: Object of class c could not be converted to int
|
||||
HipHop Notice: Object of class c could not be converted to int in %s(%d) : eval()'d code on line %d
|
||||
HipHop Notice: Object of class c could not be converted to int in %s(%d) : eval()'d code on line %d
|
||||
object(c) & object(c) = integer(1)
|
||||
HipHop Notice: Object of class c could not be converted to int
|
||||
HipHop Notice: Object of class c could not be converted to int in %s(%d) : eval()'d code on line %d
|
||||
object(c) & NULL() = integer(0)
|
||||
NULL() & boolean(1) = integer(0)
|
||||
NULL() & integer(42) = integer(0)
|
||||
NULL() & double(24.1987) = integer(0)
|
||||
NULL() & string(str) = integer(0)
|
||||
NULL() & array(Array) = integer(0)
|
||||
HipHop Notice: Object of class c could not be converted to int
|
||||
HipHop Notice: Object of class c could not be converted to int in %s(%d) : eval()'d code on line %d
|
||||
NULL() & object(c) = integer(0)
|
||||
NULL() & NULL() = integer(0)
|
||||
boolean(1) ^ boolean(1) = integer(0)
|
||||
@@ -66,7 +66,7 @@ boolean(1) ^ integer(42) = integer(43)
|
||||
boolean(1) ^ double(24.1987) = integer(25)
|
||||
boolean(1) ^ string(str) = integer(1)
|
||||
boolean(1) ^ array(Array) = integer(0)
|
||||
HipHop Notice: Object of class c could not be converted to int
|
||||
HipHop Notice: Object of class c could not be converted to int in %s(%d) : eval()'d code on line %d
|
||||
boolean(1) ^ object(c) = integer(0)
|
||||
boolean(1) ^ NULL() = integer(1)
|
||||
integer(42) ^ boolean(1) = integer(43)
|
||||
@@ -74,7 +74,7 @@ integer(42) ^ integer(42) = integer(0)
|
||||
integer(42) ^ double(24.1987) = integer(50)
|
||||
integer(42) ^ string(str) = integer(42)
|
||||
integer(42) ^ array(Array) = integer(43)
|
||||
HipHop Notice: Object of class c could not be converted to int
|
||||
HipHop Notice: Object of class c could not be converted to int in %s(%d) : eval()'d code on line %d
|
||||
integer(42) ^ object(c) = integer(43)
|
||||
integer(42) ^ NULL() = integer(42)
|
||||
double(24.1987) ^ boolean(1) = integer(25)
|
||||
@@ -82,14 +82,14 @@ double(24.1987) ^ integer(42) = integer(50)
|
||||
double(24.1987) ^ double(24.1987) = integer(0)
|
||||
double(24.1987) ^ string(str) = integer(24)
|
||||
double(24.1987) ^ array(Array) = integer(25)
|
||||
HipHop Notice: Object of class c could not be converted to int
|
||||
HipHop Notice: Object of class c could not be converted to int in %s(%d) : eval()'d code on line %d
|
||||
double(24.1987) ^ object(c) = integer(25)
|
||||
double(24.1987) ^ NULL() = integer(24)
|
||||
string(str) ^ boolean(1) = integer(1)
|
||||
string(str) ^ integer(42) = integer(42)
|
||||
string(str) ^ double(24.1987) = integer(24)
|
||||
string(str) ^ string(str) = string(string(str) ^ array(Array) = integer(1)
|
||||
HipHop Notice: Object of class c could not be converted to int
|
||||
HipHop Notice: Object of class c could not be converted to int in %s(%d) : eval()'d code on line %d
|
||||
string(str) ^ object(c) = integer(1)
|
||||
string(str) ^ NULL() = integer(0)
|
||||
array(Array) ^ boolean(1) = integer(0)
|
||||
@@ -97,30 +97,30 @@ array(Array) ^ integer(42) = integer(43)
|
||||
array(Array) ^ double(24.1987) = integer(25)
|
||||
array(Array) ^ string(str) = integer(1)
|
||||
array(Array) ^ array(Array) = integer(0)
|
||||
HipHop Notice: Object of class c could not be converted to int
|
||||
HipHop Notice: Object of class c could not be converted to int in %s(%d) : eval()'d code on line %d
|
||||
array(Array) ^ object(c) = integer(0)
|
||||
array(Array) ^ NULL() = integer(1)
|
||||
HipHop Notice: Object of class c could not be converted to int
|
||||
HipHop Notice: Object of class c could not be converted to int in %s(%d) : eval()'d code on line %d
|
||||
object(c) ^ boolean(1) = integer(0)
|
||||
HipHop Notice: Object of class c could not be converted to int
|
||||
HipHop Notice: Object of class c could not be converted to int in %s(%d) : eval()'d code on line %d
|
||||
object(c) ^ integer(42) = integer(43)
|
||||
HipHop Notice: Object of class c could not be converted to int
|
||||
HipHop Notice: Object of class c could not be converted to int in %s(%d) : eval()'d code on line %d
|
||||
object(c) ^ double(24.1987) = integer(25)
|
||||
HipHop Notice: Object of class c could not be converted to int
|
||||
HipHop Notice: Object of class c could not be converted to int in %s(%d) : eval()'d code on line %d
|
||||
object(c) ^ string(str) = integer(1)
|
||||
HipHop Notice: Object of class c could not be converted to int
|
||||
HipHop Notice: Object of class c could not be converted to int in %s(%d) : eval()'d code on line %d
|
||||
object(c) ^ array(Array) = integer(0)
|
||||
HipHop Notice: Object of class c could not be converted to int
|
||||
HipHop Notice: Object of class c could not be converted to int
|
||||
HipHop Notice: Object of class c could not be converted to int in %s(%d) : eval()'d code on line %d
|
||||
HipHop Notice: Object of class c could not be converted to int in %s(%d) : eval()'d code on line %d
|
||||
object(c) ^ object(c) = integer(0)
|
||||
HipHop Notice: Object of class c could not be converted to int
|
||||
HipHop Notice: Object of class c could not be converted to int in %s(%d) : eval()'d code on line %d
|
||||
object(c) ^ NULL() = integer(1)
|
||||
NULL() ^ boolean(1) = integer(1)
|
||||
NULL() ^ integer(42) = integer(42)
|
||||
NULL() ^ double(24.1987) = integer(24)
|
||||
NULL() ^ string(str) = integer(0)
|
||||
NULL() ^ array(Array) = integer(1)
|
||||
HipHop Notice: Object of class c could not be converted to int
|
||||
HipHop Notice: Object of class c could not be converted to int in %s(%d) : eval()'d code on line %d
|
||||
NULL() ^ object(c) = integer(1)
|
||||
NULL() ^ NULL() = integer(0)
|
||||
boolean(1) | boolean(1) = integer(1)
|
||||
@@ -128,7 +128,7 @@ boolean(1) | integer(42) = integer(43)
|
||||
boolean(1) | double(24.1987) = integer(25)
|
||||
boolean(1) | string(str) = integer(1)
|
||||
boolean(1) | array(Array) = integer(1)
|
||||
HipHop Notice: Object of class c could not be converted to int
|
||||
HipHop Notice: Object of class c could not be converted to int in %s(%d) : eval()'d code on line %d
|
||||
boolean(1) | object(c) = integer(1)
|
||||
boolean(1) | NULL() = integer(1)
|
||||
integer(42) | boolean(1) = integer(43)
|
||||
@@ -136,7 +136,7 @@ integer(42) | integer(42) = integer(42)
|
||||
integer(42) | double(24.1987) = integer(58)
|
||||
integer(42) | string(str) = integer(42)
|
||||
integer(42) | array(Array) = integer(43)
|
||||
HipHop Notice: Object of class c could not be converted to int
|
||||
HipHop Notice: Object of class c could not be converted to int in %s(%d) : eval()'d code on line %d
|
||||
integer(42) | object(c) = integer(43)
|
||||
integer(42) | NULL() = integer(42)
|
||||
double(24.1987) | boolean(1) = integer(25)
|
||||
@@ -144,7 +144,7 @@ double(24.1987) | integer(42) = integer(58)
|
||||
double(24.1987) | double(24.1987) = integer(24)
|
||||
double(24.1987) | string(str) = integer(24)
|
||||
double(24.1987) | array(Array) = integer(25)
|
||||
HipHop Notice: Object of class c could not be converted to int
|
||||
HipHop Notice: Object of class c could not be converted to int in %s(%d) : eval()'d code on line %d
|
||||
double(24.1987) | object(c) = integer(25)
|
||||
double(24.1987) | NULL() = integer(24)
|
||||
string(str) | boolean(1) = integer(1)
|
||||
@@ -152,7 +152,7 @@ string(str) | integer(42) = integer(42)
|
||||
string(str) | double(24.1987) = integer(24)
|
||||
string(str) | string(str) = string(str)
|
||||
string(str) | array(Array) = integer(1)
|
||||
HipHop Notice: Object of class c could not be converted to int
|
||||
HipHop Notice: Object of class c could not be converted to int in %s(%d) : eval()'d code on line %d
|
||||
string(str) | object(c) = integer(1)
|
||||
string(str) | NULL() = integer(0)
|
||||
array(Array) | boolean(1) = integer(1)
|
||||
@@ -160,30 +160,30 @@ array(Array) | integer(42) = integer(43)
|
||||
array(Array) | double(24.1987) = integer(25)
|
||||
array(Array) | string(str) = integer(1)
|
||||
array(Array) | array(Array) = integer(1)
|
||||
HipHop Notice: Object of class c could not be converted to int
|
||||
HipHop Notice: Object of class c could not be converted to int in %s(%d) : eval()'d code on line %d
|
||||
array(Array) | object(c) = integer(1)
|
||||
array(Array) | NULL() = integer(1)
|
||||
HipHop Notice: Object of class c could not be converted to int
|
||||
HipHop Notice: Object of class c could not be converted to int in %s(%d) : eval()'d code on line %d
|
||||
object(c) | boolean(1) = integer(1)
|
||||
HipHop Notice: Object of class c could not be converted to int
|
||||
HipHop Notice: Object of class c could not be converted to int in %s(%d) : eval()'d code on line %d
|
||||
object(c) | integer(42) = integer(43)
|
||||
HipHop Notice: Object of class c could not be converted to int
|
||||
HipHop Notice: Object of class c could not be converted to int in %s(%d) : eval()'d code on line %d
|
||||
object(c) | double(24.1987) = integer(25)
|
||||
HipHop Notice: Object of class c could not be converted to int
|
||||
HipHop Notice: Object of class c could not be converted to int in %s(%d) : eval()'d code on line %d
|
||||
object(c) | string(str) = integer(1)
|
||||
HipHop Notice: Object of class c could not be converted to int
|
||||
HipHop Notice: Object of class c could not be converted to int in %s(%d) : eval()'d code on line %d
|
||||
object(c) | array(Array) = integer(1)
|
||||
HipHop Notice: Object of class c could not be converted to int
|
||||
HipHop Notice: Object of class c could not be converted to int
|
||||
HipHop Notice: Object of class c could not be converted to int in %s(%d) : eval()'d code on line %d
|
||||
HipHop Notice: Object of class c could not be converted to int in %s(%d) : eval()'d code on line %d
|
||||
object(c) | object(c) = integer(1)
|
||||
HipHop Notice: Object of class c could not be converted to int
|
||||
HipHop Notice: Object of class c could not be converted to int in %s(%d) : eval()'d code on line %d
|
||||
object(c) | NULL() = integer(1)
|
||||
NULL() | boolean(1) = integer(1)
|
||||
NULL() | integer(42) = integer(42)
|
||||
NULL() | double(24.1987) = integer(24)
|
||||
NULL() | string(str) = integer(0)
|
||||
NULL() | array(Array) = integer(1)
|
||||
HipHop Notice: Object of class c could not be converted to int
|
||||
HipHop Notice: Object of class c could not be converted to int in %s(%d) : eval()'d code on line %d
|
||||
NULL() | object(c) = integer(1)
|
||||
NULL() | NULL() = integer(0)
|
||||
int(0)
|
||||
@@ -46,14 +46,6 @@ Break at foo() on line 24 of %s/flow_gen.php
|
||||
24* $gen1->send($a);
|
||||
25 }
|
||||
|
||||
step
|
||||
Break at Continuation::send()
|
||||
step
|
||||
Break at Continuation::send()
|
||||
step
|
||||
Break at Continuation::send()
|
||||
step
|
||||
Break at Continuation::send()
|
||||
step
|
||||
Break at genFoo() on line 11 of %s/flow_gen.php
|
||||
10
|
||||
@@ -107,14 +99,6 @@ Break at foo() on line 24 of %s/flow_gen.php
|
||||
24* $gen1->send($a);
|
||||
25 }
|
||||
|
||||
step
|
||||
Break at Continuation::send()
|
||||
step
|
||||
Break at Continuation::send()
|
||||
step
|
||||
Break at Continuation::send()
|
||||
step
|
||||
Break at Continuation::send()
|
||||
step
|
||||
Break at genFoo() on line 11 of %s/flow_gen.php
|
||||
10
|
||||
|
||||
@@ -9,10 +9,6 @@ next
|
||||
next
|
||||
step
|
||||
step
|
||||
step
|
||||
step
|
||||
step
|
||||
step
|
||||
next
|
||||
next
|
||||
next
|
||||
@@ -21,10 +17,6 @@ next
|
||||
next
|
||||
step
|
||||
step
|
||||
step
|
||||
step
|
||||
step
|
||||
step
|
||||
next
|
||||
next
|
||||
next
|
||||
|
||||
@@ -2,3 +2,12 @@
|
||||
$h = new SplMaxHeap();
|
||||
$h->insert(1);
|
||||
|
||||
function myfunc($a, $b) {
|
||||
error_log($a.$b);
|
||||
}
|
||||
|
||||
class MyClass {
|
||||
function myMeth($a, $b) {
|
||||
error_log($a.$b);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,8 +3,57 @@ br SplMaxHeap::insert()
|
||||
Breakpoint 1 set upon entering SplMaxHeap::insert()
|
||||
run
|
||||
Breakpoint 1 reached at SplHeap::insert() on line %d of systemlib.php
|
||||
655 public function insert($value) {
|
||||
656* $this->checkNotCorrupted();
|
||||
657 $index = $this->lowestFreeIndex();
|
||||
%d public function insert($value) {
|
||||
%d* $this->checkNotCorrupted();
|
||||
%d $index = $this->lowestFreeIndex();
|
||||
|
||||
list myfunc
|
||||
5 function myfunc($a, $b) {
|
||||
6 error_log($a.$b);
|
||||
7 }
|
||||
8
|
||||
9 class MyClass {
|
||||
10 function myMeth($a, $b) {
|
||||
11 error_log($a.$b);
|
||||
12 }
|
||||
13 }
|
||||
14 (END)
|
||||
|
||||
list MyClass
|
||||
9 class MyClass {
|
||||
10 function myMeth($a, $b) {
|
||||
11 error_log($a.$b);
|
||||
12 }
|
||||
13 }
|
||||
14 (END)
|
||||
|
||||
list MyClass::myMeth
|
||||
10 function myMeth($a, $b) {
|
||||
11 error_log($a.$b);
|
||||
12 }
|
||||
13 }
|
||||
14 (END)
|
||||
|
||||
list 3
|
||||
1 <?php
|
||||
2 $h = new SplMaxHeap();
|
||||
3 $h->insert(1);
|
||||
4
|
||||
5 function myfunc($a, $b) {
|
||||
6 error_log($a.$b);
|
||||
7 }
|
||||
8
|
||||
9 class MyClass {
|
||||
10 function myMeth($a, $b) {
|
||||
11 error_log($a.$b);
|
||||
12 }
|
||||
|
||||
list noSuchFunc
|
||||
Unable to read specified function, class or source file location.
|
||||
list NoSuchClass
|
||||
Unable to read specified function, class or source file location.
|
||||
list MyClass::noSuchMethod
|
||||
Unable to read specified method.
|
||||
list noSuchFile:5
|
||||
Unable to read specified function, class or source file location.
|
||||
quit
|
||||
|
||||
@@ -1,3 +1,11 @@
|
||||
br SplMaxHeap::insert()
|
||||
run
|
||||
list myfunc
|
||||
list MyClass
|
||||
list MyClass::myMeth
|
||||
list 3
|
||||
list noSuchFunc
|
||||
list NoSuchClass
|
||||
list MyClass::noSuchMethod
|
||||
list noSuchFile:5
|
||||
quit
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
HipHop Warning: Argument 1 to foo() must be of type @?Bar, Foo given in %s on line 10
|
||||
HipHop Warning: Argument 1 to foo() must be of type ?Bar, Foo given in %s on line 10
|
||||
HipHop Fatal error: Call to undefined method Foo::frob from anonymous context in %s on line 8
|
||||
|
||||
@@ -1 +1 @@
|
||||
HipHop Warning: Argument 1 to foo() must be of type @?xhp_url, array given in %s on line 7
|
||||
HipHop Warning: Argument 1 to foo() must be of type ?xhp_url, array given in %s on line 7
|
||||
|
||||
@@ -1 +1 @@
|
||||
HipHop Warning: Argument 1 to foo() must be of type @?array, stdClass given in %s on line 3
|
||||
HipHop Warning: Argument 1 to foo() must be of type ?array, stdClass given in %s on line 3
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
|
||||
spl_autoload_register(function($class) {
|
||||
var_dump($class);
|
||||
});
|
||||
|
||||
var_dump(method_exists('', 'foo'));
|
||||
@@ -0,0 +1 @@
|
||||
bool(false)
|
||||
@@ -0,0 +1,42 @@
|
||||
Eval {
|
||||
EnableXHP = true
|
||||
AllowHhas = true
|
||||
EnableHipHopSyntax = true
|
||||
EnableObjDestructCall = true
|
||||
JitASize = 10485760 # 10 MB
|
||||
JitAStubsSize = 10485760 # 10 MB
|
||||
JitGlobalDataSize = 2097152 # 2 MB
|
||||
Debugger {
|
||||
EnableDebugger = true
|
||||
EnableDebuggerColor = false
|
||||
EnableDebuggerPrompt = false
|
||||
}
|
||||
}
|
||||
|
||||
Repo {
|
||||
Eval.Mode = readonly
|
||||
Commit = true
|
||||
DebugInfo = true
|
||||
}
|
||||
|
||||
MySQL {
|
||||
ReadTimeout = 5000
|
||||
}
|
||||
|
||||
EnvVariables {
|
||||
HPHP_INTERPRETER = 1
|
||||
}
|
||||
|
||||
ServerVariables {
|
||||
ALPHA_CONSOLE = 1
|
||||
TFBENV = 16777216
|
||||
}
|
||||
|
||||
ErrorHandling {
|
||||
NoticeFrequency = 1
|
||||
WarningFrequency = 1
|
||||
}
|
||||
|
||||
ResourceLimit {
|
||||
SerializationSizeLimit=134217728
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
UTF8 = 1
|
||||
Color = 0
|
||||
Tutorial = -1
|
||||
MaxCodeLines = -1
|
||||
NeverSaveConfig = 1;
|
||||
PrintLevel = 3;
|
||||
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
|
||||
function foo() {
|
||||
$a = array_fill(0, 5000000, "abcdefghijklmn");
|
||||
}
|
||||
|
||||
foo();
|
||||
@@ -0,0 +1,34 @@
|
||||
Program %s/variables.php loaded. Type '[r]un' or '[c]ontinue' to go.
|
||||
break variables.php:5
|
||||
Breakpoint 1 set on line 5 of variables.php
|
||||
But wont break until file variables.php has been loaded.
|
||||
continue
|
||||
Breakpoint 1 reached at foo() on line 5 of %s/variables.php
|
||||
4 $a = array_fill(0, 5000000, "abcdefghijklmn");
|
||||
5*}
|
||||
6
|
||||
|
||||
variable
|
||||
$a = ...(omitted)
|
||||
=$a
|
||||
...(omitted)
|
||||
variable
|
||||
$_ = ...(omitted)
|
||||
$a = ...(omitted)
|
||||
=count($a)
|
||||
5000000
|
||||
variable
|
||||
$_ = 5000000
|
||||
$a = ...(omitted)
|
||||
continue
|
||||
Program %s/variables.php exited normally.
|
||||
$xyzklj = array_fill(0, 5000000, "abcdefghijklmn");
|
||||
=$xyzklj
|
||||
...(omitted)
|
||||
variable xyzklj
|
||||
$xyzklj = ...(omitted)
|
||||
=count($xyzklj)
|
||||
5000000
|
||||
global xyzklj
|
||||
$xyzklj = ...(omitted)
|
||||
quit
|
||||
@@ -0,0 +1,13 @@
|
||||
break variables.php:5
|
||||
continue
|
||||
variable
|
||||
=$a
|
||||
variable
|
||||
=count($a)
|
||||
variable
|
||||
continue
|
||||
$xyzklj = array_fill(0, 5000000, "abcdefghijklmn");
|
||||
=$xyzklj
|
||||
variable xyzklj
|
||||
=count($xyzklj)
|
||||
global xyzklj
|
||||
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
$doc = new DOMDocument;
|
||||
|
||||
$node1 = $doc->createElement('div');
|
||||
|
||||
$res1 = $doc->appendChild($node1);
|
||||
$res2 = $doc->appendChild($res1);
|
||||
|
||||
#var_dump($res1);
|
||||
#var_dump($res2);
|
||||
|
||||
var_dump($doc->saveXML());
|
||||
@@ -0,0 +1,3 @@
|
||||
string(29) "<?xml version="1.0"?>
|
||||
<div/>
|
||||
"
|
||||
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
$doc = new DOMDocument;
|
||||
|
||||
$node1 = $doc->createElement('div');
|
||||
$node2 = $doc->createElement('div');
|
||||
|
||||
$res1 = $doc->appendChild($node1);
|
||||
$res2 = $doc->insertBefore($node2, $res1);
|
||||
$res3 = $doc->insertBefore($node1, $node2);
|
||||
|
||||
var_dump($doc->saveXML());
|
||||
@@ -0,0 +1,4 @@
|
||||
string(36) "<?xml version="1.0"?>
|
||||
<div/>
|
||||
<div/>
|
||||
"
|
||||
@@ -0,0 +1,5 @@
|
||||
<?php
|
||||
|
||||
print "Before error\n";
|
||||
eval('blah();');
|
||||
print "After error, this should not show!\n";
|
||||
@@ -0,0 +1,2 @@
|
||||
Before error
|
||||
HipHop Fatal error: Undefined function: blah in %s(%d) : eval()'d code on line %d
|
||||
@@ -0,0 +1,5 @@
|
||||
<?php
|
||||
|
||||
echo "Before error, there should be an 'After error'\n";
|
||||
eval("invalid");
|
||||
echo "After error\n";
|
||||
@@ -0,0 +1,3 @@
|
||||
Before error, there should be an 'After error'
|
||||
HipHop Fatal error: syntax error, unexpected $end in %s(%d) : eval()'d code on line %d
|
||||
After error
|
||||
@@ -0,0 +1,5 @@
|
||||
<?php
|
||||
|
||||
print "Before silenced error\n";
|
||||
@blah();
|
||||
print "After silenced error, this should not show!\n";
|
||||
@@ -0,0 +1 @@
|
||||
Before silenced error
|
||||
@@ -0,0 +1,5 @@
|
||||
<?php
|
||||
|
||||
echo "Before error, there should be an 'After error'\n";
|
||||
@eval("invalid");
|
||||
echo "After error\n";
|
||||
@@ -0,0 +1,2 @@
|
||||
Before error, there should be an 'After error'
|
||||
After error
|
||||
Arquivo binário não exibido.
Alguns arquivos não foram exibidos porque demasiados arquivos foram alterados neste diff Mostrar Mais
Referência em uma Nova Issue
Bloquear um usuário