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