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 |