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