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 |