From 63fc74a751bd8d64203f8c4dd27c025c12717f65 Mon Sep 17 00:00:00 2001 From: Paul Tarjan Date: Wed, 12 Jun 2013 00:40:14 -0700 Subject: [PATCH] reflection for namespaced constants In repo mode this does the right thing and returns the right constant, but for non-repo it thinks it is an undefined non-namespace constant. I'll have to do something more hardcore if that starts to matter While I was in there, I made the correct name for `ReflectionParameter` that was added in 5.4 instead of the draft we copied. --- .../expression/constant_expression.cpp | 2 +- hphp/runtime/base/execution_context.h | 2 +- hphp/runtime/ext/ext_reflection.cpp | 5 +++- hphp/runtime/vm/bytecode.cpp | 19 +++++++++++-- hphp/runtime/vm/func.cpp | 5 +++- hphp/system/php/reflection/reflection.php | 18 ++++++++++++ hphp/test/slow/namespace/const_param.php | 28 +++++++++++++++++++ .../slow/namespace/const_param.php.expectf | 28 +++++++++++++++++++ 8 files changed, 101 insertions(+), 6 deletions(-) create mode 100644 hphp/test/slow/namespace/const_param.php create mode 100644 hphp/test/slow/namespace/const_param.php.expectf diff --git a/hphp/compiler/expression/constant_expression.cpp b/hphp/compiler/expression/constant_expression.cpp index b5d19f0fb..4f74b7fe1 100644 --- a/hphp/compiler/expression/constant_expression.cpp +++ b/hphp/compiler/expression/constant_expression.cpp @@ -277,5 +277,5 @@ TypePtr ConstantExpression::inferTypes(AnalysisResultPtr ar, TypePtr type, // code generation functions void ConstantExpression::outputPHP(CodeGenerator &cg, AnalysisResultPtr ar) { - cg_printf("%s", m_name.c_str()); + cg_printf("%s", getNonNSOriginalName().c_str()); } diff --git a/hphp/runtime/base/execution_context.h b/hphp/runtime/base/execution_context.h index 54df9cd73..2052b856c 100644 --- a/hphp/runtime/base/execution_context.h +++ b/hphp/runtime/base/execution_context.h @@ -671,7 +671,7 @@ public: bool m_dbgNoBreak; bool doFCall(HPHP::ActRec* ar, PC& pc); bool doFCallArray(PC& pc); - CVarRef getEvaledArg(const StringData* val); + CVarRef getEvaledArg(const StringData* val, CStrRef namespacedName); private: void enterVMWork(ActRec* enterFnAr); void enterVMPrologue(ActRec* enterFnAr); diff --git a/hphp/runtime/ext/ext_reflection.cpp b/hphp/runtime/ext/ext_reflection.cpp index d2da60ddc..387550700 100644 --- a/hphp/runtime/ext/ext_reflection.cpp +++ b/hphp/runtime/ext/ext_reflection.cpp @@ -449,7 +449,10 @@ static void set_function_info(Array &ret, const Func* func) { // undefined class constants can cause the eval() to // fatal. Zend lets such fatals propagate, so don't bother catching // exceptions here. - CVarRef v = g_vmContext->getEvaledArg(fpi.phpCode()); + CVarRef v = g_vmContext->getEvaledArg( + fpi.phpCode(), + func->cls() ? func->cls()->nameRef() : func->nameRef() + ); param.set(s_default, v); } param.set(s_defaultText, VarNR(fpi.phpCode())); diff --git a/hphp/runtime/vm/bytecode.cpp b/hphp/runtime/vm/bytecode.cpp index 75512e37b..06219000f 100644 --- a/hphp/runtime/vm/bytecode.cpp +++ b/hphp/runtime/vm/bytecode.cpp @@ -2479,14 +2479,29 @@ bool VMExecutionContext::evalUnit(Unit* unit, PC& pc, int funcType) { return ret; } -CVarRef VMExecutionContext::getEvaledArg(const StringData* val) { +StaticString + s_php_namespace("get(key); if (&arg != &null_variant) return arg; } - String code = HPHP::concat3("getEvaledArg(fpi.phpCode()); + CVarRef v = g_vmContext->getEvaledArg( + fpi.phpCode(), + cls() ? cls()->nameRef() : nameRef() + ); pi->value = strdup(f_serialize(v).get()->data()); } // This is a raw char*, but its lifetime should be at least as long diff --git a/hphp/system/php/reflection/reflection.php b/hphp/system/php/reflection/reflection.php index a9e6f87b6..1e39d31ad 100644 --- a/hphp/system/php/reflection/reflection.php +++ b/hphp/system/php/reflection/reflection.php @@ -306,7 +306,25 @@ class ReflectionParameter implements Reflector { return $defaultValue; } + /** + * @deprecated + */ public function getDefaultValueText() { + return $this->getDefaultValueConstantName(); + } + + // This doc comment block generated by idl/sysdoc.php + /** + * ( excerpt from + * http://php.net/manual/en/reflectionparameter.getdefaultvalueconstantname.php + * ) + * + * WarningThis function is currently not documented; only its argument + * list is available. + * + * @return mixed Returns string on success or NULL on failure. + */ + public function getDefaultValueConstantName() { if (isset($this->info['defaultText'])) { return $this->info['defaultText']; } diff --git a/hphp/test/slow/namespace/const_param.php b/hphp/test/slow/namespace/const_param.php new file mode 100644 index 000000000..5ae1315be --- /dev/null +++ b/hphp/test/slow/namespace/const_param.php @@ -0,0 +1,28 @@ +getParameters(); + foreach ($params as $param) { + var_dump( + $param->getDefaultValue(), + $param->getDefaultValueConstantName() + ); + } + } +} diff --git a/hphp/test/slow/namespace/const_param.php.expectf b/hphp/test/slow/namespace/const_param.php.expectf new file mode 100644 index 000000000..11993cfb8 --- /dev/null +++ b/hphp/test/slow/namespace/const_param.php.expectf @@ -0,0 +1,28 @@ +string(14) "5.4.999-hiphop" +string(11) "PHP_VERSION" +string(1) "c" +string(1) "B" +array(1) { + [0]=> + string(14) "5.4.999-hiphop" +} +string(18) "array(PHP_VERSION)" +array(1) { + [0]=> + string(1) "c" +} +string(%d) "array%w(%a)" +string(14) "5.4.999-hiphop" +string(11) "PHP_VERSION" +string(1) "c" +string(1) "B" +array(1) { + [0]=> + string(14) "5.4.999-hiphop" +} +string(18) "array(PHP_VERSION)" +array(1) { + [0]=> + string(1) "c" +} +string(%d) "array%w(%a)"