| 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 js_backend; | 5 part of js_backend; |
| 6 | 6 |
| 7 /** | 7 /** |
| 8 * A function element that represents a closure call. The signature is copied | 8 * A function element that represents a closure call. The signature is copied |
| 9 * from the given element. | 9 * from the given element. |
| 10 */ | 10 */ |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 68 /** Shorter access to [isolatePropertiesName]. Both here in the code, as | 68 /** Shorter access to [isolatePropertiesName]. Both here in the code, as |
| 69 well as in the generated code. */ | 69 well as in the generated code. */ |
| 70 String isolateProperties; | 70 String isolateProperties; |
| 71 String classesCollector; | 71 String classesCollector; |
| 72 final Set<ClassElement> neededClasses = new Set<ClassElement>(); | 72 final Set<ClassElement> neededClasses = new Set<ClassElement>(); |
| 73 final List<ClassElement> regularClasses = <ClassElement>[]; | 73 final List<ClassElement> regularClasses = <ClassElement>[]; |
| 74 final List<ClassElement> deferredClasses = <ClassElement>[]; | 74 final List<ClassElement> deferredClasses = <ClassElement>[]; |
| 75 final List<ClassElement> nativeClasses = <ClassElement>[]; | 75 final List<ClassElement> nativeClasses = <ClassElement>[]; |
| 76 final List<Selector> trivialNsmHandlers = <Selector>[]; | 76 final List<Selector> trivialNsmHandlers = <Selector>[]; |
| 77 final Map<String, String> mangledFieldNames = <String, String>{}; | 77 final Map<String, String> mangledFieldNames = <String, String>{}; |
| 78 final Set<String> interceptorInvocationNames = new Set<String>(); |
| 78 | 79 |
| 79 // TODO(ngeoffray): remove this field. | 80 // TODO(ngeoffray): remove this field. |
| 80 Set<ClassElement> instantiatedClasses; | 81 Set<ClassElement> instantiatedClasses; |
| 81 | 82 |
| 82 final List<jsAst.Expression> boundClosures = <jsAst.Expression>[]; | 83 final List<jsAst.Expression> boundClosures = <jsAst.Expression>[]; |
| 83 | 84 |
| 84 JavaScriptBackend get backend => compiler.backend; | 85 JavaScriptBackend get backend => compiler.backend; |
| 85 | 86 |
| 86 String get _ => compiler.enableMinification ? "" : " "; | 87 String get _ => compiler.enableMinification ? "" : " "; |
| 87 String get n => compiler.enableMinification ? "" : "\n"; | 88 String get n => compiler.enableMinification ? "" : "\n"; |
| (...skipping 863 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 951 // The arguments that will be passed to the real method. | 952 // The arguments that will be passed to the real method. |
| 952 List<jsAst.Expression> argumentsBuffer = | 953 List<jsAst.Expression> argumentsBuffer = |
| 953 new List<jsAst.Expression>( | 954 new List<jsAst.Expression>( |
| 954 parameters.parameterCount + extraArgumentCount); | 955 parameters.parameterCount + extraArgumentCount); |
| 955 | 956 |
| 956 int count = 0; | 957 int count = 0; |
| 957 if (isInterceptedMethod) { | 958 if (isInterceptedMethod) { |
| 958 count++; | 959 count++; |
| 959 parametersBuffer[0] = new jsAst.Parameter(receiverArgumentName); | 960 parametersBuffer[0] = new jsAst.Parameter(receiverArgumentName); |
| 960 argumentsBuffer[0] = js(receiverArgumentName); | 961 argumentsBuffer[0] = js(receiverArgumentName); |
| 962 interceptorInvocationNames.add(invocationName); |
| 961 } | 963 } |
| 962 | 964 |
| 963 int optionalParameterStart = positionalArgumentCount + extraArgumentCount; | 965 int optionalParameterStart = positionalArgumentCount + extraArgumentCount; |
| 964 // Includes extra receiver argument when using interceptor convention | 966 // Includes extra receiver argument when using interceptor convention |
| 965 int indexOfLastOptionalArgumentInParameters = optionalParameterStart - 1; | 967 int indexOfLastOptionalArgumentInParameters = optionalParameterStart - 1; |
| 966 | 968 |
| 967 TreeElements elements = | 969 TreeElements elements = |
| 968 compiler.enqueuer.resolution.getCachedElements(member); | 970 compiler.enqueuer.resolution.getCachedElements(member); |
| 969 | 971 |
| 970 parameters.orderedForEachParameter((Element element) { | 972 parameters.orderedForEachParameter((Element element) { |
| (...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1168 // TODO(floitsch): we don't need to deal with members of | 1170 // TODO(floitsch): we don't need to deal with members of |
| 1169 // uninstantiated classes, that have been overwritten by subclasses. | 1171 // uninstantiated classes, that have been overwritten by subclasses. |
| 1170 | 1172 |
| 1171 if (member.isFunction() | 1173 if (member.isFunction() |
| 1172 || member.isGenerativeConstructorBody() | 1174 || member.isGenerativeConstructorBody() |
| 1173 || member.isAccessor()) { | 1175 || member.isAccessor()) { |
| 1174 if (member.isAbstract(compiler)) return; | 1176 if (member.isAbstract(compiler)) return; |
| 1175 jsAst.Expression code = backend.generatedCode[member]; | 1177 jsAst.Expression code = backend.generatedCode[member]; |
| 1176 if (code == null) return; | 1178 if (code == null) return; |
| 1177 String name = namer.getName(member); | 1179 String name = namer.getName(member); |
| 1180 if (backend.isInterceptedMethod(member)) { |
| 1181 interceptorInvocationNames.add(name); |
| 1182 } |
| 1178 builder.addProperty(name, code); | 1183 builder.addProperty(name, code); |
| 1179 var metadata = buildMetadataFunction(member); | 1184 var metadata = buildMetadataFunction(member); |
| 1180 if (metadata != null) { | 1185 if (metadata != null) { |
| 1181 builder.addProperty('@$name', metadata); | 1186 builder.addProperty('@$name', metadata); |
| 1182 } | 1187 } |
| 1183 String reflectionName = getReflectionName(member); | 1188 String reflectionName = getReflectionName(member); |
| 1184 if (reflectionName != null) { | 1189 if (reflectionName != null) { |
| 1185 builder.addProperty('+$reflectionName', js('0')); | 1190 builder.addProperty('+$reflectionName', js('0')); |
| 1186 } | 1191 } |
| 1187 code = backend.generatedBailoutCode[member]; | 1192 code = backend.generatedBailoutCode[member]; |
| (...skipping 1782 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2970 } | 2975 } |
| 2971 | 2976 |
| 2972 /** | 2977 /** |
| 2973 * If [JSInvocationMirror._invokeOn] has been compiled, emit all the | 2978 * If [JSInvocationMirror._invokeOn] has been compiled, emit all the |
| 2974 * possible selector names that are intercepted into the | 2979 * possible selector names that are intercepted into the |
| 2975 * [interceptedNames] top-level variable. The implementation of | 2980 * [interceptedNames] top-level variable. The implementation of |
| 2976 * [_invokeOn] will use it to determine whether it should call the | 2981 * [_invokeOn] will use it to determine whether it should call the |
| 2977 * method with an extra parameter. | 2982 * method with an extra parameter. |
| 2978 */ | 2983 */ |
| 2979 void emitInterceptedNames(CodeBuffer buffer) { | 2984 void emitInterceptedNames(CodeBuffer buffer) { |
| 2985 // TODO(ahe): We should not generate the list of intercepted names at |
| 2986 // compile time, it can be generated automatically at runtime given |
| 2987 // subclasses of Interceptor (which can easily be identified). |
| 2980 if (!compiler.enabledInvokeOn) return; | 2988 if (!compiler.enabledInvokeOn) return; |
| 2981 String name = backend.namer.getName(backend.interceptedNames); | 2989 String name = backend.namer.getName(backend.interceptedNames); |
| 2982 | 2990 |
| 2983 int index = 0; | 2991 int index = 0; |
| 2984 List<jsAst.ArrayElement> elements = backend.usedInterceptors.map( | 2992 var invocationNames = interceptorInvocationNames.toList()..sort(); |
| 2985 (Selector selector) { | 2993 List<jsAst.ArrayElement> elements = invocationNames.map( |
| 2986 jsAst.Literal str = js.string(namer.invocationName(selector)); | 2994 (String invocationName) { |
| 2995 jsAst.Literal str = js.string(invocationName); |
| 2987 return new jsAst.ArrayElement(index++, str); | 2996 return new jsAst.ArrayElement(index++, str); |
| 2988 }).toList(); | 2997 }).toList(); |
| 2989 jsAst.ArrayInitializer array = new jsAst.ArrayInitializer( | 2998 jsAst.ArrayInitializer array = |
| 2990 backend.usedInterceptors.length, | 2999 new jsAst.ArrayInitializer(invocationNames.length, elements); |
| 2991 elements); | |
| 2992 | 3000 |
| 2993 jsAst.Expression assignment = js('$isolateProperties.$name = #', array); | 3001 jsAst.Expression assignment = js('$isolateProperties.$name = #', array); |
| 2994 | 3002 |
| 2995 buffer.write(jsAst.prettyPrint(assignment, compiler)); | 3003 buffer.write(jsAst.prettyPrint(assignment, compiler)); |
| 2996 buffer.write(N); | 3004 buffer.write(N); |
| 2997 } | 3005 } |
| 2998 | 3006 |
| 2999 void emitInitFunction(CodeBuffer buffer) { | 3007 void emitInitFunction(CodeBuffer buffer) { |
| 3000 jsAst.Fun fun = js.fun([], [ | 3008 jsAst.Fun fun = js.fun([], [ |
| 3001 js('$isolateProperties = {}'), | 3009 js('$isolateProperties = {}'), |
| (...skipping 383 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3385 | 3393 |
| 3386 const String HOOKS_API_USAGE = """ | 3394 const String HOOKS_API_USAGE = """ |
| 3387 // The code supports the following hooks: | 3395 // The code supports the following hooks: |
| 3388 // dartPrint(message) - if this function is defined it is called | 3396 // dartPrint(message) - if this function is defined it is called |
| 3389 // instead of the Dart [print] method. | 3397 // instead of the Dart [print] method. |
| 3390 // dartMainRunner(main) - if this function is defined, the Dart [main] | 3398 // dartMainRunner(main) - if this function is defined, the Dart [main] |
| 3391 // method will not be invoked directly. | 3399 // method will not be invoked directly. |
| 3392 // Instead, a closure that will invoke [main] is | 3400 // Instead, a closure that will invoke [main] is |
| 3393 // passed to [dartMainRunner]. | 3401 // passed to [dartMainRunner]. |
| 3394 """; | 3402 """; |
| OLD | NEW |