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