Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 142 } | 142 } |
| 143 | 143 |
| 144 return Handle<Object>(value->ToObjectUnchecked(), isolate); | 144 return Handle<Object>(value->ToObjectUnchecked(), isolate); |
| 145 } | 145 } |
| 146 | 146 |
| 147 | 147 |
| 148 Handle<Object> Execution::Call(Handle<Object> callable, | 148 Handle<Object> Execution::Call(Handle<Object> callable, |
| 149 Handle<Object> receiver, | 149 Handle<Object> receiver, |
| 150 int argc, | 150 int argc, |
| 151 Object*** args, | 151 Object*** args, |
| 152 bool* pending_exception) { | 152 bool* pending_exception, |
| 153 bool convert_receiver) { | |
| 153 if (!callable->IsJSFunction()) { | 154 if (!callable->IsJSFunction()) { |
| 154 callable = TryGetFunctionDelegate(callable, pending_exception); | 155 callable = TryGetFunctionDelegate(callable, pending_exception); |
| 155 if (*pending_exception) return callable; | 156 if (*pending_exception) return callable; |
| 156 } | 157 } |
| 157 Handle<JSFunction> func = Handle<JSFunction>::cast(callable); | 158 Handle<JSFunction> func = Handle<JSFunction>::cast(callable); |
| 159 | |
| 160 // In non-strict mode, convert receiver. | |
| 161 if (convert_receiver && !receiver->IsJSReceiver() && | |
| 162 !func->shared()->native() && !func->shared()->strict_mode()) { | |
| 163 if (receiver->IsUndefined() || receiver->IsNull()) { | |
| 164 Object* global = func->context()->global()->global_receiver(); | |
| 165 // Is there a way to get the proper global object if func is a builtin? | |
|
Kevin Millikin (Chromium)
2011/09/12 14:42:47
I guess I'm not sure what is proper. isolate()->g
rossberg
2011/09/12 15:17:25
Ah, thanks, the latter is what I was looking for,
| |
| 166 if (!global->IsJSBuiltinsObject()) receiver = Handle<Object>(global); | |
| 167 } else { | |
| 168 receiver = ToObject(receiver, pending_exception); | |
| 169 } | |
| 170 if (*pending_exception) return callable; | |
| 171 } | |
| 172 | |
| 158 return Invoke(false, func, receiver, argc, args, pending_exception); | 173 return Invoke(false, func, receiver, argc, args, pending_exception); |
| 159 } | 174 } |
| 160 | 175 |
| 161 | 176 |
| 162 Handle<Object> Execution::New(Handle<JSFunction> func, int argc, | 177 Handle<Object> Execution::New(Handle<JSFunction> func, int argc, |
| 163 Object*** args, bool* pending_exception) { | 178 Object*** args, bool* pending_exception) { |
| 164 return Invoke(true, func, Isolate::Current()->global(), argc, args, | 179 return Invoke(true, func, Isolate::Current()->global(), argc, args, |
| 165 pending_exception); | 180 pending_exception); |
| 166 } | 181 } |
| 167 | 182 |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 203 | 218 |
| 204 | 219 |
| 205 Handle<Object> Execution::GetFunctionDelegate(Handle<Object> object) { | 220 Handle<Object> Execution::GetFunctionDelegate(Handle<Object> object) { |
| 206 ASSERT(!object->IsJSFunction()); | 221 ASSERT(!object->IsJSFunction()); |
| 207 Isolate* isolate = Isolate::Current(); | 222 Isolate* isolate = Isolate::Current(); |
| 208 Factory* factory = isolate->factory(); | 223 Factory* factory = isolate->factory(); |
| 209 | 224 |
| 210 // If you return a function from here, it will be called when an | 225 // If you return a function from here, it will be called when an |
| 211 // attempt is made to call the given object as a function. | 226 // attempt is made to call the given object as a function. |
| 212 | 227 |
| 228 // If object is a function proxies, get its handler. Iterate if necessary. | |
| 229 Object* fun = *object; | |
| 230 while (fun->IsJSFunctionProxy()) { | |
| 231 fun = JSFunctionProxy::cast(fun)->call_trap(); | |
| 232 } | |
| 233 if (fun->IsJSFunction()) return Handle<Object>(fun); | |
| 234 | |
| 213 // Objects created through the API can have an instance-call handler | 235 // Objects created through the API can have an instance-call handler |
| 214 // that should be used when calling the object as a function. | 236 // that should be used when calling the object as a function. |
| 215 if (object->IsHeapObject() && | 237 if (fun->IsHeapObject() && |
| 216 HeapObject::cast(*object)->map()->has_instance_call_handler()) { | 238 HeapObject::cast(fun)->map()->has_instance_call_handler()) { |
| 217 return Handle<JSFunction>( | 239 return Handle<JSFunction>( |
| 218 isolate->global_context()->call_as_function_delegate()); | 240 isolate->global_context()->call_as_function_delegate()); |
| 219 } | 241 } |
| 220 | 242 |
| 221 return factory->undefined_value(); | 243 return factory->undefined_value(); |
| 222 } | 244 } |
| 223 | 245 |
| 224 | 246 |
| 225 Handle<Object> Execution::TryGetFunctionDelegate(Handle<Object> object, | 247 Handle<Object> Execution::TryGetFunctionDelegate(Handle<Object> object, |
| 226 bool* has_pending_exception) { | 248 bool* has_pending_exception) { |
| 227 ASSERT(!object->IsJSFunction()); | 249 ASSERT(!object->IsJSFunction()); |
| 228 Isolate* isolate = Isolate::Current(); | 250 Isolate* isolate = Isolate::Current(); |
| 229 | 251 |
| 252 // If object is a function proxies, get its handler. Iterate if necessary. | |
| 253 Object* fun = *object; | |
| 254 while (fun->IsJSFunctionProxy()) { | |
| 255 fun = JSFunctionProxy::cast(fun)->call_trap(); | |
| 256 } | |
| 257 if (fun->IsJSFunction()) return Handle<Object>(fun); | |
| 258 | |
| 230 // Objects created through the API can have an instance-call handler | 259 // Objects created through the API can have an instance-call handler |
| 231 // that should be used when calling the object as a function. | 260 // that should be used when calling the object as a function. |
| 232 if (object->IsHeapObject() && | 261 if (fun->IsHeapObject() && |
| 233 HeapObject::cast(*object)->map()->has_instance_call_handler()) { | 262 HeapObject::cast(fun)->map()->has_instance_call_handler()) { |
| 234 return Handle<JSFunction>( | 263 return Handle<JSFunction>( |
| 235 isolate->global_context()->call_as_function_delegate()); | 264 isolate->global_context()->call_as_function_delegate()); |
| 236 } | 265 } |
| 237 | 266 |
| 238 // If the Object doesn't have an instance-call handler we should | 267 // If the Object doesn't have an instance-call handler we should |
| 239 // throw a non-callable exception. | 268 // throw a non-callable exception. |
| 240 i::Handle<i::Object> error_obj = isolate->factory()->NewTypeError( | 269 i::Handle<i::Object> error_obj = isolate->factory()->NewTypeError( |
| 241 "called_non_callable", i::HandleVector<i::Object>(&object, 1)); | 270 "called_non_callable", i::HandleVector<i::Object>(&object, 1)); |
| 242 isolate->Throw(*error_obj); | 271 isolate->Throw(*error_obj); |
| 243 *has_pending_exception = true; | 272 *has_pending_exception = true; |
| 244 | 273 |
| 245 return isolate->factory()->undefined_value(); | 274 return isolate->factory()->undefined_value(); |
| 246 } | 275 } |
| 247 | 276 |
| 248 | 277 |
| 249 Handle<Object> Execution::GetConstructorDelegate(Handle<Object> object) { | 278 Handle<Object> Execution::GetConstructorDelegate(Handle<Object> object) { |
| 250 ASSERT(!object->IsJSFunction()); | 279 ASSERT(!object->IsJSFunction()); |
| 251 Isolate* isolate = Isolate::Current(); | 280 Isolate* isolate = Isolate::Current(); |
| 252 | 281 |
| 253 // If you return a function from here, it will be called when an | 282 // If you return a function from here, it will be called when an |
| 254 // attempt is made to call the given object as a constructor. | 283 // attempt is made to call the given object as a constructor. |
| 255 | 284 |
| 285 // If object is a function proxies, get its handler. Iterate if necessary. | |
| 286 Object* fun = *object; | |
| 287 while (fun->IsJSFunctionProxy()) { | |
| 288 fun = JSFunctionProxy::cast(fun)->call_trap(); | |
| 289 } | |
| 290 if (fun->IsJSFunction()) return Handle<Object>(fun); | |
| 291 | |
| 256 // Objects created through the API can have an instance-call handler | 292 // Objects created through the API can have an instance-call handler |
| 257 // that should be used when calling the object as a function. | 293 // that should be used when calling the object as a function. |
| 258 if (object->IsHeapObject() && | 294 if (fun->IsHeapObject() && |
| 259 HeapObject::cast(*object)->map()->has_instance_call_handler()) { | 295 HeapObject::cast(fun)->map()->has_instance_call_handler()) { |
| 260 return Handle<JSFunction>( | 296 return Handle<JSFunction>( |
| 261 isolate->global_context()->call_as_constructor_delegate()); | 297 isolate->global_context()->call_as_constructor_delegate()); |
| 262 } | 298 } |
| 263 | 299 |
| 264 return isolate->factory()->undefined_value(); | 300 return isolate->factory()->undefined_value(); |
| 265 } | 301 } |
| 266 | 302 |
| 267 | 303 |
| 268 Handle<Object> Execution::TryGetConstructorDelegate( | 304 Handle<Object> Execution::TryGetConstructorDelegate( |
| 269 Handle<Object> object, | 305 Handle<Object> object, |
| 270 bool* has_pending_exception) { | 306 bool* has_pending_exception) { |
| 271 ASSERT(!object->IsJSFunction()); | 307 ASSERT(!object->IsJSFunction()); |
| 272 Isolate* isolate = Isolate::Current(); | 308 Isolate* isolate = Isolate::Current(); |
| 273 | 309 |
| 274 // If you return a function from here, it will be called when an | 310 // If you return a function from here, it will be called when an |
| 275 // attempt is made to call the given object as a constructor. | 311 // attempt is made to call the given object as a constructor. |
| 276 | 312 |
| 313 // If object is a function proxies, get its handler. Iterate if necessary. | |
| 314 Object* fun = *object; | |
| 315 while (fun->IsJSFunctionProxy()) { | |
| 316 fun = JSFunctionProxy::cast(fun)->call_trap(); | |
| 317 } | |
| 318 if (fun->IsJSFunction()) return Handle<Object>(fun); | |
| 319 | |
| 277 // Objects created through the API can have an instance-call handler | 320 // Objects created through the API can have an instance-call handler |
| 278 // that should be used when calling the object as a function. | 321 // that should be used when calling the object as a function. |
| 279 if (object->IsHeapObject() && | 322 if (fun->IsHeapObject() && |
| 280 HeapObject::cast(*object)->map()->has_instance_call_handler()) { | 323 HeapObject::cast(fun)->map()->has_instance_call_handler()) { |
| 281 return Handle<JSFunction>( | 324 return Handle<JSFunction>( |
| 282 isolate->global_context()->call_as_constructor_delegate()); | 325 isolate->global_context()->call_as_constructor_delegate()); |
| 283 } | 326 } |
| 284 | 327 |
| 285 // If the Object doesn't have an instance-call handler we should | 328 // If the Object doesn't have an instance-call handler we should |
| 286 // throw a non-callable exception. | 329 // throw a non-callable exception. |
| 287 i::Handle<i::Object> error_obj = isolate->factory()->NewTypeError( | 330 i::Handle<i::Object> error_obj = isolate->factory()->NewTypeError( |
| 288 "called_non_callable", i::HandleVector<i::Object>(&object, 1)); | 331 "called_non_callable", i::HandleVector<i::Object>(&object, 1)); |
| 289 isolate->Throw(*error_obj); | 332 isolate->Throw(*error_obj); |
| 290 *has_pending_exception = true; | 333 *has_pending_exception = true; |
| (...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 546 RETURN_NATIVE_CALL(to_string, 1, { obj.location() }, exc); | 589 RETURN_NATIVE_CALL(to_string, 1, { obj.location() }, exc); |
| 547 } | 590 } |
| 548 | 591 |
| 549 | 592 |
| 550 Handle<Object> Execution::ToDetailString(Handle<Object> obj, bool* exc) { | 593 Handle<Object> Execution::ToDetailString(Handle<Object> obj, bool* exc) { |
| 551 RETURN_NATIVE_CALL(to_detail_string, 1, { obj.location() }, exc); | 594 RETURN_NATIVE_CALL(to_detail_string, 1, { obj.location() }, exc); |
| 552 } | 595 } |
| 553 | 596 |
| 554 | 597 |
| 555 Handle<Object> Execution::ToObject(Handle<Object> obj, bool* exc) { | 598 Handle<Object> Execution::ToObject(Handle<Object> obj, bool* exc) { |
| 556 if (obj->IsJSObject()) return obj; | 599 if (obj->IsSpecObject()) return obj; |
| 557 RETURN_NATIVE_CALL(to_object, 1, { obj.location() }, exc); | 600 RETURN_NATIVE_CALL(to_object, 1, { obj.location() }, exc); |
| 558 } | 601 } |
| 559 | 602 |
| 560 | 603 |
| 561 Handle<Object> Execution::ToInteger(Handle<Object> obj, bool* exc) { | 604 Handle<Object> Execution::ToInteger(Handle<Object> obj, bool* exc) { |
| 562 RETURN_NATIVE_CALL(to_integer, 1, { obj.location() }, exc); | 605 RETURN_NATIVE_CALL(to_integer, 1, { obj.location() }, exc); |
| 563 } | 606 } |
| 564 | 607 |
| 565 | 608 |
| 566 Handle<Object> Execution::ToUint32(Handle<Object> obj, bool* exc) { | 609 Handle<Object> Execution::ToUint32(Handle<Object> obj, bool* exc) { |
| (...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 824 return isolate->TerminateExecution(); | 867 return isolate->TerminateExecution(); |
| 825 } | 868 } |
| 826 if (stack_guard->IsInterrupted()) { | 869 if (stack_guard->IsInterrupted()) { |
| 827 stack_guard->Continue(INTERRUPT); | 870 stack_guard->Continue(INTERRUPT); |
| 828 return isolate->StackOverflow(); | 871 return isolate->StackOverflow(); |
| 829 } | 872 } |
| 830 return isolate->heap()->undefined_value(); | 873 return isolate->heap()->undefined_value(); |
| 831 } | 874 } |
| 832 | 875 |
| 833 } } // namespace v8::internal | 876 } } // namespace v8::internal |
| OLD | NEW |