| 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 library dart2js.ir_builder_task; | 5 library dart2js.ir_builder_task; |
| 6 | 6 |
| 7 import '../closure.dart' as closure; | 7 import '../closure.dart' as closure; |
| 8 import '../common.dart'; | 8 import '../common.dart'; |
| 9 import '../common/names.dart' show | 9 import '../common/names.dart' show |
| 10 Identifiers, | 10 Identifiers, |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 52 import '../util/util.dart'; | 52 import '../util/util.dart'; |
| 53 | 53 |
| 54 import 'package:js_runtime/shared/embedded_names.dart' | 54 import 'package:js_runtime/shared/embedded_names.dart' |
| 55 show JsBuiltin, JsGetName; | 55 show JsBuiltin, JsGetName; |
| 56 import '../constants/values.dart'; | 56 import '../constants/values.dart'; |
| 57 import 'type_mask_system.dart' show | 57 import 'type_mask_system.dart' show |
| 58 TypeMaskSystem; | 58 TypeMaskSystem; |
| 59 | 59 |
| 60 typedef void IrBuilderCallback(Element element, ir.FunctionDefinition irNode); | 60 typedef void IrBuilderCallback(Element element, ir.FunctionDefinition irNode); |
| 61 | 61 |
| 62 class ExplicitReceiverParameter implements Local { |
| 63 final ExecutableElement executableContext; |
| 64 |
| 65 ExplicitReceiverParameter(this.executableContext); |
| 66 |
| 67 String get name => 'receiver'; |
| 68 String toString() => 'ExplicitReceiverParameter($executableContext)'; |
| 69 } |
| 70 |
| 62 /// This task provides the interface to build IR nodes from [ast.Node]s, which | 71 /// This task provides the interface to build IR nodes from [ast.Node]s, which |
| 63 /// is used from the [CpsFunctionCompiler] to generate code. | 72 /// is used from the [CpsFunctionCompiler] to generate code. |
| 64 /// | 73 /// |
| 65 /// This class is mainly there to correctly measure how long building the IR | 74 /// This class is mainly there to correctly measure how long building the IR |
| 66 /// takes. | 75 /// takes. |
| 67 class IrBuilderTask extends CompilerTask { | 76 class IrBuilderTask extends CompilerTask { |
| 68 final SourceInformationStrategy sourceInformationStrategy; | 77 final SourceInformationStrategy sourceInformationStrategy; |
| 69 | 78 |
| 70 String bailoutMessage = null; | 79 String bailoutMessage = null; |
| 71 | 80 |
| (...skipping 309 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 381 ClassElement classElement = constructor.enclosingClass.implementation; | 390 ClassElement classElement = constructor.enclosingClass.implementation; |
| 382 | 391 |
| 383 IrBuilder builder = getBuilderFor(constructor); | 392 IrBuilder builder = getBuilderFor(constructor); |
| 384 | 393 |
| 385 final bool requiresTypeInformation = | 394 final bool requiresTypeInformation = |
| 386 builder.program.requiresRuntimeTypesFor(classElement); | 395 builder.program.requiresRuntimeTypesFor(classElement); |
| 387 | 396 |
| 388 return withBuilder(builder, () { | 397 return withBuilder(builder, () { |
| 389 // Setup parameters and create a box if anything is captured. | 398 // Setup parameters and create a box if anything is captured. |
| 390 List<Local> parameters = <Local>[]; | 399 List<Local> parameters = <Local>[]; |
| 400 if (constructor.isGenerativeConstructor && |
| 401 backend.isNativeOrExtendsNative(classElement)) { |
| 402 parameters.add(new ExplicitReceiverParameter(constructor)); |
| 403 } |
| 391 constructor.functionSignature.orderedForEachParameter( | 404 constructor.functionSignature.orderedForEachParameter( |
| 392 (ParameterElement p) => parameters.add(p)); | 405 (ParameterElement p) => parameters.add(p)); |
| 393 | 406 |
| 394 int firstTypeArgumentParameterIndex; | 407 int firstTypeArgumentParameterIndex; |
| 395 | 408 |
| 396 // If instances of the class may need runtime type information, we add a | 409 // If instances of the class may need runtime type information, we add a |
| 397 // synthetic parameter for each type parameter. | 410 // synthetic parameter for each type parameter. |
| 398 if (requiresTypeInformation) { | 411 if (requiresTypeInformation) { |
| 399 firstTypeArgumentParameterIndex = parameters.length; | 412 firstTypeArgumentParameterIndex = parameters.length; |
| 400 classElement.typeVariables.forEach((TypeVariableType variable) { | 413 classElement.typeVariables.forEach((TypeVariableType variable) { |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 439 evaluateConstructorFieldInitializers( | 452 evaluateConstructorFieldInitializers( |
| 440 constructor, constructorList, fieldValues); | 453 constructor, constructorList, fieldValues); |
| 441 | 454 |
| 442 // All parameters in all constructors are now bound in the environment. | 455 // All parameters in all constructors are now bound in the environment. |
| 443 // BoxLocals for captured parameters are also in the environment. | 456 // BoxLocals for captured parameters are also in the environment. |
| 444 // The initial value of all fields are now bound in [fieldValues]. | 457 // The initial value of all fields are now bound in [fieldValues]. |
| 445 | 458 |
| 446 // --- Create the object --- | 459 // --- Create the object --- |
| 447 // Get the initial field values in the canonical order. | 460 // Get the initial field values in the canonical order. |
| 448 List<ir.Primitive> instanceArguments = <ir.Primitive>[]; | 461 List<ir.Primitive> instanceArguments = <ir.Primitive>[]; |
| 462 List<FieldElement> fields = <FieldElement>[]; |
| 449 classElement.forEachInstanceField((ClassElement c, FieldElement field) { | 463 classElement.forEachInstanceField((ClassElement c, FieldElement field) { |
| 450 ir.Primitive value = fieldValues[field]; | 464 ir.Primitive value = fieldValues[field]; |
| 451 if (value != null) { | 465 if (value != null) { |
| 466 fields.add(field); |
| 452 instanceArguments.add(value); | 467 instanceArguments.add(value); |
| 453 } else { | 468 } else { |
| 454 assert(backend.isNativeOrExtendsNative(c)); | 469 assert(backend.isNativeOrExtendsNative(c)); |
| 455 // Native fields are initialized elsewhere. | 470 // Native fields are initialized elsewhere. |
| 456 } | 471 } |
| 457 }, includeSuperAndInjectedMembers: true); | 472 }, includeSuperAndInjectedMembers: true); |
| 458 | 473 |
| 459 ir.Primitive instance = new ir.CreateInstance( | 474 ir.Primitive instance; |
| 475 if (constructor.isGenerativeConstructor && |
| 476 backend.isNativeOrExtendsNative(classElement)) { |
| 477 instance = irParameters.first; |
| 478 instance.type = |
| 479 new TypeMask.exact(classElement, typeMaskSystem.classWorld); |
| 480 irBuilder.addPrimitive(new ir.ReceiverCheck.nullCheck( |
| 481 instance, Selectors.toString_, null)); |
| 482 for (int i = 0; i < fields.length; i++) { |
| 483 irBuilder.addPrimitive( |
| 484 new ir.SetField(instance, fields[i], instanceArguments[i])); |
| 485 } |
| 486 } else { |
| 487 instance = new ir.CreateInstance( |
| 460 classElement, | 488 classElement, |
| 461 instanceArguments, | 489 instanceArguments, |
| 462 typeInformation, | 490 typeInformation, |
| 463 constructor.hasNode | 491 constructor.hasNode |
| 464 ? sourceInformationBuilder.buildCreate(constructor.node) | 492 ? sourceInformationBuilder.buildCreate(constructor.node) |
| 465 // TODO(johnniwinther): Provide source information for creation | 493 // TODO(johnniwinther): Provide source information for creation |
| 466 // through synthetic constructors. | 494 // through synthetic constructors. |
| 467 : null); | 495 : null); |
| 468 irBuilder.add(new ir.LetPrim(instance)); | 496 irBuilder.add(new ir.LetPrim(instance)); |
| 497 } |
| 469 | 498 |
| 470 // --- Call constructor bodies --- | 499 // --- Call constructor bodies --- |
| 471 for (ConstructorElement target in constructorList) { | 500 for (ConstructorElement target in constructorList) { |
| 472 ConstructorBodyElement bodyElement = getConstructorBody(target); | 501 ConstructorBodyElement bodyElement = getConstructorBody(target); |
| 473 if (bodyElement == null) continue; // Skip if constructor has no body. | 502 if (bodyElement == null) continue; // Skip if constructor has no body. |
| 474 List<ir.Primitive> bodyArguments = <ir.Primitive>[]; | 503 List<ir.Primitive> bodyArguments = <ir.Primitive>[]; |
| 475 for (Local param in getConstructorBodyParameters(bodyElement)) { | 504 for (Local param in getConstructorBodyParameters(bodyElement)) { |
| 476 bodyArguments.add(irBuilder.environment.lookup(param)); | 505 bodyArguments.add(irBuilder.environment.lookup(param)); |
| 477 } | 506 } |
| 478 Selector selector = new Selector.call(target.memberName, | 507 Selector selector = new Selector.call(target.memberName, |
| (...skipping 1883 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2362 if (constructor.isRedirectingFactory && !constructor.isCyclicRedirection) { | 2391 if (constructor.isRedirectingFactory && !constructor.isCyclicRedirection) { |
| 2363 ConstructorElement current = constructor; | 2392 ConstructorElement current = constructor; |
| 2364 while (current.isRedirectingFactory) { | 2393 while (current.isRedirectingFactory) { |
| 2365 var prefix = current.redirectionDeferredPrefix; | 2394 var prefix = current.redirectionDeferredPrefix; |
| 2366 if (prefix != null) buildCheckDeferredIsLoaded(prefix, send); | 2395 if (prefix != null) buildCheckDeferredIsLoaded(prefix, send); |
| 2367 current = current.immediateRedirectionTarget; | 2396 current = current.immediateRedirectionTarget; |
| 2368 } | 2397 } |
| 2369 } | 2398 } |
| 2370 | 2399 |
| 2371 List<ir.Primitive> arguments = argumentsNode.nodes.mapToList(visit); | 2400 List<ir.Primitive> arguments = argumentsNode.nodes.mapToList(visit); |
| 2401 if (constructor.isGenerativeConstructor && |
| 2402 backend.isNativeOrExtendsNative(constructor.enclosingClass)) { |
| 2403 arguments.insert(0, irBuilder.buildNullConstant()); |
| 2404 } |
| 2372 // Use default values from the effective target, not the immediate target. | 2405 // Use default values from the effective target, not the immediate target. |
| 2373 ConstructorElement target; | 2406 ConstructorElement target; |
| 2374 if (constructor == compiler.symbolConstructor) { | 2407 if (constructor == compiler.symbolConstructor) { |
| 2375 // The Symbol constructor should perform validation of its argument | 2408 // The Symbol constructor should perform validation of its argument |
| 2376 // which is not expressible as a Dart const constructor. Instead, the | 2409 // which is not expressible as a Dart const constructor. Instead, the |
| 2377 // libraries contain a dummy const constructor implementation that | 2410 // libraries contain a dummy const constructor implementation that |
| 2378 // doesn't perform validation and the compiler compiles a call to | 2411 // doesn't perform validation and the compiler compiles a call to |
| 2379 // (non-const) Symbol.validated when it sees new Symbol(...). | 2412 // (non-const) Symbol.validated when it sees new Symbol(...). |
| 2380 target = compiler.symbolValidatedConstructor; | 2413 target = compiler.symbolValidatedConstructor; |
| 2381 } else { | 2414 } else { |
| (...skipping 1842 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4224 _backend.jsInteropAnalysis.hasAnonymousAnnotation(element.contextClass); | 4257 _backend.jsInteropAnalysis.hasAnonymousAnnotation(element.contextClass); |
| 4225 | 4258 |
| 4226 String getJsInteropTargetPath(FunctionElement element) { | 4259 String getJsInteropTargetPath(FunctionElement element) { |
| 4227 return '${_backend.namer.fixedBackendPath(element)}.' | 4260 return '${_backend.namer.fixedBackendPath(element)}.' |
| 4228 '${_backend.getFixedBackendName(element)}'; | 4261 '${_backend.getFixedBackendName(element)}'; |
| 4229 } | 4262 } |
| 4230 | 4263 |
| 4231 DartType get jsJavascriptObjectType => | 4264 DartType get jsJavascriptObjectType => |
| 4232 _backend.helpers.jsJavaScriptObjectClass.thisType; | 4265 _backend.helpers.jsJavaScriptObjectClass.thisType; |
| 4233 } | 4266 } |
| OLD | NEW |