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 4067 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4078 compiler.internalError(node.argumentsNode, | 4078 compiler.internalError(node.argumentsNode, |
4079 'At least two arguments expected.'); | 4079 'At least two arguments expected.'); |
4080 } | 4080 } |
4081 native.NativeBehavior nativeBehavior = | 4081 native.NativeBehavior nativeBehavior = |
4082 compiler.enqueuer.resolution.nativeEnqueuer.getNativeBehaviorOf(node); | 4082 compiler.enqueuer.resolution.nativeEnqueuer.getNativeBehaviorOf(node); |
4083 | 4083 |
4084 List<HInstruction> inputs = <HInstruction>[]; | 4084 List<HInstruction> inputs = <HInstruction>[]; |
4085 addGenericSendArgumentsToList(link.tail.tail, inputs); | 4085 addGenericSendArgumentsToList(link.tail.tail, inputs); |
4086 | 4086 |
4087 if (nativeBehavior.codeTemplate.positionalArgumentCount != inputs.length) { | 4087 if (nativeBehavior.codeTemplate.positionalArgumentCount != inputs.length) { |
4088 compiler.reportError( | 4088 compiler.reportErrorMessage( |
4089 node, MessageKind.GENERIC, | 4089 node, MessageKind.GENERIC, |
4090 {'text': | 4090 {'text': |
4091 'Mismatch between number of placeholders' | 4091 'Mismatch between number of placeholders' |
4092 ' and number of arguments.'}); | 4092 ' and number of arguments.'}); |
4093 stack.add(graph.addConstantNull(compiler)); // Result expected on stack. | 4093 stack.add(graph.addConstantNull(compiler)); // Result expected on stack. |
4094 return; | 4094 return; |
4095 } | 4095 } |
4096 | 4096 |
4097 TypeMask ssaType = | 4097 TypeMask ssaType = |
4098 TypeMaskFactory.fromNativeBehavior(nativeBehavior, compiler); | 4098 TypeMaskFactory.fromNativeBehavior(nativeBehavior, compiler); |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4148 } | 4148 } |
4149 pushInvokeStatic(null, element, [], typeMask: backend.dynamicType); | 4149 pushInvokeStatic(null, element, [], typeMask: backend.dynamicType); |
4150 } | 4150 } |
4151 } | 4151 } |
4152 | 4152 |
4153 void handleForeignJsGetFlag(ast.Send node) { | 4153 void handleForeignJsGetFlag(ast.Send node) { |
4154 List<ast.Node> arguments = node.arguments.toList(); | 4154 List<ast.Node> arguments = node.arguments.toList(); |
4155 ast.Node argument; | 4155 ast.Node argument; |
4156 switch (arguments.length) { | 4156 switch (arguments.length) { |
4157 case 0: | 4157 case 0: |
4158 compiler.reportError( | 4158 compiler.reportErrorMessage( |
4159 node, MessageKind.GENERIC, | 4159 node, MessageKind.GENERIC, |
4160 {'text': 'Error: Expected one argument to JS_GET_FLAG.'}); | 4160 {'text': 'Error: Expected one argument to JS_GET_FLAG.'}); |
4161 return; | 4161 return; |
4162 case 1: | 4162 case 1: |
4163 argument = arguments[0]; | 4163 argument = arguments[0]; |
4164 break; | 4164 break; |
4165 default: | 4165 default: |
4166 for (int i = 1; i < arguments.length; i++) { | 4166 for (int i = 1; i < arguments.length; i++) { |
4167 compiler.reportError( | 4167 compiler.reportErrorMessage( |
4168 arguments[i], MessageKind.GENERIC, | 4168 arguments[i], MessageKind.GENERIC, |
4169 {'text': 'Error: Extra argument to JS_GET_FLAG.'}); | 4169 {'text': 'Error: Extra argument to JS_GET_FLAG.'}); |
4170 } | 4170 } |
4171 return; | 4171 return; |
4172 } | 4172 } |
4173 ast.LiteralString string = argument.asLiteralString(); | 4173 ast.LiteralString string = argument.asLiteralString(); |
4174 if (string == null) { | 4174 if (string == null) { |
4175 compiler.reportError( | 4175 compiler.reportErrorMessage( |
4176 argument, MessageKind.GENERIC, | 4176 argument, MessageKind.GENERIC, |
4177 {'text': 'Error: Expected a literal string.'}); | 4177 {'text': 'Error: Expected a literal string.'}); |
4178 } | 4178 } |
4179 String name = string.dartString.slowToString(); | 4179 String name = string.dartString.slowToString(); |
4180 bool value = false; | 4180 bool value = false; |
4181 switch (name) { | 4181 switch (name) { |
4182 case 'MUST_RETAIN_METADATA': | 4182 case 'MUST_RETAIN_METADATA': |
4183 value = backend.mustRetainMetadata; | 4183 value = backend.mustRetainMetadata; |
4184 break; | 4184 break; |
4185 case 'USE_CONTENT_SECURITY_POLICY': | 4185 case 'USE_CONTENT_SECURITY_POLICY': |
4186 value = compiler.useContentSecurityPolicy; | 4186 value = compiler.useContentSecurityPolicy; |
4187 break; | 4187 break; |
4188 default: | 4188 default: |
4189 compiler.reportError( | 4189 compiler.reportErrorMessage( |
4190 node, MessageKind.GENERIC, | 4190 node, MessageKind.GENERIC, |
4191 {'text': 'Error: Unknown internal flag "$name".'}); | 4191 {'text': 'Error: Unknown internal flag "$name".'}); |
4192 } | 4192 } |
4193 stack.add(graph.addConstantBool(value, compiler)); | 4193 stack.add(graph.addConstantBool(value, compiler)); |
4194 } | 4194 } |
4195 | 4195 |
4196 void handleForeignJsGetName(ast.Send node) { | 4196 void handleForeignJsGetName(ast.Send node) { |
4197 List<ast.Node> arguments = node.arguments.toList(); | 4197 List<ast.Node> arguments = node.arguments.toList(); |
4198 ast.Node argument; | 4198 ast.Node argument; |
4199 switch (arguments.length) { | 4199 switch (arguments.length) { |
4200 case 0: | 4200 case 0: |
4201 compiler.reportError( | 4201 compiler.reportErrorMessage( |
4202 node, MessageKind.GENERIC, | 4202 node, MessageKind.GENERIC, |
4203 {'text': 'Error: Expected one argument to JS_GET_NAME.'}); | 4203 {'text': 'Error: Expected one argument to JS_GET_NAME.'}); |
4204 return; | 4204 return; |
4205 case 1: | 4205 case 1: |
4206 argument = arguments[0]; | 4206 argument = arguments[0]; |
4207 break; | 4207 break; |
4208 default: | 4208 default: |
4209 for (int i = 1; i < arguments.length; i++) { | 4209 for (int i = 1; i < arguments.length; i++) { |
4210 compiler.reportError( | 4210 compiler.reportErrorMessage( |
4211 arguments[i], MessageKind.GENERIC, | 4211 arguments[i], MessageKind.GENERIC, |
4212 {'text': 'Error: Extra argument to JS_GET_NAME.'}); | 4212 {'text': 'Error: Extra argument to JS_GET_NAME.'}); |
4213 } | 4213 } |
4214 return; | 4214 return; |
4215 } | 4215 } |
4216 Element element = elements[argument]; | 4216 Element element = elements[argument]; |
4217 if (element == null || | 4217 if (element == null || |
4218 element is! FieldElement || | 4218 element is! FieldElement || |
4219 element.enclosingClass != backend.jsGetNameEnum) { | 4219 element.enclosingClass != backend.jsGetNameEnum) { |
4220 compiler.reportError( | 4220 compiler.reportErrorMessage( |
4221 argument, MessageKind.GENERIC, | 4221 argument, MessageKind.GENERIC, |
4222 {'text': 'Error: Expected a JsGetName enum value.'}); | 4222 {'text': 'Error: Expected a JsGetName enum value.'}); |
4223 } | 4223 } |
4224 EnumClassElement enumClass = element.enclosingClass; | 4224 EnumClassElement enumClass = element.enclosingClass; |
4225 int index = enumClass.enumValues.indexOf(element); | 4225 int index = enumClass.enumValues.indexOf(element); |
4226 stack.add( | 4226 stack.add( |
4227 addConstantStringFromName( | 4227 addConstantStringFromName( |
4228 backend.namer.getNameForJsGetName( | 4228 backend.namer.getNameForJsGetName( |
4229 argument, JsGetName.values[index]))); | 4229 argument, JsGetName.values[index]))); |
4230 } | 4230 } |
4231 | 4231 |
4232 void handleForeignJsBuiltin(ast.Send node) { | 4232 void handleForeignJsBuiltin(ast.Send node) { |
4233 List<ast.Node> arguments = node.arguments.toList(); | 4233 List<ast.Node> arguments = node.arguments.toList(); |
4234 ast.Node argument; | 4234 ast.Node argument; |
4235 if (arguments.length < 2) { | 4235 if (arguments.length < 2) { |
4236 compiler.reportError( | 4236 compiler.reportErrorMessage( |
4237 node, MessageKind.GENERIC, | 4237 node, MessageKind.GENERIC, |
4238 {'text': 'Error: Expected at least two arguments to JS_BUILTIN.'}); | 4238 {'text': 'Error: Expected at least two arguments to JS_BUILTIN.'}); |
4239 } | 4239 } |
4240 | 4240 |
4241 Element builtinElement = elements[arguments[1]]; | 4241 Element builtinElement = elements[arguments[1]]; |
4242 if (builtinElement == null || | 4242 if (builtinElement == null || |
4243 (builtinElement is! FieldElement) || | 4243 (builtinElement is! FieldElement) || |
4244 builtinElement.enclosingClass != backend.jsBuiltinEnum) { | 4244 builtinElement.enclosingClass != backend.jsBuiltinEnum) { |
4245 compiler.reportError( | 4245 compiler.reportErrorMessage( |
4246 argument, MessageKind.GENERIC, | 4246 argument, MessageKind.GENERIC, |
4247 {'text': 'Error: Expected a JsBuiltin enum value.'}); | 4247 {'text': 'Error: Expected a JsBuiltin enum value.'}); |
4248 } | 4248 } |
4249 EnumClassElement enumClass = builtinElement.enclosingClass; | 4249 EnumClassElement enumClass = builtinElement.enclosingClass; |
4250 int index = enumClass.enumValues.indexOf(builtinElement); | 4250 int index = enumClass.enumValues.indexOf(builtinElement); |
4251 | 4251 |
4252 js.Template template = | 4252 js.Template template = |
4253 backend.emitter.builtinTemplateFor(JsBuiltin.values[index]); | 4253 backend.emitter.builtinTemplateFor(JsBuiltin.values[index]); |
4254 | 4254 |
4255 List<HInstruction> compiledArguments = <HInstruction>[]; | 4255 List<HInstruction> compiledArguments = <HInstruction>[]; |
(...skipping 13 matching lines...) Expand all Loading... |
4269 compiledArguments, | 4269 compiledArguments, |
4270 nativeBehavior: nativeBehavior)); | 4270 nativeBehavior: nativeBehavior)); |
4271 } | 4271 } |
4272 | 4272 |
4273 void handleForeignJsEmbeddedGlobal(ast.Send node) { | 4273 void handleForeignJsEmbeddedGlobal(ast.Send node) { |
4274 List<ast.Node> arguments = node.arguments.toList(); | 4274 List<ast.Node> arguments = node.arguments.toList(); |
4275 ast.Node globalNameNode; | 4275 ast.Node globalNameNode; |
4276 switch (arguments.length) { | 4276 switch (arguments.length) { |
4277 case 0: | 4277 case 0: |
4278 case 1: | 4278 case 1: |
4279 compiler.reportError( | 4279 compiler.reportErrorMessage( |
4280 node, MessageKind.GENERIC, | 4280 node, MessageKind.GENERIC, |
4281 {'text': 'Error: Expected two arguments to JS_EMBEDDED_GLOBAL.'}); | 4281 {'text': 'Error: Expected two arguments to JS_EMBEDDED_GLOBAL.'}); |
4282 return; | 4282 return; |
4283 case 2: | 4283 case 2: |
4284 // The type has been extracted earlier. We are only interested in the | 4284 // The type has been extracted earlier. We are only interested in the |
4285 // name in this function. | 4285 // name in this function. |
4286 globalNameNode = arguments[1]; | 4286 globalNameNode = arguments[1]; |
4287 break; | 4287 break; |
4288 default: | 4288 default: |
4289 for (int i = 2; i < arguments.length; i++) { | 4289 for (int i = 2; i < arguments.length; i++) { |
4290 compiler.reportError( | 4290 compiler.reportErrorMessage( |
4291 arguments[i], MessageKind.GENERIC, | 4291 arguments[i], MessageKind.GENERIC, |
4292 {'text': 'Error: Extra argument to JS_EMBEDDED_GLOBAL.'}); | 4292 {'text': 'Error: Extra argument to JS_EMBEDDED_GLOBAL.'}); |
4293 } | 4293 } |
4294 return; | 4294 return; |
4295 } | 4295 } |
4296 visit(globalNameNode); | 4296 visit(globalNameNode); |
4297 HInstruction globalNameHNode = pop(); | 4297 HInstruction globalNameHNode = pop(); |
4298 if (!globalNameHNode.isConstantString()) { | 4298 if (!globalNameHNode.isConstantString()) { |
4299 compiler.reportError( | 4299 compiler.reportErrorMessage( |
4300 arguments[1], MessageKind.GENERIC, | 4300 arguments[1], MessageKind.GENERIC, |
4301 {'text': 'Error: Expected String as second argument ' | 4301 {'text': 'Error: Expected String as second argument ' |
4302 'to JS_EMBEDDED_GLOBAL.'}); | 4302 'to JS_EMBEDDED_GLOBAL.'}); |
4303 return; | 4303 return; |
4304 } | 4304 } |
4305 HConstant hConstant = globalNameHNode; | 4305 HConstant hConstant = globalNameHNode; |
4306 StringConstantValue constant = hConstant.constant; | 4306 StringConstantValue constant = hConstant.constant; |
4307 String globalName = constant.primitiveValue.slowToString(); | 4307 String globalName = constant.primitiveValue.slowToString(); |
4308 js.Template expr = js.js.expressionTemplateYielding( | 4308 js.Template expr = js.js.expressionTemplateYielding( |
4309 backend.emitter.generateEmbeddedGlobalAccess(globalName)); | 4309 backend.emitter.generateEmbeddedGlobalAccess(globalName)); |
(...skipping 16 matching lines...) Expand all Loading... |
4326 ConstantValue argumentConstant = argumentInstruction.constant; | 4326 ConstantValue argumentConstant = argumentInstruction.constant; |
4327 if (argumentConstant is TypeConstantValue) { | 4327 if (argumentConstant is TypeConstantValue) { |
4328 ConstantValue constant = | 4328 ConstantValue constant = |
4329 new InterceptorConstantValue(argumentConstant.representedType); | 4329 new InterceptorConstantValue(argumentConstant.representedType); |
4330 HInstruction instruction = graph.addConstant(constant, compiler); | 4330 HInstruction instruction = graph.addConstant(constant, compiler); |
4331 stack.add(instruction); | 4331 stack.add(instruction); |
4332 return; | 4332 return; |
4333 } | 4333 } |
4334 } | 4334 } |
4335 } | 4335 } |
4336 compiler.reportError(node, | 4336 compiler.reportErrorMessage( |
| 4337 node, |
4337 MessageKind.WRONG_ARGUMENT_FOR_JS_INTERCEPTOR_CONSTANT); | 4338 MessageKind.WRONG_ARGUMENT_FOR_JS_INTERCEPTOR_CONSTANT); |
4338 stack.add(graph.addConstantNull(compiler)); | 4339 stack.add(graph.addConstantNull(compiler)); |
4339 } | 4340 } |
4340 | 4341 |
4341 void handleForeignJsCallInIsolate(ast.Send node) { | 4342 void handleForeignJsCallInIsolate(ast.Send node) { |
4342 Link<ast.Node> link = node.arguments; | 4343 Link<ast.Node> link = node.arguments; |
4343 if (!compiler.hasIsolateSupport) { | 4344 if (!compiler.hasIsolateSupport) { |
4344 // If the isolate library is not used, we just invoke the | 4345 // If the isolate library is not used, we just invoke the |
4345 // closure. | 4346 // closure. |
4346 visit(link.tail.head); | 4347 visit(link.tail.head); |
(...skipping 2536 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6883 stack.add(stringBuilder.result); | 6884 stack.add(stringBuilder.result); |
6884 } | 6885 } |
6885 | 6886 |
6886 void visitLiteralNull(ast.LiteralNull node) { | 6887 void visitLiteralNull(ast.LiteralNull node) { |
6887 stack.add(graph.addConstantNull(compiler)); | 6888 stack.add(graph.addConstantNull(compiler)); |
6888 } | 6889 } |
6889 | 6890 |
6890 visitNodeList(ast.NodeList node) { | 6891 visitNodeList(ast.NodeList node) { |
6891 for (Link<ast.Node> link = node.nodes; !link.isEmpty; link = link.tail) { | 6892 for (Link<ast.Node> link = node.nodes; !link.isEmpty; link = link.tail) { |
6892 if (isAborted()) { | 6893 if (isAborted()) { |
6893 compiler.reportWarning(link.head, | 6894 compiler.reportHintMessage( |
6894 MessageKind.GENERIC, {'text': 'dead code'}); | 6895 link.head, |
| 6896 MessageKind.GENERIC, |
| 6897 {'text': 'dead code'}); |
6895 } else { | 6898 } else { |
6896 visit(link.head); | 6899 visit(link.head); |
6897 } | 6900 } |
6898 } | 6901 } |
6899 } | 6902 } |
6900 | 6903 |
6901 void visitParenthesizedExpression(ast.ParenthesizedExpression node) { | 6904 void visitParenthesizedExpression(ast.ParenthesizedExpression node) { |
6902 visit(node.expression); | 6905 visit(node.expression); |
6903 } | 6906 } |
6904 | 6907 |
(...skipping 2080 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8985 if (unaliased is TypedefType) throw 'unable to unalias $type'; | 8988 if (unaliased is TypedefType) throw 'unable to unalias $type'; |
8986 unaliased.accept(this, builder); | 8989 unaliased.accept(this, builder); |
8987 } | 8990 } |
8988 | 8991 |
8989 void visitDynamicType(DynamicType type, SsaBuilder builder) { | 8992 void visitDynamicType(DynamicType type, SsaBuilder builder) { |
8990 JavaScriptBackend backend = builder.compiler.backend; | 8993 JavaScriptBackend backend = builder.compiler.backend; |
8991 ClassElement cls = backend.findHelper('DynamicRuntimeType'); | 8994 ClassElement cls = backend.findHelper('DynamicRuntimeType'); |
8992 builder.push(new HDynamicType(type, new TypeMask.exact(cls, classWorld))); | 8995 builder.push(new HDynamicType(type, new TypeMask.exact(cls, classWorld))); |
8993 } | 8996 } |
8994 } | 8997 } |
OLD | NEW |