blob: befd3370984b7b753c21f6bb6c19c3b58b63d4b0 [file] [log] [blame]
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001// 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
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005#include "src/runtime/runtime-utils.h"
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006
7#include "src/accessors.h"
8#include "src/arguments.h"
9#include "src/compiler.h"
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010#include "src/frames-inl.h"
11#include "src/isolate-inl.h"
12#include "src/messages.h"
13#include "src/profiler/cpu-profiler.h"
Emily Bernierd0a1eb72015-03-24 16:35:39 -040014
15namespace v8 {
16namespace internal {
17
Emily Bernierd0a1eb72015-03-24 16:35:39 -040018RUNTIME_FUNCTION(Runtime_FunctionGetName) {
19 SealHandleScope shs(isolate);
20 DCHECK(args.length() == 1);
21
22 CONVERT_ARG_CHECKED(JSFunction, f, 0);
23 return f->shared()->name();
24}
25
26
Emily Bernierd0a1eb72015-03-24 16:35:39 -040027RUNTIME_FUNCTION(Runtime_FunctionSetName) {
28 HandleScope scope(isolate);
29 DCHECK(args.length() == 2);
30
31 CONVERT_ARG_HANDLE_CHECKED(JSFunction, f, 0);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000032 CONVERT_ARG_HANDLE_CHECKED(String, name, 1);
Emily Bernierd0a1eb72015-03-24 16:35:39 -040033
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000034 name = String::Flatten(name);
35 f->shared()->set_name(*name);
Emily Bernierd0a1eb72015-03-24 16:35:39 -040036 return isolate->heap()->undefined_value();
37}
38
39
Emily Bernierd0a1eb72015-03-24 16:35:39 -040040RUNTIME_FUNCTION(Runtime_FunctionRemovePrototype) {
41 SealHandleScope shs(isolate);
42 DCHECK(args.length() == 1);
43
44 CONVERT_ARG_CHECKED(JSFunction, f, 0);
45 RUNTIME_ASSERT(f->RemovePrototype());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000046 f->shared()->set_construct_stub(
47 *isolate->builtins()->ConstructedNonConstructable());
Emily Bernierd0a1eb72015-03-24 16:35:39 -040048
49 return isolate->heap()->undefined_value();
50}
51
52
53RUNTIME_FUNCTION(Runtime_FunctionGetScript) {
54 HandleScope scope(isolate);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000055 DCHECK_EQ(1, args.length());
56 CONVERT_ARG_HANDLE_CHECKED(JSReceiver, function, 0);
Emily Bernierd0a1eb72015-03-24 16:35:39 -040057
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000058 if (function->IsJSBoundFunction()) return isolate->heap()->undefined_value();
59 Handle<Object> script(Handle<JSFunction>::cast(function)->shared()->script(),
60 isolate);
Emily Bernierd0a1eb72015-03-24 16:35:39 -040061 if (!script->IsScript()) return isolate->heap()->undefined_value();
Emily Bernierd0a1eb72015-03-24 16:35:39 -040062 return *Script::GetWrapper(Handle<Script>::cast(script));
63}
64
65
66RUNTIME_FUNCTION(Runtime_FunctionGetSourceCode) {
67 HandleScope scope(isolate);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000068 DCHECK_EQ(1, args.length());
69 CONVERT_ARG_HANDLE_CHECKED(JSReceiver, function, 0);
70 if (function->IsJSBoundFunction()) return isolate->heap()->undefined_value();
71 return *Handle<JSFunction>::cast(function)->shared()->GetSourceCode();
Emily Bernierd0a1eb72015-03-24 16:35:39 -040072}
73
74
75RUNTIME_FUNCTION(Runtime_FunctionGetScriptSourcePosition) {
76 SealHandleScope shs(isolate);
77 DCHECK(args.length() == 1);
78
79 CONVERT_ARG_CHECKED(JSFunction, fun, 0);
80 int pos = fun->shared()->start_position();
81 return Smi::FromInt(pos);
82}
83
84
85RUNTIME_FUNCTION(Runtime_FunctionGetPositionForOffset) {
86 SealHandleScope shs(isolate);
87 DCHECK(args.length() == 2);
88
89 CONVERT_ARG_CHECKED(Code, code, 0);
90 CONVERT_NUMBER_CHECKED(int, offset, Int32, args[1]);
91
92 RUNTIME_ASSERT(0 <= offset && offset < code->Size());
93
94 Address pc = code->address() + offset;
95 return Smi::FromInt(code->SourcePosition(pc));
96}
97
98
99RUNTIME_FUNCTION(Runtime_FunctionSetInstanceClassName) {
100 SealHandleScope shs(isolate);
101 DCHECK(args.length() == 2);
102
103 CONVERT_ARG_CHECKED(JSFunction, fun, 0);
104 CONVERT_ARG_CHECKED(String, name, 1);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000105 fun->shared()->set_instance_class_name(name);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400106 return isolate->heap()->undefined_value();
107}
108
109
110RUNTIME_FUNCTION(Runtime_FunctionSetLength) {
111 SealHandleScope shs(isolate);
112 DCHECK(args.length() == 2);
113
114 CONVERT_ARG_CHECKED(JSFunction, fun, 0);
115 CONVERT_SMI_ARG_CHECKED(length, 1);
116 RUNTIME_ASSERT((length & 0xC0000000) == 0xC0000000 ||
117 (length & 0xC0000000) == 0x0);
118 fun->shared()->set_length(length);
119 return isolate->heap()->undefined_value();
120}
121
122
123RUNTIME_FUNCTION(Runtime_FunctionSetPrototype) {
124 HandleScope scope(isolate);
125 DCHECK(args.length() == 2);
126
127 CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0);
128 CONVERT_ARG_HANDLE_CHECKED(Object, value, 1);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000129 RUNTIME_ASSERT(fun->IsConstructor());
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400130 RETURN_FAILURE_ON_EXCEPTION(isolate,
131 Accessors::FunctionSetPrototype(fun, value));
132 return args[0]; // return TOS
133}
134
135
136RUNTIME_FUNCTION(Runtime_FunctionIsAPIFunction) {
137 SealHandleScope shs(isolate);
138 DCHECK(args.length() == 1);
139
140 CONVERT_ARG_CHECKED(JSFunction, f, 0);
141 return isolate->heap()->ToBoolean(f->shared()->IsApiFunction());
142}
143
144
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400145RUNTIME_FUNCTION(Runtime_SetCode) {
146 HandleScope scope(isolate);
147 DCHECK(args.length() == 2);
148
149 CONVERT_ARG_HANDLE_CHECKED(JSFunction, target, 0);
150 CONVERT_ARG_HANDLE_CHECKED(JSFunction, source, 1);
151
152 Handle<SharedFunctionInfo> target_shared(target->shared());
153 Handle<SharedFunctionInfo> source_shared(source->shared());
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400154
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000155 if (!Compiler::Compile(source, KEEP_EXCEPTION)) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400156 return isolate->heap()->exception();
157 }
158
159 // Mark both, the source and the target, as un-flushable because the
160 // shared unoptimized code makes them impossible to enqueue in a list.
161 DCHECK(target_shared->code()->gc_metadata() == NULL);
162 DCHECK(source_shared->code()->gc_metadata() == NULL);
163 target_shared->set_dont_flush(true);
164 source_shared->set_dont_flush(true);
165
166 // Set the code, scope info, formal parameter count, and the length
167 // of the target shared function info.
168 target_shared->ReplaceCode(source_shared->code());
169 target_shared->set_scope_info(source_shared->scope_info());
170 target_shared->set_length(source_shared->length());
171 target_shared->set_feedback_vector(source_shared->feedback_vector());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000172 target_shared->set_internal_formal_parameter_count(
173 source_shared->internal_formal_parameter_count());
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400174 target_shared->set_start_position_and_type(
175 source_shared->start_position_and_type());
176 target_shared->set_end_position(source_shared->end_position());
177 bool was_native = target_shared->native();
178 target_shared->set_compiler_hints(source_shared->compiler_hints());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000179 target_shared->set_opt_count_and_bailout_reason(
180 source_shared->opt_count_and_bailout_reason());
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400181 target_shared->set_native(was_native);
182 target_shared->set_profiler_ticks(source_shared->profiler_ticks());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000183 SharedFunctionInfo::SetScript(
184 target_shared, Handle<Object>(source_shared->script(), isolate));
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400185
186 // Set the code of the target function.
187 target->ReplaceCode(source_shared->code());
188 DCHECK(target->next_function_link()->IsUndefined());
189
190 // Make sure we get a fresh copy of the literal vector to avoid cross
191 // context contamination.
192 Handle<Context> context(source->context());
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400193 target->set_context(*context);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000194
195 int number_of_literals = source->NumberOfLiterals();
196 Handle<LiteralsArray> literals =
197 LiteralsArray::New(isolate, handle(target_shared->feedback_vector()),
198 number_of_literals, TENURED);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400199 target->set_literals(*literals);
200
201 if (isolate->logger()->is_logging_code_events() ||
202 isolate->cpu_profiler()->is_profiling()) {
203 isolate->logger()->LogExistingFunction(source_shared,
204 Handle<Code>(source_shared->code()));
205 }
206
207 return *target;
208}
209
210
211// Set the native flag on the function.
212// This is used to decide if we should transform null and undefined
213// into the global object when doing call and apply.
214RUNTIME_FUNCTION(Runtime_SetNativeFlag) {
215 SealHandleScope shs(isolate);
216 RUNTIME_ASSERT(args.length() == 1);
217
218 CONVERT_ARG_CHECKED(Object, object, 0);
219
220 if (object->IsJSFunction()) {
221 JSFunction* func = JSFunction::cast(object);
222 func->shared()->set_native(true);
223 }
224 return isolate->heap()->undefined_value();
225}
226
227
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000228RUNTIME_FUNCTION(Runtime_IsConstructor) {
229 SealHandleScope shs(isolate);
230 DCHECK_EQ(1, args.length());
231 CONVERT_ARG_CHECKED(Object, object, 0);
232 return isolate->heap()->ToBoolean(object->IsConstructor());
233}
234
235
236RUNTIME_FUNCTION(Runtime_SetForceInlineFlag) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400237 SealHandleScope shs(isolate);
238 RUNTIME_ASSERT(args.length() == 1);
239 CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
240
241 if (object->IsJSFunction()) {
242 JSFunction* func = JSFunction::cast(*object);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000243 func->shared()->set_force_inline(true);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400244 }
245 return isolate->heap()->undefined_value();
246}
247
248
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400249RUNTIME_FUNCTION(Runtime_Call) {
250 HandleScope scope(isolate);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000251 DCHECK_LE(2, args.length());
252 int const argc = args.length() - 2;
253 CONVERT_ARG_HANDLE_CHECKED(JSReceiver, target, 0);
254 CONVERT_ARG_HANDLE_CHECKED(Object, receiver, 1);
255 ScopedVector<Handle<Object>> argv(argc);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400256 for (int i = 0; i < argc; ++i) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000257 argv[i] = args.at<Object>(2 + i);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400258 }
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400259 Handle<Object> result;
260 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
261 isolate, result,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000262 Execution::Call(isolate, target, receiver, argc, argv.start()));
263 return *result;
264}
265
266
267RUNTIME_FUNCTION(Runtime_TailCall) {
268 HandleScope scope(isolate);
269 DCHECK_LE(2, args.length());
270 int const argc = args.length() - 2;
271 CONVERT_ARG_HANDLE_CHECKED(JSReceiver, target, 0);
272 CONVERT_ARG_HANDLE_CHECKED(Object, receiver, 1);
273 ScopedVector<Handle<Object>> argv(argc);
274 for (int i = 0; i < argc; ++i) {
275 argv[i] = args.at<Object>(2 + i);
276 }
277 Handle<Object> result;
278 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
279 isolate, result,
280 Execution::Call(isolate, target, receiver, argc, argv.start()));
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400281 return *result;
282}
283
284
285RUNTIME_FUNCTION(Runtime_Apply) {
286 HandleScope scope(isolate);
287 DCHECK(args.length() == 5);
288 CONVERT_ARG_HANDLE_CHECKED(JSReceiver, fun, 0);
289 CONVERT_ARG_HANDLE_CHECKED(Object, receiver, 1);
290 CONVERT_ARG_HANDLE_CHECKED(JSObject, arguments, 2);
291 CONVERT_INT32_ARG_CHECKED(offset, 3);
292 CONVERT_INT32_ARG_CHECKED(argc, 4);
293 RUNTIME_ASSERT(offset >= 0);
294 // Loose upper bound to allow fuzzing. We'll most likely run out of
295 // stack space before hitting this limit.
296 static int kMaxArgc = 1000000;
297 RUNTIME_ASSERT(argc >= 0 && argc <= kMaxArgc);
298
299 // If there are too many arguments, allocate argv via malloc.
300 const int argv_small_size = 10;
301 Handle<Object> argv_small_buffer[argv_small_size];
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000302 base::SmartArrayPointer<Handle<Object> > argv_large_buffer;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400303 Handle<Object>* argv = argv_small_buffer;
304 if (argc > argv_small_size) {
305 argv = new Handle<Object>[argc];
306 if (argv == NULL) return isolate->StackOverflow();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000307 argv_large_buffer = base::SmartArrayPointer<Handle<Object> >(argv);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400308 }
309
310 for (int i = 0; i < argc; ++i) {
311 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
312 isolate, argv[i], Object::GetElement(isolate, arguments, offset + i));
313 }
314
315 Handle<Object> result;
316 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000317 isolate, result, Execution::Call(isolate, fun, receiver, argc, argv));
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400318 return *result;
319}
320
321
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000322// ES6 section 9.2.1.2, OrdinaryCallBindThis for sloppy callee.
323RUNTIME_FUNCTION(Runtime_ConvertReceiver) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400324 HandleScope scope(isolate);
325 DCHECK(args.length() == 1);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000326 CONVERT_ARG_HANDLE_CHECKED(Object, receiver, 0);
327 if (receiver->IsNull() || receiver->IsUndefined()) {
328 return isolate->global_proxy();
329 }
330 return *Object::ToObject(isolate, receiver).ToHandleChecked();
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400331}
332
333
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000334RUNTIME_FUNCTION(Runtime_IsFunction) {
335 SealHandleScope shs(isolate);
336 DCHECK_EQ(1, args.length());
337 CONVERT_ARG_CHECKED(Object, object, 0);
338 return isolate->heap()->ToBoolean(object->IsFunction());
339}
340
341
342RUNTIME_FUNCTION(Runtime_ThrowStrongModeTooFewArguments) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400343 HandleScope scope(isolate);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400344 DCHECK(args.length() == 0);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000345 THROW_NEW_ERROR_RETURN_FAILURE(isolate,
346 NewTypeError(MessageTemplate::kStrongArity));
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400347}
348
349
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000350RUNTIME_FUNCTION(Runtime_FunctionToString) {
351 HandleScope scope(isolate);
352 DCHECK_EQ(1, args.length());
353 CONVERT_ARG_HANDLE_CHECKED(JSReceiver, function, 0);
354 return function->IsJSBoundFunction()
355 ? *JSBoundFunction::ToString(
356 Handle<JSBoundFunction>::cast(function))
357 : *JSFunction::ToString(Handle<JSFunction>::cast(function));
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400358}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000359
360} // namespace internal
361} // namespace v8