| 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 part of ssa; | 5 part of ssa; |
| 6 | 6 |
| 7 class SsaFunctionCompiler implements FunctionCompiler { | 7 class SsaFunctionCompiler implements FunctionCompiler { |
| 8 final SsaCodeGeneratorTask generator; | 8 final SsaCodeGeneratorTask generator; |
| 9 final SsaBuilderTask builder; | 9 final SsaBuilderTask builder; |
| 10 final SsaOptimizerTask optimizer; | 10 final SsaOptimizerTask optimizer; |
| (...skipping 5834 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5845 ..sourceInformation = sourceInformation); | 5845 ..sourceInformation = sourceInformation); |
| 5846 } | 5846 } |
| 5847 } | 5847 } |
| 5848 | 5848 |
| 5849 bool _hasNamedParameters(FunctionElement function) { | 5849 bool _hasNamedParameters(FunctionElement function) { |
| 5850 FunctionSignature params = function.functionSignature; | 5850 FunctionSignature params = function.functionSignature; |
| 5851 return params.optionalParameterCount > 0 | 5851 return params.optionalParameterCount > 0 |
| 5852 && params.optionalParametersAreNamed; | 5852 && params.optionalParametersAreNamed; |
| 5853 } | 5853 } |
| 5854 | 5854 |
| 5855 HForeignCode invokeJsInteropFunction(Element element, | 5855 HForeignCode invokeJsInteropFunction(FunctionElement element, |
| 5856 List<HInstruction> arguments, | 5856 List<HInstruction> arguments, |
| 5857 SourceInformation sourceInformation) { | 5857 SourceInformation sourceInformation) { |
| 5858 assert(element.isJsInterop); | 5858 assert(element.isJsInterop); |
| 5859 nativeEmitter.nativeMethods.add(element); | 5859 nativeEmitter.nativeMethods.add(element); |
| 5860 String templateString; | 5860 String templateString; |
| 5861 | 5861 |
| 5862 if (element.isFactoryConstructor && | 5862 if (element.isFactoryConstructor && |
| 5863 backend.jsInteropAnalysis.hasAnonymousAnnotation(element.contextClass))
{ | 5863 backend.jsInteropAnalysis.hasAnonymousAnnotation(element.contextClass))
{ |
| 5864 // Factory constructor that is syntactic sugar for creating a JavaScript | 5864 // Factory constructor that is syntactic sugar for creating a JavaScript |
| 5865 // object literal. | 5865 // object literal. |
| (...skipping 13 matching lines...) Expand all Loading... |
| 5879 parameterNameMap[parameter.name] = | 5879 parameterNameMap[parameter.name] = |
| 5880 new js.InterpolatedExpression(positions++); | 5880 new js.InterpolatedExpression(positions++); |
| 5881 } | 5881 } |
| 5882 i++; | 5882 i++; |
| 5883 }); | 5883 }); |
| 5884 var codeTemplate = new js.Template(null, | 5884 var codeTemplate = new js.Template(null, |
| 5885 js.objectLiteral(parameterNameMap)); | 5885 js.objectLiteral(parameterNameMap)); |
| 5886 | 5886 |
| 5887 var nativeBehavior = new native.NativeBehavior() | 5887 var nativeBehavior = new native.NativeBehavior() |
| 5888 ..codeTemplate = codeTemplate; | 5888 ..codeTemplate = codeTemplate; |
| 5889 if (compiler.trustJSInteropTypeAnnotations) { |
| 5890 nativeBehavior.typesReturned.add(constructor.enclosingClass.thisType); |
| 5891 } |
| 5889 return new HForeignCode( | 5892 return new HForeignCode( |
| 5890 codeTemplate, | 5893 codeTemplate, |
| 5891 backend.dynamicType, filteredArguments, | 5894 backend.dynamicType, filteredArguments, |
| 5892 nativeBehavior: nativeBehavior) | 5895 nativeBehavior: nativeBehavior) |
| 5893 ..sourceInformation = sourceInformation; | 5896 ..sourceInformation = sourceInformation; |
| 5894 } | 5897 } |
| 5895 var target = new HForeignCode(js.js.parseForeignJS( | 5898 var target = new HForeignCode(js.js.parseForeignJS( |
| 5896 "${backend.namer.fixedBackendPath(element)}." | 5899 "${backend.namer.fixedBackendPath(element)}." |
| 5897 "${element.fixedBackendName}"), | 5900 "${element.fixedBackendName}"), |
| 5898 backend.dynamicType, | 5901 backend.dynamicType, |
| 5899 <HInstruction>[]); | 5902 <HInstruction>[]); |
| 5900 add(target); | 5903 add(target); |
| 5901 // Strip off trailing arguments that were not specified. | 5904 // Strip off trailing arguments that were not specified. |
| 5902 // we could assert that the trailing arguments are all null. | 5905 // we could assert that the trailing arguments are all null. |
| 5903 // TODO(jacobr): rewrite named arguments to an object literal matching | 5906 // TODO(jacobr): rewrite named arguments to an object literal matching |
| 5904 // the factory constructor case. | 5907 // the factory constructor case. |
| 5905 arguments = arguments.where((arg) => arg != null).toList(); | 5908 arguments = arguments.where((arg) => arg != null).toList(); |
| 5906 var inputs = <HInstruction>[target]..addAll(arguments); | 5909 var inputs = <HInstruction>[target]..addAll(arguments); |
| 5907 | 5910 |
| 5908 js.Template codeTemplate; | 5911 var nativeBehavior = new native.NativeBehavior() |
| 5909 if (element.isGetter) { | 5912 ..sideEffects.setAllSideEffects(); |
| 5910 codeTemplate = js.js.parseForeignJS("#"); | |
| 5911 } else if (element.isSetter) { | |
| 5912 codeTemplate = js.js.parseForeignJS("# = #"); | |
| 5913 } else { | |
| 5914 FunctionElement function = element; | |
| 5915 FunctionSignature params = function.functionSignature; | |
| 5916 | 5913 |
| 5917 var argsStub = <String>[]; | 5914 DartType type = element.isConstructor ? |
| 5918 for (int i = 0; i < arguments.length; i++) { | 5915 element.enclosingClass.thisType : element.type.returnType; |
| 5919 argsStub.add('#'); | 5916 // Native behavior effects here are similar to native/behavior.dart. |
| 5920 } | 5917 // The return type is dynamic if we don't trust js-interop type |
| 5918 // declarations. |
| 5919 nativeBehavior.typesReturned.add( |
| 5920 compiler.trustJSInteropTypeAnnotations ? type : const DynamicType()); |
| 5921 | 5921 |
| 5922 if (element.isConstructor) { | 5922 // The allocation effects include the declared type if it is native (which |
| 5923 codeTemplate = js.js.parseForeignJS("new #(${argsStub.join(",")})"); | 5923 // includes js interop types). |
| 5924 } else { | 5924 if (type.element != null && type.element.isNative) { |
| 5925 codeTemplate = js.js.parseForeignJS("#(${argsStub.join(",")})"); | 5925 nativeBehavior.typesInstantiated.add(type); |
| 5926 } | |
| 5927 } | 5926 } |
| 5928 | 5927 |
| 5929 var nativeBehavior = new native.NativeBehavior() | 5928 // It also includes any other JS interop type if we don't trust the |
| 5930 ..codeTemplate = codeTemplate | 5929 // annotation or if is declared too broad. |
| 5931 ..typesReturned.add( | 5930 if (!compiler.trustJSInteropTypeAnnotations || type.isObject || |
| 5932 backend.jsJavaScriptObjectClass.thisType) | 5931 type.isDynamic) { |
| 5933 ..typesInstantiated.add( | 5932 nativeBehavior.typesInstantiated.add( |
| 5934 backend.jsJavaScriptObjectClass.thisType) | 5933 backend.jsJavaScriptObjectClass.thisType); |
| 5935 ..sideEffects.setAllSideEffects(); | 5934 } |
| 5935 |
| 5936 String code; |
| 5937 if (element.isGetter) { |
| 5938 code = "#"; |
| 5939 } else if (element.isSetter) { |
| 5940 code = "# = #"; |
| 5941 } else { |
| 5942 var args = new List.filled(arguments.length, '#').join(','); |
| 5943 code = element.isConstructor ? "new #($args)" : "#($args)"; |
| 5944 } |
| 5945 js.Template codeTemplate = js.js.parseForeignJS(code); |
| 5946 nativeBehavior.codeTemplate = codeTemplate; |
| 5947 |
| 5936 return new HForeignCode( | 5948 return new HForeignCode( |
| 5937 codeTemplate, | 5949 codeTemplate, |
| 5938 backend.dynamicType, inputs, | 5950 backend.dynamicType, inputs, |
| 5939 nativeBehavior: nativeBehavior) | 5951 nativeBehavior: nativeBehavior) |
| 5940 ..sourceInformation = sourceInformation; | 5952 ..sourceInformation = sourceInformation; |
| 5941 } | 5953 } |
| 5942 | 5954 |
| 5943 void pushInvokeStatic(ast.Node location, | 5955 void pushInvokeStatic(ast.Node location, |
| 5944 Element element, | 5956 Element element, |
| 5945 List<HInstruction> arguments, | 5957 List<HInstruction> arguments, |
| (...skipping 3203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9149 if (unaliased is TypedefType) throw 'unable to unalias $type'; | 9161 if (unaliased is TypedefType) throw 'unable to unalias $type'; |
| 9150 unaliased.accept(this, builder); | 9162 unaliased.accept(this, builder); |
| 9151 } | 9163 } |
| 9152 | 9164 |
| 9153 void visitDynamicType(DynamicType type, SsaBuilder builder) { | 9165 void visitDynamicType(DynamicType type, SsaBuilder builder) { |
| 9154 JavaScriptBackend backend = builder.compiler.backend; | 9166 JavaScriptBackend backend = builder.compiler.backend; |
| 9155 ClassElement cls = backend.findHelper('DynamicRuntimeType'); | 9167 ClassElement cls = backend.findHelper('DynamicRuntimeType'); |
| 9156 builder.push(new HDynamicType(type, new TypeMask.exact(cls, classWorld))); | 9168 builder.push(new HDynamicType(type, new TypeMask.exact(cls, classWorld))); |
| 9157 } | 9169 } |
| 9158 } | 9170 } |
| OLD | NEW |