Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(124)

Unified Diff: src/runtime/runtime-function.cc

Issue 1542963002: [runtime] Introduce dedicated JSBoundFunction to represent bound functions. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@FunctionConstructor
Patch Set: [arm64] Poke does not preserve flags with --debug-code. Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/runtime/runtime-debug.cc ('k') | src/runtime/runtime-object.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/runtime/runtime-function.cc
diff --git a/src/runtime/runtime-function.cc b/src/runtime/runtime-function.cc
index 9ec4cda81a11f4f2cfab49c28d7a8804599d75ea..24ed128f670a039c635e4b39a7277d5e50a33ca5 100644
--- a/src/runtime/runtime-function.cc
+++ b/src/runtime/runtime-function.cc
@@ -53,23 +53,23 @@ RUNTIME_FUNCTION(Runtime_FunctionRemovePrototype) {
RUNTIME_FUNCTION(Runtime_FunctionGetScript) {
HandleScope scope(isolate);
- DCHECK(args.length() == 1);
+ DCHECK_EQ(1, args.length());
+ CONVERT_ARG_HANDLE_CHECKED(JSReceiver, function, 0);
- CONVERT_ARG_CHECKED(JSFunction, fun, 0);
- Handle<Object> script = Handle<Object>(fun->shared()->script(), isolate);
+ if (function->IsJSBoundFunction()) return isolate->heap()->undefined_value();
+ Handle<Object> script(Handle<JSFunction>::cast(function)->shared()->script(),
+ isolate);
if (!script->IsScript()) return isolate->heap()->undefined_value();
-
return *Script::GetWrapper(Handle<Script>::cast(script));
}
RUNTIME_FUNCTION(Runtime_FunctionGetSourceCode) {
HandleScope scope(isolate);
- DCHECK(args.length() == 1);
-
- CONVERT_ARG_HANDLE_CHECKED(JSFunction, f, 0);
- Handle<SharedFunctionInfo> shared(f->shared());
- return *shared->GetSourceCode();
+ DCHECK_EQ(1, args.length());
+ CONVERT_ARG_HANDLE_CHECKED(JSReceiver, function, 0);
+ if (function->IsJSBoundFunction()) return isolate->heap()->undefined_value();
+ return *Handle<JSFunction>::cast(function)->shared()->GetSourceCode();
}
@@ -152,7 +152,6 @@ RUNTIME_FUNCTION(Runtime_SetCode) {
Handle<SharedFunctionInfo> target_shared(target->shared());
Handle<SharedFunctionInfo> source_shared(source->shared());
- RUNTIME_ASSERT(!source_shared->bound());
if (!Compiler::Compile(source, KEEP_EXCEPTION)) {
return isolate->heap()->exception();
@@ -309,137 +308,6 @@ base::SmartArrayPointer<Handle<Object>> Runtime::GetCallerArguments(
}
-RUNTIME_FUNCTION(Runtime_FunctionBindArguments) {
- HandleScope scope(isolate);
- DCHECK(args.length() == 5);
- CONVERT_ARG_HANDLE_CHECKED(JSFunction, bound_function, 0);
- CONVERT_ARG_HANDLE_CHECKED(JSReceiver, bindee, 1);
- CONVERT_ARG_HANDLE_CHECKED(Object, this_object, 2);
- CONVERT_NUMBER_ARG_HANDLE_CHECKED(new_length, 3);
- CONVERT_ARG_HANDLE_CHECKED(Object, proto, 4);
-
- // TODO(lrn): Create bound function in C++ code from premade shared info.
- bound_function->shared()->set_bound(true);
- bound_function->shared()->set_optimized_code_map(
- isolate->heap()->cleared_optimized_code_map());
- bound_function->shared()->set_inferred_name(isolate->heap()->empty_string());
- bound_function->shared()->set_construct_stub(
- *isolate->builtins()->JSBuiltinsConstructStub());
- // Get all arguments of calling function (Function.prototype.bind).
- int argc = 0;
- base::SmartArrayPointer<Handle<Object>> arguments =
- Runtime::GetCallerArguments(isolate, 0, &argc);
- // Don't count the this-arg.
- if (argc > 0) {
- RUNTIME_ASSERT(arguments[0].is_identical_to(this_object));
- argc--;
- } else {
- RUNTIME_ASSERT(this_object->IsUndefined());
- }
- // Initialize array of bindings (function, this, and any existing arguments
- // if the function was already bound).
- Handle<BindingsArray> new_bindings;
- int out_index = 0;
- Handle<TypeFeedbackVector> vector(
- bound_function->shared()->feedback_vector());
- if (bindee->IsJSFunction() && JSFunction::cast(*bindee)->shared()->bound()) {
- Handle<BindingsArray> old_bindings(
- JSFunction::cast(*bindee)->function_bindings());
- RUNTIME_ASSERT(old_bindings->bindings_count() >= 0);
- bindee = handle(old_bindings->bound_function(), isolate);
- Handle<Object> old_bound_this(old_bindings->bound_this(), isolate);
- new_bindings = BindingsArray::New(isolate, vector, bindee, old_bound_this,
- old_bindings->bindings_count() + argc);
- for (int n = old_bindings->bindings_count(); out_index < n; out_index++) {
- new_bindings->set_binding(out_index, old_bindings->binding(out_index));
- }
- } else {
- new_bindings =
- BindingsArray::New(isolate, vector, bindee, this_object, argc);
- }
- // Copy arguments, skipping the first which is "this_arg".
- for (int j = 0; j < argc; j++, out_index++) {
- new_bindings->set_binding(out_index, *arguments[j + 1]);
- }
- new_bindings->set_map_no_write_barrier(isolate->heap()->fixed_array_map());
- bound_function->set_function_bindings(*new_bindings);
-
- // Update length. Have to remove the prototype first so that map migration
- // is happy about the number of fields.
- RUNTIME_ASSERT(bound_function->RemovePrototype());
-
- // The new function should have the given prototype.
- Handle<Map> bound_function_map =
- bindee->IsConstructor()
- ? isolate->bound_function_with_constructor_map()
- : isolate->bound_function_without_constructor_map();
- if (bound_function_map->prototype() != *proto) {
- bound_function_map = Map::TransitionToPrototype(bound_function_map, proto,
- REGULAR_PROTOTYPE);
- }
- JSObject::MigrateToMap(bound_function, bound_function_map);
- DCHECK_EQ(bindee->IsConstructor(), bound_function->IsConstructor());
-
- Handle<String> length_string = isolate->factory()->length_string();
- // These attributes must be kept in sync with how the bootstrapper
- // configures the bound_function_map retrieved above.
- // We use ...IgnoreAttributes() here because of length's read-onliness.
- PropertyAttributes attr =
- static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY);
- RETURN_FAILURE_ON_EXCEPTION(
- isolate, JSObject::SetOwnPropertyIgnoreAttributes(
- bound_function, length_string, new_length, attr));
- return *bound_function;
-}
-
-
-RUNTIME_FUNCTION(Runtime_BoundFunctionGetBindings) {
- HandleScope handles(isolate);
- DCHECK(args.length() == 1);
- CONVERT_ARG_HANDLE_CHECKED(JSReceiver, callable, 0);
- if (callable->IsJSFunction()) {
- Handle<JSFunction> function = Handle<JSFunction>::cast(callable);
- if (function->shared()->bound()) {
- RUNTIME_ASSERT(function->function_bindings()->IsBindingsArray());
- Handle<BindingsArray> bindings(function->function_bindings());
- return *BindingsArray::CreateRuntimeBindings(bindings);
- }
- }
- return isolate->heap()->undefined_value();
-}
-
-
-RUNTIME_FUNCTION(Runtime_NewObjectFromBound) {
- HandleScope scope(isolate);
- DCHECK(args.length() == 1);
- // First argument is a function to use as a constructor.
- CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
- RUNTIME_ASSERT(function->shared()->bound());
-
- // The argument is a bound function. Extract its bound arguments
- // and callable.
- Handle<BindingsArray> bound_args =
- handle(BindingsArray::cast(function->function_bindings()));
- int bound_argc = bound_args->bindings_count();
- Handle<Object> bound_function(bound_args->bound_function(), isolate);
- DCHECK(!bound_function->IsJSFunction() ||
- !Handle<JSFunction>::cast(bound_function)->shared()->bound());
-
- int total_argc = 0;
- base::SmartArrayPointer<Handle<Object>> param_data =
- Runtime::GetCallerArguments(isolate, bound_argc, &total_argc);
- for (int i = 0; i < bound_argc; i++) {
- param_data[i] = handle(bound_args->binding(i), isolate);
- }
-
- Handle<Object> result;
- ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
- isolate, result, Execution::New(isolate, bound_function, bound_function,
- total_argc, param_data.get()));
- return *result;
-}
-
-
RUNTIME_FUNCTION(Runtime_Call) {
HandleScope scope(isolate);
DCHECK_LE(2, args.length());
@@ -527,9 +395,9 @@ RUNTIME_FUNCTION(Runtime_ConvertReceiver) {
RUNTIME_FUNCTION(Runtime_IsFunction) {
SealHandleScope shs(isolate);
- DCHECK(args.length() == 1);
- CONVERT_ARG_CHECKED(Object, obj, 0);
- return isolate->heap()->ToBoolean(obj->IsJSFunction());
+ DCHECK_EQ(1, args.length());
+ CONVERT_ARG_CHECKED(Object, object, 0);
+ return isolate->heap()->ToBoolean(object->IsFunction());
}
@@ -544,8 +412,11 @@ RUNTIME_FUNCTION(Runtime_ThrowStrongModeTooFewArguments) {
RUNTIME_FUNCTION(Runtime_FunctionToString) {
HandleScope scope(isolate);
DCHECK_EQ(1, args.length());
- CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
- return *JSFunction::ToString(function);
+ CONVERT_ARG_HANDLE_CHECKED(JSReceiver, function, 0);
+ return function->IsJSBoundFunction()
+ ? *JSBoundFunction::ToString(
+ Handle<JSBoundFunction>::cast(function))
+ : *JSFunction::ToString(Handle<JSFunction>::cast(function));
}
} // namespace internal
« no previous file with comments | « src/runtime/runtime-debug.cc ('k') | src/runtime/runtime-object.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698