| Index: src/builtins.cc
|
| ===================================================================
|
| --- src/builtins.cc (revision 2771)
|
| +++ src/builtins.cc (working copy)
|
| @@ -28,6 +28,7 @@
|
| #include "v8.h"
|
|
|
| #include "api.h"
|
| +#include "arguments.h"
|
| #include "bootstrapper.h"
|
| #include "builtins.h"
|
| #include "ic-inl.h"
|
| @@ -47,17 +48,13 @@
|
| // BUILTIN_END
|
| //
|
| // In the body of the builtin function, the variable 'receiver' is visible.
|
| -// The arguments can be accessed through:
|
| +// The arguments can be accessed through the Arguments object args.
|
| //
|
| -// BUILTIN_ARG(0): Receiver (also available as 'receiver')
|
| -// BUILTIN_ARG(1): First argument
|
| +// args[0]: Receiver (also available as 'receiver')
|
| +// args[1]: First argument
|
| // ...
|
| -// BUILTIN_ARG(n): Last argument
|
| -//
|
| -// and they evaluate to undefined values if too few arguments were
|
| -// passed to the builtin function invocation.
|
| -//
|
| -// __argc__ is the number of arguments including the receiver.
|
| +// args[n]: Last argument
|
| +// args.length(): Number of arguments including the receiver.
|
| // ----------------------------------------------------------------------------
|
|
|
|
|
| @@ -65,23 +62,10 @@
|
| // builtin was invoked as a constructor as part of the
|
| // arguments. Maybe we also want to pass the called function?
|
| #define BUILTIN(name) \
|
| - static Object* Builtin_##name(int __argc__, Object** __argv__) { \
|
| - Handle<Object> receiver(&__argv__[0]);
|
| + static Object* Builtin_##name(Arguments args) { \
|
| + Handle<Object> receiver = args.at<Object>(0);
|
|
|
|
|
| -// Use an inline function to avoid evaluating the index (n) more than
|
| -// once in the BUILTIN_ARG macro.
|
| -static inline Object* __builtin_arg__(int n, int argc, Object** argv) {
|
| - ASSERT(n >= 0);
|
| - return (argc > n) ? argv[-n] : Heap::undefined_value();
|
| -}
|
| -
|
| -
|
| -// NOTE: Argument 0 is the receiver. The first 'real' argument is
|
| -// argument 1 - BUILTIN_ARG(1).
|
| -#define BUILTIN_ARG(n) (__builtin_arg__(n, __argc__, __argv__))
|
| -
|
| -
|
| #define BUILTIN_END \
|
| return Heap::undefined_value(); \
|
| }
|
| @@ -168,8 +152,8 @@
|
|
|
| // Optimize the case where there is one argument and the argument is a
|
| // small smi.
|
| - if (__argc__ == 2) {
|
| - Object* obj = BUILTIN_ARG(1);
|
| + if (args.length() == 2) {
|
| + Object* obj = args[1];
|
| if (obj->IsSmi()) {
|
| int len = Smi::cast(obj)->value();
|
| if (len >= 0 && len < JSObject::kInitialMaxFastElementArray) {
|
| @@ -182,14 +166,14 @@
|
| // Take the argument as the length.
|
| obj = array->Initialize(0);
|
| if (obj->IsFailure()) return obj;
|
| - if (__argc__ == 2) return array->SetElementsLength(BUILTIN_ARG(1));
|
| + if (args.length() == 2) return array->SetElementsLength(args[1]);
|
| }
|
|
|
| // Optimize the case where there are no parameters passed.
|
| - if (__argc__ == 1) return array->Initialize(4);
|
| + if (args.length() == 1) return array->Initialize(4);
|
|
|
| // Take the arguments as elements.
|
| - int number_of_elements = __argc__ - 1;
|
| + int number_of_elements = args.length() - 1;
|
| Smi* len = Smi::FromInt(number_of_elements);
|
| Object* obj = Heap::AllocateFixedArrayWithHoles(len->value());
|
| if (obj->IsFailure()) return obj;
|
| @@ -197,7 +181,7 @@
|
| WriteBarrierMode mode = elms->GetWriteBarrierMode();
|
| // Fill in the content
|
| for (int index = 0; index < number_of_elements; index++) {
|
| - elms->set(index, BUILTIN_ARG(index+1), mode);
|
| + elms->set(index, args[index+1], mode);
|
| }
|
|
|
| // Set length and elements on the array.
|
| @@ -217,13 +201,13 @@
|
| int len = Smi::cast(array->length())->value();
|
|
|
| // Set new length.
|
| - int new_length = len + __argc__ - 1;
|
| + int new_length = len + args.length() - 1;
|
| FixedArray* elms = FixedArray::cast(array->elements());
|
|
|
| if (new_length <= elms->length()) {
|
| // Backing storage has extra space for the provided values.
|
| - for (int index = 0; index < __argc__ - 1; index++) {
|
| - elms->set(index + len, BUILTIN_ARG(index+1));
|
| + for (int index = 0; index < args.length() - 1; index++) {
|
| + elms->set(index + len, args[index+1]);
|
| }
|
| } else {
|
| // New backing storage is needed.
|
| @@ -235,8 +219,8 @@
|
| // Fill out the new array with old elements.
|
| for (int i = 0; i < len; i++) new_elms->set(i, elms->get(i), mode);
|
| // Add the provided values.
|
| - for (int index = 0; index < __argc__ - 1; index++) {
|
| - new_elms->set(index + len, BUILTIN_ARG(index+1), mode);
|
| + for (int index = 0; index < args.length() - 1; index++) {
|
| + new_elms->set(index + len, args[index+1], mode);
|
| }
|
| // Set the new backing storage.
|
| array->set_elements(new_elms);
|
| @@ -353,7 +337,7 @@
|
|
|
| FunctionTemplateInfo* fun_data =
|
| FunctionTemplateInfo::cast(function->shared()->function_data());
|
| - Object* raw_holder = TypeCheck(__argc__, __argv__, fun_data);
|
| + Object* raw_holder = TypeCheck(args.length(), &args[0], fun_data);
|
|
|
| if (raw_holder->IsNull()) {
|
| // This function cannot be called with the given receiver. Abort!
|
| @@ -380,19 +364,19 @@
|
| Handle<JSObject> holder_handle(JSObject::cast(raw_holder));
|
| v8::Local<v8::Object> holder = v8::Utils::ToLocal(holder_handle);
|
| LOG(ApiObjectAccess("call", JSObject::cast(*receiver)));
|
| - v8::Arguments args = v8::ImplementationUtilities::NewArguments(
|
| + v8::Arguments new_args = v8::ImplementationUtilities::NewArguments(
|
| data,
|
| holder,
|
| callee,
|
| is_construct,
|
| - reinterpret_cast<void**>(__argv__ - 1),
|
| - __argc__ - 1);
|
| + reinterpret_cast<void**>(&args[0] - 1),
|
| + args.length() - 1);
|
|
|
| v8::Handle<v8::Value> value;
|
| {
|
| // Leaving JavaScript.
|
| VMState state(EXTERNAL);
|
| - value = callback(args);
|
| + value = callback(new_args);
|
| }
|
| if (value.IsEmpty()) {
|
| result = Heap::undefined_value();
|
| @@ -413,13 +397,12 @@
|
| // API. The object can be called as either a constructor (using new) or just as
|
| // a function (without new).
|
| static Object* HandleApiCallAsFunctionOrConstructor(bool is_construct_call,
|
| - int __argc__,
|
| - Object** __argv__) {
|
| + Arguments args) {
|
| // Non-functions are never called as constructors. Even if this is an object
|
| // called as a constructor the delegate call is not a construct call.
|
| ASSERT(!CalledAsConstructor());
|
|
|
| - Handle<Object> receiver(&__argv__[0]);
|
| + Handle<Object> receiver = args.at<Object>(0);
|
|
|
| // Get the object called.
|
| JSObject* obj = JSObject::cast(*receiver);
|
| @@ -448,18 +431,18 @@
|
| Handle<JSFunction> callee_handle(constructor);
|
| v8::Local<v8::Function> callee = v8::Utils::ToLocal(callee_handle);
|
| LOG(ApiObjectAccess("call non-function", JSObject::cast(*receiver)));
|
| - v8::Arguments args = v8::ImplementationUtilities::NewArguments(
|
| + v8::Arguments new_args = v8::ImplementationUtilities::NewArguments(
|
| data,
|
| self,
|
| callee,
|
| is_construct_call,
|
| - reinterpret_cast<void**>(__argv__ - 1),
|
| - __argc__ - 1);
|
| + reinterpret_cast<void**>(&args[0] - 1),
|
| + args.length() - 1);
|
| v8::Handle<v8::Value> value;
|
| {
|
| // Leaving JavaScript.
|
| VMState state(EXTERNAL);
|
| - value = callback(args);
|
| + value = callback(new_args);
|
| }
|
| if (value.IsEmpty()) {
|
| result = Heap::undefined_value();
|
| @@ -476,7 +459,7 @@
|
| // Handle calls to non-function objects created through the API. This delegate
|
| // function is used when the call is a normal function call.
|
| BUILTIN(HandleApiCallAsFunction) {
|
| - return HandleApiCallAsFunctionOrConstructor(false, __argc__, __argv__);
|
| + return HandleApiCallAsFunctionOrConstructor(false, args);
|
| }
|
| BUILTIN_END
|
|
|
| @@ -484,7 +467,7 @@
|
| // Handle calls to non-function objects created through the API. This delegate
|
| // function is used when the call is a construct call.
|
| BUILTIN(HandleApiCallAsConstructor) {
|
| - return HandleApiCallAsFunctionOrConstructor(true, __argc__, __argv__);
|
| + return HandleApiCallAsFunctionOrConstructor(true, args);
|
| }
|
| BUILTIN_END
|
|
|
|
|