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

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 second round of 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
« no previous file with comments | « src/execution.h ('k') | src/factory.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 // 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
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
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
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
OLDNEW
« no previous file with comments | « src/execution.h ('k') | src/factory.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698