Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(183)

Side by Side Diff: src/execution.cc

Issue 7623011: Implement function proxies (except for their use as constructors). (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Addressed Kevin's comments. Created 9 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
OLDNEW
« src/execution.h ('K') | « src/execution.h ('k') | src/factory.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698