Chromium Code Reviews| 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 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 56 if (index >= length()) { | 56 if (index >= length()) { |
| 57 return isolate->factory()->undefined_value(); | 57 return isolate->factory()->undefined_value(); |
| 58 } | 58 } |
| 59 return at<Object>(index); | 59 return at<Object>(index); |
| 60 } | 60 } |
| 61 | 61 |
| 62 Handle<Object> receiver() { | 62 Handle<Object> receiver() { |
| 63 return Arguments::at<Object>(0); | 63 return Arguments::at<Object>(0); |
| 64 } | 64 } |
| 65 | 65 |
| 66 enum { | |
| 67 kNewTargetOffset = 0, | |
|
Yang
2016/06/30 12:34:23
I think we usually use constants and explicitly sp
jgruber
2016/06/30 14:40:29
Done.
| |
| 68 kTargetOffset, | |
| 69 kArgcOffset, | |
| 70 kNumExtraArgs, | |
| 71 kNumExtraArgsWithReceiver | |
| 72 }; | |
| 73 | |
| 66 template <class S> | 74 template <class S> |
| 67 Handle<S> target() { | 75 Handle<S> target() { |
| 68 return Arguments::at<S>(Arguments::length() - 2); | 76 return Arguments::at<S>(Arguments::length() - 1 - kTargetOffset); |
| 69 } | 77 } |
| 70 Handle<HeapObject> new_target() { | 78 Handle<HeapObject> new_target() { |
| 71 return Arguments::at<HeapObject>(Arguments::length() - 1); | 79 return Arguments::at<HeapObject>(Arguments::length() - 1 - |
| 80 kNewTargetOffset); | |
| 72 } | 81 } |
| 73 | 82 |
| 74 // Gets the total number of arguments including the receiver (but | 83 // Gets the total number of arguments including the receiver (but |
| 75 // excluding extra arguments). | 84 // excluding extra arguments). |
| 76 int length() const { return Arguments::length() - 2; } | 85 int length() const { return Arguments::length() - kNumExtraArgs; } |
| 77 }; | 86 }; |
| 78 | 87 |
| 79 | 88 |
| 80 // ---------------------------------------------------------------------------- | 89 // ---------------------------------------------------------------------------- |
| 81 // Support macro for defining builtins in C++. | 90 // Support macro for defining builtins in C++. |
| 82 // ---------------------------------------------------------------------------- | 91 // ---------------------------------------------------------------------------- |
| 83 // | 92 // |
| 84 // A builtin function is defined by writing: | 93 // A builtin function is defined by writing: |
| 85 // | 94 // |
| 86 // BUILTIN(name) { | 95 // BUILTIN(name) { |
| (...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 415 } // namespace | 424 } // namespace |
| 416 | 425 |
| 417 BUILTIN(ArrayPush) { return DoArrayPush(isolate, args); } | 426 BUILTIN(ArrayPush) { return DoArrayPush(isolate, args); } |
| 418 | 427 |
| 419 // TODO(verwaest): This is a temporary helper until the FastArrayPush stub can | 428 // TODO(verwaest): This is a temporary helper until the FastArrayPush stub can |
| 420 // tailcall to the builtin directly. | 429 // tailcall to the builtin directly. |
| 421 RUNTIME_FUNCTION(Runtime_ArrayPush) { | 430 RUNTIME_FUNCTION(Runtime_ArrayPush) { |
| 422 DCHECK_EQ(2, args.length()); | 431 DCHECK_EQ(2, args.length()); |
| 423 Arguments* incoming = reinterpret_cast<Arguments*>(args[0]); | 432 Arguments* incoming = reinterpret_cast<Arguments*>(args[0]); |
| 424 // Rewrap the arguments as builtins arguments. | 433 // Rewrap the arguments as builtins arguments. |
| 425 BuiltinArguments caller_args(incoming->length() + 3, | 434 int argc = incoming->length() + BuiltinArguments::kNumExtraArgsWithReceiver; |
| 426 incoming->arguments() + 1); | 435 BuiltinArguments caller_args(argc, incoming->arguments() + 1); |
| 427 return DoArrayPush(isolate, caller_args); | 436 return DoArrayPush(isolate, caller_args); |
| 428 } | 437 } |
| 429 | 438 |
| 430 BUILTIN(ArrayPop) { | 439 BUILTIN(ArrayPop) { |
| 431 HandleScope scope(isolate); | 440 HandleScope scope(isolate); |
| 432 Handle<Object> receiver = args.receiver(); | 441 Handle<Object> receiver = args.receiver(); |
| 433 if (!EnsureJSArrayWithWritableFastElements(isolate, receiver, nullptr, 0)) { | 442 if (!EnsureJSArrayWithWritableFastElements(isolate, receiver, nullptr, 0)) { |
| 434 return CallJsIntrinsic(isolate, isolate->array_pop(), args); | 443 return CallJsIntrinsic(isolate, isolate->array_pop(), args); |
| 435 } | 444 } |
| 436 | 445 |
| (...skipping 4117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4554 | 4563 |
| 4555 // ES6 section 19.2.3.2 Function.prototype.bind ( thisArg, ...args ) | 4564 // ES6 section 19.2.3.2 Function.prototype.bind ( thisArg, ...args ) |
| 4556 BUILTIN(FunctionPrototypeBind) { return DoFunctionBind(isolate, args); } | 4565 BUILTIN(FunctionPrototypeBind) { return DoFunctionBind(isolate, args); } |
| 4557 | 4566 |
| 4558 // TODO(verwaest): This is a temporary helper until the FastFunctionBind stub | 4567 // TODO(verwaest): This is a temporary helper until the FastFunctionBind stub |
| 4559 // can tailcall to the builtin directly. | 4568 // can tailcall to the builtin directly. |
| 4560 RUNTIME_FUNCTION(Runtime_FunctionBind) { | 4569 RUNTIME_FUNCTION(Runtime_FunctionBind) { |
| 4561 DCHECK_EQ(2, args.length()); | 4570 DCHECK_EQ(2, args.length()); |
| 4562 Arguments* incoming = reinterpret_cast<Arguments*>(args[0]); | 4571 Arguments* incoming = reinterpret_cast<Arguments*>(args[0]); |
| 4563 // Rewrap the arguments as builtins arguments. | 4572 // Rewrap the arguments as builtins arguments. |
| 4564 BuiltinArguments caller_args(incoming->length() + 3, | 4573 int argc = incoming->length() + BuiltinArguments::kNumExtraArgsWithReceiver; |
| 4565 incoming->arguments() + 1); | 4574 BuiltinArguments caller_args(argc, incoming->arguments() + 1); |
| 4566 return DoFunctionBind(isolate, caller_args); | 4575 return DoFunctionBind(isolate, caller_args); |
| 4567 } | 4576 } |
| 4568 | 4577 |
| 4569 // ES6 section 19.2.3.5 Function.prototype.toString ( ) | 4578 // ES6 section 19.2.3.5 Function.prototype.toString ( ) |
| 4570 BUILTIN(FunctionPrototypeToString) { | 4579 BUILTIN(FunctionPrototypeToString) { |
| 4571 HandleScope scope(isolate); | 4580 HandleScope scope(isolate); |
| 4572 Handle<Object> receiver = args.receiver(); | 4581 Handle<Object> receiver = args.receiver(); |
| 4573 if (receiver->IsJSBoundFunction()) { | 4582 if (receiver->IsJSBoundFunction()) { |
| 4574 return *JSBoundFunction::ToString(Handle<JSBoundFunction>::cast(receiver)); | 4583 return *JSBoundFunction::ToString(Handle<JSBoundFunction>::cast(receiver)); |
| 4575 } else if (receiver->IsJSFunction()) { | 4584 } else if (receiver->IsJSFunction()) { |
| (...skipping 902 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5478 function->IsFunctionTemplateInfo() | 5487 function->IsFunctionTemplateInfo() |
| 5479 ? Handle<FunctionTemplateInfo>::cast(function) | 5488 ? Handle<FunctionTemplateInfo>::cast(function) |
| 5480 : handle(JSFunction::cast(*function)->shared()->get_api_func_data(), | 5489 : handle(JSFunction::cast(*function)->shared()->get_api_func_data(), |
| 5481 isolate); | 5490 isolate); |
| 5482 Handle<HeapObject> new_target = isolate->factory()->undefined_value(); | 5491 Handle<HeapObject> new_target = isolate->factory()->undefined_value(); |
| 5483 // Construct BuiltinArguments object: | 5492 // Construct BuiltinArguments object: |
| 5484 // new target, function, arguments reversed, receiver. | 5493 // new target, function, arguments reversed, receiver. |
| 5485 const int kBufferSize = 32; | 5494 const int kBufferSize = 32; |
| 5486 Object* small_argv[kBufferSize]; | 5495 Object* small_argv[kBufferSize]; |
| 5487 Object** argv; | 5496 Object** argv; |
| 5488 if (argc + 3 <= kBufferSize) { | 5497 const int frame_argc = argc + BuiltinArguments::kNumExtraArgsWithReceiver; |
| 5498 if (frame_argc <= kBufferSize) { | |
| 5489 argv = small_argv; | 5499 argv = small_argv; |
| 5490 } else { | 5500 } else { |
| 5491 argv = new Object*[argc + 3]; | 5501 argv = new Object*[frame_argc]; |
| 5492 } | 5502 } |
| 5493 argv[argc + 2] = *receiver; | 5503 int cursor = frame_argc - 1; |
| 5504 argv[cursor--] = *receiver; | |
| 5494 for (int i = 0; i < argc; ++i) { | 5505 for (int i = 0; i < argc; ++i) { |
| 5495 argv[argc - i + 1] = *args[i]; | 5506 argv[cursor--] = *args[i]; |
| 5496 } | 5507 } |
| 5497 argv[1] = *function; | 5508 DCHECK(cursor == BuiltinArguments::kArgcOffset); |
| 5498 argv[0] = *new_target; | 5509 argv[BuiltinArguments::kArgcOffset] = Smi::FromInt(frame_argc); |
| 5510 argv[BuiltinArguments::kTargetOffset] = *function; | |
| 5511 argv[BuiltinArguments::kNewTargetOffset] = *new_target; | |
| 5499 MaybeHandle<Object> result; | 5512 MaybeHandle<Object> result; |
| 5500 { | 5513 { |
| 5501 RelocatableArguments arguments(isolate, argc + 3, &argv[argc] + 2); | 5514 RelocatableArguments arguments(isolate, frame_argc, &argv[frame_argc - 1]); |
| 5502 result = HandleApiCallHelper<false>(isolate, function, new_target, fun_data, | 5515 result = HandleApiCallHelper<false>(isolate, function, new_target, fun_data, |
| 5503 receiver, arguments); | 5516 receiver, arguments); |
| 5504 } | 5517 } |
| 5505 if (argv != small_argv) delete[] argv; | 5518 if (argv != small_argv) delete[] argv; |
| 5506 return result; | 5519 return result; |
| 5507 } | 5520 } |
| 5508 | 5521 |
| 5509 | 5522 |
| 5510 // Helper function to handle calls to non-function objects created through the | 5523 // Helper function to handle calls to non-function objects created through the |
| 5511 // API. The object can be called as either a constructor (using new) or just as | 5524 // 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... | |
| 6257 BUILTIN_LIST_H(DEFINE_BUILTIN_ACCESSOR_H) | 6270 BUILTIN_LIST_H(DEFINE_BUILTIN_ACCESSOR_H) |
| 6258 BUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A) | 6271 BUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A) |
| 6259 #undef DEFINE_BUILTIN_ACCESSOR_C | 6272 #undef DEFINE_BUILTIN_ACCESSOR_C |
| 6260 #undef DEFINE_BUILTIN_ACCESSOR_A | 6273 #undef DEFINE_BUILTIN_ACCESSOR_A |
| 6261 #undef DEFINE_BUILTIN_ACCESSOR_T | 6274 #undef DEFINE_BUILTIN_ACCESSOR_T |
| 6262 #undef DEFINE_BUILTIN_ACCESSOR_S | 6275 #undef DEFINE_BUILTIN_ACCESSOR_S |
| 6263 #undef DEFINE_BUILTIN_ACCESSOR_H | 6276 #undef DEFINE_BUILTIN_ACCESSOR_H |
| 6264 | 6277 |
| 6265 } // namespace internal | 6278 } // namespace internal |
| 6266 } // namespace v8 | 6279 } // namespace v8 |
| OLD | NEW |