deps: update v8 to 4.3.61.21
[platform/upstream/nodejs.git] / deps / v8 / src / runtime / runtime-function.cc
1 // Copyright 2014 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "src/v8.h"
6
7 #include "src/accessors.h"
8 #include "src/arguments.h"
9 #include "src/compiler.h"
10 #include "src/cpu-profiler.h"
11 #include "src/deoptimizer.h"
12 #include "src/frames.h"
13 #include "src/runtime/runtime-utils.h"
14
15 namespace v8 {
16 namespace internal {
17
18 RUNTIME_FUNCTION(Runtime_IsSloppyModeFunction) {
19   SealHandleScope shs(isolate);
20   DCHECK(args.length() == 1);
21   CONVERT_ARG_CHECKED(JSReceiver, callable, 0);
22   if (!callable->IsJSFunction()) {
23     HandleScope scope(isolate);
24     Handle<Object> delegate;
25     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
26         isolate, delegate, Execution::TryGetFunctionDelegate(
27                                isolate, Handle<JSReceiver>(callable)));
28     callable = JSFunction::cast(*delegate);
29   }
30   JSFunction* function = JSFunction::cast(callable);
31   SharedFunctionInfo* shared = function->shared();
32   return isolate->heap()->ToBoolean(is_sloppy(shared->language_mode()));
33 }
34
35
36 RUNTIME_FUNCTION(Runtime_GetDefaultReceiver) {
37   SealHandleScope shs(isolate);
38   DCHECK(args.length() == 1);
39   CONVERT_ARG_CHECKED(JSReceiver, callable, 0);
40
41   if (!callable->IsJSFunction()) {
42     HandleScope scope(isolate);
43     Handle<Object> delegate;
44     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
45         isolate, delegate, Execution::TryGetFunctionDelegate(
46                                isolate, Handle<JSReceiver>(callable)));
47     callable = JSFunction::cast(*delegate);
48   }
49   JSFunction* function = JSFunction::cast(callable);
50
51   SharedFunctionInfo* shared = function->shared();
52   if (shared->native() || is_strict(shared->language_mode())) {
53     return isolate->heap()->undefined_value();
54   }
55   // Returns undefined for strict or native functions, or
56   // the associated global receiver for "normal" functions.
57
58   return function->global_proxy();
59 }
60
61
62 RUNTIME_FUNCTION(Runtime_FunctionGetName) {
63   SealHandleScope shs(isolate);
64   DCHECK(args.length() == 1);
65
66   CONVERT_ARG_CHECKED(JSFunction, f, 0);
67   return f->shared()->name();
68 }
69
70
71 static Handle<String> NameToFunctionName(Handle<Name> name) {
72   Handle<String> stringName(name->GetHeap()->empty_string());
73
74   // TODO(caitp): Follow proper rules in section 9.2.11 (SetFunctionName)
75   if (name->IsSymbol()) {
76     Handle<Object> description(Handle<Symbol>::cast(name)->name(),
77                                name->GetIsolate());
78     if (description->IsString()) {
79       stringName = Handle<String>::cast(description);
80     }
81   } else {
82     stringName = Handle<String>::cast(name);
83   }
84
85   return stringName;
86 }
87
88
89 RUNTIME_FUNCTION(Runtime_FunctionSetName) {
90   HandleScope scope(isolate);
91   DCHECK(args.length() == 2);
92
93   CONVERT_ARG_HANDLE_CHECKED(JSFunction, f, 0);
94   CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
95
96   f->shared()->set_name(*NameToFunctionName(name));
97   return isolate->heap()->undefined_value();
98 }
99
100
101 RUNTIME_FUNCTION(Runtime_FunctionNameShouldPrintAsAnonymous) {
102   SealHandleScope shs(isolate);
103   DCHECK(args.length() == 1);
104   CONVERT_ARG_CHECKED(JSFunction, f, 0);
105   return isolate->heap()->ToBoolean(
106       f->shared()->name_should_print_as_anonymous());
107 }
108
109
110 RUNTIME_FUNCTION(Runtime_FunctionMarkNameShouldPrintAsAnonymous) {
111   SealHandleScope shs(isolate);
112   DCHECK(args.length() == 1);
113   CONVERT_ARG_CHECKED(JSFunction, f, 0);
114   f->shared()->set_name_should_print_as_anonymous(true);
115   return isolate->heap()->undefined_value();
116 }
117
118
119 RUNTIME_FUNCTION(Runtime_FunctionIsArrow) {
120   SealHandleScope shs(isolate);
121   DCHECK(args.length() == 1);
122   CONVERT_ARG_CHECKED(JSFunction, f, 0);
123   return isolate->heap()->ToBoolean(f->shared()->is_arrow());
124 }
125
126
127 RUNTIME_FUNCTION(Runtime_FunctionIsConciseMethod) {
128   SealHandleScope shs(isolate);
129   DCHECK(args.length() == 1);
130   CONVERT_ARG_CHECKED(JSFunction, f, 0);
131   return isolate->heap()->ToBoolean(f->shared()->is_concise_method());
132 }
133
134
135 RUNTIME_FUNCTION(Runtime_FunctionRemovePrototype) {
136   SealHandleScope shs(isolate);
137   DCHECK(args.length() == 1);
138
139   CONVERT_ARG_CHECKED(JSFunction, f, 0);
140   RUNTIME_ASSERT(f->RemovePrototype());
141
142   return isolate->heap()->undefined_value();
143 }
144
145
146 RUNTIME_FUNCTION(Runtime_FunctionGetScript) {
147   HandleScope scope(isolate);
148   DCHECK(args.length() == 1);
149
150   CONVERT_ARG_CHECKED(JSFunction, fun, 0);
151   Handle<Object> script = Handle<Object>(fun->shared()->script(), isolate);
152   if (!script->IsScript()) return isolate->heap()->undefined_value();
153
154   return *Script::GetWrapper(Handle<Script>::cast(script));
155 }
156
157
158 RUNTIME_FUNCTION(Runtime_FunctionGetSourceCode) {
159   HandleScope scope(isolate);
160   DCHECK(args.length() == 1);
161
162   CONVERT_ARG_HANDLE_CHECKED(JSFunction, f, 0);
163   Handle<SharedFunctionInfo> shared(f->shared());
164   return *shared->GetSourceCode();
165 }
166
167
168 RUNTIME_FUNCTION(Runtime_FunctionGetScriptSourcePosition) {
169   SealHandleScope shs(isolate);
170   DCHECK(args.length() == 1);
171
172   CONVERT_ARG_CHECKED(JSFunction, fun, 0);
173   int pos = fun->shared()->start_position();
174   return Smi::FromInt(pos);
175 }
176
177
178 RUNTIME_FUNCTION(Runtime_FunctionGetPositionForOffset) {
179   SealHandleScope shs(isolate);
180   DCHECK(args.length() == 2);
181
182   CONVERT_ARG_CHECKED(Code, code, 0);
183   CONVERT_NUMBER_CHECKED(int, offset, Int32, args[1]);
184
185   RUNTIME_ASSERT(0 <= offset && offset < code->Size());
186
187   Address pc = code->address() + offset;
188   return Smi::FromInt(code->SourcePosition(pc));
189 }
190
191
192 RUNTIME_FUNCTION(Runtime_FunctionSetInstanceClassName) {
193   SealHandleScope shs(isolate);
194   DCHECK(args.length() == 2);
195
196   CONVERT_ARG_CHECKED(JSFunction, fun, 0);
197   CONVERT_ARG_CHECKED(String, name, 1);
198   fun->SetInstanceClassName(name);
199   return isolate->heap()->undefined_value();
200 }
201
202
203 RUNTIME_FUNCTION(Runtime_FunctionSetLength) {
204   SealHandleScope shs(isolate);
205   DCHECK(args.length() == 2);
206
207   CONVERT_ARG_CHECKED(JSFunction, fun, 0);
208   CONVERT_SMI_ARG_CHECKED(length, 1);
209   RUNTIME_ASSERT((length & 0xC0000000) == 0xC0000000 ||
210                  (length & 0xC0000000) == 0x0);
211   fun->shared()->set_length(length);
212   return isolate->heap()->undefined_value();
213 }
214
215
216 RUNTIME_FUNCTION(Runtime_FunctionSetPrototype) {
217   HandleScope scope(isolate);
218   DCHECK(args.length() == 2);
219
220   CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0);
221   CONVERT_ARG_HANDLE_CHECKED(Object, value, 1);
222   RUNTIME_ASSERT(fun->should_have_prototype());
223   RETURN_FAILURE_ON_EXCEPTION(isolate,
224                               Accessors::FunctionSetPrototype(fun, value));
225   return args[0];  // return TOS
226 }
227
228
229 RUNTIME_FUNCTION(Runtime_FunctionIsAPIFunction) {
230   SealHandleScope shs(isolate);
231   DCHECK(args.length() == 1);
232
233   CONVERT_ARG_CHECKED(JSFunction, f, 0);
234   return isolate->heap()->ToBoolean(f->shared()->IsApiFunction());
235 }
236
237
238 RUNTIME_FUNCTION(Runtime_FunctionIsBuiltin) {
239   SealHandleScope shs(isolate);
240   DCHECK(args.length() == 1);
241
242   CONVERT_ARG_CHECKED(JSFunction, f, 0);
243   return isolate->heap()->ToBoolean(f->IsBuiltin());
244 }
245
246
247 RUNTIME_FUNCTION(Runtime_SetCode) {
248   HandleScope scope(isolate);
249   DCHECK(args.length() == 2);
250
251   CONVERT_ARG_HANDLE_CHECKED(JSFunction, target, 0);
252   CONVERT_ARG_HANDLE_CHECKED(JSFunction, source, 1);
253
254   Handle<SharedFunctionInfo> target_shared(target->shared());
255   Handle<SharedFunctionInfo> source_shared(source->shared());
256   RUNTIME_ASSERT(!source_shared->bound());
257
258   if (!Compiler::EnsureCompiled(source, KEEP_EXCEPTION)) {
259     return isolate->heap()->exception();
260   }
261
262   // Mark both, the source and the target, as un-flushable because the
263   // shared unoptimized code makes them impossible to enqueue in a list.
264   DCHECK(target_shared->code()->gc_metadata() == NULL);
265   DCHECK(source_shared->code()->gc_metadata() == NULL);
266   target_shared->set_dont_flush(true);
267   source_shared->set_dont_flush(true);
268
269   // Set the code, scope info, formal parameter count, and the length
270   // of the target shared function info.
271   target_shared->ReplaceCode(source_shared->code());
272   target_shared->set_scope_info(source_shared->scope_info());
273   target_shared->set_length(source_shared->length());
274   target_shared->set_feedback_vector(source_shared->feedback_vector());
275   target_shared->set_internal_formal_parameter_count(
276       source_shared->internal_formal_parameter_count());
277   target_shared->set_script(source_shared->script());
278   target_shared->set_start_position_and_type(
279       source_shared->start_position_and_type());
280   target_shared->set_end_position(source_shared->end_position());
281   bool was_native = target_shared->native();
282   target_shared->set_compiler_hints(source_shared->compiler_hints());
283   target_shared->set_opt_count_and_bailout_reason(
284       source_shared->opt_count_and_bailout_reason());
285   target_shared->set_native(was_native);
286   target_shared->set_profiler_ticks(source_shared->profiler_ticks());
287
288   // Set the code of the target function.
289   target->ReplaceCode(source_shared->code());
290   DCHECK(target->next_function_link()->IsUndefined());
291
292   // Make sure we get a fresh copy of the literal vector to avoid cross
293   // context contamination.
294   Handle<Context> context(source->context());
295   int number_of_literals = source->NumberOfLiterals();
296   Handle<FixedArray> literals =
297       isolate->factory()->NewFixedArray(number_of_literals, TENURED);
298   target->set_context(*context);
299   target->set_literals(*literals);
300
301   if (isolate->logger()->is_logging_code_events() ||
302       isolate->cpu_profiler()->is_profiling()) {
303     isolate->logger()->LogExistingFunction(source_shared,
304                                            Handle<Code>(source_shared->code()));
305   }
306
307   return *target;
308 }
309
310
311 // Set the native flag on the function.
312 // This is used to decide if we should transform null and undefined
313 // into the global object when doing call and apply.
314 RUNTIME_FUNCTION(Runtime_SetNativeFlag) {
315   SealHandleScope shs(isolate);
316   RUNTIME_ASSERT(args.length() == 1);
317
318   CONVERT_ARG_CHECKED(Object, object, 0);
319
320   if (object->IsJSFunction()) {
321     JSFunction* func = JSFunction::cast(object);
322     func->shared()->set_native(true);
323   }
324   return isolate->heap()->undefined_value();
325 }
326
327
328 RUNTIME_FUNCTION(Runtime_IsConstructor) {
329   HandleScope handles(isolate);
330   RUNTIME_ASSERT(args.length() == 1);
331
332   CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
333
334   // TODO(caitp): implement this in a better/simpler way, allow inlining via TF
335   if (object->IsJSFunction()) {
336     Handle<JSFunction> func = Handle<JSFunction>::cast(object);
337     bool should_have_prototype = func->should_have_prototype();
338     if (func->shared()->bound()) {
339       Handle<FixedArray> bound_args =
340           Handle<FixedArray>(FixedArray::cast(func->function_bindings()));
341       Handle<Object> bound_function(
342           JSReceiver::cast(bound_args->get(JSFunction::kBoundFunctionIndex)),
343           isolate);
344       if (bound_function->IsJSFunction()) {
345         Handle<JSFunction> bound = Handle<JSFunction>::cast(bound_function);
346         DCHECK(!bound->shared()->bound());
347         should_have_prototype = bound->should_have_prototype();
348       }
349     }
350     return isolate->heap()->ToBoolean(should_have_prototype);
351   }
352   return isolate->heap()->false_value();
353 }
354
355
356 RUNTIME_FUNCTION(Runtime_SetInlineBuiltinFlag) {
357   SealHandleScope shs(isolate);
358   RUNTIME_ASSERT(args.length() == 1);
359   CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
360
361   if (object->IsJSFunction()) {
362     JSFunction* func = JSFunction::cast(*object);
363     func->shared()->set_inline_builtin(true);
364   }
365   return isolate->heap()->undefined_value();
366 }
367
368
369 // Find the arguments of the JavaScript function invocation that called
370 // into C++ code. Collect these in a newly allocated array of handles (possibly
371 // prefixed by a number of empty handles).
372 static SmartArrayPointer<Handle<Object> > GetCallerArguments(Isolate* isolate,
373                                                              int prefix_argc,
374                                                              int* total_argc) {
375   // Find frame containing arguments passed to the caller.
376   JavaScriptFrameIterator it(isolate);
377   JavaScriptFrame* frame = it.frame();
378   List<JSFunction*> functions(2);
379   frame->GetFunctions(&functions);
380   if (functions.length() > 1) {
381     int inlined_jsframe_index = functions.length() - 1;
382     JSFunction* inlined_function = functions[inlined_jsframe_index];
383     SlotRefValueBuilder slot_refs(
384         frame, inlined_jsframe_index,
385         inlined_function->shared()->internal_formal_parameter_count());
386
387     int args_count = slot_refs.args_length();
388
389     *total_argc = prefix_argc + args_count;
390     SmartArrayPointer<Handle<Object> > param_data(
391         NewArray<Handle<Object> >(*total_argc));
392     slot_refs.Prepare(isolate);
393     for (int i = 0; i < args_count; i++) {
394       Handle<Object> val = slot_refs.GetNext(isolate, 0);
395       param_data[prefix_argc + i] = val;
396     }
397     slot_refs.Finish(isolate);
398
399     return param_data;
400   } else {
401     it.AdvanceToArgumentsFrame();
402     frame = it.frame();
403     int args_count = frame->ComputeParametersCount();
404
405     *total_argc = prefix_argc + args_count;
406     SmartArrayPointer<Handle<Object> > param_data(
407         NewArray<Handle<Object> >(*total_argc));
408     for (int i = 0; i < args_count; i++) {
409       Handle<Object> val = Handle<Object>(frame->GetParameter(i), isolate);
410       param_data[prefix_argc + i] = val;
411     }
412     return param_data;
413   }
414 }
415
416
417 RUNTIME_FUNCTION(Runtime_FunctionBindArguments) {
418   HandleScope scope(isolate);
419   DCHECK(args.length() == 4);
420   CONVERT_ARG_HANDLE_CHECKED(JSFunction, bound_function, 0);
421   CONVERT_ARG_HANDLE_CHECKED(Object, bindee, 1);
422   CONVERT_ARG_HANDLE_CHECKED(Object, this_object, 2);
423   CONVERT_NUMBER_ARG_HANDLE_CHECKED(new_length, 3);
424
425   // TODO(lrn): Create bound function in C++ code from premade shared info.
426   bound_function->shared()->set_bound(true);
427   // Get all arguments of calling function (Function.prototype.bind).
428   int argc = 0;
429   SmartArrayPointer<Handle<Object> > arguments =
430       GetCallerArguments(isolate, 0, &argc);
431   // Don't count the this-arg.
432   if (argc > 0) {
433     RUNTIME_ASSERT(arguments[0].is_identical_to(this_object));
434     argc--;
435   } else {
436     RUNTIME_ASSERT(this_object->IsUndefined());
437   }
438   // Initialize array of bindings (function, this, and any existing arguments
439   // if the function was already bound).
440   Handle<FixedArray> new_bindings;
441   int i;
442   if (bindee->IsJSFunction() && JSFunction::cast(*bindee)->shared()->bound()) {
443     Handle<FixedArray> old_bindings(
444         JSFunction::cast(*bindee)->function_bindings());
445     RUNTIME_ASSERT(old_bindings->length() > JSFunction::kBoundFunctionIndex);
446     new_bindings =
447         isolate->factory()->NewFixedArray(old_bindings->length() + argc);
448     bindee = Handle<Object>(old_bindings->get(JSFunction::kBoundFunctionIndex),
449                             isolate);
450     i = 0;
451     for (int n = old_bindings->length(); i < n; i++) {
452       new_bindings->set(i, old_bindings->get(i));
453     }
454   } else {
455     int array_size = JSFunction::kBoundArgumentsStartIndex + argc;
456     new_bindings = isolate->factory()->NewFixedArray(array_size);
457     new_bindings->set(JSFunction::kBoundFunctionIndex, *bindee);
458     new_bindings->set(JSFunction::kBoundThisIndex, *this_object);
459     i = 2;
460   }
461   // Copy arguments, skipping the first which is "this_arg".
462   for (int j = 0; j < argc; j++, i++) {
463     new_bindings->set(i, *arguments[j + 1]);
464   }
465   new_bindings->set_map_no_write_barrier(isolate->heap()->fixed_array_map());
466   bound_function->set_function_bindings(*new_bindings);
467
468   // Update length. Have to remove the prototype first so that map migration
469   // is happy about the number of fields.
470   RUNTIME_ASSERT(bound_function->RemovePrototype());
471   Handle<Map> bound_function_map(
472       isolate->native_context()->bound_function_map());
473   JSObject::MigrateToMap(bound_function, bound_function_map);
474   Handle<String> length_string = isolate->factory()->length_string();
475   PropertyAttributes attr =
476       static_cast<PropertyAttributes>(DONT_DELETE | DONT_ENUM | READ_ONLY);
477   RETURN_FAILURE_ON_EXCEPTION(
478       isolate, JSObject::SetOwnPropertyIgnoreAttributes(
479                    bound_function, length_string, new_length, attr));
480   return *bound_function;
481 }
482
483
484 RUNTIME_FUNCTION(Runtime_BoundFunctionGetBindings) {
485   HandleScope handles(isolate);
486   DCHECK(args.length() == 1);
487   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, callable, 0);
488   if (callable->IsJSFunction()) {
489     Handle<JSFunction> function = Handle<JSFunction>::cast(callable);
490     if (function->shared()->bound()) {
491       RUNTIME_ASSERT(function->function_bindings()->IsFixedArray());
492       Handle<FixedArray> bindings(function->function_bindings());
493       return *isolate->factory()->NewJSArrayWithElements(bindings);
494     }
495   }
496   return isolate->heap()->undefined_value();
497 }
498
499
500 RUNTIME_FUNCTION(Runtime_NewObjectFromBound) {
501   HandleScope scope(isolate);
502   DCHECK(args.length() == 1);
503   // First argument is a function to use as a constructor.
504   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
505   RUNTIME_ASSERT(function->shared()->bound());
506
507   // The argument is a bound function. Extract its bound arguments
508   // and callable.
509   Handle<FixedArray> bound_args =
510       Handle<FixedArray>(FixedArray::cast(function->function_bindings()));
511   int bound_argc = bound_args->length() - JSFunction::kBoundArgumentsStartIndex;
512   Handle<Object> bound_function(
513       JSReceiver::cast(bound_args->get(JSFunction::kBoundFunctionIndex)),
514       isolate);
515   DCHECK(!bound_function->IsJSFunction() ||
516          !Handle<JSFunction>::cast(bound_function)->shared()->bound());
517
518   int total_argc = 0;
519   SmartArrayPointer<Handle<Object> > param_data =
520       GetCallerArguments(isolate, bound_argc, &total_argc);
521   for (int i = 0; i < bound_argc; i++) {
522     param_data[i] = Handle<Object>(
523         bound_args->get(JSFunction::kBoundArgumentsStartIndex + i), isolate);
524   }
525
526   if (!bound_function->IsJSFunction()) {
527     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
528         isolate, bound_function,
529         Execution::TryGetConstructorDelegate(isolate, bound_function));
530   }
531   DCHECK(bound_function->IsJSFunction());
532
533   Handle<Object> result;
534   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
535       isolate, result, Execution::New(Handle<JSFunction>::cast(bound_function),
536                                       total_argc, param_data.get()));
537   return *result;
538 }
539
540
541 RUNTIME_FUNCTION(Runtime_Call) {
542   HandleScope scope(isolate);
543   DCHECK(args.length() >= 2);
544   int argc = args.length() - 2;
545   CONVERT_ARG_CHECKED(JSReceiver, fun, argc + 1);
546   Object* receiver = args[0];
547
548   // If there are too many arguments, allocate argv via malloc.
549   const int argv_small_size = 10;
550   Handle<Object> argv_small_buffer[argv_small_size];
551   SmartArrayPointer<Handle<Object> > argv_large_buffer;
552   Handle<Object>* argv = argv_small_buffer;
553   if (argc > argv_small_size) {
554     argv = new Handle<Object>[argc];
555     if (argv == NULL) return isolate->StackOverflow();
556     argv_large_buffer = SmartArrayPointer<Handle<Object> >(argv);
557   }
558
559   for (int i = 0; i < argc; ++i) {
560     argv[i] = Handle<Object>(args[1 + i], isolate);
561   }
562
563   Handle<JSReceiver> hfun(fun);
564   Handle<Object> hreceiver(receiver, isolate);
565   Handle<Object> result;
566   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
567       isolate, result,
568       Execution::Call(isolate, hfun, hreceiver, argc, argv, true));
569   return *result;
570 }
571
572
573 RUNTIME_FUNCTION(Runtime_Apply) {
574   HandleScope scope(isolate);
575   DCHECK(args.length() == 5);
576   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, fun, 0);
577   CONVERT_ARG_HANDLE_CHECKED(Object, receiver, 1);
578   CONVERT_ARG_HANDLE_CHECKED(JSObject, arguments, 2);
579   CONVERT_INT32_ARG_CHECKED(offset, 3);
580   CONVERT_INT32_ARG_CHECKED(argc, 4);
581   RUNTIME_ASSERT(offset >= 0);
582   // Loose upper bound to allow fuzzing. We'll most likely run out of
583   // stack space before hitting this limit.
584   static int kMaxArgc = 1000000;
585   RUNTIME_ASSERT(argc >= 0 && argc <= kMaxArgc);
586
587   // If there are too many arguments, allocate argv via malloc.
588   const int argv_small_size = 10;
589   Handle<Object> argv_small_buffer[argv_small_size];
590   SmartArrayPointer<Handle<Object> > argv_large_buffer;
591   Handle<Object>* argv = argv_small_buffer;
592   if (argc > argv_small_size) {
593     argv = new Handle<Object>[argc];
594     if (argv == NULL) return isolate->StackOverflow();
595     argv_large_buffer = SmartArrayPointer<Handle<Object> >(argv);
596   }
597
598   for (int i = 0; i < argc; ++i) {
599     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
600         isolate, argv[i], Object::GetElement(isolate, arguments, offset + i));
601   }
602
603   Handle<Object> result;
604   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
605       isolate, result,
606       Execution::Call(isolate, fun, receiver, argc, argv, true));
607   return *result;
608 }
609
610
611 RUNTIME_FUNCTION(Runtime_GetFunctionDelegate) {
612   HandleScope scope(isolate);
613   DCHECK(args.length() == 1);
614   CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
615   RUNTIME_ASSERT(!object->IsJSFunction());
616   return *Execution::GetFunctionDelegate(isolate, object);
617 }
618
619
620 RUNTIME_FUNCTION(Runtime_GetConstructorDelegate) {
621   HandleScope scope(isolate);
622   DCHECK(args.length() == 1);
623   CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
624   RUNTIME_ASSERT(!object->IsJSFunction());
625   return *Execution::GetConstructorDelegate(isolate, object);
626 }
627
628
629 RUNTIME_FUNCTION(Runtime_CallFunction) {
630   SealHandleScope shs(isolate);
631   return __RT_impl_Runtime_Call(args, isolate);
632 }
633
634
635 RUNTIME_FUNCTION(Runtime_IsConstructCall) {
636   SealHandleScope shs(isolate);
637   DCHECK(args.length() == 0);
638   JavaScriptFrameIterator it(isolate);
639   JavaScriptFrame* frame = it.frame();
640   return isolate->heap()->ToBoolean(frame->IsConstructor());
641 }
642
643
644 RUNTIME_FUNCTION(Runtime_IsFunction) {
645   SealHandleScope shs(isolate);
646   DCHECK(args.length() == 1);
647   CONVERT_ARG_CHECKED(Object, obj, 0);
648   return isolate->heap()->ToBoolean(obj->IsJSFunction());
649 }
650 }
651 }  // namespace v8::internal