Flutter Engine
The Flutter Engine
Static Public Member Functions | List of all members
dart::Evaluator Class Reference

#include <evaluator.h>

Inheritance diagram for dart::Evaluator:
dart::AllStatic

Static Public Member Functions

static int64_t TruncateTo (int64_t v, Representation r)
 
static IntegerPtr BinaryIntegerEvaluate (const Object &left, const Object &right, Token::Kind token_kind, bool is_truncating, Representation representation, Thread *thread)
 
static IntegerPtr UnaryIntegerEvaluate (const Object &value, Token::Kind token_kind, Representation representation, Thread *thread)
 
static IntegerPtr BitLengthEvaluate (const Object &value, Representation representation, Thread *thread)
 
static double EvaluateUnaryDoubleOp (const double value, Token::Kind token_kind, Representation representation)
 
static double EvaluateBinaryDoubleOp (const double left, const double right, Token::Kind token_kind, Representation representation)
 
static bool ToIntegerConstant (Value *value, int64_t *result)
 

Detailed Description

Definition at line 20 of file evaluator.h.

Member Function Documentation

◆ BinaryIntegerEvaluate()

IntegerPtr dart::Evaluator::BinaryIntegerEvaluate ( const Object left,
const Object right,
Token::Kind  token_kind,
bool  is_truncating,
Representation  representation,
Thread thread 
)
static

Definition at line 99 of file evaluator.cc.

104 {
105 if (!left.IsInteger() || !right.IsInteger()) {
106 return Integer::null();
107 }
108 Zone* zone = thread->zone();
109 const Integer& left_int = Integer::Cast(left);
110 const Integer& right_int = Integer::Cast(right);
111 Integer& result = Integer::Handle(
112 zone, BinaryIntegerEvaluateRaw(left_int, right_int, token_kind));
113
114 if (!result.IsNull()) {
115 if (is_truncating) {
116 const int64_t truncated =
117 TruncateTo(result.AsTruncatedInt64Value(), representation);
118 result = Integer::New(truncated, Heap::kOld);
120 result, representation, /*tagged_value_must_be_smi=*/true));
122 result, representation, /*tagged_value_must_be_smi=*/true)) {
123 // If this operation is not truncating it would deoptimize on overflow.
124 // Check that we match this behavior and don't produce a value that is
125 // larger than something this operation can produce. We could have
126 // specialized instructions that use this value under this assumption.
127 return Integer::null();
128 }
129 result ^= result.Canonicalize(thread);
130 }
131
132 return result.ptr();
133}
static int64_t TruncateTo(int64_t v, Representation r)
Definition: evaluator.cc:81
static bool IsConstantRepresentable(const Object &value, Representation target_rep, bool tagged_value_must_be_smi)
Definition: flow_graph.cc:205
@ kOld
Definition: heap.h:39
static IntegerPtr New(const String &str, Heap::Space space=Heap::kNew)
Definition: object.cc:22984
static ObjectPtr null()
Definition: object.h:433
static Object & Handle()
Definition: object.h:407
#define ASSERT(E)
GAsyncResult * result
static IntegerPtr BinaryIntegerEvaluateRaw(const Integer &left, const Integer &right, Token::Kind token_kind)
Definition: evaluator.cc:9

◆ BitLengthEvaluate()

IntegerPtr dart::Evaluator::BitLengthEvaluate ( const Object value,
Representation  representation,
Thread thread 
)
static

Definition at line 164 of file evaluator.cc.

166 {
167 if (!value.IsInteger()) {
168 return Integer::null();
169 }
170 Zone* zone = thread->zone();
171 const Integer& value_int = Integer::Cast(value);
172 Integer& result =
173 Integer::Handle(zone, BitLengthEvaluateRaw(value_int, zone));
174
175 if (!result.IsNull()) {
177 result, representation,
178 /*tagged_value_must_be_smi=*/true)) {
179 // If this operation is not truncating it would deoptimize on overflow.
180 // Check that we match this behavior and don't produce a value that is
181 // larger than something this operation can produce. We could have
182 // specialized instructions that use this value under this assumption.
183 return Integer::null();
184 }
185
186 result ^= result.Canonicalize(thread);
187 }
188
189 return result.ptr();
190}
uint8_t value
static IntegerPtr BitLengthEvaluateRaw(const Integer &value, Zone *zone)
Definition: evaluator.cc:71

