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 return %NewObjectFromBound(fn, null); |
| 1161 } |
| 1162 |
| 1163 return fn.apply(this_arg, arguments); |
| 1164 }; |
| 1165 } else { |
1157 var bound_args = new $Array(argc_bound); | 1166 var bound_args = new $Array(argc_bound); |
1158 for(var i = 0; i < argc_bound; i++) { | 1167 for(var i = 0; i < argc_bound; i++) { |
1159 bound_args[i] = %_Arguments(i+1); | 1168 bound_args[i] = %_Arguments(i+1); |
1160 } | 1169 } |
| 1170 |
| 1171 var result = function() { |
| 1172 // If this is a construct call we use a special runtime method |
| 1173 // to generate the actual object using the bound function. |
| 1174 if (%_IsConstructCall()) { |
| 1175 return %NewObjectFromBound(fn, bound_args); |
| 1176 } |
| 1177 |
| 1178 // Combine the args we got from the bind call with the args |
| 1179 // given as argument to the invocation. |
| 1180 var argc = %_ArgumentsLength(); |
| 1181 var args = new $Array(argc + argc_bound); |
| 1182 // Add bound arguments. |
| 1183 for (var i = 0; i < argc_bound; i++) { |
| 1184 args[i] = bound_args[i]; |
| 1185 } |
| 1186 // Add arguments from call. |
| 1187 for (var i = 0; i < argc; i++) { |
| 1188 args[argc_bound + i] = %_Arguments(i); |
| 1189 } |
| 1190 return fn.apply(this_arg, args); |
| 1191 }; |
1161 } | 1192 } |
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 | 1193 |
1184 // We already have caller and arguments properties on functions, | 1194 // We already have caller and arguments properties on functions, |
1185 // which are non-configurable. It therefore makes no sence to | 1195 // which are non-configurable. It therefore makes no sence to |
1186 // try to redefine these as defined by the spec. The spec says | 1196 // 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 | 1197 // that bind should make these throw a TypeError if get or set |
1188 // is called and make them non-enumerable and non-configurable. | 1198 // is called and make them non-enumerable and non-configurable. |
1189 // To be consistent with our normal functions we leave this as it is. | 1199 // To be consistent with our normal functions we leave this as it is. |
1190 | 1200 |
1191 // Set the correct length. | 1201 // Set the correct length. |
1192 var length = (this.length - argc_bound) > 0 ? this.length - argc_bound : 0; | 1202 var length = (this.length - argc_bound) > 0 ? this.length - argc_bound : 0; |
(...skipping 30 matching lines...) Expand all Loading... |
1223 // ---------------------------------------------------------------------------- | 1233 // ---------------------------------------------------------------------------- |
1224 | 1234 |
1225 function SetupFunction() { | 1235 function SetupFunction() { |
1226 InstallFunctions($Function.prototype, DONT_ENUM, $Array( | 1236 InstallFunctions($Function.prototype, DONT_ENUM, $Array( |
1227 "bind", FunctionBind, | 1237 "bind", FunctionBind, |
1228 "toString", FunctionToString | 1238 "toString", FunctionToString |
1229 )); | 1239 )); |
1230 } | 1240 } |
1231 | 1241 |
1232 SetupFunction(); | 1242 SetupFunction(); |
OLD | NEW |