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 '../constants/expressions.dart'; | 9 import '../constants/expressions.dart'; |
10 import '../dart_types.dart'; | 10 import '../dart_types.dart'; |
(...skipping 383 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
394 assert(definition.arguments.tail.isEmpty); | 394 assert(definition.arguments.tail.isEmpty); |
395 initialValue = visit(definition.arguments.head); | 395 initialValue = visit(definition.arguments.head); |
396 } else { | 396 } else { |
397 assert(definition is ast.Identifier); | 397 assert(definition is ast.Identifier); |
398 } | 398 } |
399 irBuilder.declareLocalVariable(element, initialValue: initialValue); | 399 irBuilder.declareLocalVariable(element, initialValue: initialValue); |
400 } | 400 } |
401 return null; | 401 return null; |
402 } | 402 } |
403 | 403 |
| 404 static final RegExp nativeRedirectionRegExp = |
| 405 new RegExp(r'^[a-zA-Z][a-zA-Z_$0-9]*$'); |
| 406 |
404 // Build(Return(e), C) = C'[InvokeContinuation(return, x)] | 407 // Build(Return(e), C) = C'[InvokeContinuation(return, x)] |
405 // where (C', x) = Build(e, C) | 408 // where (C', x) = Build(e, C) |
406 // | 409 // |
407 // Return without a subexpression is translated as if it were return null. | 410 // Return without a subexpression is translated as if it were return null. |
408 ir.Primitive visitReturn(ast.Return node) { | 411 visitReturn(ast.Return node) { |
409 assert(irBuilder.isOpen); | 412 assert(irBuilder.isOpen); |
410 assert(invariant(node, node.beginToken.value != 'native')); | 413 SourceInformation source = sourceInformationBuilder.buildReturn(node); |
411 irBuilder.buildReturn( | 414 if (node.beginToken.value == 'native') { |
412 value: build(node.expression), | 415 FunctionElement function = irBuilder.state.currentElement; |
413 sourceInformation: sourceInformationBuilder.buildReturn(node)); | 416 assert(function.isNative); |
414 return null; | 417 ast.Node nativeBody = node.expression; |
| 418 if (nativeBody != null) { |
| 419 ast.LiteralString jsCode = nativeBody.asLiteralString(); |
| 420 String javaScriptCode = jsCode.dartString.slowToString(); |
| 421 assert(invariant(nativeBody, |
| 422 !nativeRedirectionRegExp.hasMatch(javaScriptCode), |
| 423 message: "Deprecated syntax, use @JSName('name') instead.")); |
| 424 assert(invariant(nativeBody, |
| 425 function.functionSignature.parameterCount == 0, |
| 426 message: 'native "..." syntax is restricted to ' |
| 427 'functions with zero parameters.')); |
| 428 irBuilder.buildNativeFunctionBody(function, javaScriptCode); |
| 429 } else { |
| 430 irBuilder.buildRedirectingNativeFunctionBody(function, source); |
| 431 } |
| 432 } else { |
| 433 irBuilder.buildReturn( |
| 434 value: build(node.expression), |
| 435 sourceInformation: source); |
| 436 } |
415 } | 437 } |
416 | 438 |
417 visitSwitchStatement(ast.SwitchStatement node) { | 439 visitSwitchStatement(ast.SwitchStatement node) { |
418 assert(irBuilder.isOpen); | 440 assert(irBuilder.isOpen); |
419 // We do not handle switch statements with continue to labeled cases. | 441 // We do not handle switch statements with continue to labeled cases. |
420 for (ast.SwitchCase switchCase in node.cases) { | 442 for (ast.SwitchCase switchCase in node.cases) { |
421 for (ast.Node labelOrCase in switchCase.labelsAndCases) { | 443 for (ast.Node labelOrCase in switchCase.labelsAndCases) { |
422 if (labelOrCase is ast.Label) { | 444 if (labelOrCase is ast.Label) { |
423 LabelDefinition definition = elements.getLabelDefinition(labelOrCase); | 445 LabelDefinition definition = elements.getLabelDefinition(labelOrCase); |
424 if (definition != null && definition.isContinueTarget) { | 446 if (definition != null && definition.isContinueTarget) { |
(...skipping 1849 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2274 return _backend.getStringInterpolationHelper(); | 2296 return _backend.getStringInterpolationHelper(); |
2275 } | 2297 } |
2276 | 2298 |
2277 FunctionElement get throwTypeErrorHelper => _backend.getThrowTypeError(); | 2299 FunctionElement get throwTypeErrorHelper => _backend.getThrowTypeError(); |
2278 | 2300 |
2279 ClassElement get nullClass => _compiler.nullClass; | 2301 ClassElement get nullClass => _compiler.nullClass; |
2280 | 2302 |
2281 DartType unaliasType(DartType type) => type.unalias(_compiler); | 2303 DartType unaliasType(DartType type) => type.unalias(_compiler); |
2282 | 2304 |
2283 TypeMask getTypeMaskForForeign(NativeBehavior behavior) { | 2305 TypeMask getTypeMaskForForeign(NativeBehavior behavior) { |
| 2306 if (behavior == null) { |
| 2307 return _backend.dynamicType; |
| 2308 } |
2284 return TypeMaskFactory.fromNativeBehavior(behavior, _compiler); | 2309 return TypeMaskFactory.fromNativeBehavior(behavior, _compiler); |
2285 } | 2310 } |
2286 | 2311 |
2287 FieldElement locateSingleField(Selector selector, TypeMask type) { | 2312 FieldElement locateSingleField(Selector selector, TypeMask type) { |
2288 return _compiler.world.locateSingleField(selector, type); | 2313 return _compiler.world.locateSingleField(selector, type); |
2289 } | 2314 } |
| 2315 |
| 2316 Element get closureConverter { |
| 2317 return _backend.getClosureConverter(); |
| 2318 } |
| 2319 |
| 2320 void addNativeMethod(FunctionElement function) { |
| 2321 _backend.emitter.nativeEmitter.nativeMethods.add(function); |
| 2322 } |
2290 } | 2323 } |
2291 | 2324 |
2292 /// IR builder specific to the JavaScript backend, coupled to the [JsIrBuilder]. | 2325 /// IR builder specific to the JavaScript backend, coupled to the [JsIrBuilder]. |
2293 class JsIrBuilderVisitor extends IrBuilderVisitor { | 2326 class JsIrBuilderVisitor extends IrBuilderVisitor { |
2294 JavaScriptBackend get backend => compiler.backend; | 2327 JavaScriptBackend get backend => compiler.backend; |
2295 | 2328 |
2296 /// Result of closure conversion for the current body of code. | 2329 /// Result of closure conversion for the current body of code. |
2297 /// | 2330 /// |
2298 /// Will be initialized upon entering the body of a function. | 2331 /// Will be initialized upon entering the body of a function. |
2299 /// It is computed by the [ClosureTranslator]. | 2332 /// It is computed by the [ClosureTranslator]. |
(...skipping 1047 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3347 if (compiler.backend.isForeign(function)) { | 3380 if (compiler.backend.isForeign(function)) { |
3348 return handleForeignCode(node, function, argumentList, callStructure); | 3381 return handleForeignCode(node, function, argumentList, callStructure); |
3349 } else { | 3382 } else { |
3350 return irBuilder.buildStaticFunctionInvocation(function, callStructure, | 3383 return irBuilder.buildStaticFunctionInvocation(function, callStructure, |
3351 translateStaticArguments(argumentList, function, callStructure), | 3384 translateStaticArguments(argumentList, function, callStructure), |
3352 sourceInformation: | 3385 sourceInformation: |
3353 sourceInformationBuilder.buildCall(node, node.selector)); | 3386 sourceInformationBuilder.buildCall(node, node.selector)); |
3354 } | 3387 } |
3355 } | 3388 } |
3356 } | 3389 } |
OLD | NEW |