◆ EvaluateBinaryDoubleOp()

double dart::Evaluator::EvaluateBinaryDoubleOp ( const double  left,
const double  right,
Token::Kind  token_kind,
Representation  representation 
)
static

Definition at line 238 of file evaluator.cc.

241 {
242 if (representation == kUnboxedDouble) {
243 switch (token_kind) {
244 case Token::kADD:
245 return left + right;
246 case Token::kSUB:
247 return left - right;
248 case Token::kMUL:
249 return left * right;
250 case Token::kDIV:
251 return Utils::DivideAllowZero(left, right);
252 case Token::kMIN:
253 return fmin(left, right);
254 case Token::kMAX:
255 return fmax(left, right);
256 default:
257 UNREACHABLE();
258 }
259 } else {
260 ASSERT(representation == kUnboxedFloat);
261 switch (token_kind) {
262 case Token::kADD:
263 return static_cast<float>(left) + static_cast<float>(right);
264 case Token::kSUB:
265 return static_cast<float>(left) - static_cast<float>(right);
266 case Token::kMUL:
267 return static_cast<float>(left) * static_cast<float>(right);
268 case Token::kDIV:
269 return Utils::DivideAllowZero(static_cast<float>(left),
270 static_cast<float>(right));
271 case Token::kMIN:
272 return fminf(static_cast<float>(left), static_cast<float>(right));
273 case Token::kMAX:
274 return fmaxf(static_cast<float>(left), static_cast<float>(right));
275 default:
276 UNREACHABLE();
277 }
278 }
279}
#define UNREACHABLE()
Definition: assert.h:248
static float DivideAllowZero(float a, float b)
Definition: utils.h:496

◆ EvaluateUnaryDoubleOp()

double dart::Evaluator::EvaluateUnaryDoubleOp ( const double  value,
Token::Kind  token_kind,
Representation  representation 
)
static

Definition at line 192 of file evaluator.cc.

194 {
195 // The different set of operations for float32 and float64 is due to the
196 // different set of operations made available by dart:core.double and
197 // dart:typed_data.Float64x2 versus dart:typed_data.Float32x4.
198 if (representation == kUnboxedDouble) {
199 switch (token_kind) {
200 case Token::kABS:
201 return fabs(value);
202 case Token::kNEGATE:
203 return -value;
204 case Token::kSQRT:
205 return sqrt(value);
206 case Token::kSQUARE:
207 return value * value;
208 case Token::kTRUNCATE:
209 return trunc(value);
210 case Token::kFLOOR:
211 return floor(value);
212 case Token::kCEILING:
213 return ceil(value);
214 default:
215 UNREACHABLE();
216 }
217 } else {
218 ASSERT(representation == kUnboxedFloat);
219 switch (token_kind) {
220 case Token::kABS:
221 return fabsf(static_cast<float>(value));
222 case Token::kNEGATE:
223 return -static_cast<float>(value);
224 case Token::kRECIPROCAL:
225 return 1.0f / static_cast<float>(value);
226 case Token::kRECIPROCAL_SQRT:
227 return sqrtf(1.0f / static_cast<float>(value));
228 case Token::kSQRT:
229 return sqrtf(static_cast<float>(value));
230 case Token::kSQUARE:
231 return static_cast<float>(value) * static_cast<float>(value);
232 default:
233 UNREACHABLE();
234 }
235 }
236}
SIN Vec< N, float > trunc(const Vec< N, float > &x)
Definition: SkVx.h:704
SIN Vec< N, float > sqrt(const Vec< N, float > &x)
Definition: SkVx.h:706
SIN Vec< N, float > floor(const Vec< N, float > &x)
Definition: SkVx.h:703
SIN Vec< N, float > ceil(const Vec< N, float > &x)
Definition: SkVx.h:702

