| OLD | NEW |
| 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/kernel_binary_flowgraph.h" | 5 #include "vm/kernel_binary_flowgraph.h" |
| 6 | 6 |
| 7 #include "vm/object_store.h" |
| 8 |
| 7 #if !defined(DART_PRECOMPILED_RUNTIME) | 9 #if !defined(DART_PRECOMPILED_RUNTIME) |
| 8 | 10 |
| 9 namespace dart { | 11 namespace dart { |
| 10 namespace kernel { | 12 namespace kernel { |
| 11 | 13 |
| 12 #define Z (zone_) | 14 #define Z (zone_) |
| 13 #define H (translation_helper_) | 15 #define H (translation_helper_) |
| 16 #define I Isolate::Current() |
| 14 | 17 |
| 15 StreamingConstantEvaluator::StreamingConstantEvaluator( | 18 StreamingConstantEvaluator::StreamingConstantEvaluator( |
| 16 StreamingFlowGraphBuilder* builder, | 19 StreamingFlowGraphBuilder* builder, |
| 17 Zone* zone, | 20 Zone* zone, |
| 18 TranslationHelper* h, | 21 TranslationHelper* h, |
| 19 DartTypeTranslator* type_translator) | 22 DartTypeTranslator* type_translator) |
| 20 : builder_(builder), | 23 : builder_(builder), |
| 21 isolate_(Isolate::Current()), | 24 isolate_(Isolate::Current()), |
| 22 zone_(zone), | 25 zone_(zone), |
| 23 translation_helper_(*h), | 26 translation_helper_(*h), |
| 24 // type_translator_(*type_translator), | 27 // type_translator_(*type_translator), |
| 25 script_(Script::Handle( | 28 script_(Script::Handle( |
| 26 zone, | 29 zone, |
| 27 builder == NULL ? Script::null() | 30 builder == NULL ? Script::null() |
| 28 : builder_->parsed_function()->function().script())), | 31 : builder_->parsed_function()->function().script())), |
| 29 result_(Instance::Handle(zone)) {} | 32 result_(Instance::Handle(zone)) {} |
| 30 | 33 |
| 31 | 34 |
| 32 Instance& StreamingConstantEvaluator::EvaluateExpression() { | 35 Instance& StreamingConstantEvaluator::EvaluateExpression() { |
| 33 intptr_t offset = builder_->ReaderOffset(); | 36 intptr_t offset = builder_->ReaderOffset(); |
| 34 if (!GetCachedConstant(offset, &result_)) { | 37 if (!GetCachedConstant(offset, &result_)) { |
| 35 uint8_t payload = 0; | 38 uint8_t payload = 0; |
| 36 Tag tag = builder_->ReadTag(&payload); | 39 Tag tag = builder_->ReadTag(&payload); |
| 37 switch (tag) { | 40 switch (tag) { |
| 41 case kSymbolLiteral: |
| 42 EvaluateSymbolLiteral(); |
| 43 break; |
| 38 case kDoubleLiteral: | 44 case kDoubleLiteral: |
| 39 EvaluateDoubleLiteral(); | 45 EvaluateDoubleLiteral(); |
| 40 break; | 46 break; |
| 41 default: | 47 default: |
| 42 UNREACHABLE(); | 48 UNREACHABLE(); |
| 43 } | 49 } |
| 44 | 50 |
| 45 CacheConstantValue(offset, result_); | 51 CacheConstantValue(offset, result_); |
| 46 } | 52 } |
| 47 // We return a new `ZoneHandle` here on purpose: The intermediate language | 53 // We return a new `ZoneHandle` here on purpose: The intermediate language |
| 48 // instructions do not make a copy of the handle, so we do it. | 54 // instructions do not make a copy of the handle, so we do it. |
| 49 return dart::Instance::ZoneHandle(Z, result_.raw()); | 55 return dart::Instance::ZoneHandle(Z, result_.raw()); |
| 50 } | 56 } |
| 51 | 57 |
| 58 void StreamingConstantEvaluator::EvaluateSymbolLiteral() { |
| 59 int str_index = builder_->ReadUInt(); |
| 60 const dart::String& symbol_value = builder_->DartSymbol(str_index); |
| 61 |
| 62 const dart::Class& symbol_class = |
| 63 dart::Class::ZoneHandle(Z, I->object_store()->symbol_class()); |
| 64 ASSERT(!symbol_class.IsNull()); |
| 65 const dart::Function& symbol_constructor = Function::ZoneHandle( |
| 66 Z, symbol_class.LookupConstructor(Symbols::SymbolCtor())); |
| 67 ASSERT(!symbol_constructor.IsNull()); |
| 68 result_ ^= EvaluateConstConstructorCall( |
| 69 symbol_class, TypeArguments::Handle(Z), symbol_constructor, symbol_value); |
| 70 } |
| 71 |
| 52 void StreamingConstantEvaluator::EvaluateDoubleLiteral() { | 72 void StreamingConstantEvaluator::EvaluateDoubleLiteral() { |
| 53 int str_index = builder_->ReadUInt(); | 73 int str_index = builder_->ReadUInt(); |
| 54 result_ = dart::Double::New(builder_->DartString(str_index), Heap::kOld); | 74 result_ = dart::Double::New(builder_->DartString(str_index), Heap::kOld); |
| 55 result_ = H.Canonicalize(result_); | 75 result_ = H.Canonicalize(result_); |
| 56 } | 76 } |
| 57 | 77 |
| 78 RawObject* StreamingConstantEvaluator::EvaluateConstConstructorCall( |
| 79 const dart::Class& type_class, |
| 80 const TypeArguments& type_arguments, |
| 81 const Function& constructor, |
| 82 const Object& argument) { |
| 83 // Factories have one extra argument: the type arguments. |
| 84 // Constructors have 1 extra arguments: receiver. |
| 85 const int kNumArgs = 1; |
| 86 const int kNumExtraArgs = 1; |
| 87 const int num_arguments = kNumArgs + kNumExtraArgs; |
| 88 const Array& arg_values = |
| 89 Array::Handle(Z, Array::New(num_arguments, Heap::kOld)); |
| 90 Instance& instance = Instance::Handle(Z); |
| 91 if (!constructor.IsFactory()) { |
| 92 instance = Instance::New(type_class, Heap::kOld); |
| 93 if (!type_arguments.IsNull()) { |
| 94 ASSERT(type_arguments.IsInstantiated()); |
| 95 instance.SetTypeArguments( |
| 96 TypeArguments::Handle(Z, type_arguments.Canonicalize())); |
| 97 } |
| 98 arg_values.SetAt(0, instance); |
| 99 } else { |
| 100 // Prepend type_arguments to list of arguments to factory. |
| 101 ASSERT(type_arguments.IsZoneHandle()); |
| 102 arg_values.SetAt(0, type_arguments); |
| 103 } |
| 104 arg_values.SetAt((0 + kNumExtraArgs), argument); |
| 105 const Array& args_descriptor = Array::Handle( |
| 106 Z, ArgumentsDescriptor::New(num_arguments, Object::empty_array())); |
| 107 const Object& result = Object::Handle( |
| 108 Z, DartEntry::InvokeFunction(constructor, arg_values, args_descriptor)); |
| 109 ASSERT(!result.IsError()); |
| 110 if (constructor.IsFactory()) { |
| 111 // The factory method returns the allocated object. |
| 112 instance ^= result.raw(); |
| 113 } |
| 114 return H.Canonicalize(instance); |
| 115 } |
| 116 |
| 58 bool StreamingConstantEvaluator::GetCachedConstant(intptr_t kernel_offset, | 117 bool StreamingConstantEvaluator::GetCachedConstant(intptr_t kernel_offset, |
| 59 Instance* value) { | 118 Instance* value) { |
| 60 if (builder_ == NULL) return false; | 119 if (builder_ == NULL) return false; |
| 61 | 120 |
| 62 const Function& function = builder_->parsed_function()->function(); | 121 const Function& function = builder_->parsed_function()->function(); |
| 63 if (function.kind() == RawFunction::kImplicitStaticFinalGetter) { | 122 if (function.kind() == RawFunction::kImplicitStaticFinalGetter) { |
| 64 // Don't cache constants in initializer expressions. They get | 123 // Don't cache constants in initializer expressions. They get |
| 65 // evaluated only once. | 124 // evaluated only once. |
| 66 return false; | 125 return false; |
| 67 } | 126 } |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 154 // case kLogicalExpression: | 213 // case kLogicalExpression: |
| 155 // return LogicalExpression::ReadFrom(reader_); | 214 // return LogicalExpression::ReadFrom(reader_); |
| 156 // case kConditionalExpression: | 215 // case kConditionalExpression: |
| 157 // return ConditionalExpression::ReadFrom(reader_); | 216 // return ConditionalExpression::ReadFrom(reader_); |
| 158 // case kStringConcatenation: | 217 // case kStringConcatenation: |
| 159 // return StringConcatenation::ReadFrom(reader_); | 218 // return StringConcatenation::ReadFrom(reader_); |
| 160 // case kIsExpression: | 219 // case kIsExpression: |
| 161 // return IsExpression::ReadFrom(reader_); | 220 // return IsExpression::ReadFrom(reader_); |
| 162 // case kAsExpression: | 221 // case kAsExpression: |
| 163 // return AsExpression::ReadFrom(reader_); | 222 // return AsExpression::ReadFrom(reader_); |
| 164 // case kSymbolLiteral: | 223 case kSymbolLiteral: |
| 165 // return SymbolLiteral::ReadFrom(reader_); | 224 return BuildSymbolLiteral(); |
| 166 // case kTypeLiteral: | 225 // case kTypeLiteral: |
| 167 // return TypeLiteral::ReadFrom(reader_); | 226 // return TypeLiteral::ReadFrom(reader_); |
| 168 case kThisExpression: | 227 case kThisExpression: |
| 169 return BuildThisExpression(); | 228 return BuildThisExpression(); |
| 170 case kRethrow: | 229 case kRethrow: |
| 171 return BuildRethrow(); | 230 return BuildRethrow(); |
| 172 // case kThrow: | 231 // case kThrow: |
| 173 // return Throw::ReadFrom(reader_); | 232 // return Throw::ReadFrom(reader_); |
| 174 // case kListLiteral: | 233 // case kListLiteral: |
| 175 // return ListLiteral::ReadFrom(reader_, false); | 234 // return ListLiteral::ReadFrom(reader_, false); |
| 176 // case kConstListLiteral: | 235 // case kConstListLiteral: |
| 177 // return ListLiteral::ReadFrom(reader_, true); | 236 // return ListLiteral::ReadFrom(reader_, true); |
| 178 // case kMapLiteral: | 237 // case kMapLiteral: |
| 179 // return MapLiteral::ReadFrom(reader_, false); | 238 // return MapLiteral::ReadFrom(reader_, false); |
| 180 // case kConstMapLiteral: | 239 // case kConstMapLiteral: |
| 181 // return MapLiteral::ReadFrom(reader_, true); | 240 // return MapLiteral::ReadFrom(reader_, true); |
| 182 // case kAwaitExpression: | 241 // case kAwaitExpression: |
| 183 // return AwaitExpression::ReadFrom(reader_); | 242 // return AwaitExpression::ReadFrom(reader_); |
| 184 // case kFunctionExpression: | 243 // case kFunctionExpression: |
| 185 // return FunctionExpression::ReadFrom(reader_); | 244 // return FunctionExpression::ReadFrom(reader_); |
| 186 // case kLet: | 245 // case kLet: |
| 187 // return Let::ReadFrom(reader_); | 246 // return Let::ReadFrom(reader_); |
| 188 // case kBigIntLiteral: | 247 case kBigIntLiteral: |
| 189 // return BigintLiteral::ReadFrom(reader_); | 248 return BuildBigIntLiteral(); |
| 190 case kStringLiteral: | 249 case kStringLiteral: |
| 191 return BuildStringLiteral(); | 250 return BuildStringLiteral(); |
| 192 case kSpecialIntLiteral: | 251 case kSpecialIntLiteral: |
| 193 return BuildIntLiteral(payload); | 252 return BuildIntLiteral(payload); |
| 194 case kNegativeIntLiteral: | 253 case kNegativeIntLiteral: |
| 195 return BuildIntLiteral(true); | 254 return BuildIntLiteral(true); |
| 196 case kPositiveIntLiteral: | 255 case kPositiveIntLiteral: |
| 197 return BuildIntLiteral(false); | 256 return BuildIntLiteral(false); |
| 198 case kDoubleLiteral: | 257 case kDoubleLiteral: |
| 199 return BuildDoubleLiteral(); | 258 return BuildDoubleLiteral(); |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 327 return flow_graph_builder_->IntConstant(value); | 386 return flow_graph_builder_->IntConstant(value); |
| 328 } | 387 } |
| 329 | 388 |
| 330 Fragment StreamingFlowGraphBuilder::BuildInvalidExpression() { | 389 Fragment StreamingFlowGraphBuilder::BuildInvalidExpression() { |
| 331 // The frontend will take care of emitting normal errors (like | 390 // The frontend will take care of emitting normal errors (like |
| 332 // [NoSuchMethodError]s) and only emit [InvalidExpression]s in very special | 391 // [NoSuchMethodError]s) and only emit [InvalidExpression]s in very special |
| 333 // situations (e.g. an invalid annotation). | 392 // situations (e.g. an invalid annotation). |
| 334 return ThrowNoSuchMethodError(); | 393 return ThrowNoSuchMethodError(); |
| 335 } | 394 } |
| 336 | 395 |
| 396 Fragment StreamingFlowGraphBuilder::BuildSymbolLiteral() { |
| 397 SkipBytes(-1); // EvaluateExpression needs the tag. |
| 398 return Constant(constant_evaluator_.EvaluateExpression()); |
| 399 } |
| 400 |
| 337 Fragment StreamingFlowGraphBuilder::BuildThisExpression() { | 401 Fragment StreamingFlowGraphBuilder::BuildThisExpression() { |
| 338 return LoadLocal(scopes()->this_variable); | 402 return LoadLocal(scopes()->this_variable); |
| 339 } | 403 } |
| 340 | 404 |
| 341 Fragment StreamingFlowGraphBuilder::BuildRethrow() { | 405 Fragment StreamingFlowGraphBuilder::BuildRethrow() { |
| 342 TokenPosition position = ReadPosition(); | 406 TokenPosition position = ReadPosition(); |
| 343 Fragment instructions = DebugStepCheck(position); | 407 Fragment instructions = DebugStepCheck(position); |
| 344 instructions += LoadLocal(catch_block()->exception_var()); | 408 instructions += LoadLocal(catch_block()->exception_var()); |
| 345 instructions += PushArgument(); | 409 instructions += PushArgument(); |
| 346 instructions += LoadLocal(catch_block()->stack_trace_var()); | 410 instructions += LoadLocal(catch_block()->stack_trace_var()); |
| 347 instructions += PushArgument(); | 411 instructions += PushArgument(); |
| 348 instructions += RethrowException(position, catch_block()->catch_try_index()); | 412 instructions += RethrowException(position, catch_block()->catch_try_index()); |
| 349 | 413 |
| 350 return instructions; | 414 return instructions; |
| 351 } | 415 } |
| 352 | 416 |
| 417 Fragment StreamingFlowGraphBuilder::BuildBigIntLiteral() { |
| 418 const dart::String& value = DartString(ReadUInt()); |
| 419 return Constant(Integer::ZoneHandle(Z, Integer::New(value, Heap::kOld))); |
| 420 } |
| 421 |
| 353 Fragment StreamingFlowGraphBuilder::BuildStringLiteral() { | 422 Fragment StreamingFlowGraphBuilder::BuildStringLiteral() { |
| 354 intptr_t str_index = ReadUInt(); | 423 intptr_t str_index = ReadUInt(); |
| 355 return Constant(DartSymbol(str_index)); | 424 return Constant(DartSymbol(str_index)); |
| 356 } | 425 } |
| 357 | 426 |
| 358 Fragment StreamingFlowGraphBuilder::BuildIntLiteral(uint8_t payload) { | 427 Fragment StreamingFlowGraphBuilder::BuildIntLiteral(uint8_t payload) { |
| 359 int64_t value = static_cast<int32_t>(payload) - SpecializedIntLiteralBias; | 428 int64_t value = static_cast<int32_t>(payload) - SpecializedIntLiteralBias; |
| 360 return IntConstant(value); | 429 return IntConstant(value); |
| 361 } | 430 } |
| 362 | 431 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 375 } | 444 } |
| 376 | 445 |
| 377 Fragment StreamingFlowGraphBuilder::BuildNullLiteral() { | 446 Fragment StreamingFlowGraphBuilder::BuildNullLiteral() { |
| 378 return Constant(Instance::ZoneHandle(Z, Instance::null())); | 447 return Constant(Instance::ZoneHandle(Z, Instance::null())); |
| 379 } | 448 } |
| 380 | 449 |
| 381 } // namespace kernel | 450 } // namespace kernel |
| 382 } // namespace dart | 451 } // namespace dart |
| 383 | 452 |
| 384 #endif // !defined(DART_PRECOMPILED_RUNTIME) | 453 #endif // !defined(DART_PRECOMPILED_RUNTIME) |
| OLD | NEW |