| OLD | NEW |
| 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 import 'package:kernel/ast.dart' as ir; | 5 import 'package:kernel/ast.dart' as ir; |
| 6 | 6 |
| 7 import '../closure.dart'; | 7 import '../closure.dart'; |
| 8 import '../common.dart'; | 8 import '../common.dart'; |
| 9 import '../common/codegen.dart' show CodegenRegistry; | 9 import '../common/codegen.dart' show CodegenRegistry; |
| 10 import '../common/names.dart'; | 10 import '../common/names.dart'; |
| (...skipping 1272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1283 visitThen: () => ifStatement.then.accept(this), | 1283 visitThen: () => ifStatement.then.accept(this), |
| 1284 visitElse: () => ifStatement.otherwise?.accept(this)); | 1284 visitElse: () => ifStatement.otherwise?.accept(this)); |
| 1285 } | 1285 } |
| 1286 | 1286 |
| 1287 void handleIf( | 1287 void handleIf( |
| 1288 {ir.Node node, | 1288 {ir.Node node, |
| 1289 void visitCondition(), | 1289 void visitCondition(), |
| 1290 void visitThen(), | 1290 void visitThen(), |
| 1291 void visitElse(), | 1291 void visitElse(), |
| 1292 SourceInformation sourceInformation}) { | 1292 SourceInformation sourceInformation}) { |
| 1293 SsaBranchBuilder branchBuilder = new SsaBranchBuilder( | 1293 SsaBranchBuilder branchBuilder = new SsaBranchBuilder(this, |
| 1294 this, node == null ? node : astAdapter.getNode(node)); | 1294 node == null ? node : _elementMap.getSpannable(targetElement, node)); |
| 1295 branchBuilder.handleIf(visitCondition, visitThen, visitElse, | 1295 branchBuilder.handleIf(visitCondition, visitThen, visitElse, |
| 1296 sourceInformation: sourceInformation); | 1296 sourceInformation: sourceInformation); |
| 1297 } | 1297 } |
| 1298 | 1298 |
| 1299 @override | 1299 @override |
| 1300 void visitAsExpression(ir.AsExpression asExpression) { | 1300 void visitAsExpression(ir.AsExpression asExpression) { |
| 1301 asExpression.operand.accept(this); | 1301 asExpression.operand.accept(this); |
| 1302 HInstruction expressionInstruction = pop(); | 1302 HInstruction expressionInstruction = pop(); |
| 1303 | 1303 |
| 1304 if (asExpression.type is ir.InvalidType) { | 1304 if (asExpression.type is ir.InvalidType) { |
| (...skipping 428 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1733 // to create the phis in [joinBlock]. | 1733 // to create the phis in [joinBlock]. |
| 1734 // If we never jump to the join block, [caseHandlers] will stay empty, and | 1734 // If we never jump to the join block, [caseHandlers] will stay empty, and |
| 1735 // the join block is never added to the graph. | 1735 // the join block is never added to the graph. |
| 1736 HBasicBlock joinBlock = new HBasicBlock(); | 1736 HBasicBlock joinBlock = new HBasicBlock(); |
| 1737 List<LocalsHandler> caseHandlers = <LocalsHandler>[]; | 1737 List<LocalsHandler> caseHandlers = <LocalsHandler>[]; |
| 1738 jumpHandler.forEachBreak((HBreak instruction, LocalsHandler locals) { | 1738 jumpHandler.forEachBreak((HBreak instruction, LocalsHandler locals) { |
| 1739 instruction.block.addSuccessor(joinBlock); | 1739 instruction.block.addSuccessor(joinBlock); |
| 1740 caseHandlers.add(locals); | 1740 caseHandlers.add(locals); |
| 1741 }); | 1741 }); |
| 1742 jumpHandler.forEachContinue((HContinue instruction, LocalsHandler locals) { | 1742 jumpHandler.forEachContinue((HContinue instruction, LocalsHandler locals) { |
| 1743 assert(invariant(astAdapter.getNode(switchStatement), false, | 1743 assert(invariant( |
| 1744 _elementMap.getSpannable(targetElement, switchStatement), false, |
| 1744 message: 'Continue cannot target a switch.')); | 1745 message: 'Continue cannot target a switch.')); |
| 1745 }); | 1746 }); |
| 1746 if (!isAborted()) { | 1747 if (!isAborted()) { |
| 1747 current.close(new HGoto()); | 1748 current.close(new HGoto()); |
| 1748 lastOpenedBlock.addSuccessor(joinBlock); | 1749 lastOpenedBlock.addSuccessor(joinBlock); |
| 1749 caseHandlers.add(localsHandler); | 1750 caseHandlers.add(localsHandler); |
| 1750 } | 1751 } |
| 1751 if (!hasDefault) { | 1752 if (!hasDefault) { |
| 1752 // Always create a default case, to avoid a critical edge in the | 1753 // Always create a default case, to avoid a critical edge in the |
| 1753 // graph. | 1754 // graph. |
| (...skipping 537 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2291 } else if (name == 'JS_GET_FLAG') { | 2292 } else if (name == 'JS_GET_FLAG') { |
| 2292 handleForeignJsGetFlag(invocation); | 2293 handleForeignJsGetFlag(invocation); |
| 2293 } else if (name == 'JS_EFFECT') { | 2294 } else if (name == 'JS_EFFECT') { |
| 2294 stack.add(graph.addConstantNull(closedWorld)); | 2295 stack.add(graph.addConstantNull(closedWorld)); |
| 2295 } else if (name == 'JS_INTERCEPTOR_CONSTANT') { | 2296 } else if (name == 'JS_INTERCEPTOR_CONSTANT') { |
| 2296 handleJsInterceptorConstant(invocation); | 2297 handleJsInterceptorConstant(invocation); |
| 2297 } else if (name == 'JS_STRING_CONCAT') { | 2298 } else if (name == 'JS_STRING_CONCAT') { |
| 2298 handleJsStringConcat(invocation); | 2299 handleJsStringConcat(invocation); |
| 2299 } else { | 2300 } else { |
| 2300 reporter.internalError( | 2301 reporter.internalError( |
| 2301 astAdapter.getNode(invocation), "Unknown foreign: ${name}"); | 2302 _elementMap.getSpannable(targetElement, invocation), |
| 2303 "Unknown foreign: ${name}"); |
| 2302 } | 2304 } |
| 2303 } | 2305 } |
| 2304 | 2306 |
| 2305 bool _unexpectedForeignArguments( | 2307 bool _unexpectedForeignArguments( |
| 2306 ir.StaticInvocation invocation, int minPositional, | 2308 ir.StaticInvocation invocation, int minPositional, |
| 2307 [int maxPositional]) { | 2309 [int maxPositional]) { |
| 2308 String pluralizeArguments(int count) { | 2310 String pluralizeArguments(int count) { |
| 2309 if (count == 0) return 'no arguments'; | 2311 if (count == 0) return 'no arguments'; |
| 2310 if (count == 1) return 'one argument'; | 2312 if (count == 1) return 'one argument'; |
| 2311 if (count == 2) return 'two arguments'; | 2313 if (count == 2) return 'two arguments'; |
| 2312 return '$count arguments'; | 2314 return '$count arguments'; |
| 2313 } | 2315 } |
| 2314 | 2316 |
| 2315 String name() => invocation.target.name.name; | 2317 String name() => invocation.target.name.name; |
| 2316 | 2318 |
| 2317 ir.Arguments arguments = invocation.arguments; | 2319 ir.Arguments arguments = invocation.arguments; |
| 2318 bool bad = false; | 2320 bool bad = false; |
| 2319 if (arguments.types.isNotEmpty) { | 2321 if (arguments.types.isNotEmpty) { |
| 2320 reporter.reportErrorMessage( | 2322 reporter.reportErrorMessage( |
| 2321 astAdapter.getNode(invocation), | 2323 _elementMap.getSpannable(targetElement, invocation), |
| 2322 MessageKind.GENERIC, | 2324 MessageKind.GENERIC, |
| 2323 {'text': "Error: '${name()}' does not take type arguments."}); | 2325 {'text': "Error: '${name()}' does not take type arguments."}); |
| 2324 bad = true; | 2326 bad = true; |
| 2325 } | 2327 } |
| 2326 if (arguments.positional.length < minPositional) { | 2328 if (arguments.positional.length < minPositional) { |
| 2327 String phrase = pluralizeArguments(minPositional); | 2329 String phrase = pluralizeArguments(minPositional); |
| 2328 if (maxPositional != minPositional) phrase = 'at least $phrase'; | 2330 if (maxPositional != minPositional) phrase = 'at least $phrase'; |
| 2329 reporter.reportErrorMessage( | 2331 reporter.reportErrorMessage( |
| 2330 astAdapter.getNode(invocation), | 2332 _elementMap.getSpannable(targetElement, invocation), |
| 2331 MessageKind.GENERIC, | 2333 MessageKind.GENERIC, |
| 2332 {'text': "Error: Too few arguments. '${name()}' takes $phrase."}); | 2334 {'text': "Error: Too few arguments. '${name()}' takes $phrase."}); |
| 2333 bad = true; | 2335 bad = true; |
| 2334 } | 2336 } |
| 2335 if (maxPositional != null && arguments.positional.length > maxPositional) { | 2337 if (maxPositional != null && arguments.positional.length > maxPositional) { |
| 2336 String phrase = pluralizeArguments(maxPositional); | 2338 String phrase = pluralizeArguments(maxPositional); |
| 2337 if (maxPositional != minPositional) phrase = 'at most $phrase'; | 2339 if (maxPositional != minPositional) phrase = 'at most $phrase'; |
| 2338 reporter.reportErrorMessage( | 2340 reporter.reportErrorMessage( |
| 2339 astAdapter.getNode(invocation), | 2341 _elementMap.getSpannable(targetElement, invocation), |
| 2340 MessageKind.GENERIC, | 2342 MessageKind.GENERIC, |
| 2341 {'text': "Error: Too many arguments. '${name()}' takes $phrase."}); | 2343 {'text': "Error: Too many arguments. '${name()}' takes $phrase."}); |
| 2342 bad = true; | 2344 bad = true; |
| 2343 } | 2345 } |
| 2344 if (arguments.named.isNotEmpty) { | 2346 if (arguments.named.isNotEmpty) { |
| 2345 reporter.reportErrorMessage( | 2347 reporter.reportErrorMessage( |
| 2346 astAdapter.getNode(invocation), | 2348 _elementMap.getSpannable(targetElement, invocation), |
| 2347 MessageKind.GENERIC, | 2349 MessageKind.GENERIC, |
| 2348 {'text': "Error: '${name()}' does not take named arguments."}); | 2350 {'text': "Error: '${name()}' does not take named arguments."}); |
| 2349 bad = true; | 2351 bad = true; |
| 2350 } | 2352 } |
| 2351 return bad; | 2353 return bad; |
| 2352 } | 2354 } |
| 2353 | 2355 |
| 2354 /// Returns the value of the string argument. The argument must evaluate to a | 2356 /// Returns the value of the string argument. The argument must evaluate to a |
| 2355 /// constant. If there is an error, the error is reported and `null` is | 2357 /// constant. If there is an error, the error is reported and `null` is |
| 2356 /// returned. | 2358 /// returned. |
| 2357 String _foreignConstantStringArgument( | 2359 String _foreignConstantStringArgument( |
| 2358 ir.StaticInvocation invocation, int position, String methodName, | 2360 ir.StaticInvocation invocation, int position, String methodName, |
| 2359 [String adjective = '']) { | 2361 [String adjective = '']) { |
| 2360 ir.Expression argument = invocation.arguments.positional[position]; | 2362 ir.Expression argument = invocation.arguments.positional[position]; |
| 2361 argument.accept(this); | 2363 argument.accept(this); |
| 2362 HInstruction instruction = pop(); | 2364 HInstruction instruction = pop(); |
| 2363 | 2365 |
| 2364 if (!instruction.isConstantString()) { | 2366 if (!instruction.isConstantString()) { |
| 2365 reporter.reportErrorMessage( | 2367 reporter.reportErrorMessage( |
| 2366 astAdapter.getNode(argument), MessageKind.GENERIC, { | 2368 _elementMap.getSpannable(targetElement, argument), |
| 2369 MessageKind.GENERIC, { |
| 2367 'text': "Error: Expected String constant as ${adjective}argument " | 2370 'text': "Error: Expected String constant as ${adjective}argument " |
| 2368 "to '$methodName'." | 2371 "to '$methodName'." |
| 2369 }); | 2372 }); |
| 2370 return null; | 2373 return null; |
| 2371 } | 2374 } |
| 2372 | 2375 |
| 2373 HConstant hConstant = instruction; | 2376 HConstant hConstant = instruction; |
| 2374 StringConstantValue stringConstant = hConstant.constant; | 2377 StringConstantValue stringConstant = hConstant.constant; |
| 2375 return stringConstant.primitiveValue; | 2378 return stringConstant.primitiveValue; |
| 2376 } | 2379 } |
| (...skipping 11 matching lines...) Expand all Loading... |
| 2388 String name = namer.staticStateHolder; | 2391 String name = namer.staticStateHolder; |
| 2389 push(new HForeignCode( | 2392 push(new HForeignCode( |
| 2390 js.js.parseForeignJS(name), commonMasks.dynamicType, <HInstruction>[], | 2393 js.js.parseForeignJS(name), commonMasks.dynamicType, <HInstruction>[], |
| 2391 nativeBehavior: native.NativeBehavior.DEPENDS_OTHER)); | 2394 nativeBehavior: native.NativeBehavior.DEPENDS_OTHER)); |
| 2392 } else { | 2395 } else { |
| 2393 // Call a helper method from the isolate library. The isolate library uses | 2396 // Call a helper method from the isolate library. The isolate library uses |
| 2394 // its own isolate structure that encapsulates the isolate structure used | 2397 // its own isolate structure that encapsulates the isolate structure used |
| 2395 // for binding to methods. | 2398 // for binding to methods. |
| 2396 FunctionEntity target = _commonElements.currentIsolate; | 2399 FunctionEntity target = _commonElements.currentIsolate; |
| 2397 if (target == null) { | 2400 if (target == null) { |
| 2398 reporter.internalError(astAdapter.getNode(invocation), | 2401 reporter.internalError( |
| 2402 _elementMap.getSpannable(targetElement, invocation), |
| 2399 'Isolate library and compiler mismatch.'); | 2403 'Isolate library and compiler mismatch.'); |
| 2400 } | 2404 } |
| 2401 _pushStaticInvocation(target, <HInstruction>[], commonMasks.dynamicType); | 2405 _pushStaticInvocation(target, <HInstruction>[], commonMasks.dynamicType); |
| 2402 } | 2406 } |
| 2403 } | 2407 } |
| 2404 | 2408 |
| 2405 void handleForeignJsCallInIsolate(ir.StaticInvocation invocation) { | 2409 void handleForeignJsCallInIsolate(ir.StaticInvocation invocation) { |
| 2406 if (_unexpectedForeignArguments(invocation, 2, 2)) { | 2410 if (_unexpectedForeignArguments(invocation, 2, 2)) { |
| 2407 // Result expected on stack. | 2411 // Result expected on stack. |
| 2408 stack.add(graph.addConstantNull(closedWorld)); | 2412 stack.add(graph.addConstantNull(closedWorld)); |
| 2409 return; | 2413 return; |
| 2410 } | 2414 } |
| 2411 | 2415 |
| 2412 List<HInstruction> inputs = _visitPositionalArguments(invocation.arguments); | 2416 List<HInstruction> inputs = _visitPositionalArguments(invocation.arguments); |
| 2413 | 2417 |
| 2414 if (!backendUsage.isIsolateInUse) { | 2418 if (!backendUsage.isIsolateInUse) { |
| 2415 // If the isolate library is not used, we ignore the isolate argument and | 2419 // If the isolate library is not used, we ignore the isolate argument and |
| 2416 // just invoke the closure. | 2420 // just invoke the closure. |
| 2417 push(new HInvokeClosure(new Selector.callClosure(0), | 2421 push(new HInvokeClosure(new Selector.callClosure(0), |
| 2418 <HInstruction>[inputs[1]], commonMasks.dynamicType)); | 2422 <HInstruction>[inputs[1]], commonMasks.dynamicType)); |
| 2419 } else { | 2423 } else { |
| 2420 // Call a helper method from the isolate library. | 2424 // Call a helper method from the isolate library. |
| 2421 FunctionEntity callInIsolate = _commonElements.callInIsolate; | 2425 FunctionEntity callInIsolate = _commonElements.callInIsolate; |
| 2422 if (callInIsolate == null) { | 2426 if (callInIsolate == null) { |
| 2423 reporter.internalError(astAdapter.getNode(invocation), | 2427 reporter.internalError( |
| 2428 _elementMap.getSpannable(targetElement, invocation), |
| 2424 'Isolate library and compiler mismatch.'); | 2429 'Isolate library and compiler mismatch.'); |
| 2425 } | 2430 } |
| 2426 _pushStaticInvocation(callInIsolate, inputs, commonMasks.dynamicType); | 2431 _pushStaticInvocation(callInIsolate, inputs, commonMasks.dynamicType); |
| 2427 } | 2432 } |
| 2428 } | 2433 } |
| 2429 | 2434 |
| 2430 void handleForeignDartClosureToJs( | 2435 void handleForeignDartClosureToJs( |
| 2431 ir.StaticInvocation invocation, String name) { | 2436 ir.StaticInvocation invocation, String name) { |
| 2432 // TODO(sra): Do we need to wrap the closure in something that saves the | 2437 // TODO(sra): Do we need to wrap the closure in something that saves the |
| 2433 // current isolate? | 2438 // current isolate? |
| (...skipping 26 matching lines...) Expand all Loading... |
| 2460 <HInstruction>[], | 2465 <HInstruction>[], |
| 2461 nativeBehavior: native.NativeBehavior.PURE, | 2466 nativeBehavior: native.NativeBehavior.PURE, |
| 2462 foreignFunction: _elementMap.getMethod(staticTarget))); | 2467 foreignFunction: _elementMap.getMethod(staticTarget))); |
| 2463 return; | 2468 return; |
| 2464 } | 2469 } |
| 2465 problem = 'does not handle a closure with optional parameters'; | 2470 problem = 'does not handle a closure with optional parameters'; |
| 2466 } | 2471 } |
| 2467 } | 2472 } |
| 2468 } | 2473 } |
| 2469 | 2474 |
| 2470 reporter.reportErrorMessage(astAdapter.getNode(invocation), | 2475 reporter.reportErrorMessage( |
| 2471 MessageKind.GENERIC, {'text': "'$name' $problem."}); | 2476 _elementMap.getSpannable(targetElement, invocation), |
| 2477 MessageKind.GENERIC, |
| 2478 {'text': "'$name' $problem."}); |
| 2472 stack.add(graph.addConstantNull(closedWorld)); // Result expected on stack. | 2479 stack.add(graph.addConstantNull(closedWorld)); // Result expected on stack. |
| 2473 return; | 2480 return; |
| 2474 } | 2481 } |
| 2475 | 2482 |
| 2476 void handleForeignJsSetStaticState(ir.StaticInvocation invocation) { | 2483 void handleForeignJsSetStaticState(ir.StaticInvocation invocation) { |
| 2477 if (_unexpectedForeignArguments(invocation, 1, 1)) { | 2484 if (_unexpectedForeignArguments(invocation, 1, 1)) { |
| 2478 // Result expected on stack. | 2485 // Result expected on stack. |
| 2479 stack.add(graph.addConstantNull(closedWorld)); | 2486 stack.add(graph.addConstantNull(closedWorld)); |
| 2480 return; | 2487 return; |
| 2481 } | 2488 } |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2515 HInstruction instruction = pop(); | 2522 HInstruction instruction = pop(); |
| 2516 | 2523 |
| 2517 if (instruction is HConstant) { | 2524 if (instruction is HConstant) { |
| 2518 js.Name name = | 2525 js.Name name = |
| 2519 astAdapter.getNameForJsGetName(argument, instruction.constant); | 2526 astAdapter.getNameForJsGetName(argument, instruction.constant); |
| 2520 stack.add(graph.addConstantStringFromName(name, closedWorld)); | 2527 stack.add(graph.addConstantStringFromName(name, closedWorld)); |
| 2521 return; | 2528 return; |
| 2522 } | 2529 } |
| 2523 | 2530 |
| 2524 reporter.reportErrorMessage( | 2531 reporter.reportErrorMessage( |
| 2525 astAdapter.getNode(argument), | 2532 _elementMap.getSpannable(targetElement, argument), |
| 2526 MessageKind.GENERIC, | 2533 MessageKind.GENERIC, |
| 2527 {'text': 'Error: Expected a JsGetName enum value.'}); | 2534 {'text': 'Error: Expected a JsGetName enum value.'}); |
| 2528 // Result expected on stack. | 2535 // Result expected on stack. |
| 2529 stack.add(graph.addConstantNull(closedWorld)); | 2536 stack.add(graph.addConstantNull(closedWorld)); |
| 2530 } | 2537 } |
| 2531 | 2538 |
| 2532 void handleForeignJsEmbeddedGlobal(ir.StaticInvocation invocation) { | 2539 void handleForeignJsEmbeddedGlobal(ir.StaticInvocation invocation) { |
| 2533 if (_unexpectedForeignArguments(invocation, 2, 2)) { | 2540 if (_unexpectedForeignArguments(invocation, 2, 2)) { |
| 2534 // Result expected on stack. | 2541 // Result expected on stack. |
| 2535 stack.add(graph.addConstantNull(closedWorld)); | 2542 stack.add(graph.addConstantNull(closedWorld)); |
| 2536 return; | 2543 return; |
| 2537 } | 2544 } |
| 2538 String globalName = _foreignConstantStringArgument( | 2545 String globalName = _foreignConstantStringArgument( |
| 2539 invocation, 1, 'JS_EMBEDDED_GLOBAL', 'second '); | 2546 invocation, 1, 'JS_EMBEDDED_GLOBAL', 'second '); |
| 2540 js.Template expr = js.js.expressionTemplateYielding( | 2547 js.Template expr = js.js.expressionTemplateYielding( |
| 2541 emitter.generateEmbeddedGlobalAccess(globalName)); | 2548 emitter.generateEmbeddedGlobalAccess(globalName)); |
| 2542 | 2549 |
| 2543 native.NativeBehavior nativeBehavior = | 2550 native.NativeBehavior nativeBehavior = |
| 2544 astAdapter.getNativeBehavior(invocation); | 2551 astAdapter.getNativeBehavior(invocation); |
| 2545 assert(invariant(astAdapter.getNode(invocation), nativeBehavior != null, | 2552 assert(invariant(_elementMap.getSpannable(targetElement, invocation), |
| 2553 nativeBehavior != null, |
| 2546 message: "No NativeBehavior for $invocation")); | 2554 message: "No NativeBehavior for $invocation")); |
| 2547 | 2555 |
| 2548 TypeMask ssaType = | 2556 TypeMask ssaType = |
| 2549 _typeInferenceMap.typeFromNativeBehavior(nativeBehavior, closedWorld); | 2557 _typeInferenceMap.typeFromNativeBehavior(nativeBehavior, closedWorld); |
| 2550 push(new HForeignCode(expr, ssaType, const <HInstruction>[], | 2558 push(new HForeignCode(expr, ssaType, const <HInstruction>[], |
| 2551 nativeBehavior: nativeBehavior)); | 2559 nativeBehavior: nativeBehavior)); |
| 2552 } | 2560 } |
| 2553 | 2561 |
| 2554 void handleForeignJsBuiltin(ir.StaticInvocation invocation) { | 2562 void handleForeignJsBuiltin(ir.StaticInvocation invocation) { |
| 2555 if (_unexpectedForeignArguments(invocation, 2)) { | 2563 if (_unexpectedForeignArguments(invocation, 2)) { |
| 2556 // Result expected on stack. | 2564 // Result expected on stack. |
| 2557 stack.add(graph.addConstantNull(closedWorld)); | 2565 stack.add(graph.addConstantNull(closedWorld)); |
| 2558 return; | 2566 return; |
| 2559 } | 2567 } |
| 2560 | 2568 |
| 2561 List<ir.Expression> arguments = invocation.arguments.positional; | 2569 List<ir.Expression> arguments = invocation.arguments.positional; |
| 2562 ir.Expression nameArgument = arguments[1]; | 2570 ir.Expression nameArgument = arguments[1]; |
| 2563 | 2571 |
| 2564 nameArgument.accept(this); | 2572 nameArgument.accept(this); |
| 2565 HInstruction instruction = pop(); | 2573 HInstruction instruction = pop(); |
| 2566 | 2574 |
| 2567 js.Template template; | 2575 js.Template template; |
| 2568 if (instruction is HConstant) { | 2576 if (instruction is HConstant) { |
| 2569 template = astAdapter.getJsBuiltinTemplate(instruction.constant); | 2577 template = astAdapter.getJsBuiltinTemplate(instruction.constant); |
| 2570 } | 2578 } |
| 2571 if (template == null) { | 2579 if (template == null) { |
| 2572 reporter.reportErrorMessage( | 2580 reporter.reportErrorMessage( |
| 2573 astAdapter.getNode(nameArgument), | 2581 _elementMap.getSpannable(targetElement, nameArgument), |
| 2574 MessageKind.GENERIC, | 2582 MessageKind.GENERIC, |
| 2575 {'text': 'Error: Expected a JsBuiltin enum value.'}); | 2583 {'text': 'Error: Expected a JsBuiltin enum value.'}); |
| 2576 // Result expected on stack. | 2584 // Result expected on stack. |
| 2577 stack.add(graph.addConstantNull(closedWorld)); | 2585 stack.add(graph.addConstantNull(closedWorld)); |
| 2578 return; | 2586 return; |
| 2579 } | 2587 } |
| 2580 | 2588 |
| 2581 List<HInstruction> inputs = <HInstruction>[]; | 2589 List<HInstruction> inputs = <HInstruction>[]; |
| 2582 for (ir.Expression argument in arguments.skip(2)) { | 2590 for (ir.Expression argument in arguments.skip(2)) { |
| 2583 argument.accept(this); | 2591 argument.accept(this); |
| 2584 inputs.add(pop()); | 2592 inputs.add(pop()); |
| 2585 } | 2593 } |
| 2586 | 2594 |
| 2587 native.NativeBehavior nativeBehavior = | 2595 native.NativeBehavior nativeBehavior = |
| 2588 astAdapter.getNativeBehavior(invocation); | 2596 astAdapter.getNativeBehavior(invocation); |
| 2589 assert(invariant(astAdapter.getNode(invocation), nativeBehavior != null, | 2597 assert(invariant(_elementMap.getSpannable(targetElement, invocation), |
| 2598 nativeBehavior != null, |
| 2590 message: "No NativeBehavior for $invocation")); | 2599 message: "No NativeBehavior for $invocation")); |
| 2591 | 2600 |
| 2592 TypeMask ssaType = | 2601 TypeMask ssaType = |
| 2593 _typeInferenceMap.typeFromNativeBehavior(nativeBehavior, closedWorld); | 2602 _typeInferenceMap.typeFromNativeBehavior(nativeBehavior, closedWorld); |
| 2594 push(new HForeignCode(template, ssaType, inputs, | 2603 push(new HForeignCode(template, ssaType, inputs, |
| 2595 nativeBehavior: nativeBehavior)); | 2604 nativeBehavior: nativeBehavior)); |
| 2596 } | 2605 } |
| 2597 | 2606 |
| 2598 void handleForeignJsGetFlag(ir.StaticInvocation invocation) { | 2607 void handleForeignJsGetFlag(ir.StaticInvocation invocation) { |
| 2599 if (_unexpectedForeignArguments(invocation, 1, 1)) { | 2608 if (_unexpectedForeignArguments(invocation, 1, 1)) { |
| 2600 stack.add( | 2609 stack.add( |
| 2601 // Result expected on stack. | 2610 // Result expected on stack. |
| 2602 graph.addConstantBool(false, closedWorld)); | 2611 graph.addConstantBool(false, closedWorld)); |
| 2603 return; | 2612 return; |
| 2604 } | 2613 } |
| 2605 String name = _foreignConstantStringArgument(invocation, 0, 'JS_GET_FLAG'); | 2614 String name = _foreignConstantStringArgument(invocation, 0, 'JS_GET_FLAG'); |
| 2606 bool value = getFlagValue(name); | 2615 bool value = getFlagValue(name); |
| 2607 if (value == null) { | 2616 if (value == null) { |
| 2608 reporter.reportErrorMessage( | 2617 reporter.reportErrorMessage( |
| 2609 astAdapter.getNode(invocation), | 2618 _elementMap.getSpannable(targetElement, invocation), |
| 2610 MessageKind.GENERIC, | 2619 MessageKind.GENERIC, |
| 2611 {'text': 'Error: Unknown internal flag "$name".'}); | 2620 {'text': 'Error: Unknown internal flag "$name".'}); |
| 2612 } else { | 2621 } else { |
| 2613 stack.add(graph.addConstantBool(value, closedWorld)); | 2622 stack.add(graph.addConstantBool(value, closedWorld)); |
| 2614 } | 2623 } |
| 2615 } | 2624 } |
| 2616 | 2625 |
| 2617 void handleJsInterceptorConstant(ir.StaticInvocation invocation) { | 2626 void handleJsInterceptorConstant(ir.StaticInvocation invocation) { |
| 2618 // Single argument must be a TypeConstant which is converted into a | 2627 // Single argument must be a TypeConstant which is converted into a |
| 2619 // InterceptorConstant. | 2628 // InterceptorConstant. |
| (...skipping 11 matching lines...) Expand all Loading... |
| 2631 argumentConstant.representedType is ResolutionInterfaceType) { | 2640 argumentConstant.representedType is ResolutionInterfaceType) { |
| 2632 ResolutionInterfaceType type = argumentConstant.representedType; | 2641 ResolutionInterfaceType type = argumentConstant.representedType; |
| 2633 // TODO(sra): Check that type is a subclass of [Interceptor]. | 2642 // TODO(sra): Check that type is a subclass of [Interceptor]. |
| 2634 ConstantValue constant = new InterceptorConstantValue(type.element); | 2643 ConstantValue constant = new InterceptorConstantValue(type.element); |
| 2635 HInstruction instruction = graph.addConstant(constant, closedWorld); | 2644 HInstruction instruction = graph.addConstant(constant, closedWorld); |
| 2636 stack.add(instruction); | 2645 stack.add(instruction); |
| 2637 return; | 2646 return; |
| 2638 } | 2647 } |
| 2639 } | 2648 } |
| 2640 | 2649 |
| 2641 reporter.reportErrorMessage(astAdapter.getNode(invocation), | 2650 reporter.reportErrorMessage( |
| 2651 _elementMap.getSpannable(targetElement, invocation), |
| 2642 MessageKind.WRONG_ARGUMENT_FOR_JS_INTERCEPTOR_CONSTANT); | 2652 MessageKind.WRONG_ARGUMENT_FOR_JS_INTERCEPTOR_CONSTANT); |
| 2643 stack.add(graph.addConstantNull(closedWorld)); | 2653 stack.add(graph.addConstantNull(closedWorld)); |
| 2644 } | 2654 } |
| 2645 | 2655 |
| 2646 void handleForeignJs(ir.StaticInvocation invocation) { | 2656 void handleForeignJs(ir.StaticInvocation invocation) { |
| 2647 if (_unexpectedForeignArguments(invocation, 2)) { | 2657 if (_unexpectedForeignArguments(invocation, 2)) { |
| 2648 // Result expected on stack. | 2658 // Result expected on stack. |
| 2649 stack.add(graph.addConstantNull(closedWorld)); | 2659 stack.add(graph.addConstantNull(closedWorld)); |
| 2650 return; | 2660 return; |
| 2651 } | 2661 } |
| 2652 | 2662 |
| 2653 native.NativeBehavior nativeBehavior = | 2663 native.NativeBehavior nativeBehavior = |
| 2654 astAdapter.getNativeBehaviorForJsCall(invocation); | 2664 astAdapter.getNativeBehaviorForJsCall(invocation); |
| 2655 assert(invariant(astAdapter.getNode(invocation), nativeBehavior != null, | 2665 assert(invariant(_elementMap.getSpannable(targetElement, invocation), |
| 2666 nativeBehavior != null, |
| 2656 message: "No NativeBehavior for $invocation")); | 2667 message: "No NativeBehavior for $invocation")); |
| 2657 | 2668 |
| 2658 List<HInstruction> inputs = <HInstruction>[]; | 2669 List<HInstruction> inputs = <HInstruction>[]; |
| 2659 for (ir.Expression argument in invocation.arguments.positional.skip(2)) { | 2670 for (ir.Expression argument in invocation.arguments.positional.skip(2)) { |
| 2660 argument.accept(this); | 2671 argument.accept(this); |
| 2661 inputs.add(pop()); | 2672 inputs.add(pop()); |
| 2662 } | 2673 } |
| 2663 | 2674 |
| 2664 if (nativeBehavior.codeTemplate.positionalArgumentCount != inputs.length) { | 2675 if (nativeBehavior.codeTemplate.positionalArgumentCount != inputs.length) { |
| 2665 reporter.reportErrorMessage( | 2676 reporter.reportErrorMessage( |
| 2666 astAdapter.getNode(invocation), MessageKind.GENERIC, { | 2677 _elementMap.getSpannable(targetElement, invocation), |
| 2678 MessageKind.GENERIC, { |
| 2667 'text': 'Mismatch between number of placeholders' | 2679 'text': 'Mismatch between number of placeholders' |
| 2668 ' and number of arguments.' | 2680 ' and number of arguments.' |
| 2669 }); | 2681 }); |
| 2670 // Result expected on stack. | 2682 // Result expected on stack. |
| 2671 stack.add(graph.addConstantNull(closedWorld)); | 2683 stack.add(graph.addConstantNull(closedWorld)); |
| 2672 return; | 2684 return; |
| 2673 } | 2685 } |
| 2674 | 2686 |
| 2675 if (native.HasCapturedPlaceholders.check(nativeBehavior.codeTemplate.ast)) { | 2687 if (native.HasCapturedPlaceholders.check(nativeBehavior.codeTemplate.ast)) { |
| 2676 reporter.reportErrorMessage( | 2688 reporter.reportErrorMessage( |
| 2677 astAdapter.getNode(invocation), MessageKind.JS_PLACEHOLDER_CAPTURE); | 2689 _elementMap.getSpannable(targetElement, invocation), |
| 2690 MessageKind.JS_PLACEHOLDER_CAPTURE); |
| 2678 } | 2691 } |
| 2679 | 2692 |
| 2680 TypeMask ssaType = | 2693 TypeMask ssaType = |
| 2681 _typeInferenceMap.typeFromNativeBehavior(nativeBehavior, closedWorld); | 2694 _typeInferenceMap.typeFromNativeBehavior(nativeBehavior, closedWorld); |
| 2682 | 2695 |
| 2683 SourceInformation sourceInformation = null; | 2696 SourceInformation sourceInformation = null; |
| 2684 push(new HForeignCode(nativeBehavior.codeTemplate, ssaType, inputs, | 2697 push(new HForeignCode(nativeBehavior.codeTemplate, ssaType, inputs, |
| 2685 isStatement: !nativeBehavior.codeTemplate.isExpression, | 2698 isStatement: !nativeBehavior.codeTemplate.isExpression, |
| 2686 effects: nativeBehavior.sideEffects, | 2699 effects: nativeBehavior.sideEffects, |
| 2687 nativeBehavior: nativeBehavior) | 2700 nativeBehavior: nativeBehavior) |
| (...skipping 401 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3089 HInstruction awaited = pop(); | 3102 HInstruction awaited = pop(); |
| 3090 // TODO(herhut): Improve this type. | 3103 // TODO(herhut): Improve this type. |
| 3091 push(new HAwait(awaited, closedWorld.commonMasks.dynamicType)); | 3104 push(new HAwait(awaited, closedWorld.commonMasks.dynamicType)); |
| 3092 } | 3105 } |
| 3093 | 3106 |
| 3094 @override | 3107 @override |
| 3095 void visitRethrow(ir.Rethrow rethrowNode) { | 3108 void visitRethrow(ir.Rethrow rethrowNode) { |
| 3096 HInstruction exception = rethrowableException; | 3109 HInstruction exception = rethrowableException; |
| 3097 if (exception == null) { | 3110 if (exception == null) { |
| 3098 exception = graph.addConstantNull(closedWorld); | 3111 exception = graph.addConstantNull(closedWorld); |
| 3099 reporter.internalError(astAdapter.getNode(rethrowNode), | 3112 reporter.internalError( |
| 3113 _elementMap.getSpannable(targetElement, rethrowNode), |
| 3100 'rethrowableException should not be null.'); | 3114 'rethrowableException should not be null.'); |
| 3101 } | 3115 } |
| 3102 handleInTryStatement(); | 3116 handleInTryStatement(); |
| 3103 SourceInformation sourceInformation = null; | 3117 SourceInformation sourceInformation = null; |
| 3104 closeAndGotoExit(new HThrow(exception, sourceInformation, isRethrow: true)); | 3118 closeAndGotoExit(new HThrow(exception, sourceInformation, isRethrow: true)); |
| 3105 // ir.Rethrow is an expression so we need to push a value - a constant with | 3119 // ir.Rethrow is an expression so we need to push a value - a constant with |
| 3106 // no type. | 3120 // no type. |
| 3107 stack.add(graph.addConstantUnreachable(closedWorld)); | 3121 stack.add(graph.addConstantUnreachable(closedWorld)); |
| 3108 } | 3122 } |
| 3109 | 3123 |
| (...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3385 enterBlock.setBlockFlow( | 3399 enterBlock.setBlockFlow( |
| 3386 new HTryBlockInformation( | 3400 new HTryBlockInformation( |
| 3387 kernelBuilder.wrapStatementGraph(bodyGraph), | 3401 kernelBuilder.wrapStatementGraph(bodyGraph), |
| 3388 exception, | 3402 exception, |
| 3389 kernelBuilder.wrapStatementGraph(catchGraph), | 3403 kernelBuilder.wrapStatementGraph(catchGraph), |
| 3390 kernelBuilder.wrapStatementGraph(finallyGraph)), | 3404 kernelBuilder.wrapStatementGraph(finallyGraph)), |
| 3391 exitBlock); | 3405 exitBlock); |
| 3392 kernelBuilder.inTryStatement = previouslyInTryStatement; | 3406 kernelBuilder.inTryStatement = previouslyInTryStatement; |
| 3393 } | 3407 } |
| 3394 } | 3408 } |
| OLD | NEW |