| OLD | NEW |
| 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 10 matching lines...) Expand all Loading... |
| 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 27 | 27 |
| 28 #include "v8.h" | 28 #include "v8.h" |
| 29 | 29 |
| 30 #include "api.h" | 30 #include "api.h" |
| 31 #include "arguments.h" |
| 31 #include "bootstrapper.h" | 32 #include "bootstrapper.h" |
| 32 #include "builtins.h" | 33 #include "builtins.h" |
| 33 #include "ic-inl.h" | 34 #include "ic-inl.h" |
| 34 | 35 |
| 35 namespace v8 { | 36 namespace v8 { |
| 36 namespace internal { | 37 namespace internal { |
| 37 | 38 |
| 38 // ---------------------------------------------------------------------------- | 39 // ---------------------------------------------------------------------------- |
| 39 // Support macros for defining builtins in C. | 40 // Support macros for defining builtins in C. |
| 40 // ---------------------------------------------------------------------------- | 41 // ---------------------------------------------------------------------------- |
| 41 // | 42 // |
| 42 // A builtin function is defined by writing: | 43 // A builtin function is defined by writing: |
| 43 // | 44 // |
| 44 // BUILTIN(name) { | 45 // BUILTIN(name) { |
| 45 // ... | 46 // ... |
| 46 // } | 47 // } |
| 47 // BUILTIN_END | 48 // BUILTIN_END |
| 48 // | 49 // |
| 49 // In the body of the builtin function, the variable 'receiver' is visible. | 50 // In the body of the builtin function, the variable 'receiver' is visible. |
| 50 // The arguments can be accessed through: | 51 // The arguments can be accessed through the Arguments object args. |
| 51 // | 52 // |
| 52 // BUILTIN_ARG(0): Receiver (also available as 'receiver') | 53 // args[0]: Receiver (also available as 'receiver') |
| 53 // BUILTIN_ARG(1): First argument | 54 // args[1]: First argument |
| 54 // ... | 55 // ... |
| 55 // BUILTIN_ARG(n): Last argument | 56 // args[n]: Last argument |
| 56 // | 57 // args.length(): Number of arguments including the receiver. |
| 57 // and they evaluate to undefined values if too few arguments were | |
| 58 // passed to the builtin function invocation. | |
| 59 // | |
| 60 // __argc__ is the number of arguments including the receiver. | |
| 61 // ---------------------------------------------------------------------------- | 58 // ---------------------------------------------------------------------------- |
| 62 | 59 |
| 63 | 60 |
| 64 // TODO(428): We should consider passing whether or not the | 61 // TODO(428): We should consider passing whether or not the |
| 65 // builtin was invoked as a constructor as part of the | 62 // builtin was invoked as a constructor as part of the |
| 66 // arguments. Maybe we also want to pass the called function? | 63 // arguments. Maybe we also want to pass the called function? |
| 67 #define BUILTIN(name) \ | 64 #define BUILTIN(name) \ |
| 68 static Object* Builtin_##name(int __argc__, Object** __argv__) { \ | 65 static Object* Builtin_##name(Arguments args) { \ |
| 69 Handle<Object> receiver(&__argv__[0]); | 66 Handle<Object> receiver = args.at<Object>(0); |
| 70 | |
| 71 | |
| 72 // Use an inline function to avoid evaluating the index (n) more than | |
| 73 // once in the BUILTIN_ARG macro. | |
| 74 static inline Object* __builtin_arg__(int n, int argc, Object** argv) { | |
| 75 ASSERT(n >= 0); | |
| 76 return (argc > n) ? argv[-n] : Heap::undefined_value(); | |
| 77 } | |
| 78 | |
| 79 | |
| 80 // NOTE: Argument 0 is the receiver. The first 'real' argument is | |
| 81 // argument 1 - BUILTIN_ARG(1). | |
| 82 #define BUILTIN_ARG(n) (__builtin_arg__(n, __argc__, __argv__)) | |
| 83 | 67 |
| 84 | 68 |
| 85 #define BUILTIN_END \ | 69 #define BUILTIN_END \ |
| 86 return Heap::undefined_value(); \ | 70 return Heap::undefined_value(); \ |
| 87 } | 71 } |
| 88 | 72 |
| 89 | 73 |
| 90 static inline bool CalledAsConstructor() { | 74 static inline bool CalledAsConstructor() { |
| 91 #ifdef DEBUG | 75 #ifdef DEBUG |
| 92 // Calculate the result using a full stack frame iterator and check | 76 // Calculate the result using a full stack frame iterator and check |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 161 Top::context()->global_context()->array_function(); | 145 Top::context()->global_context()->array_function(); |
| 162 Object* obj = Heap::AllocateJSObject(constructor); | 146 Object* obj = Heap::AllocateJSObject(constructor); |
| 163 if (obj->IsFailure()) return obj; | 147 if (obj->IsFailure()) return obj; |
| 164 array = JSArray::cast(obj); | 148 array = JSArray::cast(obj); |
| 165 } | 149 } |
| 166 | 150 |
| 167 // 'array' now contains the JSArray we should initialize. | 151 // 'array' now contains the JSArray we should initialize. |
| 168 | 152 |
| 169 // Optimize the case where there is one argument and the argument is a | 153 // Optimize the case where there is one argument and the argument is a |
| 170 // small smi. | 154 // small smi. |
| 171 if (__argc__ == 2) { | 155 if (args.length() == 2) { |
| 172 Object* obj = BUILTIN_ARG(1); | 156 Object* obj = args[1]; |
| 173 if (obj->IsSmi()) { | 157 if (obj->IsSmi()) { |
| 174 int len = Smi::cast(obj)->value(); | 158 int len = Smi::cast(obj)->value(); |
| 175 if (len >= 0 && len < JSObject::kInitialMaxFastElementArray) { | 159 if (len >= 0 && len < JSObject::kInitialMaxFastElementArray) { |
| 176 Object* obj = Heap::AllocateFixedArrayWithHoles(len); | 160 Object* obj = Heap::AllocateFixedArrayWithHoles(len); |
| 177 if (obj->IsFailure()) return obj; | 161 if (obj->IsFailure()) return obj; |
| 178 array->SetContent(FixedArray::cast(obj)); | 162 array->SetContent(FixedArray::cast(obj)); |
| 179 return array; | 163 return array; |
| 180 } | 164 } |
| 181 } | 165 } |
| 182 // Take the argument as the length. | 166 // Take the argument as the length. |
| 183 obj = array->Initialize(0); | 167 obj = array->Initialize(0); |
| 184 if (obj->IsFailure()) return obj; | 168 if (obj->IsFailure()) return obj; |
| 185 if (__argc__ == 2) return array->SetElementsLength(BUILTIN_ARG(1)); | 169 if (args.length() == 2) return array->SetElementsLength(args[1]); |
| 186 } | 170 } |
| 187 | 171 |
| 188 // Optimize the case where there are no parameters passed. | 172 // Optimize the case where there are no parameters passed. |
| 189 if (__argc__ == 1) return array->Initialize(4); | 173 if (args.length() == 1) return array->Initialize(4); |
| 190 | 174 |
| 191 // Take the arguments as elements. | 175 // Take the arguments as elements. |
| 192 int number_of_elements = __argc__ - 1; | 176 int number_of_elements = args.length() - 1; |
| 193 Smi* len = Smi::FromInt(number_of_elements); | 177 Smi* len = Smi::FromInt(number_of_elements); |
| 194 Object* obj = Heap::AllocateFixedArrayWithHoles(len->value()); | 178 Object* obj = Heap::AllocateFixedArrayWithHoles(len->value()); |
| 195 if (obj->IsFailure()) return obj; | 179 if (obj->IsFailure()) return obj; |
| 196 FixedArray* elms = FixedArray::cast(obj); | 180 FixedArray* elms = FixedArray::cast(obj); |
| 197 WriteBarrierMode mode = elms->GetWriteBarrierMode(); | 181 WriteBarrierMode mode = elms->GetWriteBarrierMode(); |
| 198 // Fill in the content | 182 // Fill in the content |
| 199 for (int index = 0; index < number_of_elements; index++) { | 183 for (int index = 0; index < number_of_elements; index++) { |
| 200 elms->set(index, BUILTIN_ARG(index+1), mode); | 184 elms->set(index, args[index+1], mode); |
| 201 } | 185 } |
| 202 | 186 |
| 203 // Set length and elements on the array. | 187 // Set length and elements on the array. |
| 204 array->set_elements(FixedArray::cast(obj)); | 188 array->set_elements(FixedArray::cast(obj)); |
| 205 array->set_length(len, SKIP_WRITE_BARRIER); | 189 array->set_length(len, SKIP_WRITE_BARRIER); |
| 206 | 190 |
| 207 return array; | 191 return array; |
| 208 } | 192 } |
| 209 BUILTIN_END | 193 BUILTIN_END |
| 210 | 194 |
| 211 | 195 |
| 212 BUILTIN(ArrayPush) { | 196 BUILTIN(ArrayPush) { |
| 213 JSArray* array = JSArray::cast(*receiver); | 197 JSArray* array = JSArray::cast(*receiver); |
| 214 ASSERT(array->HasFastElements()); | 198 ASSERT(array->HasFastElements()); |
| 215 | 199 |
| 216 // Make sure we have space for the elements. | 200 // Make sure we have space for the elements. |
| 217 int len = Smi::cast(array->length())->value(); | 201 int len = Smi::cast(array->length())->value(); |
| 218 | 202 |
| 219 // Set new length. | 203 // Set new length. |
| 220 int new_length = len + __argc__ - 1; | 204 int new_length = len + args.length() - 1; |
| 221 FixedArray* elms = FixedArray::cast(array->elements()); | 205 FixedArray* elms = FixedArray::cast(array->elements()); |
| 222 | 206 |
| 223 if (new_length <= elms->length()) { | 207 if (new_length <= elms->length()) { |
| 224 // Backing storage has extra space for the provided values. | 208 // Backing storage has extra space for the provided values. |
| 225 for (int index = 0; index < __argc__ - 1; index++) { | 209 for (int index = 0; index < args.length() - 1; index++) { |
| 226 elms->set(index + len, BUILTIN_ARG(index+1)); | 210 elms->set(index + len, args[index+1]); |
| 227 } | 211 } |
| 228 } else { | 212 } else { |
| 229 // New backing storage is needed. | 213 // New backing storage is needed. |
| 230 int capacity = new_length + (new_length >> 1) + 16; | 214 int capacity = new_length + (new_length >> 1) + 16; |
| 231 Object* obj = Heap::AllocateFixedArrayWithHoles(capacity); | 215 Object* obj = Heap::AllocateFixedArrayWithHoles(capacity); |
| 232 if (obj->IsFailure()) return obj; | 216 if (obj->IsFailure()) return obj; |
| 233 FixedArray* new_elms = FixedArray::cast(obj); | 217 FixedArray* new_elms = FixedArray::cast(obj); |
| 234 WriteBarrierMode mode = new_elms->GetWriteBarrierMode(); | 218 WriteBarrierMode mode = new_elms->GetWriteBarrierMode(); |
| 235 // Fill out the new array with old elements. | 219 // Fill out the new array with old elements. |
| 236 for (int i = 0; i < len; i++) new_elms->set(i, elms->get(i), mode); | 220 for (int i = 0; i < len; i++) new_elms->set(i, elms->get(i), mode); |
| 237 // Add the provided values. | 221 // Add the provided values. |
| 238 for (int index = 0; index < __argc__ - 1; index++) { | 222 for (int index = 0; index < args.length() - 1; index++) { |
| 239 new_elms->set(index + len, BUILTIN_ARG(index+1), mode); | 223 new_elms->set(index + len, args[index+1], mode); |
| 240 } | 224 } |
| 241 // Set the new backing storage. | 225 // Set the new backing storage. |
| 242 array->set_elements(new_elms); | 226 array->set_elements(new_elms); |
| 243 } | 227 } |
| 244 // Set the length. | 228 // Set the length. |
| 245 array->set_length(Smi::FromInt(new_length), SKIP_WRITE_BARRIER); | 229 array->set_length(Smi::FromInt(new_length), SKIP_WRITE_BARRIER); |
| 246 return array->length(); | 230 return array->length(); |
| 247 } | 231 } |
| 248 BUILTIN_END | 232 BUILTIN_END |
| 249 | 233 |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 346 FunctionTemplateInfo::cast(function->shared()->function_data())); | 330 FunctionTemplateInfo::cast(function->shared()->function_data())); |
| 347 bool pending_exception = false; | 331 bool pending_exception = false; |
| 348 Factory::ConfigureInstance(desc, Handle<JSObject>::cast(receiver), | 332 Factory::ConfigureInstance(desc, Handle<JSObject>::cast(receiver), |
| 349 &pending_exception); | 333 &pending_exception); |
| 350 ASSERT(Top::has_pending_exception() == pending_exception); | 334 ASSERT(Top::has_pending_exception() == pending_exception); |
| 351 if (pending_exception) return Failure::Exception(); | 335 if (pending_exception) return Failure::Exception(); |
| 352 } | 336 } |
| 353 | 337 |
| 354 FunctionTemplateInfo* fun_data = | 338 FunctionTemplateInfo* fun_data = |
| 355 FunctionTemplateInfo::cast(function->shared()->function_data()); | 339 FunctionTemplateInfo::cast(function->shared()->function_data()); |
| 356 Object* raw_holder = TypeCheck(__argc__, __argv__, fun_data); | 340 Object* raw_holder = TypeCheck(args.length(), &args[0], fun_data); |
| 357 | 341 |
| 358 if (raw_holder->IsNull()) { | 342 if (raw_holder->IsNull()) { |
| 359 // This function cannot be called with the given receiver. Abort! | 343 // This function cannot be called with the given receiver. Abort! |
| 360 Handle<Object> obj = | 344 Handle<Object> obj = |
| 361 Factory::NewTypeError("illegal_invocation", HandleVector(&function, 1)); | 345 Factory::NewTypeError("illegal_invocation", HandleVector(&function, 1)); |
| 362 return Top::Throw(*obj); | 346 return Top::Throw(*obj); |
| 363 } | 347 } |
| 364 | 348 |
| 365 Object* raw_call_data = fun_data->call_code(); | 349 Object* raw_call_data = fun_data->call_code(); |
| 366 if (!raw_call_data->IsUndefined()) { | 350 if (!raw_call_data->IsUndefined()) { |
| 367 CallHandlerInfo* call_data = CallHandlerInfo::cast(raw_call_data); | 351 CallHandlerInfo* call_data = CallHandlerInfo::cast(raw_call_data); |
| 368 Object* callback_obj = call_data->callback(); | 352 Object* callback_obj = call_data->callback(); |
| 369 v8::InvocationCallback callback = | 353 v8::InvocationCallback callback = |
| 370 v8::ToCData<v8::InvocationCallback>(callback_obj); | 354 v8::ToCData<v8::InvocationCallback>(callback_obj); |
| 371 Object* data_obj = call_data->data(); | 355 Object* data_obj = call_data->data(); |
| 372 Object* result; | 356 Object* result; |
| 373 | 357 |
| 374 v8::Local<v8::Object> self = | 358 v8::Local<v8::Object> self = |
| 375 v8::Utils::ToLocal(Handle<JSObject>::cast(receiver)); | 359 v8::Utils::ToLocal(Handle<JSObject>::cast(receiver)); |
| 376 Handle<Object> data_handle(data_obj); | 360 Handle<Object> data_handle(data_obj); |
| 377 v8::Local<v8::Value> data = v8::Utils::ToLocal(data_handle); | 361 v8::Local<v8::Value> data = v8::Utils::ToLocal(data_handle); |
| 378 ASSERT(raw_holder->IsJSObject()); | 362 ASSERT(raw_holder->IsJSObject()); |
| 379 v8::Local<v8::Function> callee = v8::Utils::ToLocal(function); | 363 v8::Local<v8::Function> callee = v8::Utils::ToLocal(function); |
| 380 Handle<JSObject> holder_handle(JSObject::cast(raw_holder)); | 364 Handle<JSObject> holder_handle(JSObject::cast(raw_holder)); |
| 381 v8::Local<v8::Object> holder = v8::Utils::ToLocal(holder_handle); | 365 v8::Local<v8::Object> holder = v8::Utils::ToLocal(holder_handle); |
| 382 LOG(ApiObjectAccess("call", JSObject::cast(*receiver))); | 366 LOG(ApiObjectAccess("call", JSObject::cast(*receiver))); |
| 383 v8::Arguments args = v8::ImplementationUtilities::NewArguments( | 367 v8::Arguments new_args = v8::ImplementationUtilities::NewArguments( |
| 384 data, | 368 data, |
| 385 holder, | 369 holder, |
| 386 callee, | 370 callee, |
| 387 is_construct, | 371 is_construct, |
| 388 reinterpret_cast<void**>(__argv__ - 1), | 372 reinterpret_cast<void**>(&args[0] - 1), |
| 389 __argc__ - 1); | 373 args.length() - 1); |
| 390 | 374 |
| 391 v8::Handle<v8::Value> value; | 375 v8::Handle<v8::Value> value; |
| 392 { | 376 { |
| 393 // Leaving JavaScript. | 377 // Leaving JavaScript. |
| 394 VMState state(EXTERNAL); | 378 VMState state(EXTERNAL); |
| 395 value = callback(args); | 379 value = callback(new_args); |
| 396 } | 380 } |
| 397 if (value.IsEmpty()) { | 381 if (value.IsEmpty()) { |
| 398 result = Heap::undefined_value(); | 382 result = Heap::undefined_value(); |
| 399 } else { | 383 } else { |
| 400 result = *reinterpret_cast<Object**>(*value); | 384 result = *reinterpret_cast<Object**>(*value); |
| 401 } | 385 } |
| 402 | 386 |
| 403 RETURN_IF_SCHEDULED_EXCEPTION(); | 387 RETURN_IF_SCHEDULED_EXCEPTION(); |
| 404 if (!is_construct || result->IsJSObject()) return result; | 388 if (!is_construct || result->IsJSObject()) return result; |
| 405 } | 389 } |
| 406 | 390 |
| 407 return *receiver; | 391 return *receiver; |
| 408 } | 392 } |
| 409 BUILTIN_END | 393 BUILTIN_END |
| 410 | 394 |
| 411 | 395 |
| 412 // Helper function to handle calls to non-function objects created through the | 396 // Helper function to handle calls to non-function objects created through the |
| 413 // API. The object can be called as either a constructor (using new) or just as | 397 // API. The object can be called as either a constructor (using new) or just as |
| 414 // a function (without new). | 398 // a function (without new). |
| 415 static Object* HandleApiCallAsFunctionOrConstructor(bool is_construct_call, | 399 static Object* HandleApiCallAsFunctionOrConstructor(bool is_construct_call, |
| 416 int __argc__, | 400 Arguments args) { |
| 417 Object** __argv__) { | |
| 418 // Non-functions are never called as constructors. Even if this is an object | 401 // Non-functions are never called as constructors. Even if this is an object |
| 419 // called as a constructor the delegate call is not a construct call. | 402 // called as a constructor the delegate call is not a construct call. |
| 420 ASSERT(!CalledAsConstructor()); | 403 ASSERT(!CalledAsConstructor()); |
| 421 | 404 |
| 422 Handle<Object> receiver(&__argv__[0]); | 405 Handle<Object> receiver = args.at<Object>(0); |
| 423 | 406 |
| 424 // Get the object called. | 407 // Get the object called. |
| 425 JSObject* obj = JSObject::cast(*receiver); | 408 JSObject* obj = JSObject::cast(*receiver); |
| 426 | 409 |
| 427 // Get the invocation callback from the function descriptor that was | 410 // Get the invocation callback from the function descriptor that was |
| 428 // used to create the called object. | 411 // used to create the called object. |
| 429 ASSERT(obj->map()->has_instance_call_handler()); | 412 ASSERT(obj->map()->has_instance_call_handler()); |
| 430 JSFunction* constructor = JSFunction::cast(obj->map()->constructor()); | 413 JSFunction* constructor = JSFunction::cast(obj->map()->constructor()); |
| 431 Object* template_info = constructor->shared()->function_data(); | 414 Object* template_info = constructor->shared()->function_data(); |
| 432 Object* handler = | 415 Object* handler = |
| 433 FunctionTemplateInfo::cast(template_info)->instance_call_handler(); | 416 FunctionTemplateInfo::cast(template_info)->instance_call_handler(); |
| 434 ASSERT(!handler->IsUndefined()); | 417 ASSERT(!handler->IsUndefined()); |
| 435 CallHandlerInfo* call_data = CallHandlerInfo::cast(handler); | 418 CallHandlerInfo* call_data = CallHandlerInfo::cast(handler); |
| 436 Object* callback_obj = call_data->callback(); | 419 Object* callback_obj = call_data->callback(); |
| 437 v8::InvocationCallback callback = | 420 v8::InvocationCallback callback = |
| 438 v8::ToCData<v8::InvocationCallback>(callback_obj); | 421 v8::ToCData<v8::InvocationCallback>(callback_obj); |
| 439 | 422 |
| 440 // Get the data for the call and perform the callback. | 423 // Get the data for the call and perform the callback. |
| 441 Object* data_obj = call_data->data(); | 424 Object* data_obj = call_data->data(); |
| 442 Object* result; | 425 Object* result; |
| 443 { HandleScope scope; | 426 { HandleScope scope; |
| 444 v8::Local<v8::Object> self = | 427 v8::Local<v8::Object> self = |
| 445 v8::Utils::ToLocal(Handle<JSObject>::cast(receiver)); | 428 v8::Utils::ToLocal(Handle<JSObject>::cast(receiver)); |
| 446 Handle<Object> data_handle(data_obj); | 429 Handle<Object> data_handle(data_obj); |
| 447 v8::Local<v8::Value> data = v8::Utils::ToLocal(data_handle); | 430 v8::Local<v8::Value> data = v8::Utils::ToLocal(data_handle); |
| 448 Handle<JSFunction> callee_handle(constructor); | 431 Handle<JSFunction> callee_handle(constructor); |
| 449 v8::Local<v8::Function> callee = v8::Utils::ToLocal(callee_handle); | 432 v8::Local<v8::Function> callee = v8::Utils::ToLocal(callee_handle); |
| 450 LOG(ApiObjectAccess("call non-function", JSObject::cast(*receiver))); | 433 LOG(ApiObjectAccess("call non-function", JSObject::cast(*receiver))); |
| 451 v8::Arguments args = v8::ImplementationUtilities::NewArguments( | 434 v8::Arguments new_args = v8::ImplementationUtilities::NewArguments( |
| 452 data, | 435 data, |
| 453 self, | 436 self, |
| 454 callee, | 437 callee, |
| 455 is_construct_call, | 438 is_construct_call, |
| 456 reinterpret_cast<void**>(__argv__ - 1), | 439 reinterpret_cast<void**>(&args[0] - 1), |
| 457 __argc__ - 1); | 440 args.length() - 1); |
| 458 v8::Handle<v8::Value> value; | 441 v8::Handle<v8::Value> value; |
| 459 { | 442 { |
| 460 // Leaving JavaScript. | 443 // Leaving JavaScript. |
| 461 VMState state(EXTERNAL); | 444 VMState state(EXTERNAL); |
| 462 value = callback(args); | 445 value = callback(new_args); |
| 463 } | 446 } |
| 464 if (value.IsEmpty()) { | 447 if (value.IsEmpty()) { |
| 465 result = Heap::undefined_value(); | 448 result = Heap::undefined_value(); |
| 466 } else { | 449 } else { |
| 467 result = *reinterpret_cast<Object**>(*value); | 450 result = *reinterpret_cast<Object**>(*value); |
| 468 } | 451 } |
| 469 } | 452 } |
| 470 // Check for exceptions and return result. | 453 // Check for exceptions and return result. |
| 471 RETURN_IF_SCHEDULED_EXCEPTION(); | 454 RETURN_IF_SCHEDULED_EXCEPTION(); |
| 472 return result; | 455 return result; |
| 473 } | 456 } |
| 474 | 457 |
| 475 | 458 |
| 476 // Handle calls to non-function objects created through the API. This delegate | 459 // Handle calls to non-function objects created through the API. This delegate |
| 477 // function is used when the call is a normal function call. | 460 // function is used when the call is a normal function call. |
| 478 BUILTIN(HandleApiCallAsFunction) { | 461 BUILTIN(HandleApiCallAsFunction) { |
| 479 return HandleApiCallAsFunctionOrConstructor(false, __argc__, __argv__); | 462 return HandleApiCallAsFunctionOrConstructor(false, args); |
| 480 } | 463 } |
| 481 BUILTIN_END | 464 BUILTIN_END |
| 482 | 465 |
| 483 | 466 |
| 484 // Handle calls to non-function objects created through the API. This delegate | 467 // Handle calls to non-function objects created through the API. This delegate |
| 485 // function is used when the call is a construct call. | 468 // function is used when the call is a construct call. |
| 486 BUILTIN(HandleApiCallAsConstructor) { | 469 BUILTIN(HandleApiCallAsConstructor) { |
| 487 return HandleApiCallAsFunctionOrConstructor(true, __argc__, __argv__); | 470 return HandleApiCallAsFunctionOrConstructor(true, args); |
| 488 } | 471 } |
| 489 BUILTIN_END | 472 BUILTIN_END |
| 490 | 473 |
| 491 | 474 |
| 492 // TODO(1238487): This is a nasty hack. We need to improve the way we | 475 // TODO(1238487): This is a nasty hack. We need to improve the way we |
| 493 // call builtins considerable to get rid of this and the hairy macros | 476 // call builtins considerable to get rid of this and the hairy macros |
| 494 // in builtins.cc. | 477 // in builtins.cc. |
| 495 Object* Builtins::builtin_passed_function; | 478 Object* Builtins::builtin_passed_function; |
| 496 | 479 |
| 497 | 480 |
| (...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 773 if (entry->contains(pc)) { | 756 if (entry->contains(pc)) { |
| 774 return names_[i]; | 757 return names_[i]; |
| 775 } | 758 } |
| 776 } | 759 } |
| 777 } | 760 } |
| 778 return NULL; | 761 return NULL; |
| 779 } | 762 } |
| 780 | 763 |
| 781 | 764 |
| 782 } } // namespace v8::internal | 765 } } // namespace v8::internal |
| OLD | NEW |