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 closurelib; | 7 import '../closure.dart' as closurelib; |
8 import '../closure.dart' hide ClosureScope; | 8 import '../closure.dart' hide ClosureScope; |
9 import '../common.dart'; | 9 import '../common.dart'; |
10 import '../common/names.dart' show | 10 import '../common/names.dart' show |
11 Names, | 11 Names, |
12 Selectors; | 12 Selectors; |
13 import '../common/tasks.dart' show | 13 import '../common/tasks.dart' show |
14 CompilerTask; | 14 CompilerTask; |
15 import '../compiler.dart' show | 15 import '../compiler.dart' show |
16 Compiler; | 16 Compiler; |
17 import '../constants/expressions.dart'; | 17 import '../constants/expressions.dart'; |
18 import '../dart_types.dart'; | 18 import '../dart_types.dart'; |
19 import '../elements/elements.dart'; | 19 import '../elements/elements.dart'; |
20 import '../elements/modelx.dart' show | 20 import '../elements/modelx.dart' show |
21 SynthesizedConstructorElementX, | 21 SynthesizedConstructorElementX, |
22 ConstructorBodyElementX, | 22 ConstructorBodyElementX, |
23 FunctionSignatureX; | 23 FunctionSignatureX; |
24 import '../io/source_information.dart'; | 24 import '../io/source_information.dart'; |
| 25 import '../js_backend/backend_helpers.dart' show |
| 26 BackendHelpers; |
25 import '../js_backend/js_backend.dart' show | 27 import '../js_backend/js_backend.dart' show |
26 JavaScriptBackend, | 28 JavaScriptBackend, |
27 SyntheticConstantKind; | 29 SyntheticConstantKind; |
28 import '../resolution/tree_elements.dart' show | 30 import '../resolution/tree_elements.dart' show |
29 TreeElements; | 31 TreeElements; |
30 import '../resolution/semantic_visitor.dart'; | 32 import '../resolution/semantic_visitor.dart'; |
31 import '../resolution/send_resolver.dart' show | 33 import '../resolution/send_resolver.dart' show |
32 SendResolverMixin; | 34 SendResolverMixin; |
33 import '../resolution/operators.dart' as op; | 35 import '../resolution/operators.dart' as op; |
34 import '../tree/tree.dart' as ast; | 36 import '../tree/tree.dart' as ast; |
(...skipping 2493 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2528 /// | 2530 /// |
2529 /// Will be initialized upon entering the body of a function. | 2531 /// Will be initialized upon entering the body of a function. |
2530 /// It is computed by the [ClosureTranslator]. | 2532 /// It is computed by the [ClosureTranslator]. |
2531 ClosureClassMap closureClassMap; | 2533 ClosureClassMap closureClassMap; |
2532 | 2534 |
2533 JsIrBuilderVisitor(TreeElements elements, | 2535 JsIrBuilderVisitor(TreeElements elements, |
2534 Compiler compiler, | 2536 Compiler compiler, |
2535 SourceInformationBuilder sourceInformationBuilder) | 2537 SourceInformationBuilder sourceInformationBuilder) |
2536 : super(elements, compiler, sourceInformationBuilder); | 2538 : super(elements, compiler, sourceInformationBuilder); |
2537 | 2539 |
| 2540 BackendHelpers get helpers => backend.helpers; |
2538 | 2541 |
2539 /// Builds the IR for creating an instance of the closure class corresponding | 2542 /// Builds the IR for creating an instance of the closure class corresponding |
2540 /// to the given nested function. | 2543 /// to the given nested function. |
2541 ClosureClassElement makeSubFunction(ast.FunctionExpression node) { | 2544 ClosureClassElement makeSubFunction(ast.FunctionExpression node) { |
2542 ClosureClassMap innerMap = | 2545 ClosureClassMap innerMap = |
2543 compiler.closureToClassMapper.getMappingForNestedFunction(node); | 2546 compiler.closureToClassMapper.getMappingForNestedFunction(node); |
2544 ClosureClassElement closureClass = innerMap.closureClassElement; | 2547 ClosureClassElement closureClass = innerMap.closureClassElement; |
2545 return closureClass; | 2548 return closureClass; |
2546 } | 2549 } |
2547 | 2550 |
(...skipping 816 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3364 internalError(argument, 'Additional argument.'); | 3367 internalError(argument, 'Additional argument.'); |
3365 } | 3368 } |
3366 } | 3369 } |
3367 if (count < minimum) { | 3370 if (count < minimum) { |
3368 internalError(node, 'Expected at least $minimum arguments.'); | 3371 internalError(node, 'Expected at least $minimum arguments.'); |
3369 } | 3372 } |
3370 } | 3373 } |
3371 | 3374 |
3372 /// Call a helper method from the isolate library. The isolate library uses | 3375 /// Call a helper method from the isolate library. The isolate library uses |
3373 /// its own isolate structure, that encapsulates dart2js's isolate. | 3376 /// its own isolate structure, that encapsulates dart2js's isolate. |
3374 ir.Primitive buildIsolateHelperInvocation(String helperName, | 3377 ir.Primitive buildIsolateHelperInvocation(Element element, |
3375 CallStructure callStructure) { | 3378 CallStructure callStructure) { |
3376 Element element = backend.isolateHelperLibrary.find(helperName); | |
3377 if (element == null) { | 3379 if (element == null) { |
3378 reporter.internalError(node, | 3380 reporter.internalError(node, |
3379 'Isolate library and compiler mismatch.'); | 3381 'Isolate library and compiler mismatch.'); |
3380 } | 3382 } |
3381 List<ir.Primitive> arguments = translateStaticArguments(argumentList, | 3383 List<ir.Primitive> arguments = translateStaticArguments(argumentList, |
3382 element, callStructure); | 3384 element, callStructure); |
3383 return irBuilder.buildStaticFunctionInvocation(element, | 3385 return irBuilder.buildStaticFunctionInvocation(element, |
3384 callStructure, arguments, | 3386 callStructure, arguments, |
3385 sourceInformation: | 3387 sourceInformation: |
3386 sourceInformationBuilder.buildCall(node, node.selector)); | 3388 sourceInformationBuilder.buildCall(node, node.selector)); |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3448 | 3450 |
3449 case 'JS_BUILTIN': | 3451 case 'JS_BUILTIN': |
3450 // The first argument is a description of the type and effect of the | 3452 // The first argument is a description of the type and effect of the |
3451 // builtin, which has already been analyzed in the frontend. The second | 3453 // builtin, which has already been analyzed in the frontend. The second |
3452 // argument must be a [JsBuiltin] value. All other arguments are | 3454 // argument must be a [JsBuiltin] value. All other arguments are |
3453 // values used by the JavaScript template that is associated with the | 3455 // values used by the JavaScript template that is associated with the |
3454 // builtin. | 3456 // builtin. |
3455 validateArgumentCount(minimum: 2); | 3457 validateArgumentCount(minimum: 2); |
3456 | 3458 |
3457 ast.Node builtin = argumentNodes.tail.head; | 3459 ast.Node builtin = argumentNodes.tail.head; |
3458 JsBuiltin value = getEnumValue(builtin, backend.jsBuiltinEnum, | 3460 JsBuiltin value = getEnumValue(builtin, helpers.jsBuiltinEnum, |
3459 JsBuiltin.values); | 3461 JsBuiltin.values); |
3460 js.Template template = backend.emitter.builtinTemplateFor(value); | 3462 js.Template template = backend.emitter.builtinTemplateFor(value); |
3461 List<ir.Primitive> arguments = | 3463 List<ir.Primitive> arguments = |
3462 argumentNodes.skip(2).mapToList(visit, growable: false); | 3464 argumentNodes.skip(2).mapToList(visit, growable: false); |
3463 return irBuilder.buildForeignCode(template, arguments, behavior); | 3465 return irBuilder.buildForeignCode(template, arguments, behavior); |
3464 | 3466 |
3465 case 'JS_EMBEDDED_GLOBAL': | 3467 case 'JS_EMBEDDED_GLOBAL': |
3466 validateArgumentCount(exactly: 2); | 3468 validateArgumentCount(exactly: 2); |
3467 | 3469 |
3468 String name = expectStringConstant(argumentNodes.tail.head); | 3470 String name = expectStringConstant(argumentNodes.tail.head); |
(...skipping 17 matching lines...) Expand all Loading... |
3486 } | 3488 } |
3487 break; | 3489 break; |
3488 | 3490 |
3489 case 'JS_EFFECT': | 3491 case 'JS_EFFECT': |
3490 return irBuilder.buildNullConstant(); | 3492 return irBuilder.buildNullConstant(); |
3491 | 3493 |
3492 case 'JS_GET_NAME': | 3494 case 'JS_GET_NAME': |
3493 validateArgumentCount(exactly: 1); | 3495 validateArgumentCount(exactly: 1); |
3494 | 3496 |
3495 ast.Node argument = argumentNodes.head; | 3497 ast.Node argument = argumentNodes.head; |
3496 JsGetName id = getEnumValue(argument, backend.jsGetNameEnum, | 3498 JsGetName id = getEnumValue(argument, helpers.jsGetNameEnum, |
3497 JsGetName.values); | 3499 JsGetName.values); |
3498 js.Name name = backend.namer.getNameForJsGetName(argument, id); | 3500 js.Name name = backend.namer.getNameForJsGetName(argument, id); |
3499 ConstantValue nameConstant = | 3501 ConstantValue nameConstant = |
3500 new SyntheticConstantValue(SyntheticConstantKind.NAME, | 3502 new SyntheticConstantValue(SyntheticConstantKind.NAME, |
3501 js.js.quoteName(name)); | 3503 js.js.quoteName(name)); |
3502 | 3504 |
3503 return irBuilder.buildConstant(nameConstant); | 3505 return irBuilder.buildConstant(nameConstant); |
3504 | 3506 |
3505 case 'JS_GET_FLAG': | 3507 case 'JS_GET_FLAG': |
3506 validateArgumentCount(exactly: 1); | 3508 validateArgumentCount(exactly: 1); |
(...skipping 18 matching lines...) Expand all Loading... |
3525 return irBuilder.buildStringConcatenation(arguments); | 3527 return irBuilder.buildStringConcatenation(arguments); |
3526 | 3528 |
3527 case 'JS_CURRENT_ISOLATE_CONTEXT': | 3529 case 'JS_CURRENT_ISOLATE_CONTEXT': |
3528 validateArgumentCount(exactly: 0); | 3530 validateArgumentCount(exactly: 0); |
3529 | 3531 |
3530 if (!compiler.hasIsolateSupport) { | 3532 if (!compiler.hasIsolateSupport) { |
3531 // If the isolate library is not used, we just generate code | 3533 // If the isolate library is not used, we just generate code |
3532 // to fetch the current isolate. | 3534 // to fetch the current isolate. |
3533 continue getStaticState; | 3535 continue getStaticState; |
3534 } | 3536 } |
3535 return buildIsolateHelperInvocation('_currentIsolate', | 3537 return buildIsolateHelperInvocation(backend.helpers.currentIsolate, |
3536 CallStructure.NO_ARGS); | 3538 CallStructure.NO_ARGS); |
3537 | 3539 |
3538 getStaticState: case 'JS_GET_STATIC_STATE': | 3540 getStaticState: case 'JS_GET_STATIC_STATE': |
3539 validateArgumentCount(exactly: 0); | 3541 validateArgumentCount(exactly: 0); |
3540 | 3542 |
3541 return irBuilder.buildForeignCode( | 3543 return irBuilder.buildForeignCode( |
3542 js.js.parseForeignJS(backend.namer.staticStateHolder), | 3544 js.js.parseForeignJS(backend.namer.staticStateHolder), |
3543 const <ir.Primitive>[], | 3545 const <ir.Primitive>[], |
3544 NativeBehavior.PURE); | 3546 NativeBehavior.PURE); |
3545 | 3547 |
3546 case 'JS_SET_STATIC_STATE': | 3548 case 'JS_SET_STATIC_STATE': |
3547 validateArgumentCount(exactly: 1); | 3549 validateArgumentCount(exactly: 1); |
3548 | 3550 |
3549 ir.Primitive value = visit(argumentNodes.single); | 3551 ir.Primitive value = visit(argumentNodes.single); |
3550 String isolateName = backend.namer.staticStateHolder; | 3552 String isolateName = backend.namer.staticStateHolder; |
3551 return irBuilder.buildForeignCode( | 3553 return irBuilder.buildForeignCode( |
3552 js.js.parseForeignJS("$isolateName = #"), | 3554 js.js.parseForeignJS("$isolateName = #"), |
3553 <ir.Primitive>[value], | 3555 <ir.Primitive>[value], |
3554 NativeBehavior.PURE); | 3556 NativeBehavior.PURE); |
3555 | 3557 |
3556 case 'JS_CALL_IN_ISOLATE': | 3558 case 'JS_CALL_IN_ISOLATE': |
3557 validateArgumentCount(exactly: 2); | 3559 validateArgumentCount(exactly: 2); |
3558 | 3560 |
3559 if (!compiler.hasIsolateSupport) { | 3561 if (!compiler.hasIsolateSupport) { |
3560 ir.Primitive closure = visit(argumentNodes.tail.head); | 3562 ir.Primitive closure = visit(argumentNodes.tail.head); |
3561 return irBuilder.buildCallInvocation(closure, CallStructure.NO_ARGS, | 3563 return irBuilder.buildCallInvocation(closure, CallStructure.NO_ARGS, |
3562 const <ir.Primitive>[]); | 3564 const <ir.Primitive>[]); |
3563 } | 3565 } |
3564 return buildIsolateHelperInvocation('_callInIsolate', | 3566 return buildIsolateHelperInvocation(backend.helpers.callInIsolate, |
3565 CallStructure.TWO_ARGS); | 3567 CallStructure.TWO_ARGS); |
3566 | 3568 |
3567 default: | 3569 default: |
3568 giveup(node, 'unplemented native construct: ${function.name}'); | 3570 giveup(node, 'unplemented native construct: ${function.name}'); |
3569 break; | 3571 break; |
3570 } | 3572 } |
3571 } | 3573 } |
3572 | 3574 |
3573 @override | 3575 @override |
3574 ir.Primitive handleStaticFunctionInvoke(ast.Send node, | 3576 ir.Primitive handleStaticFunctionInvoke(ast.Send node, |
3575 MethodElement function, | 3577 MethodElement function, |
3576 ast.NodeList argumentList, | 3578 ast.NodeList argumentList, |
3577 CallStructure callStructure, | 3579 CallStructure callStructure, |
3578 _) { | 3580 _) { |
3579 if (compiler.backend.isForeign(function)) { | 3581 if (compiler.backend.isForeign(function)) { |
3580 return handleForeignCode(node, function, argumentList, callStructure); | 3582 return handleForeignCode(node, function, argumentList, callStructure); |
3581 } else { | 3583 } else { |
3582 return irBuilder.buildStaticFunctionInvocation(function, callStructure, | 3584 return irBuilder.buildStaticFunctionInvocation(function, callStructure, |
3583 translateStaticArguments(argumentList, function, callStructure), | 3585 translateStaticArguments(argumentList, function, callStructure), |
3584 sourceInformation: | 3586 sourceInformation: |
3585 sourceInformationBuilder.buildCall(node, node.selector)); | 3587 sourceInformationBuilder.buildCall(node, node.selector)); |
3586 } | 3588 } |
3587 } | 3589 } |
3588 } | 3590 } |
OLD | NEW |