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

Side by Side Diff: src/runtime/runtime-function.cc

Issue 1552473002: Revert of [runtime] Introduce dedicated JSBoundFunction to represent bound functions. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@FunctionConstructor
Patch Set: Created 4 years, 11 months 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 unified diff | Download patch
« no previous file with comments | « src/runtime/runtime-debug.cc ('k') | src/runtime/runtime-object.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 the V8 project authors. All rights reserved. 1 // Copyright 2014 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 "src/runtime/runtime-utils.h" 5 #include "src/runtime/runtime-utils.h"
6 6
7 #include "src/accessors.h" 7 #include "src/accessors.h"
8 #include "src/arguments.h" 8 #include "src/arguments.h"
9 #include "src/compiler.h" 9 #include "src/compiler.h"
10 #include "src/deoptimizer.h" 10 #include "src/deoptimizer.h"
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
46 RUNTIME_ASSERT(f->RemovePrototype()); 46 RUNTIME_ASSERT(f->RemovePrototype());
47 f->shared()->set_construct_stub( 47 f->shared()->set_construct_stub(
48 *isolate->builtins()->ConstructedNonConstructable()); 48 *isolate->builtins()->ConstructedNonConstructable());
49 49
50 return isolate->heap()->undefined_value(); 50 return isolate->heap()->undefined_value();
51 } 51 }
52 52
53 53
54 RUNTIME_FUNCTION(Runtime_FunctionGetScript) { 54 RUNTIME_FUNCTION(Runtime_FunctionGetScript) {
55 HandleScope scope(isolate); 55 HandleScope scope(isolate);
56 DCHECK_EQ(1, args.length()); 56 DCHECK(args.length() == 1);
57 CONVERT_ARG_HANDLE_CHECKED(JSReceiver, function, 0);
58 57
59 if (function->IsJSBoundFunction()) return isolate->heap()->undefined_value(); 58 CONVERT_ARG_CHECKED(JSFunction, fun, 0);
60 Handle<Object> script(Handle<JSFunction>::cast(function)->shared()->script(), 59 Handle<Object> script = Handle<Object>(fun->shared()->script(), isolate);
61 isolate);
62 if (!script->IsScript()) return isolate->heap()->undefined_value(); 60 if (!script->IsScript()) return isolate->heap()->undefined_value();
61
63 return *Script::GetWrapper(Handle<Script>::cast(script)); 62 return *Script::GetWrapper(Handle<Script>::cast(script));
64 } 63 }
65 64
66 65
67 RUNTIME_FUNCTION(Runtime_FunctionGetSourceCode) { 66 RUNTIME_FUNCTION(Runtime_FunctionGetSourceCode) {
68 HandleScope scope(isolate); 67 HandleScope scope(isolate);
69 DCHECK_EQ(1, args.length()); 68 DCHECK(args.length() == 1);
70 CONVERT_ARG_HANDLE_CHECKED(JSReceiver, function, 0); 69
71 if (function->IsJSBoundFunction()) return isolate->heap()->undefined_value(); 70 CONVERT_ARG_HANDLE_CHECKED(JSFunction, f, 0);
72 return *Handle<JSFunction>::cast(function)->shared()->GetSourceCode(); 71 Handle<SharedFunctionInfo> shared(f->shared());
72 return *shared->GetSourceCode();
73 } 73 }
74 74
75 75
76 RUNTIME_FUNCTION(Runtime_FunctionGetScriptSourcePosition) { 76 RUNTIME_FUNCTION(Runtime_FunctionGetScriptSourcePosition) {
77 SealHandleScope shs(isolate); 77 SealHandleScope shs(isolate);
78 DCHECK(args.length() == 1); 78 DCHECK(args.length() == 1);
79 79
80 CONVERT_ARG_CHECKED(JSFunction, fun, 0); 80 CONVERT_ARG_CHECKED(JSFunction, fun, 0);
81 int pos = fun->shared()->start_position(); 81 int pos = fun->shared()->start_position();
82 return Smi::FromInt(pos); 82 return Smi::FromInt(pos);
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
145 145
146 RUNTIME_FUNCTION(Runtime_SetCode) { 146 RUNTIME_FUNCTION(Runtime_SetCode) {
147 HandleScope scope(isolate); 147 HandleScope scope(isolate);
148 DCHECK(args.length() == 2); 148 DCHECK(args.length() == 2);
149 149
150 CONVERT_ARG_HANDLE_CHECKED(JSFunction, target, 0); 150 CONVERT_ARG_HANDLE_CHECKED(JSFunction, target, 0);
151 CONVERT_ARG_HANDLE_CHECKED(JSFunction, source, 1); 151 CONVERT_ARG_HANDLE_CHECKED(JSFunction, source, 1);
152 152
153 Handle<SharedFunctionInfo> target_shared(target->shared()); 153 Handle<SharedFunctionInfo> target_shared(target->shared());
154 Handle<SharedFunctionInfo> source_shared(source->shared()); 154 Handle<SharedFunctionInfo> source_shared(source->shared());
155 RUNTIME_ASSERT(!source_shared->bound());
155 156
156 if (!Compiler::Compile(source, KEEP_EXCEPTION)) { 157 if (!Compiler::Compile(source, KEEP_EXCEPTION)) {
157 return isolate->heap()->exception(); 158 return isolate->heap()->exception();
158 } 159 }
159 160
160 // Mark both, the source and the target, as un-flushable because the 161 // Mark both, the source and the target, as un-flushable because the
161 // shared unoptimized code makes them impossible to enqueue in a list. 162 // shared unoptimized code makes them impossible to enqueue in a list.
162 DCHECK(target_shared->code()->gc_metadata() == NULL); 163 DCHECK(target_shared->code()->gc_metadata() == NULL);
163 DCHECK(source_shared->code()->gc_metadata() == NULL); 164 DCHECK(source_shared->code()->gc_metadata() == NULL);
164 target_shared->set_dont_flush(true); 165 target_shared->set_dont_flush(true);
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
301 NewArray<Handle<Object> >(*total_argc)); 302 NewArray<Handle<Object> >(*total_argc));
302 for (int i = 0; i < args_count; i++) { 303 for (int i = 0; i < args_count; i++) {
303 Handle<Object> val = Handle<Object>(frame->GetParameter(i), isolate); 304 Handle<Object> val = Handle<Object>(frame->GetParameter(i), isolate);
304 param_data[prefix_argc + i] = val; 305 param_data[prefix_argc + i] = val;
305 } 306 }
306 return param_data; 307 return param_data;
307 } 308 }
308 } 309 }
309 310
310 311
312 RUNTIME_FUNCTION(Runtime_FunctionBindArguments) {
313 HandleScope scope(isolate);
314 DCHECK(args.length() == 5);
315 CONVERT_ARG_HANDLE_CHECKED(JSFunction, bound_function, 0);
316 CONVERT_ARG_HANDLE_CHECKED(JSReceiver, bindee, 1);
317 CONVERT_ARG_HANDLE_CHECKED(Object, this_object, 2);
318 CONVERT_NUMBER_ARG_HANDLE_CHECKED(new_length, 3);
319 CONVERT_ARG_HANDLE_CHECKED(Object, proto, 4);
320
321 // TODO(lrn): Create bound function in C++ code from premade shared info.
322 bound_function->shared()->set_bound(true);
323 bound_function->shared()->set_optimized_code_map(
324 isolate->heap()->cleared_optimized_code_map());
325 bound_function->shared()->set_inferred_name(isolate->heap()->empty_string());
326 bound_function->shared()->set_construct_stub(
327 *isolate->builtins()->JSBuiltinsConstructStub());
328 // Get all arguments of calling function (Function.prototype.bind).
329 int argc = 0;
330 base::SmartArrayPointer<Handle<Object>> arguments =
331 Runtime::GetCallerArguments(isolate, 0, &argc);
332 // Don't count the this-arg.
333 if (argc > 0) {
334 RUNTIME_ASSERT(arguments[0].is_identical_to(this_object));
335 argc--;
336 } else {
337 RUNTIME_ASSERT(this_object->IsUndefined());
338 }
339 // Initialize array of bindings (function, this, and any existing arguments
340 // if the function was already bound).
341 Handle<BindingsArray> new_bindings;
342 int out_index = 0;
343 Handle<TypeFeedbackVector> vector(
344 bound_function->shared()->feedback_vector());
345 if (bindee->IsJSFunction() && JSFunction::cast(*bindee)->shared()->bound()) {
346 Handle<BindingsArray> old_bindings(
347 JSFunction::cast(*bindee)->function_bindings());
348 RUNTIME_ASSERT(old_bindings->bindings_count() >= 0);
349 bindee = handle(old_bindings->bound_function(), isolate);
350 Handle<Object> old_bound_this(old_bindings->bound_this(), isolate);
351 new_bindings = BindingsArray::New(isolate, vector, bindee, old_bound_this,
352 old_bindings->bindings_count() + argc);
353 for (int n = old_bindings->bindings_count(); out_index < n; out_index++) {
354 new_bindings->set_binding(out_index, old_bindings->binding(out_index));
355 }
356 } else {
357 new_bindings =
358 BindingsArray::New(isolate, vector, bindee, this_object, argc);
359 }
360 // Copy arguments, skipping the first which is "this_arg".
361 for (int j = 0; j < argc; j++, out_index++) {
362 new_bindings->set_binding(out_index, *arguments[j + 1]);
363 }
364 new_bindings->set_map_no_write_barrier(isolate->heap()->fixed_array_map());
365 bound_function->set_function_bindings(*new_bindings);
366
367 // Update length. Have to remove the prototype first so that map migration
368 // is happy about the number of fields.
369 RUNTIME_ASSERT(bound_function->RemovePrototype());
370
371 // The new function should have the given prototype.
372 Handle<Map> bound_function_map =
373 bindee->IsConstructor()
374 ? isolate->bound_function_with_constructor_map()
375 : isolate->bound_function_without_constructor_map();
376 if (bound_function_map->prototype() != *proto) {
377 bound_function_map = Map::TransitionToPrototype(bound_function_map, proto,
378 REGULAR_PROTOTYPE);
379 }
380 JSObject::MigrateToMap(bound_function, bound_function_map);
381 DCHECK_EQ(bindee->IsConstructor(), bound_function->IsConstructor());
382
383 Handle<String> length_string = isolate->factory()->length_string();
384 // These attributes must be kept in sync with how the bootstrapper
385 // configures the bound_function_map retrieved above.
386 // We use ...IgnoreAttributes() here because of length's read-onliness.
387 PropertyAttributes attr =
388 static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY);
389 RETURN_FAILURE_ON_EXCEPTION(
390 isolate, JSObject::SetOwnPropertyIgnoreAttributes(
391 bound_function, length_string, new_length, attr));
392 return *bound_function;
393 }
394
395
396 RUNTIME_FUNCTION(Runtime_BoundFunctionGetBindings) {
397 HandleScope handles(isolate);
398 DCHECK(args.length() == 1);
399 CONVERT_ARG_HANDLE_CHECKED(JSReceiver, callable, 0);
400 if (callable->IsJSFunction()) {
401 Handle<JSFunction> function = Handle<JSFunction>::cast(callable);
402 if (function->shared()->bound()) {
403 RUNTIME_ASSERT(function->function_bindings()->IsBindingsArray());
404 Handle<BindingsArray> bindings(function->function_bindings());
405 return *BindingsArray::CreateRuntimeBindings(bindings);
406 }
407 }
408 return isolate->heap()->undefined_value();
409 }
410
411
412 RUNTIME_FUNCTION(Runtime_NewObjectFromBound) {
413 HandleScope scope(isolate);
414 DCHECK(args.length() == 1);
415 // First argument is a function to use as a constructor.
416 CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
417 RUNTIME_ASSERT(function->shared()->bound());
418
419 // The argument is a bound function. Extract its bound arguments
420 // and callable.
421 Handle<BindingsArray> bound_args =
422 handle(BindingsArray::cast(function->function_bindings()));
423 int bound_argc = bound_args->bindings_count();
424 Handle<Object> bound_function(bound_args->bound_function(), isolate);
425 DCHECK(!bound_function->IsJSFunction() ||
426 !Handle<JSFunction>::cast(bound_function)->shared()->bound());
427
428 int total_argc = 0;
429 base::SmartArrayPointer<Handle<Object>> param_data =
430 Runtime::GetCallerArguments(isolate, bound_argc, &total_argc);
431 for (int i = 0; i < bound_argc; i++) {
432 param_data[i] = handle(bound_args->binding(i), isolate);
433 }
434
435 Handle<Object> result;
436 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
437 isolate, result, Execution::New(isolate, bound_function, bound_function,
438 total_argc, param_data.get()));
439 return *result;
440 }
441
442
311 RUNTIME_FUNCTION(Runtime_Call) { 443 RUNTIME_FUNCTION(Runtime_Call) {
312 HandleScope scope(isolate); 444 HandleScope scope(isolate);
313 DCHECK_LE(2, args.length()); 445 DCHECK_LE(2, args.length());
314 int const argc = args.length() - 2; 446 int const argc = args.length() - 2;
315 CONVERT_ARG_HANDLE_CHECKED(JSReceiver, target, 0); 447 CONVERT_ARG_HANDLE_CHECKED(JSReceiver, target, 0);
316 CONVERT_ARG_HANDLE_CHECKED(Object, receiver, 1); 448 CONVERT_ARG_HANDLE_CHECKED(Object, receiver, 1);
317 ScopedVector<Handle<Object>> argv(argc); 449 ScopedVector<Handle<Object>> argv(argc);
318 for (int i = 0; i < argc; ++i) { 450 for (int i = 0; i < argc; ++i) {
319 argv[i] = args.at<Object>(2 + i); 451 argv[i] = args.at<Object>(2 + i);
320 } 452 }
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
388 CONVERT_ARG_HANDLE_CHECKED(Object, receiver, 0); 520 CONVERT_ARG_HANDLE_CHECKED(Object, receiver, 0);
389 if (receiver->IsNull() || receiver->IsUndefined()) { 521 if (receiver->IsNull() || receiver->IsUndefined()) {
390 return isolate->global_proxy(); 522 return isolate->global_proxy();
391 } 523 }
392 return *Object::ToObject(isolate, receiver).ToHandleChecked(); 524 return *Object::ToObject(isolate, receiver).ToHandleChecked();
393 } 525 }
394 526
395 527
396 RUNTIME_FUNCTION(Runtime_IsFunction) { 528 RUNTIME_FUNCTION(Runtime_IsFunction) {
397 SealHandleScope shs(isolate); 529 SealHandleScope shs(isolate);
398 DCHECK_EQ(1, args.length()); 530 DCHECK(args.length() == 1);
399 CONVERT_ARG_CHECKED(Object, object, 0); 531 CONVERT_ARG_CHECKED(Object, obj, 0);
400 return isolate->heap()->ToBoolean(object->IsFunction()); 532 return isolate->heap()->ToBoolean(obj->IsJSFunction());
401 } 533 }
402 534
403 535
404 RUNTIME_FUNCTION(Runtime_ThrowStrongModeTooFewArguments) { 536 RUNTIME_FUNCTION(Runtime_ThrowStrongModeTooFewArguments) {
405 HandleScope scope(isolate); 537 HandleScope scope(isolate);
406 DCHECK(args.length() == 0); 538 DCHECK(args.length() == 0);
407 THROW_NEW_ERROR_RETURN_FAILURE(isolate, 539 THROW_NEW_ERROR_RETURN_FAILURE(isolate,
408 NewTypeError(MessageTemplate::kStrongArity)); 540 NewTypeError(MessageTemplate::kStrongArity));
409 } 541 }
410 542
411 543
412 RUNTIME_FUNCTION(Runtime_FunctionToString) { 544 RUNTIME_FUNCTION(Runtime_FunctionToString) {
413 HandleScope scope(isolate); 545 HandleScope scope(isolate);
414 DCHECK_EQ(1, args.length()); 546 DCHECK_EQ(1, args.length());
415 CONVERT_ARG_HANDLE_CHECKED(JSReceiver, function, 0); 547 CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
416 return function->IsJSBoundFunction() 548 return *JSFunction::ToString(function);
417 ? *JSBoundFunction::ToString(
418 Handle<JSBoundFunction>::cast(function))
419 : *JSFunction::ToString(Handle<JSFunction>::cast(function));
420 } 549 }
421 550
422 } // namespace internal 551 } // namespace internal
423 } // namespace v8 552 } // namespace v8
OLDNEW
« 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