| 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 | 
|---|