| 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 "src/builtins.h" | 5 #include "src/builtins.h" |
| 6 | 6 |
| 7 #include "src/api-arguments.h" | 7 #include "src/api-arguments.h" |
| 8 #include "src/api-natives.h" | 8 #include "src/api-natives.h" |
| 9 #include "src/api.h" | 9 #include "src/api.h" |
| 10 #include "src/base/ieee754.h" | 10 #include "src/base/ieee754.h" |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 57 if (index >= length()) { | 57 if (index >= length()) { |
| 58 return isolate->factory()->undefined_value(); | 58 return isolate->factory()->undefined_value(); |
| 59 } | 59 } |
| 60 return at<Object>(index); | 60 return at<Object>(index); |
| 61 } | 61 } |
| 62 | 62 |
| 63 Handle<Object> receiver() { | 63 Handle<Object> receiver() { |
| 64 return Arguments::at<Object>(0); | 64 return Arguments::at<Object>(0); |
| 65 } | 65 } |
| 66 | 66 |
| 67 static const int kNewTargetOffset = 0; |
| 68 static const int kTargetOffset = 1; |
| 69 static const int kArgcOffset = 2; |
| 70 static const int kNumExtraArgs = 3; |
| 71 static const int kNumExtraArgsWithReceiver = 4; |
| 72 |
| 67 template <class S> | 73 template <class S> |
| 68 Handle<S> target() { | 74 Handle<S> target() { |
| 69 return Arguments::at<S>(Arguments::length() - 2); | 75 return Arguments::at<S>(Arguments::length() - 1 - kTargetOffset); |
| 70 } | 76 } |
| 71 Handle<HeapObject> new_target() { | 77 Handle<HeapObject> new_target() { |
| 72 return Arguments::at<HeapObject>(Arguments::length() - 1); | 78 return Arguments::at<HeapObject>(Arguments::length() - 1 - |
| 79 kNewTargetOffset); |
| 73 } | 80 } |
| 74 | 81 |
| 75 // Gets the total number of arguments including the receiver (but | 82 // Gets the total number of arguments including the receiver (but |
| 76 // excluding extra arguments). | 83 // excluding extra arguments). |
| 77 int length() const { return Arguments::length() - 2; } | 84 int length() const { return Arguments::length() - kNumExtraArgs; } |
| 78 }; | 85 }; |
| 79 | 86 |
| 80 | 87 |
| 81 // ---------------------------------------------------------------------------- | 88 // ---------------------------------------------------------------------------- |
| 82 // Support macro for defining builtins in C++. | 89 // Support macro for defining builtins in C++. |
| 83 // ---------------------------------------------------------------------------- | 90 // ---------------------------------------------------------------------------- |
| 84 // | 91 // |
| 85 // A builtin function is defined by writing: | 92 // A builtin function is defined by writing: |
| 86 // | 93 // |
| 87 // BUILTIN(name) { | 94 // BUILTIN(name) { |
| (...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 416 } // namespace | 423 } // namespace |
| 417 | 424 |
| 418 BUILTIN(ArrayPush) { return DoArrayPush(isolate, args); } | 425 BUILTIN(ArrayPush) { return DoArrayPush(isolate, args); } |
| 419 | 426 |
| 420 // TODO(verwaest): This is a temporary helper until the FastArrayPush stub can | 427 // TODO(verwaest): This is a temporary helper until the FastArrayPush stub can |
| 421 // tailcall to the builtin directly. | 428 // tailcall to the builtin directly. |
| 422 RUNTIME_FUNCTION(Runtime_ArrayPush) { | 429 RUNTIME_FUNCTION(Runtime_ArrayPush) { |
| 423 DCHECK_EQ(2, args.length()); | 430 DCHECK_EQ(2, args.length()); |
| 424 Arguments* incoming = reinterpret_cast<Arguments*>(args[0]); | 431 Arguments* incoming = reinterpret_cast<Arguments*>(args[0]); |
| 425 // Rewrap the arguments as builtins arguments. | 432 // Rewrap the arguments as builtins arguments. |
| 426 BuiltinArguments caller_args(incoming->length() + 3, | 433 int argc = incoming->length() + BuiltinArguments::kNumExtraArgsWithReceiver; |
| 427 incoming->arguments() + 1); | 434 BuiltinArguments caller_args(argc, incoming->arguments() + 1); |
| 428 return DoArrayPush(isolate, caller_args); | 435 return DoArrayPush(isolate, caller_args); |
| 429 } | 436 } |
| 430 | 437 |
| 431 BUILTIN(ArrayPop) { | 438 BUILTIN(ArrayPop) { |
| 432 HandleScope scope(isolate); | 439 HandleScope scope(isolate); |
| 433 Handle<Object> receiver = args.receiver(); | 440 Handle<Object> receiver = args.receiver(); |
| 434 if (!EnsureJSArrayWithWritableFastElements(isolate, receiver, nullptr, 0)) { | 441 if (!EnsureJSArrayWithWritableFastElements(isolate, receiver, nullptr, 0)) { |
| 435 return CallJsIntrinsic(isolate, isolate->array_pop(), args); | 442 return CallJsIntrinsic(isolate, isolate->array_pop(), args); |
| 436 } | 443 } |
| 437 | 444 |
| (...skipping 4162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4600 | 4607 |
| 4601 // ES6 section 19.2.3.2 Function.prototype.bind ( thisArg, ...args ) | 4608 // ES6 section 19.2.3.2 Function.prototype.bind ( thisArg, ...args ) |
| 4602 BUILTIN(FunctionPrototypeBind) { return DoFunctionBind(isolate, args); } | 4609 BUILTIN(FunctionPrototypeBind) { return DoFunctionBind(isolate, args); } |
| 4603 | 4610 |
| 4604 // TODO(verwaest): This is a temporary helper until the FastFunctionBind stub | 4611 // TODO(verwaest): This is a temporary helper until the FastFunctionBind stub |
| 4605 // can tailcall to the builtin directly. | 4612 // can tailcall to the builtin directly. |
| 4606 RUNTIME_FUNCTION(Runtime_FunctionBind) { | 4613 RUNTIME_FUNCTION(Runtime_FunctionBind) { |
| 4607 DCHECK_EQ(2, args.length()); | 4614 DCHECK_EQ(2, args.length()); |
| 4608 Arguments* incoming = reinterpret_cast<Arguments*>(args[0]); | 4615 Arguments* incoming = reinterpret_cast<Arguments*>(args[0]); |
| 4609 // Rewrap the arguments as builtins arguments. | 4616 // Rewrap the arguments as builtins arguments. |
| 4610 BuiltinArguments caller_args(incoming->length() + 3, | 4617 int argc = incoming->length() + BuiltinArguments::kNumExtraArgsWithReceiver; |
| 4611 incoming->arguments() + 1); | 4618 BuiltinArguments caller_args(argc, incoming->arguments() + 1); |
| 4612 return DoFunctionBind(isolate, caller_args); | 4619 return DoFunctionBind(isolate, caller_args); |
| 4613 } | 4620 } |
| 4614 | 4621 |
| 4615 // ES6 section 19.2.3.5 Function.prototype.toString ( ) | 4622 // ES6 section 19.2.3.5 Function.prototype.toString ( ) |
| 4616 BUILTIN(FunctionPrototypeToString) { | 4623 BUILTIN(FunctionPrototypeToString) { |
| 4617 HandleScope scope(isolate); | 4624 HandleScope scope(isolate); |
| 4618 Handle<Object> receiver = args.receiver(); | 4625 Handle<Object> receiver = args.receiver(); |
| 4619 if (receiver->IsJSBoundFunction()) { | 4626 if (receiver->IsJSBoundFunction()) { |
| 4620 return *JSBoundFunction::ToString(Handle<JSBoundFunction>::cast(receiver)); | 4627 return *JSBoundFunction::ToString(Handle<JSBoundFunction>::cast(receiver)); |
| 4621 } else if (receiver->IsJSFunction()) { | 4628 } else if (receiver->IsJSFunction()) { |
| (...skipping 902 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5524 function->IsFunctionTemplateInfo() | 5531 function->IsFunctionTemplateInfo() |
| 5525 ? Handle<FunctionTemplateInfo>::cast(function) | 5532 ? Handle<FunctionTemplateInfo>::cast(function) |
| 5526 : handle(JSFunction::cast(*function)->shared()->get_api_func_data(), | 5533 : handle(JSFunction::cast(*function)->shared()->get_api_func_data(), |
| 5527 isolate); | 5534 isolate); |
| 5528 Handle<HeapObject> new_target = isolate->factory()->undefined_value(); | 5535 Handle<HeapObject> new_target = isolate->factory()->undefined_value(); |
| 5529 // Construct BuiltinArguments object: | 5536 // Construct BuiltinArguments object: |
| 5530 // new target, function, arguments reversed, receiver. | 5537 // new target, function, arguments reversed, receiver. |
| 5531 const int kBufferSize = 32; | 5538 const int kBufferSize = 32; |
| 5532 Object* small_argv[kBufferSize]; | 5539 Object* small_argv[kBufferSize]; |
| 5533 Object** argv; | 5540 Object** argv; |
| 5534 if (argc + 3 <= kBufferSize) { | 5541 const int frame_argc = argc + BuiltinArguments::kNumExtraArgsWithReceiver; |
| 5542 if (frame_argc <= kBufferSize) { |
| 5535 argv = small_argv; | 5543 argv = small_argv; |
| 5536 } else { | 5544 } else { |
| 5537 argv = new Object*[argc + 3]; | 5545 argv = new Object*[frame_argc]; |
| 5538 } | 5546 } |
| 5539 argv[argc + 2] = *receiver; | 5547 int cursor = frame_argc - 1; |
| 5548 argv[cursor--] = *receiver; |
| 5540 for (int i = 0; i < argc; ++i) { | 5549 for (int i = 0; i < argc; ++i) { |
| 5541 argv[argc - i + 1] = *args[i]; | 5550 argv[cursor--] = *args[i]; |
| 5542 } | 5551 } |
| 5543 argv[1] = *function; | 5552 DCHECK(cursor == BuiltinArguments::kArgcOffset); |
| 5544 argv[0] = *new_target; | 5553 argv[BuiltinArguments::kArgcOffset] = Smi::FromInt(frame_argc); |
| 5554 argv[BuiltinArguments::kTargetOffset] = *function; |
| 5555 argv[BuiltinArguments::kNewTargetOffset] = *new_target; |
| 5545 MaybeHandle<Object> result; | 5556 MaybeHandle<Object> result; |
| 5546 { | 5557 { |
| 5547 RelocatableArguments arguments(isolate, argc + 3, &argv[argc] + 2); | 5558 RelocatableArguments arguments(isolate, frame_argc, &argv[frame_argc - 1]); |
| 5548 result = HandleApiCallHelper<false>(isolate, function, new_target, fun_data, | 5559 result = HandleApiCallHelper<false>(isolate, function, new_target, fun_data, |
| 5549 receiver, arguments); | 5560 receiver, arguments); |
| 5550 } | 5561 } |
| 5551 if (argv != small_argv) delete[] argv; | 5562 if (argv != small_argv) delete[] argv; |
| 5552 return result; | 5563 return result; |
| 5553 } | 5564 } |
| 5554 | 5565 |
| 5555 | 5566 |
| 5556 // Helper function to handle calls to non-function objects created through the | 5567 // Helper function to handle calls to non-function objects created through the |
| 5557 // API. The object can be called as either a constructor (using new) or just as | 5568 // API. The object can be called as either a constructor (using new) or just as |
| (...skipping 745 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6303 BUILTIN_LIST_H(DEFINE_BUILTIN_ACCESSOR_H) | 6314 BUILTIN_LIST_H(DEFINE_BUILTIN_ACCESSOR_H) |
| 6304 BUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A) | 6315 BUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A) |
| 6305 #undef DEFINE_BUILTIN_ACCESSOR_C | 6316 #undef DEFINE_BUILTIN_ACCESSOR_C |
| 6306 #undef DEFINE_BUILTIN_ACCESSOR_A | 6317 #undef DEFINE_BUILTIN_ACCESSOR_A |
| 6307 #undef DEFINE_BUILTIN_ACCESSOR_T | 6318 #undef DEFINE_BUILTIN_ACCESSOR_T |
| 6308 #undef DEFINE_BUILTIN_ACCESSOR_S | 6319 #undef DEFINE_BUILTIN_ACCESSOR_S |
| 6309 #undef DEFINE_BUILTIN_ACCESSOR_H | 6320 #undef DEFINE_BUILTIN_ACCESSOR_H |
| 6310 | 6321 |
| 6311 } // namespace internal | 6322 } // namespace internal |
| 6312 } // namespace v8 | 6323 } // namespace v8 |
| OLD | NEW |