blob: d424a9ebfeb262592044d6712a8498e20c7d19c7 [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 Murdoch097c5b22016-05-18 11:27:45 +010058 if (function->IsJSFunction()) {
59 Handle<Object> script(
60 Handle<JSFunction>::cast(function)->shared()->script(), isolate);
61 if (script->IsScript()) {
62 return *Script::GetWrapper(Handle<Script>::cast(script));
63 }
64 }
65 return isolate->heap()->undefined_value();
Emily Bernierd0a1eb72015-03-24 16:35:39 -040066}
67
68
69RUNTIME_FUNCTION(Runtime_FunctionGetSourceCode) {
70 HandleScope scope(isolate);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000071 DCHECK_EQ(1, args.length());
72 CONVERT_ARG_HANDLE_CHECKED(JSReceiver, function, 0);
Ben Murdoch097c5b22016-05-18 11:27:45 +010073 if (function->IsJSFunction()) {
74 return *Handle<JSFunction>::cast(function)->shared()->GetSourceCode();
75 }
76 return isolate->heap()->undefined_value();
Emily Bernierd0a1eb72015-03-24 16:35:39 -040077}
78
79
80RUNTIME_FUNCTION(Runtime_FunctionGetScriptSourcePosition) {
81 SealHandleScope shs(isolate);
82 DCHECK(args.length() == 1);
83
84 CONVERT_ARG_CHECKED(JSFunction, fun, 0);
85 int pos = fun->shared()->start_position();
86 return Smi::FromInt(pos);
87}
88
89
90RUNTIME_FUNCTION(Runtime_FunctionGetPositionForOffset) {
91 SealHandleScope shs(isolate);
92 DCHECK(args.length() == 2);
93
Ben Murdoch097c5b22016-05-18 11:27:45 +010094 CONVERT_ARG_CHECKED(AbstractCode, abstract_code, 0);
Emily Bernierd0a1eb72015-03-24 16:35:39 -040095 CONVERT_NUMBER_CHECKED(int, offset, Int32, args[1]);
Ben Murdoch097c5b22016-05-18 11:27:45 +010096 return Smi::FromInt(abstract_code->SourcePosition(offset));
Emily Bernierd0a1eb72015-03-24 16:35:39 -040097}
98
99
100RUNTIME_FUNCTION(Runtime_FunctionSetInstanceClassName) {
101 SealHandleScope shs(isolate);
102 DCHECK(args.length() == 2);
103
104 CONVERT_ARG_CHECKED(JSFunction, fun, 0);
105 CONVERT_ARG_CHECKED(String, name, 1);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000106 fun->shared()->set_instance_class_name(name);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400107 return isolate->heap()->undefined_value();
108}
109
110
111RUNTIME_FUNCTION(Runtime_FunctionSetLength) {
112 SealHandleScope shs(isolate);
113 DCHECK(args.length() == 2);
114
115 CONVERT_ARG_CHECKED(JSFunction, fun, 0);
116 CONVERT_SMI_ARG_CHECKED(length, 1);
117 RUNTIME_ASSERT((length & 0xC0000000) == 0xC0000000 ||
118 (length & 0xC0000000) == 0x0);
119 fun->shared()->set_length(length);
120 return isolate->heap()->undefined_value();
121}
122
123
124RUNTIME_FUNCTION(Runtime_FunctionSetPrototype) {
125 HandleScope scope(isolate);
126 DCHECK(args.length() == 2);
127
128 CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0);
129 CONVERT_ARG_HANDLE_CHECKED(Object, value, 1);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000130 RUNTIME_ASSERT(fun->IsConstructor());
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400131 RETURN_FAILURE_ON_EXCEPTION(isolate,
132 Accessors::FunctionSetPrototype(fun, value));
133 return args[0]; // return TOS
134}
135
136
137RUNTIME_FUNCTION(Runtime_FunctionIsAPIFunction) {
138 SealHandleScope shs(isolate);
139 DCHECK(args.length() == 1);
140
141 CONVERT_ARG_CHECKED(JSFunction, f, 0);
142 return isolate->heap()->ToBoolean(f->shared()->IsApiFunction());
143}
144
145
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400146RUNTIME_FUNCTION(Runtime_SetCode) {
147 HandleScope scope(isolate);
148 DCHECK(args.length() == 2);
149
150 CONVERT_ARG_HANDLE_CHECKED(JSFunction, target, 0);
151 CONVERT_ARG_HANDLE_CHECKED(JSFunction, source, 1);
152
153 Handle<SharedFunctionInfo> target_shared(target->shared());
154 Handle<SharedFunctionInfo> source_shared(source->shared());
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400155
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000156 if (!Compiler::Compile(source, KEEP_EXCEPTION)) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400157 return isolate->heap()->exception();
158 }
159
160 // Mark both, the source and the target, as un-flushable because the
161 // shared unoptimized code makes them impossible to enqueue in a list.
162 DCHECK(target_shared->code()->gc_metadata() == NULL);
163 DCHECK(source_shared->code()->gc_metadata() == NULL);
164 target_shared->set_dont_flush(true);
165 source_shared->set_dont_flush(true);
166
167 // Set the code, scope info, formal parameter count, and the length
168 // of the target shared function info.
169 target_shared->ReplaceCode(source_shared->code());
Ben Murdoch097c5b22016-05-18 11:27:45 +0100170 if (source_shared->HasBytecodeArray()) {
171 target_shared->set_function_data(source_shared->bytecode_array());
172 }
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400173 target_shared->set_scope_info(source_shared->scope_info());
174 target_shared->set_length(source_shared->length());
175 target_shared->set_feedback_vector(source_shared->feedback_vector());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000176 target_shared->set_internal_formal_parameter_count(
177 source_shared->internal_formal_parameter_count());
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400178 target_shared->set_start_position_and_type(
179 source_shared->start_position_and_type());
180 target_shared->set_end_position(source_shared->end_position());
181 bool was_native = target_shared->native();
182 target_shared->set_compiler_hints(source_shared->compiler_hints());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000183 target_shared->set_opt_count_and_bailout_reason(
184 source_shared->opt_count_and_bailout_reason());
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400185 target_shared->set_native(was_native);
186 target_shared->set_profiler_ticks(source_shared->profiler_ticks());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000187 SharedFunctionInfo::SetScript(
188 target_shared, Handle<Object>(source_shared->script(), isolate));
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400189
190 // Set the code of the target function.
191 target->ReplaceCode(source_shared->code());
192 DCHECK(target->next_function_link()->IsUndefined());
193
194 // Make sure we get a fresh copy of the literal vector to avoid cross
195 // context contamination.
196 Handle<Context> context(source->context());
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400197 target->set_context(*context);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000198
199 int number_of_literals = source->NumberOfLiterals();
200 Handle<LiteralsArray> literals =
201 LiteralsArray::New(isolate, handle(target_shared->feedback_vector()),
202 number_of_literals, TENURED);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400203 target->set_literals(*literals);
204
205 if (isolate->logger()->is_logging_code_events() ||
206 isolate->cpu_profiler()->is_profiling()) {
207 isolate->logger()->LogExistingFunction(source_shared,
208 Handle<Code>(source_shared->code()));
209 }
210
211 return *target;
212}
213
214
215// Set the native flag on the function.
216// This is used to decide if we should transform null and undefined
217// into the global object when doing call and apply.
218RUNTIME_FUNCTION(Runtime_SetNativeFlag) {
219 SealHandleScope shs(isolate);
220 RUNTIME_ASSERT(args.length() == 1);
221
222 CONVERT_ARG_CHECKED(Object, object, 0);
223
224 if (object->IsJSFunction()) {
225 JSFunction* func = JSFunction::cast(object);
226 func->shared()->set_native(true);
227 }
228 return isolate->heap()->undefined_value();
229}
230
231
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000232RUNTIME_FUNCTION(Runtime_IsConstructor) {
233 SealHandleScope shs(isolate);
234 DCHECK_EQ(1, args.length());
235 CONVERT_ARG_CHECKED(Object, object, 0);
236 return isolate->heap()->ToBoolean(object->IsConstructor());
237}
238
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000239RUNTIME_FUNCTION(Runtime_SetForceInlineFlag) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400240 SealHandleScope shs(isolate);
241 RUNTIME_ASSERT(args.length() == 1);
242 CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
243
244 if (object->IsJSFunction()) {
245 JSFunction* func = JSFunction::cast(*object);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000246 func->shared()->set_force_inline(true);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400247 }
248 return isolate->heap()->undefined_value();
249}
250
251
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400252RUNTIME_FUNCTION(Runtime_Call) {
253 HandleScope scope(isolate);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000254 DCHECK_LE(2, args.length());
255 int const argc = args.length() - 2;
256 CONVERT_ARG_HANDLE_CHECKED(JSReceiver, target, 0);
257 CONVERT_ARG_HANDLE_CHECKED(Object, receiver, 1);
258 ScopedVector<Handle<Object>> argv(argc);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400259 for (int i = 0; i < argc; ++i) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000260 argv[i] = args.at<Object>(2 + i);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400261 }
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400262 Handle<Object> result;
263 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
264 isolate, result,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000265 Execution::Call(isolate, target, receiver, argc, argv.start()));
266 return *result;
267}
268
269
270RUNTIME_FUNCTION(Runtime_TailCall) {
271 HandleScope scope(isolate);
272 DCHECK_LE(2, args.length());
273 int const argc = args.length() - 2;
274 CONVERT_ARG_HANDLE_CHECKED(JSReceiver, target, 0);
275 CONVERT_ARG_HANDLE_CHECKED(Object, receiver, 1);
276 ScopedVector<Handle<Object>> argv(argc);
277 for (int i = 0; i < argc; ++i) {
278 argv[i] = args.at<Object>(2 + i);
279 }
280 Handle<Object> result;
281 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
282 isolate, result,
283 Execution::Call(isolate, target, receiver, argc, argv.start()));
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400284 return *result;
285}
286
287
288RUNTIME_FUNCTION(Runtime_Apply) {
289 HandleScope scope(isolate);
290 DCHECK(args.length() == 5);
291 CONVERT_ARG_HANDLE_CHECKED(JSReceiver, fun, 0);
292 CONVERT_ARG_HANDLE_CHECKED(Object, receiver, 1);
293 CONVERT_ARG_HANDLE_CHECKED(JSObject, arguments, 2);
294 CONVERT_INT32_ARG_CHECKED(offset, 3);
295 CONVERT_INT32_ARG_CHECKED(argc, 4);
296 RUNTIME_ASSERT(offset >= 0);
297 // Loose upper bound to allow fuzzing. We'll most likely run out of
298 // stack space before hitting this limit.
299 static int kMaxArgc = 1000000;
300 RUNTIME_ASSERT(argc >= 0 && argc <= kMaxArgc);
301
302 // If there are too many arguments, allocate argv via malloc.
303 const int argv_small_size = 10;
304 Handle<Object> argv_small_buffer[argv_small_size];
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000305 base::SmartArrayPointer<Handle<Object> > argv_large_buffer;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400306 Handle<Object>* argv = argv_small_buffer;
307 if (argc > argv_small_size) {
308 argv = new Handle<Object>[argc];
309 if (argv == NULL) return isolate->StackOverflow();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000310 argv_large_buffer = base::SmartArrayPointer<Handle<Object> >(argv);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400311 }
312
313 for (int i = 0; i < argc; ++i) {
314 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
315 isolate, argv[i], Object::GetElement(isolate, arguments, offset + i));
316 }
317
318 Handle<Object> result;
319 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000320 isolate, result, Execution::Call(isolate, fun, receiver, argc, argv));
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400321 return *result;
322}
323
324
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000325// ES6 section 9.2.1.2, OrdinaryCallBindThis for sloppy callee.
326RUNTIME_FUNCTION(Runtime_ConvertReceiver) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400327 HandleScope scope(isolate);
328 DCHECK(args.length() == 1);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000329 CONVERT_ARG_HANDLE_CHECKED(Object, receiver, 0);
330 if (receiver->IsNull() || receiver->IsUndefined()) {
331 return isolate->global_proxy();
332 }
333 return *Object::ToObject(isolate, receiver).ToHandleChecked();
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400334}
335
336
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000337RUNTIME_FUNCTION(Runtime_IsFunction) {
338 SealHandleScope shs(isolate);
339 DCHECK_EQ(1, args.length());
340 CONVERT_ARG_CHECKED(Object, object, 0);
341 return isolate->heap()->ToBoolean(object->IsFunction());
342}
343
344
345RUNTIME_FUNCTION(Runtime_ThrowStrongModeTooFewArguments) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400346 HandleScope scope(isolate);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400347 DCHECK(args.length() == 0);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000348 THROW_NEW_ERROR_RETURN_FAILURE(isolate,
349 NewTypeError(MessageTemplate::kStrongArity));
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400350}
351
352
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000353RUNTIME_FUNCTION(Runtime_FunctionToString) {
354 HandleScope scope(isolate);
355 DCHECK_EQ(1, args.length());
356 CONVERT_ARG_HANDLE_CHECKED(JSReceiver, function, 0);
357 return function->IsJSBoundFunction()
358 ? *JSBoundFunction::ToString(
359 Handle<JSBoundFunction>::cast(function))
360 : *JSFunction::ToString(Handle<JSFunction>::cast(function));
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400361}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000362
363} // namespace internal
364} // namespace v8