| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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/intermediate_language.h" | 5 #include "vm/intermediate_language.h" |
| 6 | 6 |
| 7 #include "vm/bit_vector.h" | 7 #include "vm/bit_vector.h" |
| 8 #include "vm/constant_propagator.h" | 8 #include "vm/constant_propagator.h" |
| 9 #include "vm/cpu.h" | 9 #include "vm/cpu.h" |
| 10 #include "vm/dart_entry.h" | 10 #include "vm/dart_entry.h" |
| (...skipping 3412 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3423 } | 3423 } |
| 3424 | 3424 |
| 3425 CreateArrayInstr* create_array = value()->definition()->AsCreateArray(); | 3425 CreateArrayInstr* create_array = value()->definition()->AsCreateArray(); |
| 3426 ASSERT(create_array != NULL); | 3426 ASSERT(create_array != NULL); |
| 3427 // Check if the string interpolation has only constant inputs. | 3427 // Check if the string interpolation has only constant inputs. |
| 3428 Value* num_elements = create_array->num_elements(); | 3428 Value* num_elements = create_array->num_elements(); |
| 3429 if (!num_elements->BindsToConstant() || | 3429 if (!num_elements->BindsToConstant() || |
| 3430 !num_elements->BoundConstant().IsSmi()) { | 3430 !num_elements->BoundConstant().IsSmi()) { |
| 3431 return this; | 3431 return this; |
| 3432 } | 3432 } |
| 3433 intptr_t length = Smi::Cast(num_elements->BoundConstant()).Value(); | 3433 const intptr_t length = Smi::Cast(num_elements->BoundConstant()).Value(); |
| 3434 GrowableArray<ConstantInstr*> constants(length); | 3434 Zone* zone = Thread::Current()->zone(); |
| 3435 GrowableHandlePtrArray<const String> pieces(zone, length); |
| 3435 for (intptr_t i = 0; i < length; i++) { | 3436 for (intptr_t i = 0; i < length; i++) { |
| 3436 constants.Add(NULL); | 3437 pieces.Add(Object::null_string()); |
| 3437 } | 3438 } |
| 3439 |
| 3438 for (Value::Iterator it(create_array->input_use_list()); | 3440 for (Value::Iterator it(create_array->input_use_list()); |
| 3439 !it.Done(); | 3441 !it.Done(); |
| 3440 it.Advance()) { | 3442 it.Advance()) { |
| 3441 Instruction* curr = it.Current()->instruction(); | 3443 Instruction* curr = it.Current()->instruction(); |
| 3442 if (curr != this) { | 3444 if (curr == this) continue; |
| 3443 StoreIndexedInstr* store = curr->AsStoreIndexed(); | 3445 |
| 3444 ASSERT(store != NULL); | 3446 StoreIndexedInstr* store = curr->AsStoreIndexed(); |
| 3445 if (store->value()->definition()->IsConstant()) { | 3447 if (!store->index()->BindsToConstant() || |
| 3446 ASSERT(store->index()->BindsToConstant()); | 3448 !store->index()->BoundConstant().IsSmi()) { |
| 3447 const Object& obj = store->value()->definition()->AsConstant()->value(); | 3449 return this; |
| 3448 if (obj.IsNumber() || obj.IsString() || obj.IsBool() || obj.IsNull()) { | 3450 } |
| 3449 constants[Smi::Cast(store->index()->BoundConstant()).Value()] = | 3451 intptr_t store_index = Smi::Cast(store->index()->BoundConstant()).Value(); |
| 3450 store->value()->definition()->AsConstant(); | 3452 ASSERT(store_index < length); |
| 3451 } else { | 3453 ASSERT(store != NULL); |
| 3452 return this; | 3454 if (store->value()->definition()->IsConstant()) { |
| 3453 } | 3455 ASSERT(store->index()->BindsToConstant()); |
| 3456 const Object& obj = store->value()->definition()->AsConstant()->value(); |
| 3457 // TODO(srdjan): Verify if any other types should be converted as well. |
| 3458 if (obj.IsString()) { |
| 3459 pieces.SetAt(store_index, String::Cast(obj)); |
| 3460 } else if (obj.IsSmi()) { |
| 3461 const char* cstr = obj.ToCString(); |
| 3462 pieces.SetAt(store_index, String::Handle(zone, String::New(cstr))); |
| 3463 } else if (obj.IsBool()) { |
| 3464 pieces.SetAt(store_index, |
| 3465 Bool::Cast(obj).value() ? Symbols::True() : Symbols::False()); |
| 3466 } else if (obj.IsNull()) { |
| 3467 pieces.SetAt(store_index, Symbols::Null()); |
| 3454 } else { | 3468 } else { |
| 3455 return this; | 3469 return this; |
| 3456 } | 3470 } |
| 3471 } else { |
| 3472 return this; |
| 3457 } | 3473 } |
| 3458 } | 3474 } |
| 3459 // Interpolate string at compile time. | 3475 |
| 3460 const Array& array_argument = | 3476 ASSERT(pieces.length() == length); |
| 3461 Array::Handle(Array::New(length)); | 3477 const String& concatenated = String::ZoneHandle(zone, |
| 3462 for (intptr_t i = 0; i < constants.length(); i++) { | 3478 Symbols::FromConcatAll(pieces)); |
| 3463 array_argument.SetAt(i, constants[i]->value()); | |
| 3464 } | |
| 3465 // Build argument array to pass to the interpolation function. | |
| 3466 const Array& interpolate_arg = Array::Handle(Array::New(1)); | |
| 3467 interpolate_arg.SetAt(0, array_argument); | |
| 3468 // Call interpolation function. | |
| 3469 const Object& result = Object::Handle( | |
| 3470 DartEntry::InvokeFunction(CallFunction(), interpolate_arg)); | |
| 3471 if (result.IsUnhandledException()) { | |
| 3472 return this; | |
| 3473 } | |
| 3474 ASSERT(result.IsString()); | |
| 3475 const String& concatenated = | |
| 3476 String::ZoneHandle(Symbols::New(String::Cast(result))); | |
| 3477 return flow_graph->GetConstant(concatenated); | 3479 return flow_graph->GetConstant(concatenated); |
| 3478 } | 3480 } |
| 3479 | 3481 |
| 3480 | 3482 |
| 3481 InvokeMathCFunctionInstr::InvokeMathCFunctionInstr( | 3483 InvokeMathCFunctionInstr::InvokeMathCFunctionInstr( |
| 3482 ZoneGrowableArray<Value*>* inputs, | 3484 ZoneGrowableArray<Value*>* inputs, |
| 3483 intptr_t deopt_id, | 3485 intptr_t deopt_id, |
| 3484 MethodRecognizer::Kind recognized_kind, | 3486 MethodRecognizer::Kind recognized_kind, |
| 3485 intptr_t token_pos) | 3487 intptr_t token_pos) |
| 3486 : PureDefinition(deopt_id), | 3488 : PureDefinition(deopt_id), |
| (...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3647 case Token::kTRUNCDIV: return 0; | 3649 case Token::kTRUNCDIV: return 0; |
| 3648 case Token::kMOD: return 1; | 3650 case Token::kMOD: return 1; |
| 3649 default: UNIMPLEMENTED(); return -1; | 3651 default: UNIMPLEMENTED(); return -1; |
| 3650 } | 3652 } |
| 3651 } | 3653 } |
| 3652 | 3654 |
| 3653 | 3655 |
| 3654 #undef __ | 3656 #undef __ |
| 3655 | 3657 |
| 3656 } // namespace dart | 3658 } // namespace dart |
| OLD | NEW |