PageRenderTime 50ms CodeModel.GetById 21ms RepoModel.GetById 1ms app.codeStats 0ms

/hphp/runtime/ext/std/ext_std_variable.cpp

https://github.com/tstarling/hiphop-php
C++ | 345 lines | 281 code | 38 blank | 26 comment | 55 complexity | 3e103ed1f6024c45efb5dbe6003f84d6 MD5 | raw file
  1. /*
  2. +----------------------------------------------------------------------+
  3. | HipHop for PHP |
  4. +----------------------------------------------------------------------+
  5. | Copyright (c) 2010-2013 Facebook, Inc. (http://www.facebook.com) |
  6. | Copyright (c) 1997-2010 The PHP Group |
  7. +----------------------------------------------------------------------+
  8. | This source file is subject to version 3.01 of the PHP license, |
  9. | that is bundled with this package in the file LICENSE, and is |
  10. | available through the world-wide-web at the following url: |
  11. | http://www.php.net/license/3_01.txt |
  12. | If you did not receive a copy of the PHP license and are unable to |
  13. | obtain it through the world-wide-web, please send a note to |
  14. | license@php.net so we can mail you a copy immediately. |
  15. +----------------------------------------------------------------------+
  16. */
  17. #include "hphp/runtime/ext/std/ext_std_variable.h"
  18. #include "hphp/runtime/base/variable-serializer.h"
  19. #include "hphp/runtime/base/variable-unserializer.h"
  20. #include "hphp/runtime/base/builtin-functions.h"
  21. #include "hphp/util/logger.h"
  22. namespace HPHP {
  23. ///////////////////////////////////////////////////////////////////////////////
  24. const StaticString
  25. s_unknown_type("unknown type"),
  26. s_boolean("boolean"),
  27. s_bool("bool"),
  28. s_integer("integer"),
  29. s_int("int"),
  30. s_float("float"),
  31. s_string("string"),
  32. s_object("object"),
  33. s_array("array"),
  34. s_null("null");
  35. String HHVM_FUNCTION(gettype, const Variant& v) {
  36. if (v.getType() == KindOfResource && v.getResourceData()->isInvalid()) {
  37. return s_unknown_type;
  38. }
  39. return getDataTypeString(v.getType());
  40. }
  41. String HHVM_FUNCTION(get_resource_type, const Resource& handle) {
  42. return handle->o_getResourceName();
  43. }
  44. bool HHVM_FUNCTION(boolval, const Variant& v) {
  45. return v.toBoolean();
  46. }
  47. int64_t HHVM_FUNCTION(intval, const Variant& v, int64_t base /* = 10 */) {
  48. return v.toInt64(base);
  49. }
  50. double HHVM_FUNCTION(floatval, const Variant& v) {
  51. return v.toDouble();
  52. }
  53. String HHVM_FUNCTION(strval, const Variant& v) {
  54. return v.toString();
  55. }
  56. bool HHVM_FUNCTION(settype, VRefParam var, const String& type) {
  57. if (type == s_boolean) var = var.toBoolean();
  58. else if (type == s_bool ) var = var.toBoolean();
  59. else if (type == s_integer) var = var.toInt64();
  60. else if (type == s_int ) var = var.toInt64();
  61. else if (type == s_float ) var = var.toDouble();
  62. else if (type == s_string ) var = var.toString();
  63. else if (type == s_array ) var = var.toArray();
  64. else if (type == s_object ) var = var.toObject();
  65. else if (type == s_null ) var = uninit_null();
  66. else return false;
  67. return true;
  68. }
  69. bool HHVM_FUNCTION(is_null, const Variant& v) {
  70. return is_null(v);
  71. }
  72. bool HHVM_FUNCTION(is_bool, const Variant& v) {
  73. return is_bool(v);
  74. }
  75. bool HHVM_FUNCTION(is_int, const Variant& v) {
  76. return is_int(v);
  77. }
  78. bool HHVM_FUNCTION(is_float, const Variant& v) {
  79. return is_double(v);
  80. }
  81. bool HHVM_FUNCTION(is_numeric, const Variant& v) {
  82. return v.isNumeric(true);
  83. }
  84. bool HHVM_FUNCTION(is_string, const Variant& v) {
  85. return is_string(v);
  86. }
  87. bool HHVM_FUNCTION(is_scalar, const Variant& v) {
  88. return v.isScalar();
  89. }
  90. bool HHVM_FUNCTION(is_array, const Variant& v) {
  91. return is_array(v);
  92. }
  93. bool HHVM_FUNCTION(is_object, const Variant& v) {
  94. return is_object(v);
  95. }
  96. bool HHVM_FUNCTION(is_resource, const Variant& v) {
  97. return (v.getType() == KindOfResource && !v.getResourceData()->isInvalid());
  98. }
  99. ///////////////////////////////////////////////////////////////////////////////
  100. // input/output
  101. Variant HHVM_FUNCTION(print_r, const Variant& expression,
  102. bool ret /* = false */) {
  103. Variant res;
  104. try {
  105. VariableSerializer vs(VariableSerializer::Type::PrintR);
  106. if (ret) {
  107. res = vs.serialize(expression, ret);
  108. } else {
  109. vs.serialize(expression, ret);
  110. res = true;
  111. }
  112. } catch (StringBufferLimitException &e) {
  113. raise_notice("print_r() exceeded max bytes limit");
  114. res = e.m_result;
  115. }
  116. return res;
  117. }
  118. Variant HHVM_FUNCTION(var_export, const Variant& expression,
  119. bool ret /* = false */) {
  120. Variant res;
  121. try {
  122. VariableSerializer vs(VariableSerializer::Type::VarExport);
  123. if (ret) {
  124. res = vs.serialize(expression, ret);
  125. } else {
  126. vs.serialize(expression, ret);
  127. res = true;
  128. }
  129. } catch (StringBufferLimitException &e) {
  130. raise_notice("var_export() exceeded max bytes limit");
  131. }
  132. return res;
  133. }
  134. void f_var_dump(const Variant& v) {
  135. VariableSerializer vs(VariableSerializer::Type::VarDump, 0, 2);
  136. // manipulate maxCount to match PHP behavior
  137. if (!v.isObject()) {
  138. vs.incMaxCount();
  139. }
  140. vs.serialize(v, false);
  141. }
  142. void f_var_dump(int _argc, const Variant& expression,
  143. const Array& _argv /* = null_array */) {
  144. f_var_dump(expression);
  145. for (int i = 0; i < _argv.size(); i++) {
  146. f_var_dump(_argv[i]);
  147. }
  148. }
  149. void HHVM_FUNCTION(debug_zval_dump, const Variant& variable) {
  150. VariableSerializer vs(VariableSerializer::Type::DebugDump);
  151. vs.serialize(variable, false);
  152. }
  153. String HHVM_FUNCTION(serialize, const Variant& value) {
  154. switch (value.getType()) {
  155. case KindOfUninit:
  156. case KindOfNull:
  157. return "N;";
  158. case KindOfBoolean:
  159. return value.getBoolean() ? "b:1;" : "b:0;";
  160. case KindOfInt64: {
  161. StringBuffer sb;
  162. sb.append("i:");
  163. sb.append(value.getInt64());
  164. sb.append(';');
  165. return sb.detach();
  166. }
  167. case KindOfStaticString:
  168. case KindOfString: {
  169. StringData *str = value.getStringData();
  170. StringBuffer sb;
  171. sb.append("s:");
  172. sb.append(str->size());
  173. sb.append(":\"");
  174. sb.append(str->data(), str->size());
  175. sb.append("\";");
  176. return sb.detach();
  177. }
  178. case KindOfArray: {
  179. ArrayData *arr = value.getArrayData();
  180. if (arr->empty()) return "a:0:{}";
  181. // fall-through
  182. }
  183. case KindOfObject:
  184. case KindOfResource:
  185. case KindOfDouble: {
  186. VariableSerializer vs(VariableSerializer::Type::Serialize);
  187. return vs.serialize(value, true);
  188. }
  189. default:
  190. assert(false);
  191. break;
  192. }
  193. return "";
  194. }
  195. Variant HHVM_FUNCTION(unserialize, const String& str,
  196. const Array& class_whitelist /* =[] */) {
  197. return unserialize_from_string(str, class_whitelist);
  198. }
  199. ///////////////////////////////////////////////////////////////////////////////
  200. // variable table
  201. Array HHVM_FUNCTION(get_defined_vars) {
  202. VarEnv* v = g_context->getVarEnv();
  203. if (v) {
  204. return v->getDefinedVariables();
  205. } else {
  206. return Array::Create();
  207. }
  208. }
  209. int64_t HHVM_FUNCTION(extract, const Array& var_array,
  210. int extract_type /* = EXTR_OVERWRITE */,
  211. const String& prefix /* = "" */) {
  212. bool reference = extract_type & EXTR_REFS;
  213. extract_type &= ~EXTR_REFS;
  214. VarEnv* v = g_context->getVarEnv();
  215. if (!v) return 0;
  216. int count = 0;
  217. for (ArrayIter iter(var_array); iter; ++iter) {
  218. String name = iter.first();
  219. StringData* nameData = name.get();
  220. switch (extract_type) {
  221. case EXTR_SKIP:
  222. if (v->lookup(nameData) != NULL) {
  223. continue;
  224. }
  225. break;
  226. case EXTR_IF_EXISTS:
  227. if (v->lookup(nameData) == NULL) {
  228. continue;
  229. }
  230. break;
  231. case EXTR_PREFIX_SAME:
  232. if (v->lookup(nameData) != NULL) {
  233. name = prefix + "_" + name;
  234. }
  235. break;
  236. case EXTR_PREFIX_ALL:
  237. name = prefix + "_" + name;
  238. break;
  239. case EXTR_PREFIX_INVALID:
  240. if (!is_valid_var_name(nameData->data(), nameData->size())) {
  241. name = prefix + "_" + name;
  242. }
  243. break;
  244. case EXTR_PREFIX_IF_EXISTS:
  245. if (v->lookup(nameData) == NULL) {
  246. continue;
  247. }
  248. name = prefix + "_" + name;
  249. break;
  250. default:
  251. break;
  252. }
  253. nameData = name.get();
  254. // skip invalid variable names, as in PHP
  255. if (!is_valid_var_name(nameData->data(), nameData->size())) {
  256. continue;
  257. }
  258. g_context->setVar(nameData, iter.nvSecond(), reference);
  259. count++;
  260. }
  261. return count;
  262. }
  263. /////////////////////////////////////////////////////////////////////////////
  264. #define EXTR_CONST(v) Native::registerConstant<KindOfInt64> \
  265. (makeStaticString("EXTR_" #v), EXTR_##v);
  266. void StandardExtension::initVariable() {
  267. EXTR_CONST(IF_EXISTS);
  268. EXTR_CONST(OVERWRITE);
  269. EXTR_CONST(PREFIX_ALL);
  270. EXTR_CONST(PREFIX_IF_EXISTS);
  271. EXTR_CONST(PREFIX_INVALID);
  272. EXTR_CONST(PREFIX_SAME);
  273. EXTR_CONST(REFS);
  274. EXTR_CONST(SKIP);
  275. HHVM_FE(is_null);
  276. HHVM_FE(is_bool);
  277. HHVM_FE(is_int);
  278. HHVM_FALIAS(is_integer, is_int);
  279. HHVM_FALIAS(is_long, is_int);
  280. HHVM_FE(is_float);
  281. HHVM_FALIAS(is_double, is_float);
  282. HHVM_FALIAS(is_real, is_float);
  283. HHVM_FE(is_numeric);
  284. HHVM_FE(is_string);
  285. HHVM_FE(is_scalar);
  286. HHVM_FE(is_array);
  287. HHVM_FE(is_object);
  288. HHVM_FE(is_resource);
  289. HHVM_FE(boolval);
  290. HHVM_FE(intval);
  291. HHVM_FE(floatval);
  292. HHVM_FALIAS(doubleval, floatval);
  293. HHVM_FE(strval);
  294. HHVM_FE(gettype);
  295. HHVM_FE(get_resource_type);
  296. HHVM_FE(settype);
  297. HHVM_FE(print_r);
  298. HHVM_FE(var_export);
  299. HHVM_FE(debug_zval_dump);
  300. HHVM_FE(serialize);
  301. HHVM_FE(unserialize);
  302. HHVM_FE(get_defined_vars);
  303. HHVM_FE(extract);
  304. loadSystemlib("std_variable");
  305. }
  306. ///////////////////////////////////////////////////////////////////////////////
  307. } // namespace HPHP