Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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/flow_graph_builder.h" | 5 #include "vm/flow_graph_builder.h" |
| 6 | 6 |
| 7 #include "vm/ast_printer.h" | 7 #include "vm/ast_printer.h" |
| 8 #include "vm/code_descriptors.h" | 8 #include "vm/code_descriptors.h" |
| 9 #include "vm/dart_entry.h" | 9 #include "vm/dart_entry.h" |
| 10 #include "vm/flags.h" | 10 #include "vm/flags.h" |
| (...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 170 value = new UseVal(assert_boolean); | 170 value = new UseVal(assert_boolean); |
| 171 } | 171 } |
| 172 BranchInstr* branch = new BranchInstr(value); | 172 BranchInstr* branch = new BranchInstr(value); |
| 173 AddInstruction(branch); | 173 AddInstruction(branch); |
| 174 CloseFragment(); | 174 CloseFragment(); |
| 175 true_successor_address_ = branch->true_successor_address(); | 175 true_successor_address_ = branch->true_successor_address(); |
| 176 false_successor_address_ = branch->false_successor_address(); | 176 false_successor_address_ = branch->false_successor_address(); |
| 177 } | 177 } |
| 178 | 178 |
| 179 | 179 |
| 180 void ArgumentGraphVisitor::ReturnValue(Value* value) { | |
| 181 value_ = value; | |
| 182 if (value->IsConstant()) { | |
| 183 BindInstr* defn = new BindInstr(temp_index(), value); | |
| 184 AddInstruction(defn); | |
| 185 value_ = new UseVal(defn); | |
| 186 AllocateTempIndex(); | |
| 187 } | |
| 188 } | |
| 189 | |
| 190 | |
| 191 void EffectGraphVisitor::Bailout(const char* reason) { | 180 void EffectGraphVisitor::Bailout(const char* reason) { |
| 192 owner()->Bailout(reason); | 181 owner()->Bailout(reason); |
| 193 } | 182 } |
| 194 | 183 |
| 195 | 184 |
| 196 // <Statement> ::= Return { value: <Expression> | 185 // <Statement> ::= Return { value: <Expression> |
| 197 // inlined_finally_list: <InlinedFinally>* } | 186 // inlined_finally_list: <InlinedFinally>* } |
| 198 void EffectGraphVisitor::VisitReturnNode(ReturnNode* node) { | 187 void EffectGraphVisitor::VisitReturnNode(ReturnNode* node) { |
| 199 ValueGraphVisitor for_value(owner(), temp_index()); | 188 ValueGraphVisitor for_value(owner(), temp_index()); |
| 200 node->value()->Visit(&for_value); | 189 node->value()->Visit(&for_value); |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 216 const bool is_static = owner()->parsed_function().function().is_static(); | 205 const bool is_static = owner()->parsed_function().function().is_static(); |
| 217 // Implicit getters do not need a type check at return, unless they compute | 206 // Implicit getters do not need a type check at return, unless they compute |
| 218 // the initial value of a static field. | 207 // the initial value of a static field. |
| 219 if (is_static || !is_implicit_getter) { | 208 if (is_static || !is_implicit_getter) { |
| 220 const AbstractType& dst_type = | 209 const AbstractType& dst_type = |
| 221 AbstractType::ZoneHandle( | 210 AbstractType::ZoneHandle( |
| 222 owner()->parsed_function().function().result_type()); | 211 owner()->parsed_function().function().result_type()); |
| 223 const String& dst_name = | 212 const String& dst_name = |
| 224 String::ZoneHandle(String::NewSymbol("function result")); | 213 String::ZoneHandle(String::NewSymbol("function result")); |
| 225 return_value = BuildAssignableValue(node->id(), | 214 return_value = BuildAssignableValue(node->id(), |
| 226 node->value()->token_index(), | 215 node->value(), |
| 227 return_value, | 216 return_value, |
| 228 dst_type, | 217 dst_type, |
| 229 dst_name, | 218 dst_name, |
| 230 temp_index()); | 219 temp_index()); |
| 231 } | 220 } |
| 232 } | 221 } |
| 233 | 222 |
| 234 intptr_t current_context_level = owner()->context_level(); | 223 intptr_t current_context_level = owner()->context_level(); |
| 235 ASSERT(current_context_level >= 0); | 224 ASSERT(current_context_level >= 0); |
| 236 if (owner()->parsed_function().saved_context_var() != NULL) { | 225 if (owner()->parsed_function().saved_context_var() != NULL) { |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 247 CloseFragment(); | 236 CloseFragment(); |
| 248 } | 237 } |
| 249 | 238 |
| 250 | 239 |
| 251 // <Expression> ::= Literal { literal: Instance } | 240 // <Expression> ::= Literal { literal: Instance } |
| 252 void EffectGraphVisitor::VisitLiteralNode(LiteralNode* node) { | 241 void EffectGraphVisitor::VisitLiteralNode(LiteralNode* node) { |
| 253 return; | 242 return; |
| 254 } | 243 } |
| 255 | 244 |
| 256 void ValueGraphVisitor::VisitLiteralNode(LiteralNode* node) { | 245 void ValueGraphVisitor::VisitLiteralNode(LiteralNode* node) { |
| 257 ReturnValue(new ConstantVal(node->literal())); | 246 ReturnComputation(new ConstantVal(node->literal())); |
| 258 } | 247 } |
| 259 | 248 |
| 260 void TestGraphVisitor::VisitLiteralNode(LiteralNode* node) { | |
| 261 ReturnValue(new ConstantVal(node->literal())); | |
| 262 } | |
| 263 | |
| 264 | |
| 265 // Type nodes only occur as the right-hand side of instanceof comparisons, | 249 // Type nodes only occur as the right-hand side of instanceof comparisons, |
| 266 // and they are handled specially in that context. | 250 // and they are handled specially in that context. |
| 267 void EffectGraphVisitor::VisitTypeNode(TypeNode* node) { UNREACHABLE(); } | 251 void EffectGraphVisitor::VisitTypeNode(TypeNode* node) { UNREACHABLE(); } |
| 268 | 252 |
| 269 | 253 |
| 270 // Returns true if the type check can be skipped, for example, if the type is | 254 // Returns true if the type check can be skipped, for example, if the type is |
| 271 // Dynamic or if the value is a compile time constant and an instance of type. | 255 // Dynamic or if the value is a compile time constant and an instance of type. |
| 272 static bool CanSkipTypeCheck(Value* value, const AbstractType& dst_type) { | 256 static bool CanSkipTypeCheck(AstNode* value, const AbstractType& dst_type) { |
| 273 ASSERT(FLAG_enable_type_checks); | 257 ASSERT(FLAG_enable_type_checks); |
| 274 ASSERT(!dst_type.IsNull()); | 258 ASSERT(!dst_type.IsNull()); |
| 275 ASSERT(dst_type.IsFinalized()); | 259 ASSERT(dst_type.IsFinalized()); |
| 276 | 260 |
| 277 // Any expression is assignable to the Dynamic type and to the Object type. | 261 // Any expression is assignable to the Dynamic type and to the Object type. |
| 278 // Skip the test. | 262 // Skip the test. |
| 279 if (!dst_type.IsMalformed() && | 263 if (!dst_type.IsMalformed() && |
| 280 (dst_type.IsDynamicType() || dst_type.IsObjectType())) { | 264 (dst_type.IsDynamicType() || dst_type.IsObjectType())) { |
| 281 return true; | 265 return true; |
| 282 } | 266 } |
| 283 | 267 |
| 284 // It is a compile-time error to explicitly return a value (including null) | 268 // It is a compile-time error to explicitly return a value (including null) |
| 285 // from a void function. However, functions that do not explicitly return a | 269 // from a void function. However, functions that do not explicitly return a |
| 286 // value, implicitly return null. This includes void functions. Therefore, we | 270 // value, implicitly return null. This includes void functions. Therefore, we |
| 287 // skip the type test here and trust the parser to only return null in void | 271 // skip the type test here and trust the parser to only return null in void |
| 288 // function. | 272 // function. |
| 289 if (dst_type.IsVoidType()) { | 273 if (dst_type.IsVoidType()) { |
| 290 return true; | 274 return true; |
| 291 } | 275 } |
| 292 | 276 |
| 293 // Eliminate the test if it can be performed successfully at compile time. | 277 // Eliminate the test if it can be performed successfully at compile time. |
| 294 if ((value != NULL) && value->IsConstant()) { | 278 if ((value != NULL) && value->IsLiteralNode()) { |
|
Kevin Millikin (Google)
2012/04/30 14:54:53
We still need this constant check, because in the
| |
| 295 Instance& literal_value = Instance::Handle(); | 279 const Instance& literal_value = value->AsLiteralNode()->literal(); |
| 296 literal_value ^= value->AsConstant()->value().raw(); | |
| 297 const Class& cls = Class::Handle(literal_value.clazz()); | 280 const Class& cls = Class::Handle(literal_value.clazz()); |
| 298 if (cls.IsNullClass()) { | 281 if (cls.IsNullClass()) { |
| 299 // There are only three instances that can be of Class Null: | 282 // There are only three instances that can be of Class Null: |
| 300 // Object::null(), Object::sentinel(), and Object::transition_sentinel(). | 283 // Object::null(), Object::sentinel(), and Object::transition_sentinel(). |
| 301 // The inline code and run time code performing the type check will never | 284 // The inline code and run time code performing the type check will never |
| 302 // encounter the 2 sentinel values. The type check of a sentinel value | 285 // encounter the 2 sentinel values. The type check of a sentinel value |
| 303 // will always be eliminated here, because these sentinel values can only | 286 // will always be eliminated here, because these sentinel values can only |
| 304 // be encountered as constants, never as actual value of an heap object | 287 // be encountered as constants, never as actual value of an heap object |
| 305 // being type checked. | 288 // being type checked. |
| 306 ASSERT(literal_value.IsNull() || | 289 ASSERT(literal_value.IsNull() || |
| 307 (literal_value.raw() == Object::sentinel()) || | 290 (literal_value.raw() == Object::sentinel()) || |
| 308 (literal_value.raw() == Object::transition_sentinel())); | 291 (literal_value.raw() == Object::transition_sentinel())); |
| 309 return true; | 292 return true; |
| 310 } | 293 } |
| 311 Error& malformed_error = Error::Handle(); | 294 Error& malformed_error = Error::Handle(); |
| 312 if (!dst_type.IsMalformed() && | 295 if (!dst_type.IsMalformed() && |
| 313 dst_type.IsInstantiated() && | 296 dst_type.IsInstantiated() && |
| 314 literal_value.IsInstanceOf(dst_type, | 297 literal_value.IsInstanceOf(dst_type, |
| 315 TypeArguments::Handle(), | 298 TypeArguments::Handle(), |
| 316 &malformed_error)) { | 299 &malformed_error)) { |
| 317 return true; | 300 return true; |
| 318 } | 301 } |
| 319 } | 302 } |
| 303 | |
| 320 return false; | 304 return false; |
| 321 } | 305 } |
| 322 | 306 |
| 323 | 307 |
| 324 // <Expression> :: Assignable { expr: <Expression> | 308 // <Expression> :: Assignable { expr: <Expression> |
| 325 // type: AbstractType | 309 // type: AbstractType |
| 326 // dst_name: String } | 310 // dst_name: String } |
| 327 void EffectGraphVisitor::VisitAssignableNode(AssignableNode* node) { | 311 void EffectGraphVisitor::VisitAssignableNode(AssignableNode* node) { |
| 328 UNREACHABLE(); | 312 UNREACHABLE(); |
| 329 } | 313 } |
| 330 | 314 |
| 331 | 315 |
| 332 void ValueGraphVisitor::VisitAssignableNode(AssignableNode* node) { | 316 void ValueGraphVisitor::VisitAssignableNode(AssignableNode* node) { |
| 333 ValueGraphVisitor for_value(owner(), temp_index()); | 317 ValueGraphVisitor for_value(owner(), temp_index()); |
| 334 node->expr()->Visit(&for_value); | 318 node->expr()->Visit(&for_value); |
| 335 Append(for_value); | 319 Append(for_value); |
| 336 ReturnValue(BuildAssignableValue(node->id(), | 320 ReturnValue(BuildAssignableValue(node->id(), |
| 337 node->token_index(), | 321 node->expr(), |
|
Kevin Millikin (Google)
2012/04/30 14:54:53
This changes the token index from node->token_inde
| |
| 338 for_value.value(), | 322 for_value.value(), |
| 339 node->type(), | 323 node->type(), |
| 340 node->dst_name(), | 324 node->dst_name(), |
| 341 temp_index())); | 325 temp_index())); |
| 342 } | 326 } |
| 343 | 327 |
| 344 | 328 |
| 345 // <Expression> :: BinaryOp { kind: Token::Kind | 329 // <Expression> :: BinaryOp { kind: Token::Kind |
| 346 // left: <Expression> | 330 // left: <Expression> |
| 347 // right: <Expression> } | 331 // right: <Expression> } |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 358 EffectGraphVisitor for_right(owner(), temp_index()); | 342 EffectGraphVisitor for_right(owner(), temp_index()); |
| 359 node->right()->Visit(&for_right); | 343 node->right()->Visit(&for_right); |
| 360 EffectGraphVisitor empty(owner(), temp_index()); | 344 EffectGraphVisitor empty(owner(), temp_index()); |
| 361 if (node->kind() == Token::kAND) { | 345 if (node->kind() == Token::kAND) { |
| 362 Join(for_left, for_right, empty); | 346 Join(for_left, for_right, empty); |
| 363 } else { | 347 } else { |
| 364 Join(for_left, empty, for_right); | 348 Join(for_left, empty, for_right); |
| 365 } | 349 } |
| 366 return; | 350 return; |
| 367 } | 351 } |
| 368 ArgumentGraphVisitor for_left_value(owner(), temp_index()); | 352 ValueGraphVisitor for_left_value(owner(), temp_index()); |
| 369 node->left()->Visit(&for_left_value); | 353 node->left()->Visit(&for_left_value); |
| 370 Append(for_left_value); | 354 Append(for_left_value); |
| 371 ArgumentGraphVisitor for_right_value(owner(), for_left_value.temp_index()); | 355 ValueGraphVisitor for_right_value(owner(), for_left_value.temp_index()); |
| 372 node->right()->Visit(&for_right_value); | 356 node->right()->Visit(&for_right_value); |
| 373 Append(for_right_value); | 357 Append(for_right_value); |
| 374 ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(2); | 358 ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(2); |
| 375 arguments->Add(for_left_value.value()); | 359 arguments->Add(for_left_value.value()); |
| 376 arguments->Add(for_right_value.value()); | 360 arguments->Add(for_right_value.value()); |
| 377 const String& name = String::ZoneHandle(String::NewSymbol(node->Name())); | 361 const String& name = String::ZoneHandle(String::NewSymbol(node->Name())); |
| 378 InstanceCallComp* call = new InstanceCallComp(node->id(), | 362 InstanceCallComp* call = new InstanceCallComp(node->id(), |
| 379 node->token_index(), | 363 node->token_index(), |
| 380 owner()->try_index(), | 364 owner()->try_index(), |
| 381 name, | 365 name, |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 401 TestGraphVisitor for_test(owner(), | 385 TestGraphVisitor for_test(owner(), |
| 402 temp_index(), | 386 temp_index(), |
| 403 node->left()->id(), | 387 node->left()->id(), |
| 404 node->left()->token_index()); | 388 node->left()->token_index()); |
| 405 node->left()->Visit(&for_test); | 389 node->left()->Visit(&for_test); |
| 406 | 390 |
| 407 ValueGraphVisitor for_right(owner(), temp_index()); | 391 ValueGraphVisitor for_right(owner(), temp_index()); |
| 408 node->right()->Visit(&for_right); | 392 node->right()->Visit(&for_right); |
| 409 Value* right_value = for_right.value(); | 393 Value* right_value = for_right.value(); |
| 410 if (FLAG_enable_type_checks) { | 394 if (FLAG_enable_type_checks) { |
| 411 AssertBooleanComp* assert_boolean = | 395 BindInstr* assert_boolean = |
| 412 new AssertBooleanComp(node->right()->id(), | 396 new BindInstr(temp_index(), |
| 413 node->right()->token_index(), | 397 new AssertBooleanComp(node->right()->id(), |
| 414 owner()->try_index(), | 398 node->right()->token_index(), |
| 415 right_value); | 399 owner()->try_index(), |
| 416 for_right.AddInstruction(new BindInstr(temp_index(), assert_boolean)); | 400 right_value)); |
| 417 right_value = new TempVal(temp_index()); | 401 for_right.AddInstruction(assert_boolean); |
| 402 right_value = new UseVal(assert_boolean); | |
| 418 } | 403 } |
| 404 BindInstr* constant_true = | |
| 405 new BindInstr(temp_index(), new ConstantVal(bool_true)); | |
| 406 for_right.AddInstruction(constant_true); | |
| 419 StrictCompareComp* comp = new StrictCompareComp(Token::kEQ_STRICT, | 407 StrictCompareComp* comp = new StrictCompareComp(Token::kEQ_STRICT, |
| 420 right_value, new ConstantVal(bool_true)); | 408 right_value, new UseVal(constant_true)); |
| 421 for_right.AddInstruction(new BindInstr(temp_index(), comp)); | 409 for_right.AddInstruction(new BindInstr(temp_index(), comp)); |
| 422 | 410 |
| 423 if (node->kind() == Token::kAND) { | 411 if (node->kind() == Token::kAND) { |
| 424 ValueGraphVisitor for_false(owner(), temp_index()); | 412 ValueGraphVisitor for_false(owner(), temp_index()); |
| 425 for_false.AddInstruction( | 413 for_false.ReturnComputation(new ConstantVal(bool_false)); |
| 426 new BindInstr(temp_index(), new ConstantVal(bool_false))); | |
| 427 Join(for_test, for_right, for_false); | 414 Join(for_test, for_right, for_false); |
| 428 } else { | 415 } else { |
| 429 ASSERT(node->kind() == Token::kOR); | 416 ASSERT(node->kind() == Token::kOR); |
| 430 ValueGraphVisitor for_true(owner(), temp_index()); | 417 ValueGraphVisitor for_true(owner(), temp_index()); |
| 431 for_true.AddInstruction( | 418 for_true.ReturnComputation(new ConstantVal(bool_true)); |
| 432 new BindInstr(temp_index(), new ConstantVal(bool_true))); | |
| 433 Join(for_test, for_true, for_right); | 419 Join(for_test, for_true, for_right); |
| 434 } | 420 } |
| 435 ReturnValue(new TempVal(AllocateTempIndex())); | 421 ReturnValue(new TempVal(AllocateTempIndex())); |
| 436 return; | 422 return; |
| 437 } | 423 } |
| 438 EffectGraphVisitor::VisitBinaryOpNode(node); | 424 EffectGraphVisitor::VisitBinaryOpNode(node); |
| 439 } | 425 } |
| 440 | 426 |
| 441 | 427 |
| 442 void EffectGraphVisitor::CompiletimeStringInterpolation( | 428 void EffectGraphVisitor::CompiletimeStringInterpolation( |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 455 String& concatenated = String::ZoneHandle(); | 441 String& concatenated = String::ZoneHandle(); |
| 456 concatenated ^= DartEntry::InvokeStatic(interpol_func, | 442 concatenated ^= DartEntry::InvokeStatic(interpol_func, |
| 457 interpolate_arg, | 443 interpolate_arg, |
| 458 kNoArgumentNames); | 444 kNoArgumentNames); |
| 459 if (concatenated.IsUnhandledException()) { | 445 if (concatenated.IsUnhandledException()) { |
| 460 // TODO(srdjan): Remove this node and this UNREACHABLE. | 446 // TODO(srdjan): Remove this node and this UNREACHABLE. |
| 461 UNREACHABLE(); | 447 UNREACHABLE(); |
| 462 } | 448 } |
| 463 ASSERT(!concatenated.IsNull()); | 449 ASSERT(!concatenated.IsNull()); |
| 464 concatenated = String::NewSymbol(concatenated); | 450 concatenated = String::NewSymbol(concatenated); |
| 465 ReturnValue(new ConstantVal(concatenated)); | 451 ReturnComputation(new ConstantVal(concatenated)); |
| 466 } | 452 } |
| 467 | 453 |
| 468 | 454 |
| 469 | 455 |
| 470 // TODO(srdjan): Remove this node once the "+" string operator has been | 456 // TODO(srdjan): Remove this node once the "+" string operator has been |
| 471 // eliminated. | 457 // eliminated. |
| 472 void EffectGraphVisitor::VisitStringConcatNode(StringConcatNode* node) { | 458 void EffectGraphVisitor::VisitStringConcatNode(StringConcatNode* node) { |
| 473 const String& cls_name = String::Handle(String::NewSymbol("StringBase")); | 459 const String& cls_name = String::Handle(String::NewSymbol("StringBase")); |
| 474 const Library& core_lib = Library::Handle( | 460 const Library& core_lib = Library::Handle( |
| 475 Isolate::Current()->object_store()->core_library()); | 461 Isolate::Current()->object_store()->core_library()); |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 515 ReturnComputation(call); | 501 ReturnComputation(call); |
| 516 } | 502 } |
| 517 | 503 |
| 518 | 504 |
| 519 void EffectGraphVisitor::BuildAssertAssignable(intptr_t node_id, | 505 void EffectGraphVisitor::BuildAssertAssignable(intptr_t node_id, |
| 520 intptr_t token_index, | 506 intptr_t token_index, |
| 521 Value* value, | 507 Value* value, |
| 522 const AbstractType& dst_type, | 508 const AbstractType& dst_type, |
| 523 const String& dst_name, | 509 const String& dst_name, |
| 524 intptr_t start_index) { | 510 intptr_t start_index) { |
| 525 // We should not call this function if the type check can be skipped. | |
| 526 ASSERT(!CanSkipTypeCheck(value, dst_type)); | |
| 527 | |
| 528 // Build the type check computation. | 511 // Build the type check computation. |
| 529 Value* instantiator_type_arguments = NULL; | 512 Value* instantiator_type_arguments = NULL; |
| 530 if (!dst_type.IsInstantiated()) { | 513 if (!dst_type.IsInstantiated()) { |
| 531 instantiator_type_arguments = | 514 instantiator_type_arguments = |
| 532 BuildInstantiatorTypeArguments(token_index, start_index + 1); | 515 BuildInstantiatorTypeArguments(token_index, start_index + 1); |
| 533 } | 516 } |
| 534 AssertAssignableComp* assert_assignable = | 517 AssertAssignableComp* assert_assignable = |
| 535 new AssertAssignableComp(node_id, | 518 new AssertAssignableComp(node_id, |
| 536 token_index, | 519 token_index, |
| 537 owner()->try_index(), | 520 owner()->try_index(), |
| 538 value, | 521 value, |
| 539 instantiator_type_arguments, | 522 instantiator_type_arguments, |
| 540 dst_type, | 523 dst_type, |
| 541 dst_name); | 524 dst_name); |
| 542 AddInstruction(new DoInstr(assert_assignable)); | 525 AddInstruction(new DoInstr(assert_assignable)); |
| 543 } | 526 } |
| 544 | 527 |
| 545 | 528 |
| 546 Value* EffectGraphVisitor::BuildAssignableValue(intptr_t node_id, | 529 Value* EffectGraphVisitor::BuildAssignableValue(intptr_t node_id, |
| 547 intptr_t token_index, | 530 AstNode* value_node, |
| 548 Value* value, | 531 Value* value, |
| 549 const AbstractType& dst_type, | 532 const AbstractType& dst_type, |
| 550 const String& dst_name, | 533 const String& dst_name, |
| 551 intptr_t start_index) { | 534 intptr_t start_index) { |
| 552 if (CanSkipTypeCheck(value, dst_type)) { | 535 if (CanSkipTypeCheck(value_node, dst_type)) { |
| 553 return value; | 536 return value; |
| 554 } | 537 } |
| 555 | 538 |
| 556 // Build the type check computation. | 539 // Build the type check computation. |
| 557 Value* instantiator_type_arguments = NULL; | 540 Value* instantiator_type_arguments = NULL; |
| 558 if (!dst_type.IsInstantiated()) { | 541 if (!dst_type.IsInstantiated()) { |
| 559 instantiator_type_arguments = | 542 instantiator_type_arguments = |
| 560 BuildInstantiatorTypeArguments(token_index, start_index + 1); | 543 BuildInstantiatorTypeArguments(value_node->token_index(), |
| 544 start_index + 1); | |
| 561 } | 545 } |
| 562 BindInstr* assert_assignable = | 546 BindInstr* assert_assignable = |
| 563 new BindInstr(start_index, | 547 new BindInstr(start_index, |
| 564 new AssertAssignableComp(node_id, | 548 new AssertAssignableComp(node_id, |
| 565 token_index, | 549 value_node->token_index(), |
| 566 owner()->try_index(), | 550 owner()->try_index(), |
| 567 value, | 551 value, |
| 568 instantiator_type_arguments, | 552 instantiator_type_arguments, |
| 569 dst_type, | 553 dst_type, |
| 570 dst_name)); | 554 dst_name)); |
| 571 AddInstruction(assert_assignable); | 555 AddInstruction(assert_assignable); |
| 572 return new UseVal(assert_assignable); | 556 return new UseVal(assert_assignable); |
| 573 } | 557 } |
| 574 | 558 |
| 575 | 559 |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 591 // All objects are instances of type T if Object type is a subtype of type T. | 575 // All objects are instances of type T if Object type is a subtype of type T. |
| 592 const Type& object_type = | 576 const Type& object_type = |
| 593 Type::Handle(Isolate::Current()->object_store()->object_type()); | 577 Type::Handle(Isolate::Current()->object_store()->object_type()); |
| 594 Error& malformed_error = Error::Handle(); | 578 Error& malformed_error = Error::Handle(); |
| 595 if (type.IsInstantiated() && | 579 if (type.IsInstantiated() && |
| 596 object_type.IsSubtypeOf(type, &malformed_error)) { | 580 object_type.IsSubtypeOf(type, &malformed_error)) { |
| 597 // Must evaluate left side. | 581 // Must evaluate left side. |
| 598 EffectGraphVisitor for_left_value(owner(), temp_index()); | 582 EffectGraphVisitor for_left_value(owner(), temp_index()); |
| 599 node->left()->Visit(&for_left_value); | 583 node->left()->Visit(&for_left_value); |
| 600 Append(for_left_value); | 584 Append(for_left_value); |
| 601 ReturnValue(new ConstantVal(negate_result ? bool_false : bool_true)); | 585 ReturnComputation(new ConstantVal(negate_result ? bool_false : bool_true)); |
| 602 return; | 586 return; |
| 603 } | 587 } |
| 604 | 588 |
| 605 // Eliminate the test if it can be performed successfully at compile time. | 589 // Eliminate the test if it can be performed successfully at compile time. |
| 606 if ((node->left() != NULL) && | 590 if ((node->left() != NULL) && |
| 607 node->left()->IsLiteralNode() && | 591 node->left()->IsLiteralNode() && |
| 608 type.IsInstantiated()) { | 592 type.IsInstantiated()) { |
| 609 const Instance& literal_value = node->left()->AsLiteralNode()->literal(); | 593 const Instance& literal_value = node->left()->AsLiteralNode()->literal(); |
| 610 const Class& cls = Class::Handle(literal_value.clazz()); | 594 const Class& cls = Class::Handle(literal_value.clazz()); |
| 611 ConstantVal* result = NULL; | 595 ConstantVal* result = NULL; |
| 612 if (cls.IsNullClass()) { | 596 if (cls.IsNullClass()) { |
| 613 // A null object is only an instance of Object and Dynamic, which has | 597 // A null object is only an instance of Object and Dynamic, which has |
| 614 // already been checked above (if the type is instantiated). So we can | 598 // already been checked above (if the type is instantiated). So we can |
| 615 // return false here if the instance is null (and if the type is | 599 // return false here if the instance is null (and if the type is |
| 616 // instantiated). | 600 // instantiated). |
| 617 result = new ConstantVal(negate_result ? bool_true : bool_false); | 601 result = new ConstantVal(negate_result ? bool_true : bool_false); |
| 618 } else { | 602 } else { |
| 619 Error& malformed_error = Error::Handle(); | 603 Error& malformed_error = Error::Handle(); |
| 620 if (literal_value.IsInstanceOf(type, | 604 if (literal_value.IsInstanceOf(type, |
| 621 TypeArguments::Handle(), | 605 TypeArguments::Handle(), |
| 622 &malformed_error)) { | 606 &malformed_error)) { |
| 623 result = new ConstantVal(negate_result ? bool_false : bool_true); | 607 result = new ConstantVal(negate_result ? bool_false : bool_true); |
| 624 } else { | 608 } else { |
| 625 ASSERT(malformed_error.IsNull()); | 609 ASSERT(malformed_error.IsNull()); |
| 626 result = new ConstantVal(negate_result ? bool_true : bool_false); | 610 result = new ConstantVal(negate_result ? bool_true : bool_false); |
| 627 } | 611 } |
| 628 } | 612 } |
| 629 ReturnValue(result); | 613 ReturnComputation(result); |
| 630 return; | 614 return; |
| 631 } | 615 } |
| 632 | 616 |
| 633 ArgumentGraphVisitor for_left_value(owner(), temp_index()); | 617 ValueGraphVisitor for_left_value(owner(), temp_index()); |
| 634 node->left()->Visit(&for_left_value); | 618 node->left()->Visit(&for_left_value); |
| 635 Append(for_left_value); | 619 Append(for_left_value); |
| 636 Value* type_arguments = NULL; | 620 Value* type_arguments = NULL; |
| 637 if (!type.IsInstantiated()) { | 621 if (!type.IsInstantiated()) { |
| 638 type_arguments = | 622 type_arguments = |
| 639 BuildInstantiatorTypeArguments(node->token_index(), | 623 BuildInstantiatorTypeArguments(node->token_index(), |
| 640 for_left_value.temp_index()); | 624 for_left_value.temp_index()); |
| 641 } | 625 } |
| 642 InstanceOfComp* instance_of = | 626 InstanceOfComp* instance_of = |
| 643 new InstanceOfComp(node->id(), | 627 new InstanceOfComp(node->id(), |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 697 owner()->try_index(), | 681 owner()->try_index(), |
| 698 new UseVal(eq_result))); | 682 new UseVal(eq_result))); |
| 699 AddInstruction(eq_result); | 683 AddInstruction(eq_result); |
| 700 } | 684 } |
| 701 BooleanNegateComp* negate = new BooleanNegateComp(new UseVal(eq_result)); | 685 BooleanNegateComp* negate = new BooleanNegateComp(new UseVal(eq_result)); |
| 702 ReturnComputation(negate); | 686 ReturnComputation(negate); |
| 703 } | 687 } |
| 704 return; | 688 return; |
| 705 } | 689 } |
| 706 | 690 |
| 707 ArgumentGraphVisitor for_left_value(owner(), temp_index()); | 691 ValueGraphVisitor for_left_value(owner(), temp_index()); |
| 708 node->left()->Visit(&for_left_value); | 692 node->left()->Visit(&for_left_value); |
| 709 Append(for_left_value); | 693 Append(for_left_value); |
| 710 ArgumentGraphVisitor for_right_value(owner(), for_left_value.temp_index()); | 694 ValueGraphVisitor for_right_value(owner(), for_left_value.temp_index()); |
| 711 node->right()->Visit(&for_right_value); | 695 node->right()->Visit(&for_right_value); |
| 712 Append(for_right_value); | 696 Append(for_right_value); |
| 713 ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(2); | 697 ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(2); |
| 714 arguments->Add(for_left_value.value()); | 698 arguments->Add(for_left_value.value()); |
| 715 arguments->Add(for_right_value.value()); | 699 arguments->Add(for_right_value.value()); |
| 716 const String& name = String::ZoneHandle(String::NewSymbol(node->Name())); | 700 const String& name = String::ZoneHandle(String::NewSymbol(node->Name())); |
| 717 InstanceCallComp* call = new InstanceCallComp( | 701 InstanceCallComp* call = new InstanceCallComp( |
| 718 node->id(), node->token_index(), owner()->try_index(), name, | 702 node->id(), node->token_index(), owner()->try_index(), name, |
| 719 arguments, Array::ZoneHandle(), 2); | 703 arguments, Array::ZoneHandle(), 2); |
| 720 ReturnComputation(call); | 704 ReturnComputation(call); |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 735 node->operand()->token_index(), | 719 node->operand()->token_index(), |
| 736 owner()->try_index(), | 720 owner()->try_index(), |
| 737 value)); | 721 value)); |
| 738 AddInstruction(assert_boolean); | 722 AddInstruction(assert_boolean); |
| 739 value = new UseVal(assert_boolean); | 723 value = new UseVal(assert_boolean); |
| 740 } | 724 } |
| 741 BooleanNegateComp* negate = new BooleanNegateComp(value); | 725 BooleanNegateComp* negate = new BooleanNegateComp(value); |
| 742 ReturnComputation(negate); | 726 ReturnComputation(negate); |
| 743 return; | 727 return; |
| 744 } | 728 } |
| 745 ArgumentGraphVisitor for_value(owner(), temp_index()); | 729 ValueGraphVisitor for_value(owner(), temp_index()); |
| 746 node->operand()->Visit(&for_value); | 730 node->operand()->Visit(&for_value); |
| 747 Append(for_value); | 731 Append(for_value); |
| 748 ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(1); | 732 ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(1); |
| 749 arguments->Add(for_value.value()); | 733 arguments->Add(for_value.value()); |
| 750 const String& name = | 734 const String& name = |
| 751 String::ZoneHandle(String::NewSymbol((node->kind() == Token::kSUB) | 735 String::ZoneHandle(String::NewSymbol((node->kind() == Token::kSUB) |
| 752 ? Token::Str(Token::kNEGATE) | 736 ? Token::Str(Token::kNEGATE) |
| 753 : node->Name())); | 737 : node->Name())); |
| 754 InstanceCallComp* call = new InstanceCallComp( | 738 InstanceCallComp* call = new InstanceCallComp( |
| 755 node->id(), node->token_index(), owner()->try_index(), name, | 739 node->id(), node->token_index(), owner()->try_index(), name, |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 814 ReturnValue(new UseVal(load)); | 798 ReturnValue(new UseVal(load)); |
| 815 } | 799 } |
| 816 | 800 |
| 817 | 801 |
| 818 Definition* EffectGraphVisitor::BuildIncrOpFieldLoad( | 802 Definition* EffectGraphVisitor::BuildIncrOpFieldLoad( |
| 819 IncrOpInstanceFieldNode* node, | 803 IncrOpInstanceFieldNode* node, |
| 820 Value** receiver) { | 804 Value** receiver) { |
| 821 // Evaluate the receiver and duplicate it (it has two uses). | 805 // Evaluate the receiver and duplicate it (it has two uses). |
| 822 // t_n <- ... receiver ... | 806 // t_n <- ... receiver ... |
| 823 // t_n+1 <- Pick(t_n) | 807 // t_n+1 <- Pick(t_n) |
| 824 ArgumentGraphVisitor for_receiver(owner(), temp_index()); | 808 ValueGraphVisitor for_receiver(owner(), temp_index()); |
| 825 node->receiver()->Visit(&for_receiver); | 809 node->receiver()->Visit(&for_receiver); |
| 826 Append(for_receiver); | 810 Append(for_receiver); |
| 827 AllocateTempIndex(); | 811 AllocateTempIndex(); |
| 828 ASSERT(temp_index() == for_receiver.temp_index()); | 812 ASSERT(temp_index() == for_receiver.temp_index()); |
| 829 PickTempInstr* duplicate = | 813 PickTempInstr* duplicate = |
| 830 new PickTempInstr(temp_index(), temp_index() - 1); | 814 new PickTempInstr(temp_index(), temp_index() - 1); |
| 831 AddInstruction(duplicate); | 815 AddInstruction(duplicate); |
| 832 | 816 |
| 833 // Load the value. | 817 // Load the value. |
| 834 // t_n+1 <- InstanceCall(get:name, t_n+1) | 818 // t_n+1 <- InstanceCall(get:name, t_n+1) |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 949 } | 933 } |
| 950 | 934 |
| 951 | 935 |
| 952 Definition* EffectGraphVisitor::BuildIncrOpIndexedLoad( | 936 Definition* EffectGraphVisitor::BuildIncrOpIndexedLoad( |
| 953 IncrOpIndexedNode* node, | 937 IncrOpIndexedNode* node, |
| 954 Value** receiver, | 938 Value** receiver, |
| 955 Value** index) { | 939 Value** index) { |
| 956 // Evaluate the receiver and index. | 940 // Evaluate the receiver and index. |
| 957 // t_n <- ... receiver ... | 941 // t_n <- ... receiver ... |
| 958 // t_n+1 <- ... index ... | 942 // t_n+1 <- ... index ... |
| 959 ArgumentGraphVisitor for_receiver(owner(), temp_index()); | 943 ValueGraphVisitor for_receiver(owner(), temp_index()); |
| 960 node->array()->Visit(&for_receiver); | 944 node->array()->Visit(&for_receiver); |
| 961 Append(for_receiver); | 945 Append(for_receiver); |
| 962 AllocateTempIndex(); | 946 AllocateTempIndex(); |
| 963 ASSERT(temp_index() == for_receiver.temp_index()); | 947 ASSERT(temp_index() == for_receiver.temp_index()); |
| 964 | 948 |
| 965 ArgumentGraphVisitor for_index(owner(), temp_index()); | 949 ValueGraphVisitor for_index(owner(), temp_index()); |
| 966 node->index()->Visit(&for_index); | 950 node->index()->Visit(&for_index); |
| 967 Append(for_index); | 951 Append(for_index); |
| 968 AllocateTempIndex(); | 952 AllocateTempIndex(); |
| 969 ASSERT(temp_index() == for_index.temp_index()); | 953 ASSERT(temp_index() == for_index.temp_index()); |
| 970 | 954 |
| 971 // Duplicate the receiver and index values, load the value. | 955 // Duplicate the receiver and index values, load the value. |
| 972 // t_n+2 <- Pick(t_n) | 956 // t_n+2 <- Pick(t_n) |
| 973 // t_n+3 <- Pick(t_n+1) | 957 // t_n+3 <- Pick(t_n+1) |
| 974 // t_n+2 <- InstanceCall([], t_n+2, t_n+3) | 958 // t_n+2 <- InstanceCall([], t_n+2, t_n+3) |
| 975 PickTempInstr* duplicate_receiver = | 959 PickTempInstr* duplicate_receiver = |
| (...skipping 598 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1574 new CreateClosureComp(node, owner()->try_index(), type_arguments); | 1558 new CreateClosureComp(node, owner()->try_index(), type_arguments); |
| 1575 ReturnComputation(create); | 1559 ReturnComputation(create); |
| 1576 } | 1560 } |
| 1577 | 1561 |
| 1578 | 1562 |
| 1579 void EffectGraphVisitor::TranslateArgumentList( | 1563 void EffectGraphVisitor::TranslateArgumentList( |
| 1580 const ArgumentListNode& node, | 1564 const ArgumentListNode& node, |
| 1581 intptr_t next_temp_index, | 1565 intptr_t next_temp_index, |
| 1582 ZoneGrowableArray<Value*>* values) { | 1566 ZoneGrowableArray<Value*>* values) { |
| 1583 for (intptr_t i = 0; i < node.length(); ++i) { | 1567 for (intptr_t i = 0; i < node.length(); ++i) { |
| 1584 ArgumentGraphVisitor for_argument(owner(), next_temp_index); | 1568 ValueGraphVisitor for_argument(owner(), next_temp_index); |
| 1585 node.NodeAt(i)->Visit(&for_argument); | 1569 node.NodeAt(i)->Visit(&for_argument); |
| 1586 Append(for_argument); | 1570 Append(for_argument); |
| 1587 next_temp_index = for_argument.temp_index(); | 1571 next_temp_index = for_argument.temp_index(); |
| 1588 values->Add(for_argument.value()); | 1572 values->Add(for_argument.value()); |
| 1589 } | 1573 } |
| 1590 } | 1574 } |
| 1591 | 1575 |
| 1592 void EffectGraphVisitor::VisitInstanceCallNode(InstanceCallNode* node) { | 1576 void EffectGraphVisitor::VisitInstanceCallNode(InstanceCallNode* node) { |
| 1593 ArgumentListNode* arguments = node->arguments(); | 1577 ArgumentListNode* arguments = node->arguments(); |
| 1594 int length = arguments->length(); | 1578 int length = arguments->length(); |
| 1595 ZoneGrowableArray<Value*>* values = new ZoneGrowableArray<Value*>(length + 1); | 1579 ZoneGrowableArray<Value*>* values = new ZoneGrowableArray<Value*>(length + 1); |
| 1596 | 1580 |
| 1597 ArgumentGraphVisitor for_receiver(owner(), temp_index()); | 1581 ValueGraphVisitor for_receiver(owner(), temp_index()); |
| 1598 node->receiver()->Visit(&for_receiver); | 1582 node->receiver()->Visit(&for_receiver); |
| 1599 Append(for_receiver); | 1583 Append(for_receiver); |
| 1600 values->Add(for_receiver.value()); | 1584 values->Add(for_receiver.value()); |
| 1601 | 1585 |
| 1602 TranslateArgumentList(*arguments, for_receiver.temp_index(), values); | 1586 TranslateArgumentList(*arguments, for_receiver.temp_index(), values); |
| 1603 InstanceCallComp* call = new InstanceCallComp( | 1587 InstanceCallComp* call = new InstanceCallComp( |
| 1604 node->id(), node->token_index(), owner()->try_index(), | 1588 node->id(), node->token_index(), owner()->try_index(), |
| 1605 node->function_name(), values, | 1589 node->function_name(), values, |
| 1606 arguments->names(), 1); | 1590 arguments->names(), 1); |
| 1607 ReturnComputation(call); | 1591 ReturnComputation(call); |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 1623 ReturnComputation(call); | 1607 ReturnComputation(call); |
| 1624 } | 1608 } |
| 1625 | 1609 |
| 1626 | 1610 |
| 1627 void EffectGraphVisitor::VisitClosureCallNode(ClosureCallNode* node) { | 1611 void EffectGraphVisitor::VisitClosureCallNode(ClosureCallNode* node) { |
| 1628 // Context is saved around the call, it's treated as an extra operand | 1612 // Context is saved around the call, it's treated as an extra operand |
| 1629 // consumed by the call (but not an argument). | 1613 // consumed by the call (but not an argument). |
| 1630 BindInstr* context = new BindInstr(temp_index(), new CurrentContextComp()); | 1614 BindInstr* context = new BindInstr(temp_index(), new CurrentContextComp()); |
| 1631 AddInstruction(context); | 1615 AddInstruction(context); |
| 1632 | 1616 |
| 1633 ArgumentGraphVisitor for_closure(owner(), temp_index() + 1); | 1617 ValueGraphVisitor for_closure(owner(), temp_index() + 1); |
| 1634 node->closure()->Visit(&for_closure); | 1618 node->closure()->Visit(&for_closure); |
| 1635 Append(for_closure); | 1619 Append(for_closure); |
| 1636 | 1620 |
| 1637 ZoneGrowableArray<Value*>* arguments = | 1621 ZoneGrowableArray<Value*>* arguments = |
| 1638 new ZoneGrowableArray<Value*>(node->arguments()->length()); | 1622 new ZoneGrowableArray<Value*>(node->arguments()->length()); |
| 1639 arguments->Add(for_closure.value()); | 1623 arguments->Add(for_closure.value()); |
| 1640 TranslateArgumentList(*node->arguments(), temp_index() + 2, arguments); | 1624 TranslateArgumentList(*node->arguments(), temp_index() + 2, arguments); |
| 1641 // First operand is the saved context, consumed by the call. | 1625 // First operand is the saved context, consumed by the call. |
| 1642 ClosureCallComp* call = new ClosureCallComp(node, | 1626 ClosureCallComp* call = new ClosureCallComp(node, |
| 1643 owner()->try_index(), | 1627 owner()->try_index(), |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1750 Type::New(instantiator_class, type_arguments, token_index)); | 1734 Type::New(instantiator_class, type_arguments, token_index)); |
| 1751 type ^= ClassFinalizer::FinalizeType( | 1735 type ^= ClassFinalizer::FinalizeType( |
| 1752 instantiator_class, type, ClassFinalizer::kFinalizeWellFormed); | 1736 instantiator_class, type, ClassFinalizer::kFinalizeWellFormed); |
| 1753 type_arguments = type.arguments(); | 1737 type_arguments = type.arguments(); |
| 1754 BindInstr* args = | 1738 BindInstr* args = |
| 1755 new BindInstr(temp_index(), new ConstantVal(type_arguments)); | 1739 new BindInstr(temp_index(), new ConstantVal(type_arguments)); |
| 1756 AddInstruction(args); | 1740 AddInstruction(args); |
| 1757 return new UseVal(args); | 1741 return new UseVal(args); |
| 1758 } | 1742 } |
| 1759 ASSERT(owner()->parsed_function().instantiator() != NULL); | 1743 ASSERT(owner()->parsed_function().instantiator() != NULL); |
| 1760 ArgumentGraphVisitor for_instantiator(owner(), start_index); | 1744 ValueGraphVisitor for_instantiator(owner(), start_index); |
| 1761 owner()->parsed_function().instantiator()->Visit(&for_instantiator); | 1745 owner()->parsed_function().instantiator()->Visit(&for_instantiator); |
| 1762 Append(for_instantiator); | 1746 Append(for_instantiator); |
| 1763 Function& outer_function = | 1747 Function& outer_function = |
| 1764 Function::Handle(owner()->parsed_function().function().raw()); | 1748 Function::Handle(owner()->parsed_function().function().raw()); |
| 1765 while (outer_function.IsLocalFunction()) { | 1749 while (outer_function.IsLocalFunction()) { |
| 1766 outer_function = outer_function.parent_function(); | 1750 outer_function = outer_function.parent_function(); |
| 1767 } | 1751 } |
| 1768 if (outer_function.IsFactory()) { | 1752 if (outer_function.IsFactory()) { |
| 1769 // All OK. | 1753 // All OK. |
| 1770 return for_instantiator.value(); | 1754 return for_instantiator.value(); |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1883 PickTempInstr* duplicate = | 1867 PickTempInstr* duplicate = |
| 1884 new PickTempInstr(temp_index(), allocate->temp_index()); | 1868 new PickTempInstr(temp_index(), allocate->temp_index()); |
| 1885 AddInstruction(duplicate); | 1869 AddInstruction(duplicate); |
| 1886 AllocateTempIndex(); | 1870 AllocateTempIndex(); |
| 1887 BuildConstructorCall(node, new UseVal(duplicate)); | 1871 BuildConstructorCall(node, new UseVal(duplicate)); |
| 1888 ReturnValue(new UseVal(allocate)); | 1872 ReturnValue(new UseVal(allocate)); |
| 1889 } | 1873 } |
| 1890 | 1874 |
| 1891 | 1875 |
| 1892 void EffectGraphVisitor::VisitInstanceGetterNode(InstanceGetterNode* node) { | 1876 void EffectGraphVisitor::VisitInstanceGetterNode(InstanceGetterNode* node) { |
| 1893 ArgumentGraphVisitor for_receiver(owner(), temp_index()); | 1877 ValueGraphVisitor for_receiver(owner(), temp_index()); |
| 1894 node->receiver()->Visit(&for_receiver); | 1878 node->receiver()->Visit(&for_receiver); |
| 1895 Append(for_receiver); | 1879 Append(for_receiver); |
| 1896 ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(1); | 1880 ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(1); |
| 1897 arguments->Add(for_receiver.value()); | 1881 arguments->Add(for_receiver.value()); |
| 1898 const String& name = | 1882 const String& name = |
| 1899 String::ZoneHandle(Field::GetterSymbol(node->field_name())); | 1883 String::ZoneHandle(Field::GetterSymbol(node->field_name())); |
| 1900 InstanceCallComp* call = new InstanceCallComp( | 1884 InstanceCallComp* call = new InstanceCallComp( |
| 1901 node->id(), node->token_index(), owner()->try_index(), name, | 1885 node->id(), node->token_index(), owner()->try_index(), name, |
| 1902 arguments, Array::ZoneHandle(), 1); | 1886 arguments, Array::ZoneHandle(), 1); |
| 1903 ReturnComputation(call); | 1887 ReturnComputation(call); |
| 1904 } | 1888 } |
| 1905 | 1889 |
| 1906 | 1890 |
| 1907 void EffectGraphVisitor::VisitInstanceSetterNode(InstanceSetterNode* node) { | 1891 void EffectGraphVisitor::VisitInstanceSetterNode(InstanceSetterNode* node) { |
| 1908 ArgumentGraphVisitor for_receiver(owner(), temp_index()); | 1892 ValueGraphVisitor for_receiver(owner(), temp_index()); |
| 1909 node->receiver()->Visit(&for_receiver); | 1893 node->receiver()->Visit(&for_receiver); |
| 1910 Append(for_receiver); | 1894 Append(for_receiver); |
| 1911 ArgumentGraphVisitor for_value(owner(), for_receiver.temp_index()); | 1895 ValueGraphVisitor for_value(owner(), for_receiver.temp_index()); |
| 1912 node->value()->Visit(&for_value); | 1896 node->value()->Visit(&for_value); |
| 1913 Append(for_value); | 1897 Append(for_value); |
| 1914 InstanceSetterComp* setter = | 1898 InstanceSetterComp* setter = |
| 1915 new InstanceSetterComp(node->id(), | 1899 new InstanceSetterComp(node->id(), |
| 1916 node->token_index(), | 1900 node->token_index(), |
| 1917 owner()->try_index(), | 1901 owner()->try_index(), |
| 1918 node->field_name(), | 1902 node->field_name(), |
| 1919 for_receiver.value(), | 1903 for_receiver.value(), |
| 1920 for_value.value()); | 1904 for_value.value()); |
| 1921 ReturnComputation(setter); | 1905 ReturnComputation(setter); |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 1937 ReturnComputation(call); | 1921 ReturnComputation(call); |
| 1938 } | 1922 } |
| 1939 | 1923 |
| 1940 | 1924 |
| 1941 void EffectGraphVisitor::VisitStaticSetterNode(StaticSetterNode* node) { | 1925 void EffectGraphVisitor::VisitStaticSetterNode(StaticSetterNode* node) { |
| 1942 const String& setter_name = | 1926 const String& setter_name = |
| 1943 String::Handle(Field::SetterName(node->field_name())); | 1927 String::Handle(Field::SetterName(node->field_name())); |
| 1944 const Function& setter_function = | 1928 const Function& setter_function = |
| 1945 Function::ZoneHandle(node->cls().LookupStaticFunction(setter_name)); | 1929 Function::ZoneHandle(node->cls().LookupStaticFunction(setter_name)); |
| 1946 ASSERT(!setter_function.IsNull()); | 1930 ASSERT(!setter_function.IsNull()); |
| 1947 ArgumentGraphVisitor for_value(owner(), temp_index()); | 1931 ValueGraphVisitor for_value(owner(), temp_index()); |
| 1948 node->value()->Visit(&for_value); | 1932 node->value()->Visit(&for_value); |
| 1949 Append(for_value); | 1933 Append(for_value); |
| 1950 StaticSetterComp* call = new StaticSetterComp(node->token_index(), | 1934 StaticSetterComp* call = new StaticSetterComp(node->token_index(), |
| 1951 owner()->try_index(), | 1935 owner()->try_index(), |
| 1952 setter_function, | 1936 setter_function, |
| 1953 for_value.value()); | 1937 for_value.value()); |
| 1954 ReturnComputation(call); | 1938 ReturnComputation(call); |
| 1955 } | 1939 } |
| 1956 | 1940 |
| 1957 | 1941 |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 1974 } | 1958 } |
| 1975 | 1959 |
| 1976 | 1960 |
| 1977 void ValueGraphVisitor::VisitLoadLocalNode(LoadLocalNode* node) { | 1961 void ValueGraphVisitor::VisitLoadLocalNode(LoadLocalNode* node) { |
| 1978 LoadLocalComp* load = new LoadLocalComp(node->local(), | 1962 LoadLocalComp* load = new LoadLocalComp(node->local(), |
| 1979 owner()->context_level()); | 1963 owner()->context_level()); |
| 1980 ReturnComputation(load); | 1964 ReturnComputation(load); |
| 1981 } | 1965 } |
| 1982 | 1966 |
| 1983 | 1967 |
| 1984 void TestGraphVisitor::VisitLoadLocalNode(LoadLocalNode* node) { | |
| 1985 LoadLocalComp* load = new LoadLocalComp(node->local(), | |
| 1986 owner()->context_level()); | |
| 1987 ReturnComputation(load); | |
| 1988 } | |
| 1989 | |
| 1990 | |
| 1991 // <Expression> ::= StoreLocal { local: LocalVariable | 1968 // <Expression> ::= StoreLocal { local: LocalVariable |
| 1992 // value: <Expression> } | 1969 // value: <Expression> } |
| 1993 void EffectGraphVisitor::VisitStoreLocalNode(StoreLocalNode* node) { | 1970 void EffectGraphVisitor::VisitStoreLocalNode(StoreLocalNode* node) { |
| 1994 ValueGraphVisitor for_value(owner(), temp_index()); | 1971 ValueGraphVisitor for_value(owner(), temp_index()); |
| 1995 node->value()->Visit(&for_value); | 1972 node->value()->Visit(&for_value); |
| 1996 Append(for_value); | 1973 Append(for_value); |
| 1997 Value* store_value = for_value.value(); | 1974 Value* store_value = for_value.value(); |
| 1998 if (FLAG_enable_type_checks) { | 1975 if (FLAG_enable_type_checks) { |
| 1999 store_value = BuildAssignableValue(node->id(), | 1976 store_value = BuildAssignableValue(node->id(), |
| 2000 node->value()->token_index(), | 1977 node->value(), |
| 2001 store_value, | 1978 store_value, |
| 2002 node->local().type(), | 1979 node->local().type(), |
| 2003 node->local().name(), | 1980 node->local().name(), |
| 2004 temp_index()); | 1981 temp_index()); |
| 2005 } | 1982 } |
| 2006 StoreLocalComp* store = | 1983 StoreLocalComp* store = |
| 2007 new StoreLocalComp(node->local(), store_value, owner()->context_level()); | 1984 new StoreLocalComp(node->local(), store_value, owner()->context_level()); |
| 2008 ReturnComputation(store); | 1985 ReturnComputation(store); |
| 2009 } | 1986 } |
| 2010 | 1987 |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 2026 node->instance()->Visit(&for_instance); | 2003 node->instance()->Visit(&for_instance); |
| 2027 Append(for_instance); | 2004 Append(for_instance); |
| 2028 ValueGraphVisitor for_value(owner(), for_instance.temp_index()); | 2005 ValueGraphVisitor for_value(owner(), for_instance.temp_index()); |
| 2029 node->value()->Visit(&for_value); | 2006 node->value()->Visit(&for_value); |
| 2030 Append(for_value); | 2007 Append(for_value); |
| 2031 Value* store_value = for_value.value(); | 2008 Value* store_value = for_value.value(); |
| 2032 if (FLAG_enable_type_checks) { | 2009 if (FLAG_enable_type_checks) { |
| 2033 const AbstractType& type = AbstractType::ZoneHandle(node->field().type()); | 2010 const AbstractType& type = AbstractType::ZoneHandle(node->field().type()); |
| 2034 const String& dst_name = String::ZoneHandle(node->field().name()); | 2011 const String& dst_name = String::ZoneHandle(node->field().name()); |
| 2035 store_value = BuildAssignableValue(node->id(), | 2012 store_value = BuildAssignableValue(node->id(), |
| 2036 node->value()->token_index(), | 2013 node->value(), |
| 2037 store_value, | 2014 store_value, |
| 2038 type, | 2015 type, |
| 2039 dst_name, | 2016 dst_name, |
| 2040 for_instance.temp_index()); | 2017 for_instance.temp_index()); |
| 2041 } | 2018 } |
| 2042 StoreInstanceFieldComp* store = | 2019 StoreInstanceFieldComp* store = |
| 2043 new StoreInstanceFieldComp(node, for_instance.value(), store_value); | 2020 new StoreInstanceFieldComp(node, for_instance.value(), store_value); |
| 2044 ReturnComputation(store); | 2021 ReturnComputation(store); |
| 2045 } | 2022 } |
| 2046 | 2023 |
| 2047 | 2024 |
| 2048 void EffectGraphVisitor::VisitLoadStaticFieldNode(LoadStaticFieldNode* node) { | 2025 void EffectGraphVisitor::VisitLoadStaticFieldNode(LoadStaticFieldNode* node) { |
| 2049 LoadStaticFieldComp* load = new LoadStaticFieldComp(node->field()); | 2026 LoadStaticFieldComp* load = new LoadStaticFieldComp(node->field()); |
| 2050 ReturnComputation(load); | 2027 ReturnComputation(load); |
| 2051 } | 2028 } |
| 2052 | 2029 |
| 2053 | 2030 |
| 2054 void EffectGraphVisitor::VisitStoreStaticFieldNode(StoreStaticFieldNode* node) { | 2031 void EffectGraphVisitor::VisitStoreStaticFieldNode(StoreStaticFieldNode* node) { |
| 2055 ValueGraphVisitor for_value(owner(), temp_index()); | 2032 ValueGraphVisitor for_value(owner(), temp_index()); |
| 2056 node->value()->Visit(&for_value); | 2033 node->value()->Visit(&for_value); |
| 2057 Append(for_value); | 2034 Append(for_value); |
| 2058 Value* store_value = for_value.value(); | 2035 Value* store_value = for_value.value(); |
| 2059 if (FLAG_enable_type_checks) { | 2036 if (FLAG_enable_type_checks) { |
| 2060 const AbstractType& type = AbstractType::ZoneHandle(node->field().type()); | 2037 const AbstractType& type = AbstractType::ZoneHandle(node->field().type()); |
| 2061 const String& dst_name = String::ZoneHandle(node->field().name()); | 2038 const String& dst_name = String::ZoneHandle(node->field().name()); |
| 2062 store_value = BuildAssignableValue(node->id(), | 2039 store_value = BuildAssignableValue(node->id(), |
| 2063 node->value()->token_index(), | 2040 node->value(), |
| 2064 store_value, | 2041 store_value, |
| 2065 type, | 2042 type, |
| 2066 dst_name, | 2043 dst_name, |
| 2067 temp_index()); | 2044 temp_index()); |
| 2068 } | 2045 } |
| 2069 StoreStaticFieldComp* store = | 2046 StoreStaticFieldComp* store = |
| 2070 new StoreStaticFieldComp(node->field(), store_value); | 2047 new StoreStaticFieldComp(node->field(), store_value); |
| 2071 ReturnComputation(store); | 2048 ReturnComputation(store); |
| 2072 } | 2049 } |
| 2073 | 2050 |
| 2074 | 2051 |
| 2075 void EffectGraphVisitor::VisitLoadIndexedNode(LoadIndexedNode* node) { | 2052 void EffectGraphVisitor::VisitLoadIndexedNode(LoadIndexedNode* node) { |
| 2076 ArgumentGraphVisitor for_array(owner(), temp_index()); | 2053 ValueGraphVisitor for_array(owner(), temp_index()); |
| 2077 node->array()->Visit(&for_array); | 2054 node->array()->Visit(&for_array); |
| 2078 Append(for_array); | 2055 Append(for_array); |
| 2079 ArgumentGraphVisitor for_index(owner(), for_array.temp_index()); | 2056 ValueGraphVisitor for_index(owner(), for_array.temp_index()); |
| 2080 node->index_expr()->Visit(&for_index); | 2057 node->index_expr()->Visit(&for_index); |
| 2081 Append(for_index); | 2058 Append(for_index); |
| 2082 ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(2); | 2059 ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(2); |
| 2083 arguments->Add(for_array.value()); | 2060 arguments->Add(for_array.value()); |
| 2084 arguments->Add(for_index.value()); | 2061 arguments->Add(for_index.value()); |
| 2085 const String& name = | 2062 const String& name = |
| 2086 String::ZoneHandle(String::NewSymbol(Token::Str(Token::kINDEX))); | 2063 String::ZoneHandle(String::NewSymbol(Token::Str(Token::kINDEX))); |
| 2087 InstanceCallComp* call = new InstanceCallComp( | 2064 InstanceCallComp* call = new InstanceCallComp( |
| 2088 node->id(), node->token_index(), owner()->try_index(), name, | 2065 node->id(), node->token_index(), owner()->try_index(), name, |
| 2089 arguments, Array::ZoneHandle(), 1); | 2066 arguments, Array::ZoneHandle(), 1); |
| 2090 ReturnComputation(call); | 2067 ReturnComputation(call); |
| 2091 } | 2068 } |
| 2092 | 2069 |
| 2093 | 2070 |
| 2094 void EffectGraphVisitor::VisitStoreIndexedNode(StoreIndexedNode* node) { | 2071 void EffectGraphVisitor::VisitStoreIndexedNode(StoreIndexedNode* node) { |
| 2095 ArgumentGraphVisitor for_array(owner(), temp_index()); | 2072 ValueGraphVisitor for_array(owner(), temp_index()); |
| 2096 node->array()->Visit(&for_array); | 2073 node->array()->Visit(&for_array); |
| 2097 Append(for_array); | 2074 Append(for_array); |
| 2098 ArgumentGraphVisitor for_index(owner(), for_array.temp_index()); | 2075 ValueGraphVisitor for_index(owner(), for_array.temp_index()); |
| 2099 node->index_expr()->Visit(&for_index); | 2076 node->index_expr()->Visit(&for_index); |
| 2100 Append(for_index); | 2077 Append(for_index); |
| 2101 ArgumentGraphVisitor for_value(owner(), for_index.temp_index()); | 2078 ValueGraphVisitor for_value(owner(), for_index.temp_index()); |
| 2102 node->value()->Visit(&for_value); | 2079 node->value()->Visit(&for_value); |
| 2103 Append(for_value); | 2080 Append(for_value); |
| 2104 StoreIndexedComp* store = new StoreIndexedComp(node->id(), | 2081 StoreIndexedComp* store = new StoreIndexedComp(node->id(), |
| 2105 node->token_index(), | 2082 node->token_index(), |
| 2106 owner()->try_index(), | 2083 owner()->try_index(), |
| 2107 for_array.value(), | 2084 for_array.value(), |
| 2108 for_index.value(), | 2085 for_index.value(), |
| 2109 for_value.value()); | 2086 for_value.value()); |
| 2110 ReturnComputation(store); | 2087 ReturnComputation(store); |
| 2111 } | 2088 } |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2154 // save it in a pre-allocated variable and restore it on exit. | 2131 // save it in a pre-allocated variable and restore it on exit. |
| 2155 if (MustSaveRestoreContext(node)) { | 2132 if (MustSaveRestoreContext(node)) { |
| 2156 BindInstr* current_context = | 2133 BindInstr* current_context = |
| 2157 new BindInstr(temp_index() + 1, new CurrentContextComp()); | 2134 new BindInstr(temp_index() + 1, new CurrentContextComp()); |
| 2158 AddInstruction(current_context); | 2135 AddInstruction(current_context); |
| 2159 StoreLocalComp* store_local = new StoreLocalComp( | 2136 StoreLocalComp* store_local = new StoreLocalComp( |
| 2160 *owner()->parsed_function().saved_context_var(), | 2137 *owner()->parsed_function().saved_context_var(), |
| 2161 new UseVal(current_context), | 2138 new UseVal(current_context), |
| 2162 0); | 2139 0); |
| 2163 AddInstruction(new DoInstr(store_local)); | 2140 AddInstruction(new DoInstr(store_local)); |
| 2141 BindInstr* null_context = | |
| 2142 new BindInstr(temp_index() + 1, | |
| 2143 new ConstantVal(Object::ZoneHandle())); | |
| 2144 AddInstruction(null_context); | |
| 2164 StoreContextComp* store_context = | 2145 StoreContextComp* store_context = |
| 2165 new StoreContextComp(new ConstantVal(Object::ZoneHandle())); | 2146 new StoreContextComp(new UseVal(null_context)); |
| 2166 AddInstruction(new DoInstr(store_context)); | 2147 AddInstruction(new DoInstr(store_context)); |
| 2167 } | 2148 } |
| 2168 | 2149 |
| 2169 ChainContextComp* chain_context = | 2150 ChainContextComp* chain_context = |
| 2170 new ChainContextComp(new UseVal(allocated_context)); | 2151 new ChainContextComp(new UseVal(allocated_context)); |
| 2171 AddInstruction(new DoInstr(chain_context)); | 2152 AddInstruction(new DoInstr(chain_context)); |
| 2172 owner()->set_context_level(scope->context_level()); | 2153 owner()->set_context_level(scope->context_level()); |
| 2173 | 2154 |
| 2174 // If this node_sequence is the body of the function being compiled, copy | 2155 // If this node_sequence is the body of the function being compiled, copy |
| 2175 // the captured parameters from the frame into the context. | 2156 // the captured parameters from the frame into the context. |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 2199 owner()->context_level())); | 2180 owner()->context_level())); |
| 2200 AddInstruction(load); | 2181 AddInstruction(load); |
| 2201 StoreLocalComp* store_local = new StoreLocalComp( | 2182 StoreLocalComp* store_local = new StoreLocalComp( |
| 2202 parameter, | 2183 parameter, |
| 2203 new UseVal(load), | 2184 new UseVal(load), |
| 2204 owner()->context_level()); | 2185 owner()->context_level()); |
| 2205 AddInstruction(new DoInstr(store_local)); | 2186 AddInstruction(new DoInstr(store_local)); |
| 2206 // Write NULL to the source location to detect buggy accesses and | 2187 // Write NULL to the source location to detect buggy accesses and |
| 2207 // allow GC of passed value if it gets overwritten by a new value in | 2188 // allow GC of passed value if it gets overwritten by a new value in |
| 2208 // the function. | 2189 // the function. |
| 2190 BindInstr* null_constant = | |
| 2191 new BindInstr(temp_index(), | |
| 2192 new ConstantVal(Object::ZoneHandle())); | |
| 2193 AddInstruction(null_constant); | |
| 2209 StoreLocalComp* clear_local = new StoreLocalComp( | 2194 StoreLocalComp* clear_local = new StoreLocalComp( |
| 2210 *temp_local, | 2195 *temp_local, |
| 2211 new ConstantVal(Object::ZoneHandle()), | 2196 new UseVal(null_constant), |
| 2212 owner()->context_level()); | 2197 owner()->context_level()); |
| 2213 AddInstruction(new DoInstr(clear_local)); | 2198 AddInstruction(new DoInstr(clear_local)); |
| 2214 } | 2199 } |
| 2215 } | 2200 } |
| 2216 } | 2201 } |
| 2217 } | 2202 } |
| 2218 | 2203 |
| 2219 if (FLAG_enable_type_checks && | 2204 if (FLAG_enable_type_checks && |
| 2220 (node == owner()->parsed_function().node_sequence())) { | 2205 (node == owner()->parsed_function().node_sequence())) { |
| 2221 const int num_params = | 2206 const int num_params = |
| (...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2368 BuildThrowNode(node); | 2353 BuildThrowNode(node); |
| 2369 CloseFragment(); | 2354 CloseFragment(); |
| 2370 } | 2355 } |
| 2371 | 2356 |
| 2372 | 2357 |
| 2373 // A throw cannot be part of an expression, however, the parser may replace | 2358 // A throw cannot be part of an expression, however, the parser may replace |
| 2374 // certain expression nodes with a throw. In that case generate a literal null | 2359 // certain expression nodes with a throw. In that case generate a literal null |
| 2375 // so that the fragment is not closed in the middle of an expression. | 2360 // so that the fragment is not closed in the middle of an expression. |
| 2376 void ValueGraphVisitor::VisitThrowNode(ThrowNode* node) { | 2361 void ValueGraphVisitor::VisitThrowNode(ThrowNode* node) { |
| 2377 BuildThrowNode(node); | 2362 BuildThrowNode(node); |
| 2378 ReturnValue(new ConstantVal(Instance::ZoneHandle())); | 2363 ReturnComputation(new ConstantVal(Instance::ZoneHandle())); |
| 2379 } | 2364 } |
| 2380 | 2365 |
| 2381 | 2366 |
| 2382 void EffectGraphVisitor::VisitInlinedFinallyNode(InlinedFinallyNode* node) { | 2367 void EffectGraphVisitor::VisitInlinedFinallyNode(InlinedFinallyNode* node) { |
| 2383 const intptr_t try_index = owner()->try_index(); | 2368 const intptr_t try_index = owner()->try_index(); |
| 2384 if (try_index >= 0) { | 2369 if (try_index >= 0) { |
| 2385 // We are about to generate code for an inlined finally block. Exceptions | 2370 // We are about to generate code for an inlined finally block. Exceptions |
| 2386 // thrown in this block of code should be treated as though they are | 2371 // thrown in this block of code should be treated as though they are |
| 2387 // thrown not from the current try block but the outer try block if any. | 2372 // thrown not from the current try block but the outer try block if any. |
| 2388 owner()->set_try_index((try_index - 1)); | 2373 owner()->set_try_index((try_index - 1)); |
| (...skipping 555 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2944 char* chars = reinterpret_cast<char*>( | 2929 char* chars = reinterpret_cast<char*>( |
| 2945 Isolate::Current()->current_zone()->Allocate(len)); | 2930 Isolate::Current()->current_zone()->Allocate(len)); |
| 2946 OS::SNPrint(chars, len, kFormat, function_name, reason); | 2931 OS::SNPrint(chars, len, kFormat, function_name, reason); |
| 2947 const Error& error = Error::Handle( | 2932 const Error& error = Error::Handle( |
| 2948 LanguageError::New(String::Handle(String::New(chars)))); | 2933 LanguageError::New(String::Handle(String::New(chars)))); |
| 2949 Isolate::Current()->long_jump_base()->Jump(1, error); | 2934 Isolate::Current()->long_jump_base()->Jump(1, error); |
| 2950 } | 2935 } |
| 2951 | 2936 |
| 2952 | 2937 |
| 2953 } // namespace dart | 2938 } // namespace dart |
| OLD | NEW |