| OLD | NEW |
| 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 1135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1146 } | 1146 } |
| 1147 | 1147 |
| 1148 | 1148 |
| 1149 // ES5 15.3.4.5 | 1149 // ES5 15.3.4.5 |
| 1150 function FunctionBind(this_arg) { // Length is 1. | 1150 function FunctionBind(this_arg) { // Length is 1. |
| 1151 if (!IS_FUNCTION(this)) { | 1151 if (!IS_FUNCTION(this)) { |
| 1152 throw new $TypeError('Bind must be called on a function'); | 1152 throw new $TypeError('Bind must be called on a function'); |
| 1153 } | 1153 } |
| 1154 // this_arg is not an argument that should be bound. | 1154 // this_arg is not an argument that should be bound. |
| 1155 var argc_bound = (%_ArgumentsLength() || 1) - 1; | 1155 var argc_bound = (%_ArgumentsLength() || 1) - 1; |
| 1156 if (argc_bound > 0) { | 1156 var fn = this; |
| 1157 if (argc_bound == 0) { |
| 1158 var result = function() { |
| 1159 if (%_IsConstructCall()) { |
| 1160 // %NewObjectFromBound implicitly uses arguments passed to this |
| 1161 // function. We do not pass the arguments object explicitly to avoid |
| 1162 // materializing it and guarantee that this function will be optimized. |
| 1163 return %NewObjectFromBound(fn, null); |
| 1164 } |
| 1165 |
| 1166 return fn.apply(this_arg, arguments); |
| 1167 }; |
| 1168 } else { |
| 1157 var bound_args = new $Array(argc_bound); | 1169 var bound_args = new $Array(argc_bound); |
| 1158 for(var i = 0; i < argc_bound; i++) { | 1170 for(var i = 0; i < argc_bound; i++) { |
| 1159 bound_args[i] = %_Arguments(i+1); | 1171 bound_args[i] = %_Arguments(i+1); |
| 1160 } | 1172 } |
| 1173 |
| 1174 var result = function() { |
| 1175 // If this is a construct call we use a special runtime method |
| 1176 // to generate the actual object using the bound function. |
| 1177 if (%_IsConstructCall()) { |
| 1178 // %NewObjectFromBound implicitly uses arguments passed to this |
| 1179 // function. We do not pass the arguments object explicitly to avoid |
| 1180 // materializing it and guarantee that this function will be optimized. |
| 1181 return %NewObjectFromBound(fn, bound_args); |
| 1182 } |
| 1183 |
| 1184 // Combine the args we got from the bind call with the args |
| 1185 // given as argument to the invocation. |
| 1186 var argc = %_ArgumentsLength(); |
| 1187 var args = new $Array(argc + argc_bound); |
| 1188 // Add bound arguments. |
| 1189 for (var i = 0; i < argc_bound; i++) { |
| 1190 args[i] = bound_args[i]; |
| 1191 } |
| 1192 // Add arguments from call. |
| 1193 for (var i = 0; i < argc; i++) { |
| 1194 args[argc_bound + i] = %_Arguments(i); |
| 1195 } |
| 1196 return fn.apply(this_arg, args); |
| 1197 }; |
| 1161 } | 1198 } |
| 1162 var fn = this; | |
| 1163 var result = function() { | |
| 1164 // Combine the args we got from the bind call with the args | |
| 1165 // given as argument to the invocation. | |
| 1166 var argc = %_ArgumentsLength(); | |
| 1167 var args = new $Array(argc + argc_bound); | |
| 1168 // Add bound arguments. | |
| 1169 for (var i = 0; i < argc_bound; i++) { | |
| 1170 args[i] = bound_args[i]; | |
| 1171 } | |
| 1172 // Add arguments from call. | |
| 1173 for (var i = 0; i < argc; i++) { | |
| 1174 args[argc_bound + i] = %_Arguments(i); | |
| 1175 } | |
| 1176 // If this is a construct call we use a special runtime method | |
| 1177 // to generate the actual object using the bound function. | |
| 1178 if (%_IsConstructCall()) { | |
| 1179 return %NewObjectFromBound(fn, args); | |
| 1180 } | |
| 1181 return fn.apply(this_arg, args); | |
| 1182 }; | |
| 1183 | 1199 |
| 1184 // We already have caller and arguments properties on functions, | 1200 // We already have caller and arguments properties on functions, |
| 1185 // which are non-configurable. It therefore makes no sence to | 1201 // which are non-configurable. It therefore makes no sence to |
| 1186 // try to redefine these as defined by the spec. The spec says | 1202 // try to redefine these as defined by the spec. The spec says |
| 1187 // that bind should make these throw a TypeError if get or set | 1203 // that bind should make these throw a TypeError if get or set |
| 1188 // is called and make them non-enumerable and non-configurable. | 1204 // is called and make them non-enumerable and non-configurable. |
| 1189 // To be consistent with our normal functions we leave this as it is. | 1205 // To be consistent with our normal functions we leave this as it is. |
| 1190 | 1206 |
| 1191 // Set the correct length. | 1207 // Set the correct length. |
| 1192 var length = (this.length - argc_bound) > 0 ? this.length - argc_bound : 0; | 1208 var length = (this.length - argc_bound) > 0 ? this.length - argc_bound : 0; |
| (...skipping 30 matching lines...) Expand all Loading... |
| 1223 // ---------------------------------------------------------------------------- | 1239 // ---------------------------------------------------------------------------- |
| 1224 | 1240 |
| 1225 function SetupFunction() { | 1241 function SetupFunction() { |
| 1226 InstallFunctions($Function.prototype, DONT_ENUM, $Array( | 1242 InstallFunctions($Function.prototype, DONT_ENUM, $Array( |
| 1227 "bind", FunctionBind, | 1243 "bind", FunctionBind, |
| 1228 "toString", FunctionToString | 1244 "toString", FunctionToString |
| 1229 )); | 1245 )); |
| 1230 } | 1246 } |
| 1231 | 1247 |
| 1232 SetupFunction(); | 1248 SetupFunction(); |
| OLD | NEW |