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