Fix some bugs in Function.prototype.bind implementation.

Correctly handle not passing thisArg.
Fixes to NewObjectFromBound to use correct argument count, not leak memory,
and handle constructors that throw exceptions.

Review URL: http://codereview.chromium.org/2878057

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@5137 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
lrn@chromium.org 2010-07-27 09:20:21 +00:00
parent 3f0d383db6
commit 539142a161
2 changed files with 11 additions and 5 deletions

View File

@ -6757,17 +6757,23 @@ static Object* Runtime_NewObjectFromBound(Arguments args) {
CONVERT_ARG_CHECKED(JSFunction, function, 0);
CONVERT_ARG_CHECKED(JSArray, params, 1);
RUNTIME_ASSERT(params->HasFastElements());
FixedArray* fixed = FixedArray::cast(params->elements());
bool exception = false;
Object*** param_data = NewArray<Object**>(fixed->length());
for (int i = 0; i < fixed->length(); i++) {
int fixed_length = Smi::cast(params->length())->value();
SmartPointer<Object**> param_data(NewArray<Object**>(fixed_length));
for (int i = 0; i < fixed_length; i++) {
Handle<Object> val = Handle<Object>(fixed->get(i));
param_data[i] = val.location();
}
bool exception = false;
Handle<Object> result = Execution::New(
function, fixed->length(), param_data, &exception);
function, fixed_length, *param_data, &exception);
if (exception) {
return Failure::Exception();
}
ASSERT(!result.is_null());
return *result;
}

View File

@ -1105,7 +1105,7 @@ function FunctionBind(this_arg) { // Length is 1.
throw new $TypeError('Bind must be called on a function');
}
// this_arg is not an argument that should be bound.
var argc_bound = %_ArgumentsLength() - 1;
var argc_bound = (%_ArgumentsLength() || 1) - 1;
if (argc_bound > 0) {
var bound_args = new $Array(argc_bound);
for(var i = 0; i < argc_bound; i++) {