| OLD | NEW | 
|---|
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. | 
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be | 
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. | 
| 4 | 4 | 
| 5 #include <stdlib.h> | 5 #include <stdlib.h> | 
| 6 #include <limits> | 6 #include <limits> | 
| 7 | 7 | 
| 8 #include "src/v8.h" | 8 #include "src/v8.h" | 
| 9 | 9 | 
| 10 #include "src/accessors.h" | 10 #include "src/accessors.h" | 
| (...skipping 8173 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 8184     } | 8184     } | 
| 8185     return param_data; | 8185     return param_data; | 
| 8186   } | 8186   } | 
| 8187 } | 8187 } | 
| 8188 | 8188 | 
| 8189 | 8189 | 
| 8190 RUNTIME_FUNCTION(Runtime_FunctionBindArguments) { | 8190 RUNTIME_FUNCTION(Runtime_FunctionBindArguments) { | 
| 8191   HandleScope scope(isolate); | 8191   HandleScope scope(isolate); | 
| 8192   ASSERT(args.length() == 4); | 8192   ASSERT(args.length() == 4); | 
| 8193   CONVERT_ARG_HANDLE_CHECKED(JSFunction, bound_function, 0); | 8193   CONVERT_ARG_HANDLE_CHECKED(JSFunction, bound_function, 0); | 
| 8194   RUNTIME_ASSERT(args[3]->IsNumber()); | 8194   CONVERT_ARG_HANDLE_CHECKED(Object, bindee, 1); | 
| 8195   Handle<Object> bindee = args.at<Object>(1); | 8195   CONVERT_ARG_HANDLE_CHECKED(Object, this_object, 2); | 
|  | 8196   CONVERT_NUMBER_ARG_HANDLE_CHECKED(new_length, 3); | 
| 8196 | 8197 | 
| 8197   // TODO(lrn): Create bound function in C++ code from premade shared info. | 8198   // TODO(lrn): Create bound function in C++ code from premade shared info. | 
| 8198   bound_function->shared()->set_bound(true); | 8199   bound_function->shared()->set_bound(true); | 
| 8199   // Get all arguments of calling function (Function.prototype.bind). | 8200   // Get all arguments of calling function (Function.prototype.bind). | 
| 8200   int argc = 0; | 8201   int argc = 0; | 
| 8201   SmartArrayPointer<Handle<Object> > arguments = | 8202   SmartArrayPointer<Handle<Object> > arguments = | 
| 8202       GetCallerArguments(isolate, 0, &argc); | 8203       GetCallerArguments(isolate, 0, &argc); | 
| 8203   // Don't count the this-arg. | 8204   // Don't count the this-arg. | 
| 8204   if (argc > 0) { | 8205   if (argc > 0) { | 
| 8205     RUNTIME_ASSERT(*arguments[0] == args[2]); | 8206     RUNTIME_ASSERT(arguments[0].is_identical_to(this_object)); | 
| 8206     argc--; | 8207     argc--; | 
| 8207   } else { | 8208   } else { | 
| 8208     RUNTIME_ASSERT(args[2]->IsUndefined()); | 8209     RUNTIME_ASSERT(this_object->IsUndefined()); | 
| 8209   } | 8210   } | 
| 8210   // Initialize array of bindings (function, this, and any existing arguments | 8211   // Initialize array of bindings (function, this, and any existing arguments | 
| 8211   // if the function was already bound). | 8212   // if the function was already bound). | 
| 8212   Handle<FixedArray> new_bindings; | 8213   Handle<FixedArray> new_bindings; | 
| 8213   int i; | 8214   int i; | 
| 8214   if (bindee->IsJSFunction() && JSFunction::cast(*bindee)->shared()->bound()) { | 8215   if (bindee->IsJSFunction() && JSFunction::cast(*bindee)->shared()->bound()) { | 
| 8215     Handle<FixedArray> old_bindings( | 8216     Handle<FixedArray> old_bindings( | 
| 8216         JSFunction::cast(*bindee)->function_bindings()); | 8217         JSFunction::cast(*bindee)->function_bindings()); | 
| 8217     RUNTIME_ASSERT(old_bindings->length() > JSFunction::kBoundFunctionIndex); | 8218     RUNTIME_ASSERT(old_bindings->length() > JSFunction::kBoundFunctionIndex); | 
| 8218     new_bindings = | 8219     new_bindings = | 
| 8219         isolate->factory()->NewFixedArray(old_bindings->length() + argc); | 8220         isolate->factory()->NewFixedArray(old_bindings->length() + argc); | 
| 8220     bindee = Handle<Object>(old_bindings->get(JSFunction::kBoundFunctionIndex), | 8221     bindee = Handle<Object>(old_bindings->get(JSFunction::kBoundFunctionIndex), | 
| 8221                             isolate); | 8222                             isolate); | 
| 8222     i = 0; | 8223     i = 0; | 
| 8223     for (int n = old_bindings->length(); i < n; i++) { | 8224     for (int n = old_bindings->length(); i < n; i++) { | 
| 8224       new_bindings->set(i, old_bindings->get(i)); | 8225       new_bindings->set(i, old_bindings->get(i)); | 
| 8225     } | 8226     } | 
| 8226   } else { | 8227   } else { | 
| 8227     int array_size = JSFunction::kBoundArgumentsStartIndex + argc; | 8228     int array_size = JSFunction::kBoundArgumentsStartIndex + argc; | 
| 8228     new_bindings = isolate->factory()->NewFixedArray(array_size); | 8229     new_bindings = isolate->factory()->NewFixedArray(array_size); | 
| 8229     new_bindings->set(JSFunction::kBoundFunctionIndex, *bindee); | 8230     new_bindings->set(JSFunction::kBoundFunctionIndex, *bindee); | 
| 8230     new_bindings->set(JSFunction::kBoundThisIndex, args[2]); | 8231     new_bindings->set(JSFunction::kBoundThisIndex, *this_object); | 
| 8231     i = 2; | 8232     i = 2; | 
| 8232   } | 8233   } | 
| 8233   // Copy arguments, skipping the first which is "this_arg". | 8234   // Copy arguments, skipping the first which is "this_arg". | 
| 8234   for (int j = 0; j < argc; j++, i++) { | 8235   for (int j = 0; j < argc; j++, i++) { | 
| 8235     new_bindings->set(i, *arguments[j + 1]); | 8236     new_bindings->set(i, *arguments[j + 1]); | 
| 8236   } | 8237   } | 
| 8237   new_bindings->set_map_no_write_barrier( | 8238   new_bindings->set_map_no_write_barrier( | 
| 8238       isolate->heap()->fixed_cow_array_map()); | 8239       isolate->heap()->fixed_cow_array_map()); | 
| 8239   bound_function->set_function_bindings(*new_bindings); | 8240   bound_function->set_function_bindings(*new_bindings); | 
| 8240 | 8241 | 
| 8241   // Update length. | 8242   // Update length. Have to remove the prototype first so that map migration | 
|  | 8243   // is happy about the number of fields. | 
|  | 8244   RUNTIME_ASSERT(bound_function->RemovePrototype()); | 
|  | 8245   Handle<Map> bound_function_map( | 
|  | 8246       isolate->native_context()->bound_function_map()); | 
|  | 8247   JSObject::MigrateToMap(bound_function, bound_function_map); | 
| 8242   Handle<String> length_string = isolate->factory()->length_string(); | 8248   Handle<String> length_string = isolate->factory()->length_string(); | 
| 8243   Handle<Object> new_length(args.at<Object>(3)); |  | 
| 8244   PropertyAttributes attr = | 8249   PropertyAttributes attr = | 
| 8245       static_cast<PropertyAttributes>(DONT_DELETE | DONT_ENUM | READ_ONLY); | 8250       static_cast<PropertyAttributes>(DONT_DELETE | DONT_ENUM | READ_ONLY); | 
| 8246   Runtime::ForceSetObjectProperty( | 8251   JSObject::SetOwnPropertyIgnoreAttributes(bound_function, length_string, | 
| 8247       bound_function, length_string, new_length, attr).Assert(); | 8252                                            new_length, attr); | 
| 8248   return *bound_function; | 8253   return *bound_function; | 
| 8249 } | 8254 } | 
| 8250 | 8255 | 
| 8251 | 8256 | 
| 8252 RUNTIME_FUNCTION(Runtime_BoundFunctionGetBindings) { | 8257 RUNTIME_FUNCTION(Runtime_BoundFunctionGetBindings) { | 
| 8253   HandleScope handles(isolate); | 8258   HandleScope handles(isolate); | 
| 8254   ASSERT(args.length() == 1); | 8259   ASSERT(args.length() == 1); | 
| 8255   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, callable, 0); | 8260   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, callable, 0); | 
| 8256   if (callable->IsJSFunction()) { | 8261   if (callable->IsJSFunction()) { | 
| 8257     Handle<JSFunction> function = Handle<JSFunction>::cast(callable); | 8262     Handle<JSFunction> function = Handle<JSFunction>::cast(callable); | 
| (...skipping 6944 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 15202   } | 15207   } | 
| 15203   return NULL; | 15208   return NULL; | 
| 15204 } | 15209 } | 
| 15205 | 15210 | 
| 15206 | 15211 | 
| 15207 const Runtime::Function* Runtime::FunctionForId(Runtime::FunctionId id) { | 15212 const Runtime::Function* Runtime::FunctionForId(Runtime::FunctionId id) { | 
| 15208   return &(kIntrinsicFunctions[static_cast<int>(id)]); | 15213   return &(kIntrinsicFunctions[static_cast<int>(id)]); | 
| 15209 } | 15214 } | 
| 15210 | 15215 | 
| 15211 } }  // namespace v8::internal | 15216 } }  // namespace v8::internal | 
| OLD | NEW | 
|---|