◆ ToIntegerConstant()

bool dart::Evaluator::ToIntegerConstant ( Value value,
int64_t *  result 
)
static

Definition at line 281 of file evaluator.cc.

281 {
282 if (!value->BindsToConstant()) {
283 UnboxInstr* unbox = value->definition()->AsUnbox();
284 if (unbox != nullptr) {
285 switch (unbox->representation()) {
286 case kUnboxedDouble:
287 case kUnboxedInt64:
288 return ToIntegerConstant(unbox->value(), result);
289 case kUnboxedUint32:
290 if (ToIntegerConstant(unbox->value(), result)) {
291 *result = Evaluator::TruncateTo(*result, kUnboxedUint32);
292 return true;
293 }
294 break;
295 // No need to handle Unbox<Int32>(Constant(C)) because it gets
296 // canonicalized to UnboxedConstant<Int32>(C).
297 case kUnboxedInt32:
298 default:
299 break;
300 }
301 }
302 return false;
303 }
304 const Object& constant = value->BoundConstant();
305 if (constant.IsDouble()) {
306 const Double& double_constant = Double::Cast(constant);
307 *result = Utils::SafeDoubleToInt<int64_t>(double_constant.value());
308 return (static_cast<double>(*result) == double_constant.value());
309 } else if (constant.IsSmi()) {
310 *result = Smi::Cast(constant).Value();
311 return true;
312 } else if (constant.IsMint()) {
313 *result = Mint::Cast(constant).value();
314 return true;
315 }
316 return false;
317}
static bool ToIntegerConstant(Value *value, int64_t *result)
Definition: evaluator.cc:281

◆ TruncateTo()

int64_t dart::Evaluator::TruncateTo ( int64_t  v,
Representation  r 
)
static

Definition at line 81 of file evaluator.cc.

81 {
82 switch (r) {
83 case kTagged: {
84 const intptr_t kTruncateBits =
85 kBitsPerInt64 - (compiler::target::kSmiBits + 1 /*sign bit*/);
86 return Utils::ShiftLeftWithTruncation(v, kTruncateBits) >> kTruncateBits;
87 }
88 case kUnboxedInt32:
90 case kUnboxedUint32:
91 return v & kMaxUint32;
92 case kUnboxedInt64:
93 return v;
94 default:
96 }
97}
static int64_t ShiftLeftWithTruncation(int64_t a, int64_t b)
Definition: utils.h:464
constexpr intptr_t kSmiBits
Definition: runtime_api.h:301
constexpr uint32_t kMaxUint32
Definition: globals.h:484
constexpr intptr_t kBitsPerInt32
Definition: globals.h:466
constexpr intptr_t kBitsPerInt64
Definition: globals.h:467

◆ UnaryIntegerEvaluate()

IntegerPtr dart::Evaluator::UnaryIntegerEvaluate ( const Object value,
Token::Kind  token_kind,
Representation  representation,
Thread thread 
)
static

Definition at line 135 of file evaluator.cc.

138 {
139 if (!value.IsInteger()) {
140 return Integer::null();
141 }
142 Zone* zone = thread->zone();
143 const Integer& value_int = Integer::Cast(value);
144 Integer& result = Integer::Handle(
145 zone, UnaryIntegerEvaluateRaw(value_int, token_kind, zone));
146
147 if (!result.IsNull()) {
149 result, representation,
150 /*tagged_value_must_be_smi=*/true)) {
151 // If this operation is not truncating it would deoptimize on overflow.
152 // Check that we match this behavior and don't produce a value that is
153 // larger than something this operation can produce. We could have
154 // specialized instructions that use this value under this assumption.
155 return Integer::null();
156 }
157
158 result ^= result.Canonicalize(thread);
159 }
160
161 return result.ptr();
162}
static IntegerPtr UnaryIntegerEvaluateRaw(const Integer &value, Token::Kind token_kind, Zone *zone)
Definition: evaluator.cc:51

The documentation for this class was generated from the following files: