/usr/include/hphp/hhbbc/eval-cell.h is in hhvm-dev 3.21.0+dfsg-2ubuntu2.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 | /*
+----------------------------------------------------------------------+
| HipHop for PHP |
+----------------------------------------------------------------------+
| Copyright (c) 2010-present 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. |
+----------------------------------------------------------------------+
*/
#ifndef incl_HHBBC_EVAL_CELL_H_
#define incl_HHBBC_EVAL_CELL_H_
#include <stdexcept>
#include <exception>
#include <folly/ScopeGuard.h>
#include <folly/Optional.h>
#include "hphp/runtime/base/array-data.h"
#include "hphp/runtime/base/execution-context.h"
#include "hphp/runtime/base/string-data.h"
#include "hphp/runtime/base/tv-refcount.h"
#include "hphp/runtime/vm/repo.h"
#include "hphp/hhbbc/hhbbc.h"
#include "hphp/hhbbc/type-system.h"
namespace HPHP { namespace HHBBC {
//////////////////////////////////////////////////////////////////////
/*
* When constant-evaluating certain operations, it's possible they
* will return non-static objects, or throw exceptions (e.g. cellAdd()
* with an array and an int).
*
* This routine converts these things back to types. In the case of
* an exception it returns TInitCell.
*/
template<class Pred>
folly::Optional<Type> eval_cell(Pred p) {
try {
assert(!RuntimeOption::EvalJit);
ThrowAllErrorsSetter taes;
Cell c = p();
if (isRefcountedType(c.m_type)) {
switch (c.m_type) {
case KindOfString:
{
if (c.m_data.pstr->size() > Repo::get().stringLengthLimit()) {
tvDecRefCountable(&c);
return TStr;
}
auto const sstr = makeStaticString(c.m_data.pstr);
tvDecRefCountable(&c);
c = make_tv<KindOfPersistentString>(sstr);
}
break;
case KindOfArray:
{
auto const sarr = ArrayData::GetScalarArray(c.m_data.parr);
tvDecRefCountable(&c);
c = make_tv<KindOfPersistentArray>(sarr);
}
break;
case KindOfVec:
{
auto const sarr = ArrayData::GetScalarArray(c.m_data.parr);
tvDecRefCountable(&c);
c = make_tv<KindOfPersistentVec>(sarr);
}
break;
case KindOfDict:
{
auto const sarr = ArrayData::GetScalarArray(c.m_data.parr);
tvDecRefCountable(&c);
c = make_tv<KindOfPersistentDict>(sarr);
}
break;
case KindOfKeyset:
{
auto const sarr = ArrayData::GetScalarArray(c.m_data.parr);
tvDecRefCountable(&c);
c = make_tv<KindOfPersistentKeyset>(sarr);
}
break;
case KindOfUninit:
case KindOfNull:
case KindOfInt64:
case KindOfBoolean:
case KindOfDouble:
case KindOfPersistentString:
case KindOfPersistentArray:
case KindOfPersistentVec:
case KindOfPersistentDict:
case KindOfPersistentKeyset:
case KindOfObject:
case KindOfResource:
case KindOfRef:
always_assert(0 && "Impossible constant evaluation occurred");
}
}
/*
* We need to get rid of statics if we're not actually going to do
* constant propagation. When ConstantProp is on, the types we
* create here can reflect that we'll be changing bytecode later
* to actually make these into non-reference-counted SStr or
* SArrs. If we leave the bytecode alone, though, it generally
* won't actually be static at runtime.
*
* TODO(#3696042): loosen_statics here should ideally not give up
* on the array or string value, just its staticness.
*/
auto const t = from_cell(c);
return options.ConstantProp ? t : loosen_statics(t);
} catch (const Object&) {
return folly::none;
} catch (const std::exception&) {
return folly::none;
} catch (...) {
always_assert_flog(0, "a non-std::exception was thrown in eval_cell");
}
}
template<typename Pred>
folly::Optional<typename std::result_of<Pred()>::type>
eval_cell_value(Pred p) {
try {
ThrowAllErrorsSetter taes;
return p();
} catch (const Object&) {
return folly::none;
} catch (const std::exception&) {
return folly::none;
} catch (...) {
always_assert_flog(0, "a non-std::exception was thrown in eval_cell_value");
}
}
//////////////////////////////////////////////////////////////////////
}}
#endif
|