/* +----------------------------------------------------------------------+ | HipHop for PHP | +----------------------------------------------------------------------+ | Copyright (c) 2010- 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 #include #include #include #include #include #include #include #include #include #include #include #include using std::istringstream; using std::ostringstream; /////////////////////////////////////////////////////////////////////////////// const char *TestCodeRun::Filter = 0; // By default, use shared linking for faster testing. bool TestCodeRun::FastMode = true; TestCodeRun::TestCodeRun() : m_perfMode(false), m_test(0) { Option::GenerateCPPMain = true; Option::GenerateCPPMetaInfo = true; Option::GenerateCPPMacros = true; Option::GenerateCPPComments = true; Option::GenerateCPPNameSpace = true; Option::KeepStatementsWithNoEffect = false; Option::ParserThreadCount = 4; } bool TestCodeRun::preTest() { if (!CleanUp()) return false; m_infos.clear(); return true; } bool TestCodeRun::postTest() { if (!MultiVerifyCodeRun()) return false; return true; } bool TestCodeRun::CleanUp() { string out, err; const char *argv[] = {"", NULL}; Process::Exec("runtime/tmp/cleanup.sh", argv, NULL, out, &err); if (!err.empty()) { printf("Failed to clean up runtime/tmp: %s\n", err.c_str()); return false; } return true; } static bool GenerateMainPHP(const std::string &fullPath, const char *file, int line, const char *input) { Util::mkdir(fullPath.c_str()); std::ofstream f(fullPath.c_str()); if (!f) { printf("Unable to open %s for write. Run this test from hphp/.\n", fullPath.c_str()); return false; } if (file && !strncmp(input, "setOutputPath(path.c_str()); Compiler::Parser::ParseString(input, ar); BuiltinSymbols::Load(ar); ar->loadBuiltins(); ar->analyzeProgram(); ar->preOptimize(); ar->analyzeIncludes(); ar->inferTypes(); ar->postOptimize(); ar->analyzeProgramFinal(); ar->outputAllCPP(CodeGenerator::ClusterCPP, 0, NULL); string target = path + "/Makefile"; const char *argv1[] = {"", "runtime/tmp/single.mk", target.c_str(), NULL}; string out, err; Process::Exec("cp", argv1, NULL, out, &err); if (!err.empty()) { printf("Failed to copy runtime/tmp/single.mk: %s\n", err.c_str()); return false; } if (FastMode) { string sys = string(subdir) + "/sys"; const char *argv2[] = {"", sys.c_str(), NULL}; Process::Exec("runtime/tmp/mergecpp.sh", argv2, NULL, out, &err); if (!err.empty()) { printf("Failed to merge runtime/tmp/%s/*.cpp: %s\n", sys.c_str(), err.c_str()); return false; } } return true; } static string filter_distcc(string &msg) { istringstream is(msg); ostringstream os; string line; while (getline(is, line)) { if (line.compare(0, 6, "distcc")) { os << line << '\n'; } } return os.str(); } bool TestCodeRun::CompileFiles() { string out, err; const char *argv[] = {"", FastMode ? "SHARED" : "LINK", NULL}; Process::Exec("runtime/makeall.sh", argv, NULL, out, &err); err = filter_distcc(err); if (!err.empty()) { printf("Failed to compile files:\n"); istringstream is(err); string line; string buffer; while (getline(is, line)) { buffer += line + "\n"; if (!line.compare(0, 4, "make")) { unsigned int start = 0; while (start < line.length() && line.compare(start, 4, "Test")) { start++; } if (start < line.length()) { istringstream isl(line.substr(start + 4)); int seqno; if (isl >> seqno) { printf("======================================\n" "runtime/tmp/Test%d/main.php:\n" "======================================\n", seqno); printf("\n%s:%d\nParsing: [%s]\n%s\n", m_infos[seqno].file, m_infos[seqno].line, m_infos[seqno].input, buffer.c_str()); buffer = ""; } } } } if (!buffer.empty()) { // leftover error messages, if any printf("\n%s\n", buffer.c_str()); } return false; } return true; } static string escape(const std::string &s) { string ret; ret.reserve(s.size() + 20); for (unsigned int i = 0; i < s.length(); i++) { char ch = s[i]; if (isprint(ch) || ch == '\n') { ret += ch; } else { char buf[10]; snprintf(buf, sizeof(buf), "{\\x%02X}", (unsigned char)ch); ret += buf; } } return ret; } static bool verify_result(const char *input, const char *output, bool perfMode, const char *file = "", int line = 0, bool nowarnings = false, bool fileoutput = false, const char *subdir = "", bool fastMode = false) { // generate main.php string fullPath = "runtime/tmp"; if (subdir && subdir[0]) fullPath = fullPath + "/" + subdir; fullPath += "/main.php"; if (!GenerateMainPHP(fullPath, 0, 0, input)) return false; // get PHP's output if "output" is NULL string expected; if (output) { if (fileoutput) { String s = f_file_get_contents(output); expected = string(s.data(), s.size()); } else { expected = output; } } else { const char *argv1[] = {"", "-ddisplay_errors=stderr", "-dapc.enable_cli=1", fullPath.c_str(), NULL}; const char *argv2[] = {"", "-ddisplay_errors=On", "-dapc.enable_cli=1", fullPath.c_str(), NULL}; string err; Process::Exec(php_path, nowarnings ? argv2 : argv1, NULL, expected, &err); if (!err.empty() && nowarnings) { printf("%s:%d\nParsing: [%s]\nFailed to run %s: %s\n", file, line, input, fullPath.c_str(), err.c_str()); return false; } } // run and verify output { string actual, err; string dir = "runtime/tmp/"; if (subdir) dir = dir + subdir + "/"; string repoarg = "-vRepo.Central.Path=" + dir + "hhvm.hhbc"; if (Option::EnableEval < Option::FullEval) { if (fastMode) { string path = dir + "libtest.so"; const char *argv[] = {"", "--file=string", "--config=test/config.hdf", repoarg.c_str(), path.c_str(), NULL}; Process::Exec("runtime/tmp/run.sh", argv, NULL, actual, &err); } else { const char *argv[] = {"", "--file=string", "--config=test/config.hdf", repoarg.c_str(), NULL}; string path = dir + "test"; Process::Exec(path.c_str(), argv, NULL, actual, &err); } } else { string filearg = "--file=" + dir + "main.php"; string jitarg = string("-vEval.Jit=") + (RuntimeOption::EvalJit ? "true" : "false"); string jit_use_ir = string("-vEval.JitUseIR=") + (RuntimeOption::EvalJitUseIR ? "true" : "false"); string jit_rename = string("-vEval.JitEnableRenameFunction=") + (RuntimeOption::EvalJit ? "true" : "false"); const char *argv[] = {"", filearg.c_str(), "--config=test/config.hdf", repoarg.c_str(), jitarg.c_str(), jit_use_ir.c_str(), jit_rename.c_str(), NULL}; Process::Exec(HHVM_PATH, argv, NULL, actual, &err); } if (perfMode) { string sinput = input; const char *marker = "/* INPUT */"; int pos1 = sinput.find(marker); int pos2 = sinput.find(marker, pos1+1); pos1 += strlen(marker); sinput = sinput.substr(pos1, pos2 - pos1); if (sinput.size() > 1000) sinput = "(long program)"; // we have to adjust timing by removing loop cost, which is the 1st test static int adj1 = -1; static int adj2 = -1; int ms1 = atoi(expected.c_str()); int ms2 = atoi(actual.c_str()); if (adj1 == -1) adj1 = ms1; if (adj2 == -1) adj2 = ms2; int msAdj1 = ms1 - adj1; int msAdj2 = ms2 - adj2; double x = 0.0; // how many times faster double p = 0.0; // percentage if (msAdj2 != 0) { x = ((double)(int)(msAdj1 * 100 / msAdj2)) / 100; } if (msAdj1 != 0) { p = ((double)(int)(msAdj2 * 10000 / msAdj1)) / 100; } printf("----------------------------------------------------------\n" "%s\n\n" " PHP C++\n" "===========================================\n" " %6d ms %6d ms\n" " -%6d ms %6d ms\n" "===========================================\n" " %6d ms %6d ms = %2.4gx or %2.4g%%\n\n", sinput.c_str(), ms1, ms2, adj1, adj2, msAdj1, msAdj2, x, p); return true; } bool out_ok = actual == expected; if (!out_ok || (!nowarnings && !err.empty())) { if (out_ok && err.find("symbol lookup error:") != string::npos && err.find("undefined symbol: ") != string::npos) { printf("%s: Ignoring loader error: %s\n", fullPath.c_str(), err.c_str()); } else { printf("======================================\n" "%s:\n" "======================================\n" "%s:%d\nParsing: [%s]\nBet %d:\n" "--------------------------------------\n" "%s" "--------------------------------------\n" "Got %d:\n" "--------------------------------------\n" "%s" "--------------------------------------\n" "Err: [%s]\n", fullPath.c_str(), file, line, input, (int)expected.length(), escape(expected).c_str(), (int)actual.length(), escape(actual).c_str(), err.c_str()); return false; } } } return true; } bool TestCodeRun::RecordMulti(const char *input, const char *output, const char *file, int line, bool nowarnings, bool fileoutput) { if (Filter) { const char *errptr; int erroffset; pcre *re = pcre_compile(Filter, PCRE_CASELESS, &errptr, &erroffset, 0); if (re && pcre_exec(re, 0, input, strlen(input), 0, 0, 0, 0) >= 0) { return true; } } string fullPath = "runtime/tmp/" + Test::s_suite + "/" + test_name + "/tcr-" + boost::lexical_cast(m_test++); if (!GenerateMainPHP(fullPath + "/main.php", file, line, input)) return false; if (nowarnings) { std::ofstream((fullPath + "/nowarnings").c_str()); } if (!m_compileOptions.empty()) { std::ofstream s((fullPath + "/build.opts").c_str()); s << m_compileOptions; } if (!m_runtimeOptions.empty()) { std::ofstream s((fullPath + "/test.opts").c_str()); s << m_runtimeOptions; } if (!m_envVars.empty()) { std::ofstream s((fullPath + "/test.env").c_str()); s << m_envVars; } if (output) { std::ofstream s((fullPath + "/test.result").c_str()); if (fileoutput) { String expected = f_file_get_contents(output); s << string(expected.data(), expected.size()); } else { s << output; } } return true; } bool TestCodeRun::MultiVerifyCodeRun() { return true; if (Option::EnableEval < Option::FullEval) { CompileFiles(); } bool ret = true; for (unsigned i = 0; i < m_infos.size(); i++) { assert(m_infos[i].input); ostringstream os; os << "Test" << i; if (!Count(verify_result(m_infos[i].input, m_infos[i].output, m_perfMode, m_infos[i].file, m_infos[i].line, m_infos[i].nowarnings, m_infos[i].fileoutput, os.str().c_str(), FastMode))) { ret = false; } } return ret; } bool TestCodeRun::VerifyCodeRun(const char *input, const char *output, const char *file /* = "" */, int line /* = 0 */, bool nowarnings /* = false */, bool fileoutput /* = false */) { assert(input); if (!CleanUp()) return false; if (Option::EnableEval < Option::FullEval) { if (!GenerateFiles(input, "Test0") || !CompileFiles()) { return false; } } return verify_result(input, output, m_perfMode, file, line, nowarnings, fileoutput, "Test0", FastMode); } /////////////////////////////////////////////////////////////////////////////// #define GEN_TEST(test) \ if (!which.empty() && which != #test) { \ } else { \ test_name = #test; \ test(); \ } bool TestCodeRun::RunTests(const std::string &which) { CleanUp(); bool ret = true; GEN_TEST(TestSanity); GEN_TEST(TestInnerFunction); GEN_TEST(TestInnerClass); GEN_TEST(TestVariableArgument); GEN_TEST(TestArgumentHandling); GEN_TEST(TestListAssignment); GEN_TEST(TestExceptions); GEN_TEST(TestPredefined); GEN_TEST(TestLabels); GEN_TEST(TestPerfectVirtual); GEN_TEST(TestBoolean); GEN_TEST(TestInteger); GEN_TEST(TestDouble); GEN_TEST(TestString); GEN_TEST(TestLocale); GEN_TEST(TestArray); GEN_TEST(TestArrayInit); GEN_TEST(TestArrayCopy); GEN_TEST(TestArrayEscalation); GEN_TEST(TestArrayOffset); GEN_TEST(TestArrayAccess); GEN_TEST(TestArrayIterator); GEN_TEST(TestArrayForEach); GEN_TEST(TestArrayAssignment); GEN_TEST(TestArrayFunctions); GEN_TEST(TestArrayCSE); GEN_TEST(TestScalarArray); GEN_TEST(TestRange); GEN_TEST(TestVariant); GEN_TEST(TestObject); GEN_TEST(TestObjectProperty); GEN_TEST(TestObjectMethod); GEN_TEST(TestClassMethod); GEN_TEST(TestObjectMagicMethod); GEN_TEST(TestObjectInvokeMethod); GEN_TEST(TestObjectAssignment); GEN_TEST(TestNewObjectExpression); GEN_TEST(TestObjectPropertyExpression); GEN_TEST(TestCollectionClasses); GEN_TEST(TestComparisons); GEN_TEST(TestReference); GEN_TEST(TestUnset); GEN_TEST(TestDynamicConstants); GEN_TEST(TestDynamicVariables); GEN_TEST(TestDynamicProperties); GEN_TEST(TestDynamicFunctions); GEN_TEST(TestRenameFunction); GEN_TEST(TestIntercept); GEN_TEST(TestMaxInt); GEN_TEST(TestDynamicMethods); GEN_TEST(TestVolatile); GEN_TEST(TestHereDoc); GEN_TEST(TestProgramFunctions); GEN_TEST(TestCompilation); GEN_TEST(TestReflection); GEN_TEST(TestReflectionClasses); GEN_TEST(TestErrorHandler); GEN_TEST(TestAssertOptions); GEN_TEST(TestExtMisc); GEN_TEST(TestInvalidArgument); GEN_TEST(TestSuperGlobals); GEN_TEST(TestGlobalStatement); GEN_TEST(TestStaticStatement); GEN_TEST(TestIfStatement); GEN_TEST(TestBreakStatement); GEN_TEST(TestContinueStatement); GEN_TEST(TestReturnStatement); GEN_TEST(TestAdd); GEN_TEST(TestMinus); GEN_TEST(TestMultiply); GEN_TEST(TestDivide); GEN_TEST(TestModulus); GEN_TEST(TestOperationTypes); GEN_TEST(TestUnaryOperators); GEN_TEST(TestSilenceOperator); GEN_TEST(TestPrint); GEN_TEST(TestVarExport); GEN_TEST(TestLogicalOperators); GEN_TEST(TestGetClass); GEN_TEST(TestGetParentClass); GEN_TEST(TestRedeclaredFunctions); GEN_TEST(TestRedeclaredClasses); GEN_TEST(TestReassignThis); GEN_TEST(TestClone); GEN_TEST(TestEvalOrder); GEN_TEST(TestGetObjectVars); GEN_TEST(TestSerialization); GEN_TEST(TestJson); GEN_TEST(TestThrift); GEN_TEST(TestExit); GEN_TEST(TestCreateFunction); GEN_TEST(TestConstructorDestructor); GEN_TEST(TestConcat); GEN_TEST(TestConstant); GEN_TEST(TestClassConstant); GEN_TEST(TestConstantFunction); GEN_TEST(TestDefined); GEN_TEST(TestSimpleXML); GEN_TEST(TestXML); GEN_TEST(TestDOMDocument); GEN_TEST(TestFile); GEN_TEST(TestDirectory); GEN_TEST(TestAssignment); GEN_TEST(TestBadFunctionCalls); GEN_TEST(TestConstructor); GEN_TEST(TestIntIsset); GEN_TEST(TestTernary); GEN_TEST(TestUselessAssignment); GEN_TEST(TestTypes); GEN_TEST(TestSwitchStatement); GEN_TEST(TestExtString); GEN_TEST(TestExtArray); GEN_TEST(TestExtFile); GEN_TEST(TestExtDate); GEN_TEST(TestExtImage); GEN_TEST(TestExtSplFile); GEN_TEST(TestExtIterator); GEN_TEST(TestExtSoap); GEN_TEST(TestExtCollator); GEN_TEST(TestExtSocket); GEN_TEST(TestAPC); GEN_TEST(TestInlining); GEN_TEST(TestCopyProp); GEN_TEST(TestParser); GEN_TEST(TestTypeAssertions); GEN_TEST(TestSerialize); if (Option::EnableEval == Option::FullEval) { // hphpc is intentionally more liberal with its hoisting rules GEN_TEST(TestHoisting); } // PHP 5.3 features GEN_TEST(TestVariableClassName); GEN_TEST(TestLateStaticBinding); GEN_TEST(TestCallStatic); GEN_TEST(TestNowDoc); GEN_TEST(TestTernaryShortcut); GEN_TEST(TestGoto); GEN_TEST(TestClosure); if (!hhvm) { GEN_TEST(TestNamespace); } // PHP 5.4 features GEN_TEST(TestTraits); // PHP 5.5 features GEN_TEST(TestUConverter); // HipHop features GEN_TEST(TestYield); GEN_TEST(TestHint); GEN_TEST(TestUserAttributes); #ifdef TAINTED GEN_TEST(TestTaint); GEN_TEST(TestTaintExt); #endif GEN_TEST(TestStrictMode); GEN_TEST(TestAdHoc); { // We have a still unresolved repo contention issues with more // than 20 jobs. t1394416 int cpus = std::min(20, Process::GetCPUCount()); int jobs = cpus; char* hphp_slow_tests_jobs = getenv("HPHP_SLOW_TESTS_JOBS"); if (hphp_slow_tests_jobs) { int n = atoi(hphp_slow_tests_jobs); if (n > 0) jobs = n; } string cmd = "env -u MFLAGS -u MAKEFLAGS " "make -f runtime/tmp/test.mk --no-print-directory " "SUITE="+Test::s_suite + " -j" + boost::lexical_cast(jobs); if (::system(cmd.c_str())) { printf("Failed to run testsuite: %s\n", Test::s_suite.c_str()); return false; } std::ifstream in(("runtime/tmp/"+Test::s_suite+"/results").c_str()); if (in.fail()) return false; in >> fail_count; in >> pass_count; int total; in >> total; Test::s_passed = pass_count; Test::s_total = total; return total == pass_count && !fail_count; } return ret; } /////////////////////////////////////////////////////////////////////////////// // code generation bool TestCodeRun::TestSanity() { MVCR("#"); return true; } bool TestCodeRun::TestInnerFunction() { MVCR("p();"); MVCR("p();"); MVCR("p();"); return true; } bool TestCodeRun::TestVariableArgument() { MVCR("test('test'); $obj->test(1, 2, 3);"); MVCR("buz);" "unset($x);"); if (!hhvm) { MVCR(" 10, 'y' => 20, 'z' => 30, 'j' => 40));\n" " call_user_func_array($f, " " array(3 => 10, 80 => 20, 10 => 30, 30 => 40));\n" "}\n" "g(10);\n"); MVCR("container = array(" " 'one' => 1," " 'two' => 2," " 'three' => 3," " );" " }" " public function offsetSet($offset, $value) {" " $this->container[$offset] = $value;" " }" " public function offsetExists($offset) {" " return isset($this->container[$offset]);" " }" " public function offsetUnset($offset) {" " unset($this->container[$offset]);" " }" " public function offsetGet($offset) {" " return isset($this->container[$offset]) ? $this->container[$offset] : null;" " }" "}" "class SetTest {" " private $_vals = array(" " 'one' => 1," " 'two' => 2," " 'three' => 3," " );" " public function __set($name, $value) {" " $this->_vals[$name] = $value;" " }" "}" "$o = new obj;" "$q = list($o['one'], $o['two'], list($o['three'])) =" " array('eins', 'zwei', array('drei'));" "var_dump($o);" "var_dump($q);" "$x = new SetTest;" "$qq = list($x->one, $x->two, list($x->three)) = 1;" "var_dump($x);" "$qq = list($x->one, $x->two, list($x->three)) = $q;" "var_dump($x);" "var_dump($qq);"); MVCR("foo();" "X::$val = null;"); return true; } bool TestCodeRun::TestExceptions() { MVCR("getTrace(); foreach ($a as &$b) $b['file'] = 'string';\n" " var_dump($a);\n" " var_dump($exn->getLine());\n" "}\n" ); MVCR("getTrace(); foreach ($a as &$b) $b['file'] = 'string';\n" " var_dump($a);\n" " var_dump($exn->getLine());\n" " }\n" "}\n" "\n" "bar();\n"); MVCR("code, '\nm:', $this->message, '\n';" " echo 'x:', $this->x, '\ny:', $this->y, '\n';" " }" "}" "if (0) { class a extends Exception {} }" "try {" " throw(new b(1, 2));" "} catch (b $e) {" " $e->dump();" "}"); MVCR("foo();\n" "var_dump($ex->getMessage());\n"); MVCR("= Option::FullEval) { MVCRNW("getTrace();\n" " foreach ($bt as $k => $_) {\n" " $frame = $bt[$k];\n" " unset($frame['file']);\n" " unset($frame['line']);\n" " unset($frame['args']);\n" " ksort($frame);\n" " $bt[$k] = $frame;\n" " }\n" " var_dump($bt);\n" " }\n" " function f() {\n" " $this->g();\n" " }\n" "}\n" "$obj = new C;\n" "$obj->f();\n" "echo \"==========\\n\";\n" "Exception::setTraceOptions(true);\n" "$obj->f();\n" , "array(2) {\n" " [0]=>\n" " array(3) {\n" " [\"class\"]=>\n" " string(1) \"C\"\n" " [\"function\"]=>\n" " string(1) \"g\"\n" " [\"type\"]=>\n" " string(2) \"->\"\n" " }\n" " [1]=>\n" " array(3) {\n" " [\"class\"]=>\n" " string(1) \"C\"\n" " [\"function\"]=>\n" " string(1) \"f\"\n" " [\"type\"]=>\n" " string(2) \"->\"\n" " }\n" "}\n" "==========\n" "array(2) {\n" " [0]=>\n" " array(4) {\n" " [\"class\"]=>\n" " string(1) \"C\"\n" " [\"function\"]=>\n" " string(1) \"g\"\n" " [\"object\"]=>\n" " object(C)#1 (0) {\n" " }\n" " [\"type\"]=>\n" " string(2) \"->\"\n" " }\n" " [1]=>\n" " array(4) {\n" " [\"class\"]=>\n" " string(1) \"C\"\n" " [\"function\"]=>\n" " string(1) \"f\"\n" " [\"object\"]=>\n" " object(C)#1 (0) {\n" " }\n" " [\"type\"]=>\n" " string(2) \"->\"\n" " }\n" "}\n" ); if (!hhvm) { FinallyStatement w(this); MVCRO("getMessage();\n" " $e = $e->getPrevious();\n" " }\n" "}\n", "Exception 4" "Exception 3" "Exception 2" "Exception 1"); MVCRO("testr();"); MVCR("foo();" " $obj = new B; $obj->foo();" "} bar();" ); MVCR("foo();" " $obj = new B; $obj->foo();" "} bar();" ); MVCR("foo(123);" " $obj = new B; $obj->foo(123, 456);" "} bar();" ); MVCR("foo();" " $obj = new B; $obj->foo();" "} bar();" ); MVCR("foo(5);" " return ++$y;" "}" "test(new Y);"); return true; } /////////////////////////////////////////////////////////////////////////////// // type system bool TestCodeRun::TestBoolean() { MVCR("> 2);"); MVCR(">= 2; var_dump($a);"); MVCR("'foo');" "$b = 'qqq';" "class c {}" "$c = new c;" "$c->p = 'zzz';" "var_dump(\"AAA ${a['x']} $a[x] $b $c->p\");"); MVCR(" 1, 'abcd' => 2);\n" " $s .= 'c'; var_dump($a[$s]);\n" " $s .= 'd'; var_dump($a[$s]);\n" // should find 'abcd' in $a "}\n" "test('ab');\n"); MVCR(" '2', 'a' => '1'));"); MVCR(" 'a', 0 => 'b'));"); MVCR(" 1); var_dump($a);"); MVCR(" 2, 'a' => 1); var_dump($a);"); MVCR(" '1'); var_dump($a);"); MVCR(" '2', 'a' => '1'); var_dump($a);"); MVCR(" 1, 'a' => 2); var_dump($a);"); MVCR(" 1, 'b' => 2, 'a' => 3); var_dump($a);"); MVCR(" 2, 'a' => 1); " "foreach ($a as $item) print '['.$item.']';"); MVCR(" 2, 'a' => 1); " "foreach ($a as $name => $item) print '['.$name.'=>'.$item.']';"); MVCR(" 2, 'a' => 1); var_dump($a['b']);"); MVCR(" 2, 'a' => 1); var_dump($a['bogus']);"); MVCR(" 1); var_dump($a);"); MVCR(" 'test'); var_dump($a[1]);"); MVCR(" 1, 'b' => 2);" "foreach ($a as $b => $c) {" " var_dump($b);" " unset($a['b']);" "}"); MVCR(" 1, 'b' => 2);" "foreach ($a as $b => &$c) {" " var_dump($b);" " unset($a['b']);" "}"); MVCRO(" 1, 'b' => 2);" " foreach ($a as $b => &$c) {" " yield null;" " var_dump($b);" " unset($a['b']);" " }" "}" "foreach (gen() as $_) {}" , "string(1) \"a\"\n" ); MVCR(" $val) {" " if($val == 2) {" " $foo[$key] = 0;" " } else if($val == 3) {" " unset($foo[$key]);" " } else {" " $foo[$key] = $val + 1;" " }" "}" "var_dump($foo);"); MVCR(" &$val) {" " if($val == 2) {" " $foo[$key] = 0;" " } else if($val == 3) {" " unset($foo[$key]);" " } else {" " $val++;" " }" "}" "var_dump($foo);"); MVCRO(" &$val) {" " if($val == 2) {" " $foo[$key] = 0;" " } else if($val == 3) {" " unset($foo[$key]);" " } else {" " $val++;" " }" " }" " var_dump($foo);" " yield null;" "}" "foreach (gen() as $_) {}" , "array(3) {\n" " [0]=>\n" " int(2)\n" " [1]=>\n" " int(0)\n" " [3]=>\n" " &int(5)\n" "}\n" ); MVCR(" 'apple', 'b' => 'banana', 'c' => 'citrus');" "foreach ($a as $k1 => &$v1) {" " foreach ($a as $k2 => &$v2) {" " if ($k2 == 'a') {" " unset($a[$k2]);" " }" " var_dump($v1, $v2);" " }" "}"); MVCRO(" 'apple', 'b' => 'banana', 'c' => 'citrus');" " foreach ($a as $k1 => &$v1) {" " foreach ($a as $k2 => &$v2) {" " if ($k2 == 'a') {" " unset($a[$k2]);" " }" " var_dump($v1, $v2);" " }" " }" " yield null;" "}" "foreach (gen() as $_) {}" , "string(5) \"apple\"\n" "string(5) \"apple\"\n" "string(5) \"apple\"\n" "string(6) \"banana\"\n" "string(5) \"apple\"\n" "string(6) \"citrus\"\n" "string(6) \"banana\"\n" "string(6) \"banana\"\n" "string(6) \"banana\"\n" "string(6) \"citrus\"\n" "string(6) \"citrus\"\n" "string(6) \"banana\"\n" "string(6) \"citrus\"\n" "string(6) \"citrus\"\n" ); MVCR("f(array());"); MVCR(" array(2 => 'test'));" "unset($array['1'][2]);" "var_dump($array['1']);"); MVCR(" 0, 3 => true, 4 => true); " " var_dump($args);" " }" "}" "$obj = new A;" "$obj->foo(1, 2, 3);"); MVCRO("valid(); $o->next()) {" " $v = &$o->currentRef();" " var_dump($v);" " var_dump($v);" " }" " var_dump(array_key_exists('foo', $args));" " var_dump(array_unshift($args, 4));" " var_dump(array_pop($args));" " if (isset($args['foo'])) {}" " var_dump(each($args));" " var_dump(array_shift($args));" " }" "}" "$obj = new A;" "$obj->foo(1, 2, 3);", "int(1)\n" "int(1)\n" "int(2)\n" "int(2)\n" "int(3)\n" "int(3)\n" "bool(false)\n" "int(4)\n" "int(3)\n" "array(4) {\n" " [1]=>\n" " int(4)\n" " [\"value\"]=>\n" " int(4)\n" " [0]=>\n" " int(0)\n" " [\"key\"]=>\n" " int(0)\n" "}\n" "int(4)\n"); MVCR(" $a);" " if ($x) {" " var_dump(isset($x[0][1]), isset($x['foo'][1]));" " var_dump(isset($x[$b][1]), isset($x[$c][1]));" " var_dump(end($x[0]));" " }" "}" "test(5, array(0,1), 0, 'foo');"); MVCR(" 1, new MyClass() => 2, " "false => 3, true => 4, count(array(1,2,3)) => 5);\n" "var_dump($arr);\n"); MVCR(" 'a', 1 => 'b', 2 => $p);" " $a[] = 'd';" " var_dump($a);" " $a = array(2 => 'a', 4 => 'b', 6 => $p);" " $a[] = 'd';" " var_dump($a);" " $a = array(-2 => 'a', -4 => 'b', -6 => $p);" " $a[] = 'd';" " var_dump($a);" " $a = array(0 => 'a');" " $a[] = 'b';" " var_dump($a);" "}" "foo('c');"); MVCR(" $b);\n" " $a[0] = $a; var_dump($a);\n" "}\n" "f(false);\n"); MVCR(" $b);\n" " $a2 = &$a; $a[] = $a2; var_dump($a);\n" "}\n" "f(false);\n" , "array(2) {\n" " [\"x\"]=>\n" " bool(false)\n" " [0]=>\n" " array(1) {\n" " [\"x\"]=>\n" " bool(false)\n" " }\n" "}\n"); MVCR(" true, false => 0, 1 => 1.0," " '1.0' => 1.23456789e+34," " 1.7976931348623157e+308 => 1E666," " 1E666/1E666 => \"a bc\"," " \"\\xc1 bc\");" "$a16 = array(null => true, false => 0, 1 => 1.0," " '1.0' => 1.23456789e+34," " 1.7976931348623157e+308 => 1E666," " 1E666/1E666 => \"a bc\"," " \"\\xc1 bc\"," " array(null => true, array()," " false => 0, 1 => 1.0," " '1.0' => 1.23456789e+34," " 1.7976931348623157e+308 => 1E666," " 1E666/1E666 => \"a bc\"," " \"\\xc1 bc\"));" "var_dump($a1);" "var_dump($a2);" "var_dump($a3);" "var_dump($a4);" "var_dump($a5);" "var_dump($a6);" "var_dump($a7);" "var_dump($a8);" "var_dump($a9);" "var_dump($a10);" "var_dump($a11);" "var_dump($a12);" "var_dump($a13);" "var_dump($a14);" "var_dump($a15);" "var_dump($a16);"); MVCR(" @VALUE));"); return true; } bool TestCodeRun::TestRange() { MVCR(" 20); var_dump($a);"); \ MVCR(" 'b'); var_dump($a);"); \ MVCR(" array(3)); var_dump($a);"); \ bool TestCodeRun::TestArrayEscalation() { TEST_ARRAY_CONVERT("array()"); TEST_ARRAY_CONVERT("array(10)"); TEST_ARRAY_CONVERT("array('test')"); TEST_ARRAY_CONVERT("array(array(0))"); TEST_ARRAY_CONVERT("array('a' => 10)"); TEST_ARRAY_CONVERT("array('a' => 'va')"); TEST_ARRAY_CONVERT("array('a' => array(1))"); TEST_ARRAY_PLUS("array()"); TEST_ARRAY_PLUS("array(10)"); TEST_ARRAY_PLUS("array('test')"); TEST_ARRAY_PLUS("array(array(0))"); TEST_ARRAY_PLUS("array('a' => 10)"); TEST_ARRAY_PLUS("array('a' => 'va')"); TEST_ARRAY_PLUS("array('a' => array(1))"); MVCR("$offset.'get';" " }" " public function offsetSet($offset, $value) {" " $this->$offset = $value.'set';" " }" " public function offsetUnset($offset) {" " $this->$offset = 'unset';" " }" "}" "function f() { var_dump('f()'); return 1; }\n" "function test($a) {\n" "$a['foo'] .= f();\n" "$a['bar'] += f();\n" "$a['bar'] -= f();\n" "$a['bar'] *= f();\n" "$a['bar'] /= f();\n" "$a['bar'] %= f();\n" "$a['bar'] &= f();\n" "$a['bar'] |= f();\n" "$a['bar'] ^= f();\n" "$a['bar'] <<= f();\n" "$a['bar'] >>= f();\n" "}\n" "test(new A);\n" ); MVCR("$offset.'get';" " }" " public function offsetSet($offset, $value) {" " $this->$offset = $value.'set';" " }" " public function offsetUnset($offset) {" " $this->$offset = 'unset';" " }" "}" "$obj = new A();" "if (!isset($obj['a'])) {" " $obj['a'] = 'test';" "}" "if (!empty($obj['a'])) {" " $obj['a'] = 'test2';" "}" "var_dump($obj['a']);" "unset($obj['a']);" "var_dump($obj['a']);" ); MVCR("data[$index];" " if(is_array($value)) {" " $u = new ArrayAccessImpl();" " foreach($value as $idx=>$e)" " $u[$idx]=$e;" " } else" " $u=$value;" " }" " public function offsetGet($index) {" " echo (\"GET: $index\\n\");" " if(!isset($this->data[$index]))" " $this->data[$index]=new ArrayAccessImpl();" " return $this->data[$index];" " }" " public function offsetExists($index) {" " echo (\"EXISTS: $index\\n\");" " if(isset($this->data[$index])) {" " if($this->data[$index] instanceof ArrayAccessImpl) {" " if(count($this->data[$index]->data)>0)" " return true;" " else" " return false;" " } else" " return true;" " } else" " return false;" " }" "}" "" "class ArrayAccessImpl2 extends ArrayAccessImpl {" " public function offsetUnset($index) { echo \"UNSET2: $index\\n\"; }" " public function offsetSet($index, $value) {" " echo (\"SET2: $index\\n\");" " if(isset($data[$index])) {" " unset($data[$index]);" " }" " $u = &$this->data[$index];" " if(is_array($value)) {" " $u = new ArrayAccessImpl();" " foreach($value as $idx=>$e)" " $u[$idx]=$e;" " } else" " $u=$value;" " }" " public function offsetGet($index) {" " echo (\"GET2: $index\\n\");" " if(!isset($this->data[$index]))" " $this->data[$index]=new ArrayAccessImpl();" " return $this->data[$index];" " }" " public function offsetExists($index) {" " echo (\"EXISTS2: $index\\n\");" " if(isset($this->data[$index])) {" " if($this->data[$index] instanceof ArrayAccessImpl) {" " if(count($this->data[$index]->data)>0)" " return true;" " else" " return false;" " } else" " return true;" " } else" " return false;" " }" "}" "offsetGet('foo');" "$data = new ArrayAccessImpl();" "$data['string']=\"Just a simple string\";" "$data['number']=33;" "$data['array']['another_string']=\"Alpha\";" "$data['array']['some_object']=new stdClass();" "$data['array']['another_array']['x']['y']=\"Beta\";" "$data['blank_array']=array();" "print_r(isset($data['array']));" "print_r($data['array']['non_existent']);" "print_r(isset($data['array']['non_existent']));" "print_r($data['blank_array']);" "print_r(isset($data['blank_array']));" "unset($data['blank_array']);" "print_r($data);" "$data2 = new ArrayAccessImpl2();" "$data2['string']=\"Just a simple string\";" "$data2['number']=33;" "$data2['array']['another_string']=\"Alpha\";" "$data2['array']['some_object']=new stdClass();" "$data2['array']['another_array']['x']['y']=\"Beta\";" "$data2['blank_array']=array();" "print_r(isset($data2['array']));" "print_r($data2['array']['non_existent']);" "print_r(isset($data2['array']['non_existent']));" "print_r($data2['blank_array']);" "print_r(isset($data2['blank_array']));" "unset($data2['blank_array']);" "print_r($data2);"); MVCR("foo = 1;" " var_dump($a, $b);" " $a = $x;" " $b = $a;" " $a[0][1] = 1;" " var_dump($a, $b);" " $a = $x;" " $c = &$a[0];" " $b = $a;" " $a[0][1] = 1;" " var_dump($a, $b);" " }" "test(array(false));" "var_dump(array(false));"); return true; } bool TestCodeRun::TestArrayIterator() { HipHopSyntax w(this); MVCR("var = $array;" " }" " }" " public function rewind() {" " echo \"rewinding\n\";" " reset($this->var);" " }" " public function current() {" " $var = current($this->var);" " echo \"current: $var\n\";" " return $var;" " }" " public function key() {" " $var = key($this->var);" " echo \"key: $var\n\";" " return $var;" " }" " public function next() {" " $var = next($this->var);" " echo \"next: $var\n\";" " return $var;" " }" " public function valid() {" " $var = $this->current() !== false;" " echo \"valid: {$var}\n\";" " return $var;" " }" "}" "$values = array(1,2,3);" "$it = new MyIterator($values);" "foreach ($it as $a => $b) {" " print \"$a: $b\n\";" "}" "$itp = \"it\";" "foreach ($$itp as $a => $b) {" " print \"$a: $b\n\";" "}" "function getIter() {" " $values = array(1,2,3);" " $it = new MyIterator($values);" " return $it;" "}" "foreach (getIter() as $a => $b) {" " print \"$a: $b\n\";" "}" "class MyIteratorAggregate implements IteratorAggregate {" " public function getIterator() {" " return getIter();" " }" "}" "$obj = new MyIteratorAggregate();" "foreach ($obj as $a => $b) {" " print \"$a: $b\n\";" "}" ); MVCR(" $v) { if ($v >= 4) $a = $v + $v; }\n" "var_dump($a);\n"); MVCR("valid()) {" " var_dump($it->key());" " var_dump($it->current());" " $it->next();" " }" "}" "test(array('a' => 'x'," " false => 'y'," " '1' => false," " null => 'z'," " 'c' => 'w'));"); MVCR("next());\n" "var_dump($o->rewind());\n" "var_dump($o->seek());\n" "var_dump($o->asort());\n" "var_dump($o->ksort());\n" "var_dump($o->natsort());\n" "var_dump($o->natcasesort());\n"); // MutableArrayIterator MVCRO(" &$v1) { $v1 += $k1; }\n" "var_dump($a);\n" "$a = array(1, 2, 3);\n" "for ($o = new MutableArrayIterator($a); $o->valid(); $o->next()) {\n" " $k2 = $o->key();\n" " $v2 = &$o->currentRef();\n" " $v2 += $k2;\n" "}\n" "var_dump($a);\n" , "array(3) {\n" " [0]=>\n" " int(1)\n" " [1]=>\n" " int(3)\n" " [2]=>\n" " &int(5)\n" "}\n" "array(3) {\n" " [0]=>\n" " int(1)\n" " [1]=>\n" " int(3)\n" " [2]=>\n" " &int(5)\n" "}\n"); MVCRO(" &$v1) { $v1 += $k1; }\n" " var_dump($a);\n" " $a = array(1, 2, 3);\n" " for ($o = new MutableArrayIterator($a); $o->valid(); $o->next()) {\n" " $k2 = $o->key();\n" " $v2 = &$o->currentRef();\n" " $v2 += $k2;\n" " }\n" " var_dump($a);\n" " yield null;\n" "}\n" "foreach (gen() as $_) {}\n" , "array(3) {\n" " [0]=>\n" " int(1)\n" " [1]=>\n" " int(3)\n" " [2]=>\n" " &int(5)\n" "}\n" "array(3) {\n" " [0]=>\n" " int(1)\n" " [1]=>\n" " int(3)\n" " [2]=>\n" " &int(5)\n" "}\n"); MVCR("tn = $tn; $this->tv = $tv; }" " function __destruct() {" " var_dump(__METHOD__);" " }" " public function gen() { return new I($this->tn, $this->tv); }" "}" "class JJ {" " private $tn, $tv;" " function __construct($tn, $tv) { $this->tn = $tn; $this->tv = $tv; }" " function __destruct() {" " var_dump(__METHOD__);" " }" " public function gen() { return new J($this->tn, $this->tv); }" "}" "class KK {" " private $tn, $tv;" " function __construct($tn, $tv) { $this->tn = $tn; $this->tv = $tv; }" " function __destruct() {" " var_dump(__METHOD__);" " }" " public function gen() { return new K($this->tn, $this->tv); }" "}" "class LL {" " private $tn, $tv;" " function __construct($tn, $tv) { $this->tn = $tn; $this->tv = $tv; }" " function __destruct() {" " var_dump(__METHOD__);" " }" " public function gen() { return new L($this->tn, $this->tv); }" "}" "class I implements Iterator" "{" " private $tn, $tv, $i = 0;" " public function gen() { return $this; }" " public function __construct($tn, $tv) {" " $this->tn = $tn;" " $this->tv = $tv;" " }" " public function __destruct() {" " var_dump(__METHOD__);" " }" " public function rewind() {" " var_dump(__METHOD__);" " if ($this->tn == 0) ex(__METHOD__);" " $this->i = 1;" " }" " public function current() {" " var_dump(__METHOD__);" " return $this->i;" " }" " public function key() {" " var_dump(__METHOD__);" " return $this->i;" " }" " public function next() {" " var_dump(__METHOD__);" " if ($this->tn == $this->i) ex(__METHOD__);" " return ++$this->i;" " }" " public function valid() {" " var_dump(__METHOD__);" " if ($this->tv == $this->i) ex(__METHOD__);" " return $this->i < 10;" " }" "}" "class J implements IteratorAggregate {" " private $i;" " public function __construct($tn, $tv) {" " $this->i = new I($tn, $tv);" " }" " public function __destruct() {" " var_dump(__METHOD__);" " }" " public function getIterator() { return $this->i; }" " public function gen() { return $this; }" "}" "class K implements IteratorAggregate {" " private $tn, $tv;" " public function __construct($tn, $tv) {" " $this->tn = $tn;" " $this->tv = $tv;" " }" " public function __destruct() {" " var_dump(__METHOD__);" " }" " public function getIterator() { return new I($this->tn, $this->tv); }" " public function gen() { return $this; }" "}" "class L implements IteratorAggregate {" " public function getIterator() { ex(__METHOD__); }" " public function gen() { return $this; }" "}" "function run($n, $tn, $tv) {" " var_dump('>>>main');" " $a = new A();" " $b = new $n($tn, $tv);" " $b->a = $a;" " try {" " foreach ($b->gen() as $k) {" " var_dump('got '.$k);" " }" " } catch(Exception $e) {" " var_dump('Exception: ' . $e->getMessage());" " unset($e);" " }" " unset($b);" " var_dump('<< &$val) {\n" " echo \"key=$key val=$val\\n\";\n" " if($val == 2) {\n" " $foo[$key] = 0;\n" " } else if($val == 3) {\n" " unset($foo[$key]);\n" " } else {\n" " $val++;\n" " }\n" " ++$i;\n" " if ($i >= 20)\n" " break;\n" " }\n" " var_dump($foo);\n" "}\n" "f1();\n"); MVCRO(" &$val) {\n" " yield null;\n" " echo \"key=$key val=$val\\n\";\n" " if($val == 2) {\n" " $foo[$key] = 0;\n" " } else if($val == 3) {\n" " unset($foo[$key]);\n" " } else {\n" " $val++;\n" " }\n" " ++$i;\n" " if ($i >= 20)\n" " break;\n" " }\n" " var_dump($foo);\n" "}\n" "foreach (f1() as $_) {}\n" , "key=0 val=1\n" "key=1 val=2\n" "key=2 val=3\n" "key=3 val=4\n" "array(3) {\n" " [0]=>\n" " int(2)\n" " [1]=>\n" " int(0)\n" " [3]=>\n" " &int(5)\n" "}\n" ); MVCR(" &$val) {\n" " echo \"key=$key val=$val\\n\";\n" " if($val == 2) {\n" " $foo[$key] = 0;\n" " } else if($val == 3) {\n" " $foo['a'] = 7;\n" " } else {\n" " $val++;\n" " }\n" " ++$i;\n" " if ($i >= 20)\n" " break;\n" " }\n" " var_dump($foo);\n" "}\n" "f2();\n"); MVCRO(" &$val) {\n" " yield null;\n" " echo \"key=$key val=$val\\n\";\n" " if($val == 2) {\n" " $foo[$key] = 0;\n" " } else if($val == 3) {\n" " $foo['a'] = 7;\n" " } else {\n" " $val++;\n" " }\n" " ++$i;\n" " if ($i >= 20)\n" " break;\n" " }\n" " var_dump($foo);\n" "}\n" "foreach (f2() as $_) {}\n" , "key=0 val=1\n" "key=1 val=2\n" "key=2 val=3\n" "key=3 val=4\n" "key=a val=7\n" "array(5) {\n" " [0]=>\n" " int(2)\n" " [1]=>\n" " int(0)\n" " [2]=>\n" " int(3)\n" " [3]=>\n" " int(5)\n" " [\"a\"]=>\n" " &int(8)\n" "}\n" ); /** * Zend PHP 5.2 outputs: * key=a val=1 * key=b val=2 * key=c val=333 * array(6) { * ["a"]=> * int(1) * ["b"]=> * int(2) * ["d"]=> * int(4) * ["e"]=> * int(5) * ["f"]=> * int(6) * ["c"]=> * &int(333) * } * * The difference in behavior is intentional. Under Zend, when the next * element is unset inside a foreach by reference loop, a heuristic is used * to figure out which element should be visited next. In this specific * example, the loop resumes at key 'c', skipping over keys 'd', 'e', and * 'f'. * * Under HPHP, when the next element is unset inside a foreach by loop, the * loop's iterator is appropriately updated. HPHP successfully upholds the * invariant that a foreach by refererence loop that exhausts the array will * visit every element that has not been deleted exactly once. */ MVCRO("1, 'b'=>2, 'c'=>3, 'd'=>4, 'e'=>5, 'f'=>6);\n" " $bar = array();\n" " $a = 0;\n" " foreach ($foo as $key => &$val) {\n" " echo \"key=$key val=$val\\n\";\n" " if ($key == 'b' && $a == 0) {\n" " $a = 1;\n" " unset($foo['c']);\n" " $foo['c'] = 333;\n" " }\n" " ++$i;\n" " if ($i >= 20)\n" " break;\n" " }\n" " var_dump($foo);\n" "}\n" "f3();\n" , "key=a val=1\n" "key=b val=2\n" "key=d val=4\n" "key=e val=5\n" "key=f val=6\n" "key=c val=333\n" "array(6) {\n" " [\"a\"]=>\n" " int(1)\n" " [\"b\"]=>\n" " int(2)\n" " [\"d\"]=>\n" " int(4)\n" " [\"e\"]=>\n" " int(5)\n" " [\"f\"]=>\n" " int(6)\n" " [\"c\"]=>\n" " &int(333)\n" "}\n" ); MVCRO("1, 'b'=>2, 'c'=>3, 'd'=>4, 'e'=>5, 'f'=>6);\n" " $bar = array();\n" " $a = 0;\n" " foreach ($foo as $key => &$val) {\n" " yield null;\n" " echo \"key=$key val=$val\\n\";\n" " if ($key == 'b' && $a == 0) {\n" " $a = 1;\n" " unset($foo['c']);\n" " $foo['c'] = 333;\n" " }\n" " ++$i;\n" " if ($i >= 20)\n" " break;\n" " }\n" " var_dump($foo);\n" "}\n" "foreach (f3() as $_) {}\n" , "key=a val=1\n" "key=b val=2\n" "key=d val=4\n" "key=e val=5\n" "key=f val=6\n" "key=c val=333\n" "array(6) {\n" " [\"a\"]=>\n" " int(1)\n" " [\"b\"]=>\n" " int(2)\n" " [\"d\"]=>\n" " int(4)\n" " [\"e\"]=>\n" " int(5)\n" " [\"f\"]=>\n" " int(6)\n" " [\"c\"]=>\n" " &int(333)\n" "}\n" ); MVCR("1, 'b'=>2, 'c'=>3, 'd'=>4, 'e'=>5, 'f'=>6);\n" " $bar = array();\n" " $a = 0;\n" " foreach ($foo as $key => &$val) {\n" " echo \"key=$key val=$val\\n\";\n" " if ($key == 'b' && $a == 0) {\n" " $a = 1;\n" " unset($foo['c']);\n" " $bar['b'] = 888;\n" " $foo['c'] = 333;\n" " }\n" " ++$i;\n" " if ($i >= 20)\n" " break;\n" " }\n" " var_dump($foo);\n" "}\n" "f4();\n"); MVCRO("1, 'b'=>2, 'c'=>3, 'd'=>4, 'e'=>5, 'f'=>6);\n" " $bar = array();\n" " $a = 0;\n" " foreach ($foo as $key => &$val) {\n" " yield null;\n" " echo \"key=$key val=$val\\n\";\n" " if ($key == 'b' && $a == 0) {\n" " $a = 1;\n" " unset($foo['c']);\n" " $bar['b'] = 888;\n" " $foo['c'] = 333;\n" " }\n" " ++$i;\n" " if ($i >= 20)\n" " break;\n" " }\n" " var_dump($foo);\n" "}\n" "foreach (f4() as $_) {}\n" , "key=a val=1\n" "key=b val=2\n" "key=d val=4\n" "key=e val=5\n" "key=f val=6\n" "key=c val=333\n" "array(6) {\n" " [\"a\"]=>\n" " int(1)\n" " [\"b\"]=>\n" " int(2)\n" " [\"d\"]=>\n" " int(4)\n" " [\"e\"]=>\n" " int(5)\n" " [\"f\"]=>\n" " int(6)\n" " [\"c\"]=>\n" " &int(333)\n" "}\n" ); /** * Zend PHP 5.2 outputs: * key=f val=3 * key()=e current()=1 * key=e val=1 * key()=d current()=5 * key=d val=9 * key()=0s0 current()=0 * key=0s0 val=0 * key()=1s1 current()=1 * key=1s1 val=1 * key()=2s2 current()=2 * key=2s2 val=2 * key()=3s3 current()=3 * key=3s3 val=3 * key()=4s4 current()=4 * ... * * The difference in behavior is intentional. For more info, see testcase h3. */ MVCRO("3, 'e'=>1, 'd'=>5, 'a'=>6, 'b'=>2, 'c'=>4);\n" " $a = 0;\n" " foreach ($foo as $key => &$val) {\n" " echo \"key=$key val=$val\\n\";\n" " if ($key == 'e' && $a == 0) {\n" " $a = 1;\n" " unset($foo['e']);\n" " unset($foo['d']);\n" " $foo['d'] = 9;\n" " for ($j = 0; $j < 10000; ++$j)\n" " $foo[$j . 's' . $j] = $j;\n" " }\n" " ++$i;\n" " if ($i >= 20)\n" " break;\n" " }\n" "}\n" "f5();\n" , "key=f val=3\n" "key=e val=1\n" "key=a val=6\n" "key=b val=2\n" "key=c val=4\n" "key=d val=9\n" "key=0s0 val=0\n" "key=1s1 val=1\n" "key=2s2 val=2\n" "key=3s3 val=3\n" "key=4s4 val=4\n" "key=5s5 val=5\n" "key=6s6 val=6\n" "key=7s7 val=7\n" "key=8s8 val=8\n" "key=9s9 val=9\n" "key=10s10 val=10\n" "key=11s11 val=11\n" "key=12s12 val=12\n" "key=13s13 val=13\n" ); MVCRO("3, 'e'=>1, 'd'=>5, 'a'=>6, 'b'=>2, 'c'=>4);\n" " $a = 0;\n" " foreach ($foo as $key => &$val) {\n" " yield null;\n" " echo \"key=$key val=$val\\n\";\n" " if ($key == 'e' && $a == 0) {\n" " $a = 1;\n" " unset($foo['e']);\n" " unset($foo['d']);\n" " $foo['d'] = 9;\n" " for ($j = 0; $j < 10000; ++$j)\n" " $foo[$j . 's' . $j] = $j;\n" " }\n" " ++$i;\n" " if ($i >= 20)\n" " break;\n" " }\n" "}\n" "foreach (f5() as $_) {}\n" , "key=f val=3\n" "key=e val=1\n" "key=a val=6\n" "key=b val=2\n" "key=c val=4\n" "key=d val=9\n" "key=0s0 val=0\n" "key=1s1 val=1\n" "key=2s2 val=2\n" "key=3s3 val=3\n" "key=4s4 val=4\n" "key=5s5 val=5\n" "key=6s6 val=6\n" "key=7s7 val=7\n" "key=8s8 val=8\n" "key=9s9 val=9\n" "key=10s10 val=10\n" "key=11s11 val=11\n" "key=12s12 val=12\n" "key=13s13 val=13\n" ); MVCR("3, 'e'=>1, 'd'=>5, 'a'=>6, 'b'=>2, 'c'=>4);\n" " $a = 0;\n" " foreach ($foo as $key => &$val) {\n" " echo \"key=$key val=$val\\n\";\n" " if ($key == 'e' && $a == 0) {\n" " $a = 1;\n" " unset($foo['e']);\n" " unset($foo['d']);\n" " $bar['e'] = 8;\n" " $foo['d'] = 9;\n" " for ($j = 0; $j < 10000; ++$j)\n" " $foo[$j . 's' . $j] = $j;\n" " }\n" " ++$i;\n" " if ($i >= 20)\n" " break;\n" " }\n" "}\n" "f6();\n"); MVCRO("3, 'e'=>1, 'd'=>5, 'a'=>6, 'b'=>2, 'c'=>4);\n" " $a = 0;\n" " foreach ($foo as $key => &$val) {\n" " yield null;\n" " echo \"key=$key val=$val\\n\";\n" " if ($key == 'e' && $a == 0) {\n" " $a = 1;\n" " unset($foo['e']);\n" " unset($foo['d']);\n" " $bar['e'] = 8;\n" " $foo['d'] = 9;\n" " for ($j = 0; $j < 10000; ++$j)\n" " $foo[$j . 's' . $j] = $j;\n" " }\n" " ++$i;\n" " if ($i >= 20)\n" " break;\n" " }\n" "}\n" "foreach (f6() as $_) {}\n" , "key=f val=3\n" "key=e val=1\n" "key=a val=6\n" "key=b val=2\n" "key=c val=4\n" "key=d val=9\n" "key=0s0 val=0\n" "key=1s1 val=1\n" "key=2s2 val=2\n" "key=3s3 val=3\n" "key=4s4 val=4\n" "key=5s5 val=5\n" "key=6s6 val=6\n" "key=7s7 val=7\n" "key=8s8 val=8\n" "key=9s9 val=9\n" "key=10s10 val=10\n" "key=11s11 val=11\n" "key=12s12 val=12\n" "key=13s13 val=13\n" ); /** * Zend PHP 5.2 outputs: * key=0 value=0 * key=1 value=1 * key=2 value=0 * key=3 value=1 * * The difference in behavior is intentional. Under PHP, a foreach by * reference loop will not visit an element that is appended to the array * during the iteration for the last element in the array. * * Under HPHP, a foreach by reference loop will always visit an element that * is appended to the array during any iteration, provided that the element * is not deleted and the loop does not exit early. */ MVCRO(" &$v) {\n" " echo \"key=$k value=$v\\n\";\n" " if ($k == 0)\n" " $val = 1;\n" " else\n" " $val = $arr[$k-1];\n" " $arr[$k+1] = $val;\n" " ++$i;\n" " if ($i >= 20)\n" " break;\n" " }\n" "}\n" "f7();\n" , "key=0 value=0\n" "key=1 value=1\n" "key=2 value=0\n" "key=3 value=1\n" "key=4 value=0\n" "key=5 value=1\n" "key=6 value=0\n" "key=7 value=1\n" "key=8 value=0\n" "key=9 value=1\n" "key=10 value=0\n" "key=11 value=1\n" "key=12 value=0\n" "key=13 value=1\n" "key=14 value=0\n" "key=15 value=1\n" "key=16 value=0\n" "key=17 value=1\n" "key=18 value=0\n" "key=19 value=1\n" ); MVCRO(" &$v) {\n" " yield null;\n" " echo \"key=$k value=$v\\n\";\n" " if ($k == 0)\n" " $val = 1;\n" " else\n" " $val = $arr[$k-1];\n" " $arr[$k+1] = $val;\n" " ++$i;\n" " if ($i >= 20)\n" " break;\n" " }\n" "}\n" "foreach (f7() as $_) {}\n" , "key=0 value=0\n" "key=1 value=1\n" "key=2 value=0\n" "key=3 value=1\n" "key=4 value=0\n" "key=5 value=1\n" "key=6 value=0\n" "key=7 value=1\n" "key=8 value=0\n" "key=9 value=1\n" "key=10 value=0\n" "key=11 value=1\n" "key=12 value=0\n" "key=13 value=1\n" "key=14 value=0\n" "key=15 value=1\n" "key=16 value=0\n" "key=17 value=1\n" "key=18 value=0\n" "key=19 value=1\n" ); MVCR(" &$v) {\n" " echo \"key=$k value=$v\\n\";\n" " if ($k == 0)\n" " $val = 1;\n" " else\n" " $val = $arr[$k-1];\n" " unset($arr[$k+1]);\n" " $bar[] = 0;\n" " $arr[$k+1] = $val;\n" " ++$i;\n" " if ($i >= 20)\n" " break;\n" " }\n" "}\n" "f8();\n"); MVCRO(" &$v) {\n" " yield null;\n" " echo \"key=$k value=$v\\n\";\n" " if ($k == 0)\n" " $val = 1;\n" " else\n" " $val = $arr[$k-1];\n" " unset($arr[$k+1]);\n" " $bar[] = 0;\n" " $arr[$k+1] = $val;\n" " ++$i;\n" " if ($i >= 20)\n" " break;\n" " }\n" "}\n" "foreach (f8() as $_) {}\n" , "key=0 value=0\n" "key=2 value=0\n" "key=1 value=1\n" "key=3 value=1\n" "key=2 value=0\n" "key=4 value=0\n" "key=3 value=1\n" "key=5 value=1\n" "key=4 value=0\n" "key=6 value=0\n" "key=5 value=1\n" "key=7 value=1\n" "key=6 value=0\n" "key=8 value=0\n" "key=7 value=1\n" "key=9 value=1\n" "key=8 value=0\n" "key=10 value=0\n" "key=9 value=1\n" "key=11 value=1\n" ); MVCR(" &$v) {\n" " echo \"k=$k v=$v\\n\";\n" " if (!$first) {\n" " $prev_k = ($k+2)%3;\n" " unset($arr[$prev_k]);\n" " if (count($bar) > 100)\n" " $bar = array();\n" " $bar[] = 1;\n" " $arr[$prev_k] = 1;\n" " }\n" " $first = false;\n" " ++$i;\n" " if ($i >= 20)\n" " break;\n" " }\n" "}\n" "f9();\n"); MVCRO(" &$v) {\n" " yield null;\n" " echo \"k=$k v=$v\\n\";\n" " if (!$first) {\n" " $prev_k = ($k+2)%3;\n" " unset($arr[$prev_k]);\n" " if (count($bar) > 100)\n" " $bar = array();\n" " $bar[] = 1;\n" " $arr[$prev_k] = 1;\n" " }\n" " $first = false;\n" " ++$i;\n" " if ($i >= 20)\n" " break;\n" " }\n" "}\n" "foreach (f9() as $_) {}\n" , "k=0 v=1\n" "k=1 v=1\n" "k=2 v=1\n" "k=0 v=1\n" "k=1 v=1\n" "k=2 v=1\n" "k=0 v=1\n" "k=1 v=1\n" "k=2 v=1\n" "k=0 v=1\n" "k=1 v=1\n" "k=2 v=1\n" "k=0 v=1\n" "k=1 v=1\n" "k=2 v=1\n" "k=0 v=1\n" "k=1 v=1\n" "k=2 v=1\n" "k=0 v=1\n" "k=1 v=1\n" ); MVCR("1,2,'b'=>3,4);\n" " $b = true;\n" " foreach ($arr as $k => &$v) {\n" " echo \"key=$k val=$v\\n\";\n" " if ($b && $v == 1) {\n" " $b = false;\n" " array_pop($arr);\n" " }\n" " }\n" "}\n" "g6();\n"); MVCRO("1,2,'b'=>3,4);\n" " $b = true;\n" " foreach ($arr as $k => &$v) {\n" " yield null;\n" " echo \"key=$k val=$v\\n\";\n" " if ($b && $v == 1) {\n" " $b = false;\n" " array_pop($arr);\n" " }\n" " }\n" "}\n" "foreach (g6() as $_) {}\n" , "key=0 val=0\n" "key=a val=1\n" "key=1 val=2\n" "key=b val=3\n" ); MVCR("1,2,'b'=>3,4);\n" " $b = true;\n" " foreach ($arr as $k => &$v) {\n" " echo \"key=$k val=$v\\n\";\n" " if ($b && $v == 1) {\n" " $b = false;\n" " unset($arr[1]); \n" " }\n" " }\n" "}\n" "g7();\n"); MVCRO("1,2,'b'=>3,4);\n" " $b = true;\n" " foreach ($arr as $k => &$v) {\n" " yield null;\n" " echo \"key=$k val=$v\\n\";\n" " if ($b && $v == 1) {\n" " $b = false;\n" " unset($arr[1]); \n" " }\n" " }\n" "}\n" "foreach (g7() as $_) {}\n" , "key=0 val=0\n" "key=a val=1\n" "key=b val=3\n" "key=2 val=4\n" ); /** * Zend PHP 5.2 outputs: * key=0 val=0 * key=a val=1 * key=0 val=0 * key=a val=1 * key=b val=3 * * The difference in behavior is intentional. Under PHP, after the next * element is unset inside the foreach by reference loop and the array_pop * operation is performed, a heuristic is used to determine which element * should be visited next. If this specific example, the loop chooses to * resume at key '0'. * * Under HPHP, when the next element is unset inside a foreach by loop, the * loop's iterator is appropriately updated. Likewise, the loop's iterator * remains intact after the array_pop operation. Thus, after the unset and * the pop operation, HPHP resumes the loop at key 'b'. */ MVCRO("1,2,'b'=>3,4);\n" " $b = true;\n" " foreach ($arr as $k => &$v) {\n" " echo \"key=$k val=$v\\n\";\n" " if ($b && $v == 1) {\n" " $b = false;\n" " unset($arr[1]); \n" " array_pop($arr);\n" " }\n" " }\n" "}\n" "g8();\n" , "key=0 val=0\n" "key=a val=1\n" "key=b val=3\n" ); MVCRO("1,2,'b'=>3,4);\n" " $b = true;\n" " foreach ($arr as $k => &$v) {\n" " yield null;\n" " echo \"key=$k val=$v\\n\";\n" " if ($b && $v == 1) {\n" " $b = false;\n" " unset($arr[1]); \n" " array_pop($arr);\n" " }\n" " }\n" "}\n" "foreach (g8() as $_) {}\n" , "key=0 val=0\n" "key=a val=1\n" "key=b val=3\n" ); MVCR("\n" " int(0)\n" " [1]=>\n" " int(0)\n" " [2]=>\n" " int(0)\n" " [3]=>\n" " int(0)\n" "}\n" "array(4) {\n" " [0]=>\n" " int(0)\n" " [1]=>\n" " int(0)\n" " [2]=>\n" " int(0)\n" " [3]=>\n" " int(0)\n" "}\n" ); MVCR(" &$v) {\n" " echo \"i=$i key=$k\\n\";\n" " if ($k == 0) {\n" " if ($i > 0) {\n" " h1($arr, $i-1);\n" " } else if ($i == 0) {\n" " echo \"Unsetting key 1\\n\";\n" " unset($arr[1]);\n" " }\n" " }\n" " }\n" " end($arr);\n" "}\n" "$arr = array('a','b','c');\n" "h1($arr, 10);\n" "var_dump($arr);\n"); MVCRO(" &$v) {\n" " yield null;\n" " echo \"i=$i key=$k\\n\";\n" " if ($k == 0) {\n" " if ($i > 0) {\n" " foreach (h1($arr, $i-1) as $_) {}\n" " } else if ($i == 0) {\n" " echo \"Unsetting key 1\\n\";\n" " unset($arr[1]);\n" " }\n" " }\n" " }\n" " end($arr);\n" "}\n" "$arr = array('a','b','c');\n" "foreach (h1($arr, 10) as $_) {}\n" "var_dump($arr);\n" , "i=10 key=0\n" "i=9 key=0\n" "i=8 key=0\n" "i=7 key=0\n" "i=6 key=0\n" "i=5 key=0\n" "i=4 key=0\n" "i=3 key=0\n" "i=2 key=0\n" "i=1 key=0\n" "i=0 key=0\n" "Unsetting key 1\n" "i=0 key=2\n" "i=1 key=2\n" "i=2 key=2\n" "i=3 key=2\n" "i=4 key=2\n" "i=5 key=2\n" "i=6 key=2\n" "i=7 key=2\n" "i=8 key=2\n" "i=9 key=2\n" "i=10 key=2\n" "array(2) {\n" " [0]=>\n" " string(1) \"a\"\n" " [2]=>\n" " string(1) \"c\"\n" "}\n" ); MVCR(" &$v) {\n" " echo $k . \"\\n\";\n" " if ($k == 2 && !isset($arr2)) {\n" " $arr2 = $arr;\n" " }\n" " $v += 100;\n" " }\n" " var_dump($arr);\n" " var_dump($arr2);\n" "}\n" "foo();\n"); MVCRO(" &$v) {\n" " yield null;\n" " echo $k . \"\\n\";\n" " if ($k == 2 && !isset($arr2)) {\n" " $arr2 = $arr;\n" " }\n" " $v += 100;\n" " }\n" " var_dump($arr);\n" " var_dump($arr2);\n" "}\n" "foreach (foo() as $_) {}\n" , "0\n" "1\n" "2\n" "3\n" "4\n" "array(5) {\n" " [0]=>\n" " int(110)\n" " [1]=>\n" " int(120)\n" " [2]=>\n" " &int(130)\n" " [3]=>\n" " int(140)\n" " [4]=>\n" " &int(150)\n" "}\n" "array(5) {\n" " [0]=>\n" " int(110)\n" " [1]=>\n" " int(120)\n" " [2]=>\n" " &int(130)\n" " [3]=>\n" " int(40)\n" " [4]=>\n" " int(50)\n" "}\n" ); MVCR(" &$v) {\n" " echo $k . \"\\n\";\n" " if ($k == 2 && !isset($arr2)) {\n" " $arr2 = $arr;\n" " $arr[] = 60;\n" " }\n" " $v += 100;\n" " }\n" " var_dump($arr);\n" " var_dump($arr2);\n" "}\n" "foo();\n"); MVCRO(" &$v) {\n" " yield null;\n" " echo $k . \"\\n\";\n" " if ($k == 2 && !isset($arr2)) {\n" " $arr2 = $arr;\n" " $arr[] = 60;\n" " }\n" " $v += 100;\n" " }\n" " var_dump($arr);\n" " var_dump($arr2);\n" "}\n" "foreach (foo() as $_) {}\n" , "0\n" "1\n" "2\n" "3\n" "4\n" "5\n" "array(6) {\n" " [0]=>\n" " int(110)\n" " [1]=>\n" " int(120)\n" " [2]=>\n" " &int(130)\n" " [3]=>\n" " int(140)\n" " [4]=>\n" " int(150)\n" " [5]=>\n" " &int(160)\n" "}\n" "array(5) {\n" " [0]=>\n" " int(110)\n" " [1]=>\n" " int(120)\n" " [2]=>\n" " &int(130)\n" " [3]=>\n" " int(40)\n" " [4]=>\n" " int(50)\n" "}\n" ); /** * Zend PHP 5.2 outputs: * val=0 * val=1 * val=2 * val=3 * val=4 * bool(false) * * The difference in behavior is intentional. Under PHP, foreach by value can * in some cases modify the array's internal iterator without triggering an * array copy. This can potentially expose information to user code about * when array copies are triggered. * * Under HPHP, foreach by value will never modify the array's internal * iterator. The advantage here is that we do not expose information about * when array copies are triggered to user code. * * The PHP manual states the following: * foreach has some side effects on the array pointer. Don't rely on the * array pointer during or after the foreach without resetting it. */ MVCRO(" &$a[foo($i++, $i++, $i++)]) {" " var_dump($a[1],$a[2]);" "}" "foreach ($a as " " $a[bar($i++, $i++, $i++)] => $a[foo($i++, $i++, $i++)]) {" " var_dump($a[1],$a[2]);" "}"); MVCR(" 1) as $k => $v) {\n" " break;\n" " }\n" " echo \"Leaving main\\n\";\n" "}\n" "main();\n"); return true; } bool TestCodeRun::TestArrayAssignment() { MVCR(" '1', 2 => 2, 'c' => '3');" "var_dump($a);" "$a = array('a' => '1', 2 => 2, 'c' => '3'," " 'd' => array('a' => '1', 2 => 2, 'c' => '3'));" "var_dump($a);"); MVCR("'main', 2=>'sub');" "$b = $a;" "var_dump(array_pop($b));" "print_r($a);" "var_dump(array_shift($b));" "print_r($a);"); MVCR("$p, '2'=>&$q);" " $b = array('3'=>$r, '4'=>&$s);" " var_dump($a);" " $a += $b;" " var_dump($a);" " var_dump($b);" "}" "foo();"); MVCR("$f($a[$obj] = 1, $value);\n" " var_dump($a[$obj] = 1);\n" "}\n" "function setNullVariant($value) {\n" " setNullVariantHelper('f', $value);\n" "}\n" "setNullVariant('Surprise!');\n" "$b = null;\n" "var_dump($b[1]);\n"); // empty string to array conversion MVCR(" 'a'),\n" " array('b' => 'bb'),\n" " array('c' => 'cc'),\n" ");\n" "\n" "$refs = array();\n" "foreach ($a as &$arr) {\n" " $refs[] = &$arr;\n" "}\n" "array_splice($a, 1, 1);\n" "var_dump($a);\n" ); MVCR(" 'y');\n" "$a = array('a1' => $x, 'a2' => $x);\n" "$b = array('a1' => array(1,2,3), 'a2' => array(1,2,3));\n" "var_dump(array_merge_recursive($a, $b));"); MVCR(" 'y');\n" "$a = array('a1' => &$x, 'a2' => &$x);\n" "$b = array('a1' => array(), 'a2' => array(1,2));\n" "var_dump(array_merge_recursive($a, $b));"); MVCR(" 'y');\n" "$a = array('a1' => &$x, 'a2' => &$x);\n" "$b = array('a1' => array(1,2), 'a2' => array(3,4));\n" "var_dump(array_merge_recursive($a, $b));"); MVCR(" 1, 3 => 3); " "var_dump(array_merge($a, array(2)));"); MVCR(" 1, 3 => 3); " "var_dump(array_merge($a, array()));"); MVCR(" 1, 3 => 3); " "var_dump(array_merge($a, array(2)));"); MVCR(" 1, 'b' => 3); " "var_dump(array_merge($a, array(2)));"); MVCR(" 1, 3 => 3); " "var_dump(array_merge($a, array('a' => 2)));"); MVCR(" 1, 3 => 3); " "var_dump(array_merge($a, array('b' => 2)));"); MVCR(" 1, 'b' => 3); " "var_dump(array_merge($a, array('c' => 2)));"); MVCR(" \"green\"," " \"red\", \"b\" => \"green\", \"blue\", \"red\");" "$result = array_unique($input);" "print_r($result);"); MVCR("$f = 100;\n" "$a = (array)$o;\n" "$v = 1;\n" "$a[10] = &$v;\n" "$a[11] = array(&$v);\n" "var_dump($a);\n" // array_diff "$b = array(10 => 10);\n" "var_dump(array_diff_key($a, $b));\n" // array_merge and array_merge_recursive "var_dump(array_merge($a, $b));\n" "var_dump(array_merge_recursive($a, $b));\n" // array_reverse "var_dump(array_reverse($a));\n" // array_chunk "var_dump(array_chunk($a, 2));\n" ); // Test array_reduce MVCR(" 22)));"); return true; } bool TestCodeRun::TestArrayCSE() { HipHopSyntax w0(this); OptionSetter w1(this, OptionSetter::CompileTime, "-vArrayAccessIdempotent=1"); MVCR(" array('baz' => 40)), 'e');\n" "var_dump(f(array('y' => array()), 'y'));\n" "var_dump(f(array(), 'y'));\n" "var_dump(f(array(), array()));\n" "h(array(), 0);\n" "h(array(array()), 0);\n"); MVCRO("\n" " array(1) {\n" " [0]=>\n" " int(30)\n" " }\n" "}\n" "array(1) {\n" " [0]=>\n" " int(30)\n" "}\n" "string(1) \"b\"\n" "string(1) \"a\"\n" "string(1) \"b\"\n" "string(0) \"\"\n" "string(0) \"\"\n" "string(0) \"\"\n" "string(1) \"b\"\n" "string(0) \"\"\n" "string(1) \"b\"\n"); MVCR("x = $x;\n" " }\n" " public function offsetSet($offset, $value) {\n" " $this->x[$offset] = $value;\n" " }\n" " public function offsetExists($offset) {\n" " return isset($this->x[$offset]);\n" " }\n" " public function offsetUnset($offset) {\n" " unset($this->x[$offset]);\n" " }\n" " public function offsetGet($offset) {\n" " return $this->x[$offset];\n" " }\n" "}\n" "$o = new ArrayWrap(array(0, 1, 2));\n" "\n" "function f1($x) {\n" " return isset($x[0]) && $x[0];\n" "}\n" "var_dump(f1(null));\n" "var_dump(f1(array()));\n" "var_dump(f1(array(0)));\n" "var_dump(f1(''));\n" "var_dump(f1('a'));\n" "var_dump(f1($o));\n" "\n" "function f2($x) {\n" " if (!is_null($x[0])) var_dump($x[0]);\n" " var_dump($x[0]);\n" "}\n" "f2(array(0 => array()));\n" "f2(array());\n" "f2('');\n" "f2($o);\n" "f2(null);\n" "\n" "function f3($x) {\n" " foreach ($x['foo'] as $k => $v) {\n" " if ($v) unset($x['foo'][$k]);\n" " }\n" " var_dump($x);\n" "}\n" "f3(array('foo' => array(0,1,2,3)));\n" "\n" "function f4($x) {\n" " var_dump($x[0][1]);\n" " unset($x[0][1]);\n" " var_dump($x[0][1]);\n" "}\n" "f4(array(array(1 => new stdClass())));\n" "\n" "function f5($x) {\n" " var_dump(md5($x[0]), $x[0]);\n" "}\n" "f5('foobar');\n"); MVCR("function f1($x) {\n" " if (count($x) > 0) { \n" " var_dump($x); \n" " } else if (count($x[0]) > 0) {\n" " var_dump($x[0]);\n" " }\n" "}\n" "f1(array(array(0, 1, 2)));\n" "f1('abc');\n" "\n" "function id($x) { return $x; }\n" "function f2($x) {\n" " if ($x[0]) var_dump(id($x), $x[0]);\n" "}\n" "f2(null);\n" "f2(array());\n" "f2(array(10));\n" "\n" "function f3($x) {\n" " var_dump($x[0].'/'. $x[1]);\n" " var_dump($x[0].'/'. $x[1]);\n" "}\n" "f3(array('first', 'second'));\n" "f3('AB');\n" "\n" "function f4($x) {\n" " $z = @id($x[0]);\n" " var_dump($z);\n" " var_dump($x[0]);\n" "}\n" "f4(array('e1', 'e2'));\n" "\n" "function f5($x) {\n" " if ($x[0][id($x[0])-1]) var_dump($x);\n" "}\n" "f5(array(0, 1, 2));\n"); MVCR("function id($x) { return $x; }\n" "function f1($x) {\n" " $z = id($x[0]);\n" " foreach ($x[0] as $a) {\n" " $z[] = array(id($z), count($x[0]));\n" " }\n" "}\n" "f1(array(array(0, 1, 2, 3)));\n" "\n" "function f2($x) {\n" " var_dump($x[0]);\n" " $y = 'foo' . $x[0] . 'bar';\n" "}\n" "f2('foobar');\n" "\n" "function f3($x) {\n" " $x = is_string($x[0]) ? $x[0] : get_class($x[0]);\n" " return $x;\n" "}\n" "var_dump(f3('abc'));\n" "var_dump(f3(array(new stdClass)));\n"); MVCR(" array($GLOBALS['foo']),\n" " 20 => array($GLOBALS['foo']));\n" "var_dump($GLOBALS['bar']);\n"); MVCR(" $v) {\n" " var_dump($x[0]);\n" " var_dump($k, $v);\n" " }\n" "}\n" "function f5($x) {\n" " switch ($x[0]) {\n" " case 0:\n" " var_dump($x[0]);\n" " }\n" "}\n" "function f6($x, $y, $z) {\n" " if ($z) goto my_clause;\n" " if ($y) { var_dump($y); }\n" " else if ($x[0]) {\n" " var_dump($x[0]);\n" " my_clause:\n" " var_dump($x);\n" " }\n" "}\n" "f1(array(0, 0));\n" "f2(array(10));\n" "f3(array(10), false);\n" "f4(array(array(1, 2, 3)));\n" "f5(array(false, false));\n" "f6(array(true), false, false);\n"); MVCR("> 2);"); MVCR("> $b);"); MVCR("> $b);"); MVCR(">= 2; var_dump($a);"); MVCR("var1 = 1; }" "f();"); //#147156 return true; } bool TestCodeRun::TestObject() { HipHopSyntax w(this); MVCR("a++; " "$obj3 = new B(); $obj3->a = 10;" "var_dump($obj1->a);" "var_dump($obj1);" "var_dump($obj2->a);" "var_dump($obj2);" "var_dump($obj3);" "var_dump($obj1 instanceof A);" "var_dump($obj3 instanceof A);" "var_dump($obj1 instanceof B);" "var_dump($obj3 instanceof B);" ); MVCR("a = $a + 1;" " }" " public function __destruct() {" " $this->a += 2;" " var_dump($this->a);" " }" "}" "class B extends A {" " public function __construct($a) {" " }" "}" "class C extends A {" " public function __construct($a) {" " parent::__construct($a);" " }" "}" "$obj = new A(1); var_dump($obj->a);" "$obj = new B(1); var_dump($obj->a);" "$obj = new C(1); var_dump($obj->a);" "unset($obj);" ); MVCR("c);" ); MVCR("b);*/" // undeclared "$obj = new B(); var_dump($obj); var_dump($obj->b);" ); MVCR("a);" "$obj = new B(); var_dump($obj); var_dump($obj->b);" ); MVCR("b);" "$obj = new B(); var_dump($obj); var_dump($obj->b);" ); MVCR("b);" "$obj = new B(); var_dump($obj); var_dump($obj->b);" ); MVCR("test('cool');" ); MVCR("test(1);" "$obj = new B(); $obj->test(1);" ); // circular references MVCR("a = $obj2; $obj2->a = $obj1;" "var_dump($obj1);"); MVCR("t();"); MVCR("v = $v;" " return $this;" " }" "}" "function foo() {" " $z = 1;" " $qd = array('x' => $z);" " $a = G()->set($qd);" " var_dump($a);" " $qd['e'] = true;" " $b = G()->set($qd);" " var_dump($a);" "" "}" "function G() {" " return new g;" "}" "foo();"); MVCR("c = 3;" "var_dump($obj);" "foreach ($obj as &$value) {" " $value = 2;" "}" "var_dump($obj);"); MVCRO("c = 3;" " var_dump($obj);" " foreach ($obj as &$value) {" " yield null;" " $value = 2;" " }" " var_dump($obj);" "}" "foreach (gen() as $_) {}" , "object(A)#2 (2) {\n" " [\"a\"]=>\n" " NULL\n" " [\"b\"]=>\n" " NULL\n" "}\n" "object(A)#2 (2) {\n" " [\"a\"]=>\n" " int(1)\n" " [\"b\"]=>\n" " &int(1)\n" "}\n" "object(A)#2 (3) {\n" " [\"a\"]=>\n" " int(1)\n" " [\"b\"]=>\n" " &int(1)\n" " [\"c\"]=>\n" " int(3)\n" "}\n" "object(A)#2 (3) {\n" " [\"a\"]=>\n" " int(2)\n" " [\"b\"]=>\n" " int(2)\n" " [\"c\"]=>\n" " &int(2)\n" "}\n" ); MVCR(" &$value) {" " $value = 'ok';" "}" "var_dump($obj);" "var_dump($obj2);"); MVCRO(" &$value) {" " yield null;" " $value = 'ok';" " }" " var_dump($obj);" " var_dump($obj2);" "}" "foreach (gen() as $_) {}" , "object(A)#2 (2) {\n" " [\"a\"]=>\n" " string(2) \"ok\"\n" " [\"b\"]=>\n" " &string(2) \"ok\"\n" "}\n" "object(A)#2 (2) {\n" " [\"a\"]=>\n" " string(2) \"ok\"\n" " [\"b\"]=>\n" " &string(2) \"ok\"\n" "}\n" ); MVCR("a = $p1;" " $this->b = $p2;" " $this->c = $p3;" " $this->d = $p4;" " }" "};" "$obj = new A(1, 2, 3, 4);" "foreach ($obj as $key => &$val) {" " if($val == 2) {" " $obj->$key = 0;" " } else if($val == 3) {" " var_dump($key);" " unset($obj->$key);" " } else {" " $val++;" " }" "}" "var_dump($obj);"); MVCRO("a = $p1;" " $this->b = $p2;" " $this->c = $p3;" " $this->d = $p4;" " }" "};" "function gen() {" " $obj = new A(1, 2, 3, 4);" " foreach ($obj as $key => &$val) {" " yield null;" " if($val == 2) {" " $obj->$key = 0;" " } else if($val == 3) {" " var_dump($key);" " unset($obj->$key);" " } else {" " $val++;" " }" " }" " var_dump($obj);" "}" "foreach (gen() as $_) {}" , "string(1) \"c\"\n" "object(A)#2 (3) {\n" " [\"a\"]=>\n" " int(2)\n" " [\"b\"]=>\n" " int(0)\n" " [\"d\"]=>\n" " &int(5)\n" "}\n" ); MVCR("a = 1;" " $this->b = 2;" " $this->c = 3;" " $this->d = 4;" " }" "};" "function f() {" " $obj = new A();" " foreach ($obj as $key => &$val) {" " $val = 5;" " }" " var_dump($obj);" "}" "f();"); MVCRO("a = 1;" " $this->b = 2;" " $this->c = 3;" " $this->d = 4;" " }" "};" "function f() {" " $obj = new A();" " foreach ($obj as $key => &$val) {" " yield null;" " $val = 5;" " }" " var_dump($obj);" "}" "foreach (f() as $_) {}" , "object(A)#2 (4) {\n" " [\"a\"]=>\n" " int(5)\n" " [\"b\"]=>\n" " int(5)\n" " [\"c\"]=>\n" " int(5)\n" " [\"d\"]=>\n" " &int(5)\n" "}\n" ); MVCR("x);" " $x = new X;" " var_dump($x->x);" "}" "test();"); MVCR("p = \"changed\";\n" " $x = $this;\n" " }\n" "}\n" "$c = new C();\n" "var_dump($c);\n" "$c = null;\n" "$y = 140;\n" "var_dump($x);\n" "$x = null;\n"); MVCR("foo();" " }" "}" "test(45, 0);" "test(77, 1);"); MVCR("{__fUNCTION__} = 1;\n" " $obj->{__cLASS__} = 2;\n" " $obj->__FuNCTION__ = 3;\n" " $obj->__ClASS__ = 4;\n" " $obj->{__FUnCTION__}();\n" " $obj->{__CLaSS__}();\n" " $obj->__FUNcTION__();\n" " $obj->__CLAsS__();\n" " $arr = array();\n" " foreach ($obj as $k => $v) {\n" " $arr[$k] = $v;\n" " }\n" " ksort($arr);\n" " var_dump($arr);\n" " }\n" "}\n" "tEst::eXclaiM();\n"); return true; } bool TestCodeRun::TestObjectProperty() { MVCR("a);\n" "var_dump($old);\n" "\n" "$new = new A;\n" "unset($new->b);\n" "var_dump($new);\n" "\n" "foreach ($new as $property => $value) {\n" " $old->$property = $value;\n" "}\n" "var_dump($old->a);\n" "var_dump($old->b);\n" // We can't really maintain the same order as PHP does, even though we // can move unset and reset properties to the back of the list, but // then we can't really tell who's added back first if there are two :-( //"var_dump($old);\n" ); MVCR("a), property_exists($obj, 'a'));\n" "$obj->a = null;\n" "var_dump(isset($obj->a), property_exists($obj, 'a'));\n" "unset($obj->a);\n" "var_dump(isset($obj->a), property_exists($obj, 'a'));\n" "$obj->a = 123;\n" "var_dump(isset($obj->a), property_exists($obj, 'a'));\n" "$obj->a = null;\n" "var_dump(isset($obj->a), property_exists($obj, 'a'));\n" ); MVCR("$name;\n" " }}\n" "\n" "$obj = new A();\n" "var_dump($obj->prop);\n" ); MVCR("a = 20;} } " "class B extends A { public $a = 'test';} " "$obj = new B(); $obj->foo(); var_dump($obj->a);"); MVCR("a);} } " "class C extends B { public $a = 'test';} " "$obj = new C(); $obj->foo();"); MVCR(" $v) {" " var_dump($v);" " }" " }" "}" "class d extends c {" " public $a = 'a';" " private $b = 'b';" " protected $c = 'c';" " function t2($y) {" " foreach ($this as $k => $v) {" " var_dump($v);" " }" " foreach ($y as $k => $v) {" " var_dump($v);" " }" " foreach ($y as $k => $v) {" " var_dump($v);" " }" " }" "}" "$x = new d;" "$x->surprise = 1;" "$y = new d;" "$y->shock = 2;" "echo \"t2\n\";" "$x->t2($y);" "echo \"t1\n\";" "$x->t1($y);" "$z = new c;" "echo \"t12\n\";" "$z->t1($x);" "foreach ($x as $k => $v) {" " var_dump($v);" "}"); MVCR(" 1, 'version'=>2);" "var_dump(isset($one->cluster));" "var_dump(empty($one->cluster));" "$two = 'hello';" "var_dump(isset($two->scalar));"); MVCR("pri);" " $pri = $q ? 'zz' : 'p'.'ri';" " var_dump($this->$pri);" " }" " function bar2() {" " var_dump($this->pro);" " }" "}" "class B extends A {" " private $pri = 'b-pri';" " function bar() {" " parent::bar();" " var_dump($this->pri);" " }" "}" "$obj = new B(); $obj->bar();" "class C extends B {" " public $pri = 'c-pri';" " public $pro = 'c-pro';" " function bar2() {" " parent::bar2();" " var_dump($this->pro);" " }" "}" "$obj = new C; $obj->bar(); $obj->bar2();" "var_dump(serialize($obj));" "class Base {" " protected $pro = 1;" " private $pri = 'base-pri';" " function q0() {" " var_dump($this->pri);" " }" "}" "" "class R extends Base {" " public $rpub = 1;" " protected $pro = 2;" " private $pri = 'r-pri';" " function q() {" " var_dump($this->pri);" " }" "}" "" "class D extends R {" " public $dpub = 'd';" " protected $pro = 'pro';" " private $pri = 'd-pri';" " function qq() {" " var_dump($this->pri);" " }" "}" "" "class DD extends D {" " private $pri = 'dd-pri';" " function qqq() {" " var_dump($this->pri);" " }" "}" "" "if (false) {" " class R{}" "}" "$d = new D;" "$d->qq();" "$d->q();" "$d->q0();" "$d = new DD;" "$d->qqq();" "$d->qq();" "$d->q();" "$d->q0();" ); MVCR("$f = 100;\n" "var_dump($a);\n" "unset($a->$f);\n" "var_dump($a);\n"); MVCR("y(f(),$x->x);" " var_dump($x);" " $x->y(0,$x->x);" " var_dump($x);" "}" "test();"); MVCR("b);" " var_dump($b);" " foreach ($b as $prop => $value) {" " var_dump($prop);" " }" " }" "}" "A::foo();"); MVCR("foo));" "var_dump(isset($x->baz));" "var_dump(isset($x->buz));" "var_dump(isset($x->pub_var));" "var_dump(isset($x->pub_set));" "var_dump(isset($x->priv_var));" "var_dump(empty($x->foo));" "var_dump(empty($x->baz));" "var_dump(empty($x->buz));" "var_dump(empty($x->pub_var));" "var_dump(empty($x->pub_set));" "var_dump(empty($x->priv_var));" "unset($x->pub_var);" "var_dump(isset($x->pub_var));" "var_dump(empty($x->pub_var));"); MVCR(" &$v) { var_dump($k); $v = 100; }\n" " var_dump($this);\n" " }\n" "}\n" "$b = new B();\n" "$b->f();\n" "function f() {\n" " $o = new B();\n" " foreach ($o as $k => &$v) { var_dump($k); $v = 100; }\n" " var_dump($o);\n" "}\n" "f();\n"); // empty property name shouldn't crash MVCR(" 30);" " public static function foo($type, $key) {" " return isset( self::${$type}[$key] );" " }" "}" "var_dump(Test::foo('color', 'gray'));"); MVCR("v = array(1, 2);" " return $x;" "}" "foo()->v[0] += 5;" "var_dump(shuffle(foo()->v));"); MVCR("data = $result;" " }" "}" "function foo($obj) {" " $obj->data = new A;" " $a = $obj->data;" " var_dump($a);" " $obj->setData(null);" " $a = $obj->data;" " var_dump($a);" "}" "foo(new B);"); MVCR("b = true;" " $this->i = 5;" " $this->a = array(1,2,3);" " $this->s = 'goodbye';" " }" " function foo() {" " var_dump($this->b, $this->i, $this->a, $this->s);" " }" "}" "function test() {" " $x = new X;" " $x->set();" " $s = serialize($x);" " $y = unserialize($s);" " $y->foo();" " var_dump($y);" "}" "test();"); MVCR("$v)); }" "test(false, \"\");" "test(false, \"\\0foo\");" "test(true, \"\");" "test(true, \"\\0foo\");" "test(new stdclass, \"\");" "test(new stdclass, \"\\0foo\");"); MVCRNW("$v); }" "test(false, \"\");" "test(false, \"\\0foo\");" "test(true, \"\");" "test(true, \"\\0foo\");" "test(new stdclass, \"\");"); MVCRNW("$v); }" "test(new stdclass, \"\\0foo\");"); MVCRNW("$v = 1); }" "test(true, \"\");" "test(true, \"\\0foo\");" "test(false, \"\");"); MVCRNW("$v = 1); }" "test(false, \"\\0foo\");"); MVCRNW("$v = 1); }" "test(new stdclass, \"\");"); MVCRNW("$v = 1); }" "test(new stdclass, \"\\0foo\");"); MVCRNW("$v++); }" "test(true, \"\");" "test(true, \"\\0foo\");" "test(false, \"\");"); MVCRNW("$v++); }" "test(false, \"\\0foo\");"); MVCRNW("$v++); }" "test(new stdclass, \"\");"); MVCRNW("$v++); }" "test(new stdclass, \"\\0foo\");"); MVCRNW("$v += 1); }" "test(true, \"\");" "test(true, \"\\0foo\");" "test(false, \"\");"); MVCRNW("$v += 1); }" "test(false, \"\\0foo\");"); MVCRNW("$v += 1); }" "test(new stdclass, \"\");"); MVCRNW("$v += 1); }" "test(new stdclass, \"\\0foo\");"); MVCRNW("$v); var_dump($x); }" "test(false, \"\");" "test(false, \"\\0foo\");" "test(true, \"\");" "test(true, \"\\0foo\");" "test(new stdclass, \"\");"); MVCRNW("$v); var_dump($x); }" "test(new stdclass, \"\\0foo\");"); MVCRNW("$y);"); MVCRNW("$y =& $z);"); MVCR("foo()->bar);" " var_dump($x->foo()->bar);" " var_dump($x->foo()->bar);" " var_dump(foo()->bar);" " foo()->bar = 6;" " var_dump(foo()->bar);" " foo()->bar = 7;" " var_dump(foo()->bar);" " foo()->bar = 8;" " var_dump(foo()->bar);" " bar()->bar = 6;" " var_dump(bar()->bar);" " bar()->bar = 7;" " var_dump(bar()->bar);" " bar()->bar = 8;" " var_dump(bar()->bar);" "}" "test();"); return true; } bool TestCodeRun::TestObjectMethod() { MVCR("test(); $obj = 1;"); // calling a function that's implemented in a derived class MVCR("test();} }" "class R extends T { function test() { var_dump('test'); }} " "$obj = new R(); $obj->test(); $obj->foo();"); MVCR("test();}} " "class B extends A { function test() { print 'B';}} " "$obj = new A(); $obj = new B(); $obj->foo();"); MVCR("test();}}" "$obj = new AA(); $b = new B(); $b->foo($obj);" ); // calling a virtual function MVCR("test();} }" "class R extends T { function test() { var_dump('test'); }} " "$obj = new R(); $obj->test(); $obj->foo();"); // calling a virtual function MVCR("test();"); MVCR("test2();" "foo::test1();" "foo::test2();" "foo::test3();" "$obj->test3();" "$obj->test4();"); // calling instance method statically MVCR("a);" " }" " function g() {" " $this->a = 100;" " call_user_func(array('self', 'f'));" " }" "}"); MVCR("foo(meh());" " $p = null;" "}" "z();"); MVCR("f();" "function g() {" " $y = new m3;" " var_dump($y->meth());" "}" "g();"); MVCR("x();"); MVCR("privateData = 1;" " var_dump('ok');" " }" " public function f2() {" " $this->f1();" " }" "}" "function foo() {" " $obj = new Test();" " $obj->f2();" " $obj->privateData = 2;" " $obj = new Base();" "}" "foo();"); #define TEST_BODY_FOR_IS_CALLABLE \ "var_dump(is_callable('A::a_spub'));" \ "var_dump(is_callable('A::a_spro'));" \ "var_dump(is_callable('A::a_spri'));" \ "var_dump(is_callable('A::a_pro'));" \ "var_dump(is_callable('A::a_pri'));" \ "var_dump(is_callable('a_spub'));" \ "var_dump(is_callable('a_spro'));" \ "var_dump(is_callable('a_spri'));" \ "var_dump(is_callable('a_pub'));" \ "var_dump(is_callable('a_pro'));" \ "var_dump(is_callable('a_pri'));" \ "var_dump(is_callable('B::b_spub'));" \ "var_dump(is_callable('B::b_spro'));" \ "var_dump(is_callable('B::b_spri'));" \ "var_dump(is_callable('B::b_pro'));" \ "var_dump(is_callable('B::b_pri'));" \ "var_dump(is_callable('b_spub'));" \ "var_dump(is_callable('b_spro'));" \ "var_dump(is_callable('b_spri'));" \ "var_dump(is_callable('b_pub'));" \ "var_dump(is_callable('b_pro'));" \ "var_dump(is_callable('b_pri'));" \ "var_dump(is_callable(array('A', 'a_spub')));" \ "var_dump(is_callable(array('A', 'a_spro')));" \ "var_dump(is_callable(array('A', 'a_spri')));" \ "var_dump(is_callable(array('A', 'a_pub')));" \ "var_dump(is_callable(array('A', 'a_pro')));" \ "var_dump(is_callable(array('A', 'a_pri')));" \ "var_dump(is_callable(array('A', 'A::a_spub')));" \ "var_dump(is_callable(array('A', 'A::a_spro')));" \ "var_dump(is_callable(array('A', 'A::a_spri')));" \ "var_dump(is_callable(array('A', 'A::a_pro')));" \ "var_dump(is_callable(array('A', 'A::a_pri')));" \ "var_dump(is_callable(array('A', 'A::A::a_spub')));" \ "var_dump(is_callable(array('A', 'A::A::a_spro')));" \ "var_dump(is_callable(array('A', 'A::A::a_spri')));" \ "var_dump(is_callable(array('A', 'A::A::a_pro')));" \ "var_dump(is_callable(array('A', 'A::A::a_pri')));" \ "var_dump(is_callable(array('A', 'C::a_spub')));" \ "var_dump(is_callable(array('A', 'C::a_spro')));" \ "var_dump(is_callable(array('A', 'C::a_spri')));" \ "var_dump(is_callable(array('A', 'C::a_pub')));" \ "var_dump(is_callable(array('A', 'C::a_pro')));" \ "var_dump(is_callable(array('A', 'C::a_pri')));" \ "var_dump(is_callable(array('A', 'A::C::a_spub')));" \ "var_dump(is_callable(array('A', 'A::C::a_spro')));" \ "var_dump(is_callable(array('A', 'A::C::a_spri')));" \ "var_dump(is_callable(array('A', 'A::C::a_pub')));" \ "var_dump(is_callable(array('A', 'A::C::a_pro')));" \ "var_dump(is_callable(array('A', 'A::C::a_pri')));" \ "var_dump(is_callable(array('A', 'b_spub')));" \ "var_dump(is_callable(array('A', 'b_spro')));" \ "var_dump(is_callable(array('A', 'b_spri')));" \ "var_dump(is_callable(array('A', 'b_pub')));" \ "var_dump(is_callable(array('A', 'b_pro')));" \ "var_dump(is_callable(array('A', 'b_pri')));" \ "var_dump(is_callable(array('A', 'B::a_spub')));" \ "var_dump(is_callable(array('A', 'B::a_spro')));" \ "var_dump(is_callable(array('A', 'B::a_spri')));" \ "var_dump(is_callable(array('A', 'B::a_pub')));" \ "var_dump(is_callable(array('A', 'B::a_pro')));" \ "var_dump(is_callable(array('A', 'B::a_pri')));" \ "var_dump(is_callable(array('A', 'B::B::a_spub')));" \ "var_dump(is_callable(array('A', 'B::B::a_spro')));" \ "var_dump(is_callable(array('A', 'B::B::a_spri')));" \ "var_dump(is_callable(array('A', 'B::B::a_pub')));" \ "var_dump(is_callable(array('A', 'B::B::a_pro')));" \ "var_dump(is_callable(array('A', 'B::B::a_pri')));" \ "var_dump(is_callable(array('B', 'a_spub')));" \ "var_dump(is_callable(array('B', 'a_spro')));" \ "var_dump(is_callable(array('B', 'a_spri')));" \ "var_dump(is_callable(array('B', 'a_pub')));" \ "var_dump(is_callable(array('B', 'a_pro')));" \ "var_dump(is_callable(array('B', 'a_pri')));" \ "var_dump(is_callable(array('B', 'A::a_spub')));" \ "var_dump(is_callable(array('B', 'A::a_spro')));" \ "var_dump(is_callable(array('B', 'A::a_spri')));" \ "var_dump(is_callable(array('B', 'A::a_pro')));" \ "var_dump(is_callable(array('B', 'A::a_pri')));" \ "var_dump(is_callable(array('B', 'A::A::a_spub')));" \ "var_dump(is_callable(array('B', 'A::A::a_spro')));" \ "var_dump(is_callable(array('B', 'A::A::a_spri')));" \ "var_dump(is_callable(array('B', 'A::A::a_pro')));" \ "var_dump(is_callable(array('B', 'A::A::a_pri')));" \ "var_dump(is_callable(array('B', 'C::a_spub')));" \ "var_dump(is_callable(array('B', 'C::a_spro')));" \ "var_dump(is_callable(array('B', 'C::a_spri')));" \ "var_dump(is_callable(array('B', 'C::a_pub')));" \ "var_dump(is_callable(array('B', 'C::a_pro')));" \ "var_dump(is_callable(array('B', 'C::a_pri')));" \ "var_dump(is_callable(array('B', 'B::C::a_spub')));" \ "var_dump(is_callable(array('B', 'B::C::a_spro')));" \ "var_dump(is_callable(array('B', 'B::C::a_spri')));" \ "var_dump(is_callable(array('B', 'B::C::a_pub')));" \ "var_dump(is_callable(array('B', 'B::C::a_pro')));" \ "var_dump(is_callable(array('B', 'B::C::a_pri')));" \ "var_dump(is_callable(array('B', 'b_spub')));" \ "var_dump(is_callable(array('B', 'b_spro')));" \ "var_dump(is_callable(array('B', 'b_spri')));" \ "var_dump(is_callable(array('B', 'b_pub')));" \ "var_dump(is_callable(array('B', 'b_pro')));" \ "var_dump(is_callable(array('B', 'b_pri')));" \ "var_dump(is_callable(array('B', 'B::a_spub')));" \ "var_dump(is_callable(array('B', 'B::a_spro')));" \ "var_dump(is_callable(array('B', 'B::a_spri')));" \ "var_dump(is_callable(array('B', 'B::a_pub')));" \ "var_dump(is_callable(array('B', 'B::a_pro')));" \ "var_dump(is_callable(array('B', 'B::a_pri')));" \ "var_dump(is_callable(array('B', 'B::A::a_spub')));" \ "var_dump(is_callable(array('B', 'B::A::a_spro')));" \ "var_dump(is_callable(array('B', 'B::A::a_spri')));" \ "var_dump(is_callable(array('B', 'B::A::a_pro')));" \ "var_dump(is_callable(array('B', 'B::A::a_pri')));" \ "var_dump(is_callable(array('B', 'B::B::a_spub')));" \ "var_dump(is_callable(array('B', 'B::B::a_spro')));" \ "var_dump(is_callable(array('B', 'B::B::a_spri')));" \ "var_dump(is_callable(array('B', 'B::B::a_pub')));" \ "var_dump(is_callable(array('B', 'B::B::a_pro')));" \ "var_dump(is_callable(array('B', 'B::B::a_pri')));" \ "var_dump(is_callable(array(new A(), 'a_spub')));" \ "var_dump(is_callable(array(new A(), 'a_spro')));" \ "var_dump(is_callable(array(new A(), 'a_spri')));" \ "var_dump(is_callable(array(new A(), 'a_pub')));" \ "var_dump(is_callable(array(new A(), 'a_pro')));" \ "var_dump(is_callable(array(new A(), 'a_pri')));" \ "var_dump(is_callable(array(new A(), 'A::a_spub')));" \ "var_dump(is_callable(array(new A(), 'A::a_spro')));" \ "var_dump(is_callable(array(new A(), 'A::a_spri')));" \ "var_dump(is_callable(array(new A(), 'A::a_pro')));" \ "var_dump(is_callable(array(new A(), 'A::a_pri')));" \ "var_dump(is_callable(array(new A(), 'A::A::a_spub')));" \ "var_dump(is_callable(array(new A(), 'A::A::a_spro')));" \ "var_dump(is_callable(array(new A(), 'A::A::a_spri')));" \ "var_dump(is_callable(array(new A(), 'A::A::a_pro')));" \ "var_dump(is_callable(array(new A(), 'A::A::a_pri')));" \ "var_dump(is_callable(array(new A(), 'C::a_spub')));" \ "var_dump(is_callable(array(new A(), 'C::a_spro')));" \ "var_dump(is_callable(array(new A(), 'C::a_spri')));" \ "var_dump(is_callable(array(new A(), 'C::a_pub')));" \ "var_dump(is_callable(array(new A(), 'C::a_pro')));" \ "var_dump(is_callable(array(new A(), 'C::a_pri')));" \ "var_dump(is_callable(array(new A(), 'A::C::a_spub')));" \ "var_dump(is_callable(array(new A(), 'A::C::a_spro')));" \ "var_dump(is_callable(array(new A(), 'A::C::a_spri')));" \ "var_dump(is_callable(array(new A(), 'A::C::a_pub')));" \ "var_dump(is_callable(array(new A(), 'A::C::a_pro')));" \ "var_dump(is_callable(array(new A(), 'A::C::a_pri')));" \ "var_dump(is_callable(array(new A(), 'b_spub')));" \ "var_dump(is_callable(array(new A(), 'b_spro')));" \ "var_dump(is_callable(array(new A(), 'b_spri')));" \ "var_dump(is_callable(array(new A(), 'b_pub')));" \ "var_dump(is_callable(array(new A(), 'b_pro')));" \ "var_dump(is_callable(array(new A(), 'b_pri')));" \ "var_dump(is_callable(array(new A(), 'B::a_spub')));" \ "var_dump(is_callable(array(new A(), 'B::a_spro')));" \ "var_dump(is_callable(array(new A(), 'B::a_spri')));" \ "var_dump(is_callable(array(new A(), 'B::a_pub')));" \ "var_dump(is_callable(array(new A(), 'B::a_pro')));" \ "var_dump(is_callable(array(new A(), 'B::a_pri')));" \ "var_dump(is_callable(array(new A(), 'B::A::a_spub')));" \ "var_dump(is_callable(array(new A(), 'B::A::a_spro')));" \ "var_dump(is_callable(array(new A(), 'B::A::a_spri')));" \ "var_dump(is_callable(array(new A(), 'B::A::a_pro')));" \ "var_dump(is_callable(array(new A(), 'B::A::a_pri')));" \ "var_dump(is_callable(array(new B(), 'b_spub')));" \ "var_dump(is_callable(array(new B(), 'b_spro')));" \ "var_dump(is_callable(array(new B(), 'b_spri')));" \ "var_dump(is_callable(array(new B(), 'b_pub')));" \ "var_dump(is_callable(array(new B(), 'b_pro')));" \ "var_dump(is_callable(array(new B(), 'b_pri')));" \ "var_dump(is_callable(array(new B(), 'B::b_spub')));" \ "var_dump(is_callable(array(new B(), 'B::b_spro')));" \ "var_dump(is_callable(array(new B(), 'B::b_spri')));" \ "var_dump(is_callable(array(new B(), 'B::b_pro')));" \ "var_dump(is_callable(array(new B(), 'B::b_pri')));" \ "var_dump(is_callable(array(new B(), 'B::B::b_spub')));" \ "var_dump(is_callable(array(new B(), 'B::B::b_spro')));" \ "var_dump(is_callable(array(new B(), 'B::B::b_spri')));" \ "var_dump(is_callable(array(new B(), 'B::B::b_pro')));" \ "var_dump(is_callable(array(new B(), 'B::B::b_pri')));" \ "var_dump(is_callable(array(new B(), 'C::b_spub')));" \ "var_dump(is_callable(array(new B(), 'C::b_spro')));" \ "var_dump(is_callable(array(new B(), 'C::b_spri')));" \ "var_dump(is_callable(array(new B(), 'C::b_pub')));" \ "var_dump(is_callable(array(new B(), 'C::b_pro')));" \ "var_dump(is_callable(array(new B(), 'C::b_pri')));" \ "var_dump(is_callable(array(new B(), 'B::C::b_spub')));" \ "var_dump(is_callable(array(new B(), 'B::C::b_spro')));" \ "var_dump(is_callable(array(new B(), 'B::C::b_spri')));" \ "var_dump(is_callable(array(new B(), 'B::C::b_pub')));" \ "var_dump(is_callable(array(new B(), 'B::C::b_pro')));" \ "var_dump(is_callable(array(new B(), 'B::C::b_pri')));" \ "var_dump(is_callable(array(new B(), 'a_spub')));" \ "var_dump(is_callable(array(new B(), 'a_spro')));" \ "var_dump(is_callable(array(new B(), 'a_spri')));" \ "var_dump(is_callable(array(new B(), 'a_pub')));" \ "var_dump(is_callable(array(new B(), 'a_pro')));" \ "var_dump(is_callable(array(new B(), 'a_pri')));" \ "var_dump(is_callable(array(new B(), 'A::B::b_spub')));" \ "var_dump(is_callable(array(new B(), 'A::B::b_spro')));" \ "var_dump(is_callable(array(new B(), 'A::B::b_spri')));" \ "var_dump(is_callable(array(new B(), 'A::B::b_pro')));" \ "var_dump(is_callable(array(new B(), 'A::B::b_pri')));" \ MVCRNW("a_sf();" "$obj->b_sf();" "$obj->a_f();" "$obj->b_f();"); MVCR("foo(); }" "}" "function test($y,$z) {" " $y->$z($y);" "}" "test(new Y, 'bar');"); MVCR("id.\")>\"; }\n" " private function f4helper($a) { return $x=$a+12; }\n" "}\n" "class G extends B {\n" " public $pointless;\n" " function __call($name, $arguments) {\n" " // keep f4bogus from fatalling\n" " echo \"Calling G object method '$name' \" . " "implode(', ', $arguments). \"\\n\";\n" " }\n" " function __construct($i) { $this->id=$i; }\n" " function f($a) { $this->trace(\"G::f\"); return $a; }\n" " function f1($a) { return $a; } // override\n" " function flongerthan8($a,$b,$c) { return $a+$b+$c+1; }\n" " function f4($a) { return B::f4($a); } \n" " // check SimpleFunctionCall::outputCPPParamOrderControlled\n" " /// !m_valid, !m_className.empty() case\n" " // called method must not exist anywhere even though it\n" " // looks like it might\n" " function f4missing($a) { \n" " // check SimpleFunctionCall::outputCPPParamOrderControlled\n" " // !m_valid, !m_className.empty() cases\n" "\n" " // m_validClass \n" " echo \"Calling G object 'f4missing' 3 == \"; \n" " //php53 echo parent::f4missing(3),\"\\n\"; // fatals in PHP\n" "\n" " // !m_validClass, m_class\n" " $b=\"B\"; // $b::f4(4); // task 217171\n" " echo \"static parent method B::f4, 16 == \", B::f4(4),\"\\n\"; " " // should work\n" " \n" " // call an non-existant method on the one object via dynamic " "class name\n" " //php53 if($fix249639) echo \"Calling G object method 'f4bogus' " "5 == \", $b::f4bogus(5); __call, \n" " // call existing method on the one object via dynamic class name\n" " //php53 if($fix249639) echo \"Calling G object method 'f4missing' " "5 == \", $b::f4missing(5); \n" " // $b=\"Bbogus\"; $b::f4bogus(6); // report error\n" " // !m_validClass, !m_class // DDD need this test yet \n" " //echo \"missing 3 \", Bbogus::f4bogus(6),\"\\n\"; " "// fatals in PHP\n" "\n" " } \n" " function f5($a) { return H::f4($a); } // static call\n" "}\n" "class H {\n" " function f($a) { global $trace; $trace=\"H::f,\"; return \"\"; }\n" " function f3($a) { return \"\"; }\n" " function f4($a) { return $a+12; }\n" " function f7($a) { return \"\"; }\n" "}\n" "\n" "class J {\n" " function __call($name, $arguments) {\n" " echo \"Calling object method '$name' \" . implode(', ', " "$arguments). \"\\n\";\n" " }\n" " function f6($a) { return \"\"; }\n" "}\n" "\n" "function error_handler ($errnor, $errstr, $errfile, $errline) {\n" " // Should catch these undefined methods here, but task 333319\n" " // is blocking their being caught. For now, suppress the PHP error\n" " // so as to match the missing HPHP one.\n" " //echo \"error handler<<<\\n\";\n" " //var_dump($errnor, $errstr, $errfile, $errline) ;\n" " //echo \">>>\\n\";\n" " return true;\n" "}\n" "// test invoke_builtin_static_method\n" "//echo \"bar == \", \n" " // call_user_func_array(array('Normalizer','normalize')," "array(\"bar\")), \"\\n\";\n" "\n" "$g = new G(5);\n" "// test simple function case\n" "echo \"600 == \",\n" " call_user_func_array('f2',array(call_user_func_array('f4',array(0))))" ", " "\"\\n\";\n" "\n" "// test C::o_invoke, C::o_invoke_few_args, lookup in call_user_func\n" "// static method call (in G::f4).\n" "echo \"1 1 13 34 12 == \",$g->f(1),\" \", $g->f1(1),\" \", \n" " $g->f2(1),\" \",$g->flongerthan8(10,11,12,13,14,15,16),\n" " \" \",$g->f4(0),\"\\n\";\n" "// check case insensitive\n" "echo \"1 1 13 34 12 == \",$g->F(1),\" \", $g->F1(1),\" \", \n" " $g->F2(1),\" \",$g->Flongerthan8(10,11,12,13,14,15,16),\n" " \" \",$g->F4(0),\"\\n\";\n" "\n" "// check SimpleFunctionCall::outputCPPParamOrderControlled\n" "$prev_handler=set_error_handler(\"error_handler\");\n" "$g->f4missing(3);\n" "// $b=\"G\"; $b::f4(4); \n" "\n" "// For those dynamic cases, check:\n" "// 1) A call to an existing method\n" "// 2) A call to a method which exists, but not in this class (exists " "in methodMap)\n" "// 3) A call to a method which does not exist anywhere\n" "\n" "// $func=\"f3\"; echo \"{G::f3}(3) = \",$g->$func(3),\"\\n\";\n" "// $func=\"missing\"; echo \"{G::missing}(3) = \",$g->$func(3),\"\\n\";" "\n" "// tests direct dynamic call \n" "$f='f'; $f1='f1';\n" "echo \"1 1 == \",$g->{$f}(1),\" \", $g->{$f1}(1),\"\\n\"; \n" "echo \"1 1 == \",$g->{'F'}(1),\" \", $g->{$f1}(1),\"\\n\"; \n" "\n" "$res = call_user_func_array(\"H::f\",array(2)); // ok\n" "\n" "// tests methodIndexLookup and this variety of dynamic calls\n" "// trying to exhause f_call_user_func_array cases\n" "$res = call_user_func_array(array($g,'f'),array(20)); // ok\n" "echo \"dynamic call \\$g->'f' $trace, 20 == $res\\n\"; \n" "$res= call_user_func_array(array($g,'G::f'),array(21)); // G::G::f a " "bit wierd\n" "echo \"dynamic call \\$g->'G::f' $trace, 21 == $res\\n\";\n" "//echo \"dynamic call \\$g->'H::f' $trace, FAIL = \",\n" "// call_user_func_array(array($g,'H::f'),array(22)),\"\\n\"; " "// G::H::f better break\n" "\n" "// Test on static class, dynamic method name, static call\n" "$f = 'f1';\n" "echo \"31 == \",G::$f(31),\"\\n\"; // G::f exists\n" "$f = 'f3';\n" "if ($fix249639) echo \"(32) == \",G::$f(32),\"\\n\"; " "// H::f3 exists, but not G::f3\n" "$f = 'missing';\n" "if ($fix249639) echo \"(33) == \",G::$f(33),\"\\n\"; " "// missing does not exist \n" "\n" "// Test dynamic class, dynamic method name, static call\n" "$cls='G';\n" "$f = 'f1';\n" "\n" "//php53 echo \"31 == \",$cls::$f(31),\"\\n\"; // G::f1 exists\n" "$f = 'f3';\n" "//php53 if ($fix249639) echo \"(32) == \"," "$cls::$f(32),\"\\n\"; // H::f3 exists, but not G::f3\n" "$f = 'missing';\n" "//php53 if ($fix249639) echo \"(33) == \"," "$cls::$f(33),\"\\n\"; // missing does not exist \n" "\n" "\n" "// test methodIndexLookupReverse\n" "echo \"dynamic call \\$g->'missing' $trace, Calling G object method " "'missing' 2 = \", call_user_func_array(array($g,'missing')," "array(2)),\"\\n\";\n" "echo \"dynamic call 'missing(2)' $trace, FAIL =\", " "call_user_func_array('missing',array(2)),\"\\n\";\n" "\n" "// more __call testing\n" "$j = new J();\n" "echo \"Calling object method 'missing' 3 = \";\n" "call_user_func_array(array($j,'missing'),array(3)); \n" "\n" "// test mapping for system function names\n" "$ourFileName = \"testFile.txt\";\n" "$ourFileHandle = fopen($ourFileName, 'w') or die(\"can't open file\");\n" "fclose($ourFileHandle);\n" "unlink($ourFileName);\n" "\n" "echo \"done\\n\";"); MVCR("bar();" " }" " private function bar() {" " var_dump('in B::bar...');" " }" "}" "class C extends B {" " private function bar() {" " var_dump('in C::bar!');" " }" "}" "$obj = new C;" "$obj->foo();"); return true; } bool TestCodeRun::TestClassMethod() { MVCR( "bar)) {\n" " echo \"isset\\n\";\n" " }\n" " var_dump($this);\n" " }\n" "} Foo::Bar(); $obj = new Foo(); $obj->Bar();\n" ); MVCR( "whatever();\n" ); MVCR(" $v) {}\n"); MVCR("writeMsg('error', $error);" "class AdsConsoleRenderer {" " public static function getInstance() {" " return new AdsConsoleRenderer();" " }" "" " function writeMsg($classname = '', $s = '') {" " echo $classname . \"::\" . $s;" " }" "}"); MVCR("{'f'}();"); MVCR("foo(1);", "1 \n"); MVCR("test();\n" ); MVCR("foo = 1; $this->bar = 2;} " " public function __sleep() { $this->foo = 3; return array('foo');} " "}" " $a = new A(); var_dump(serialize($a));"); MVCR("a[$name] = $value.'set';} " " function __get($name) { return $this->a[$name].'get';} " "} " "$obj = new A(); $obj->test = 'test'; var_dump($obj->test);"); MVCR("a);" "var_dump($obj->b);" "$obj = new B();" "var_dump($obj->a);" "var_dump($obj->b);"); MVCR("a[$name] = $value;} " " function __get($name) { return $this->a[$name];} " "} " "$obj = new A(); $obj->test = 'test'; var_dump($obj->test);"); MVCR("test = 'test'; var_dump($obj->test);"); MVCR("test($a, 'ss');"); /* MVCR("a[$name] = $value;} " " function __get($name) { return $this->a[$name];} " "} " "$obj = new A(); $obj->test = 'test'; var_dump($obj->test);"); */ MVCR("data[$name] = $value;" " }" " public function __get($name) {" " echo \"Getting '$name'\n\";" " if (array_key_exists($name, $this->data)) {" " return $this->data[$name];" " }" " return null;" " }" " public function __unset($name) {" " echo \"Unsetting '$name'\n\";" " unset($this->data[$name]);" " return 1;" " }" "}" "$obj = new MemberTest;" "$obj->a = 1;" "var_dump($obj->a);" "var_dump(isset($obj->a));" "unset($obj->a);"); MVCR("foo);\n"); MVCR("f2);" " }" "}" "class c extends b{" " private $f = 10;" " private static $sf = 10;" " function __get($n) {" " echo 'got';" " return 1;" " }" " function t() {" " var_dump($this->f2);" " }" "}" "$x = new c;" "var_dump($x->f);" "$x->t();" "$x->t2();"); MVCR("x = 'baz'; $b = $foo->x .= 'bar';" "var_dump($a,$b);"); MVCR("a[$n] = $v; }\n" " function __get($n) { return $this->a[$n]; }\n" " function f() { $this->f = 100; $this->f += 100; }\n" "}\n" "function test() {\n" " $a = new A();\n" " $a->f();\n" " var_dump($a);\n" "}\n" "test();\n"); MVCR("foo;" " var_dump($x->bar++);" " $x->real++;" " var_dump($x);" "}" "test(new X);"); MVCR(" 10;\n" " }\n" "}\n" "$c = new C1;\n" "$d = new D1;\n" "$e = new E1;\n" "$c(0, 1);\n" "$d(0, 1);\n" "$e(0, 1);\n" "call_user_func($c, 0, 1);\n" "call_user_func($d, 0, 1);\n" "call_user_func($e, 0, 1);\n" "call_user_func_array($c, array(0, 1));\n" "call_user_func_array($d, array(0, 1));\n" "call_user_func_array($e, array(0, 1));\n" "$c->__invoke(0, 1);\n" "$d->__invoke(0, 1);\n" "$e->__invoke(0, 1);\n" "C1::__invoke(0, 1);\n" "D1::__invoke(0, 1);\n" "E1::__invoke(0, 1);\n" "function mk($n) { return $n . '::__invoke'; }\n" "call_user_func(mk('C1'), 0, 1);\n" "call_user_func(mk('D1'), 0, 1);\n" "call_user_func(mk('E1'), 0, 1);\n" "var_dump(array_filter(array(0, 1, 11, 13), new F1));\n"); // this differs from regular PHP behavior MVCR("test();\n" "$y = new Y;\n" "$y->test($x);\n"); MVCR("__invoke($y); }\n" "function f2(A $x, $y) { $x($y); $x->__invoke($y); }\n" "function f3(IfaceInvoke $x, $y) { $x($y); $x->__invoke($y); }\n" "$t1 = new Test1;\n" "$t2 = new Test2;\n" "f1($t1, 1);\n" "f1($t2, 2);\n" "f2($t1, 1);\n" "f3($t2, 2);\n"); return true; } bool TestCodeRun::TestObjectAssignment() { MVCR("val = 1;" " }" " function bar() {" " echo $this->val;" " $ref = &$this;" " $ref->val = 2;" " echo $this->val;" " $ref2 = $this;" " $ref2->val = 3;" " echo $this->val;" " $x = new foo();" " echo $x->val;" " $ref3 = &$x;" " $ref3->val = 4;" " echo $x->val;" " $ref4 = $x;" " $ref4->val = 5;" " echo $x->val;" " }" " var $val;" "}" "$x = new foo();" "$x->bar();" "$ref5 = $x;" "$ref5->val = 6;" "echo $x->val;" "$ref6 = &$x;" "$ref6->val = 7;" "echo $x->val;"); return true; } bool TestCodeRun::TestNewObjectExpression() { MVCR("num = 1;" "print($a->num);"); MVCR("id = $id;" " }" "}" "class B1 extends A1 {" "}" "class C1 extends B1 {" " public function __construct($id) {" " parent::__construct($id);" " }" " function zz($id) {" " parent::__construct($id);" " }" "}" "" "$x = new C1(100);" "echo $x->id.\"\\n\";" "$x->zz(1);" "echo $x->id.\"\\n\";"); MVCRO("blah->prop->foo->bar = \"string\";" " var_dump($this->blah);" " }" "}" "$t = new test;" "$t->foo();"); MVCR("_p[ $what ];" " }" " public function __set( $what, $value ) {" " echo \"set\n\";" " $this->_p[ $what ] = $value;" " }" " private $_p = array();" "}" "$c = new C1();" "$c->a = 1;" "$c->a .= 1;" "print $c->a;"); MVCR("_p[ $what ];" " }" " public function __set( $what, $value ) {" " echo \"set\n\";" " $this->_p[ $what ] = $value;" " }" " private $_p = array();" "}" "class C2 {" " public $p2;" "}" "$c2 = new C2();" "$c2->p = new C1();" "$c2->p->a = 1;" "$c2->p->a .= 1;" "print $c2->p->a;"); MVCR("_p[ $what ];" " }" " public function __set( $what, $value ) {" " echo \"set\n\";" " $this->_p[ $what ] = $value;" " }" " private $_p = array();" "}" "class C2 {" " public $p2;" "}" "class C3 {" " public $p3;" "}" "$c3 = new C3();" "$c3->p3 = new C2();" "$c3->p3->p2 = new C1();" "$c3->p3->p2->a = 1;" "$c3->p3->p2->a .= 1;" "print $c3->p3->p2->a;"); MVCR("_p[ $what ];" " }" " public function __set( $what, $value ) {" " echo \"set C1\n\";" " $this->_p[ $what ] = $value;" " }" " private $_p = array();" "}" "class C2 {" " public function __get( $what ) {" " echo \"get C2\n\";" " return $this->_p[ $what ];" " }" " public function __set( $what, $value ) {" " echo \"set C2\n\";" " $this->_p[ $what ] = $value;" " }" " private $_p = array();" "}" "class C3 {" " public function __get( $what) {" " echo \"get C3\n\";" " return $this->_p[ $what ];" " }" " public function __set( $what, $value ) {" " echo \"set C3\n\";" " $this->_p[ $what ] = $value;" " }" " private $_p = array();" "}" "$c3 = new C3();" "$c3->p3 = new C2();" "$c3->p3->p2 = new C1();" "$c3->p3->p2->a = 1;" "$c3->p3->p2->a .= 1;" "print $c3->p3->p2->a;"); MVCR("_p[ $what ];" " }" " public function __set( $what, $value ) {" " echo \"set C1\n\";" " $this->_p[ $what ] = $value;" " }" " private $_p = array();" "}" "class C2 {" " public function __get( $what ) {" " echo \"get C2\n\";" " return $this->_p[ $what ];" " }" " public function __set( $what, $value ) {" " echo \"set C2\n\";" " $this->_p[ $what ] = $value;" " }" " private $_p = array();" "}" "class C3 {" " public function __get( $what) {" " echo \"get C3\n\";" " return $this->_p[ $what ];" " }" " public function __set( $what, $value ) {" " echo \"set C3\n\";" " $this->_p[ $what ] = $value;" " }" " private $_p = array();" "}" "$c3 = new C3();" "$c3->p3 = new C2();" "$c3->p3->p2 = new C1();" "$c3->p3->p2->a = 1;" "$c3->p3->p2->a .= 1;" "print $c3->p3->p2->a;"); MVCR("_p[ $what ];" " }" " public function __set( $what, $value ) {" " echo \"set C1\n\";" " $this->_p[ $what ] = $value;" " }" " private $_p = array();" "}" "class C2 {" " public function __get( $what ) {" " echo \"get C2\n\";" " return $this->_p[ $what ];" " }" " public function __set( $what, $value ) {" " echo \"set C2\n\";" " $this->_p[ $what ] = $value;" " }" " private $_p = array();" "}" "class C3 {" " public function __get( $what) {" " echo \"get C3\n\";" " return $this->_p[ $what ];" " }" " public function __set( $what, $value ) {" " echo \"set C3\n\";" " $this->_p[ $what ] = $value;" " }" " private $_p = array();" "}" "$c3 = new C3();" "$c3->p3 = new C2();" "$c3->p3->p2 = new C1();" "$c3->p3->p2->a = 1;" "$c3->p3->p2->a .= 1;" "print $c3->p3->p2->a;"); MVCR("_p[ $what ];" " }" " public function __set( $what, $value ) {" " echo \"set\n\";" " $this->_p[ $what ] = $value;" " }" " private $_p = array();" "}" "$c = new C1();" "$c->a += 1;" "print $c->a;" "$c->a += 10;" "print $c->a;" "$c->a -= 2;" "print $c->a;" "$c->a *= 3;" "print $c->a;" "$c->a /= 2;" "print $c->a;" "$c->a %= 8;" "print $c->a;" "$c->a <<= 3;" "print $c->a;" "$c->a >>= 2;" "print $c->a;" "$c->a ^= 18;" "print $c->a;" "$c->a &= 333;" "print $c->a;" "$c->a |= 7;" "print $c->a;"); MVCR("_p[ $what ];" " }" " public function __set( $what, $value ) {" " echo \"set C2\n\";" " $this->_p[ $what ] = $value;" " }" " private $_p = array();" "}" "class C3 {" " public function __get( $what ) {" " echo \"get C3\n\";" " return $this->_p[ $what ];" " }" " public function __set( $what, $value ) {" " echo \"set C3\n\";" " $this->_p[ $what ] = $value;" " }" " private $_p = array();" "}" "function assign_ref(&$v) {" " $v = 22;" "}" "$c3 = new C3();" "$c3->p3 = new C2();" "$c3->p3->p2 = new C1();" "$c3->p3->p2->a = 1;" "$c3->p3->p2->a .= 1;" "print $c3->p3->p2->a;" "assign_ref($c3->p3->p2->a);" "print $c3->p3->p2->a;"); MVCR("_p[ $what ];" " }" " public function __set( $what, $value ) {" " echo \"set C1\n\";" " $this->_p[ $what ] = $value;" " }" " private $_p = array();" "}" "class C2 {" " public function __get( $what ) {" " echo \"get C2\n\";" " return $this->_p[ $what ];" " }" " public function __set( $what, $value ) {" " echo \"set C2\n\";" " $this->_p[ $what ] = $value;" " }" " private $_p = array();" "}" "class C3 {" " public function __get( $what ) {" " echo \"get C3\n\";" " return $this->_p[ $what ];" " }" " public function __set( $what, $value ) {" " echo \"set C3\n\";" " $this->_p[ $what ] = $value;" " }" " private $_p = array();" "}" "function assign_ref(&$v) {" " $v = 22;" "}" "$c3 = new C3();" "$c3->p3 = new C2();" "$c3->p3->p2 = new C1();" "$c3->p3->p2->a = 1;" "$c3->p3->p2->a .= 1;" "print $c3->p3->p2->a;" "assign_ref($c3->p3->p2->a);" "print $c3->p3->p2->a;"); MVCR("a);" "var_dump($b);"); MVCR("_p[ $what ];" " }" " public function __set( $what, $value ) {" " echo \"set C1\n\";" " $this->_p[ $what ] = $value;" " }" " private $_p = array();" "}" "$c1 = new C1();" "$c1->a = new C1();" "$c1->a->b = new C1();" "$c1->a->b->c = 10;" "var_dump($c1->a->b->c);" "$c1->a->b->c .= 10;" "var_dump($c1->a->b->c);"); MVCR("_p[ $what ];" " }" " public function __set( $what, $value ) {" " echo \"set C1\n\";" " $this->_p[ $what ] = $value;" " }" " private $_p = array();" "}" "$c1 = new C1();" "$c1->a = new C1();" "$c1->a->b = new C1();" "for ($i = 0; $i < 2048; $i++) {" " $c1->a->b->c = 10;" "}" "var_dump($c1->a->b->c);"); MVCR("a = array('x' => new Y);" " }" " function bar() {" " var_dump('bar');" " $this->qq = new Y;" " $this->qq->x = $this->qq->y = 1;" " return $this->qq;" " }" "}" "function foo() { var_dump('foo'); return 'foo'; }" "function test($x, $a, $s) {" " $t = &$s->t;" " unset($x->bar()->x);" " unset($x->q->r->s->${foo()});" " unset($x->y->a->b->c);" " unset($x->a['x']->y->a->b->c);" " unset($a['a']['y'][foo()]);" " unset($a['b']->y->z);" " unset($a->c->d);" " var_dump($x, $a, $s);" "}" "test(new X, array(), false);"); MVCR("a);" "var_dump($this);" "}" "}" "$x = new X;" "$x->foo('this');"); MVCR("q = $q;" " }" "}" "function test() {" " $x = new X;" " $x->foo('hello');" " var_dump($x);" "}" "test();"); if (Option::EnableEval >= Option::FullEval) { MVCRONW("ref($this->priv);" " }" "};" "class Y extends X { private $priv; }" "class Z extends Y {}" "$z = new Z;" "$z->bar();" "var_dump($z);" "$y = new Y;" "$y->bar();" "var_dump($y);" , "object(Z)#1 (2) {\n" " [\"priv\":\"Y\":private]=>\n" " NULL\n" " [\"priv\"]=>\n" " int(1)\n" "}\n"); } return true; } bool TestCodeRun::TestCollectionClasses() { MVCRO(" $v) {\n" " var_dump($v);\n" " var_dump($vec[$k]);\n" " var_dump(isset($v));\n" " var_dump(isset($vec[$k]));\n" " var_dump(empty($v));\n" " var_dump(empty($vec[$k]));\n" " echo \"\\n\";\n" "}\n" "echo \"=====================\\n\\n\";\n" "$mp = Map::fromArray($arr);\n" "foreach ($arr as $k => $v) {\n" " var_dump($mp[$k]);\n" " var_dump(isset($mp[$k]));\n" " var_dump(empty($mp[$k])); \n" " echo \"\\n\";\n" "}\n" "$new_arr = array();\n" "foreach ($mp as $k => $v) {\n" " $new_arr[$k] = $v;\n" "}\n" "ksort($new_arr);\n" "var_dump($new_arr);\n" "echo \"=====================\\n\\n\";\n" "$smp = StableMap::fromArray($arr);\n" "foreach ($smp as $k => $v) {\n" " var_dump($v);\n" " var_dump($smp[$k]);\n" " var_dump(isset($v));\n" " var_dump(isset($smp[$k]));\n" " var_dump(empty($v));\n" " var_dump(empty($smp[$k]));\n" " echo \"\\n\";\n" "}\n" "echo \"Done\\n\";\n" , "NULL\n" "NULL\n" "bool(false)\n" "bool(false)\n" "bool(true)\n" "bool(true)\n" "\n" "bool(false)\n" "bool(false)\n" "bool(true)\n" "bool(true)\n" "bool(true)\n" "bool(true)\n" "\n" "bool(true)\n" "bool(true)\n" "bool(true)\n" "bool(true)\n" "bool(false)\n" "bool(false)\n" "\n" "int(0)\n" "int(0)\n" "bool(true)\n" "bool(true)\n" "bool(true)\n" "bool(true)\n" "\n" "int(1)\n" "int(1)\n" "bool(true)\n" "bool(true)\n" "bool(false)\n" "bool(false)\n" "\n" "float(0)\n" "float(0)\n" "bool(true)\n" "bool(true)\n" "bool(true)\n" "bool(true)\n" "\n" "float(1)\n" "float(1)\n" "bool(true)\n" "bool(true)\n" "bool(false)\n" "bool(false)\n" "\n" "string(0) \"\"\n" "string(0) \"\"\n" "bool(true)\n" "bool(true)\n" "bool(true)\n" "bool(true)\n" "\n" "string(1) \"0\"\n" "string(1) \"0\"\n" "bool(true)\n" "bool(true)\n" "bool(true)\n" "bool(true)\n" "\n" "string(1) \"1\"\n" "string(1) \"1\"\n" "bool(true)\n" "bool(true)\n" "bool(false)\n" "bool(false)\n" "\n" "string(3) \"0.0\"\n" "string(3) \"0.0\"\n" "bool(true)\n" "bool(true)\n" "bool(false)\n" "bool(false)\n" "\n" "string(3) \"1.0\"\n" "string(3) \"1.0\"\n" "bool(true)\n" "bool(true)\n" "bool(false)\n" "bool(false)\n" "\n" "string(2) \"0 \"\n" "string(2) \"0 \"\n" "bool(true)\n" "bool(true)\n" "bool(false)\n" "bool(false)\n" "\n" "string(3) \"foo\"\n" "string(3) \"foo\"\n" "bool(true)\n" "bool(true)\n" "bool(false)\n" "bool(false)\n" "\n" "=====================\n" "\n" "NULL\n" "bool(false)\n" "bool(true)\n" "\n" "bool(false)\n" "bool(true)\n" "bool(true)\n" "\n" "bool(true)\n" "bool(true)\n" "bool(false)\n" "\n" "int(0)\n" "bool(true)\n" "bool(true)\n" "\n" "int(1)\n" "bool(true)\n" "bool(false)\n" "\n" "float(0)\n" "bool(true)\n" "bool(true)\n" "\n" "float(1)\n" "bool(true)\n" "bool(false)\n" "\n" "string(0) \"\"\n" "bool(true)\n" "bool(true)\n" "\n" "string(1) \"0\"\n" "bool(true)\n" "bool(true)\n" "\n" "string(1) \"1\"\n" "bool(true)\n" "bool(false)\n" "\n" "string(3) \"0.0\"\n" "bool(true)\n" "bool(false)\n" "\n" "string(3) \"1.0\"\n" "bool(true)\n" "bool(false)\n" "\n" "string(2) \"0 \"\n" "bool(true)\n" "bool(false)\n" "\n" "string(3) \"foo\"\n" "bool(true)\n" "bool(false)\n" "\n" "array(14) {\n" " [0]=>\n" " NULL\n" " [1]=>\n" " bool(false)\n" " [2]=>\n" " bool(true)\n" " [3]=>\n" " int(0)\n" " [4]=>\n" " int(1)\n" " [5]=>\n" " float(0)\n" " [6]=>\n" " float(1)\n" " [7]=>\n" " string(0) \"\"\n" " [8]=>\n" " string(1) \"0\"\n" " [9]=>\n" " string(1) \"1\"\n" " [10]=>\n" " string(3) \"0.0\"\n" " [11]=>\n" " string(3) \"1.0\"\n" " [12]=>\n" " string(2) \"0 \"\n" " [13]=>\n" " string(3) \"foo\"\n" "}\n" "=====================\n" "\n" "NULL\n" "NULL\n" "bool(false)\n" "bool(false)\n" "bool(true)\n" "bool(true)\n" "\n" "bool(false)\n" "bool(false)\n" "bool(true)\n" "bool(true)\n" "bool(true)\n" "bool(true)\n" "\n" "bool(true)\n" "bool(true)\n" "bool(true)\n" "bool(true)\n" "bool(false)\n" "bool(false)\n" "\n" "int(0)\n" "int(0)\n" "bool(true)\n" "bool(true)\n" "bool(true)\n" "bool(true)\n" "\n" "int(1)\n" "int(1)\n" "bool(true)\n" "bool(true)\n" "bool(false)\n" "bool(false)\n" "\n" "float(0)\n" "float(0)\n" "bool(true)\n" "bool(true)\n" "bool(true)\n" "bool(true)\n" "\n" "float(1)\n" "float(1)\n" "bool(true)\n" "bool(true)\n" "bool(false)\n" "bool(false)\n" "\n" "string(0) \"\"\n" "string(0) \"\"\n" "bool(true)\n" "bool(true)\n" "bool(true)\n" "bool(true)\n" "\n" "string(1) \"0\"\n" "string(1) \"0\"\n" "bool(true)\n" "bool(true)\n" "bool(true)\n" "bool(true)\n" "\n" "string(1) \"1\"\n" "string(1) \"1\"\n" "bool(true)\n" "bool(true)\n" "bool(false)\n" "bool(false)\n" "\n" "string(3) \"0.0\"\n" "string(3) \"0.0\"\n" "bool(true)\n" "bool(true)\n" "bool(false)\n" "bool(false)\n" "\n" "string(3) \"1.0\"\n" "string(3) \"1.0\"\n" "bool(true)\n" "bool(true)\n" "bool(false)\n" "bool(false)\n" "\n" "string(2) \"0 \"\n" "string(2) \"0 \"\n" "bool(true)\n" "bool(true)\n" "bool(false)\n" "bool(false)\n" "\n" "string(3) \"foo\"\n" "string(3) \"foo\"\n" "bool(true)\n" "bool(true)\n" "bool(false)\n" "bool(false)\n" "\n" "Done\n" ); MVCRO("toArray());\n" "var_dump($v->pop());\n" "var_dump($v->toArray());\n" , "array(1) {\n" " [0]=>\n" " int(123)\n" "}\n" "int(123)\n" "array(0) {\n" "}\n" ); MVCRO("contains(1);\n" " try {\n" " $v->contains('foo');\n" " } catch (Exception $e) {\n" " echo 'A';\n" " }\n" " try {\n" " $v->contains(1.0);\n" " } catch (Exception $e) {\n" " echo 'B';\n" " }\n" " $methods = Vector::fromArray(array('contains','remove'," "'discard'));\n" " foreach ($methods as $method) {\n" " $m = new Map();\n" " $m->$method(1);\n" " $m->$method('foo');\n" " try {\n" " $m->$method(1.0);\n" " } catch (Exception $e) {\n" " echo 'C';\n" " }\n" " $s = new StableMap();\n" " $s->$method(1);\n" " $s->$method('foo');\n" " try {\n" " $s->$method(1.0);\n" " } catch (Exception $e) {\n" " echo 'D';\n" " }\n" " echo \"\\n\";\n" " }\n" "} catch (Exception $e) {\n" " echo \"Test failed\\n\";\n" "}\n" , "ABCD\n" "CD\n" "CD\n" ); MVCRO("foo;\n" " } catch (RuntimeException $e) {\n" " echo $i;\n" " }\n" " ++$i;\n" " try {\n" " $obj->foo = 123;\n" " } catch (RuntimeException $e) {\n" " echo $i;\n" " }\n" " ++$i;\n" " }\n" "} catch (Exception $e) {\n" " echo \"Fail!\\n\";\n" "}\n" "echo \"Done\\n\";\n" , "012345Done\n" ); MVCRO("\n" " int(7)\n" " [1]=>\n" " string(3) \"foo\"\n" "}\n" "Vector Object\n" "(\n" " [0] => 7\n" " [1] => foo\n" ")\n" "[7,\"foo\"]\n" "Vector::__set_state(array(\n" " 0 => 7,\n" " 1 => 'foo',\n" "))\n" "object(Vector)#2 (2) {\n" " [0]=>\n" " int(7)\n" " [1]=>\n" " string(3) \"foo\"\n" "}\n" "Vector Object\n" "(\n" " [0] => 7\n" " [1] => foo\n" ")\n" "[7,\"foo\"]\n" "Vector::__set_state(array(\n" " 0 => 7,\n" " 1 => 'foo',\n" "))\n" ); MVCRO("\n" " string(3) \"foo\"\n" "}\n" "Map Object\n" "(\n" " [3] => foo\n" ")\n" "{\"3\":\"foo\"}\n" "Map::__set_state(array(\n" " 3 => 'foo',\n" "))\n" "object(Map)#2 (1) {\n" " [3]=>\n" " string(3) \"foo\"\n" "}\n" "Map Object\n" "(\n" " [3] => foo\n" ")\n" "{\"3\":\"foo\"}\n" "Map::__set_state(array(\n" " 3 => 'foo',\n" "))\n" "=========================\n" "string(28) \"K:3:\"Map\":1:{s:3:\"bar\";i:7;}\"\n" "=========================\n" "object(Map)#3 (1) {\n" " [\"bar\"]=>\n" " int(7)\n" "}\n" "Map Object\n" "(\n" " [bar] => 7\n" ")\n" "{\"bar\":7}\n" "Map::__set_state(array(\n" " 'bar' => 7,\n" "))\n" "object(Map)#4 (1) {\n" " [\"bar\"]=>\n" " int(7)\n" "}\n" "Map Object\n" "(\n" " [bar] => 7\n" ")\n" "{\"bar\":7}\n" "Map::__set_state(array(\n" " 'bar' => 7,\n" "))\n" ); MVCRO("\n" " string(3) \"foo\"\n" " [\"bar\"]=>\n" " int(7)\n" "}\n" "StableMap Object\n" "(\n" " [3] => foo\n" " [bar] => 7\n" ")\n" "{\"3\":\"foo\",\"bar\":7}\n" "StableMap::__set_state(array(\n" " 3 => 'foo',\n" " 'bar' => 7,\n" "))\n" "object(StableMap)#2 (2) {\n" " [3]=>\n" " string(3) \"foo\"\n" " [\"bar\"]=>\n" " int(7)\n" "}\n" "StableMap Object\n" "(\n" " [3] => foo\n" " [bar] => 7\n" ")\n" "{\"3\":\"foo\",\"bar\":7}\n" "StableMap::__set_state(array(\n" " 3 => 'foo',\n" " 'bar' => 7,\n" "))\n" "=========================\n" "string(48) \"K:9:\"StableMap\":2:{s:3:\"bar\";i:7;i:3;" "s:3:\"foo\";}\"\n" "=========================\n" "object(StableMap)#3 (2) {\n" " [\"bar\"]=>\n" " int(7)\n" " [3]=>\n" " string(3) \"foo\"\n" "}\n" "StableMap Object\n" "(\n" " [bar] => 7\n" " [3] => foo\n" ")\n" "{\"bar\":7,\"3\":\"foo\"}\n" "StableMap::__set_state(array(\n" " 'bar' => 7,\n" " 3 => 'foo',\n" "))\n" "object(StableMap)#4 (2) {\n" " [\"bar\"]=>\n" " int(7)\n" " [3]=>\n" " string(3) \"foo\"\n" "}\n" "StableMap Object\n" "(\n" " [bar] => 7\n" " [3] => foo\n" ")\n" "{\"bar\":7,\"3\":\"foo\"}\n" "StableMap::__set_state(array(\n" " 'bar' => 7,\n" " 3 => 'foo',\n" "))\n" ); MVCRO("at(0));\n" "var_dump($v->get(0));\n" "var_dump($v->get(1));\n" "$m = Map::fromArray(array('foo'));\n" "var_dump($m[0]);\n" "var_dump($m->at(0));\n" "var_dump($m->get(0));\n" "var_dump($m->get(1));\n" "$sm = StableMap::fromArray(array('foo'));\n" "var_dump($sm[0]);\n" "var_dump($sm->at(0));\n" "var_dump($sm->get(0));\n" "var_dump($sm->get(1));\n" , "string(3) \"foo\"\n" "string(3) \"foo\"\n" "string(3) \"foo\"\n" "NULL\n" "string(3) \"foo\"\n" "string(3) \"foo\"\n" "string(3) \"foo\"\n" "NULL\n" "string(3) \"foo\"\n" "string(3) \"foo\"\n" "string(3) \"foo\"\n" "NULL\n" ); MVCRO(" 'foo'));\n" "var_dump($m['a']);\n" "var_dump($m->at('a'));\n" "var_dump($m->get('a'));\n" "var_dump($m->get('b'));\n" "$sm = StableMap::fromArray(array('a' => 'foo'));\n" "var_dump($sm['a']);\n" "var_dump($sm->at('a'));\n" "var_dump($sm->get('a'));\n" "var_dump($sm->get('b'));\n" , "string(3) \"foo\"\n" "string(3) \"foo\"\n" "string(3) \"foo\"\n" "NULL\n" "string(3) \"foo\"\n" "string(3) \"foo\"\n" "string(3) \"foo\"\n" "NULL\n" ); MVCRO(" $val) {\n" " echo $key . ' ' . $val . \"\\n\";\n" "}\n" "echo \"=======\\n\";\n" "$s = new StableMap;\n" "$s['w'] = 2;\n" "$s['v'] = 4;\n" "$s['y'] = 3;\n" "$s['x'] = 5;\n" "$s['z'] = 1;\n" "ksort($s);\n" "foreach ($s as $key => $val) {\n" " echo $key . ' ' . $val . \"\\n\";\n" "}\n" "echo \"=======\\n\";\n" "asort($s);\n" "foreach ($s as $key => $val) {\n" " echo $key . ' ' . $val . \"\\n\";\n" "}\n" , "0 a\n" "1 b\n" "2 c\n" "=======\n" "v 4\n" "w 2\n" "x 5\n" "y 3\n" "z 1\n" "=======\n" "z 1\n" "w 2\n" "y 3\n" "v 4\n" "x 5\n" ); MVCRO(" $y) return -1;\n" " return 0;\n" "}\n" "$v = new Vector;\n" "$v[] = 'c';\n" "$v[] = 'a';\n" "$v[] = 'b';\n" "usort($v, 'cmp');\n" "foreach ($v as $key => $val) {\n" " echo $key . ' ' . $val . \"\\n\";\n" "}\n" "echo \"=======\\n\";\n" "$s = new StableMap;\n" "$s['w'] = 2;\n" "$s['v'] = 4;\n" "$s['y'] = 3;\n" "$s['x'] = 5;\n" "$s['z'] = 1;\n" "uksort($s, 'cmp');\n" "foreach ($s as $key => $val) {\n" " echo $key . ' ' . $val . \"\\n\";\n" "}\n" "echo \"=======\\n\";\n" "uasort($s, 'cmp');\n" "foreach ($s as $key => $val) {\n" " echo $key . ' ' . $val . \"\\n\";\n" "}\n" , "0 c\n" "1 b\n" "2 a\n" "=======\n" "z 1\n" "y 3\n" "x 5\n" "w 2\n" "v 4\n" "=======\n" "x 5\n" "v 4\n" "y 3\n" "w 2\n" "z 1\n" ); MVCRO(" 1, 'b' => 2 });\n" "\n" " var_dump(Vector {});\n" " var_dump(Map {});\n" " var_dump(Vector { 1, 2 });\n" " var_dump(StableMap { 'a' => 1, 'b' => 2 });\n" "}\n" "f();\n" , "object(Vector)#1 (0) {\n" "}\n" "object(Map)#1 (0) {\n" "}\n" "object(Vector)#1 (2) {\n" " [0]=>\n" " int(1)\n" " [1]=>\n" " int(2)\n" "}\n" "object(StableMap)#1 (2) {\n" " [\"a\"]=>\n" " int(1)\n" " [\"b\"]=>\n" " int(2)\n" "}\n" "object(Vector)#1 (0) {\n" "}\n" "object(Map)#1 (0) {\n" "}\n" "object(Vector)#1 (2) {\n" " [0]=>\n" " int(1)\n" " [1]=>\n" " int(2)\n" "}\n" "object(StableMap)#1 (2) {\n" " [\"a\"]=>\n" " int(1)\n" " [\"b\"]=>\n" " int(2)\n" "}\n" ); MVCRO(" $v1, $k2 => $v2 };\n" " return $m;\n" "}\n" "var_dump(f(42, 123.456, 'blah', array(3, 5, 7)));\n" "var_dump(g('foo', 1, 2, 'bar'));\n" , "object(Vector)#1 (4) {\n" " [0]=>\n" " int(42)\n" " [1]=>\n" " float(123.456)\n" " [2]=>\n" " string(4) \"blah\"\n" " [3]=>\n" " array(3) {\n" " [0]=>\n" " int(3)\n" " [1]=>\n" " int(5)\n" " [2]=>\n" " int(7)\n" " }\n" "}\n" "object(Map)#1 (2) {\n" " [\"foo\"]=>\n" " int(1)\n" " [2]=>\n" " string(3) \"bar\"\n" "}\n" ); return true; } /////////////////////////////////////////////////////////////////////////////// // comparisons #define COMPARE(a, op, b) \ "print ++$i; print \"\\t\"; " \ "print (" #a #op #b ") ? 'Y' : 'N'; " \ "$a = 1; $a = 't'; $a = " #a "; " \ "print ($a " #op #b ") ? 'Y' : 'N'; " \ "$b = 1; $b = 't'; $b = " #b "; " \ "print (" #a #op "$b) ? 'Y' : 'N'; " \ "print ($a " #op "$b) ? 'Y' : 'N'; " \ "print \"\\t\"; " \ "print \"" #a " " #op " " #b "\t\"; " \ "print \"\\n\"; " \ #define COMPARE_ALL(a, op) \ COMPARE(a, op, true) \ COMPARE(a, op, false) \ COMPARE(a, op, 1) \ COMPARE(a, op, 0) \ COMPARE(a, op, -1) \ COMPARE(a, op, '1') \ COMPARE(a, op, '0') \ COMPARE(a, op, '-1') \ COMPARE(a, op, NULL) \ COMPARE(a, op, array()) \ COMPARE(a, op, array(1)) \ COMPARE(a, op, array(2)) \ COMPARE(a, op, array('1')) \ COMPARE(a, op, array('0' => '1')) \ COMPARE(a, op, array('a')) \ COMPARE(a, op, array('a' => 1)) \ COMPARE(a, op, array('b' => 1)) \ COMPARE(a, op, array('a' => 1, 'b' => 2)) \ COMPARE(a, op, array(array('a' => 1))) \ COMPARE(a, op, array(array('b' => 1))) \ COMPARE(a, op, 'php') \ COMPARE(a, op, '') \ #define COMPARE_OP(op) \ MVCR(" '1'), op)); \ MVCR(" 1), op)); \ MVCR(" 1), op)); \ MVCR(" 1, 'b' => 2), op)); \ MVCR(" 1)), op)); \ MVCR(" 1)), op)); \ MVCR(" 1, 2 => 1) == array(2 => 1, 1 => 1));"); MVCR(" 1, 2 => 1) === array(2 => 1, 1 => 1));"); MVCR("1,'b'=> 1) == array('b'=>1,'a'=> 1));"); MVCR("1,'b'=> 1) === array('b'=>1,'a'=> 1));"); MVCR("); COMPARE_OP(!==); COMPARE_OP(<); COMPARE_OP(>); COMPARE_OP(<=); COMPARE_OP(>=); MVCR("x = 1;" "$y = new c;" "var_dump($x > $y);" "var_dump(array($x) == array($y));"); MVCR(" '') {" " echo 'yes';" " } else {" " echo 'no';" " }" "}" "foo(false);"); MVCR(" 0);\n" "var_dump ($x >= 1);\n" "var_dump ($x < 5);\n" "var_dump ($x <= 1);\n"); return true; } /////////////////////////////////////////////////////////////////////////////// // semantics bool TestCodeRun::TestUnset() { MVCR("arr[] = 'test';" "var_dump($obj->arr); unset($obj->arr); var_dump($obj->arr);"); MVCR("a = $p;" " }" "};" "$obj = new A(1);" "var_dump($obj);" "unset($obj->a);" "var_dump($obj);" "$obj->a = 2;" "var_dump($obj);" "$obj->b = 3;" "var_dump($obj);" "unset($obj->b);" "var_dump($obj);" "$obj->a = 2;" "var_dump($obj);" "$obj->b = 3;" "var_dump($obj);" "unset($obj->a, $obj->b);" "var_dump($obj);"); MVCR("foo(); \n" "$obj->bar();\n" "A::bar();\n" "goo();\n" "unset($this);\n" "var_dump($this);\n"); MVCR(" 'foo');\n" "unset($a[null]);\n" "var_dump($a);\n"); return true; } bool TestCodeRun::TestReference() { MVCR(" 1240430476);" "$idxa = &$idxa['a'];"); MVCR(" &$v) { $v = 'ok';} var_dump($a, $b);"); MVCR(" &$a); var_dump($b); " "$a = 20; var_dump($b);"); MVCR("b = 10; f($a->b); var_dump($a);"); MVCR("b = 10; f($a->b); var_dump($a);"); MVCR("b = 10; f($a->b); var_dump($a);"); // reference returns MVCR(" &$a); var_dump($a);"); //VCR(" &$a); $b = array($a); var_dump($b);"); MVCR(" &$b); $a['r'] = 6; test($a); var_dump($a);"); MVCR("0);" "$ref = &$a['a'];" "var_dump($a);" "$b = $a;" "var_dump($a,$b);" "$b['a'] = 1;" "var_dump($a,$b);" "$a = array(0);" "$ref = &$a[0];" "var_dump($a);" "$b = $a;" "var_dump($a,$b);" "$b[0] = 1;" "var_dump($a,$b);" ); if (!hhvm) { // call-time pass by reference -- not supported in the VM MVCRNW("t($arr['hello'], $arr);" "}" "test();" "$arr = array('hello' => 1);" "$x = &$arr['hello'];" "$arr['hello'] = $x;" "var_dump($arr);" "function test2(&$a, $b) {" " $a = $b;" "}" "$v = 10;" "test2($v, $v);" "var_dump($v);"); // reference, parameter & assignment MVCR(" 1);" " $t = &$perms;" " $t = $t['x'];" " unset($t);" " return $perms;" "}" "var_dump(foo());"); MVCR("foo['a']['b']);" " $x[0]->foo['a']['b'] = 5;" " var_dump($x);" "}" "foo(false);" "function baz(&$x) {}" "foreach ($x->foo[1]->prop as &$y) {}" "var_dump($x);" "baz($q->foo[1]->prop);" "var_dump($q);" "$y = &$z->foo[1]->prop;" "var_dump($z);" "function &fiz(&$x) {" " return $x->foo[1]->prop;" "}" "fiz($w);" "var_dump($w);"); MVCR("f('f', 'this');\n" "$a->f('g', 'this');\n" "$a->g('f', 30);\n" "$a->g('g', 30);\n"); MVCR("x = 0;" " }" "}" "function test(&$a, $b) {" " var_dump($a, $b);" "}" "function f($x) {" " unset($GLOBALS['a']);" " return 1;" "}" "$a = array(new X);" "test($a[0], f(1));"); MVCR("t();"); // l-value MVCR(" 'aval')); var_dump($a);"); MVCR(" 'ok')); $a = 1; var_dump($a);"); MVCR(" 'ok'), EXTR_SKIP); var_dump($a);"); MVCR(" 'ok'), EXTR_PREFIX_SAME, 'p');" " var_dump($p_a);"); MVCR(" 'ok'), EXTR_PREFIX_ALL, 'p');" " var_dump($p_a);"); MVCR(" 'ok'), EXTR_IF_EXISTS); var_dump($a);"); MVCR(" 'ok', 'b' => 'no'), EXTR_PREFIX_IF_EXISTS, 'p'); var_dump($p_a); var_dump($b); var_dump($p_b);"); MVCR(" &$a), EXTR_REFS); $b = 'no'; var_dump($a);"); MVCR(" &$a); extract($arr, EXTR_REFS); $b = 'no'; var_dump($a);"); MVCR(" 2, '1d' => 3);\n" " extract($arr);\n" " $vars = get_defined_vars(); asort($vars); var_dump($vars);\n" "}\n" "f();\n"); MVCR("$b = 'test'; var_dump($this->$b); var_dump($this->a);" " $c = &$this->$b; $c = array(1); var_dump($this->a);" " }" "} $obj = new B(); $obj->test();"); MVCR("a);"); MVCR("$f = 100; var_dump($a); " "var_dump((array)$a); " "$f = 100; " "f($a->$f); " "foreach ($a as $k => &$v) { var_dump($k); $v = 1; } " "var_dump($a); "); return true; } bool TestCodeRun::TestDynamicFunctions() { MVCR(" 100) { $f = 'var_dump'; } else { $f = 'sscanf'; }" "$auth = \"24\\tLewis Carroll\";" "$n = $f($auth, \"%d\\t%s %s\", $id, $first, $last);" "echo \"$id,$first,$last\\n\";"); // Test dynamically calling a builtin that is MixedVariableArguments MVCR(" 3, 'a' => 2, 'c' => 1)," " array('x' => 6, 'y' => 4, 'z' => 5)," " array('p' => 8, 'q' => 9, 'r' => 7));" " if ($flag) { $f = 'var_dump'; } else { $f = 'array_multisort'; }" " $f($arr[0], $arr[1], $arr[2]);" " var_dump($arr);" "}" "bar($argc > 100);"); return true; } bool TestCodeRun::TestRenameFunction() { OptionSetter w0(this, OptionSetter::CompileTime, "-vDynamicInvokeFunctions.*=test1 " "-vDynamicInvokeFunctions.*=test2"); OptionSetter w1(this, OptionSetter::RunTime, "-vEval.JitEnableRenameFunction=true"); MVCRO("$f($b); var_dump($b); var_dump($c);"); MVCR("$name();} } " "$obj = new A(); $obj->test();"); MVCR("$m($ar[0], $st[0]); A::$m($ar[1], $st[1]);"); { OptionSetter w(this, OptionSetter::CompileTime, "-v DynamicMethodPrefix.*=_"); MVCR("$name();} }" "$obj = new A(); $obj->test();"); } MVCR("refTestHelper($x);" " var_dump($x);" "}" "$q = new z;" "$f = 'minArgTest';" "$q->minArgTest('one',2,3.333,4,5,6,7,8,9,10);" "$q->minArgTest('one',2,3.333,4,5,6,7,8,9,10,11,12);" "$q->$f('one',2,3.333,4,5,6,7,8,9,10);" "$q->$f('one',2,3.333,4,5,6,7,8,9,10,11,12);" "refTest($q);" "$f = 'varArgsTest';" "$q->varArgsTest('one',2,3.333,4,5,6,7,8,9,10);" "$q->varArgsTest('one',2,3.333,4,5,6,7,8,9,10,11,12);" "$q->$f('one',2,3.333,4,5,6,7,8,9,10);" "$q->$f('one',2,3.333,4,5,6,7,8,9,10,11,12);" "$f = 'varArgsTest2';" "$q->varArgsTest2('one',2,3.333,4,5,6,7,8,9,10);" "$q->varArgsTest2('one',2,3.333,4,5,6,7,8,9,10,11,12);" "$q->$f('one',2,3.333,4,5,6,7,8,9,10);" "$q->$f('one',2,3.333,4,5,6,7,8,9,10,11,12);"); MVCR("z();"); MVCR("functions['test'] = $function;" " print($this->functions['test']());" " }" "}" "$a = new foo ();"); MVCR("q();"); MVCR("$method($aa[3]);" "var_dump($aa);"); MVCR("overridden();" " } else {" " static::overridden();" " }" " }" "}" "class Child extends Parent_ {" " protected final function overridden() {" " var_dump(isset($this), __METHOD__);" " }" " protected function calledHere() {" " var_dump(__METHOD__);" " }" " public function entry($fun = 'calledHere') {" " self::callParent($fun);" " }" " function callParent($fun) {" " parent::$fun();" " if (isset($this)) {" " $this::$fun();" " }" " }" "}" "$c = new Child;" "$c->entry();" "$c->entry('overridden');" "Child::entry();" "Child::callParent('calledHere');" "Child::callParent('overridden');"); return true; } bool TestCodeRun::TestVolatile() { MVCR(" 1 && !defined('CON')) {" " define(/*|Dynamic|*/'CON', 1);" " }" " if (defined('CON')) {" " var_dump(CON);" " } else {" " echo \"CON does not exists\\n\";" " }" "}" "for ($i = 0; $i < 4; $i++) {" " if ($i > 1 && !function_exists('foo')) {" " function foo() {" " echo \"foo called\\n\";" " }" " }" " if (function_exists('foo')) {" " foo();" " } else {" " echo \"foo does not exists\\n\";" " }" "}" "for ($i = 0; $i < 4; $i++) {" " if ($i > 1 && !class_exists('bar')) {" " class bar {" " function bar() { echo \"bar called\\n\"; }" " }" " }" " if (class_exists('bar')) {" " $a = new bar;" " } else {" " echo \"bar does not exists\\n\";" " }" "}"); MVCR(" 1 && !function_exists('foo')) {" " function foo() {" " echo \"foo called\\n\";" " }" " }" " $foo = 'foo';" " if (function_exists($foo)) {" " foo();" " } else {" " echo \"foo does not exists\\n\";" " }" " }" " for ($i = 0; $i < 4; $i++) {" " if ($i > 1 && !class_exists('goo')) {" " class goo {" " function goo() {" " echo \"goo called\\n\";" " }" " }" " }" " $goo = 'goo';" " if (class_exists($goo)) {" " $a = new goo();" " } else {" " echo \"goo does not exists\\n\";" " }" " }" "}" "if (function_exists('bar')) bar();" "$a = 'bar';" "if (function_exists($a)) bar();" "$a = 'later';" "if (function_exists($a)) {" " echo \"later exists\\n\";" "} else {" " echo \"later does not exists\\n\";" "}" "$a = 'later2';" "if (class_exists($a)) {" " echo \"later2 exists\\n\";" "} else {" " echo \"later2 does not exists\\n\";" "}" "$a = 'later3';" "if (function_exists($a)) {" " echo \"later3 exists\\n\";" "} else {" " echo \"later3 does not exists\\n\";" "}" "$a = 'later4';" "if (class_exists($a)) {" " echo \"later4 exists\\n\";" "} else {" " echo \"later4 does not exists\\n\";" "}" "function later3() {" " echo \"later3 called\\n\";" "}" "class later4 {" "}" "if (function_exists('function_exists')) {" " echo \"yes\\n\";" "}" "if (class_exists('exception')) {" " echo \"yes\\n\";" "}"); MVCR("f();" "} else {" " var_dump('correct');" "}"); MVCR("getMessage() . \"\\n\";\n" " } while($e = $e->getPrevious());\n" "}\n" "try {\n" " $obj = new A();\n" "} catch(Exception $e) {\n" " do {\n" " echo $e->getMessage() . \"\\n\";\n" " } while($e = $e->getPrevious());\n" "}\n" "// hphpc won't call the autoloader unless there exists a \n" "// definition for the class somewhere\n" "if (true) {\n" " class A {}\n" "}\n", "autoload_first\n" "autoload_second\n" "second\n" "second_inner\n" "first\n" "first_inner\n" "autoload_first\n" "autoload_second\n" "second\n" "second_inner\n" "first\n" "first_inner\n"); MVCRO("\n" " string(1) \"f\"\n" "}\n" "array(0) {\n" "}\n" "bool(false)\n" "array(1) {\n" " [0]=>\n" " string(1) \"f\"\n" "}\n" "bool(false)\n"); MVCRO(" array()," " 'constant' => array()," " 'failure' => 'failure')," " ''));" "function failure($kind, $name) {" " if ($kind == 'constant' && $name == 'bar') define('bar', 'baz');" " var_dump($kind, $name);" "}" "var_dump(function_exists('foo'));" "var_dump(function_exists('bar', false));" "var_dump(defined('foo'));" "var_dump(defined('bar', false));" "var_dump(constant('foo'));" "var_dump(constant('bar'));" "if (0) {" " function foo() {}" " function foo() {}" " define('foo', 0);" " define('bar', 0);" "}", "bool(true)\n" "string(8) \"function\"\n" "string(3) \"foo\"\n" "bool(false)\n" "bool(false)\n" "string(8) \"constant\"\n" "string(3) \"foo\"\n" "bool(false)\n" "bool(false)\n" "string(8) \"constant\"\n" "string(3) \"foo\"\n" "NULL\n" "string(8) \"constant\"\n" "string(3) \"bar\"\n" "string(3) \"baz\"\n"); return true; } bool TestCodeRun::TestHereDoc() { MVCR(" Double MVCR(" 't');} class B { public $a;} " "$a = 1; $a = new A(); $a->a['t'] = true; var_dump($a->a['t']);"); // Variant % operator MVCR(" -MAX_LATITUDE) define('MAX_LATITUDE', 90); "); // toInt64() wrapper MVCR("a = $a->b = 'test'; var_dump($a);"); MVCR("prop++; var_dump($a->prop);"); // obj->prop doesn't need lval() wrapper MVCR("prop++; var_dump($a->prop);"); // ((p_obj)variant)->prop MVCR("prop++; var_dump($a->prop);"); // unsigned int should never be seen MVCR("test($a, $b);"); // method->method MVCR("getA()->test();" ); // constructor fallback MVCR("method MVCR("b = new A(); $a->b->test();"); // testing code generation order MVCR(" 1); var_dump($_SERVER);"); MVCR(" 1); var_dump($_SERVER);"); // class constant as default MVCR("foo();} " "function foo() { print 'foo';}}"); MVCR("f(date('m/d/y H:i:s', 123456789));" "$v = date(\"m\",123456789)+1;"); // no side effect optimization met if() short MVCR(" 0) ? $n : $n + 1);"); MVCR("test(1, 2) : false;" "}" "var_dump(test(1));"); MVCR("foo = f($b++, $b++, $b++)) . f(1,2,3);" " return $x;" "}"); MVCR("$foo) || empty($x->$foo) ||" " isset($x->{'bar'})) {" " unset($x->$foo);" " unset($x->{'bar'});" " echo true;" " }" "}"); MVCR("newInstance()->loadAll(); }"); MVCR("error = '';" " }" " return $r;" "}" "var_dump(foo(true));" "var_dump(foo(false));"); MVCR("error->line = 1;" " }" " return $r;" "}" "var_dump(foo(true));" "var_dump(foo(false));"); MVCR("baz(bar(1), bar(''));" " }" "}"); MVCR("bar();" "}"); MVCR("foo(1);"); MVCR("foo);" " $x = new X;" " var_dump($x);" "}" "foo();"); MVCR("serial = self::$nextSerial++;" " }" "}"); { OptionSetter w1(this, OptionSetter::CompileTime, "-vLocalCopyProp=0 -vEliminateDeadCode=0"); MVCR("';" " $body .= '';" " $item_num = 0;" " if (null !== $values) {" " foreach($values as $val) {" " $row_id = 'tr_sentrylist_' . $item_num . '_' . $full_name;" " $body .= '';" " $body .= '';" " $body .= '';" " $body .= '';" " $item_num += 1;" " }" " }" " $body .= '
';" " $body .= foo($item_num, 0," " $val, $parent_fields);" " $body .= '';" " $body .= foo($item_num, $full_name, 0, 0);" " $body .= '
';" "}"); MVCR("bar();" " };" " }" " function bar() {}" "}"); MVCR("bar();" "}" "test();"); MVCRNW("foo();" " $x->foo();" " }" " function foo() { var_dump(__METHOD__); }" "}" "function test() {" " X::bar(null);" "}" "test();"); MVCR("__array[$offset])) {" " return $this->initializeOffset($offset);" " } else {" " return null;" " }" " return $this->__array[$offset];" " }" "}"); MVCR("bar();" " }" " return $x;" " }" "}"); MVCR("foo(false, true));"); MVCR(" false, 5 => false);\n" " $c = new C();\n" " var_dump($c->loadAllWithIDs($testA));\n" "}\n" "\n" "main();\n"); MVCR("bar();" " if ($this instanceof B) {" " $this->b = 1;" " }" " $this->a = 1;" " }" "}" "class B extends A {" " public $b;" " function bar() {}" "}" "function main() {" " $b = new B;" " $b->foo();" " var_dump($b);" "}" "main();"); return true; } bool TestCodeRun::TestReflection() { MVCR("name, $x->class);\n"); MVCR("a();" "$y = new Y;" "$y->a();" "var_dump(get_class_methods($x));" "var_dump(get_class_methods($y));"); MVCR("getParameters();\n" "var_dump($params[0]->isDefaultValueAvailable());\n"); MVCR("getMethod($mname);" " echo \"$cname:$mname:\"; var_dump($m->isConstructor());" "}" "test('X', 'X');" "test('Y', 'Y');" "test('Y', 'y');" "test('Z', 'Z');" "test('Z', 'z');"); MVCR("getMethods()));", "int(1)\n"); MVCRO("getMethods() as $m) {" " var_dump($m->name);" " }" "}" "test();", "string(3) \"bar\"\n"); MVCRO("getDocComment());\n" "\n" "class C {\n" " /**\n" " * Doc comment on a method generator\n" " */\n" " public function bar() {\n" " yield null;\n" " }\n" "}\n" "$rm = new ReflectionMethod('C','bar');\n" "var_dump($rm->getDocComment());\n" , "string(46) \"/**\n" " * Doc comment on a function generator\n" " */\"\n" "string(48) \"/**\n" " * Doc comment on a method generator\n" " */\"\n" ); } MVCR("getMethods());" " }" " var_dump('ok');" " } catch (Exception $e) {" " var_dump($e->getMessage());" " }" "}" "test();"); MVCRO(" array(' . count($params) . \") {\\n\";\n" " foreach ($params as $p) {\n" " echo \" name => {$p->getName()}\\n\";\n" " }\n" " echo \"}\\n\";\n" "}\n" "function show($rf) {\n" " var_dump($rf->getName());\n" " var_dump($rf->isUserDefined());\n" " var_dump($rf->getStartLine());\n" " var_dump($rf->getEndLine());\n" " var_dump($rf->getDocComment());\n" " var_dump($rf->getFileName() === __FILE__);\n" " show_params($rf->getParameters());\n" " var_dump($rf->getNumberOfParameters());\n" " var_dump($rf->getNumberOfRequiredParameters());\n" "}\n" "\n" "$rf = new ReflectionFunction($f);\n" "$rg = new ReflectionFunction($g);\n" "$radd = new ReflectionFunction($add);\n" "\n" "echo \"invoking f\\n\";\n" "$rf->invoke();\n" "\n" "echo \"\\ninvoking g\\n\";\n" "$rg->invoke('hello');\n" "$rg->invokeArgs(array('goodbye'));\n" "\n" "echo \"\\ninvoking add\\n\";\n" "$radd->invoke(1, 2);\n" "$radd->invokeArgs(array(5000000000, 5000000000));\n" "\n" "echo \"\\nshowing f\\n\";\n" "show($rf);\n" "\n" "echo \"\\nshowing g\\n\";\n" "show($rg);\n" "\n" "echo \"\\nshowing add\\n\";\n" "show($radd);\n" , "invoking f\n" "in $f\n" "\n" "invoking g\n" "in $g; passed hello\n" "in $g; passed goodbye\n" "\n" "invoking add\n" "x + y = 3\n" "x + y = 10000000000\n" "\n" "showing f\n" "string(9) \"{closure}\"\n" "bool(true)\n" "int(4)\n" "int(4)\n" "bool(false)\n" "bool(true)\n" "parameters => array(0) {\n" "}\n" "int(0)\n" "int(0)\n" "\n" "showing g\n" "string(9) \"{closure}\"\n" "bool(true)\n" "int(5)\n" "int(5)\n" "bool(false)\n" "bool(true)\n" "parameters => array(1) {\n" " name => a\n" "}\n" "int(1)\n" "int(0)\n" "\n" "showing add\n" "string(9) \"{closure}\"\n" "bool(true)\n" "int(8)\n" "int(11)\n" "string(54) \"/** This doc comment is so helpful and descriptive. */\"\n" "bool(true)\n" "parameters => array(2) {\n" " name => x\n" " name => y\n" "}\n" "int(2)\n" "int(2)\n" ); MVCR("getName()); " " var_dump($func->isInternal()); " " var_dump($func->isUserDefined()); " " var_dump($func->isClosure()); " " $vars = $func->getStaticVariables(); " " var_dump(count($vars));" " var_dump(isset($vars['a']));" " var_dump($func->returnsReference()); " " var_dump($func->getNumberOfParameters()); " " var_dump($func->getNumberOfRequiredParameters()); " " foreach ($func->getParameters() as $name => $param) {" " var_dump($name); " " dump_param($param); " " }" "} " "" "function verify_class($cls) {" " if ($cls) {" " var_dump($cls->getName()); " " } else {" " var_dump(null);" " }" "}" "" "function verify_classes($classes) {" " ksort($classes);" " foreach ($classes as $cls) {" " verify_class($cls); " " }" "}" "" "function dump_param($param) {" " var_dump($param->getName()); " " var_dump($param->isPassedByReference()); " " verify_class($param->getDeclaringClass()); " " verify_class($param->getClass()); " " var_dump($param->isArray()); " " var_dump($param->allowsNull()); " " var_dump($param->isOptional()); " " var_dump($param->isDefaultValueAvailable()); " " if ($param->isOptional()) { " //" var_dump($param->getDefaultValue()); " " } " " var_dump($param->getPosition()); " "} " "" "function dump_prop($prop, $obj) {" " var_dump($prop->getName()); " " var_dump($prop->isPublic()); " " var_dump($prop->isPrivate()); " " var_dump($prop->isProtected()); " " var_dump($prop->isStatic()); " //" var_dump($prop->isDefault()); " " var_dump($prop->getModifiers() & 0xffff); " " if ($prop->isPublic()) { " " var_dump($prop->getValue($obj)); " " if (!$prop->isStatic()) {" " var_dump($prop->setValue($obj, 78)); " " }" " var_dump($prop->getValue($obj)); " " } " " verify_class($prop->getDeclaringClass()); " "} " "" "function dump_class($cls, $obj) {" " var_dump($cls->isInstance($obj)); " " var_dump($cls->getName()); " " var_dump($cls->isInternal()); " " var_dump($cls->isUserDefined()); " " var_dump($cls->isInstantiable()); " " var_dump($cls->hasConstant('CLS_CONST')); " " var_dump($cls->hasMethod('method1')); " " var_dump($cls->hasProperty('prop1')); " " dump_func($cls->getMethod('method1')); " " dump_prop($cls->getProperty('prop1'), $obj); " " verify_classes($cls->getInterfaces()); " " var_dump($cls->isInterface()); " " var_dump($cls->isAbstract()); " " var_dump($cls->isFinal()); " " var_dump($cls->getModifiers() & 0xffff); " " verify_class($cls->getParentClass()); " " var_dump($cls->isSubclassOf('i1')); " " var_dump($cls->getStaticPropertyValue('prop2')); " //" var_dump($cls->setStaticPropertyValue('prop2', 45)); " " cls1::$prop2 = 45; " " var_dump($cls->getStaticPropertyValue('prop2')); " " var_dump(cls1::$prop2); " " var_dump($cls->isIterateable()); " " var_dump($cls->implementsInterface('i2')); " " foreach ($cls->getProperties() as $name => $prop) {" " var_dump($name); " " dump_prop($prop, $obj); " " }" " foreach ($cls->getMethods() as $name => $func) {" " var_dump($name); " " dump_func($func); " " var_dump($func->isFinal()); " " var_dump($func->isAbstract()); " " var_dump($func->isPublic()); " " var_dump($func->isPrivate()); " " var_dump($func->isProtected()); " " var_dump($func->isStatic()); " " var_dump($func->isConstructor()); " " var_dump($func->isDestructor()); " " var_dump($func->getModifiers() & 0xFFFF); " " verify_class($func->getDeclaringClass()); " " if ($name == 'method1') $func->invoke($obj, 'invoked'); " " }" "}" "" // verification "$func = new ReflectionFunction('func1'); " "dump_func($func); " "" "$func = new ReflectionFunction('func2'); " "$func->invoke('invoked');" "" "$cls = new ReflectionClass('cls1'); " "$obj = $cls->newInstance(); " "dump_class($cls, $obj);" "" "$cls = new ReflectionClass('cls2'); " "$obj = $cls->newInstance(); " "dump_class($cls, $obj);" ""); MVCR("getProperty('arr');" " return $p->getValue();" " }" "}" "abstract class aa extends c {" " public function get_arr() {" " $actions = parent::get_arr();" " return $actions;" " }" "}" "class a extends aa {" " public static $arr = array('v');" "}" "$x = new a;" "var_dump($x->g());"); MVCR("getName());" "$r = new ReflectionClass('bbbb');" "var_dump($r->getName());" "$a = new aaaa;" "$a->f();"); MVCR("getConstant(\"bar\"));"); MVCR("getFileName() !== '');" "var_dump($i->getFileName() !== '');"); MVCR("hasMethod('mE'));" "var_dump($ref->hasMethod('me'));" "$m = $ref->getMethod('me');" "var_dump($m->getName());"); MVCR("name);" " }" "}" "$condition = 123;" "if ($condition) {" " class A extends Base {}" "} else {" " class A extends Base {}" "}" "class B extends A {" " function bar() {" " }" "}" "$obj = new B();" "$obj->foo();"); MVCR("implementsInterface('A'));" "$inter = new ReflectionClass('B');" "var_dump($inter->hasMethod('foo'));"); MVCR("getName()); } }\n" "$r = new ReflectionClass('A');\n" "$a = $r->getProperties(); f($a);\n" "$a = $r->getProperties(ReflectionProperty::IS_PUBLIC); f($a);\n" "$a = $r->getProperties(ReflectionProperty::IS_PRIVATE); f($a);\n" "$a = $r->getProperties(ReflectionProperty::IS_PROTECTED); f($a);\n" "$a = $r->getProperties(ReflectionProperty::IS_STATIC); f($a);\n"); { HipHopSyntax w(this); MVCROF( "isClosure()); " "var_dump($rf->isGenerator()); " " " "function is_a_generator() { " " yield 1; " " yield 2; " "}; " "$rf = new ReflectionFunction('is_a_generator'); " "var_dump($rf->isClosure()); " "var_dump($rf->isGenerator()); " " " "$cl = function() { " " return 1; " "}; " "$rf = new ReflectionFunction($cl); " "var_dump($rf->isClosure()); " "var_dump($rf->isGenerator()); " " " "$cl = function() { " " yield 1; " " yield 2; " "}; " "$rf = new ReflectionFunction($cl); " "var_dump($rf->isClosure()); " "var_dump($rf->isGenerator()); " , "test/vm/reflection_isclosure.php.exp" ); } return true; } bool TestCodeRun::TestErrorHandler() { MVCR("getMessage();" " var_dump($msg);" " }" " public static function setup() {" " set_exception_handler(array(__CLASS__, 'log'));" " }" "}" "$obj = new C;" "$obj->setup();" "throw new Exception('test');"); return true; } bool TestCodeRun::TestAssertOptions() { MVCR("a = 1;" "$x->b = 'hello';" "$x->c = $x;" "var_dump(http_build_query($x));"); MVCR(";\\$y=woo!;\\n\";\n" "$arr = token_get_all($str);\n" "foreach ($arr as $t) {\n" " if ($t[0] == 396) {\n" " var_dump($t[1]);\n" " }\n" "}\n" , "string(12) \"T_XHP_TAG_LT\"\n" "string(1) \"<\"\n" "string(1) \"<\"\n" "string(1) \"<\"\n" ); return true; } bool TestCodeRun::TestInvalidArgument() { MVCRO(" 'UTF-8'," " 'line-length' => 76," " 'line-break-chars' => '\n'" ");" "$preferences['scheme'] = 'Q';" "$preferences['input-charset'] = str_pad('invalid-charset', 64);" "var_dump(iconv_mime_encode('Subject', 'Pr\xc3\274fung Pr\xc3\274fung'," " $preferences));" "$preferences['input-charset'] = 'ISO-8859-1';" "$preferences['output-charset'] = str_pad('invalid-charset', 64);" "var_dump(iconv_mime_encode('Subject', 'Pr\xc3\274fung Pr\xc3\274fung'," " $preferences));" "var_dump(iconv_set_encoding('internal_encoding'," " str_pad('invalid-charset', 64)));" "var_dump(iconv('UTF-8', str_pad('invalid-charset', 64), ''));" "var_dump(iconv(str_pad('invalid-charset', 64), 'UTF-8', ''));" "var_dump(time_nanosleep(-1, 0));" "var_dump(time_nanosleep(0, -1));" "var_dump(time_sleep_until(0));" "var_dump(gzcompress('abc', -2));" "var_dump(gzdeflate('abc', -2));" "var_dump(http_build_query(1));" "var_dump(parse_url('http://www.example.com', 100));" "var_dump(dns_check_record('127.0.0.1', 'INVALID_TYPE'));" "var_dump(assert_options(-1));" "var_dump(simplexml_load_string('', 'INVALID_CLASS'));" "var_dump(simplexml_load_string('', 'stdClass'));" "var_dump(stream_get_contents('', -1));" "$fp = fopen('test/test_ext_file.txt', 'r');" "var_dump(fgets($fp, -1));" /* Not handled correctly. Invalid arg /types/ should result in the function not being called, and null returned (even though the functions are documented as returning false on failure). "var_dump(fputcsv($fp, array(), 'abc'));" "var_dump(fputcsv($fp, array(), 'a', 'def'));" "var_dump(fgetcsv($fp, array(), 'abc'));" "var_dump(fgetcsv($fp, array(), 'a', 'def'));" */ "fclose($fp);" "$tmpfname = tempnam('', str_repeat('a', 128));" "var_dump(strlen(basename($tmpfname)));" "unlink($tmpfname);" "$tmpfname = tempnam('', '/var/www' . str_repeat('a', 128));" "var_dump(strlen(basename($tmpfname)));" "unlink($tmpfname);" "$ar1 = array(10, 100, 100, 0);" "$ar2 = array(1, 3, 2);" "var_dump(array_multisort($ar1, $ar2));" "$phrase = 'eat fruits, vegetables, and fiber every day.';" "$healthy = array('fruits', 'vegetables');" "$yummy = array('pizza', 'beer', 'ice cream');" "var_dump(str_replace($healthy, $yummy, $phrase));" "var_dump(str_replace('ll', $yummy, 'good golly miss molly!'," " $count));" "var_dump(setlocale(LC_ALL, array('de_DE@euro', 'de_DE', 'deu_deu')," " array(1, 2)));" "var_dump(setlocale(LC_ALL, str_pad('a', 255)));" "var_dump(pack(\"\\xf4\", 0x1234, 0x5678, 65, 66));" "var_dump(pack(\"x5\", 0x1234, 0x5678, 65, 66));" "var_dump(pack(\"h\", -0x1234));" "var_dump(pack(\"h\", 12345678900));" "var_dump(unpack(\"\\xf4\", \"0x1234\"));" "var_dump(sscanf('foo', '[%s', $id, $first, $last));" "var_dump(sscanf('foo', '%z', $id, $first, $last));" "var_dump(sscanf(\"SN/abc\", \"SN/%d%d\", $out));" "var_dump($out);" "var_dump(sscanf(\"SN/abc\", \"\", $out));" "var_dump($out);" "var_dump(printf('%$', 3));" "var_dump(vsprintf('%$', 3));" "var_dump(sprintf('%$', 3));" "var_dump(vsprintf('%$', 3));" "var_dump(str_word_count('abc', 2, '...'));" "var_dump(str_word_count('abc', 2, 'b..a'));" "var_dump(str_word_count('abc', 2, 'a..b..c'));" "var_dump(base_convert('05678', 8, 37));" "var_dump(convert_cyr_string('abc', 'y', 'z'));" "var_dump(money_format('%abc', 1.33));" "var_dump(money_format('%i%i', 1.33));" "var_dump(str_pad('abc', 10, '', 100));" "var_dump(str_pad('abc', 10, ' ', 100));" "var_dump(wordwrap('', 75, '', true));" "var_dump(wordwrap(null, 75, '', true));" "var_dump(wordwrap('abc', 75, '', true));" "var_dump(wordwrap('abc', 0, '', true));"); MVCR(" 1);" "}" "test();" "var_dump($_POST);"); MVCR(" &$v) {\n" " if ($k == 'a') { $v = -1; }\n" " }\n" " global $a;\n" " var_dump($a);\n" " $b = $GLOBALS;\n" " $b['a'] = 0;\n" " var_dump($GLOBALS['a']);\n" "}\n" "f();\n"); return true; } bool TestCodeRun::TestGlobalStatement() { MVCR("bar();"); MVCR("q;" " echo $foo;" " }" " function y() {" " static $foo = 20;" " $foo++;" " echo $foo;" " }" " static function sf() {" " static $foo = 0;" " $foo++;" " echo $foo;" " }" "}" "class d extends c {" " public $q = 30;" "}" "$x = new c();" "$x->x();" "$x->y();" "$x->y();" "$x->y();" "$x->y();" "$x = new d();" "$x->x();" "$x->y();" "$x->y();" "$x->y();" "c::sf();" "c::sf();" "c::sf();" "d::sf();" "d::sf();" "d::sf();"); MVCR("foo();" " }" "}" "class B extends A {}" "class C extends A {}" "$a = new A;" "$b = new B;" "$c = new C;" "$a->run();" "$b->run();" "$c->run();"); return true; } bool TestCodeRun::TestIfStatement() { MVCR("= 2) continue 2;" " echo \"I : $i J : $j\".\"\\n\";" " }" " echo \"End\\n\";" "}" "for ($i = 0;$i<10;$i++) {" " if ($i % 2 == 0) continue 1;" " echo $i . \"\\n\";" "}" "for ($i = 0;$i<10;$i++) {" " if ($i % 2 == 0) continue;" " echo $i . \"\\n\";" "}"); MVCR(" 1) return;" " if ($a == 1) return 1;" "}" "function foo3($a) {" " if ($a > 1) return;" " if ($a == 1) return;" "}" "function bar() {" " $v1 = foo1(0);" " var_dump($v1);" " $v2 = foo2(0);" " var_dump($v2);" " $v3 = foo3(0);" " var_dump($v3);" "}" "bar();"); MVCR(" 1));" \ #op"(array(\"\\0\" => \"\\0\"));" \ #op"(array(\"\\0\" => \"\\\\\"));" \ #op"(array(\"\\0\" => \"\\'\"));" \ #op"(array(\"\\\\\" => 1));" \ #op"(array(\"\\\\\" => \"\\0\"));" \ #op"(array(\"\\\\\" => \"\\\\\"));" \ #op"(array(\"\\\\\" => \"\\'\"));" \ #op"(array(\"\\'\" => 1));" \ #op"(array(\"\\'\" => \"\\0\"));" \ #op"(array(\"\\'\" => \"\\\\\"));" \ #op"(array(\"\\'\" => \"\\'\"));" \ #op"(array(\"\\a\" => \"\\a\"));" \ #op"(!array(\"\\0\" => \"\\0\"));" \ #op"((array(\"\\0\" => \"\\0\")));" \ #op"((int)array(\"\\0\" => \"\\0\"));" \ #op"((integer)array(\"\\0\" => \"\\0\"));" \ #op"((bool)array(\"\\0\" => \"\\0\"));" \ #op"((boolean)array(\"\\0\" => \"\\0\"));" \ #op"((float)array(\"\\0\" => \"\\0\"));" \ #op"((double)array(\"\\0\" => \"\\0\"));" \ #op"((real)array(\"\\0\" => \"\\0\"));" \ #op"((string)array(\"\\0\" => \"\\0\"));" \ "$a = \"0x10\";" \ #op"($a);" \ #op"(\"\\0\");" \ "$a = array(\"\\0\" => 1);" \ #op"($a);" \ "$a = array(\"\\0\" => \"\\0\");" \ #op"($a);" \ "$a = array(\"\\0\" => \"\\\\\");" \ #op"($a);" \ "$a = array(\"\\0\" => \"\\'\");" \ #op"($a);" \ "$a = array(\"\\\\\" => 1);" \ #op"($a);" \ "$a = array(\"\\\\\" => \"\\0\");" \ #op"($a);" \ "$a = array(\"\\\\\" => \"\\\\\");" \ #op"($a);" \ "$a = array(\"\\\\\" => \"\\'\");" \ #op"($a);" \ "$a = array(\"\\'\" => 1);" \ #op"($a);" \ "$a = array(\"\\'\" => \"\\0\");" \ #op"($a);" \ "$a = array(\"\\'\" => \"\\\\\");" \ #op"($a);" \ "$a = array(\"\\'\" => \"\\'\");" \ #op"($a);" \ "$a = array(\"\\a\" => \"\\a\");" \ #op"($a);" #define UNARY_OP(op) \ MVCR(UNARY_OP_DATA(op)) \ MVCR(UNARY_OP_ARRAY_DATA(op)) bool TestCodeRun::TestUnaryOperators() { UNARY_OP(var_dump); MVCR("\");"); return true; } bool TestCodeRun::TestPrint() { UNARY_OP(echo); UNARY_OP(print); UNARY_OP(print_r); UNARY_OP(serialize); return true; } bool TestCodeRun::TestVarExport() { MVCR(UNARY_OP_DATA(var_export)); MVCRO(UNARY_OP_ARRAY_DATA(var_export), "array (\n" " '' . \"\\0\" . '' => 1,\n" ")array (\n" " '' . \"\\0\" . '' => '' . \"\\0\" . '',\n" ")array (\n" " '' . \"\\0\" . '' => '\\\\',\n" ")array (\n" " '' . \"\\0\" . '' => '\\\\\\\'',\n" ")array (\n" " '\\\\' => 1,\n" ")array (\n" " '\\\\' => '' . \"\\0\" . '',\n" ")array (\n" " '\\\\' => '\\\\',\n" ")array (\n" " '\\\\' => '\\\\\\\'',\n" ")array (\n" " '\\\\\\\'' => 1,\n" ")array (\n" " '\\\\\\\'' => '' . \"\\0\" . '',\n" ")array (\n" " '\\\\\\\'' => '\\\\',\n" ")array (\n" " '\\\\\\\'' => '\\\\\\\'',\n" ")array (\n" " '\\\\a' => '\\\\a',\n" ")falsearray (\n" " '' . \"\\0\" . '' => '' . \"\\0\" . '',\n" ")11truetrue111'Array''0x10''' . \"\\0\" . ''array (\n" " '' . \"\\0\" . '' => 1,\n" ")array (\n" " '' . \"\\0\" . '' => '' . \"\\0\" . '',\n" ")array (\n" " '' . \"\\0\" . '' => '\\\\',\n" ")array (\n" " '' . \"\\0\" . '' => '\\\\\\\'',\n" ")array (\n" " '\\\\' => 1,\n" ")array (\n" " '\\\\' => '' . \"\\0\" . '',\n" ")array (\n" " '\\\\' => '\\\\',\n" ")array (\n" " '\\\\' => '\\\\\\\'',\n" ")array (\n" " '\\\\\\\'' => 1,\n" ")array (\n" " '\\\\\\\'' => '' . \"\\0\" . '',\n" ")array (\n" " '\\\\\\\'' => '\\\\',\n" ")array (\n" " '\\\\\\\'' => '\\\\\\\'',\n" ")array (\n" " '\\\\a' => '\\\\a',\n" ")"); return true; } bool TestCodeRun::TestLocale() { MVCRO("a;}} " "$a = new A; $a->a = 'a'; $b = new A; $b->a = 'b'; " "$arr = array($a, $b); sort($arr, SORT_REGULAR, true); " "print ((string)$arr[0]);", "a"); MVCRO("a = 'a'; $b = new A; $b->a = 'b'; " "$arr = array($b, $a);" "print $arr[0]->a;" "sort($arr, SORT_REGULAR, true); " "print $arr[0]->a;", "ba"); MVCRO("bar();" "$f2->bar();" "var_dump(get_class(\"qwerty\"));" "var_dump(get_class($f1));" "var_dump(get_class($f2));" ); MVCR("test();" "$bar->test();" "$bar->test_bar();" "$goo->test();" "$goo->test_bar();" "$goo->test_goo();" "var_dump(get_parent_class($bar));" "var_dump(get_parent_class($foo));" "var_dump(get_parent_class($goo));" "var_dump(get_parent_class(\"bar\"));" "var_dump(get_parent_class(\"foo\"));" "var_dump(get_parent_class(\"goo\"));" "var_dump(get_parent_class(\"i\"));" "var_dump(get_parent_class(\"\"));" "var_dump(get_parent_class(\"[[[[\"));" "var_dump(get_parent_class(\" \"));" "var_dump(get_parent_class(new stdclass));" "var_dump(get_parent_class(array()));" "var_dump(get_parent_class(1));" ); return true; } bool TestCodeRun::TestRedeclaredFunctions() { MVCR("getCode());\n" " }\n" "}\n" "foo();\n" ); MVCR("childProp; }" " function testChildMeth() { return $this->childMeth(); }" " static function baseStatMeth() {" " return 'Base static method';" " }" " function childMeth() { return 'I am base'; }" " }" "} else {" " class base {" " }" "}" "class child1 extends base {" " public $child1Val = 'child1';" " public $childProp = 'IamChild1';" " static $child1Static = 'child1Stat';" " function childMeth() {" " return 'I am child1';" " }" " static function child1StatMeth() {" " return 'Child 1 static method';" " }" " function parentChildMeth() {" " return parent::childMeth();" " }" "}" "class child2 extends child1 {" " public $child2Val = 'child2';" " public $childProp = 'IamChild2';" " static $child2Static = 'child2Stat';" " static function child2StatMeth() {" " return 'Child 2 static method';" " }" " function childMeth() {" " return 'I am child2';" " }" " function parentChildMeth() {" " return parent::childMeth();" " }" " function testChildMeth2() { return $this->childMeth(); }" "}" "if (true) {" " class child3 extends child2 {" " public $child3Val = 'child3';" " public $childProp = 'IamChild3';" " static $child3Static = 'child3Stat';" " function childMeth() {" " return 'I am child3';" " }" " static function child3StatMeth() {" " return 'Child 3 static method';" " }" " function parentChildMeth() {" " return parent::childMeth();" " }" "" " }" "} else {" " class child3 {}" "}" "function test($val, $exp, $feature) {" " if ($val !== $exp) {" " echo $feature . \" failed. Got:\\n\";" " var_dump($val);" " echo \"But expected:\\n\";" " var_dump($exp);" " } else {" " echo $feature . \" passed\\n\";" " }" "}" "function run() {" " $base = new base;" " test($base->baseVal, 'base', 'Base object member');" " test(base::$baseStatic, 'baseStat', 'Base static member');" " test(base::baseStatMeth(), 'Base static method', 'Base static method');" " test($base->baseStatMeth(), 'Base static method', 'Base static method obj syntax');" " $child1 = new child1;" " test($child1->baseVal, 'base', 'dRedec inherited property');" " test($child1->child1Val, 'child1', 'dRedec property');" " test($child1->testChildMeth(), 'I am child1', 'dRedec parent->virtual method');" " test($child1->childProp(), 'IamChild1', 'dRedec parent->child prop method');" " test(child1::child1StatMeth(), 'Child 1 static method', 'dRedec static method');" " test(child1::baseStatMeth(), 'Base static method', 'dRedec parent static method');" " test($child1->child1StatMeth(), 'Child 1 static method', 'dRedec static method obj syntax');" " test($child1->baseStatMeth(), 'Base static method', 'dRedec parent static method obj syntax');" " test(child1::$baseStatic, 'baseStat', 'dRedec parent static prop');" " test(child1::$child1Static, 'child1Stat', 'dRedec static prop');" " test($child1->parentChildMeth(), 'I am base', 'dRedec parent method');" " $child2 = new child2;" " test($child2->baseVal, 'base', 'ddRedec grandparent property');" " test($child2->child1Val, 'child1', 'ddRedec parent property');" " test($child2->child2Val, 'child2', 'ddRedec property');" " test($child2->testChildMeth(), 'I am child2', 'ddRedec grandparent->virtual method');" " test($child2->testChildMeth2(), 'I am child2', 'ddRedec parent->virtual method');" " test($child2->childProp(), 'IamChild2', 'ddRedec grandparent->child prop method');" " test(child2::baseStatMeth(), 'Base static method', 'ddRedec grandparent static method');" " test(child2::child1StatMeth(), 'Child 1 static method', 'ddRedec parent static method');" " test(child2::child2StatMeth(), 'Child 2 static method', 'ddRedec static method');" " test($child2->baseStatMeth(), 'Base static method', 'ddRedec grandparent static method obj syntax');" " test($child2->child1StatMeth(), 'Child 1 static method', 'ddRedec parent static method obj syntax');" " test($child2->child2StatMeth(), 'Child 2 static method', 'ddRedec static method obj syntax');" " test(child2::$baseStatic, 'baseStat', 'ddRedec grandparent static prop');" " test(child2::$child1Static, 'child1Stat', 'ddRedec parent static prop');" " test(child2::$child2Static, 'child2Stat', 'ddRedec static prop');" " test($child2->parentChildMeth(), 'I am child1', 'ddRedec parent method');" " $child3 = new child3;" " test($child3->baseVal, 'base', 'RddRedec greatgrandparent property');" " test($child3->child1Val, 'child1', 'RddRedec grandparent property');" " test($child3->child2Val, 'child2', 'RddRedec parent property');" " test($child3->child3Val, 'child3', 'RddRedec property');" " test($child3->testChildMeth(), 'I am child3', 'RddRedec greatgrandparent->virtual method');" " test($child3->testChildMeth2(), 'I am child3', 'RddRedec grandparent->virtual method');" " test($child3->childProp(), 'IamChild3', 'RddRedec greatgrandparent->child prop method');" " test(child3::baseStatMeth(), 'Base static method', 'RddRedec greatgrandparent static method');" " test(child3::child1StatMeth(), 'Child 1 static method', 'RddRedec grandparent static method');" " test(child3::child2StatMeth(), 'Child 2 static method', 'RddRedec parent static method');" " test(child3::child3StatMeth(), 'Child 3 static method', 'RddRedec static method');" " test($child3->baseStatMeth(), 'Base static method', 'RddRedec greatgrandparent static method obj syntax');" " test($child3->child1StatMeth(), 'Child 1 static method', 'RddRedec grandparent static method obj syntax');" " test($child3->child2StatMeth(), 'Child 2 static method', 'RddRedec parent static method obj syntax');" " test($child3->child3StatMeth(), 'Child 3 static method', 'RddRedec static method obj syntax');" " test(child3::$baseStatic, 'baseStat', 'RddRedec greatgrandparent static prop');" " test(child3::$child1Static, 'child1Stat', 'RddRedec grandparent static prop');" " test(child3::$child2Static, 'child2Stat', 'RddRedec parent static prop');" " test(child3::$child3Static, 'child3Stat', 'RddRedec static prop');" " test($child3->parentChildMeth(), 'I am child2', 'RddRedec parent method');" "}" "run();" ); MVCR("foo();" "$t->bar();"); MVCR("foo();" "$t->bar();"); MVCR("a, '\n';" "}} test();"); MVCR("bar();" " $x = new V;" " $x->bar();" "}" "test();"); MVCR("foo + $this->bar; }" "}" "class D2 extends D1 {" " public $foo;" " private $bar;" " function bar() { return $this->foo + $this->bar; }" "}" "PEAR::f();"); MVCR("bar = 1;" "$x->foo = 2;" "var_dump($x);"); MVCR("out(A::fun()); }" " public function out($arg) { var_dump($arg); }" "}" "$c = new C();" "$c->foo();"); MVCR("x();" " }" " function y() {" " echo 'y';" " }" "}" "class c extends b {" " function x() {" " $this->y();" " }" "}" "if (false) {" " class b{}" " class c{}" "}" "$x = new c();" "$x->z();"); MVCR("meh()->work();" "}" "test();"); MVCR("t = 5;" " $x->a = 3;" " $y = clone $x;" " var_dump($y->a,$y->t);" "}" "test();"); MVCR("a = 2; }" " }" "} else {" " class A {" " protected $a = 1;" " }" " class B extends A {" " public $a;" " function f() { $this->a = 2; }" " }" "}" "$obj = new B;" "$obj->f();" "var_dump($obj);"); MVCR(" $v) {" " var_dump($v);" " }" " }" "}" "$x = new d;" "$x->t2();"); MVCR(" 2, 2 => 3); " "foreach ($myarray as $this => $wat) {" " echo \"You should not see this\"; " "}", ""); MVCRONW(" 2, 2 => 3); " "foreach ($myarray as $a => $this) {" " echo \"You should not see this\"; " "}", ""); return true; } bool TestCodeRun::TestClone() { MVCR("foo = 'foo';" "$a1->fooref = &$p;" "$a1->dyn = 'dyn';" "$a1->dynref = &$q;" "var_dump($a1);" "$a2 = clone $a1;" "var_dump($a1);" "var_dump($a2);" "$a2->foo = 'a2foo';" "$a2->fooref = 'a2fooref';" "$a2->dyn = 'a2dyn';" "$a2->dynref = 'a2dynref';" "$a2->dynref2 = 'dynref2';" "var_dump($a1);" "var_dump($a2);" "var_dump($p);" "var_dump($q);"); MVCR("cm);" " }" "}" "class c2 extends c {}" "$y = new c;" "$y->x();" "$z = clone $y;" "$z->x();" "$y = new c2;" "$y->x();" "$z = clone $y;" "$z->x();"); return true; } bool TestCodeRun::TestEvalOrder() { MVCRO("foo(var_dump('123'));\n" "var_dump('end');\n" "function h() { var_dump('errored');}", "string(7) \"errored\"\n"); MVCR(" $x) { " " var_dump($x); " "}"); MVCR("var = $array;\n" " }\n" " }\n" " public function rewind() {\n" " echo \"rewinding\n\";\n" " reset($this->var);\n" " }\n" " public function current() {\n" " $var = current($this->var);\n" " echo \"current: $var\n\";\n" " return $var;\n" " }\n" " public function key() {\n" " $var = key($this->var);\n" " echo \"key: $var\n\";\n" " return $var;\n" " }\n" " public function next() {\n" " $var = next($this->var);\n" " echo \"next: $var\n\";\n" " return $var;\n" " }\n" " public function valid() {\n" " $var = $this->current() !== false;\n" " echo \"valid: \",$var?'true':'false',\"\n\";\n" " return $var;\n" " }\n" "}\n" "\n" "function f() { var_dump('f'); return 0; }\n" "function g() { var_dump('g'); return 0; }\n" "\n" "$a = array(1, 2);\n" "$values = array('a' => 1, 'b' => 2, 'c' => 3);\n" "$it = new MyIterator($values);\n" "foreach ($it as $a[f()] => $a[g()]) {\n" " print \"$a[0]\n\";\n" "}\n"); MVCR("a[foo()]->y); "); MVCR("foo = 9;" " $this->bar = '3';" " return $this;" " }" "}" "$a = new A();" "var_dump($a->q('1')->foo + $a->q('2')->bar);" "var_dump($a->q('1')->foo - $a->q('2')->bar);" "var_dump($a->q('1')->foo / $a->q('2')->bar);" "var_dump($a->q('1')->foo * $a->q('2')->bar);" "var_dump($a->q('1')->foo % $a->q('2')->bar);" "var_dump($a->q('1')->foo << $a->q('2')->bar);" "var_dump($a->q('1')->foo >> $a->q('2')->bar);" "var_dump($a->q('1')->foo && $a->q('2')->bar);" "var_dump($a->q('1')->foo || $a->q('2')->bar);" "var_dump($a->q('1')->foo and $a->q('2')->bar);" "var_dump($a->q('1')->foo or $a->q('2')->bar);" "var_dump($a->q('1')->foo xor $a->q('2')->bar);" "var_dump($a->q('1')->foo . $a->q('2')->bar);" "var_dump($a->q('1')->foo & $a->q('2')->bar);" "var_dump($a->q('1')->foo | $a->q('2')->bar);" "var_dump($a->q('1')->foo ^ $a->q('2')->bar);" "var_dump($a->q('1')->foo == $a->q('2')->bar);" "var_dump($a->q('1')->foo === $a->q('2')->bar);" "var_dump($a->q('1')->foo != $a->q('2')->bar);" "var_dump($a->q('1')->foo !== $a->q('2')->bar);" "var_dump($a->q('1')->foo > $a->q('2')->bar);" "var_dump($a->q('1')->foo >= $a->q('2')->bar);" "var_dump($a->q('1')->foo < $a->q('2')->bar);" "var_dump($a->q('1')->foo <= $a->q('2')->bar);" ); MVCR("f(p(1), p(2), p(3), 4);" "echo \"rsfc\n\";" "rt($a, id(10));" "var_dump($a);" "dump($v++, $v++);" "$v = 10;" "dump($v, $v = 0);" "echo \"nest\n\";" "x(p(1), x(p(2), p(3), p(4), p(5)), p(6), x(p(7), p(8), p(9), p(10)));" "echo \"arr\n\";" "$z = array(p(1), p(2), x(p(3), p(4), p(5), p(6)), p(7));" "$q = 1;" "$z = array(1, 2, $q);" ); MVCR("f(pid('arg1'),pid('arg2'));" " }" "}" "$d = id1(new cls())" " ->f('arg1')" " ->f('arg2')" " ->f('arg3');" "$d = id1(new cls())" " ->f('arg1', 'argex1')" " ->f('arg2', 'argex2')" " ->f('arg3', 'argex3');" "$d = id(new cls(), pid('idarg'))" " ->f(pid('arg1'), pid('argex1'))" " ->f(pid('arg2'), pid('argex2'))" " ->f(pid('arg3'), pid('argex3'));" "$d->ttest();"); MVCR("r($x);" "var_dump($x);"); MVCR("x(3, p(1), p(2))->x(6, p(4), p(5));"); MVCR("val = $v;" " }" " public function blah() {" " return $this;" " }" "}" "class A {" " public $v;" " function set($v) {" " $this->v = $v;" " return $this;" " }" "}" "function id($x) { return $x; }" "$x = new Q(0);" "$a = id(new A)->set($x);" "$x = id(new Q(1))->blah();" "var_dump($a);"); MVCR("f, $a->g); var_dump($a);\n" "}\n" "test();\n"); MVCR("_p[ $what ];" " }" " public function __set( $what, $value ) {" " echo \"set C\\n\";" " $this->_p[ $what ] = $value;" " }" " private $_p = array();" "}" "function f() {" " echo \"f()\\n\";" " return 1;" "}" "function foo() {" " $obj = new C;" " $obj->a = f();" " $obj->b = new C;" " $obj->b->a = f();" "}" "foo();"); MVCR("data[$name];" " }" " public function offsetSet($name, $value) {" " $a = serialize($value);" " echo \"offsetSet: $name=$a\\n\";" " $this->data[$name]=$value;" " }" " public function offsetExists($name) {" " echo \"offsetExists: $name\\n\"; return true;" " }" " public function offsetUnset($name) {" " echo \"offsetUnset: $name\\n\";" " }" "}" "function f() {" " echo \"f()\\n\";" " return 1;" "}" "function f2() {" " echo \"f2()\\n\";" " return 'foo';" "}" "function foo($a) {" " $a['foo'] = new C;" " $a['foo']['bar'] = new C;" " $a['foo']['bar']['goo'] = f();" "}" "foo(new C);"); MVCR(" &$v);" " return $a;" "}" "function goo($v) {" " return $v . 1;" "}" "var_dump(foo('1.0'));" "var_dump(foo(foo('1.0')));" "var_dump(foo(goo('1.0')));"); MVCR("prop = 5;" " return 0;" "}" "$a = new stdclass;" "$a->prop = 2;" "var_dump($a->prop . k($a));" "$a = new stdclass;" "$a->prop = 2;" "var_dump(($a->prop . '') . k($a));" "$i = 0;" "var_dump($i . ++$i);" "$i = 0;" "var_dump(($i . '') . ++$i);" "function foo() {" " return 'foo';" "}" "f($a, 'test');" "var_dump(($a . 'x') . foo($a = ''));" "$a = array(2);" "var_dump($a[$a = 0]);" "$a = new stdclass;" "$a->foo = 42;" "var_dump($a->{$a = 'foo'});" "var_dump($a);" "$b = new stdclass;" "$a = null;" "$a->{f($a,$b)} = 5;" "var_dump($a, $b);" "function dump($a, $b) {" " var_dump($a, $b);" "}" "f($a, 'foo');" "dump($a, $a = 'bar');" "$a = 'foo';" "dump($a, $a = 'bar');" "f($a, 'foo');" "dump($a.'', $a = 'bar');" "f($a, 'foo');" "dump($a.$a, $a = 'bar');"); MVCR("{$n} = $v;" " echo 'set:'; var_dump($n, $v);" " }" " function OffsetExists($n) { return $n == 'foo'; }" " function OffsetUnset($n) {}" " function __get($n) { return $this->OffsetGet($n); }" " function __set($n,$v) { return $this->OffsetSet($n, $v); }" "}" "$a = new X;" "function ref(&$a, &$b, &$c) {" "}" "function test() {" " global $a;" " $a[f(0)]->{f(1)}[f(2)] = $a[f(3)][f(4)][f(5)]->foo;" " var_dump($a[f(6)]['fuz'] . f(7));" " ref($a[f(10)][f(11)][f(12)],$a[f(20)][f(21)][f(22)]," " $a[f(30)][f(31)][f(32)]);" " $a->{f(0)}[f(1)]->{f(2)} = $a->{f(3)}->{f(4)}->bar;" "}" "test();"); MVCR("foo($x = null);" " $y($y = null);" "}" "test(new X, 'y');"); MVCR(" $x[$a = 'foo']);" " return $a;" "}" "var_dump(test(array('foo' => 5)));"); MVCR("\n" " string(1) \"T\"\n" "}\n" "bool(true)\n" ); return true; } bool TestCodeRun::TestGetObjectVars() { MVCR("foo($child_obj);" "$unrelated_obj->foo($base_obj);" ); MVCR("foo($child_obj);" ); MVCR("foo($base_obj);" ); MVCR("foo($base_obj);" ); MVCR(" 'apple', 'b' => 'banana'));\n" " }\n" " public function unserialize($serialized) {\n" " $props = unserialize($serialized);\n" " $this->a = $props['a'];\n" " $this->b = $props['b'];\n" " }\n" "} $obj = unserialize(serialize(new A())); var_dump($obj->b);"); MVCR("name = 'foo'.$n;" " $this->num = 3*$n;" " }" "}" "class Big {" " public $groupAll = array();" " public $group1 = array();" " public $group2 = array();" " public $wacky;" " public $nothing;" " public $unrelated = array();" " function add() {" " $s = new Small();" " $this->groupAll[] = $s;" " if ($s->num % 2 == 0) {" " $this->group1[]=array($s->name, $s);" " } else {" " $this->group2[]=array($s->name, $s);" " }" " }" " function finish() {" " $x = 10;" " $this->wacky = array(&$x, &$x);" " $s = new Small();" " $this->unrelated[] = $s;" " $this->unrelated[] = $s;" " $this->unrelated[] = $s;" " }" "}" "function t() {" " $b = new Big;" " for ($i = 0; $i < 10; ++$i) {" " $b->add();" " }" " $b->finish();" " var_dump($b);" " $s = serialize($b);" " var_dump($s);" " $us = unserialize($s);" " var_dump($us);" "}" "t();" ); MVCR("foo = 100;" "var_dump((array)$x);" "var_dump(serialize($x));" "var_dump($x);"); // Zend PHP 5.2 has a bug here, fixed in 5.3. MVCR("\n" " string(3) \"foo\"\n" "}\n" "bool(false)\n" "bool(false)\n"); MVCR("prot,$x->priv);"); MVCR("priv = $a;" " $this->prot = $b;" " $this->pub = $c;" " }" " function foo() { var_dump($this->priv, $this->prot, $this->pub); }" "}" "$x = new X(1,2,3);" "$s = serialize($x);" "$x = unserialize($s);" "var_dump($x);" "$x->foo();"); MVCR("foo = &$q;" "for ($i = 0; $i < 10; $i++) $a->{'x'.$i} = clone $a;" "$a->bar = &$q;" "$s = serialize($a);" "var_dump($s);" "$A = unserialize($s);" "var_dump($A);" "$r = &$A->bar;" "var_dump(array_keys($r));"); MVCR("str = 'hello';" " $this->arr = array(1,2,3);" " $this->obj = $this;" " }" "}" "function test() {" " $x = new X;" " $s = serialize($x);" " $x = unserialize($s);" " var_dump($x);" "}" "test();"); return true; } bool TestCodeRun::TestJson() { MVCR("aaaa();"); // recursive object MVCR("foo = $foo;\n" "var_dump(json_encode($foo));\n"); #if 0 MVCR("1, \"2\"=>2);" "$a[] = $a;" "var_dump($a);" "var_dump(json_encode($a));" "" "$a = array(\"1\"=>\"1\", \"2\"=>\"2\");" "$a[] = $a;" "var_dump($a);" "var_dump(json_encode($a));" "" "$a = array(\"1\"=>1, 2=>\"2\");" "$a[] = $a;" "var_dump($a);" "var_dump(json_encode($a));" "" "$a = array(1);" "$a[] = &$a;" "var_dump($a);" "var_dump(json_encode($a));" "" "$a = array(\"1\");" "$a[] = &$a;" "var_dump($a);" "var_dump(json_encode($a));" "" "$a = array(1, \"2\");" "$a[] = &$a;" "var_dump($a);" "var_dump(json_encode($a));" "" "$a = array(\"1\"=>1, \"2\"=>2);" "$a[] = &$a;" "var_dump($a);" "var_dump(json_encode($a));" "" "$a = array(\"1\"=>\"1\", \"2\"=>\"2\");" "$a[] = &$a;" "var_dump($a);" "var_dump(json_encode($a));" "" "$a = array(\"1\"=>1, 2=>\"2\");" "$a[] = &$a;" "var_dump($a);" "var_dump(json_encode($a));" "" "$a = array(1);" "$a[] = $a;" "var_dump(&$a);" "var_dump(json_encode($a));" "" "$a = array(\"1\");" "$a[] = $a;" "var_dump(&$a);" "var_dump(json_encode($a));" "" "$a = array(1, \"2\");" "$a[] = $a;" "var_dump(&$a);" "var_dump(json_encode($a));" "" "$a = array(\"1\"=>1, \"2\"=>2);" "$a[] = $a;" "var_dump(&$a);" "var_dump(json_encode($a));" "" "$a = array(\"1\"=>\"1\", \"2\"=>\"2\");" "$a[] = $a;" "var_dump(&$a);" "var_dump(json_encode($a));" "" "$a = array(\"1\"=>1, 2=>\"2\");" "$a[] = $a;" "var_dump(&$a);" "var_dump(json_encode($a));" "" "$a = array(1);" "$a[] = &$a;" "var_dump(&$a);" "var_dump(json_encode($a));" "" "$a = array(\"1\");" "$a[] = &$a;" "var_dump(&$a);" "var_dump(json_encode($a));" "" "$a = array(1, \"2\");" "$a[] = &$a;" "var_dump(&$a);" "var_dump(json_encode($a));" "" "$a = array(\"1\"=>1, \"2\"=>2);" "$a[] = &$a;" "var_dump(&$a);" "var_dump(json_encode($a));" "" "$a = array(\"1\"=>\"1\", \"2\"=>\"2\");" "$a[] = &$a;" "var_dump(&$a);" "var_dump(json_encode($a));" "" "$a = array(\"1\"=>1, 2=>\"2\");" "$a[] = &$a;" "var_dump(&$a);" "var_dump(json_encode($a));" "" "$a = array(1);" "$a[] = $a;" "var_dump($a);" "var_dump(json_encode(&$a));" "" "$a = array(\"1\");" "$a[] = $a;" "var_dump($a);" "var_dump(json_encode(&$a));" "" "$a = array(1, \"2\");" "$a[] = $a;" "var_dump($a);" "var_dump(json_encode(&$a));" "" "$a = array(\"1\"=>1, \"2\"=>2);" "$a[] = $a;" "var_dump($a);" "var_dump(json_encode(&$a));" "" "$a = array(\"1\"=>\"1\", \"2\"=>\"2\");" "$a[] = $a;" "var_dump($a);" "var_dump(json_encode(&$a));" "" "$a = array(\"1\"=>1, 2=>\"2\");" "$a[] = $a;" "var_dump($a);" "var_dump(json_encode(&$a));" "" "$a = array(1);" "$a[] = &$a;" "var_dump($a);" "var_dump(json_encode(&$a));" "" "$a = array(\"1\");" "$a[] = &$a;" "var_dump($a);" "var_dump(json_encode(&$a));" "" "$a = array(1, \"2\");" "$a[] = &$a;" "var_dump($a);" "var_dump(json_encode(&$a));" "" "$a = array(\"1\"=>1, \"2\"=>2);" "$a[] = &$a;" "var_dump($a);" "var_dump(json_encode(&$a));" "" "$a = array(\"1\"=>\"1\", \"2\"=>\"2\");" "$a[] = &$a;" "var_dump($a);" "var_dump(json_encode(&$a));" "" "$a = array(\"1\"=>1, 2=>\"2\");" "$a[] = &$a;" "var_dump($a);" "var_dump(json_encode(&$a));" "" "$a = array(1);" "$a[] = $a;" "var_dump(&$a);" "var_dump(json_encode(&$a));" "" "$a = array(\"1\");" "$a[] = $a;" "var_dump(&$a);" "var_dump(json_encode(&$a));" "" "$a = array(1, \"2\");" "$a[] = $a;" "var_dump(&$a);" "var_dump(json_encode(&$a));" "" "$a = array(\"1\"=>1, \"2\"=>2);" "$a[] = $a;" "var_dump(&$a);" "var_dump(json_encode(&$a));" "" "$a = array(\"1\"=>\"1\", \"2\"=>\"2\");" "$a[] = $a;" "var_dump(&$a);" "var_dump(json_encode(&$a));" "" "$a = array(\"1\"=>1, 2=>\"2\");" "$a[] = $a;" "var_dump(&$a);" "var_dump(json_encode(&$a));" "" "$a = array(1);" "$a[] = &$a;" "var_dump(&$a);" "var_dump(json_encode(&$a));" "" "$a = array(\"1\");" "$a[] = &$a;" "var_dump(&$a);" "var_dump(json_encode(&$a));" "" "$a = array(1, \"2\");" "$a[] = &$a;" "var_dump(&$a);" "var_dump(json_encode(&$a));" "" "$a = array(\"1\"=>1, \"2\"=>2);" "$a[] = &$a;" "var_dump(&$a);" "var_dump(json_encode(&$a));" "" "$a = array(\"1\"=>\"1\", \"2\"=>\"2\");" "$a[] = &$a;" "var_dump(&$a);" "var_dump(json_encode(&$a));" "" "$a = array(\"1\"=>1, 2=>\"2\");" "$a[] = &$a;" "var_dump(&$a);" "var_dump(json_encode(&$a));"); #endif return true; } bool TestCodeRun::TestThrift() { MVCRO("t = new DummyTransport();" " }" " function getTransport() {" " return $this->t;" " }" "}" "class DummyTransport {" " public $buff = '';" " public $pos = 0;" " function flush() { }" " function write($buff) {" " $this->buff .= $buff;" " }" " function read($n) {" " $r = substr($this->buff, $this->pos, $n);" " $this->pos += $n;" " return $r;" " }" "}" "class TestStruct {" " static $_TSPEC;" "" " public $aBool = null;" " public $anInt = null;" " public $aString = null;" " public $aDouble = null;" " public $anInt64 = null;" " public $aList = null;" " public $aMap = null;" " public $aSet = null;" " public $anByte = null;" " public $anI16 = null;" "" " public function __construct($vals=null) {" " if (!isset(self::$_TSPEC)) {" " self::$_TSPEC = array(" " -1 => array(" " 'var' => 'aBool'," " 'type' => TType::BOOL," " )," " 1 => array(" " 'var' => 'anInt'," " 'type' => TType::I32," " )," " 2 => array(" " 'var' => 'aString'," " 'type' => TType::STRING," " )," " 3 => array(" " 'var' => 'aDouble'," " 'type' => TType::DOUBLE," " )," " 4 => array(" " 'var' => 'anInt64'," " 'type' => TType::I64," " )," " 5 => array(" " 'var' => 'aList'," " 'type' => TType::LST," " 'etype' => TType::DOUBLE," " 'elem' => array(" " 'type' => TType::DOUBLE," " )," " )," " 6 => array(" " 'var' => 'aMap'," " 'type' => TType::MAP," " 'ktype' => TType::I32," " 'vtype' => TType::DOUBLE," " 'key' => array(" " 'type' => TType::I32," " )," " 'val' => array(" " 'type' => TType::DOUBLE," " )," " )," " 7 => array(" " 'var' => 'aSet'," " 'type' => TType::SET," " 'etype' => TType::I32," " 'elem' => array(" " 'type' => TType::I32," " )," " )," " 8 => array(" " 'var' => 'anByte'," " 'type' => TType::BYTE," " )," " 9 => array(" " 'var' => 'anI16'," " 'type' => TType::I16," " )," " );" " }" " }" "}" "" "function test() {" " $p = new DummyProtocol();" " $v1 = new TestStruct();" " $v1->aBool = true;" " $v1->anInt = 1234;" " $v1->aString = 'abcdef';" " $v1->aDouble = 1.2345;" " $v1->anInt64 = 8589934592;" " $v1->aList = array(13.3, 23.4, 3576.2);" " $v1->aMap = array(10=>1.2, 43=>5.33);" " $v1->aSet = array(10=>true, 11=>true);" " $v1->anByte = 123;" " $v1->anI16 = 1234;" " var_dump($v1);" " thrift_protocol_write_binary($p, 'foomethod', 1, $v1, 20, true);" " var_dump(md5($p->getTransport()->buff));" " var_dump(thrift_protocol_read_binary($p, 'TestStruct', true));" "}" "test();" , "object(TestStruct)#3 (10) {\n" " [\"aBool\"]=>\n" " bool(true)\n" " [\"anInt\"]=>\n" " int(1234)\n" " [\"aString\"]=>\n" " string(6) \"abcdef\"\n" " [\"aDouble\"]=>\n" " float(1.2345)\n" " [\"anInt64\"]=>\n" " int(8589934592)\n" " [\"aList\"]=>\n" " array(3) {\n" " [0]=>\n" " float(13.3)\n" " [1]=>\n" " float(23.4)\n" " [2]=>\n" " float(3576.2)\n" " }\n" " [\"aMap\"]=>\n" " array(2) {\n" " [10]=>\n" " float(1.2)\n" " [43]=>\n" " float(5.33)\n" " }\n" " [\"aSet\"]=>\n" " array(2) {\n" " [10]=>\n" " bool(true)\n" " [11]=>\n" " bool(true)\n" " }\n" " [\"anByte\"]=>\n" " int(123)\n" " [\"anI16\"]=>\n" " int(1234)\n" "}\n" "string(32) \"6b4fbe9563551f3dee970a74b883f923\"\n" "object(TestStruct)#4 (10) {\n" " [\"aBool\"]=>\n" " bool(true)\n" " [\"anInt\"]=>\n" " int(1234)\n" " [\"aString\"]=>\n" " string(6) \"abcdef\"\n" " [\"aDouble\"]=>\n" " float(1.2345)\n" " [\"anInt64\"]=>\n" " int(8589934592)\n" " [\"aList\"]=>\n" " array(3) {\n" " [0]=>\n" " float(13.3)\n" " [1]=>\n" " float(23.4)\n" " [2]=>\n" " float(3576.2)\n" " }\n" " [\"aMap\"]=>\n" " array(2) {\n" " [10]=>\n" " float(1.2)\n" " [43]=>\n" " float(5.33)\n" " }\n" " [\"aSet\"]=>\n" " array(2) {\n" " [10]=>\n" " bool(true)\n" " [11]=>\n" " bool(true)\n" " }\n" " [\"anByte\"]=>\n" " int(123)\n" " [\"anI16\"]=>\n" " int(1234)\n" "}\n"); MVCRO( "t = new DummyTransport();" " }" " function getTransport() {" " return $this->t;" " }" "}" "class DummyTransport {" " public $buff = '';" " public $pos = 0;" " function flush() { }" " function write($buff) {" " $this->buff .= $buff;" " }" " function read($n) {" " $r = substr($this->buff, $this->pos, $n);" " $this->pos += $n;" " return $r;" " }" "}" "class TestStruct {" " static $_TSPEC;" "" " public $aBool = null;" " public $anInt = null;" " public $aDouble = null;" " public $anInt64 = null;" " public $anByte = null;" " public $anI16 = null;" "" " public function __construct($vals=null) {" " if (!isset(self::$_TSPEC)) {" " self::$_TSPEC = array(" " -1 => array(" " 'var' => 'aBool'," " 'type' => TType::BOOL," " )," " 1 => array(" " 'var' => 'anInt'," " 'type' => TType::I32," " )," " 2 => array(" " 'var' => 'aDouble'," " 'type' => TType::DOUBLE," " )," " 3 => array(" " 'var' => 'anInt64'," " 'type' => TType::I64," " )," " 4 => array(" " 'var' => 'anByte'," " 'type' => TType::BYTE," " )," " 5 => array(" " 'var' => 'anI16'," " 'type' => TType::I16," " )," " );" " }" " }" "}" "" "function test() {" " $p = new DummyProtocol();" " $v1 = new TestStruct();" " $v1->aBool = false;" " $v1->anInt = -1234;" " $v1->aDouble = -1.2345;" " $v1->anInt64 = -1;" " $v1->anByte = -12;" " $v1->anI16 = -123;" " thrift_protocol_write_binary($p, 'foomethod', 1, $v1, 20, true);" " var_dump(thrift_protocol_read_binary($p, 'TestStruct', true));" "}" "test();", "object(TestStruct)#4 (6) {\n" " [\"aBool\"]=>\n" " bool(false)\n" " [\"anInt\"]=>\n" " int(-1234)\n" " [\"aDouble\"]=>\n" " float(-1.2345)\n" " [\"anInt64\"]=>\n" " int(-1)\n" " [\"anByte\"]=>\n" " int(-12)\n" " [\"anI16\"]=>\n" " int(-123)\n" "}\n"); MVCRO( "t = new DummyTransport();" " }" " function getTransport() {" " return $this->t;" " }" "} " "class DummyTransport {" " public $buff = '';" " public $pos = 0;" " function flush() { }" " function write($buff) {" " $this->buff .= $buff;" " } " " function read($n) {" " $r = substr($this->buff, $this->pos, $n);" " $this->pos += $n;" " return $r;" " } " "} " "class TestStruct {" " static $_TSPEC;" " " " public $aBool = null;" " public $anInt = null;" " public $aString = null;" " public $aDouble = null;" " public $anInt64 = null;" " public $aList = null;" " public $aMap = null;" " public $aSet = null;" " public $anByte = null;" " public $anI16 = null;" " " " public function __construct($vals=null) {" " if (!isset(self::$_TSPEC)) {" " self::$_TSPEC = array(" " -1 => array(" " 'var' => 'aBool'," " 'type' => TType::BOOL," " )," " 1 => array(" " 'var' => 'anInt'," " 'type' => TType::I32," " )," " 2 => array(" " 'var' => 'aString'," " 'type' => TType::STRING," " )," " 3 => array(" " 'var' => 'aDouble'," " 'type' => TType::DOUBLE," " )," " 4 => array(" " 'var' => 'anInt64'," " 'type' => TType::I64," " )," " 5 => array(" " 'var' => 'aList'," " 'type' => TType::LST," " 'etype' => TType::DOUBLE," " 'elem' => array(" " 'type' => TType::DOUBLE," " )," " )," " 6 => array(" " 'var' => 'aMap'," " 'type' => TType::MAP," " 'ktype' => TType::I32," " 'vtype' => TType::DOUBLE," " 'key' => array(" " 'type' => TType::I32," " )," " 'val' => array(" " 'type' => TType::DOUBLE," " )," " )," " 7 => array(" " 'var' => 'aSet'," " 'type' => TType::SET," " 'etype' => TType::I32," " 'elem' => array(" " 'type' => TType::I32," " )," " )," " 8 => array(" " 'var' => 'anByte'," " 'type' => TType::BYTE," " )," " 9 => array(" " 'var' => 'anI16'," " 'type' => TType::I16," " )," " );" " }" " }" "}" "" "function test() {" " $p = new DummyProtocol();" " $v1 = new TestStruct();" " $v1->aBool = true;" " $v1->anInt = 1234;" " $v1->aString = 'abcdef';" " $v1->aDouble = 1.2345;" " $v1->anInt64 = 8589934592;" " $v1->aList = array(13.3, 23.4, 3576.2);" " $v1->aMap = array(10=>1.2, 43=>5.33);" " $v1->aSet = array(10=>true, 11=>true);" " $v1->anByte = 123;" " $v1->anI16 = 1234;" " thrift_protocol_write_compact($p, 'foomethod', 1, $v1, 20);" " var_dump(md5($p->getTransport()->buff));" "}" "test();", "string(32) \"cd0654ca200fe910204988f44f996a11\"\n"); MVCRO( "t = new DummyTransport();" " }" " function getTransport() {" " return $this->t;" " }" "} " "class DummyTransport {" " public $buff = '';" " public $pos = 0;" " function flush() { }" " function write($buff) {" " $this->buff .= $buff;" " } " " function read($n) {" " $r = substr($this->buff, $this->pos, $n);" " $this->pos += $n;" " return $r;" " } " " function putBack($data) {" " $this->buff = ($data . $this->buff);" " } " "} " "class TestStruct {" " static $_TSPEC;" " " " public $aBool = null;" " public $anInt = null;" " public $aString = null;" " public $aDouble = null;" " public $anInt64 = null;" " public $aList = null;" " public $aMap = null;" " public $aSet = null;" " public $anByte = null;" " public $anI16 = null;" " " " public function __construct($vals=null) {" " if (!isset(self::$_TSPEC)) {" " self::$_TSPEC = array(" " -1 => array(" " 'var' => 'aBool'," " 'type' => TType::BOOL," " )," " 1 => array(" " 'var' => 'anInt'," " 'type' => TType::I32," " )," " 2 => array(" " 'var' => 'aString'," " 'type' => TType::STRING," " )," " 3 => array(" " 'var' => 'aDouble'," " 'type' => TType::DOUBLE," " )," " 4 => array(" " 'var' => 'anInt64'," " 'type' => TType::I64," " )," " 5 => array(" " 'var' => 'aList'," " 'type' => TType::LST," " 'etype' => TType::DOUBLE," " 'elem' => array(" " 'type' => TType::DOUBLE," " )," " )," " 6 => array(" " 'var' => 'aMap'," " 'type' => TType::MAP," " 'ktype' => TType::I32," " 'vtype' => TType::DOUBLE," " 'key' => array(" " 'type' => TType::I32," " )," " 'val' => array(" " 'type' => TType::DOUBLE," " )," " )," " 7 => array(" " 'var' => 'aSet'," " 'type' => TType::SET," " 'etype' => TType::I32," " 'elem' => array(" " 'type' => TType::I32," " )," " )," " 8 => array(" " 'var' => 'anByte'," " 'type' => TType::BYTE," " )," " 9 => array(" " 'var' => 'anI16'," " 'type' => TType::I16," " )," " );" " }" " }" "}" "" "function test() {" " $p = new DummyProtocol();" " $v1 = new TestStruct();" " $v1->aBool = true;" " $v1->anInt = 1234;" " $v1->aString = 'abcdef';" " $v1->aDouble = 1.2345;" " $v1->anInt64 = 8589934592;" " $v1->aList = array(13.3, 23.4, 3576.2);" " $v1->aMap = array(10=>1.2, 43=>5.33);" " $v1->aSet = array(10=>true, 11=>true);" " $v1->anByte = 123;" " $v1->anI16 = 1234;" " thrift_protocol_write_compact($p, 'foomethod', 1, $v1, 20);" // HACK: rewrite the version and call type from "version X, call" to // "version 2, response" to appease deserializer " $p->getTransport()->buff[1] = pack('C', 0x42);" " var_dump(thrift_protocol_read_compact($p, 'TestStruct'));" "}" "test();", "object(TestStruct)#4 (10) {\n" " [\"aBool\"]=>\n" " bool(true)\n" " [\"anInt\"]=>\n" " int(1234)\n" " [\"aString\"]=>\n" " string(6) \"abcdef\"\n" " [\"aDouble\"]=>\n" " float(1.2345)\n" " [\"anInt64\"]=>\n" " int(8589934592)\n" " [\"aList\"]=>\n" " array(3) {\n" " [0]=>\n" " float(13.3)\n" " [1]=>\n" " float(23.4)\n" " [2]=>\n" " float(3576.2)\n" " }\n" " [\"aMap\"]=>\n" " array(2) {\n" " [10]=>\n" " float(1.2)\n" " [43]=>\n" " float(5.33)\n" " }\n" " [\"aSet\"]=>\n" " array(2) {\n" " [10]=>\n" " bool(true)\n" " [11]=>\n" " bool(true)\n" " }\n" " [\"anByte\"]=>\n" " int(123)\n" " [\"anI16\"]=>\n" " int(1234)\n" "}\n"); return true; } bool TestCodeRun::TestExit() { MVCR(" 1000;')));"); MVCR(" 1000;')));"); return true; } bool TestCodeRun::TestConstructorDestructor() { MVCR("';" "$payload['pane_html'] .= '
';"); MVCR("'." " n_indent()." " $arg2 ." " n_unindent()." " '
';" "}" "$GLOBALS['n_indent_level'] = 0;" "var_dump(render(\"foo\", \"bar\"));"); MVCR(" 0) {" " $sql = 'foo';" " } else {" " $sql = 'bar';" " }" " $sql .= ' baz';" " return $sql;" "}" "echo test(1),test(-1),\"\\n\";"); MVCR("_p[ $what ];" " }" " public function __set( $what, $value ) {" " echo \"set C\\n\";" " $this->_p[ $what ] = $value;" " }" " private $_p = array();" "}" "function bar() {" " print \" hello \" . foo() . \"\\n\";" " $a = new A;" " $a[0] = 0;" " $a[1] = 1;" " echo \" hello $a[0]\";" " echo \" hello $a[1]\\n\";" " print \" hello $a[0]\";" " print \" hello $a[1]\\n\";" " $b = new C;" " $b->a = 'aaaa';" " $b->b = 'bbbb';" " echo \" hello $b->a\";" " echo \" hello $b->b\\n\";" " print \" hello $b->a\";" " print \" hello $b->b\\n\";" " echo \" hello $b->a $b->b $b->a $b->b\";" "}" "bar();"); MVCR("Test\", ENT_QUOTES);" "echo htmlspecialchars_decode(\"\\0abc\");" "echo htmlspecialchars_decode(\"abc\\0def\");" "echo htmlentities(\"Test\", ENT_QUOTES);" "echo dirname(\"Test\");" "echo basename(\"Test\");" "echo version_compare(\"5.1.2\", \"5.1.3\");" "echo dechex(10);" "echo hexdec(\"See\");" "echo decbin(12);" "echo decbin('000110011');" "echo decoct(264);" "echo octdec('77');" "echo octdec(decoct(45));" "echo str_repeat(\"-=\", 10);" "echo intval(42);" "echo intval(4.2);" "echo intval('42');" "echo intval('+42');" "echo intval('-42');" "echo intval(042);" "echo intval('042');" "echo intval(1e10);" "echo intval('1e10');" "echo intval(0x1A);" "echo intval(42000000);" "echo intval(42, 8);" "echo intval('42', 8);" "echo substr(\"abcdef\", -1);" "echo substr(\"abcdef\", -2);" "echo substr(\"abcdef\", -3, 1);" "echo substr(\"abcdef\", 0, -1);" "echo substr(\"abcdef\", 2, -1);" "echo substr(\"abcdef\", 4, -4);" "echo substr(\"abcdef\", -3, -1);" "echo substr(\"abcdef\", 1);" "echo substr(\"abcdef\", 1, 3);" "echo substr(\"abcdef\", 0, 4);" "echo substr(\"abcdef\", 0, 8);" "echo substr(\"abcdef\", -1, 1);" "echo trim(\"\\t\\t\\0These are a few words :) ... \");" "echo trim(\"\\t\\t\\0These are a few words :) ... \", \" \\t.\");" "echo trim(\"\\x09Example string\\x0A\", \"\\x00..\\x1F\");" "echo ltrim(\"\\t\\t\\0These are a few words :) ... \");" "echo ltrim(\"\\t\\t\\0These are a few words :) ... \", \" \\t.\");" "echo ltrim(\"\\x09Example string\\x0A\", \"\\x00..\\x1F\");" "echo rtrim(\"\\t\\t\\0These are a few words :) ... \");" "echo rtrim(\"\\t\\t\\0These are a few words :) ... \", \" \\t.\");" "echo rtrim(\"\\x09Example string\\x0A\", \"\\x00..\\x1F\");" "echo chop(\"\\t\\t\\0These are a few words :) ... \");" "echo chop(\"\\t\\t\\0These are a few words :) ... \", \" \\t.\");" "echo chop(\"\\x09Example string\\x0A\", \"\\x00..\\x1F\");" "echo acos(0.5);" "echo acosh(0.5);" "echo asin(0.5);" "echo asinh(0.5);" "echo atan(0.5);" "echo atan2(0.5, 0.5);" "echo atanh(0.5);" "echo cos(0.5);" "echo cosh(0.5);" "echo sin(0.5);" "echo sinh(0.5);" "echo tan(0.5);" "echo tanh(0.5);" "echo exp(5.7);" "echo exp(12);" "echo log10(12);" "echo log(12);" "echo sqrt(2);" "echo ceil(7.9);" "echo floor(7.9);" "echo fmod(5.7, 1.3);" "echo ip2long(\"127.0.0.1\");" /* 5.2 accepts these, 5.3 does not. php.net says it should "echo ip2long(\"10.0.0\");" "echo ip2long(\"10.0.256\");" */ "echo long2ip(pow(2,32) + 1024);" "echo rad2deg(M_PI_4);" "echo deg2rad(45);"); MVCR("x();"); MVCR(" 'foo');" "}" "" "interface A {" " const CONSTANT = 'CONSTANT';" "}" "" "class B implements A { }" "" "class C {" " static $A_CONSTANT = A::CONSTANT;" " static $B_CONSTANT = B::CONSTANT;" "}" "" "var_dump(A::CONSTANT);" "var_dump(B::CONSTANT);" "var_dump(C::$A_CONSTANT);" "var_dump(C::$B_CONSTANT);"); MVCR(" array(" " ATB::PARAM_A => true," " ATB::PARAM_C => array(" " array('tcks', 'none')," " array('tcks', 'ids')," " )," " ATB::PARAM_B =>" " 'aaaa'," " )," " 'user_id' => array(" " ATB::PARAM_A => true," " ATB::PARAM_C => array(" " array('tcks', 'none')," " array('tcks', 'id')," " )," " ATB::PARAM_B =>" " 'bbbb'," " )," " );" " }" "}" "var_dump(ABCD::foo());"); MVCR("\n" " string(1) \"b\"\n" "}\n"); MVCRO("\n" " string(3) \"new\"\n" "}\n"); MVCRO("\n" " string(3) \"xxx\"\n" "}\n"); MVCR("getParameters() as $p) {" " var_dump($p->getDefaultValue());" " }" "}" "function fiz($c) {" " var_dump($c::FOO);" "}" "fiz('I');" "fiz('C');" "test();"); MVCR("foo();" "$rc = new ReflectionClass('Test');" "$method = $rc->getMethod('foo');" "foreach ($method->getParameters() as $param) {" " var_dump($param->getDefaultValue());" "}"); return true; } bool TestCodeRun::TestConstantFunction() { MVCR("_getJSFunction('_encode10');" " var_dump($encode10);" " $encode36 = $this->_getJSFunction('_encode36');" " var_dump($encode36);" " }" " private function _getJSFunction($aName) {" " if (defined('self::JSFUNCTION'.$aName))" " return constant('self::JSFUNCTION'.$aName);" " else" " return '';" " }" " const JSFUNCTION_encode10 =" " 'function($charCode) {" " return $charCode;" "}';" "" "}" "$obj = new JavaScriptPacker;" "$obj->foo(); "); MVCR("f();" "$obj = new Bar;" "$obj->f();"); MVCR("val = 1); }" " function goo() { f($val = 'val'); f($this->$val = 2); }" " function zoo() {" " var_dump($val); var_dump($this->val);" " }" "}" "function foo() {" " f($val2 = 1);" "}" "$obj = new ClassA();" "var_dump($obj);" "$obj->foo();" "var_dump($obj);" "$obj->bar();" "var_dump($obj);" "$obj->goo();" "var_dump($obj);" "$obj->zoo();"); MVCR("$val = 2); }" " function foo2() { f($this->val = 3); }" " function bar() {" " var_dump($val); var_dump($this->val);" " }" "}" "$obj = new ClassA();" "var_dump($obj);" "$obj->foo();" "var_dump($obj);" "$obj->bar();" "$obj->foo2();" "var_dump($obj);" "$obj->bar();"); MVCR("kid->check();\n" " $this->kid->clear_unset();\n" " }\n" "}\n" "\n" "class node {\n" " public $dom;\n" "\n" " public function __construct($dom) {\n" " $this->dom = $dom;\n" " $dom->kid = $this;\n" " }\n" " public function __destruct() {\n" " echo \"node destructing\n\";\n" " }\n" " public function clear_unset() {\n" " unset($this->dom);\n" " }\n" " public function clear_set() {\n" " $this->dom = null;\n" " }\n" " public function check() {\n" " var_dump(isset($this->dom));\n" " }\n" "}\n" "\n" "class node_arr {\n" " public $doms = array();\n" "\n" " public function __construct($dom) {\n" " $this->doms[0] = $dom;\n" " $dom->kid = $this;\n" " }\n" " public function __destruct() {\n" " echo \"node destructing\n\";\n" " }\n" " public function clear_unset() {\n" " unset($this->doms[0]);\n" " }\n" " public function clear_set() {\n" " $this->doms[0] = null;\n" " }\n" " public function check() {\n" " var_dump(isset($this->doms[0]));\n" " }\n" "}\n" "\n" "echo \"\nProperty, SetM\n\";\n" "$node = new node(new dom);\n" "$node->clear_set();\n" "unset($node);\n" "\n" "echo \"\nProperty, UnsetM\n\";\n" "$node = new node(new dom);\n" "$node->clear_unset();\n" "unset($node);\n" "\n" "echo \"\nArray, SetM\n\";\n" "$node = new node_arr(new dom);\n" "$node->clear_set();\n" "unset($node);\n" "\n" "echo \"\nArray, UnsetM\n\";\n" "$node = new node_arr(new dom);\n" "$node->clear_unset();\n" "unset($node);\n"); return true; } bool TestCodeRun::TestSimpleXML() { MVCR("addChild($node->getName(), (string)$node);\n" " foreach ($node->attributes() as $name => $value) {\n" " $newchild->addAttribute($name, $value);\n" " }\n" " foreach ($node->children() as $child) {\n" " addChildNode($newchild, $child);\n" " }\n" "}\n" "\n" "$xmlreq = '1st" "2nd';\n" "$quote = simplexml_load_string($xmlreq);\n" "$req = new SimpleXMLElement('');\n" "foreach ($quote->attributes() as $name => $value) {\n" " $req->addAttribute($name, $value);\n" "}\n" "foreach ($quote->children() as $child) {\n" " addChildNode($req, $child);\n" "}\n" "\n" "$vertex = new SimpleXMLElement('');\n" "addChildNode($vertex, $req);\n" "var_dump($vertex->asXML());\n" ); MVCR("345.234');" "var_dump((double)$x->bar);"); MVCR("');" "var_dump((bool)$x->bar);"); MVCR("0');" "var_dump((bool)$x->bar);"); MVCR("'); " "$x->addAttribute('attr', 'one'); " "$x['attr'] = 'two'; " "var_dump((string)$x['attr']); " "var_dump($x->asXML());"); MVCR("whoops');\n" "var_dump((array)$node->bar);"); MVCR("" "whoops');\n" "var_dump((array)$node->bar);"); MVCR("whoops');\n" "var_dump((string)$node[0]);"); MVCR("whoops');" "var_dump((string)$node);"); MVCR("whoops');" "var_dump((string)$node);"); MVCR("whoops');" "var_dump((string)$node);"); MVCR("');\n" "$sxe->addChild('path', 'some/path/to/my.file');\n" "$sxe->addChild('options');\n" "$sxe->options->addChild('paddingbottom', 1);\n" "var_dump((string)$sxe->path);\n" "var_dump((string)$sxe->options->paddingbottom);\n" ); MVCR("');\n" "$x->addChild('bar', 'whoops');\n" "var_dump((string)$x);\n"); MVCR( " $v) {\n" " if ($sxml['list']) {\n" " if (isset($v['key'])) {\n" " $arr[(string)$v['key']] = convert_simplexml_to_array($v);\n" " } else {\n" " $arr[] = convert_simplexml_to_array($v);\n" " }\n" " } else {\n" " $arr[$k] = convert_simplexml_to_array($v);\n" " }\n" " }\n" " }\n" " if (sizeof($arr) > 0) {\n" " return $arr;\n" " } else {\n" " return (string)$sxml;\n" " }\n" "}\n" "\n" "$xml = <<\n" " \n" " \n" " value1-1\n" " value1-2\n" " \n" " value1\n" " \n" " \n" " value2\n" " \n" "\n" "EOM;\n" "\n" "$sxml = simplexml_load_string($xml);\n" "var_dump(convert_simplexml_to_array($sxml));\n" ); MVCR("test';\n" "$sxml = simplexml_load_string($xml);\n" "foreach ($sxml as $k => $v) {\n" " var_dump($k, (string)$v);\n" "}\n"); MVCR("678';\n" "$sxml = simplexml_load_string($xml);\n" "foreach ($sxml as $k => $v) {\n" " var_dump($k, (int)$v);\n" "}\n"); MVCR("678';\n" "$sxml = simplexml_load_string($xml);\n" "foreach ($sxml as $k => $v) {\n" " var_dump($k, (string)$v);\n" "}\n"); MVCR("" "';\n" "$dom = new SimpleXMLElement($xml);\n" "$invalidations = $dom->invalidations;\n" "var_dump((string)$invalidations->invalidation[\"id\"]);\n" "foreach ($invalidations as $node) {\n" " var_dump((string)$node->invalidation[\"id\"]);\n" "}\n"); MVCR("\n" "\n" " \n" " memcache\n" " \n" " \n" "\n" " \n" " memcache\n" " \n" " \n" "\n" "EOM;\n" "var_dump($file);\n" "\n" "$xml = simplexml_load_string($file);\n" "foreach ($xml->children() as $parent_name => $xml_ele) {\n" " var_dump($parent_name);\n" "\n" " foreach ($xml_ele->children() as $key => $value) {\n" " var_dump((string)$key, (string)$value);\n" " }\n" "}\n" ); MVCR("6';\n" "$sxml = simplexml_load_string($xml);\n" "function convert_simplexml_to_array($sxml) {\n" " if ($sxml) {\n" " foreach ($sxml as $k => $v) {\n" " var_dump($k, (string)$v);\n" " convert_simplexml_to_array($v);\n" " }\n" " }\n" "}\n" "convert_simplexml_to_array($sxml);"); MVCR("'); $doc->node->option = false; var_dump($doc->asXML());"); MVCR("'); $doc->node->option = 0; var_dump($doc->asXML());"); MVCR("'); unset($doc->node->option); var_dump($doc->asXML());"); MVCR("'); foreach ($doc->list[0]->entry as $r) { var_dump((array)$r->attributes());}"); MVCR("');" "$sxe->addChild('options');" "$sxe->options->addChild('paddingtop', 0);" "echo 'Success\n';"); MVCR("c1c2c3'); $foo_ns_bar = $doc->children('http://example.com');" "var_dump($doc->getName());" "foreach ($foo_ns_bar as $v) var_dump((string)$v);" "var_dump($foo_ns_bar->getName());" "var_dump(count($foo_ns_bar->b1));" "var_dump((string)$foo_ns_bar->b1);" "var_dump((string)$foo_ns_bar->b1[0]);" "foreach ($foo_ns_bar->b1 as $v) var_dump((string)$v);" "var_dump(count($foo_ns_bar->b2));" "var_dump((string)$foo_ns_bar->b2[0]);" "var_dump((string)$foo_ns_bar->b2[1]);" "foreach ($foo_ns_bar->b2 as $v) var_dump((string)$v);" ); MVCR(" 10) {" " var_dump('Recursed to deep, backing out');" " return;" " }" " print $indent.$el->getName().\"\\n\";" " foreach ($el->attributes() as $k => $v) {" " print $indent.$k.' => '.$v.\"\\n\";" " }" " foreach ($el->children() as $child) {" " printElement($child, $indent.' ');" " }" "}" "$a = simplexml_load_string('hihi');" "printElement($a);" ); MVCR("testtestv');" "var_dump((array)$a->attributes());" "var_dump((string)$a->subnode[0]);" "var_dump((string)$a->subnode[0]['attr1']);" "var_dump((string)$a->subnode[1]['subsubnode']);" "var_dump((string)$a->subnode[1]->subsubnode);" "var_dump((string)$a->test);" "var_dump((array)$a->subnode[0]->attributes());" "var_dump((array)$a->subnode[1]->attributes());" "var_dump($a->asxml());" "var_dump((string)$a->addchild('newnode', 'newvalue'));" "$a->addattribute('newattr', 'newattrvalue');" "var_dump($a->asxml());" "var_dump((array)$a->attributes());" "var_dump((string)$a->newnode);" "var_dump($a->getname());" "var_dump((array)$a->children()->subnode[0]->subsubnode);" "$nodes = $a->xpath('//node/subnode');" "var_dump((string)$nodes[1]->subsubnode);" "$nodes = $nodes[1]->xpath('subsubnode');" "var_dump((string)$nodes[0]);" ); MVCR("test');" "var_dump((array)($a->subnode->subsubnode));" "var_dump((string)($a->subnode->subsubnode));" ); MVCR("test');" "var_dump((array)($a->subnode->subsubnode));" "var_dump((string)($a->subnode->subsubnode));" ); MVCR("test');" "var_dump((string)($a->subnode->subsubnode['0']));" "var_dump((string)($a->subnode->subsubnode[0]));" ); MVCR("test');" "var_dump((string)($a->subnode['attr1']));" ); MVCR("test');" "var_dump((string)($a->subnode->subsubnode['attr1']));" ); MVCR("test');" "var_dump((string)($a->subnode->subsubnode->sssnode));" ); MVCR("';" "$xml = new SimpleXMLElement($post_xml);" "foreach ($xml->scannedItem as $item) {" " echo $item['itemName'] . \"\\n\";" "}"); MVCR("test');" "var_dump((string)($a->subnode->subsubnode[0]));" ); MVCR("678';\n" "$sxml = simplexml_load_string($xml);\n" "var_dump(count($sxml->t));\n" "var_dump((string)$sxml->t[0]);\n" "var_dump((string)$sxml->t[1]);\n" "var_dump((string)$sxml->t[2]);\n" "var_dump(count($sxml->t->bogus));\n" "var_dump(count($sxml->t->attributes()));\n" "foreach ($sxml->bogus as $v) {}"); return true; } bool TestCodeRun::TestXML() { MVCR( "parser = xml_parser_create();\n" " xml_set_object($this->parser, $this);\n" " xml_set_element_handler($this->parser, 'tag_open', 'tag_close');\n" " xml_set_character_data_handler($this->parser, 'cdata');\n" " }\n" " function parse($data) { xml_parse($this->parser, $data);}\n" " function tag_open($parser, $tag, $attributes) {\n" " var_dump($tag, $attributes);\n" " }\n" " function cdata($parser, $cdata) { var_dump($cdata);}\n" " function tag_close($parser, $tag){ var_dump($tag);}\n" "}\n" "\n" "$xml_parser = new xml();\n" "$xml_parser->parse('PHP');\n" ); MVCR("\", true);\n" "\n" " $p = xml_parser_create();\n" " xml_set_element_handler($p, 'parse_callback', 'parse_callback');\n" " xml_set_element_handler($p, 'parse_callback', '');\n" " xml_parse($p, \"\", true);\n" "}\n" "main();\n"); return true; } bool TestCodeRun::TestDOMDocument() { MVCR("';\n" "$dom = new domDocument;\n" "$dom->loadxml($xml);\n" "$xpath = new DOMXPath($dom);\n" "$node_list = $xpath->query('//dependencies/dependency[@dependency_id = 0 and @dependent_id = 1]');\n" "$dependencies = $xpath->query('//dependencies')->item(0);\n" "$dependencies->removeChild($node_list->item(0));\n" ); MVCR("';\n" "$dom = new domDocument;\n" "$dom->loadxml($xml);\n" "$xpath = new DOMXPath($dom);\n" "$node_list = $xpath->query('//dependencies/dependency[@dependent_id = 8]');\n" "foreach ($node_list as $node) {\n" " var_dump($node->getAttribute($attribute));\n" "}\n" ); MVCR("\n" "\n" "]>\n" "\n" "Title\n" "\n" "&sp;\n" "\n" "\n" "\n" "\n" "a1b1" "c1\n" "a2c2\n" "a3b3c3\n" "\n" "\n" "\n" "\n" " \";\n" "\n" "function print_node($node)\n" "{\n" " print \"Node Name: \" . $node->nodeName;\n" " print \"\nNode Type: \" . $node->nodeType;\n" " if ($node->nodeType != 3) {\n" " $child_count = $node->childNodes->length;\n" " } else {\n" " $child_count = 0;\n" " }\n" " print \"\nNum Children: \" . $child_count;\n" " if($child_count <= 1){\n" " print \"\nNode Content: \" . $node->nodeValue;\n" " }\n" " print \"\n\n\";\n" "}\n" "\n" "function print_node_list($nodelist)\n" "{\n" " foreach($nodelist as $node)\n" " {\n" " print_node($node);\n" " }\n" "}\n" "\n" "echo \"Test 1: accessing single nodes from php\n\";\n" "$dom = new domDocument;\n" "$dom->loadxml($xmlstr);\n" "if(!$dom) {\n" " echo \"Error while parsing the document\n\";\n" " exit;\n" "}\n" "\n" "// children() of of document would result in a memleak\n" "//$children = $dom->children();\n" "//print_node_list($children);\n" "\n" "echo \"--------- root\n\";\n" "$rootnode = $dom->documentElement;\n" "print_node($rootnode);\n" "\n" "echo \"--------- children of root\n\";\n" "$children = $rootnode->childNodes;\n" "print_node_list($children);\n" "\n" "// The last node should be identical with the last " "entry in the children array\n" "echo \"--------- last\n\";\n" "$last = $rootnode->lastChild;\n" "print_node($last);\n" "\n" "// The parent of this last node is the root again\n" "echo \"--------- parent\n\";\n" "$parent = $last->parentNode;\n" "print_node($parent);\n" "\n" "// The children of this parent are the same children as one above\n" "echo \"--------- children of parent\n\";\n" "$children = $parent->childNodes;\n" "print_node_list($children);\n" "\n" "echo \"--------- creating a new attribute\n\";\n" "//This is worthless\n" "//$attr = $dom->createAttribute(\"src\", \"picture.gif\");\n" "//print_r($attr);\n" "\n" "//$rootnode->set_attributeNode($attr);\n" "$attr = $rootnode->setAttribute(\"src\", \"picture.gif\");\n" "$attr = $rootnode->getAttribute(\"src\");\n" "print_r($attr);\n" "print \"\n\";\n" "\n" "echo \"--------- Get Attribute Node\n\";\n" "$attr = $rootnode->getAttributeNode(\"src\");\n" "print_node($attr);\n" "\n" "echo \"--------- Remove Attribute Node\n\";\n" "$attr = $rootnode->removeAttribute(\"src\");\n" "print \"Removed \" . $attr . \" attributes.\n\";\n" "\n" "echo \"--------- attributes of rootnode\n\";\n" "$attrs = $rootnode->attributes;\n" "print_node_list($attrs);\n" "\n" "echo \"--------- children of an attribute\n\";\n" "$children = $attrs->item(0)->childNodes;\n" "print_node_list($children);\n" "\n" "echo \"--------- Add child to root\n\";\n" "$myelement = new domElement(\"Silly\", \"Symphony\");\n" "$newchild = $rootnode->appendChild($myelement);\n" "print_node($newchild);\n" "print $dom->saveXML();\n" "print \"\n\";\n" "\n" "echo \"--------- Find element by tagname\n\";\n" "echo \" Using dom\n\";\n" "$children = $dom->getElementsByTagname(\"Silly\");\n" "print_node_list($children);\n" "\n" "echo \" Using elem\n\";\n" "$children = $rootnode->getElementsByTagName(\"Silly\");\n" "print_node_list($children);\n" "\n" "echo \"--------- Unlink Node\n\";\n" "print_node($children->item(0));\n" "$rootnode->removeChild($children->item(0));\n" "print_node_list($rootnode->childNodes);\n" "print $dom->savexml();\n" ); // dom002.phpt MVCR("\n" "\n" " \n" " \n" " \n" " \n" "\n" "HERE;\n" "\n" "function dump($elems) {\n" " foreach ($elems as $elem) {\n" " var_dump($elem->nodeName);\n" " dump($elem->childNodes);\n" "}\n" "}\n" "\n" "$dom = new DOMDocument();\n" "$dom->loadXML($xml);\n" "$doc = $dom->documentElement;\n" "dump($dom->getElementsByTagName('bar'));\n" "dump($doc->getElementsByTagName('bar'));\n" "dump($dom->getElementsByTagNameNS('http://www.example.com/ns/fubar'," " 'bar'));\n" "dump($doc->getElementsByTagNameNS('http://www.example.com/ns/fubar'," " 'bar'));\n" ); // dom005.phpt MVCR("\n" "Hello world\n" "\n" "\n" "This is a not well-formed
\n" "html files with undeclared entities \n" "\n" "\n" "EOM;\n" "$dom->loadHTML($html);\n" "print \"--- save as XML\n\";\n" "\n" "print adjustDoctype($dom->saveXML());\n" "print \"--- save as HTML\n\";\n" "\n" "print adjustDoctype($dom->saveHTML());\n" "\n" "function adjustDoctype($xml) {\n" " return str_replace(" "array(\">\n<\",\"DOCTYPE HTML\",'

','

')," "array(\"><\",\"DOCTYPE html\",'',''),$xml);\n" "}\n" ); // dom006.phpt MVCR("createElement('title');\n" " $titleElement->appendChild($this->createTextNode($title));\n" " $authorElement = $this->createElement('author');\n" " $authorElement->appendChild($this->createTextNode($author));\n" " $bookElement = $this->createElement('book');\n" " $bookElement->appendChild($titleElement);\n" " $bookElement->appendChild($authorElement);\n" " $this->documentElement->appendChild($bookElement);\n" " }\n" "}\n" "\n" "$dom = new books;\n" "\n" "$xml = <<\n" "\n" " \n" " The Grapes of Wrath\n" " John Steinbeck\n" " \n" " The Pearl John Steinbeck\n" " \n" "EOM;\n" "\n" "$dom->loadXML($xml);\n" "$dom->addBook('PHP de Luxe', 'Richard Samar, Christian Stocker');\n" "print $dom->saveXML();" ); // dom007.phpt MVCR("\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "]>\n" "\n" " \n" " Basic Languages\n" " Introduction to Languages\n" " \n" " \n" " French I\n" " Introduction to French\n" " \n" " \n" " \n" "\n" "EOXML;\n" "\n" "$dom = new DOMDocument();\n" "$dom->loadXML($xml);\n" "\n" "$dtd = $dom->doctype;\n" "\n" "/* Notation Tests */\n" "$nots = $dtd->notations;\n" "\n" "$length = $nots->length; var_dump($length);\n" "echo \"Length: \".$length.\"\n\";\n" "\n" "foreach ($nots AS $key=>$node) {\n" " echo \"Key $key: \".$node->nodeName.\" (\".\n" "$node->systemId.\") (\".$node->publicId.\")\n\";\n" "}\n" "print \"\n\";\n" "for($x=0; $x < $length; $x++) {\n" " echo \"Index $x: \".$nots->item($x)->nodeName.\" (\".\n" " $nots->item($x)->systemId.\") " "(\".$nots->item($x)->publicId.\")\n\";\n" "}\n" "\n" "echo \"\n\";\n" "$node = $nots->getNamedItem('xxx');\n" "var_dump($node);\n" "\n" "echo \"\n\";\n" "/* Entity Decl Tests */\n" "$ents = $dtd->entities;\n" "$length = $ents->length;\n" "echo \"Length: \".$length.\"\n\";\n" "foreach ($ents AS $key=>$node) {\n" " echo \"Key: $key Name: \".$node->nodeName.\"\n\";\n" "}\n" "echo \"\n\";\n" "for($x=0; $x < $length; $x++) {\n" " echo \"Index $x: \".$ents->item($x)->nodeName.\"\n\";\n" "}\n" "\n" "echo \"\n\";\n" "$node = $ents->item(3);\n" "var_dump($node);\n" "$node = $ents->getNamedItem('xxx');\n" "var_dump($node);\n" ); MVCR("createDocumentFragment();" " $body->appendXML($html);" " } else {" " $doc->loadHTML($html);" " $body = $doc->documentElement;" " }" " return helper($body);" " }" "" " function helper($element) {" " if ($element instanceof DOMText) {" " return htmlspecialchars($element->nodeValue);" " } else {" " $body = '';" " foreach ($element->childNodes as $child) {" " $body .= helper($child);" " }" "" " if ($element instanceof DOMElement) {" " $attrs = array();" " foreach ($element->attributes as $attr) {" " $attrs[] = htmlspecialchars($attr->name) . '=\"' . " " htmlspecialchars($attr->value) . '\"';" " }" " if ($attrs) {" " $attrs = ' ' . implode(' ', $attrs);" " } else {" " $attrs = '';" " }" " return '<' . $element->tagName . $attrs . '>' . $body . " " 'tagName . '>';" " } else {" " return $body;" " }" " }" " }" "" " $fragment = 'Hello, world.';" " $document = '
" "

'.$fragment.'

';" "" " echo rerender($fragment, true).\"\n\n\";" " echo rerender($document, false).\"\n\n\";" ); MVCR("$1 - ';" "$dom = new DOMDocument();" "$dom->loadXML($xml);" "new foo($dom->documentElement);" "class foo {" " function foo($a) {" " var_dump($a);" " }" "}"); MVCR("loadXML('');\n" "$remove = array();\n" "foreach ($dom->getElementsByTagName('b') as $data) {\n" " foreach ($data->childNodes as $element) {\n" " if ($element instanceof DOMElement) {\n" " $remove[] = $element;\n" " }\n" " }\n" "}\n" "foreach ($remove as $r) {\n" " $r->parentNode->removeChild($r);\n" "}\n" "echo $dom->saveXML();\n" ); MVCRO("HelloWorld';\n" " $doc = new DOMDocument();\n" " $element = $doc->createDocumentFragment();\n" " $element->appendXML($html);\n" " foreach ($element->childNodes->getIterator() as $child) {\n" " $element = null;\n" " $doc = null;\n" " var_dump($child->nodeValue);\n" " }\n" "}\n" "foo();\n", "string(5) \"Hello\"\n" "string(5) \"World\"\n" ); /* github issue #556 */ MVCR( "registerNodeClass('DOMNode', 'MyNode'));" "var_dump($dom->registerNodeClass('DOMElement', 'MyElement'));" ); return true; } bool TestCodeRun::TestFile() { //MVCR(".\\n\";" "" "fseek($input, 0);" "$output = fopen('php://memory', 'w+');" "stream_copy_to_stream($input, $output, null);" "fseek($output, 0);" "$bytes = fread($output, 1024);" "print \"From file, using Maxlen null: <\".serialize($bytes).\">.\\n\";" "" "" "fseek($input, 0);" "$output = fopen('php://memory', 'w+');" "stream_copy_to_stream($input, $output, -1);" "fseek($output, 0);" "$bytes = fread($output, 1024);" "print \"From file, using Maxlen -1: <\".serialize($bytes).\">.\\n\";"); MVCR("path . \"\\n\";" "while (false !== ($entry = $d->read())) {" " echo $entry.\"\\n\";" "}" "$d->rewind();" "while (false !== ($entry = $d->read())) {" " echo $entry.\"\\n\";" "}" "$d->close();"); return true; } bool TestCodeRun::TestBadFunctionCalls() { // make sure no error MVCR("foo();\n" " } catch (BadMethodCallException $e) {\n" " echo \"BadMethodCallException thrown\\n\";\n" " }\n" "}\n", "BadMethodCallException thrown\n" "BadMethodCallException thrown\n" "BadMethodCallException thrown\n" "BadMethodCallException thrown\n" "BadMethodCallException thrown\n"); // Make sure call_user_func() doesn't throw an exception MVCRO("a(); }" "test();"); // __construct takes priority MVCR("a(); } " "test();"); MVCR("__construct();" " }" " public function __construct() {" " echo \"In A::__construct\\n\";" " }" "}" "class B extends A {" " public function B() {" " echo \"In B\\n\";" " $this->A();" " }" "}" "$obj = new B();" "" "class A2 {" " public function __construct() {" " echo \"In A2::__construct\\n\";" " $this->B2();" " }" " public function B2() {" " echo \"In B2\\n\";" " }" "}" "class B2 extends A2 {" " public function __construct() {" " echo \"In B2::__construct\\n\";" " parent::__construct();" " }" "}" "$obj = new B2();" "class C {" " public function C() {}" "}" "class D extends C {" " public function __construct() {" " echo \"In D::__construct\\n\";" " C::__construct();" " }" "}" "$obj = new D;" "$obj->c();" "class E {" " public function E() {" " echo \"In E\\n\";" " }" " public function foo() {" " $this->E();" " E::__construct();" " }" "}" "$obj = new E;" "$obj->foo();"); MVCR("a = $i * $i;" " $this->b = $j * $j;" " $this->c = $k * $k;" " }" " public $a;" " protected $b;" " private $c;" " public $aa = 'aa';" " protected $bb = false;" " private $cc = 1.22;" " }" "}" "class B extends A {" " public function __construct($i, $j, $k) {" " $this->a = $i + $i;" " $this->b = $j + $j;" " $this->c = $k + $k;" " }" " public $a;" " protected $b;" " private $c;" " public $aa = 'aaa';" " protected $bb = 4;" " private $cc = 1.222;" "}" "function foo() {" " $obj = new B(1, 2, 3);" " var_dump($obj);" "}" "foo();"); return true; } bool TestCodeRun::TestIntIsset() { MVCR("exp_info = $exp_info ?: array();\n" " }\n" "}\n" "$x = new X(array(0, 1, 2));\n" "var_dump($x->exp_info);\n" "$x1 = new X(null);\n" "var_dump($x->exp_info);\n"); MVCR("name = \"MyDestructableClass\";" " }" "" " function __destruct() {" " print \"Destroying \" . $this->name . \"\\n\";" " }" "}" "function foo($a) {" " if ($a) return new MyDestructableClass();" " return false;" "}" "function bar($a) {" " if ($a) {" " $obj = foo(1);" " $obj = 1;" " var_dump(2);" " }" " var_dump(1);" "}" "bar(1);"); MVCR("name = \"MyDestructableClass\";" " }" "" " function __destruct() {" " print \"Destroying \" . $this->name . \"\\n\";" " }" "}" "function foo(&$a) {" " $a = new MyDestructableClass();" "}" "function bar($a) {" " if ($a) {" " $b = array(1, 2, 3);" " var_dump($b);" " foo($dummy = array(1, 2, 3));" " $c = array(1, 2, 3);" " var_dump($c);" " }" "}" "bar(1);"); MVCR(" $p) {" " $a = 10;" " } else {" " $a = &$b;" " }" " }" "}" "function bar() {" " $a = foo(2);" " var_dump($GLOBALS['b']);" "}" "bar();"); MVCR("x = 0; }\n" " public function __toString() {\n" " return sprintf(\"Evil%d\", $this->x++);\n" " }\n" "}\n" "function f_1($x) {\n" " switch ($x) {\n" " case \"123\": print '\"123\"' . \"\n\"; break;\n" " case \"4abc\": print '\"4abc\"' . \"\n\"; break;\n" " default: print \"default\n\"; break;\n" " case \"0\": print '\"0\"' . \"\n\"; break;\n" " case \"\": print '\"\"' . \"\n\"; break; \n" " case \"Evil4\": print '\"Evil4\"' . \"\n\"; break;\n" " }\n" "}\n" "function f_2($x) {\n" " var_dump($x); print \" goes to:\";\n" " switch ($x) {\n" " case \"foo\": print \"foo\n\"; break;\n" " case \"1\": print \"1\n\"; break;\n" " case \"2.0\": print \"2.0\n\"; break;\n" " case \"2ab\": print \"2ab\n\"; break;\n" " case \"3.212\": print \"3.212\n\"; break;\n" " case \"0\": print \"0\n\"; break;\n" " case \"\": print \"{empty str}\n\"; break;\n" " default: print \"default\n\"; break;\n" " }\n" "}\n" "function g_2($x) {\n" " var_dump($x); print \" goes to:\";\n" " switch ($x) {\n" " case \"\": print \"{empty str}\n\"; break;\n" " case \"0\": print \"0\n\"; break;\n" " default: print \"default\n\"; break;\n" " }\n" "}\n" "function h_2($x) {\n" " var_dump($x); print \" goes to:\";\n" " switch ($x) {\n" " case \"3.0\": print \"3.0\n\"; break;\n" " case \"3.0abc\": print \"3.0abc\n\"; break;\n" " case \"3\": print \"3\n\"; break;\n" " default: print \"\n\";\n" " }\n" "}\n" "function f_3($x) {\n" " switch ($x) {\n" " default: print \"default\n\";\n" " case \"bar\": print \"bar\n\";\n" " case \"foo\": print \"foo\n\";\n" " case \"baz\": print \"baz\n\";\n" " }\n" "}\n" "f_1(\"\");\n" "f_1(null);\n" "f_1(false);\n" "f_1(\"0\");\n" "f_1(\"0eab\");\n" "f_1(\"0.0\");\n" "f_1(0.0);\n" "f_1(0);\n" "f_1(true);\n" "f_1(false);\n" "f_1(\"4abc\");\n" "f_1(4);\n" "f_1(\"4.0\");\n" "f_1(new Evil());\n" "f_2(1);\n" "f_2(2);\n" "f_2(2.0);\n" "f_2(true);\n" "f_2(false);\n" "f_2(null);\n" "f_2((object) null);\n" "f_2(array());\n" "f_2(3.21200);\n" "g_2(0);\n" "g_2(null);\n" "g_2(false);\n" "g_2(true);\n" "h_2(\"3\");\n" "h_2(\"3abc\");\n" "h_2(\"3a\");\n" "h_2(3);\n" "h_2(3.0);\n" "f_3(\"foo\");\n" "f_3(\"bar\");\n" "f_3(\"baz\");\n" "f_3(\"def\");\n"); MVCR("foo();\n" "$x->bar(new stdClass);\n" "$x->bar($x);\n" "foreach ($x->baz($x) as $v) {\n" " var_dump($v);\n" "}\n", "defdefargargobject(X)#1 (0) {\n" "}\n"); } MVCR(" \"a\")));" "var_dump(strtr(\"hello\", array(\"ll\" => \"a\")));"); MVCR("array('bar'=>1));\n" "function fix(&$v, $k) { $v *= 2; }\n" "array_walk_recursive($a, 'fix');\n" "var_dump($a['foo']);\n"); MVCR("foo =& $a;" " var_dump(is_object($b));" " $b = false;" " $b[0] =& $a;" " uksort($a, function ($i, $j) use(&$b) {" " if ($b[0][$i] == $b[0][$j]) return 0;" " return $b[0][$i] < $b[0][$j] ? -1 : 1;" " });" "}" "function test($x) {" " $a = array(220,250,240,$x);" " xsort($a);" " var_dump($a);" "}" "test(230);"); MVCR("getMessage());" " }" "}" "test();"); return true; } bool TestCodeRun::TestExtFile() { MVCR(" 50; $i--) {" " imagefilledarc($image, 50, $i, 100, 50, 0, 45," " $darknavy, IMG_ARC_PIE);" " imagefilledarc($image, 50, $i, 100, 50, 45, 75," " $darkgray, IMG_ARC_PIE);" " imagefilledarc($image, 50, $i, 100, 50, 75, 360," " $darkred, IMG_ARC_PIE);" "}" "" "imagefilledarc($image, 50, 50, 100, 50, 0, 45, $navy, IMG_ARC_PIE);" "imagefilledarc($image, 50, 50, 100, 50, 45, 75 , $gray, IMG_ARC_PIE);" "imagefilledarc($image, 50, 50, 100, 50, 75, 360 , $red, IMG_ARC_PIE);" "" "" "// flush image" "header('Content-type: image/png');" "imagepng($image);" "imagedestroy($image);"); MVCR("isFile()) {" " echo $info->getRealPath();" "}" "$info = new SplFileInfo('test/test_code_run.cpp');" "var_dump($info->getbaseName());" "var_dump($info->getbaseName('.cpp'));" "echo 'Last changed at ' . date('g:i a', $info->getCTime());" "var_dump($info->getGroup());" "var_dump($info->getInode());" "var_dump($info->getMTime());" "var_dump($info->getOwner());" "var_dump($info->getPerms());" "var_dump($info->getSize());" "var_dump($info->getType());" "var_dump($info->isDir());" "var_dump($info->isFile());" "var_dump($info->isLink());" "var_dump($info->isReadable());" "var_dump($info->isWritable());"); MVCR("getRealPath());" "var_dump($info->getPath());" "var_dump($info->getPathName());" "$info = new SplFileInfo('test/');" "var_dump($info->getRealPath());" "var_dump($info->getPath());" "var_dump($info->getPathName());" "$info = new SplFileInfo('test//../test');" "var_dump($info->getRealPath());" "var_dump($info->getPath());" "var_dump($info->getPathName());" "$p=realpath('test/..');" "$info = new SplFileInfo($p.'/test_link');" "var_dump($info->getLinkTarget());" "var_dump($info->getRealPath());" "var_dump($info->getPath());" "var_dump($info->getPathName());"); MVCR("getLinkTarget();" "}" "catch (Exception $e) {" " echo 'Caught exception: ', $e->getMessage(), \"\\n\";" " return;" "}" "echo \"failed to throw\\n\";" " return true;" "}"); return true; } bool TestCodeRun::TestExtIterator() { MVCR("isDot()) {" " var_dump($fileinfo->getFilename());" " }" "}" "$iterator = new DirectoryIterator(\"test\");" "foreach ($iterator as $fileinfo) {" " if ($fileinfo->isFile()) {" " echo \"BEGIN: \" . $fileinfo->getFilename() . \"\\n\";" " echo $fileinfo->getCTime() . \"\\n\";" " echo $fileinfo->getBasename() . \"\\n\";" " echo $fileinfo->getBasename('.cpp') . \"\\n\";" " echo $fileinfo->getGroup() . \"\\n\";" " echo $fileinfo->getInode() . \"\\n\";" " echo $fileinfo->getMTime() . \"\\n\";" " echo $fileinfo->getOwner() . \"\\n\";" " echo $fileinfo->getPerms() . \"\\n\";" " echo $fileinfo->getSize() . \"\\n\";" " echo $fileinfo->getType() . \"\\n\";" " echo $fileinfo->isDir() . \"\\n\";" " echo $fileinfo->isDot() . \"\\n\";" " echo $fileinfo->isExecutable() . \"\\n\";" " echo $fileinfo->isLink() . \"\\n\";" " echo $fileinfo->isReadable() . \"\\n\";" " echo $fileinfo->isWritable() . \"\\n\";" " echo \"END\" . \"\\n\";" " }" "}" "$iterator = new RecursiveDirectoryIterator(\"test\");" "foreach ($iterator as $fileinfo) {" " if ($fileinfo->isFile()) {" " echo $fileinfo->getFilename() . \"\\n\";" " echo $fileinfo->getCTime() . \"\\n\";" " echo $fileinfo->getBasename() . \"\\n\";" " echo $fileinfo->getBasename('.cpp') . \"\\n\";" " echo $fileinfo->getFilename() . \"\\n\";" " echo $fileinfo->getGroup() . \"\\n\";" " echo $fileinfo->getInode() . \"\\n\";" " echo $fileinfo->getMTime() . \"\\n\";" " echo $fileinfo->getOwner() . \"\\n\";" " echo $fileinfo->getPerms() . \"\\n\";" " echo $fileinfo->getSize() . \"\\n\";" " echo $fileinfo->getType() . \"\\n\";" " echo $fileinfo->isDir() . \"\\n\";" " echo $fileinfo->isExecutable() . \"\\n\";" " echo $fileinfo->isLink() . \"\\n\";" " echo $fileinfo->isReadable() . \"\\n\";" " echo $fileinfo->isWritable() . \"\\n\";" " }" "}"); MVCR("valid()) {" " if(!$dir->isDot()) {" " print $dir->current().\"\\n\";" " }" " $dir->next();" "}"); MVCR("$cur) {" " $filesize=$cur->getSize();" " $bytestotal+=$filesize;" " $nbfiles++;" " echo \"$filename => $filesize\\n\";" "}" "$bytestotal=number_format($bytestotal);" "echo \"Total: $nbfiles files, $bytestotal bytes\\n\";"); MVCR("$cur) {" " if (substr($filename,-1)=='.') continue;" " $filesize=$cur->getSize();" " $bytestotal+=$filesize;" " $nbfiles++;" " echo \"$filename => $filesize\\n\";" "}" "$bytestotal=number_format($bytestotal);" "echo \"Total: $nbfiles files, $bytestotal bytes\\n\";"); MVCR(" $info) {" " if ($info->isDir() && substr($file,-1)!='.') {" " echo $file.\"\\n\";" " }" "}"); MVCR(" $fileSPLObject ) {" " if (substr($fullFileName,-1)=='.') continue;" " print $fullFileName . \" \" .$fileSPLObject->getFilename(). \"\\n\";" "}" "$fileSPLObjects = new RecursiveIteratorIterator(" " new RecursiveDirectoryIterator($directory)," " RecursiveIteratorIterator::CHILD_FIRST);" "foreach( $fileSPLObjects as $fullFileName => $fileSPLObject ) {" " if (substr($fullFileName,-1)=='.') continue;" " print $fullFileName . \" \" .$fileSPLObject->getFilename(). \"\\n\";" "}" "$fileSPLObjects = new RecursiveIteratorIterator(" " new RecursiveDirectoryIterator($directory)," " RecursiveIteratorIterator::LEAVES_ONLY);" "foreach( $fileSPLObjects as $fullFileName => $fileSPLObject ) {" " if (substr($fullFileName,-1)=='.') continue;" " print $fullFileName . \" \" .$fileSPLObject->getFilename(). \"\\n\";" "}" "// invalid mode -100" "$fileSPLObjects = new RecursiveIteratorIterator(" " new RecursiveDirectoryIterator($directory), -100);" "foreach( $fileSPLObjects as $fullFileName => $fileSPLObject ) {" " if (substr($fullFileName,-1)=='.') continue;" " print $fullFileName . \" \" .$fileSPLObject->getFilename(). \"\\n\";" "}"); MVCR("rewind();$rdi->valid();$rdi->next()) {" " if ($rdi->isDot()) continue;" " if ($rdi->isDir() || $rdi->isFile()) {" " for ($i = 0; $i<=$depth;++$i) echo \" \";" " echo $rdi->current().\"\\n\";" " if ($rdi->hasChildren()) getFiles($rdi->getChildren(),1+$depth);" " }" " }" "}" "getFiles(new RecursiveDirectoryIterator('test'));"); MVCR("next();" "} catch (UnexpectedValueException $e) {" "}" "var_dump('ok');"); MVCR("getInnerIterator()->current() % 2 == 0;\n" " }\n" "}\n" "$i = new EvensOnly(new ArrayIterator(range(0, 10)));\n" "foreach ($i as $v) {\n" " var_dump($v);\n" "}\n"); MVCR(" 'http://test-uri'));" "$str = ''." " ''." " ''." " '16'." " '21'." " ' ';" "$server->addFunction('Add');" "$server->handle($str);"); MVCR(" 'bar'))->pub);"); return true; } bool TestCodeRun::TestExtCollator() { MVCR("compare( $str1, $str2 ) : collator_compare( $coll, $str1, $str2 );\n" "}\n" "function ut_coll_sort_with_sort_keys( $coll, &$arr )\n" "{\n" " return $GLOBALS['oo-mode'] ? \n" " $coll->sortWithSortKeys( $arr ) : collator_sort_with_sort_keys( $coll, $arr );\n" "}\n" "function ut_coll_sort( $coll, &$arr, $sort_flag = Collator::SORT_REGULAR )\n" "{\n" " return $GLOBALS['oo-mode'] ? \n" " $coll->sort( $arr, $sort_flag ) : collator_sort( $coll, $arr, $sort_flag );\n" "}\n" "function ut_coll_asort( $coll, &$arr, $sort_flag = Collator::SORT_REGULAR )\n" "{\n" " return $GLOBALS['oo-mode'] ? \n" " $coll->asort( $arr, $sort_flag ) : collator_asort( $coll, $arr, $sort_flag );\n" "}\n" "function ut_coll_get_locale( $coll, $type )\n" "{\n" " return $GLOBALS['oo-mode'] ? \n" " $coll->getLocale( $type ) : collator_get_locale( $coll, $type );\n" "}\n" "function ut_coll_set_strength( $coll, $strength )\n" "{\n" " return $GLOBALS['oo-mode'] ? \n" " $coll->setStrength( $strength ) : collator_set_strength( $coll, $strength );\n" "}\n" "function ut_coll_set_attribute( $coll, $attr, $val )\n" "{\n" " return $GLOBALS['oo-mode'] ? \n" " $coll->setAttribute( $attr, $val ) : collator_set_attribute( $coll, $attr, $val );\n" "}\n" "function ut_coll_set_default( $coll )\n" "{\n" " return $GLOBALS['oo-mode'] ? Collator::setDefault( $coll ) : collator_set_default( $coll );\n" "}\n" "$test_num = 1;\n" "function sort_arrays( $locale, $arrays, $sort_flag = Collator::SORT_REGULAR )\n" "{\n" " $res_str = '';\n" " $coll = ut_coll_create( $locale );\n" " foreach( $arrays as $array )\n" " {\n" " // Sort array values\n" " $res_val = ut_coll_sort( $coll, $array, $sort_flag );\n" " // Concatenate the sorted array and function result\n" " // with output string.\n" " $res_dump = \"\\n\" . dump( $array ) .\n" " \"\\n Result: \" . dump( $res_val );\n" " // Preppend test signature to output string\n" " $md5 = md5( $res_dump );\n" " global $test_num;\n" " \n" " $res_str .= \"\\n\\n\".\n" " \"Test $test_num.$md5:\" .\n" " $res_dump;\n" " ++$test_num;\n" " }\n" " return $res_str;\n" "}\n" "function ut_main1()\n" "{\n" " global $test_num;\n" " $test_num = 1;\n" " $res_str = '';\n" " // Sort an array in SORT_REGULAR mode using en_US locale.\n" " $test_params = array(\n" " array( 'abc', 'abd', 'aaa' ),\n" " array( 'm' , '1' , '_' ),\n" " array( 'a' , 'aaa', 'aa' ),\n" " array( 'ba' , 'b' , 'ab' ),\n" " array( 'e' , 'c' , 'a' ),\n" " array( '100', '25' , '36' ), // test 6\n" " array( 5 , '30' , 2 ),\n" " array( 'd' , '' , ' a' ),\n" " array( 'd ' , 'f ' , ' a' ),\n" " array( 'a' , null , '3' ),\n" " array( 'y' , 'k' , 'i' )\n" " );\n" " $res_str .= sort_arrays( 'en_US', $test_params );\n" " $test_params = array(\n" " array( '100', '25' , '36' ),\n" " array( 5 , '30' , 2 ), // test 13\n" " array( 'd' , '' , ' a' ),\n" " array( 'y' , 'k' , 'i' )\n" " );\n" " // Sort in en_US locale with SORT_STRING flag\n" " $res_str .= sort_arrays( 'en_US', $test_params, Collator::SORT_STRING );\n" " // Sort a non-ASCII array using ru_RU locale.\n" " $test_params = array(\n" " array( '\xd0\xb0\xd0\xb1\xd0\xb3', " " '\xd0\xb0\xd0\xb1\xd0\xb2', " " '\xd0\xb0\xd0\xb0\xd0\xb0', " " '\xd0\xb0\xd0\xb1\xd0\xb2' ),\n" " array( '\xd0\xb0\xd0\xb0', '\xd0\xb0\xd0\xb0\xd0\xb0'," " '\xd0\xb0' )\n" " );\n" " $res_str .= sort_arrays( 'ru_RU', $test_params );\n" " // Sort an array using Lithuanian locale.\n" " $test_params = array(\n" " array( 'y' , 'k' , 'i' )\n" " );\n" " $res_str .= sort_arrays( 'lt_LT', $test_params );\n" " return $res_str;\n" "}\n" "ut_run('ut_main1');\n" "function ut_main2() {\n" " $obj = ut_coll_create('en_US');\n" " $arr0 = array( 100, 25, 36, '30.2', '30.12' ); // test 6\n" " $arr1 = array( '100', '25', '36' ); // test 6\n" " $arr2 = array( 11, 5, '2', 64, 17, '30', 10, 2, '54' );\n" " // strcmp 17 and 30, ret = 1\n" " // Comparing values 17 and 30, ret = 1\n" " $arr3 = array( 11, 5, 2, 64, 17, 30, 10, 2, 54 );\n" " $arrA = $arr0;\n" " $arrB = $arr0;\n" " $arrC = $arr0;\n" " ut_coll_sort($obj, $arrA, Collator::SORT_REGULAR);\n" " ut_coll_sort($obj, $arrB, Collator::SORT_STRING);\n" " ut_coll_sort($obj, $arrC, Collator::SORT_NUMERIC);\n" " var_dump($arrA, $arrB, $arrC);\n" " $arrA = $arr1;\n" " $arrB = $arr1;\n" " $arrC = $arr1;\n" " ut_coll_sort($obj, $arrA, Collator::SORT_REGULAR);\n" " ut_coll_sort($obj, $arrB, Collator::SORT_STRING);\n" " ut_coll_sort($obj, $arrC, Collator::SORT_NUMERIC);\n" " var_dump($arrA, $arrB, $arrC);\n" " $arrA = $arr2;\n" " $arrB = $arr2;\n" " $arrC = $arr2;\n" " ut_coll_sort($obj, $arrA, Collator::SORT_REGULAR);\n" " ut_coll_sort($obj, $arrB, Collator::SORT_STRING);\n" " ut_coll_sort($obj, $arrC, Collator::SORT_NUMERIC);\n" " var_dump($arrA, $arrB, $arrC);\n" " $arrA = $arr3;\n" " $arrB = $arr3;\n" " $arrC = $arr3;\n" " ut_coll_sort($obj, $arrA, Collator::SORT_REGULAR);\n" " ut_coll_sort($obj, $arrB, Collator::SORT_STRING);\n" " ut_coll_sort($obj, $arrC, Collator::SORT_NUMERIC);\n" " var_dump($arrA, $arrB, $arrC);\n" "}\n" "ut_run('ut_main2');\n" "function ut_main3()\n" "{\n" " $res_str = '';\n" " $locales = array(\n" " 'EN-US-ODESSA',\n" " 'UK_UA_ODESSA',\n" " 'uk-ua_CALIFORNIA@currency=;currency=GRN',\n" " '',\n" " 'root',\n" " 'uk@currency=EURO'\n" " );\n" " foreach( $locales as $locale )\n" " {\n" " // Create Collator with the current locale.\n" " $coll = ut_coll_create( $locale );\n" " if( !is_object($coll) )\n" " {\n" " $res_str .= \"Error creating collator with '$locale' locale: \" .\n" " intl_get_error_message() . \"\\n\";\n" " continue;\n" " }\n" " // Get the requested, valid and actual locales.\n" " $vloc = ut_coll_get_locale( $coll, Locale::VALID_LOCALE );\n" " // Show them.\n" " $res_str .= \"Locale: '$locale'\\n\" .\n" " \" ULOC_VALID_LOCALE = '$vloc'\\n\";\n" " }\n" " return $res_str;\n" "}\n" "ut_run('ut_main3');\n" "function test_COW( $locale, $test_array )\n" "{\n" " $res_str = '';\n" " $coll = ut_coll_create( $locale );\n" " // Create two copies of the given array.\n" " $copy1 = $test_array;\n" " $copy2 = $test_array;\n" " // Sort given array and the first copy of it.\n" " ut_coll_sort( $coll, $test_array );\n" " ut_coll_sort( $coll, $copy1 );\n" " // Return contents of all the arrays.\n" " // The second copy should remain unsorted.\n" " $res_str .= dump( $test_array ) . \"\\n\";\n" " $res_str .= dump( $copy1 ) . \"\\n\";\n" " $res_str .= dump( $copy2 ) . \"\\n\";\n" " return $res_str;\n" "}\n" "function ut_main4()\n" "{\n" " $res_str = '';\n" " $a1 = array( 'b', 'a', 'c' );\n" " $a2 = array( '\xd0\xb1', '\xd0\xb0', '\xd0\xb2' );\n" " $res_str .= test_COW( 'en_US', $a1 );\n" " $res_str .= test_COW( 'ru_RU', $a2 );\n" " return $res_str;\n" "}\n" "ut_run('ut_main4');\n" "function cmp_array( &$coll, $a )\n" "{\n" " $res = '';\n" " $prev = null;\n" " foreach( $a as $i )\n" " {\n" " if( is_null( $prev ) )\n" " $res .= \"$i\";\n" " else\n" " {\n" " $eqrc = ut_coll_compare( $coll, $prev, $i );\n" " $eq = $eqrc < 0 ? \"<\" : ( $eqrc > 0 ? \">\" : \"=\" );\n" " $res .= \" $eq $i\";\n" " }\n" " $prev = $i;\n" " }\n" " $res .= \"\\n\";\n" " return $res;\n" "}\n" "function check_alternate_handling( &$coll )\n" "{\n" " $res = '';\n" " ut_coll_set_strength( $coll, Collator::TERTIARY );\n" " ut_coll_set_attribute( $coll, Collator::ALTERNATE_HANDLING, Collator::NON_IGNORABLE );\n" " $res .= cmp_array( $coll, array( 'di Silva', 'Di Silva', 'diSilva', 'U.S.A.', 'USA' ) );\n" " ut_coll_set_attribute( $coll, Collator::ALTERNATE_HANDLING, Collator::SHIFTED );\n" " $res .= cmp_array( $coll, array( 'di Silva', 'diSilva', 'Di Silva', 'U.S.A.', 'USA' ) );\n" " ut_coll_set_strength( $coll, Collator::QUATERNARY );\n" " $res .= cmp_array( $coll, array( 'di Silva', 'diSilva', 'Di Silva', 'U.S.A.', 'USA' ) );\n" " $res .= \"\\n\";\n" " return $res;\n" "}\n" "function ut_main5()\n" "{\n" " $coll = ut_coll_create( 'en_US' );\n" " return\n" " check_alternate_handling( $coll );\n" "}\n" "ut_run('ut_main5');\n" "function sort_arrays_with_sort_keys( $locale, $arrays )\n" "{\n" " $res_str = '';\n" " $coll = ut_coll_create( $locale );\n" " foreach( $arrays as $array )\n" " {\n" " // Sort array values\n" " $res_val = ut_coll_sort_with_sort_keys( $coll, $array );\n" " // Concatenate the sorted array and function result\n" " // with output string.\n" " $res_dump = \"\\n\" . dump( $array ) .\n" " \"\\n Result: \" . dump( $res_val );\n" " \n" " \n" " // Preppend test signature to output string\n" " $md5 = md5( $res_dump );\n" " global $test_num;\n" " $res_str .= \"\\n\\n\".\n" " \"Test $test_num.$md5:\" .\n" " $res_dump;\n" " ++$test_num;\n" " }\n" " return $res_str;\n" "}\n" "function ut_main6()\n" "{\n" " global $test_num;\n" " $test_num = 1;\n" " $res_str = '';\n" " // Sort an array in SORT_REGULAR mode using en_US locale.\n" " $test_params = array(\n" " array( 'abc', 'abd', 'aaa' ),\n" " array( 'm' , '1' , '_' ),\n" " array( 'a' , 'aaa', 'aa' ),\n" " array( 'ba' , 'b' , 'ab' ),\n" " array( 'e' , 'c' , 'a' ),\n" " array( 'd' , '' , ' a' ),\n" " array( 'd ' , 'f ' , ' a' ),\n" " array( 'a' , null , '3' ),\n" " array( 'y' , 'i' , 'k' )\n" " );\n" " $res_str .= sort_arrays_with_sort_keys( 'en_US', $test_params );\n" " // Sort a non-ASCII array using ru_RU locale.\n" " $test_params = array(\n" " array( '\xd0\xb0\xd0\xb1\xd0\xb3', " " '\xd0\xb0\xd0\xb1\xd0\xb2', " " '\xd0\xb0\xd0\xb0\xd0\xb0', " " '\xd0\xb0\xd0\xb1\xd0\xb2' ),\n" " array( '\xd0\xb0\xd0\xb0', '\xd0\xb0\xd0\xb0\xd0\xb0'," " '\xd0\xb0' )\n" " );\n" " $res_str .= sort_arrays_with_sort_keys( 'ru_RU', $test_params );\n" " // Array with data for sorting.\n" " $test_params = array(\n" " array( 'y' , 'i' , 'k' )\n" " );\n" " // Sort an array using Lithuanian locale.\n" " $res_str .= sort_arrays_with_sort_keys( 'lt_LT', $test_params );\n" " return $res_str . \"\\n\";\n" "}\n" "ut_run('ut_main6');\n" ); return true; } bool TestCodeRun::TestExtSocket() { MVCR(" 2\n" " [1] => 2\n" ")\n" "Array\n" "(\n" " [0] => 2\n" " [1] => 2\n" ")\n" "Array\n" "(\n" " [0] => 3\n" " [1] => 3\n" ")\n" ); MVCRO("v = 100; } }\n" "$a = array(array(1, 2, 3), new A());\n" "apc_store('0', $a);\n" "$b = apc_fetch(0);\n" "var_dump($b[1]->v);\n" "$b[1]->f();\n" // SharedMap::get() needs caching "var_dump($b[1]->v);\n" "$b[2] = 1;\n" // SharedMap::escalate() needs caching "var_dump($b[1]->v);\n", "int(10)\n" "int(100)\n" "int(100)\n" ); MVCRO("\n" " int(100)\n" " [\"b\":\"A\":private]=>\n" " int(10)\n" "}\n" ); MVCRO("a = 5; $a->b = &$a->a;\n" "apc_store('key', $a);\n" "var_dump(apc_fetch('key'));\n", "object(A)#2 (2) {\n" " [\"a\"]=>\n" " &int(5)\n" " [\"b\"]=>\n" " &int(5)\n" "}\n" ); MVCRO("\n" " int(10)\n" "}\n" ); // objects in an apc array can be changed without escalating the array MVCRO("i = 100;\n" "apc_store('key2', $b);\n" "$t = apc_fetch('key2');\n" "var_dump($t[0]->i);\n", "int(100)\n"); // Serializable object in APC MVCRO("a); }\n" " function unserialize($s) { $this->a = unserialize($s); }\n" "}\n" "$o = new A;\n" "apc_store('key', $o);\n" "$r = apc_fetch('key');\n" "var_dump($r);\n", "object(A)#2 (1) {\n" " [\"a\"]=>\n" " int(123)\n" "}\n"); for (int i = 0; i < 2; i++) { string cfg = "-vServer.APC.AllowObject=" + boost::lexical_cast(i); OptionSetter w(this, OptionSetter::RunTime, cfg.c_str()); // apc_fetch twice to trigger immutable object MVCRO("a = $i * $i;" " $this->b = $j * $j;" " $this->c = $k * $k;" " }" " public $a;" " protected $b;" " private $c;" " public $aa = 'aa';" " protected $bb = false;" " private $cc = 1.22;" "}" "class B extends A {" " public function __construct($i, $j, $k) {" " $this->a = $i + $i;" " $this->b = $j + $j;" " $this->c = $k + $k;" " }" " public $a;" " protected $b;" " private $c;" " public $aa = 'aaa';" " protected $bb = 4;" " private $cc = 1.222;" "}" "class C extends B {" " public function __construct($i, $j, $k) {" " $this->a = $i + $i + $i;" " $this->b = $j + $j + $j;" " $this->c = $k + $k + $k;" " }" " public $a;" " protected $b;" " private $c;" " public $aa = 'aaaa';" " protected $bb = 40;" " private $cc = 1.333;" "}" "class D extends C {" " public function __construct($i, $j, $k) {" " $this->a = $i + $i + $i;" " $this->b = $j + $j + $j;" " $this->c = $k + $k + $k;" " }" " public $a;" " public $b;" " private $c;" " public $aa = 'aaaaa';" " public $bb = 400;" " private $cc = 1.3333;" "}" "function foo() {" " $obj = new A(111, 222, 333);" " apc_store('foobar', $obj);" " $obj = apc_fetch('foobar');" " $obj = apc_fetch('foobar');" " var_dump($obj);" " $obj = new B(111, 222, 333);" " apc_store('foobar', $obj);" " $obj = apc_fetch('foobar');" " $obj = apc_fetch('foobar');" " var_dump($obj);" " $obj = new C(111, 222, 333);" " apc_store('foobar', $obj);" " $obj = apc_fetch('foobar');" " $obj = apc_fetch('foobar');" " var_dump($obj);" " $obj = new D(111, 222, 333);" " apc_store('foobar', $obj);" " $obj = apc_fetch('foobar');" " $obj = apc_fetch('foobar');" " var_dump($obj);" "}" "foo();", "object(A)#3 (6) {\n" " [\"a\"]=>\n" " int(12321)\n" " [\"b\":protected]=>\n" " int(49284)\n" " [\"c\":\"A\":private]=>\n" " int(110889)\n" " [\"aa\"]=>\n" " string(2) \"aa\"\n" " [\"bb\":protected]=>\n" " bool(false)\n" " [\"cc\":\"A\":private]=>\n" " float(1.22)\n" "}\n" "object(B)#6 (8) {\n" " [\"a\"]=>\n" " int(222)\n" " [\"b\":protected]=>\n" " int(444)\n" " [\"c\":\"B\":private]=>\n" " int(666)\n" " [\"aa\"]=>\n" " string(3) \"aaa\"\n" " [\"bb\":protected]=>\n" " int(4)\n" " [\"cc\":\"B\":private]=>\n" " float(1.222)\n" " [\"c\":\"A\":private]=>\n" " NULL\n" " [\"cc\":\"A\":private]=>\n" " float(1.22)\n" "}\n" "object(C)#9 (10) {\n" " [\"a\"]=>\n" " int(333)\n" " [\"b\":protected]=>\n" " int(666)\n" " [\"c\":\"C\":private]=>\n" " int(999)\n" " [\"aa\"]=>\n" " string(4) \"aaaa\"\n" " [\"bb\":protected]=>\n" " int(40)\n" " [\"cc\":\"C\":private]=>\n" " float(1.333)\n" " [\"c\":\"B\":private]=>\n" " NULL\n" " [\"cc\":\"B\":private]=>\n" " float(1.222)\n" " [\"c\":\"A\":private]=>\n" " NULL\n" " [\"cc\":\"A\":private]=>\n" " float(1.22)\n" "}\n" "object(D)#12 (12) {\n" " [\"a\"]=>\n" " int(333)\n" " [\"b\"]=>\n" " int(666)\n" " [\"c\":\"D\":private]=>\n" " int(999)\n" " [\"aa\"]=>\n" " string(5) \"aaaaa\"\n" " [\"bb\"]=>\n" " int(400)\n" " [\"cc\":\"D\":private]=>\n" " float(1.3333)\n" " [\"c\":\"C\":private]=>\n" " NULL\n" " [\"cc\":\"C\":private]=>\n" " float(1.333)\n" " [\"c\":\"B\":private]=>\n" " NULL\n" " [\"cc\":\"B\":private]=>\n" " float(1.222)\n" " [\"c\":\"A\":private]=>\n" " NULL\n" " [\"cc\":\"A\":private]=>\n" " float(1.22)\n" "}\n"); } MVCRO("map = $f;\n" " }\n" "}\n" "class E {\n" " protected $map;\n" " public function __construct($f) {\n" " $this->map = $f;\n" " }\n" " public function getMap() {\n" " return $this->map;\n" " }\n" "}\n" "$f = new stdclass();\n" "$arr = array(new E($f), new D($f));\n" "apc_store('ggg', $arr);\n" "$arr2 = apc_fetch('ggg');\n" "var_dump($arr[0]->getMap());\n" "var_dump($arr[1]->map);\n" "var_dump($arr2[0]->getMap());\n" "var_dump($arr2[1]->map);\n" , "object(stdClass)#1 (0) {\n" "}\n" "object(stdClass)#1 (0) {\n" "}\n" "object(stdClass)#5 (0) {\n" "}\n" "object(stdClass)#5 (0) {\n" "}\n" ); MVCRO("p = &$v;\n" "$o2->p = &$v;\n" "$arr1 = array($o1, $o2);\n" "apc_store('foo', $arr1);\n" "$arr2 = apc_fetch('foo');\n" "var_dump($arr1);\n" "var_dump($arr2);\n" , "array(2) {\n" " [0]=>\n" " object(stdClass)#1 (1) {\n" " [\"p\"]=>\n" " &int(42)\n" " }\n" " [1]=>\n" " object(stdClass)#2 (1) {\n" " [\"p\"]=>\n" " &int(42)\n" " }\n" "}\n" "array(2) {\n" " [0]=>\n" " object(stdClass)#3 (1) {\n" " [\"p\"]=>\n" " &int(42)\n" " }\n" " [1]=>\n" " object(stdClass)#4 (1) {\n" " [\"p\"]=>\n" " &int(42)\n" " }\n" "}\n" ); { HipHopSyntax w(this); MVCRO("cache_gen = $x->gen('a', 'b'); " "foreach ($x->cache_gen as $v) { var_dump($v); } " "apc_store('key', $x); " "$y = apc_fetch('key'); " "print_r($y->cache_gen);", "string(1) \"a\"\n" "string(1) \"b\"\n" "DummyContinuation Object\n" "(\n" ")\n" ); MVCRO("\n" " string(4) \"afoo\"\n" " [1]=>\n" " array(1) {\n" " [0]=>\n" " string(3) \"foo\"\n" " }\n" "}\n"); MVCRO("\n" " object(X)#2 (0) {\n" " }\n" " [1]=>\n" " object(X)#2 (0) {\n" " }\n" " [2]=>\n" " object(X)#2 (0) {\n" " }\n" "}\n" "array(3) {\n" " [0]=>\n" " object(X)#3 (0) {\n" " }\n" " [1]=>\n" " object(X)#3 (0) {\n" " }\n" " [2]=>\n" " object(X)#3 (0) {\n" " }\n" "}\n"); return true; } bool TestCodeRun::TestInlining() { OptionSetter w(this, OptionSetter::CompileTime, "-vAutoInline=5"); MVCR("f();" "}" "var_dump(test());"); MVCR("';" "}" "function test() {" " echo foo();" "}" "test();"); MVCR("x = $x; } }" "class X extends B {" " function __construct() { parent::__construct(array()); }" " function foo() { echo \"foo\n\"; }" "}" "function bar($x=0) { if ($x) return 1; return ''; }" "function test($foo) {" " id(new X(bar()))->foo();" " id(new $foo(bar()))->foo();" "}" "test('X');"); MVCR("t();" "}"); MVCR("bar = 1;" "}"); MVCR(" $tr_row) {" " if ($tr_row == 45) $temp_tr = $tr_id;" " if ($tr_id == 0) {" " continue;" " } else {" " return $tr_row;" " }" " }" " if ($temp_tr) {" " return $temp_tr;" " }" " return null;" "}" "var_dump(test(array('a' => 1, 'b' => 45)));"); MVCR("map = $map;" " $this->parents = $parents;" " }" "}"); MVCR("o = $this;" " $this->a = array(1,2,3);" " $this->o2 = $this;" " }" "}" "function test() {" " $x = new X;" " $x->foo();" " $s = serialize($x);" " var_dump($s);" " $y = unserialize($s);" " var_dump($y);" "}" "test();"); return true; } bool TestCodeRun::TestHoisting() { MVCR("f4(3);\n"); MVCR("f4missing(3);\n" "echo \"finish\n\";\n"); MVCR("foo();}\n" "}\n" "class G extends B {\n" " function foo() { var_dump(__CLASS__);}\n" " function f4missing() { $b = func(); $b::f4missing();}\n" "}\n" "$g = new G; $g->f4missing();\n"); return true; } bool TestCodeRun::TestLateStaticBinding() { MVCR( "foo();\n" " static::g();\n" " $y->foo();\n" " self::g();\n" " Y::foo() && static::g();\n" " }\n" " static function g() { var_dump(__CLASS__); }\n" "}\n" "class Y extends X {\n" " static function g() { var_dump(__CLASS__); }\n" " static function foo() { return true; }\n" "}\n" "function test() {\n" " $x = new X;\n" " $y = new Y;\n" " $x->f();\n" " $y->f();\n" "}\n" "test();\n" ); MVCR( "foo(); // $this changes 'static'\n" " parent::foo(); // 'parent' doesn't change 'static'\n" " }\n" "}\n" "\n" "$a = new A();\n" "$b = new B();\n" "\n" "B::foo(); // B\n" "$b->foo(); // B\n" "\n" "$b->foo2(); // BB\n" "$b->foo3(); // BB\n" "\n" "A::foo(); // A\n" "$a->foo(); // A\n" "\n" "$a->foo2(); // BA\n" ); MVCR("baz();\n" "Y::baz();\n"); MVCR("f(); }\n" " }\n" "} else {\n" " class A { }\n" "}\n" "class B extends A { static $a = 'B'; }\n" "$b = new B;\n" "$b->g();\n"); // instanceof static and new static MVCR("bar();\n" "self::test();\n" "}\n" "}\n" "class Foo {\n" "public function bar() {}\n" "}\n" "$obj = new Foo();\n" "TestA::nativeTest($obj);\n"); MVCR("foo('y');" "$x->foo(new Y);"); MVCR("fiz(self::foo());\n" " }\n" " function fiz($x) {}\n" "}\n" "class B extends A {}\n" "$array = array('foo');\n" "array_map('B::foo', $array);\n" "call_user_func('B::foo');\n" "call_user_func(array('B', 'foo'));\n" "A::bar();\n"); if (!hhvm) { MVCR("getMethod('foo')->invoke($o);" " $x->getMethod('foo')->invoke(null);" " $x->getMethod('bar')->invoke($o);" "}" "test(new ReflectionClass('X'), new X);" "test(new ReflectionClass('Y'), new X);" // "test(new ReflectionClass('X'), new Y);" // "test(new ReflectionClass('Y'), new Y);" "test(new ReflectionClass('X'), new X);" // "test(new ReflectionClass('X'), new Z);" "test(new ReflectionClass('Z'), new Z);" "call_user_func(array(new Y, 'X::foo'));" "call_user_func(array(new Z, 'X::foo'));"); MVCR("foo();"); return true; } bool TestCodeRun::TestCallStatic() { MVCRO("test1a();\n", "d2::__call\n" // "c2::__callStatic\n" <--- PHP 5.3 returns this ); MVCRO("test1a();\n" "var_dump('end');\n", "d2::__call\n" "string(3) \"end\"\n" // "string(7) \"errored\"\n" <--- PHP 5.3 returns this ); MVCRO("test1a();\n" "var_dump('end');\n", "c2::__call\n" "string(3) \"end\"\n" // "string(7) \"errored\"\n" <--- PHP 5.3 returns this ); MVCR("test();\n"); MVCRO("test();\n" "var_dump('end');\n", "string(7) \"errored\"\n" ); MVCR("test();\n" "$obj = new b2;\n" "$obj->test();\n"); MVCR("test();\n" "$obj = new b1;\n" "$obj->test();\n"); MVCR("test();\n" "$obj = new b2;\n" "$obj->test();\n"); MVCR("test();\n" "$obj = new b1;\n" "$obj->test();\n"); MVCR("test();\n" "$obj = new b2;\n" "$obj->test();\n"); MVCR("runTest('in object context');\n" "MethodTest::runTest('in static context');\n"); MVCR("f(42);\n"); MVCR("getMessage());" " }" " var_dump('after try2');" " } catch (Exception $e) {" " l2: var_dump($e->getMessage());" " } catch (MyException $m) {" " l3: var_dump($m->getMessage());" " }" " var_dump('after try1');" "}" "for ($i = 0; $i < 16; $i++) foo($i);"); MVCR(" 2; }; echo $a(4).\"\n\";" " echo call_user_func_array($a, array(4));"); MVCR("'bar'));"); MVCR("goo($p);" " }, $values);" " var_dump($values);" " }" " public function bar() { return $this; }" " public function goo($p) { return $p; }" "}" "$obj = new A;" "var_dump($obj->bar());" "$obj->foo();", "object(A)#1 (0) {\n" "}\n" "array(3) {\n" " [0]=>\n" " int(1)\n" " [1]=>\n" " int(2)\n" " [2]=>\n" " int(3)\n" "}\n"); return true; } bool TestCodeRun::TestNamespace() { MVCR("fiz();" " var_dump(true);" " var_dump(false);" " var_dump(null);" " var_dump(INF);" " var_dump(FIZ);" " var_dump(FUZ);" " var_dump(\\FUZ);" "}"); MVCR("fruit() as $fruit) { var_dump($fruit);} ", "string(5) \"apple\"\n" "string(6) \"banana\"\n" ); MVCRO(" $v1) {\n" " foreach ($a2 as $k2 => &$v2) {\n" " $v2 += $v1; yield $v2;\n" " }\n" " }\n" "}\n" "$a1 = array(1, 2);\n" "$a2 = array(1, 2);\n" "foreach (f($a1, $a2) as $v) { var_dump($v); }\n" "var_dump($a2[0], $a2[1]);\n", "int(2)\n" "int(3)\n" "int(4)\n" "int(5)\n" "int(4)\n" "int(5)\n"); // yield within anonymous function MVCRO("f();\n" "foreach ($f() as $v) { var_dump($v); }\n", "int(1)\n" "int(2)\n"); // Continuatin::send() MVCRO("next();\n" "var_dump($c->current());\n" "$c->send(2);\n" "var_dump($c->current());\n" "$c->send(array(3, 4));\n" "var_dump($c->current());\n", "int(1)\n" "int(2)\n" "int(4)\n"); MVCRO("bar(function() {yield 1; yield 2; yield 3;});" " }" " public function bar(Closure $c) {" " $a = $c();" " foreach ($a as $b) {" " echo $b.\"\\n\";" " }" " }" "}" "$a = new A();" "$a->foo();", "1\n" "2\n" "3\n"); MVCRO("doIt();\n" " } catch (Exception $e) {\n" " $res = $e->getMessage();\n" " }\n" " yield $res;\n" "}\n" "$x = new X;\n" "foreach (f($x) as $i) { var_dump($i); }\n", "string(6) \"foobar\"\n"); MVCRO("yielder() as $foo) { var_dump($foo); }\n" "\n" "// derive from redec gen\n" "class Foo {\n" " public function fooMsg() { return 'foo'; }\n" " public function fooGen() { yield $this->fooMsg(); }\n" "}\n" "if (get()) {\n" " class Bar extends Foo {\n" " public function fooMsg() { return 'bar'; }\n" " public function barMsg() { return 'bar'; }\n" " public function barGen() { yield $this->barMsg(); }\n" " }\n" "} else {\n" " class Bar extends Foo {}\n" "}\n" "$f = new Foo;\n" "foreach ($f->fooGen() as $foo) { var_dump($foo); }\n" "$b = new Bar;\n" "foreach ($b->fooGen() as $foo) { var_dump($foo); }\n" "foreach ($b->barGen() as $foo) { var_dump($foo); }\n" "\n" "// conditional derive from redec gen\n" "function get0() { return false; }\n" "function f($x) {\n" " if ($x) {\n" " if (get0()) {\n" " class X1 {\n" " public function msg() { return 'first, first'; }\n" " public function gen() { yield $this->msg(); }\n" " } \n" " } else {\n" " class X1 {\n" " public function msg() { return 'first, second'; }\n" " public function gen() { yield $this->msg(); }\n" " } \n" " } \n" " } else {\n" " if (get()) {\n" " class Y extends X1 {\n" " public function msg() { return 'second, first'; }\n" " public function gen() { yield $this->msg(); }\n" " } \n" " } else {\n" " class Y extends X1 {\n" " public function msg() { return 'second, second'; }\n" " public function gen() { yield $this->msg(); }\n" " } \n" " } \n" " }\n" " $x = $x ? new X1 : new Y;\n" " foreach ($x->gen() as $foo) { var_dump($foo); }\n" "}\n" "f(true);\n" "f(false);\n", "string(5) \"first\"\n" "string(3) \"foo\"\n" "string(3) \"bar\"\n" "string(3) \"bar\"\n" "string(13) \"first, second\"\n" "string(13) \"second, first\"\n"); MVCRO("foo('this') as $v) { var_dump($v); }\n", "int(5)\n"); // Test passing null to hphp_get_iterator() MVCRO("gen());" "t($b->foo());" "$a = new A;" "t($a->gen());" "t($a->foo());" , "string(1) \"B\"\n" "string(1) \"B\"\n" "string(1) \"A\"\n" "string(1) \"A\"\n" "string(1) \"B\"\n" "string(1) \"B\"\n" "string(1) \"A\"\n" "string(1) \"A\"\n" "string(1) \"B\"\n" "string(1) \"B\"\n" "string(1) \"A\"\n" "string(1) \"A\"\n"); // getting the original function MVCRO("getOrigFuncName());\n" "class X {\n" " function f($x) { yield $x; }\n" " static function g($x) { yield get_called_class(); }\n" "}\n" "class Y extends X {}\n" "$x = new X;\n" "$c = $x->f(32);\n" "var_dump($c->getOrigFuncName());\n" "$c = X::g(32);\n" "var_dump($c->getOrigFuncName());\n" "$c = Y::g(32);\n" "var_dump($c->getOrigFuncName());\n" "$fcn = function ($x) { yield $x; };\n" "$c = $fcn(32);\n" "var_dump($c->getOrigFuncName());\n", "string(1) \"f\"\n" "string(4) \"X::f\"\n" "string(4) \"X::g\"\n" "string(4) \"Y::g\"\n" "string(9) \"{closure}\"\n"); MVCRO("getMessage());" " yield 4;" " }" " yield 5;" "}" "foreach (gen() as $x) { var_dump($x); }" "$g = gen();" "$g->next();" "var_dump($g->current());" "$g->next();" "var_dump($g->current());" "$g->next();" "var_dump($g->current());" "$g->raise(new Exception('foobar'));" "var_dump($g->current());" "$g->next();" "var_dump($g->current());" , "int(1)\n" "int(2)\n" "int(3)\n" "int(5)\n" "int(1)\n" "int(2)\n" "int(3)\n" "string(6) \"foobar\"\n" "int(4)\n" "int(5)\n"); MVCRO("next();" "} catch(YieldedException $e) {" " try {" " $g->raise(new ReflectedException());" " } catch (Exception $e) {" " var_dump($e->getMessage());" " }" "}" , "string(33) \"Got yieldedException, re-raising.\"\n" "string(32) \"Continuation is already finished\"\n"); MVCRO("drc[$key] = true;" " yield (true);" " }" " public function edd($key) {" " if (array_key_exists($key, $this->drc)) {" " var_dump(true);" " } " " }" "}" "class C { use DY; }" "class D extends C { }" "$obj = new D;" "foreach($obj->dty('foo') as $var) {" " var_dump($var);" "}" "$obj->edd('foo');", "bool(true)\n" "bool(true)\n"); MVCRO("gpc();" " }" "}" "class C1 {" " use T;" " protected function gpc() {" " return 1;" " }" "}" "class C2 {" " use T;" " protected function gpc() {" " return 2;" " }" "}" "$obj1 = new C1();" "$obj2 = new C2();" "$c1 = $obj1->gen();" "$c2 = $obj2->gen();" "$c1->next();" "var_dump($c1->current());" "$c2->next();" "var_dump($c2->current());", "int(1)\n" "int(2)\n"); MVCRO("foo = 1;" " }" " var_dump($results);" " yield 1;" "}" "function bar() {" " foreach (foo(array()) as $r) {" " var_dump($r);" " }" "}" "bar();", "int(0)\n" "array(0) {\n" "}\n" "int(1)\n"); MVCRO("a; }" "}" "if (isset($g)) {" " class Y {}" "} else {" " class Y extends X {}" "}" "class Z extends Y {}" "function test() {" " $z = new Z;" " foreach ($z->foo() as $v) {" " var_dump($v);" " }" "}" "test();", "array(3) {\n" " [0]=>\n" " int(1)\n" " [1]=>\n" " int(2)\n" " [2]=>\n" " int(3)\n" "}\n"); // Testing destructor/assignment corner cases MVCRO("getMessage());\n" " }\n" " }\n" "}\n" "function dumpCurrent() {\n" " var_dump($GLOBALS['cont']->current());\n" " if (isset($GLOBALS['gonext'])) {\n" " $GLOBALS['cont']->next();\n" " }\n" "}\n" "function gen() {\n" " yield new Evil;\n" " yield null;\n" " yield null;\n" " yield null;\n" "}\n" "function main() {\n" " $GLOBALS['cont'] = $c = gen();\n" " $c->next();\n" "\n" " $c->send(new Evil);\n" " $GLOBALS['gonext'] = true;\n" " $c->next();\n" " $c->send(new Evil);\n" " $c->send(null);\n" " echo \"Finished!\\n\";\n" "}\n" "main();\n" "echo \"Returned from main safely\\n\";\n" , "in __destruct()\n" "NULL\n" "in __destruct()\n" "NULL\n" "Caught: Continuation is already running\n" "in __destruct()\n" "NULL\n" "Caught: Continuation is already running\n" "Finished!\n" "Returned from main safely\n"); MVCRO("data);\n" " }\n" " public function key() {\n" " return key($this->data);\n" " }\n" " public function next() {\n" " next($this->data);\n" " }\n" " public function rewind() {\n" " echo \"hagfish\\n\";\n" " reset($this->data);\n" " }\n" " public function valid() {\n" " return current($this->data);\n" " }\n" "}\n" "\n" "function run_test() {\n" " $f = new Foo();\n" "\n" " foreach ($f as $value) {\n" " echo $value . \"\\n\";\n" " }\n" "\n" " yield 1230;\n" "\n" " foreach($f as $value) {\n" " echo $value . \"\\n\";\n" " }\n" "}\n" "\n" "foreach (run_test() as $_) {}\n", "hagfish\n1\n2\n3\nhagfish\n1\n2\n3\n"); MVCRO("next();\n" " while ($gen->valid()) {\n" " var_dump($gen->current());\n" " $gen->next();\n" " }\n" " } catch (Exception $ex) {\n" " echo \"EXCEPTION\\n\";\n" " }\n" " var_dump($gen->valid());\n" " var_dump($gen->current());\n" "}\n", "Testing mode 0:\n" "int(0)\n" "int(47)\n" "bool(false)\n" "NULL\n" "Testing mode 1:\n" "int(1)\n" "bool(false)\n" "NULL\n" "Testing mode 2:\n" "int(2)\n" "EXCEPTION\n" "bool(false)\n" "NULL\n"); return true; } bool TestCodeRun::TestHint() { MVCR("generator() as $v) {\n" " var_dump($v);\n" "}\n", "int(1)\n" "int(2)\n"); MVCRO("getMethod('f');\n" " $params = $rf->getParameters();\n" " $first = true;\n" "\n" " $clsDecl = \"class Y extends X {\npublic function f(\";\n" " foreach ($params as $rp) {\n" " if (!$first) $clsDecl .= ', ';\n" " $first = false;\n" " $th = $rp->getTypehintText();\n" " if ($th) {\n" " $clsDecl .= ($th . ' ');\n" " }\n" " $clsDecl .= ('$' . $rp->getName());\n" " if ($rp->isDefaultValueAvailable()) {\n" " $clsDecl .= (' = ' . $rp->getDefaultValueText());\n" " }\n" " }\n" " $clsDecl .= \") {}\n}\n\";\n" " echo $clsDecl;\n" "}\n" "main();\n" , "class Y extends X {\n" "public function f($x1, $x2 = NULL, $x3 = 123, string $x4, " "string $x5 = NULL, string $x6 = \"abc\", array $x7, array $x8 = NULL, " "C $x9, D $x10 = NULL, bool $x11, boolean $x12 = true, int $x13, " "integer $x14 = 73, real $x15, double $x16 = 1.5, float $x17) {}\n" "}\n" ); return true; } bool TestCodeRun::TestUserAttributes() { HipHopSyntax w(this); MVCRO(">\n" "class C extends B {\n" " public function foo() { echo \"C::foo\\n\"; }\n" " public static function bar() { echo \"C::bar\\n\"; }\n" "}\n" "function test() {\n" " $obj = new C;\n" " $obj->foo();\n" " C::bar();\n" "}\n" "test();\n" , "C::foo\n" "C::bar\n"); MVCRO("> interface I {}\n" "<< Foo2, Bar2(), Baz2('blah',array(1,2)) >> trait T {}\n" "<< Foo3, Bar3(), Baz3('blah',array(1,2)) >> function f() {}\n" "<< Foo4, Bar4(), Baz4('blah',array(1,2)) >>\n" "function g() { yield null; }\n" "class C {\n" " << Foo5, Bar5(), Baz5('blah',array(1,2)) >>\n" " public function f() {}\n" " << Foo6, Bar6(), Baz6('blah',array(1,2)) >>\n" " public function g() { yield null; }\n" "}\n" "echo \"Done\\n\";\n" , "Done\n"); MVCRO(">\n" "class C {\n" " <>\n" " function f() {}\n" "}\n" "$rc = new ReflectionClass('C');\n" "$attrs = $rc->getAttributes();\n" "ksort($attrs);\n" "var_dump($attrs);\n" "$rm = $rc->getMethod('f');\n" "$attrs = $rm->getAttributes();\n" "ksort($attrs);\n" "var_dump($attrs);\n" "\n" "<>\n" "function f() {}\n" "$rf = new ReflectionFunction('f');\n" "$attrs = $rf->getAttributes();\n" "ksort($attrs);\n" "var_dump($attrs);\n" , "array(2) {\n" " [\"A\"]=>\n" " array(1) {\n" " [0]=>\n" " int(1)\n" " }\n" " [\"B\"]=>\n" " array(2) {\n" " [0]=>\n" " string(3) \"foo\"\n" " [1]=>\n" " array(2) {\n" " [0]=>\n" " int(42)\n" " [1]=>\n" " int(73)\n" " }\n" " }\n" "}\n" "array(2) {\n" " [\"A\"]=>\n" " array(1) {\n" " [0]=>\n" " int(2)\n" " }\n" " [\"B\"]=>\n" " array(2) {\n" " [0]=>\n" " string(3) \"bar\"\n" " [1]=>\n" " array(2) {\n" " [0]=>\n" " int(43)\n" " [1]=>\n" " int(74)\n" " }\n" " }\n" "}\n" "array(2) {\n" " [\"A\"]=>\n" " array(1) {\n" " [0]=>\n" " int(3)\n" " }\n" " [\"B\"]=>\n" " array(2) {\n" " [0]=>\n" " string(3) \"bar\"\n" " [1]=>\n" " array(2) {\n" " [0]=>\n" " int(44)\n" " [1]=>\n" " int(75)\n" " }\n" " }\n" "}\n"); MVCRO(">\n" "function f() {}\n" "$rf = new ReflectionFunction('f');\n" "var_dump($rf->getAttribute('A'));\n" "var_dump($rf->getAttribute('B'));\n" "var_dump($rf->getAttributes());\n" "var_dump($rf->getAttributeRecursive('A'));\n" "var_dump($rf->getAttributeRecursive('B'));\n" "var_dump($rf->getAttributesRecursive());\n" , "array(1) {\n" " [0]=>\n" " int(1)\n" "}\n" "NULL\n" "array(1) {\n" " [\"A\"]=>\n" " array(1) {\n" " [0]=>\n" " int(1)\n" " }\n" "}\n" "array(1) {\n" " [0]=>\n" " int(1)\n" "}\n" "NULL\n" "array(1) {\n" " [\"A\"]=>\n" " array(1) {\n" " [0]=>\n" " int(1)\n" " }\n" "}\n"); MVCRO(">\n" " private function foo() {}\n" "}\n" "class B extends A {}\n" "class C extends B {\n" " <>\n" " protected function foo() {}\n" "}\n" "class D extends C {}\n" "class E extends D {\n" " <>\n" " public function foo() {}\n" "}\n" "class F extends E {}\n" "\n" "$rm = new ReflectionMethod('F', 'foo');\n" "\n" "var_dump($rm->getAttribute('W'));\n" "var_dump($rm->getAttribute('X'));\n" "var_dump($rm->getAttribute('Y'));\n" "var_dump($rm->getAttribute('Z'));\n" "\n" "$attrs = $rm->getAttributes();\n" "ksort($attrs);\n" "var_dump($attrs);\n" "\n" "var_dump($rm->getAttributeRecursive('W'));\n" "var_dump($rm->getAttributeRecursive('X'));\n" "var_dump($rm->getAttributeRecursive('Y'));\n" "var_dump($rm->getAttributeRecursive('Z'));\n" "\n" "$attrs = $rm->getAttributesRecursive();\n" "ksort($attrs);\n" "var_dump($attrs);\n" , "NULL\n" "NULL\n" "array(1) {\n" " [0]=>\n" " int(5)\n" "}\n" "array(1) {\n" " [0]=>\n" " int(6)\n" "}\n" "array(2) {\n" " [\"Y\"]=>\n" " array(1) {\n" " [0]=>\n" " int(5)\n" " }\n" " [\"Z\"]=>\n" " array(1) {\n" " [0]=>\n" " int(6)\n" " }\n" "}\n" "NULL\n" "array(1) {\n" " [0]=>\n" " int(3)\n" "}\n" "array(1) {\n" " [0]=>\n" " int(5)\n" "}\n" "array(1) {\n" " [0]=>\n" " int(6)\n" "}\n" "array(3) {\n" " [\"X\"]=>\n" " array(1) {\n" " [0]=>\n" " int(3)\n" " }\n" " [\"Y\"]=>\n" " array(1) {\n" " [0]=>\n" " int(5)\n" " }\n" " [\"Z\"]=>\n" " array(1) {\n" " [0]=>\n" " int(6)\n" " }\n" "}\n"); MVCRO("getMethod($fn);\n" "}\n" "\n" "function show($fn, $class=null) {\n" " $rf = null;\n" " if ($class) {\n" " $rf = get_rf_for_method($fn, $class);\n" " } else {\n" " $rf = new ReflectionFunction($fn);\n" " }\n" " $params = $rf->getParameters();\n" " foreach ($params as $param) {\n" " echo \"{$param->getName()}:\\n\";\n" " $attrs = $param->getAttributes();\n" " ksort($attrs);\n" " var_dump($attrs);\n" " }\n" "}\n" "\n" "function showr($fn, $class=null) {\n" " $rf = null;\n" " if ($class) {\n" " $rf = get_rf_for_method($fn, $class);\n" " } else {\n" " $rf = new ReflectionFunction($fn);\n" " }\n" " $params = $rf->getParameters();\n" " foreach ($params as $param) {\n" " echo \"{$param->getName()}:\\n\";\n" " $attrs = $param->getAttributesRecursive();\n" " ksort($attrs);\n" " var_dump($attrs);\n" " }\n" "}\n" "\n" "function doboth($fn, $class=null) {\n" " echo \">>> \";\n" " if ($class) echo \"$class::\";\n" " echo \"$fn =>\\n---- non-recursive: ----\\n\";\n" " show($fn, $class);\n" " echo \"\\n---- recursive: ----\\n\";\n" " showr($fn, $class);\n" " echo \"\\n\";\n" "}\n" "\n" "//------------------------\n" "\n" "function no_attrs($p1, $p2) {}\n" "function simple_attr(<> $param) {}\n" "function two_attrs(<> $p1, <> $p2) {}\n" "\n" "class C {\n" " public static function m(<> $param) {}\n" " public static function n(<> $param) {}\n" " public function o(<> $param) {}\n" " public function p(<> $param) {}\n" " public function q(<> $tuv) {}\n" " public function wxy(<> $z, <> $wont_you_sing_with_me) {}\n" "}\n" "\n" "class D extends C {\n" " // Static functions shouldn't care about the parent class\n" " public static function m($param) {}\n" "\n" " // TODO: should we include n, and should m's attrs inherit from C::m?\n" "\n" " // Changing the value of the attribute\n" " public function o(<> $param) {}\n" "\n" " // Changing the name of the parameter\n" " public function q($rstuv) {}\n" "\n" " // Adding an attribute and leaving one off\n" " public function wxy(<> $z, $wont_you_sing_with_me) {}\n" "}\n" "\n" "//------------------------\n" "\n" "doboth('no_attrs');\n" "doboth('simple_attr');\n" "doboth('two_attrs');\n" "doboth('m', 'C');\n" "doboth('n', 'C');\n" "doboth('o', 'C');\n" "doboth('p', 'C');\n" "doboth('q', 'C');\n" "doboth('wxy', 'C');\n" "doboth('m', 'D');\n" "doboth('n', 'D');\n" "doboth('o', 'D');\n" "doboth('p', 'D');\n" "doboth('q', 'D');\n" "doboth('wxy', 'D');" , ">>> no_attrs =>\n" "---- non-recursive: ----\n" "p1:\n" "array(0) {\n" "}\n" "p2:\n" "array(0) {\n" "}\n" "\n" "---- recursive: ----\n" "p1:\n" "array(0) {\n" "}\n" "p2:\n" "array(0) {\n" "}\n" "\n" ">>> simple_attr =>\n" "---- non-recursive: ----\n" "param:\n" "array(1) {\n" " [\"Attribute\"]=>\n" " array(0) {\n" " }\n" "}\n" "\n" "---- recursive: ----\n" "param:\n" "array(1) {\n" " [\"Attribute\"]=>\n" " array(0) {\n" " }\n" "}\n" "\n" ">>> two_attrs =>\n" "---- non-recursive: ----\n" "p1:\n" "array(1) {\n" " [\"Attr1\"]=>\n" " array(0) {\n" " }\n" "}\n" "p2:\n" "array(1) {\n" " [\"Attr2\"]=>\n" " array(0) {\n" " }\n" "}\n" "\n" "---- recursive: ----\n" "p1:\n" "array(1) {\n" " [\"Attr1\"]=>\n" " array(0) {\n" " }\n" "}\n" "p2:\n" "array(1) {\n" " [\"Attr2\"]=>\n" " array(0) {\n" " }\n" "}\n" "\n" ">>> C::m =>\n" "---- non-recursive: ----\n" "param:\n" "array(1) {\n" " [\"Attr\"]=>\n" " array(3) {\n" " [0]=>\n" " int(1)\n" " [1]=>\n" " int(2)\n" " [2]=>\n" " int(3)\n" " }\n" "}\n" "\n" "---- recursive: ----\n" "param:\n" "array(1) {\n" " [\"Attr\"]=>\n" " array(3) {\n" " [0]=>\n" " int(1)\n" " [1]=>\n" " int(2)\n" " [2]=>\n" " int(3)\n" " }\n" "}\n" "\n" ">>> C::n =>\n" "---- non-recursive: ----\n" "param:\n" "array(2) {\n" " [\"Bar\"]=>\n" " array(0) {\n" " }\n" " [\"Foo\"]=>\n" " array(0) {\n" " }\n" "}\n" "\n" "---- recursive: ----\n" "param:\n" "array(2) {\n" " [\"Bar\"]=>\n" " array(0) {\n" " }\n" " [\"Foo\"]=>\n" " array(0) {\n" " }\n" "}\n" "\n" ">>> C::o =>\n" "---- non-recursive: ----\n" "param:\n" "array(1) {\n" " [\"Hi\"]=>\n" " array(1) {\n" " [0]=>\n" " string(3) \"bye\"\n" " }\n" "}\n" "\n" "---- recursive: ----\n" "param:\n" "array(1) {\n" " [\"Hi\"]=>\n" " array(1) {\n" " [0]=>\n" " string(3) \"bye\"\n" " }\n" "}\n" "\n" ">>> C::p =>\n" "---- non-recursive: ----\n" "param:\n" "array(2) {\n" " [\"A\"]=>\n" " array(2) {\n" " [0]=>\n" " string(1) \"b\"\n" " [1]=>\n" " array(2) {\n" " [0]=>\n" " string(1) \"c\"\n" " [1]=>\n" " string(1) \"d\"\n" " }\n" " }\n" " [\"E\"]=>\n" " array(1) {\n" " [0]=>\n" " string(2) \"fg\"\n" " }\n" "}\n" "\n" "---- recursive: ----\n" "param:\n" "array(2) {\n" " [\"A\"]=>\n" " array(2) {\n" " [0]=>\n" " string(1) \"b\"\n" " [1]=>\n" " array(2) {\n" " [0]=>\n" " string(1) \"c\"\n" " [1]=>\n" " string(1) \"d\"\n" " }\n" " }\n" " [\"E\"]=>\n" " array(1) {\n" " [0]=>\n" " string(2) \"fg\"\n" " }\n" "}\n" "\n" ">>> C::q =>\n" "---- non-recursive: ----\n" "tuv:\n" "array(1) {\n" " [\"RS\"]=>\n" " array(0) {\n" " }\n" "}\n" "\n" "---- recursive: ----\n" "tuv:\n" "array(1) {\n" " [\"RS\"]=>\n" " array(0) {\n" " }\n" "}\n" "\n" ">>> C::wxy =>\n" "---- non-recursive: ----\n" "z:\n" "array(1) {\n" " [\"And_\"]=>\n" " array(0) {\n" " }\n" "}\n" "wont_you_sing_with_me:\n" "array(1) {\n" " [\"NextTime\"]=>\n" " array(0) {\n" " }\n" "}\n" "\n" "---- recursive: ----\n" "z:\n" "array(1) {\n" " [\"And_\"]=>\n" " array(0) {\n" " }\n" "}\n" "wont_you_sing_with_me:\n" "array(1) {\n" " [\"NextTime\"]=>\n" " array(0) {\n" " }\n" "}\n" "\n" ">>> D::m =>\n" "---- non-recursive: ----\n" "param:\n" "array(0) {\n" "}\n" "\n" "---- recursive: ----\n" "param:\n" "array(1) {\n" " [\"Attr\"]=>\n" " array(3) {\n" " [0]=>\n" " int(1)\n" " [1]=>\n" " int(2)\n" " [2]=>\n" " int(3)\n" " }\n" "}\n" "\n" ">>> D::n =>\n" "---- non-recursive: ----\n" "param:\n" "array(2) {\n" " [\"Bar\"]=>\n" " array(0) {\n" " }\n" " [\"Foo\"]=>\n" " array(0) {\n" " }\n" "}\n" "\n" "---- recursive: ----\n" "param:\n" "array(2) {\n" " [\"Bar\"]=>\n" " array(0) {\n" " }\n" " [\"Foo\"]=>\n" " array(0) {\n" " }\n" "}\n" "\n" ">>> D::o =>\n" "---- non-recursive: ----\n" "param:\n" "array(1) {\n" " [\"Hi\"]=>\n" " array(1) {\n" " [0]=>\n" " string(5) \"hello\"\n" " }\n" "}\n" "\n" "---- recursive: ----\n" "param:\n" "array(1) {\n" " [\"Hi\"]=>\n" " array(1) {\n" " [0]=>\n" " string(5) \"hello\"\n" " }\n" "}\n" "\n" ">>> D::p =>\n" "---- non-recursive: ----\n" "param:\n" "array(2) {\n" " [\"A\"]=>\n" " array(2) {\n" " [0]=>\n" " string(1) \"b\"\n" " [1]=>\n" " array(2) {\n" " [0]=>\n" " string(1) \"c\"\n" " [1]=>\n" " string(1) \"d\"\n" " }\n" " }\n" " [\"E\"]=>\n" " array(1) {\n" " [0]=>\n" " string(2) \"fg\"\n" " }\n" "}\n" "\n" "---- recursive: ----\n" "param:\n" "array(2) {\n" " [\"A\"]=>\n" " array(2) {\n" " [0]=>\n" " string(1) \"b\"\n" " [1]=>\n" " array(2) {\n" " [0]=>\n" " string(1) \"c\"\n" " [1]=>\n" " string(1) \"d\"\n" " }\n" " }\n" " [\"E\"]=>\n" " array(1) {\n" " [0]=>\n" " string(2) \"fg\"\n" " }\n" "}\n" "\n" ">>> D::q =>\n" "---- non-recursive: ----\n" "rstuv:\n" "array(0) {\n" "}\n" "\n" "---- recursive: ----\n" "rstuv:\n" "array(1) {\n" " [\"RS\"]=>\n" " array(0) {\n" " }\n" "}\n" "\n" ">>> D::wxy =>\n" "---- non-recursive: ----\n" "z:\n" "array(1) {\n" " [\"EnglishPeopleCallThisZed\"]=>\n" " array(0) {\n" " }\n" "}\n" "wont_you_sing_with_me:\n" "array(0) {\n" "}\n" "\n" "---- recursive: ----\n" "z:\n" "array(2) {\n" " [\"And_\"]=>\n" " array(0) {\n" " }\n" " [\"EnglishPeopleCallThisZed\"]=>\n" " array(0) {\n" " }\n" "}\n" "wont_you_sing_with_me:\n" "array(1) {\n" " [\"NextTime\"]=>\n" " array(0) {\n" " }\n" "}\n" "\n"); return true; } #ifdef TAINTED #define INIT_TEST_TAINT_HELPERS \ "$taint_counter = 0;\n" \ "function assert_tainted($str, $taint) {\n" \ " global $taint_counter;\n" \ " if (!fb_get_taint($str, $taint)) {\n" \ " var_dump($taint_counter);\n" \ " }\n" \ " $taint_counter++;" \ "}\n" \ "function assert_not_tainted($str, $taint) {\n" \ " global $taint_counter;\n" \ " if (fb_get_taint($str, $taint)) {\n" \ " var_dump($taint_counter);\n" \ " }\n" \ " $taint_counter++;" \ "}\n" // We reconstruct our strings to ensure they aren't ever treated as // literals by hphp. #define INIT_TEST_TAINT_STRINGS \ "$tmp = \"heLlO\\nworld\\ntoto\\narent\\ntaTa\";\n" \ "$good1 = '';\n" \ "for ($i = 0; $i < strlen($tmp); $i++) {\n" \ " $good1 .= $tmp[$i];\n" \ "}\n" \ "$tmp = 'world';\n" \ "$good2 = '';\n" \ "for ($i = 0; $i < strlen($tmp); $i++) {\n" \ " $good2 .= $tmp[$i];\n" \ "}\n" \ "$tmp = \"eViL\\nsTring\\nare\\tfun\\narent\\tworld?\";\n" \ "$bad1 = '';\n" \ "for ($i = 0; $i < strlen($tmp); $i++) {\n" \ " $bad1 .= $tmp[$i];\n" \ "}\n" \ "$tmp = 'arent';\n" \ "$bad2 = '';\n" \ "for ($i = 0; $i < strlen($tmp); $i++) {\n" \ " $bad2 .= $tmp[$i];\n" \ "}\n" \ "unset($tmp);\n" \ "fb_set_taint($bad1, TAINT_ALL);\n" \ "fb_set_taint($bad2, TAINT_ALL);\n" bool TestCodeRun::TestTaint() { HipHopSyntax w(this); // Literals and assignments MVCRO("m_a = $a;\n" " $this->m_b = $b;\n" " }\n" " function test() {\n" " var_dump(fb_get_taint($this->m_a, TAINT_ALL));\n" " var_dump(fb_get_taint($this->m_b, TAINT_ALL));\n" " }\n" "}\n" "$foo = new Foo($a, $b);\n" "$foo->test();\n" "var_dump(fb_get_taint(Foo::FOO, TAINT_ALL));\n" , "bool(false)\n" "bool(true)\n" "bool(false)\n" "bool(true)\n" "bool(false)\n" "bool(true)\n" "bool(false)\n"); // Copy-on-taint and taint independence MVCRO("'foo');\n" "$tmp = 'qqq';\n" "$b = '';\n" "for ($i = 0; $i < strlen($tmp); $i++) {\n" " $b .= $tmp[$i];\n" "}\n" "unset($tmp);\n" "class c {}\n" "$c = new c;\n" "$c->p = 'zzz';\n" "assert_not_tainted(\"AAA ${a['x']} $a[x] $b $c->p\", TAINT_ALL);\n" "fb_set_taint($b, TAINT_ALL);\n" "assert_tainted(\"AAA ${a['x']} $a[x] $b $c->p\", TAINT_ALL);\n" "class X {\n" " static function g() {}\n" "};\n" "$tmp = 'efg';\n" "$a = '';\n" "for ($i = 0; $i < strlen($tmp); $i++) {\n" " $a .= $tmp[$i];\n" "}\n" "unset($tmp);\n" "$b = rand() % 42;\n" "assert_tainted('abc' . X::g() . $b . $a, TAINT_ALL);\n" "fb_set_taint($a, TAINT_ALL);\n" "assert_tainted('abc' . X::g() . 42 . $a, TAINT_ALL);\n" "assert_tainted('abc' . X::g() . $b . $a, TAINT_ALL);\n" "function f() {\n" " $tmp = 'x';\n" " $a = '';\n" " for ($i = 0; $i < strlen($tmp); $i++) {\n" " $a .= $tmp[$i];\n" " }\n" " unset($tmp);\n" " fb_set_taint($a, TAINT_ALL);\n" " return $a;\n" "}\n" "function g() {}\n" "function test1($a) {\n" " $buf = '';\n" " foreach ($a as $s) {\n" " $buf .= f() . g() . 'h' . f() . 'h' . g();\n" " }\n" " foreach ($a as $s) {\n" " $buf .= ($s . 'h' . $s);\n" " }\n" " return $buf;\n" "}\n" "assert_tainted(test1(array(1)), TAINT_ALL);\n" "function test2() {\n" " return f() . g() . f() . g();\n" "}\n" "assert_tainted(test2(), TAINT_ALL);\n" "function test3() {\n" " return f() . g() . f() . g() . f() . g() . f() . g() . f();\n" "}\n" "assert_tainted(test3(), TAINT_ALL);\n" "function test4() {\n" " $s = f();\n" " $s .=\n" " ('foo'.\n" " 'bar'.\n" " f().\n" " 'foo'.\n" " 'baz'.\n" " f().\n" " 'fuz'.\n" " 'boo'.\n" " f().\n" " 'fiz'.\n" " 'faz');\n" " $s .= f();\n" " return $s;\n" "}\n" "assert_tainted(test4(), TAINT_ALL);\n" "function test6() {\n" " return g().f().g();\n" "}\n" "assert_tainted(test6(), TAINT_ALL);\n", ""); // Arrays MVCRO(" $good2,\n" " $bad1 => $bad2,\n" " $bad2 => array(\n" " $good2 => $bad2,\n" " $bad2 => $good3,\n" " ),\n" ");\n" "assert_not_tainted($arr, TAINT_ALL);\n" "assert_tainted(print_r($arr, true), TAINT_ALL);\n" "assert_not_tainted($arr[$good1], TAINT_ALL);\n" "assert_tainted($arr[$bad1], TAINT_ALL);\n" "assert_not_tainted($arr[$bad2], TAINT_ALL);\n" "assert_tainted(print_r($arr[$bad2], true), TAINT_ALL);\n" "assert_tainted($arr[$bad2][$good2], TAINT_ALL);\n" "assert_not_tainted($arr[$bad2][$bad2], TAINT_ALL);\n" "$keys = array_keys($arr);\n" "assert_not_tainted($keys[0], TAINT_ALL);\n" "assert_tainted($keys[1], TAINT_ALL);\n" "assert_tainted($keys[2], TAINT_ALL);\n", ""); // Typecasts MVCRO(" rand(),\n" " $a => 'barbaz',\n" ");\n" "var_dump(fb_get_taint($arr, TAINT_ALL));\n" "var_dump(fb_get_taint($arr['foostr'], TAINT_ALL));\n" "var_dump(fb_get_taint($arr[$a], TAINT_ALL));\n" "class CleanObj {\n" " function __toString() { return 'obj'; }\n" "}\n" "class TaintedObj {\n" " function __toString() {\n" " $bad1 = \"eViL\\nsTring\\nare\\tfun\\narent\\tthey?\";\n" " fb_set_taint($bad1, TAINT_MUTATED);\n" " return 'obj' . $bad1;\n" " }\n" "}\n" "$obj1 = new CleanObj();\n" "var_dump(fb_get_taint($obj1, TAINT_MUTATED));\n" "$obj2 = new TaintedObj();\n" "var_dump(fb_get_taint($obj2, TAINT_MUTATED));\n", "bool(false)\n" "bool(false)\n" "bool(false)\n" "bool(true)\n" "bool(true)\n" "bool(false)\n" "bool(false)\n" "bool(false)\n" "bool(false)\n" "bool(false)\n" "bool(false)\n" "bool(true)\n" "bool(true)\n" "bool(true)\n" "bool(true)\n" "bool(false)\n" "bool(true)\n" "bool(false)\n" "bool(false)\n" "bool(true)\n"); // Tokens MVCRO("foostr();\n" "foostr::staticFoostr();\n", "bool(false)\n" "bool(true)\n" "bool(false)\n" "bool(false)\n" "bool(false)\n" "bool(false)\n" "bool(false)\n"); // Closures MVCRO(" $v) {\n" " if ($check_key) {\n" " var_dump(fb_get_taint($k, TAINT_ALL));\n" " }\n" " if ($check_val) {\n" " var_dump(fb_get_taint($v, TAINT_ALL));\n" " }\n" " }\n" "}\n" "$mixed_arr = array(\n" " $bad3 => $good1,\n" " $good3 => $bad1,\n" " $good4 => $good2,\n" " $bad4 => $bad2,\n" ");\n" "$num_arr = array($good1, $bad1, $good2, $bad2);\n" "$arr = array_change_key_case($mixed_arr);\n" "foreach ($arr as $k => $v) {\n" " var_dump(fb_get_taint($k, TAINT_HTML));\n" " var_dump(fb_get_taint($k, TAINT_MUTATED));\n" " var_dump(fb_get_taint($v, TAINT_ALL));\n" "}\n" "$arr = array_chunk($mixed_arr, 2, true);\n" "check_array($arr[0]);\n" "check_array($arr[1]);\n" "check_array(array_combine(\n" " array($bad3, $good3, $good4, $bad4),\n" " $num_arr\n" "));\n" "check_array(array_count_values($mixed_arr), true, false);\n" "check_array(array_fill_keys($num_arr, $bad1));\n" "check_array(array_fill(0, 2, $good1), false);\n" "check_array(array_fill(0, 2, $bad1), false);\n" "check_array(array_filter(\n" " $mixed_arr,\n" " function($str) { return strlen($str) < 42; }\n" "));\n" "check_array(array_flip($mixed_arr));\n" "check_array(array_keys($mixed_arr), false);\n" "check_array(array_map(\n" " function($str) { return $str . $str; },\n" " $mixed_arr\n" "));\n" "$arr = array_chunk($mixed_arr, 2, true);\n" "check_array(array_merge($arr[0], $arr[1]));\n" "check_array(array_replace(\n" " $mixed_arr,\n" " array(\n" " $bad3 => $bad1,\n" " $good3 => $bad2,\n" " $good4 => $good1,\n" " $bad4 => $good2,\n" " )\n" "));\n" "check_array(array_pad($mixed_arr, 5, $good1));\n" "check_array(array_pad($mixed_arr, 5, $bad1));\n" "$arr = $num_arr;\n" "$v = array_pop($arr);\n" "$u = array_pop($arr);\n" "check_array($arr, false);\n" "var_dump(fb_get_taint($u, TAINT_ALL));\n" "var_dump(fb_get_taint($v, TAINT_ALL));\n" "array_push($arr, $u);\n" "array_push($arr, $v);\n" "check_array($arr, false);\n" "var_dump(fb_get_taint(array_reduce(\n" " $mixed_arr,\n" " function($a, $b) { return $a . $b; },\n" " ''\n" "), TAINT_ALL));\n" "check_array(array_reverse($mixed_arr));\n" "var_dump(fb_get_taint(array_search($good1, $mixed_arr), TAINT_ALL));\n" "var_dump(fb_get_taint(array_search($bad1, $mixed_arr), TAINT_ALL));\n" "var_dump(fb_get_taint(array_search($good2, $mixed_arr), TAINT_ALL));\n" "var_dump(fb_get_taint(array_search($bad2, $mixed_arr), TAINT_ALL));\n" "$arr = $num_arr;\n" "$v = array_shift($arr);\n" "$u = array_shift($arr);\n" "var_dump(fb_get_taint($v, TAINT_ALL));\n" "var_dump(fb_get_taint($u, TAINT_ALL));\n" "check_array($arr, false);\n" "array_unshift($arr, $u);\n" "array_unshift($arr, $v);\n" "check_array($arr, false);\n" "check_array(array_slice($mixed_arr, 0, 4), false);\n" "check_array(array_slice($mixed_arr, 0, 4, true));\n" "$arr = $mixed_arr;\n" "$ins = array_splice($arr, 1, 2);\n" "array_splice($arr, 1, 0, $ins);\n" "check_array($arr, false);\n" "check_array(array_values($mixed_arr), false);\n" "$arr = $mixed_arr;\n" "array_walk(\n" " $arr,\n" " function ($v, $k, $x) { $v .= $x; $k .= $x; },\n" " 'foobar'\n" ");\n" "check_array($arr);\n" "check_array(compact('bad3', 'good3', 'good4', 'bad4'), false);\n" "check_array(array_diff($num_arr, array_slice($num_arr, 0, 2)), false);\n" "check_array(array_diff($num_arr, array_slice($num_arr, 2, 2)), false);\n" "check_array(array_diff_key(\n" " array_flip($mixed_arr),\n" " array_flip(array_slice($mixed_arr, 2, 2))\n" "), false);\n" "check_array(array_diff_key(\n" " array_flip($mixed_arr),\n" " array_flip(array_slice($mixed_arr, 0, 2))\n" "), false);\n" "check_array(array_intersect($mixed_arr, $num_arr), false);\n" "check_array(array_intersect_key(\n" " array_flip($mixed_arr),\n" " array_flip($num_arr)\n" "), false);\n" "$arr = $mixed_arr;\n" "sort($arr);\n" "check_array($arr, false);\n" "asort($mixed_arr);\n" "check_array($mixed_arr);\n" "ksort($mixed_arr);\n" "check_array($mixed_arr);\n", // array_change_key_case "bool(true)\n" "bool(true)\n" "bool(false)\n" "bool(false)\n" "bool(true)\n" "bool(true)\n" "bool(false)\n" "bool(true)\n" "bool(false)\n" "bool(true)\n" "bool(true)\n" "bool(true)\n" // array_chunk TEST_TAINT_EXT_ARRAY_STD_TAINTS // array_combine TEST_TAINT_EXT_ARRAY_STD_TAINTS // array_count_values TEST_TAINT_EXT_ARRAY_VAL_TAINTS // array_fill_keys "bool(false)\n" "bool(true)\n" "bool(true)\n" "bool(true)\n" "bool(false)\n" "bool(true)\n" "bool(true)\n" "bool(true)\n" // array_fill "bool(false)\n" "bool(false)\n" "bool(true)\n" "bool(true)\n" // array_filter TEST_TAINT_EXT_ARRAY_STD_TAINTS // array_flip "bool(false)\n" "bool(true)\n" "bool(true)\n" "bool(false)\n" "bool(false)\n" "bool(false)\n" "bool(true)\n" "bool(true)\n" // array_keys TEST_TAINT_EXT_ARRAY_KEY_TAINTS // array_map TEST_TAINT_EXT_ARRAY_STD_TAINTS // array_merge TEST_TAINT_EXT_ARRAY_STD_TAINTS // array_replace "bool(true)\n" "bool(true)\n" "bool(false)\n" "bool(true)\n" "bool(false)\n" "bool(false)\n" "bool(true)\n" "bool(false)\n" // array_pad TEST_TAINT_EXT_ARRAY_STD_TAINTS "bool(true)\n" "bool(false)\n" TEST_TAINT_EXT_ARRAY_STD_TAINTS "bool(true)\n" "bool(true)\n" // array_pop TEST_TAINT_EXT_ARRAY_VAL_TAINTS // array_push TEST_TAINT_EXT_ARRAY_VAL_TAINTS // array_reduce "bool(true)\n" // array_reverse "bool(true)\n" "bool(true)\n" "bool(false)\n" "bool(false)\n" "bool(false)\n" "bool(true)\n" "bool(true)\n" "bool(false)\n" // array_search TEST_TAINT_EXT_ARRAY_KEY_TAINTS // array_shift TEST_TAINT_EXT_ARRAY_VAL_TAINTS // array_unshift TEST_TAINT_EXT_ARRAY_VAL_TAINTS // array_slice TEST_TAINT_EXT_ARRAY_VAL_TAINTS TEST_TAINT_EXT_ARRAY_STD_TAINTS // array_splice TEST_TAINT_EXT_ARRAY_VAL_TAINTS // array_values TEST_TAINT_EXT_ARRAY_VAL_TAINTS // array_walk TEST_TAINT_EXT_ARRAY_STD_TAINTS // compact TEST_TAINT_EXT_ARRAY_KEY_TAINTS // array_diff TEST_TAINT_EXT_ARRAY_VAL_TAINTS // array_diff_key TEST_TAINT_EXT_ARRAY_KEY_TAINTS // array_intersect TEST_TAINT_EXT_ARRAY_VAL_TAINTS // array_intersect_key TEST_TAINT_EXT_ARRAY_KEY_TAINTS // sort "bool(true)\n" "bool(true)\n" "bool(false)\n" "bool(false)\n" // asort "bool(true)\n" "bool(true)\n" "bool(false)\n" "bool(true)\n" "bool(true)\n" "bool(false)\n" "bool(false)\n" "bool(false)\n" // ksort "bool(true)\n" "bool(true)\n" "bool(false)\n" "bool(true)\n" "bool(true)\n" "bool(false)\n" "bool(false)\n" "bool(false)\n"); #undef TEST_TAINT_EXT_ARRAY_VAL_RESULT #undef TEST_TAINT_EXT_ARRAY_KEY_RESULT #undef TEST_TAINT_EXT_ARRAY_STD_RESULT /** * BC Math * * bc{add, sub, mul, div, pow, mod, powmod, sqrt}: These taint with the * same semantics as concatenation; that is, they propagate taint only * and do not mutate. * * The remaining functions, bcscale and bccomp, have no need for taint. */ MVCRO("good = $good1;\n" " $this->bad = $bad1;\n" " }\n" " public function foo() { }\n" "}\n" "$a = new Foo();\n" "$arr = get_object_vars($a);\n" "assert_not_tainted($arr['good'], TAINT_ALL);\n" "assert_tainted($arr['bad'], TAINT_ALL);\n", ""); /** * Closure * Continuation * Ctype * * No functions are defined in closure, only object creation helpers * are defined in continuation, and character typing doesn't produce * any output; none of these need taint. */ /** * Curl * * Functions such as curl_exec() and curl_getinfo() return fully tainted * strings; all remaining functions have no need for taint. */ MVCRO("name, TAINT_HTML);\n" "$res = mysql_query('SELECT * FROM test');\n" "$ret = mysql_result($res, 0, 'name');\n" "assert_tainted($ret, TAINT_HTML);\n" "$ret = mysql_result($res, 0, 'name');\n" "assert_tainted($ret, TAINT_HTML);\n" "$ret = mysql_fetch_field($res, 1);\n" "assert_tainted($ret->name, TAINT_HTML);\n" "$ret = mysql_field_name($res, 1);\n" "assert_tainted($ret, TAINT_HTML);\n" "$ret = mysql_field_table($res, 1);\n" "assert_tainted($ret, TAINT_HTML);\n" "mysql_query('DROP TABLE test');\n", ""); /** * Network (TODO) */ /** * OpenSSL (TODO) */ /** * Option * * get_defined_constants: Taint is passed by reference. * * The remaining functions are control functions not requiring taint. */ MVCRO(" $good1);\n" "$mixed_arr = array($good2 => $bad1, $bad2 => $good1);\n" "$bad_arr = array($bad2 => $bad1);\n" "var_dump(fb_get_taint(strval($good1), TAINT_ALL));\n" "var_dump(fb_get_taint(strval($bad1), TAINT_ALL));\n" "var_dump(fb_get_taint(print_r($good1, true), TAINT_ALL));\n" "var_dump(fb_get_taint(print_r($bad1, true), TAINT_ALL));\n" "var_dump(fb_get_taint(print_r($good_arr, true), TAINT_ALL));\n" "var_dump(fb_get_taint(print_r($mixed_arr, true), TAINT_ALL));\n" "var_dump(fb_get_taint(print_r($bad_arr, true), TAINT_ALL));\n" "var_dump(fb_get_taint(var_export($good1, true), TAINT_ALL));\n" "var_dump(fb_get_taint(var_export($bad1, true), TAINT_ALL));\n" "var_dump(fb_get_taint(var_export($good_arr, true), TAINT_ALL));\n" "var_dump(fb_get_taint(var_export($mixed_arr, true), TAINT_ALL));\n" "var_dump(fb_get_taint(var_export($bad_arr, true), TAINT_ALL));\n" "ob_start();\n" "var_export($good1);\n" "var_dump(fb_get_taint(ob_get_clean(), TAINT_ALL));\n" "ob_start();\n" "var_export($bad1);\n" "var_dump(fb_get_taint(ob_get_clean(), TAINT_ALL));\n" "ob_start();\n" "var_dump($good1);\n" "var_dump(fb_get_taint(ob_get_clean(), TAINT_ALL));\n" "ob_start();\n" "var_dump($bad1);\n" "var_dump(fb_get_taint(ob_get_clean(), TAINT_ALL));\n" "ob_start();\n" "debug_zval_dump($good1);\n" "var_dump(fb_get_taint(ob_get_clean(), TAINT_ALL));\n" "ob_start();\n" "debug_zval_dump($bad1);\n" "var_dump(fb_get_taint(ob_get_clean(), TAINT_ALL));\n" "var_dump(fb_get_taint(serialize($good1), TAINT_HTML));\n" "var_dump(fb_get_taint(serialize($good1), TAINT_MUTATED));\n" "var_dump(fb_get_taint(serialize($bad1), TAINT_HTML));\n" "var_dump(fb_get_taint(serialize($bad1), TAINT_MUTATED));\n" "var_dump(fb_get_taint(unserialize($serialized_good), TAINT_HTML));\n" "var_dump(fb_get_taint(unserialize($serialized_good), TAINT_MUTATED));\n" "var_dump(fb_get_taint(unserialize($serialized_bad), TAINT_HTML));\n" "var_dump(fb_get_taint(unserialize($serialized_bad), TAINT_MUTATED));\n" "$arr = get_defined_vars();\n" "var_dump(fb_get_taint($arr['good1'], TAINT_ALL));\n" "var_dump(fb_get_taint($arr['bad1'], TAINT_ALL));\n" "$arr = array(\n" " 'good1' => $good1,\n" " 'bad1' => $bad1,\n" ");\n" "extract($arr, EXTR_PREFIX_ALL, 'extract');\n" "var_dump(fb_get_taint($extract_good1, TAINT_ALL));\n" "var_dump(fb_get_taint($extract_bad1, TAINT_ALL));\n", "bool(false)\n" "bool(true)\n" "bool(false)\n" "bool(true)\n" "bool(false)\n" "bool(true)\n" "bool(true)\n" "bool(false)\n" "bool(true)\n" "bool(false)\n" "bool(true)\n" "bool(true)\n" "bool(false)\n" "bool(true)\n" "bool(false)\n" "bool(true)\n" "bool(false)\n" "bool(true)\n" "bool(false)\n" "bool(true)\n" "bool(true)\n" "bool(true)\n" "bool(false)\n" "bool(true)\n" "bool(true)\n" "bool(true)\n" "bool(false)\n" "bool(true)\n" "bool(false)\n" "bool(true)\n"); /** * XML (TODO) * XMLReader (TODO) * XMLWriter (TODO) */ /** * zlib (TODO) */ return true; } #endif bool TestCodeRun::TestParser() { MVCRO("a = function ($x) { echo '!' . $x; };\n" "($foo->a)(\"foo\\n\");\n" "Foo::$b = function ($x) { echo '?' . $x; };\n" "(Foo::$b)(\"bar\\n\");\n" "Foo::$c[0] = function ($x) { echo '.' . $x; };\n" "(Foo::$c[0])(\"baz\\n\");\n" , "!foo\n" "?bar\n" ".baz\n" ); MVCRO("prop = 3;\n" "var_dump($c->prop);\n" , "int(1)\n" "int(2)\n" "int(3)\n" ); return true; } bool TestCodeRun::TestTypeAssertions() { MVCR(" 1)));\n"); MVCR("x)) {\n" " var_dump($x->x);\n" " }\n" " if ($x instanceof Y && isset($x->y)) {\n" " var_dump($x->y);\n" " }\n" " if (is_a($x, 'X1')) {\n" " var_dump($x->x);\n" " }\n" "}\n" "f(null);\n" "f(new X);\n" "f(new Y);\n" "f(new X1);\n" "f(new stdClass());\n"); MVCR("container = $container;\n" " }\n" " public function offsetSet($offset, $value) {\n" " if (is_null($offset)) {\n" " $this->container[] = $value;\n" " } else {\n" " $this->container[$offset] = $value;\n" " } \n" " }\n" " public function offsetExists($offset) {\n" " return isset($this->container[$offset]);\n" " }\n" " public function offsetUnset($offset) {\n" " unset($this->container[$offset]);\n" " }\n" " public function offsetGet($offset) {\n" " return isset($this->container[$offset]) ?\n" " $this->container[$offset] : null;\n" " }\n" "}\n" "$x = new X(array(0, 1, 2));\n" "f($x);\n" "f(array(0, 1, 2));\n" "g($x);\n" "g(array(0, 1, 2));\n" "h(array(0, 1, 2));\n" "h('foobar');\n" "h(new stdClass());\n" "var_dump(i($x));\n" "var_dump(i(array(0, 1, 2)));\n"); MVCR("f();\n" " }\n" " if ($x instanceof X) {\n" " $x->f();\n" " }\n" " if ($x instanceof Y) {\n" " $x->f();\n" " }\n" "}\n" "f(new Base);\n" "f(new X);\n" "f(new Y);\n"); MVCR("bar();\n" " $this->baz();\n" " var_dump($this->propX);\n" " return $this->propY;\n" " }\n" " return null;\n" " }\n" "}\n" "class Y extends X {\n" " public $propY;\n" " function bar(){\n" " echo 'Y';\n" " }\n" "}\n" "$y = new Y;\n" "$y->propX = 16;\n" "$y->propY = 32;\n" "var_dump($y->foo());\n" "class A1 {\n" " public $a1prop;\n" " function a1method() {\n" " return 0;\n" " }\n" " function doStuff() {\n" " if ($this instanceof D1) {\n" " var_dump($this->d1prop);\n" " var_dump($this->d1method());\n" " } else if ($this instanceof C1) {\n" " var_dump($this->c1prop);\n" " var_dump($this->c1method());\n" " } else if ($this instanceof B1) {\n" " var_dump($this->b1prop);\n" " var_dump($this->b1method());\n" " } else if ($this instanceof A1) {\n" " var_dump($this->a1prop);\n" " var_dump($this->a1method());\n" " }\n" " }\n" "}\n" "class B1 extends A1 {\n" " public $b1prop;\n" " function b1method() {\n" " return 1;\n" " }\n" "}\n" "if (rand(0, 1)) {\n" " class C1 extends B1 {\n" " public $c1prop;\n" " function c1method() {\n" " return 2;\n" " }\n" " }\n" "} else {\n" " class C1 extends B1 {\n" " public $c1prop;\n" " function c1method() {\n" " return 2;\n" " }\n" " }\n" "}\n" "class D1 extends C1 {\n" " public $d1prop;\n" " function d1method() {\n" " return 3;\n" " }\n" "}\n" "$a1 = new A1;\n" "$a1->a1prop = 0;\n" "$a1->doStuff();\n" "$b1 = new B1;\n" "$b1->b1prop = 1;\n" "$b1->doStuff();\n" "$c1 = new C1;\n" "$c1->c1prop = 2;\n" "$c1->doStuff();\n" "$d1 = new D1;\n" "$d1->d1prop = 3;\n" "$d1->doStuff();\n"); MVCR("\n" , "" ); MVCRO( "sayHello();\n" "?>\n\n" , "Hello World!\n" ); MVCRO( "sayHello();\n" "?>\n" , "Hello Universe!\n" ); MVCRO( "sayHello();\n" "$o->sayWorld();\n" "$o->sayExclamationMark();\n" , "Hello World!\n" ); MVCRO( "sayHello();\n" "$o->sayWorld();\n" "$o->sayExclamationMark();\n" , "Hello World!\n" ); MVCRO( "sayHello();\n" " echo 'World!';\n" " }\n" "}\n" "class MyHelloWorld {\n" " use SayWorld;\n" " public function sayHello() {\n" " echo 'Hello ';\n" " }\n" "}\n" "$o = new MyHelloWorld();\n" "$o->sayHelloWorld();\n" "?>\n\n" , "Hello World!\n" ); MVCRO( "sayHello();\n" "?>\n\n" , "Hello from class!\n" ); MVCRO( "sayHello();\n" "?>\n\n" , "Hello from trait!\n" ); MVCRO( "sayHello();\n" "?>\n\n" , "Hello from MY_TRAIT2!\n" ); MVCRO( "falaOi();\n" "?>\n\n" , "Hello from MY_TRAIT1!\n" ); MVCRO( "falaOi();\n" "$o->falaTchau();\n" "$o->sayHello();\n" "$o->sayGoodbye();\n" "?>\n" , "Hello from MY_TRAIT1!\n" "Goodbye from MY_TRAIT2!\n" "Hello from MY_TRAIT1!\n" "Goodbye from MY_TRAIT2!\n" ); MVCRO( "falaTchau();\n" "?>\n" , "Goodbye from MY_TRAIT2!\n" ); MVCRO( "getCompanyName() . \"\\n\";\n" " echo \"I'm \" . $this->getName() . \"\\n\";\n" " }\n" "}\n" "class Portuguese extends Language {\n" " use Company, Person {\n" " Person::getName insteadof Company;\n" " Company::getName as getCompanyName;\n" " }\n" " public function sayHello() {\n" " echo \"Oi \" . $this->getCompanyName() . \"\\n\";\n" " echo \"Eu sou \" . $this->getName() . \"\\n\";\n" " }\n" "}\n" "$e = new English();\n" "$e->sayHello();\n" "$p = new Portuguese();\n" "$p->sayHello();\n" , "Hello Facebook\n" "I'm Ottoni\n" "Oi Facebook\n" "Eu sou Ottoni\n" ); MVCRO( "fala();\n" "?>\n" , "Hello\n" ); MVCRO( "say();\n" "$talker->fala();\n" "$talker->parla();\n" "?>\n" , "Banana\n" "Banana\n" "Banana\n" ); MVCRO( "sayHello();\n" "?>\n\n" , "World!\n" ); MVCRO( "sayHello();\n" "?>\n" , "Hello from MY_TRAIT2\n" ); MVCRO( "getHi() . $this->getName();\n" " }\n" "}\n" "$e = new English();\n" "$e->sayHello();\n" "?>\n\n" , "Hi Facebook\n" ); MVCRO( "bar();\n" " }\n" " abstract function bar();\n" "}\n" "class C {\n" " use T;\n" " function bar() {\n" " echo \"BAR!\\n\";\n" " }\n" "}\n" "$x = new C();\n" "$x->foo();\n" "?>\n" , "FooBAR!\n" ); MVCRO( "sayHelloWorld();\n" "?>\n\n" , "Hello World!\n" ); MVCRO( "\n\n" , "B: B\n" ); MVCRO( "Func1();\n" "?>\n\n" , "Hello\n" ); MVCRO( "x . \"\\n\";\n" " echo \"y = \" . $this->y . \"\\n\";\n" " }\n" "}\n" "class D {\n" " public $y = 4;\n" "}\n" "$o = new C;\n" "$o->printY();\n" "?>\n" , "x = 10\n" "y = 3\n" ); MVCRO( "y);\n" " var_dump($this->x);\n" " }\n" "}\n" "$o = new C;\n" "$o->printProps();\n" "?>\n" , "int(3)\n" "int(4)\n" ); MVCRO( "x);\n" " }\n" "}\n" "$o = new MY_CLASS;\n" "$o->printProps();\n" "?>\n" , "int(1977)\n" ); MVCRO( "x);\n" " }\n" "}\n" "$o = new C;\n" "$o->printProps();\n" "?>\n" , "int(3)\n" ); MVCRO( "printX();\n" "var_dump(MY_BASE::$x);\n" "var_dump(MY_CLASS::$x);\n" "?>\n" , "int(3)\n" "int(3)\n" "int(4)\n" ); MVCRO( "printX();\n" "?>\n" , "int(3)\n" ); MVCRO( "x);\n" " }\n" "}\n" "$o = new MY_CLASS;\n" "$o->printX();\n" "?>\n" , "int(4)\n" ); MVCRO( "x);\n" " }\n" "}\n" "$o = new MY_CLASS;\n" "$o->printX();\n" "?>\n" , "string(3) \"123\"\n" ); MVCRO( "x);\n" " $this->x = 10;\n" " var_dump($this->x);\n" " }\n" "}\n" "$o = new MY_CLASS;\n" "$o->printX();\n" "?>\n" , "NULL\n" "int(10)\n" ); MVCRO( "bigTalk($m);\n" " }\n" "}\n" "trait B {\n" " public function smallTalk() {\n" " echo \"b\\n\";\n" " }\n" " public function bigTalk($n) {\n" " if ($n == 0) return;\n" " echo \"B$n\\n\";\n" " $this->bigTalk($n - 1);\n" " }\n" "}\n" "class Talker {\n" " use A, B {\n" " B::smallTalk insteadof A;\n" " A::bigTalk insteadof B;\n" " B::bigTalk as bTalk;\n" " }\n" "}\n" "$talker = new Talker();\n" "$talker->smallTalk();\n" "$talker->bigTalk(1);\n" "$talker->bTalk(2);\n" "?>\n" , "b\n" "A1\n" "B2\n" "A1\n" ); MVCRO( "p();\n" "?>\n" , "A\n" ); MVCRO( "foo();\n" "?>\n" , "FooBAR!\n" "__class__: D\n" ); MVCRO( "inc();\n" "$p = new C2();\n" "$p->inc();\n" "$o->inc();\n" "$p->inc();\n" "?>\n" , "1\n" "1\n" "2\n" "2\n" ); MVCRO( "\n" , "Hello from static function!\n" ); MVCRO( "\n" , "Hello World!\n" ); MVCRO( "\n" , "Hello World!\n" "World!\n" ); MVCRO( "foo();\n" "?>\n" , "FooBAR!\n" "I'm in class D\n" ); MVCRO( "sayHello();\n" "$a = new MyClass2;\n" "$a->sayHello();\n" "?>\n" , "Hello World!\n" "Hello World!\n" ); MVCRO( "hello . ' ' . $this->world;\n" " }\n" "}\n" "var_dump(property_exists('TraitsTest', 'hello'));\n" "var_dump(property_exists('TraitsTest', 'world'));\n" "$t = new TraitsTest;\n" "$t->test();\n" "?>\n" , "bool(true)\n" "bool(true)\n" "Hello World!\n" ); MVCRO( "sayHello();\n" "?>\n\n" , "Hello World!\n" ); MVCRO( "sayHello();\n" " $this->sayWorld();\n" " echo \"!\\n\";\n" " }\n" " use World {\n" " World::say as sayWorld;\n" " }\n" "}\n" "$o = new MyHelloWorld();\n" "$o->say();\n" , "Hello World!\n" ); MVCRO( "sayHello();\n" , "Hello\n" ); MVCRO( "sayNum();\n" , "1\n" ); MVCRO( "sayNum();\n" , "1\n" ); MVCRO( "print_meth();\n" , "meth: MyClass\n" ); MVCRO( "fala();\n" "?>\n\n" , "Hello\n" ); MVCRO( " __CLASS__: <\" . __CLASS__ .\n" " \"> __METHOD__: <\" . __METHOD__ . \">\";\n" "}\n" "class NoTraitUsed {\n" " public static function test() {\n" " return \"__TRAIT__: <\" . __TRAIT__ .\n" " \"> __CLASS__: <\" . __CLASS__ .\n" " \"> __METHOD__: <\" . __METHOD__ . \">\";\n" " }\n" "}\n" "trait TestTrait {\n" " public static function test() {\n" " return \"__TRAIT__: <\" . __TRAIT__ .\n" " \"> __CLASS__: <\" . __CLASS__ .\n" " \"> __METHOD__: <\" . __METHOD__ . \">\";\n" " }\n" "}\n" "echo Direct::test().\"\\n\";\n" "echo IndirectInheritance::test().\"\\n\";\n" "echo Indirect::test().\"\\n\";\n" "echo NoTraitUsed::test().\"\\n\";\n" "echo test().\"\\n\";\n" , "__TRAIT__: __CLASS__: __METHOD__: \n" "__TRAIT__: __CLASS__: __METHOD__: \n" "__TRAIT__: __CLASS__: __METHOD__: \n" "__TRAIT__: <> __CLASS__: __METHOD__: \n" "__TRAIT__: <> __CLASS__: <> __METHOD__: \n" ); MVCRO( "sayHello();\n" "$a->sayHello2();\n" "?>\n" , "Hello World 1!\n" "Hello World 2!\n" ); MVCRO( "falaOi();\n" "?>\n" , "Hello World!\n" ); MVCRO( "\n" , "array(1) {\n" " [0]=>\n" " string(15) \"this_is_a_trait\"\n" "}\n" ); MVCRO( "isTrait());\n" "$rtrait = new ReflectionClass('this_is_a_trait');\n" "var_dump($rtrait->isTrait());\n" "$rinterface = new ReflectionClass('this_is_an_interface');\n" "var_dump($rinterface->isTrait());\n" , "bool(false)\n" "bool(true)\n" "bool(false)\n" ); if (!hhvm) { MVCRO( "\n" " string(6) \"test\\c\"\n" "}\n" ); } MVCRO( "\n" , "array(1) {\n" " [0]=>\n" " string(8) \"MY_TRAIT\"\n" "}\n" ); MVCRO( "\n" , "bool(false)\n" "bool(true)\n" "bool(true)\n" ); } MVCRO( "isConstructor());\n" "$rbarfoo = new ReflectionMethod('Bar::Foo');\n" "var_dump($rbarfoo->isConstructor());\n" "$rbarbar = new ReflectionMethod('Bar::Bar');\n" "var_dump($rbarbar->isConstructor());\n" , "bool(false)\n" "bool(false)\n" "bool(true)\n" ); MVCRO( "isConstructor());\n" "var_dump($rconstr->isDestructor());\n" "var_dump($rdestr->isConstructor());\n" "var_dump($rdestr->isDestructor());\n" "var_dump($rfunc->isConstructor());\n" "var_dump($rfunc->isDestructor());\n" , "bool(true)\n" "bool(false)\n" "bool(false)\n" "bool(true)\n" "bool(false)\n" "bool(false)\n" ); if (!hhvm) { MVCRO( "hello(), PHP_EOL;\n" " echo $a->foo(), PHP_EOL;\n" "}\n" , "hello from t1\n" "hello from t2\n" ); } MVCRO( "getTraitNames());\n" "?>\n" , "array(1) {\n" " [0]=>\n" " string(8) \"MY_TRAIT\"\n" "}\n" ); MVCRO( "getTraitNames());\n" "echo \"\\nT3:\\n\";\n" "var_dump(class_uses('T3'));\n" "$rt3 = new ReflectionClass('T3');\n" "var_dump($rt3->getTraitNames());\n" "echo \"\\nC1:\\n\";\n" "var_dump(class_uses('C1'));\n" "$rc1 = new ReflectionClass('C1');\n" "var_dump($rc1->getTraitNames());\n" "echo \"\\nC2:\\n\";\n" "var_dump(class_uses('C2'));\n" "$rc2 = new ReflectionClass('C2');\n" "var_dump($rc2->getTraitNames());\n" "echo \"\\nC3:\\n\";\n" "var_dump(class_uses('C3'));\n" "$rc3 = new ReflectionClass('C3');\n" "var_dump($rc3->getTraitNames());\n" "echo \"\\nC4:\\n\";\n" "var_dump(class_uses('C4'));\n" "$rc4 = new ReflectionClass('C4');\n" "var_dump($rc4->getTraitNames());\n" "echo \"\\nC5:\\n\";\n" "var_dump(class_uses('C5'));\n" "$rc5 = new ReflectionClass('C5');\n" "var_dump($rc5->getTraitNames());\n" "echo \"\\nI1:\\n\";\n" "var_dump(class_uses('I1'));\n" "$ri1 = new ReflectionClass('I1');\n" "var_dump($ri1->getTraitNames());\n" "?>\n" , "T1:\n" "array(0) {\n" "}\n" "array(0) {\n" "}\n\n" "T3:\n" "array(1) {\n" " [\"T2\"]=>\n" " string(2) \"T2\"\n" "}\n" "array(1) {\n" " [0]=>\n" " string(2) \"T2\"\n" "}\n\n" "C1:\n" "array(0) {\n" "}\n" "array(0) {\n" "}\n\n" "C2:\n" "array(1) {\n" " [\"T1\"]=>\n" " string(2) \"T1\"\n" "}\n" "array(1) {\n" " [0]=>\n" " string(2) \"T1\"\n" "}\n\n" "C3:\n" "array(2) {\n" " [\"T1\"]=>\n" " string(2) \"T1\"\n" " [\"T2\"]=>\n" " string(2) \"T2\"\n" "}\n" "array(2) {\n" " [0]=>\n" " string(2) \"T1\"\n" " [1]=>\n" " string(2) \"T2\"\n" "}\n\n" "C4:\n" "array(1) {\n" " [\"T3\"]=>\n" " string(2) \"T3\"\n" "}\n" "array(1) {\n" " [0]=>\n" " string(2) \"T3\"\n" "}\n\n" "C5:\n" "array(0) {\n" "}\n" "array(0) {\n" "}\n\n" "I1:\n" "array(0) {\n" "}\n" "array(0) {\n" "}\n" ); MVCRO( "\n" " string(2) \"T2\"\n" "}\n" "array(2) {\n" " [\"T3\"]=>\n" " string(2) \"T3\"\n" " [\"T1\"]=>\n" " string(2) \"T1\"\n" "}\n" ); MVCRO( "\n" " string(6) \"Hello1\"\n" " [\"Hello2\"]=>\n" " string(6) \"Hello2\"\n" "}\n" ); MVCRO( "getTraitAliases());\n" "$rc2 = new ReflectionClass('C2');\n" "var_dump($rc2->getTraitAliases());\n" "$rc3 = new ReflectionClass('T3');\n" "var_dump($rc3->getTraitAliases());\n" , "array(1) {\n" " [\"G\"]=>\n" " string(5) \"T2::F\"\n" "}\n" "array(0) {\n" "}\n" "array(1) {\n" " [\"G\"]=>\n" " string(9) \"(null)::F\"\n" "}\n" ); MVCRO( "F($x);\n" "echo $x;\n" "echo \"\\n\";\n" "$y = \"zero\";\n" "$o->F($y, \"0\");\n" "echo $y;\n" "?>\n\n" , "value = default\n" "zero = 0\n" ); // Zend tests MVCRO( "\n" "===DONE===\n" , "*** Testing class_uses() : basic ***\n" "array(2) {\n" " [\"foo\"]=>\n" " string(3) \"foo\"\n" " [\"bar\"]=>\n" " string(3) \"bar\"\n" "}\n" "array(2) {\n" " [\"foo\"]=>\n" " string(3) \"foo\"\n" " [\"bar\"]=>\n" " string(3) \"bar\"\n" "}\n" "array(1) {\n" " [\"foo\"]=>\n" " string(3) \"foo\"\n" "}\n" "array(1) {\n" " [\"foo\"]=>\n" " string(3) \"foo\"\n" "}\n" "array(0) {\n" "}\n" "array(0) {\n" "}\n" "===DONE===\n" ); MVCRO( "\n" , "bool(false)\n" "bool(true)\n" "bool(true)\n" "bool(false)\n" ); MVCRO( "saySomething();\n" "?>\n\n" , "Hello\n" ); MVCRO( "2));\n" "$o= myHelloWorld::getInstance(array(1=>2));\n" "\n" "?>\n" , "int(1)\n" "int(2)\n" "array(1) {\n" " [1]=>\n" " int(2)\n" "}\n" ); MVCRO( "\n" , "string(11) \"__construct\"\n" "string(10) \"__destruct\"\n" ); MVCRO( "\n\n" , "Test\n" ); MVCRO( "sayHello();\n" "$o->sayWorld();\n" "?>\n\n" , "Hello World!\n" ); MVCRO( "inc();\n" "$o->inc();\n" "\n" "?>\n" , "1\n" "2\n" ); MVCRO( "getTraitAliases());\n" " echo \"\\n\";\n" "}\n" "?>\n" , "class C1:\n" "array(0) {\n" "}\n" "\n" "class C2:\n" "array(0) {\n" "}\n" "\n" "class C3:\n" "array(1) {\n" " [\"a1\"]=>\n" " string(10) \"(null)::m1\"\n" "}\n" "\n" "class C4:\n" "array(2) {\n" " [\"a1\"]=>\n" " string(10) \"(null)::m1\"\n" " [\"a2\"]=>\n" " string(10) \"(null)::m2\"\n" "}\n" "\n" ); MVCRO( "saySomething();\n" "$o->sayWorld();\n" "?>\n\n" , "Hello World\n" ); MVCRO( "hello . ' ' . $this->world;\n" " }\n" "}\n" "\n" "var_dump(property_exists('TraitsTest', 'hello'));\n" "var_dump(property_exists('TraitsTest', 'world'));\n" "\n" "$t = new TraitsTest;\n" "$t->test();\n" "?>\n\n" , "bool(true)\n" "bool(true)\n" "hello World!\n" ); MVCRO( "\n" , "bool(false)\n" "bool(false)\n" "bool(false)\n" "bool(true)\n" ); MVCRO( "\n\n" , "B\n" ); MVCRO( "xyz;\n" "$o->xyz = 2;\n" "clone $o;\n" "\n" "?>\n" , "123\n" "string(3) \"xyz\"\n" "string(7) \"xyz===2\"\n" "string(7) \"__clone\"\n" ); MVCRO( "sayHello(); // echos Hello Universe!\n" "?>\n\n" , "Hello Universe!\n" ); MVCRO( "\n\n" , "*** Testing get_declared_traits() : basic functionality ***\n" "\n" "-- Testing get_declared_traits() function with Zero arguments --\n" "array(1) {\n" " [0]=>\n" " string(7) \"MyTrait\"\n" "}\n" "\n" "-- Ensure trait is listed --\n" "bool(true)\n" "\n" "-- Ensure userspace interfaces are not listed --\n" "bool(false)\n" "\n" "-- Ensure userspace classes are not listed --\n" "bool(false)\n" "Done\n" ); MVCRO( "\n" , "string(0) \"\"\n" "string(0) \"\"\n" "string(0) \"\"\n" ); MVCRO( "sayHello();\n" "?>\n\n" , "Hello World!\n" ); MVCRO( "hello();\n" "?>\n\n" , "Hello\n" ); MVCRO( "isConstructor());\n" "\n" "$rbarfoo = new ReflectionMethod('Bar::Foo');\n" "var_dump($rbarfoo->isConstructor());\n" "\n" "$rbarbar = new ReflectionMethod('Bar::Bar');\n" "var_dump($rbarbar->isConstructor());\n" "?>\n" , "bool(false)\n" "bool(false)\n" "bool(true)\n" ); MVCRO( "\n\n" , "bool(true)\n" "Done\n" ); MVCRO( "sayHello();\n" "$o->sayWorld();\n" "\n" "?>\n\n" , "Hello World!\n" ); MVCRO( "\n\n" , "Test\n" ); MVCRO( "get_class_name_obj();\n" "var_dump($r);\n" "\n" "$r = UsingIndirect::get_class_name();\n" "var_dump($r);\n" "\n" "$o = new UsingIndirect();\n" "$r = $o->get_class_name_obj();\n" "var_dump($r);\n" "\n" "\n" "?>\n" , "string(9) \"SomeClass\"\n" "string(9) \"SomeClass\"\n" "string(13) \"UsingIndirect\"\n" "string(13) \"UsingIndirect\"\n" ); MVCRO( "getWorld();\n" " }\n" " abstract public function getWorld();\n" " }\n" "\n" "class MyHelloWorld {\n" " private $world;\n" " use Hello;\n" " public function getWorld() {\n" " return $this->world;\n" " }\n" " public function setWorld($val) {\n" " $this->world = $val;\n" " }\n" "}\n" "\n" "$o = new MyHelloWorld();\n" "$o->setWorld(' World!');\n" "$o->sayHelloWorld();\n" "\n" "?>\n\n" , "Hello World!\n" ); MVCRO( "sayHello();\n" "$o->sayWorld();\n" "$o->sayExclamationMark();\n" "?>\n\n" , "Hello World!\n" ); MVCRO( "\n\n" , "Test B\n" ); MVCRO( "\n\n" , "*** Testing trait_exists() : basic functionality ***\n" "Calling trait_exists() on non-existent trait with autoload explicitly enabled:\n" "In __autoload(C)\n" "bool(false)\n" "\n" "Calling trait_exists() on existing trait with autoload explicitly enabled:\n" "bool(true)\n" "\n" "Calling trait_exists() on non-existent trait with autoload explicitly enabled:\n" "bool(false)\n" "\n" "Calling trait_exists() on existing trait with autoload explicitly disabled:\n" "bool(true)\n" "\n" "Calling trait_exists() on non-existent trait with autoload unspecified:\n" "In __autoload(E)\n" "bool(false)\n" "\n" "Calling trait_exists() on existing trait with autoload unspecified:\n" "bool(true)\n" "Done\n" ); MVCRO( "\n" , "TestTrait\n" "TestTrait\n" "TestTrait\n" ); MVCRO( "\n\n" , "Forwarded Test A\n" ); MVCRO( "\n" , "OK\n" ); MVCRO( "inc();\n" "$o->inc();\n" "\n" "$p = new C2();\n" "$p->inc();\n" "$p->inc();\n" "\n" "?>\n" , "1\n" "2\n" "1\n" "2\n" ); MVCRO( "\n" , "string(20) \"C:3:\"bar\":6:{foobar}\"\n" "string(6) \"foobar\"\n" "object(bar)#1 (0) {\n" "}\n" ); MVCRO( "smallTalk();\n" "$t->bigTalk();\n" "$t->talk();\n" "\n" "?>\n\n" , "bAB\n" ); MVCRO( "sayHello(); // echos Hello Universe!\n" "?>\n\n" , "Hello Universe!\n" ); MVCRO( "\n" , "array(1) {\n" " [0]=>\n" " string(1) \"c\"\n" "}\n" ); MVCRO( "isTrait());\n" "\n" "$x = new ReflectionClass('bar');\n" "var_dump($x->isTrait());\n" "\n" "$x = new ReflectionClass('baz');\n" "var_dump($x->isTrait());\n" "\n" "?>\n" , "bool(false)\n" "bool(true)\n" "bool(false)\n" ); MVCRO( "\n" , "abc\n" "def\n" ); MVCRO( "\n" "===DONE===\n" , "*** Testing class_uses() : basic ***\n" "array(1) {\n" " [\"foo\"]=>\n" " string(3) \"foo\"\n" "}\n" "array(1) {\n" " [\"foo\"]=>\n" " string(3) \"foo\"\n" "}\n" "===DONE===\n" ); MVCRO( "\n\n" , "Test\n" ); MVCRO( "sayHello();\n" "?>\n\n" , "World!\n" ); MVCRO( "foo();\n" "\n" "?>\n\n" , "b\n" ); MVCRO( "text;\n" " }\n" "}\n" "\n" "trait T2 {\n" " public function setTextT2($val) {\n" " $this->text = $val;\n" " }\n" "}\n" "\n" "class TraitsTest {\n" " use T1;\n" " use T2;\n" " private $text = 'test';\n" " public function setText($val) {\n" " $this->text = $val;\n" " }\n" "}\n" "\n" "$o = new TraitsTest();\n" "var_dump($o->getText());\n" "\n" "$o->setText('foo');\n" "\n" "var_dump($o->getText());\n" "\n" "$o->setText('bar');\n" "\n" "var_dump($o->getText());\n" "?>\n" , "string(4) \"test\"\n" "string(3) \"foo\"\n" "string(3) \"bar\"\n" ); MVCRO( "foo();\n" "C::foo();\n" "D::foo();\n" "T::foo();\n" "T2::foo();\n" "T3::foo();\n" "?>" , "I'm in class C\n" "I'm in class C\n" "I'm in class C\n" "I'm in class T\n" "I'm in class T2\n" "I'm in class T3\n" ); MVCRO( "sayClass(); // echo Cls\n" "$o->sayParent(); // echos Base\n" "?>\n" "\n" , "Cls\n" "Base\n" ); MVCRO( "printX();\n" "$o2->printX();\n" "T::$x++;\n" "var_dump(T::$x);\n" "var_dump(C1::$x);\n" "var_dump(C2::$x);\n" "$o1->printX();\n" "$o2->printX();\n" "C1::$x++;\n" "var_dump(T::$x);\n" "var_dump(C1::$x);\n" "var_dump(C2::$x);\n" "$o1->printX();\n" "$o2->printX();\n" "C2::$x++;\n" "var_dump(T::$x);\n" "var_dump(C1::$x);\n" "var_dump(C2::$x);\n" "$o1->printX();\n" "$o2->printX();\n" "$o1->x++;\n" "var_dump(T::$x);\n" "var_dump(C1::$x);\n" "var_dump(C2::$x);\n" "$o1->printX();\n" "$o2->printX();\n" , "int(1)\n" "int(1)\n" "int(1)\n" "int(1)\n" "int(1)\n" "int(2)\n" "int(1)\n" "int(1)\n" "int(1)\n" "int(1)\n" "int(2)\n" "int(2)\n" "int(1)\n" "int(2)\n" "int(1)\n" "int(2)\n" "int(2)\n" "int(2)\n" "int(2)\n" "int(2)\n" "int(2)\n" "int(2)\n" "int(2)\n" "int(2)\n" "int(2)\n" ); MVCRO( "bar();\n" , "I am bar\n" "I am foo\n" ); MVCRO( "inc(\"c1\");\n" "$c2->inc(\"c2\");\n" "$d1->inc(\"d1\");\n" "$b1->inc(\"b1\");\n" "$b1->inc(\"b1\");\n" "$c2->inc(\"c2\");\n" "$d1->inc(\"d1\");\n" "$c1->inc(\"c1\");\n" , "c1 (C): 1\n" "c2 (C): 2\n" "d1 (C): 1\n" "b1 (B): 1\n" "b1 (B): 2\n" "c2 (C): 3\n" "d1 (C): 2\n" "c1 (C): 4\n" ); MVCRO( "bar();\n" " }\n" "}\n" "class B {\n" " public function bar() {\n" " echo \"I'm bar\\n\";\n" " }\n" "}\n" "class C extends B {\n" " use T;\n" "}\n" "$o = new C;\n" "$o->foo();\n" "\n" , "I'm bar\n" ); MVCRO( "bar();\n" " }\n" "}\n" "\n" "trait T2 {\n" " public function bar() {\n" " echo \"Hello from bar()\\n\";\n" " }\n" "}\n" "\n" "class C {\n" " use T1, T2;\n" "}\n" "\n" "$o = new C;\n" "$o->foo();\n" "\n" "\n" , "Hello from bar()\n" ); MVCRO( "f();" " }" " function h() {" " return $this->p();" " }" "}" "class C {" " use T;" "}" "$c = new C;" "echo $c->g();" "echo $c->h();", "12"); MVCRO( "test());" "var_dump($obj->test1());" "var_dump($obj->test2());" "var_dump(call_user_func(array($obj, \"test\")));" "var_dump(call_user_func(array($obj, \"test1\")));" "var_dump(call_user_func(array($obj, \"test2\")));" "var_dump(T::test8(1, 2, 3, 4, 5, 6, 7, 8));" "var_dump(T::test81(1, 2, 3, 4, 5, 6, 7, 8));" "var_dump(T::test82(1, 2, 3, 4, 5, 6, 7, 8));" "var_dump(call_user_func(\"T::test8\", 1, 2, 3, 4, 5, 6, 7, 8));" "var_dump(call_user_func(\"T::test81\", 1, 2, 3, 4, 5, 6, 7, 8));" "var_dump(call_user_func(\"T::test82\", 1, 2, 3, 4, 5, 6, 7, 8));" "$obj = new T;" "var_dump($obj->test8(1, 2, 3, 4, 5, 6, 7, 8));" "var_dump($obj->test81(1, 2, 3, 4, 5, 6, 7, 8));" "var_dump($obj->test82(1, 2, 3, 4, 5, 6, 7, 8));" "var_dump(call_user_func(array($obj, \"test8\"), " "1, 2, 3, 4, 5, 6, 7, 8));" "var_dump(call_user_func(array($obj, \"test81\"), " "1, 2, 3, 4, 5, 6, 7, 8));" "var_dump(call_user_func(array($obj, \"test82\"), " "1, 2, 3, 4, 5, 6, 7, 8));", "int(1)\n" "int(1)\n" "int(1)\n" "int(2)\n" "int(2)\n" "int(2)\n" "int(3)\n" "int(3)\n" "int(3)\n" "int(4)\n" "int(4)\n" "int(4)\n" "int(1)\n" "int(1)\n" "int(1)\n" "int(2)\n" "int(2)\n" "int(2)\n" "int(3)\n" "int(3)\n" "int(3)\n" "int(4)\n" "int(4)\n" "int(4)\n" ); MVCRO("entCanComment);" " var_dump(must_prepare($this->entCanComment));" " }" "}" "class EntShare {" " use EntWithViewerComments;" "}" "$obj1 = new EntShare;" "$obj1->canViewerComment();" , "int(1)\nint(1)\n"); MVCROF( "x = 'set from trait'; } }" "" "class A {" " function useA() { $this->x = 'set from A'; }" "}" "class B extends A {" " use T;" " function useB() { $this->x = 'set from B'; }" "}" "class C extends B {" " function useC() { $this->x = 'set from C'; }" "}" "class D extends C {" " function useD() { $this->x = 'set from D'; }" "}" "$x = new D(); echo serialize($x), \"\\n\";" "$x = new D(); $x->useT(); echo serialize($x), \"\\n\";" "$x = new D(); $x->useA(); echo serialize($x), \"\\n\";" "$x = new D(); $x->useB(); echo serialize($x), \"\\n\";" "$x = new D(); $x->useC(); echo serialize($x), \"\\n\";" "$x = new D(); $x->useD(); echo serialize($x), \"\\n\";", "test/output/trait1.out"); MVCRO("xT1);\n" "var_dump($y->xT2);\n" "var_dump($y->xT3);\n" "var_dump($y->xA);\n" "var_dump($y->xB);\n" , "O:1:\"A\":5:{s:2:\"xA\";s:2:\"xA\";s:3:\"xT3\";s:3:\"xT3\";" "s:2:\"xB\";s:2:\"xB\";s:3:\"xT1\";s:3:\"xT1\";s:3:\"xT2\";" "s:3:\"xT2\";}\n" "string(3) \"xT1\"\n" "string(3) \"xT2\"\n" "string(3) \"xT3\"\n" "string(2) \"xA\"\n" "string(2) \"xB\"\n" ); MVCRO( "x; } }" "class Y extends X { use T; function y() { return ++$this->x; } }" "class Z extends Y { function z() { return ++$this->x; } }" "$a = new Z();" "echo join(\" \", array($a->x(), $a->x(), $a->y(), $a->y(), " "$a->z(), $a->z())), \"\\n\";", "1 2 1 2 2 3\n"); MVCRO("protectedMethod();" " }" " protected function protectedMethod() {" " return 'fallback protected method';" " }" " public function getStringThroughPrivateMethod() {" " return $this->privateMethod();" " }" " private function privateMethod() {" " return 'fallback private method';" " }" "}" "" "class A {" " use TraitFoo;" " protected function protectedMethod() {" " return 'in a protectedMethod';" " }" " private function privateMethod() {" " return 'in a privateMethod';" " }" "}" "$a = new A();" "echo $a->getStringThroughProtectedMethod().\"\\n\";" "echo $a->getStringThroughPrivateMethod().\"\\n\";", "in a protectedMethod\n" "in a privateMethod\n"); { // begin trait tests requiring EnableHipHopSyntax HipHopSyntax w(this); MVCRO("fruit() as $fruit) {\n" " var_dump($fruit);\n" "}\n" , "string(5) \"apple\"\n" "string(6) \"banana\"\n" ); MVCRO("fruit() as $fruit) {\n" " var_dump($fruit);\n" "}\n" "foreach ($o->fruit2() as $fruit) {\n" " var_dump($fruit);\n" "}\n" , "string(5) \"apple\"\n" "string(6) \"banana\"\n" "string(4) \"pear\"\n" "string(5) \"grape\"\n" ); MVCRO("doIt();\n" " } catch (Exception $e) {\n" " $res = $e->getMessage();\n" " }\n" " yield $res;\n" "}\n" "$x = new X;\n" "foreach (f($x) as $i) { var_dump($i); }\n" , "string(6) \"foobar\"\n" ); MVCRO("foo('this') as $v) { var_dump($v); }\n" , "int(5)\n" ); MVCRO("getOrigFuncName());\n" "trait T {\n" " function f($x) { yield get_called_class(); }\n" "}\n" "class X { use T; }\n" "$x = new X;\n" "$c = $x->f(32);\n" "var_dump($c->getOrigFuncName());\n" "$fcn = function ($x) { yield $x; };\n" "$c = $fcn(32);\n" "var_dump($c->getOrigFuncName());\n" , "string(1) \"f\"\n" "string(4) \"X::f\"\n" "string(9) \"{closure}\"\n" ); MVCRO("info() as $info) {\n" " var_dump($info);\n" "}\n" "$o2 = new C2;\n" "foreach ($o2->info() as $info) {\n" " var_dump($info);\n" "}\n" , "string(7) \"T::info\"\n" "string(2) \"C1\"\n" "string(1) \"T\"\n" "string(7) \"T::info\"\n" "string(2) \"C2\"\n" "string(1) \"T\"\n" ); MVCRO("f();\n" "foreach ($f() as $v) { var_dump($v); }\n" , "int(1)\n" "int(2)\n" ); MVCRO("bar(function() {yield 1; yield 2; yield 3;});" " }" " public function bar(Closure $c) {" " $a = $c();" " foreach ($a as $b) {" " echo $b.\"\\n\";" " }" " }" "}" "class A { use T; }" "$a = new A();" "$a->foo();" , "1\n" "2\n" "3\n" ); MVCRO("foo();\n" " yield null;\n" " }\n" "}\n" "class D {\n" " use U;\n" " protected function foo() {\n" " echo \"U::foo\\n\";\n" " }\n" "}\n" "$obj = new D;\n" "$x = $obj->test();\n" "foreach ($x as $v) {}\n" , "D\n" "U::foo\n" ); MVCRO("m();\n" "fb_intercept(\"A::m\", function() { echo \"new\n\"; });\n" "$a2 = new A;\n" "$a2->m();\n" "$b1 = new B;\n" "$b1->m();\n" "T::m();\n" , "original\n" "new\n" "original\n" "original\n"); MVCRO("m();\n" "fb_intercept(\"T::m\", function() { echo \"new\n\"; });\n" "$a2 = new A;\n" "$a2->m();\n" "$b1 = new B;\n" "$b1->m();\n" "T::m();\n" , "original\n" "original\n" "original\n" "original\n" "new\n"); MVCRONW("\n" " int(789)\n" "}\n" ); MVCRO("goo($p);" " }, $values);" " var_dump($values);" " }" " public function bar() { return $this; }" " public function goo($p) { return $p; }" "}" "class A { use T;}\n" "$obj = new A;" "var_dump($obj->bar());" "$obj->foo();", "object(A)#1 (0) {\n" "}\n" "array(3) {\n" " [0]=>\n" " int(1)\n" " [1]=>\n" " int(2)\n" " [2]=>\n" " int(3)\n" "}\n"); MVCRO("input();\n" " $a = function ($arg) use ($abc, $this) {\n" " var_dump($arg);\n" " var_dump($abc);\n" " return $this->output();\n" " };\n" " return $a;\n" " }\n" " function input() { return 1; }\n" " function output() { return 2; }\n" "}\n" "class Foo {\n" " use Too;\n" " function input() { return \"str1\"; }\n" " function output() { return \"str2\"; }\n" "}\n" "class Goo {\n" " use Too;\n" " function input() { return false; }\n" " function output() { return true; }\n" "}\n" "$of = new Foo;\n" "$f = $of->gen();\n" "var_dump($f(1000));\n" "$og = new Goo;\n" "$g = $og->gen();\n" "var_dump($g(2000));\n" , "int(1000)\n" "string(4) \"str1\"\n" "string(4) \"str2\"\n" "int(2000)\n" "bool(false)\n" "bool(true)\n" ); MVCRO("x);\n" , "int(123)\n" ); MVCRO("x);\n" "var_dump($obj->y);\n" , "string(1) \"1\"\n" "string(1) \"2\"\n" ); MVCRO("x);\n" , "int(123)\n" ); MVCRO("x);\n" "var_dump($obj->y);\n" , "int(123)\n" "int(456)\n" ); MVCRO("x);\n" , "int(123)\n" ); MVCRO("x);\n" "var_dump($obj->y);\n" , "int(123)\n" "int(456)\n" ); MVCRO("testDoSomething().\"\n\";\n" "echo $a->testDoSomethingInTrait().\"\n\";\n" "echo $a->testDoSomethingPublicInTrait().\"\n\";\n" , "doSomething\n" "doSomethingInTrait\n" "doSomethingPublicInTrait\n" ); MVCRO("dump_vars();\n" , "array(2) {\n" " [\"y\"]=>\n" " int(2)\n" " [\"x\"]=>\n" " int(1)\n" "}\n" ); MVCRO("bar();" " }" " private function bar() {" " echo \"in bar...\\n\";" " }" "}" "class B { use T; }" "class C extends B { }" "$obj = new C;" "$obj->foo();", "in bar...\n"); MVCRO("foo;" " }" "}" "" "class Base {" " public static function create() {" " return new static();" " }" "}" "" "class UsePrivateState extends Base {" " use PrivateState;" "}" "" "class DerivedUsePrivateState extends UsePrivateState {" "" "}" "" "" "$state = new DerivedUsePrivateState();" "$method = new ReflectionMethod('DerivedUsePrivateState', 'getFoo');" "echo $method->invoke($state).\"\\n\";" "", "2\n"); MVCRO("foo(1);\n" , "1 \n" ); MVCRO("init();", "A::init"); MVCRO("foo();\n" " }\n" "}\n" "$d = new D;\n" "E::test($d);\n" "echo \"Done\\n\";\n" , "Done\n" ); MVCRO("foo();\n" " }\n" "}\n" "$d = new D;\n" "E::test($d);\n" "echo \"Done\\n\";\n" , "T::foo\n" "Done\n" ); MVCRO("foo().\"\\n\";\n" , "Foo\n"); MVCRO("f().\"\\n\";\n" , "Bar\n"); MVCRO("f();\n" " }\n" "}\n" "$b = new Bar();\n" "echo $b->inv().\"\\n\";\n" , "Bar\n"); MVCRO("f();\n" " }\n" "}\n" "$b = new Bar();\n" "echo $b->inv().\"\\n\";\n" , "Bar\n"); MVCRO("f();\n" " }\n" "}\n" "$b = new Bar();\n" "echo $b->inv().\"\\n\";\n" , "Bar\n"); MVCRO("hello();\n" "$oc = new C();\n" "$oc->hello();\n" "$od = new D();\n" "$od->hello();\n" , "Hello from B!\n" "Hello from B!\n" "Hello from B!\n" ); MVCRO("foo();\n" , "hello\n"); MVCRO("foo();\n" , "hello\n"); MVCRO("foo();\n" , "hello\n"); MVCRO("foo();\n" , "C::hello\n"); MVCRO("foo();\n" , "B::hello\n"); MVCRO("foo(); }" "}" "trait BT {" " function foo() { var_dump('ok'); }" "}" "class B extends A {" " use BT;" "}" "function test() {" " $b = new B;" " $b->bar();" "}" "test();", "string(2) \"ok\"\n"); MVCRO("getProperties() as $prop) {\n" " $props[] = $prop->getName();\n" " }\n" " asort($props);\n" " show_without_extra_vardump_nonsense($props);\n" " $meths = array();\n" " echo \"yall know what time it is now too. time to show you some methods\\n\";\n" " foreach ($r->getMethods() as $meth) {\n" " $meths[] = $meth->getName();\n" " }\n" " asort($meths);\n" " show_without_extra_vardump_nonsense($meths);\n" "}\n" "\n" "trait T {\n" " private $priv;\n" " protected $prot;\n" " public $pub;\n" "\n" " private static $priv_st;\n" " protected static $prot_st;\n" " public static $pub_st;\n" "\n" " private function fpriv() {}\n" " protected function fprot() {}\n" " public function fpub() {}\n" "\n" " private static function fpriv_st() {}\n" " protected static function fprot_st() {}\n" " public static function fpub_st() {}\n" "}\n" "\n" "trait U {\n" " public $foo;\n" " public static $static;\n" "\n" " public function ffoo() {}\n" " public static function fstatic() {}\n" "}\n" "\n" "class C {\n" " use T;\n" "\n" " private $c_priv;\n" "}\n" "\n" "class D extends C {\n" " use U;\n" "\n" " public $class_prop;\n" " public function class_method() {}\n" "\n" "}\n" "\n" "$r = new ReflectionClass('C');\n" "do_wonderful_things_with($r);\n" "\n" "$r = new ReflectionClass('D');\n" "do_wonderful_things_with($r);\n" , "yall know what time it is. time to show you some properties\n" "array (7) {\n" " c_priv\n" " priv\n" " priv_st\n" " prot\n" " prot_st\n" " pub\n" " pub_st\n" "}\n" "yall know what time it is now too. time to show you some methods\n" "array (6) {\n" " fpriv\n" " fpriv_st\n" " fprot\n" " fprot_st\n" " fpub\n" " fpub_st\n" "}\n" "yall know what time it is. time to show you some properties\n" "array (7) {\n" " class_prop\n" " foo\n" " prot\n" " prot_st\n" " pub\n" " pub_st\n" " static\n" "}\n" "yall know what time it is now too. time to show you some methods\n" "array (9) {\n" " class_method\n" " ffoo\n" " fpriv\n" " fpriv_st\n" " fprot\n" " fprot_st\n" " fpub\n" " fpub_st\n" " fstatic\n" "}\n" ); return true; } bool TestCodeRun::TestUConverter() { // ext/intl/tests/uconverter_enum.phpt MVCRO(" 100);" "var_dump(in_array('UTF-7', $avail));" "var_dump(in_array('CESU-8', $avail));" "var_dump(in_array('ISO-8859-1', $avail));" "$latin1 = UConverter::getAliases('latin1');" "var_dump(in_array('ISO-8859-1', $latin1));" , "bool(true)\n" "bool(true)\n" "bool(true)\n" "bool(true)\n" "bool(true)\n" ); // ext/intl/tests/uconverter_func_basic.phpt MVCRO(" $subst);" " $ret = UConverter::transcode(\"This is an ascii string\", 'ascii', 'utf-8', $opts);" " if ($ret === NULL) {" " echo \"Error: \", intl_get_error_message(), \"\\n\";" " } else {" " var_dump($ret);" " }" " $ret = UConverter::transcode(\"Snowman: (\\xE2\\x98\\x83)\", 'ascii', 'utf-8', $opts);" " if ($ret === NULL) {" " echo \"Error: \", intl_get_error_message(), \"\\n\";" " } else {" " var_dump($ret);" " }" "}" , "string(23) \"This is an ascii string\"\n" "string(12) \"Snowman: (?)\"\n" "Error: ucnv_setSubstChars() returned error 1: U_ILLEGAL_ARGUMENT_ERROR\n" "Error: ucnv_setSubstChars() returned error 1: U_ILLEGAL_ARGUMENT_ERROR\n" "Error: ucnv_setSubstChars() returned error 1: U_ILLEGAL_ARGUMENT_ERROR\n" "Error: ucnv_setSubstChars() returned error 1: U_ILLEGAL_ARGUMENT_ERROR\n" ); // ext/intl/tests/uconverter_oop_algo.phpt MVCRO("getSourceType());" "var_dump(UConverter::UTF8 === $c->getDestinationType());" "$c = new UConverter('koi8-r', 'utf-32be');" "var_dump(UConverter::UTF32_BigEndian === $c->getSourceType());" "var_dump(UConverter::SBCS === $c->getDestinationType());" , "bool(true)\n" "bool(true)\n" "bool(true)\n" "bool(true)\n" ); // ext/intl/tests/uconverter_oop_basic.phpt MVCRO("convert(\"This is an ascii string\"));" "var_dump(urlencode($c->convert(\"Espa\\xF1ol\")));" "var_dump(urlencode($c->convert(\"Stra\\xDFa\")));" "var_dump(urlencode($c->convert(\"Stra\\xC3\\x9Fa\", true)));" "$k = new UConverter('utf-8', 'koi8-r');" "var_dump(bin2hex($k->convert(\"\\xE4\")));" , "string(23) \"This is an ascii string\"\n" "string(12) \"Espa%C3%B1ol\"\n" "string(11) \"Stra%C3%9Fa\"\n" "string(8) \"Stra%DFa\"\n" "string(4) \"d094\"\n" ); // ext/intl/tests/uconverter_oop_callback.phpt MVCRO("convert($word);" "}" "unset($c);" , "toUCallback(REASON_RESET, ...)\n" "toUCallback(REASON_RESET, ...)\n" "fromUCallback(REASON_RESET, ...)\n" "fromUCallback(REASON_RESET, ...)\n" "toUCallback(REASON_RESET, ...)\n" "toUCallback(REASON_ILLEGAL, ...)\n" "toUCallback(REASON_RESET, ...)\n" "toUCallback(REASON_ILLEGAL, ...)\n" "fromUCallback(REASON_RESET, ...)\n" "fromUCallback(REASON_RESET, ...)\n" "toUCallback(REASON_RESET, ...)\n" "toUCallback(REASON_RESET, ...)\n" "fromUCallback(REASON_RESET, ...)\n" "fromUCallback(REASON_UNASSIGNED, ...)\n" "fromUCallback(REASON_RESET, ...)\n" "fromUCallback(REASON_UNASSIGNED, ...)\n" "toUCallback(REASON_CLOSE, ...)\n" "fromUCallback(REASON_CLOSE, ...)\n" "toUCallback(REASON_CLOSE, ...)\n" "fromUCallback(REASON_CLOSE, ...)\n" ); // ext/intl/tests/uconverter_oop_callback_return.phpt MVCRO("convert(\"\\x80\\x81\\x82\\x83\"));" "var_dump($c->convert(\"\\xC3\\xB1\\xC3\\xB2\\xC3\\xB3\\xC3\\xB4\"));" , "string(3) \"abc\"\n" "string(3) \"ABC\"\n" ); // ext/intl/tests/uconverter_oop_subst.phpt MVCRO("') as $subst) {" " if (!$c->setSubstChars($subst)) {" " echo \"**Disallowed\\n\";" " continue;" " }" " var_dump($c->convert(\"This is an ascii string\"));" " var_dump($c->convert(\"Snowman: (\\xE2\\x98\\x83)\"));" "}" , "string(23) \"This is an ascii string\"\n" "string(12) \"Snowman: (?)\"\n" "**Disallowed\n" "**Disallowed\n" ); return true; } bool TestCodeRun::TestStrictMode() { HipHopSyntax w(this); MVCRO("", ""); // Wrong type, fail MVCRONW("(X $a) { echo 1; } t(42);", "1"); // Generic with as MVCRO("{}", ""); // Silent type hint MVCRO("> {}", ""); // Arrays with generic types MVCRO(" $x) {}", ""); MVCRO(" $x) {}", ""); // Kitchen sink MVCRO("(blarg $list, int $idx):X {\n" " return $list->d[$idx];\n" "}\n" "function pair(X $x, Y $y):(X,Y) { return array($x, $y); }\n" "function car((X,?Y) $pair):X {\n" " return $pair[0];\n" "}\n" "interface Face {\n" "}\n" "class blarg { function __construct($x) { $this->d = $x; } }\n" "function blarg(/*...*/):blarg { return new blarg(func_get_args()); }\n" "\n" "class Foo implements Face {\n" " const string BLEH = \"b\";\n" "}\n" "\n" "$blork = pair('c', '-');\n" "\n" "function right_shift_hack(Foo,Foo>>,Foo>>>,Foo>>>> $bonk,\n" " (function(Foo,Bar):C) $d) {\n" "}\n" "\n" "$a = blarg('a','aa','aaa');\n" "$d = (function():UNICORNS{return 'd';});\n" "echo vidx($a, 0), Foo::BLEH, car($blork), $d();\n", "abcd"); MVCRO("();\n" " $x = new Foo>();\n" " $y = new Foo();\n" " $z = new Foo,Blah>();\n" " yo();\n" " yo>();\n" " yo();\n" " yo,Blah<:my:xhp:class>>();\n" " $x->baz();\n" " $x->baz>();\n" " $y->baz();\n" " $y->baz,Blah<:my:xhp:class>>();\n" " Foo::biz();\n" " Foo>::biz();\n" " Foo::biz();\n" " Foo>::biz>();\n" " Foo::biz();\n" " Foo>::biz,Blah<:my:xhp:class>>();\n" " Foo::biz();\n" " Foo,Blah>::biz();\n" " Foo::biz();\n" " Foo,Blah>::biz>();\n" " Foo::biz();\n" " Foo,Blah>::biz,Blah<:my:xhp:class>>();\n" " var_dump(Foo::SOME_CONST);\n" " var_dump(Foo>::SOME_CONST);\n" " var_dump(Foo::SOME_CONST);\n" " var_dump(Foo,Blah>::SOME_CONST);\n" " var_dump(Foo::$staticProp);\n" " var_dump(Foo>::$staticProp);\n" " var_dump(Foo::$staticProp);\n" " var_dump(Foo,Blah>::$staticProp);\n" "}\n" "echo \"Done\\n\";\n" , "Done\n" ); MVCRO(";\n" " abstract function g2() : Foo<(function(int):void)>;\n" " abstract function g3() : Foo<(function(int,string):void)>;\n" " abstract function g4() : Foo<(function(...):void)>;\n" " abstract function g5() : Foo<(function(int,...):void)>;\n" " abstract function g6() : Foo<(function(int,string,...):void)>;\n" " abstract function h1((function():void) $x) : void;\n" " abstract function h2((function(int):void) $x) : void;\n" " abstract function h3((function(int,string):void) $x) : void;\n" " abstract function h4((function(...):void) $x) : void;\n" " abstract function h5((function(int,...):void) $x) : void;\n" " abstract function h6((function(int,string,...):void) $x) : void;\n" " abstract function j1(Foo<(function():void)> $x) : void;\n" " abstract function j2(Foo<(function(int):void)> $x) : void;\n" " abstract function j3(Foo<(function(int,string):void)> $x) : void;\n" " abstract function j4(Foo<(function(...):void)> $x): void;\n" " abstract function j5(Foo<(function(int,...):void)> $x): void;\n" " abstract function j6(Foo<(function(int,string,...):void)> $x): " "void;\n" "}\n" "echo \"Done\\n\";\n" , "Done\n" ); return true; } // please leave this unit test at last for debugging ad hoc code bool TestCodeRun::TestAdHoc() { return true; }