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