| 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 321 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 332 js('field = field.substring(divider + 1)') | 332 js('field = field.substring(divider + 1)') |
| 333 ]), | 333 ]), |
| 334 | 334 |
| 335 // if (needsGetter) { | 335 // if (needsGetter) { |
| 336 js.if_('getterCode', [ | 336 js.if_('getterCode', [ |
| 337 js('var args = (getterCode & 2) ? "$receiverParamName" : ""'), | 337 js('var args = (getterCode & 2) ? "$receiverParamName" : ""'), |
| 338 js('var receiver = (getterCode & 1) ? "this" : "$receiverParamName"'), | 338 js('var receiver = (getterCode & 1) ? "this" : "$receiverParamName"'), |
| 339 js('var body = "return " + receiver + "." + field'), | 339 js('var body = "return " + receiver + "." + field'), |
| 340 js('prototype["${namer.getterPrefix}" + accessorName] = ' | 340 js('prototype["${namer.getterPrefix}" + accessorName] = ' |
| 341 'new Function(args, body)'), | 341 'new Function(args, body)'), |
| 342 js.if_('!reflectable', [ | 342 js.if_('reflectable', [ |
| 343 js('prototype["${namer.getterPrefix}" + accessorName].' | 343 js('prototype["${namer.getterPrefix}" + accessorName].' |
| 344 '$reflectableField = false')]) | 344 '$reflectableField = 1')]) |
| 345 ]), | 345 ]), |
| 346 | 346 |
| 347 // if (needsSetter) { | 347 // if (needsSetter) { |
| 348 js.if_('setterCode', [ | 348 js.if_('setterCode', [ |
| 349 js('var args = (setterCode & 2)' | 349 js('var args = (setterCode & 2)' |
| 350 ' ? "$receiverParamName,${_}$valueParamName"' | 350 ' ? "$receiverParamName,${_}$valueParamName"' |
| 351 ' : "$valueParamName"'), | 351 ' : "$valueParamName"'), |
| 352 js('var receiver = (setterCode & 1) ? "this" : "$receiverParamName"'), | 352 js('var receiver = (setterCode & 1) ? "this" : "$receiverParamName"'), |
| 353 js('var body = receiver + "." + field + "$_=$_$valueParamName"'), | 353 js('var body = receiver + "." + field + "$_=$_$valueParamName"'), |
| 354 js('prototype["${namer.setterPrefix}" + accessorName] = ' | 354 js('prototype["${namer.setterPrefix}" + accessorName] = ' |
| 355 'new Function(args, body)'), | 355 'new Function(args, body)'), |
| 356 js.if_('!reflectable', [ | 356 js.if_('reflectable', [ |
| 357 js('prototype["${namer.setterPrefix}" + accessorName].' | 357 js('prototype["${namer.setterPrefix}" + accessorName].' |
| 358 '$reflectableField = false')]) | 358 '$reflectableField = 1')]) |
| 359 ]), | 359 ]), |
| 360 | 360 |
| 361 ]), | 361 ]), |
| 362 | 362 |
| 363 // return field; | 363 // return field; |
| 364 js.return_('field') | 364 js.return_('field') |
| 365 ]); | 365 ]); |
| 366 | 366 |
| 367 return new jsAst.FunctionDeclaration( | 367 return new jsAst.FunctionDeclaration( |
| 368 new jsAst.VariableDeclaration('generateAccessor'), | 368 new jsAst.VariableDeclaration('generateAccessor'), |
| (...skipping 2504 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2873 for (int i = 0; i < selector.argumentCount; i++) { | 2873 for (int i = 0; i < selector.argumentCount; i++) { |
| 2874 parameters.add(new jsAst.Parameter('\$$i')); | 2874 parameters.add(new jsAst.Parameter('\$$i')); |
| 2875 } | 2875 } |
| 2876 | 2876 |
| 2877 List<jsAst.Expression> argNames = | 2877 List<jsAst.Expression> argNames = |
| 2878 selector.getOrderedNamedArguments().map((SourceString name) => | 2878 selector.getOrderedNamedArguments().map((SourceString name) => |
| 2879 js.string(name.slowToString())).toList(); | 2879 js.string(name.slowToString())).toList(); |
| 2880 | 2880 |
| 2881 String methodName = selector.invocationMirrorMemberName; | 2881 String methodName = selector.invocationMirrorMemberName; |
| 2882 String internalName = namer.invocationMirrorInternalName(selector); | 2882 String internalName = namer.invocationMirrorInternalName(selector); |
| 2883 String reflectionName = getReflectionName(selector, internalName); |
| 2883 if (!haveVeryFewNoSuchMemberHandlers && | 2884 if (!haveVeryFewNoSuchMemberHandlers && |
| 2884 isTrivialNsmHandler(type, argNames, selector, internalName)) { | 2885 isTrivialNsmHandler(type, argNames, selector, internalName) && |
| 2886 reflectionName == null) { |
| 2885 trivialNsmHandlers.add(selector); | 2887 trivialNsmHandlers.add(selector); |
| 2886 return null; | 2888 return null; |
| 2887 } | 2889 } |
| 2888 | 2890 |
| 2889 String createInvocationMirror = namer.getName( | 2891 String createInvocationMirror = namer.getName( |
| 2890 backend.getCreateInvocationMirror()); | 2892 backend.getCreateInvocationMirror()); |
| 2891 | 2893 |
| 2892 assert(backend.isInterceptedName(Compiler.NO_SUCH_METHOD)); | 2894 assert(backend.isInterceptedName(Compiler.NO_SUCH_METHOD)); |
| 2893 jsAst.Expression expression = js('this.$noSuchMethodName')( | 2895 jsAst.Expression expression = js('this.$noSuchMethodName')( |
| 2894 [js('this'), | 2896 [js('this'), |
| 2895 js(namer.CURRENT_ISOLATE)[createInvocationMirror]([ | 2897 js(namer.CURRENT_ISOLATE)[createInvocationMirror]([ |
| 2896 js.string(compiler.enableMinification ? | 2898 js.string(compiler.enableMinification ? |
| 2897 internalName : methodName), | 2899 internalName : methodName), |
| 2898 js.string(internalName), | 2900 js.string(internalName), |
| 2899 type, | 2901 type, |
| 2900 new jsAst.ArrayInitializer.from( | 2902 new jsAst.ArrayInitializer.from( |
| 2901 parameters.map((param) => js(param.name)).toList()), | 2903 parameters.map((param) => js(param.name)).toList()), |
| 2902 new jsAst.ArrayInitializer.from(argNames)])]); | 2904 new jsAst.ArrayInitializer.from(argNames)])]); |
| 2903 parameters = backend.isInterceptedName(selector.name) | 2905 parameters = backend.isInterceptedName(selector.name) |
| 2904 ? ([new jsAst.Parameter('\$receiver')]..addAll(parameters)) | 2906 ? ([new jsAst.Parameter('\$receiver')]..addAll(parameters)) |
| 2905 : parameters; | 2907 : parameters; |
| 2906 return js.fun(parameters, js.return_(expression)); | 2908 return js.fun(parameters, js.return_(expression)); |
| 2907 } | 2909 } |
| 2908 | 2910 |
| 2909 for (String jsName in addedJsNames.keys.toList()..sort()) { | 2911 for (String jsName in addedJsNames.keys.toList()..sort()) { |
| 2910 Selector selector = addedJsNames[jsName]; | 2912 Selector selector = addedJsNames[jsName]; |
| 2911 jsAst.Expression method = generateMethod(jsName, selector); | 2913 jsAst.Expression method = generateMethod(jsName, selector); |
| 2912 if (method != null) defineStub(jsName, method); | 2914 if (method != null) { |
| 2915 defineStub(jsName, method); |
| 2916 String reflectionName = getReflectionName(selector, jsName); |
| 2917 if (reflectionName != null) { |
| 2918 bool accessible = compiler.world.allFunctions.filter(selector).any( |
| 2919 (Element e) => backend.isAccessibleByReflection(e)); |
| 2920 defineStub('+$reflectionName', js(accessible ? '1' : '0')); |
| 2921 } |
| 2922 } |
| 2913 } | 2923 } |
| 2914 } | 2924 } |
| 2915 | 2925 |
| 2916 String buildIsolateSetup(CodeBuffer buffer, | 2926 String buildIsolateSetup(CodeBuffer buffer, |
| 2917 Element appMain, | 2927 Element appMain, |
| 2918 Element isolateMain) { | 2928 Element isolateMain) { |
| 2919 String mainAccess = "${namer.isolateStaticClosureAccess(appMain)}"; | 2929 String mainAccess = "${namer.isolateStaticClosureAccess(appMain)}"; |
| 2920 String currentIsolate = "${namer.CURRENT_ISOLATE}"; | 2930 String currentIsolate = "${namer.CURRENT_ISOLATE}"; |
| 2921 // Since we pass the closurized version of the main method to | 2931 // Since we pass the closurized version of the main method to |
| 2922 // the isolate method, we must make sure that it exists. | 2932 // the isolate method, we must make sure that it exists. |
| (...skipping 1181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4104 var functions = []; | 4114 var functions = []; |
| 4105 function processStatics(descriptor) { | 4115 function processStatics(descriptor) { |
| 4106 for (var property in descriptor) { | 4116 for (var property in descriptor) { |
| 4107 if (!hasOwnProperty.call(descriptor, property)) continue; | 4117 if (!hasOwnProperty.call(descriptor, property)) continue; |
| 4108 if (property === "") continue; | 4118 if (property === "") continue; |
| 4109 var element = descriptor[property]; | 4119 var element = descriptor[property]; |
| 4110 var firstChar = property.substring(0, 1); | 4120 var firstChar = property.substring(0, 1); |
| 4111 var previousProperty; | 4121 var previousProperty; |
| 4112 if (firstChar === "+") { | 4122 if (firstChar === "+") { |
| 4113 mangledGlobalNames[previousProperty] = property.substring(1); | 4123 mangledGlobalNames[previousProperty] = property.substring(1); |
| 4114 descriptor[previousProperty].''' // Break long line. | 4124 if (descriptor[property] == 1) ''' // Break long line. |
| 4115 '''$reflectableField = (descriptor[property] == 1); | 4125 '''descriptor[previousProperty].$reflectableField = 1; |
| 4116 if (element && element.length) ''' // Break long line. | 4126 if (element && element.length) ''' // Break long line. |
| 4117 '''init.interfaces[previousProperty] = element; | 4127 '''init.interfaces[previousProperty] = element; |
| 4118 } else if (firstChar === "@") { | 4128 } else if (firstChar === "@") { |
| 4119 property = property.substring(1); | 4129 property = property.substring(1); |
| 4120 ${namer.CURRENT_ISOLATE}[property][$metadataField] = element; | 4130 ${namer.CURRENT_ISOLATE}[property][$metadataField] = element; |
| 4121 } else if (typeof element === "function") { | 4131 } else if (typeof element === "function") { |
| 4122 ${namer.CURRENT_ISOLATE}[previousProperty = property] = element; | 4132 ${namer.CURRENT_ISOLATE}[previousProperty = property] = element; |
| 4123 functions.push(property); | 4133 functions.push(property); |
| 4124 } else { | 4134 } else { |
| 4125 previousProperty = property; | 4135 previousProperty = property; |
| 4126 var newDesc = {}; | 4136 var newDesc = {}; |
| 4127 var previousProp; | 4137 var previousProp; |
| 4128 for (var prop in element) { | 4138 for (var prop in element) { |
| 4129 if (!hasOwnProperty.call(element, prop)) continue; | 4139 if (!hasOwnProperty.call(element, prop)) continue; |
| 4130 firstChar = prop.substring(0, 1); | 4140 firstChar = prop.substring(0, 1); |
| 4131 if (prop === "static") { | 4141 if (prop === "static") { |
| 4132 processStatics(init.statics[property] = element[prop]); | 4142 processStatics(init.statics[property] = element[prop]); |
| 4133 } else if (firstChar === "+") { | 4143 } else if (firstChar === "+") { |
| 4134 mangledNames[previousProp] = prop.substring(1); | 4144 mangledNames[previousProp] = prop.substring(1); |
| 4135 element[previousProp].''' // Break long line. | 4145 if (element[prop] == 1) ''' // Break long line. |
| 4136 '''$reflectableField = (element[prop] == 1); | 4146 '''element[previousProp].$reflectableField = 1; |
| 4137 } else if (firstChar === "@" && prop !== "@") { | 4147 } else if (firstChar === "@" && prop !== "@") { |
| 4138 newDesc[prop.substring(1)][$metadataField] = element[prop]; | 4148 newDesc[prop.substring(1)][$metadataField] = element[prop]; |
| 4139 } else { | 4149 } else { |
| 4140 newDesc[previousProp = prop] = element[prop]; | 4150 newDesc[previousProp = prop] = element[prop]; |
| 4141 } | 4151 } |
| 4142 } | 4152 } |
| 4143 $classesCollector[property] = newDesc; | 4153 $classesCollector[property] = newDesc; |
| 4144 classes.push(property); | 4154 classes.push(property); |
| 4145 } | 4155 } |
| 4146 } | 4156 } |
| (...skipping 11 matching lines...) Expand all Loading... |
| 4158 | 4168 |
| 4159 const String HOOKS_API_USAGE = """ | 4169 const String HOOKS_API_USAGE = """ |
| 4160 // The code supports the following hooks: | 4170 // The code supports the following hooks: |
| 4161 // dartPrint(message) - if this function is defined it is called | 4171 // dartPrint(message) - if this function is defined it is called |
| 4162 // instead of the Dart [print] method. | 4172 // instead of the Dart [print] method. |
| 4163 // dartMainRunner(main) - if this function is defined, the Dart [main] | 4173 // dartMainRunner(main) - if this function is defined, the Dart [main] |
| 4164 // method will not be invoked directly. | 4174 // method will not be invoked directly. |
| 4165 // Instead, a closure that will invoke [main] is | 4175 // Instead, a closure that will invoke [main] is |
| 4166 // passed to [dartMainRunner]. | 4176 // passed to [dartMainRunner]. |
| 4167 """; | 4177 """; |
| OLD | NEW |