blob: 3a66869d41d8f341e770091b658fadbe0904f4a6 [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"
Ben Murdochc5610432016-08-08 18:44:38 +010013#include "src/wasm/wasm-module.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) {
Ben Murdochda12d292016-06-02 14:46:10 +010019 HandleScope scope(isolate);
Emily Bernierd0a1eb72015-03-24 16:35:39 -040020 DCHECK(args.length() == 1);
21
Ben Murdochda12d292016-06-02 14:46:10 +010022 CONVERT_ARG_HANDLE_CHECKED(JSReceiver, function, 0);
Ben Murdochc5610432016-08-08 18:44:38 +010023 if (function->IsJSBoundFunction()) {
Ben Murdoch61f157c2016-09-16 13:49:30 +010024 RETURN_RESULT_OR_FAILURE(
25 isolate, JSBoundFunction::GetName(
26 isolate, Handle<JSBoundFunction>::cast(function)));
Ben Murdochda12d292016-06-02 14:46:10 +010027 } else {
Ben Murdoch61f157c2016-09-16 13:49:30 +010028 return *JSFunction::GetName(isolate, Handle<JSFunction>::cast(function));
Ben Murdochda12d292016-06-02 14:46:10 +010029 }
Emily Bernierd0a1eb72015-03-24 16:35:39 -040030}
31
32
Emily Bernierd0a1eb72015-03-24 16:35:39 -040033RUNTIME_FUNCTION(Runtime_FunctionSetName) {
34 HandleScope scope(isolate);
35 DCHECK(args.length() == 2);
36
37 CONVERT_ARG_HANDLE_CHECKED(JSFunction, f, 0);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000038 CONVERT_ARG_HANDLE_CHECKED(String, name, 1);
Emily Bernierd0a1eb72015-03-24 16:35:39 -040039
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000040 name = String::Flatten(name);
41 f->shared()->set_name(*name);
Emily Bernierd0a1eb72015-03-24 16:35:39 -040042 return isolate->heap()->undefined_value();
43}
44
45
Emily Bernierd0a1eb72015-03-24 16:35:39 -040046RUNTIME_FUNCTION(Runtime_FunctionRemovePrototype) {
47 SealHandleScope shs(isolate);
48 DCHECK(args.length() == 1);
49
50 CONVERT_ARG_CHECKED(JSFunction, f, 0);
Ben Murdoch61f157c2016-09-16 13:49:30 +010051 CHECK(f->RemovePrototype());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000052 f->shared()->set_construct_stub(
53 *isolate->builtins()->ConstructedNonConstructable());
Emily Bernierd0a1eb72015-03-24 16:35:39 -040054
55 return isolate->heap()->undefined_value();
56}
57
58
59RUNTIME_FUNCTION(Runtime_FunctionGetScript) {
60 HandleScope scope(isolate);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000061 DCHECK_EQ(1, args.length());
62 CONVERT_ARG_HANDLE_CHECKED(JSReceiver, function, 0);
Emily Bernierd0a1eb72015-03-24 16:35:39 -040063
Ben Murdoch097c5b22016-05-18 11:27:45 +010064 if (function->IsJSFunction()) {
65 Handle<Object> script(
66 Handle<JSFunction>::cast(function)->shared()->script(), isolate);
67 if (script->IsScript()) {
68 return *Script::GetWrapper(Handle<Script>::cast(script));
69 }
70 }
71 return isolate->heap()->undefined_value();
Emily Bernierd0a1eb72015-03-24 16:35:39 -040072}
73
74
75RUNTIME_FUNCTION(Runtime_FunctionGetSourceCode) {
76 HandleScope scope(isolate);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000077 DCHECK_EQ(1, args.length());
78 CONVERT_ARG_HANDLE_CHECKED(JSReceiver, function, 0);
Ben Murdoch097c5b22016-05-18 11:27:45 +010079 if (function->IsJSFunction()) {
80 return *Handle<JSFunction>::cast(function)->shared()->GetSourceCode();
81 }
82 return isolate->heap()->undefined_value();
Emily Bernierd0a1eb72015-03-24 16:35:39 -040083}
84
85
86RUNTIME_FUNCTION(Runtime_FunctionGetScriptSourcePosition) {
87 SealHandleScope shs(isolate);
88 DCHECK(args.length() == 1);
89
90 CONVERT_ARG_CHECKED(JSFunction, fun, 0);
91 int pos = fun->shared()->start_position();
92 return Smi::FromInt(pos);
93}
94
95
96RUNTIME_FUNCTION(Runtime_FunctionGetPositionForOffset) {
97 SealHandleScope shs(isolate);
98 DCHECK(args.length() == 2);
99
Ben Murdoch097c5b22016-05-18 11:27:45 +0100100 CONVERT_ARG_CHECKED(AbstractCode, abstract_code, 0);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400101 CONVERT_NUMBER_CHECKED(int, offset, Int32, args[1]);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100102 return Smi::FromInt(abstract_code->SourcePosition(offset));
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400103}
104
Ben Murdochda12d292016-06-02 14:46:10 +0100105RUNTIME_FUNCTION(Runtime_FunctionGetContextData) {
106 SealHandleScope shs(isolate);
107 DCHECK(args.length() == 1);
108
109 CONVERT_ARG_CHECKED(JSFunction, fun, 0);
110 FixedArray* array = fun->native_context()->embedder_data();
111 return array->get(v8::Context::kDebugIdIndex);
112}
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400113
114RUNTIME_FUNCTION(Runtime_FunctionSetInstanceClassName) {
115 SealHandleScope shs(isolate);
116 DCHECK(args.length() == 2);
117
118 CONVERT_ARG_CHECKED(JSFunction, fun, 0);
119 CONVERT_ARG_CHECKED(String, name, 1);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000120 fun->shared()->set_instance_class_name(name);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400121 return isolate->heap()->undefined_value();
122}
123
124
125RUNTIME_FUNCTION(Runtime_FunctionSetLength) {
126 SealHandleScope shs(isolate);
127 DCHECK(args.length() == 2);
128
129 CONVERT_ARG_CHECKED(JSFunction, fun, 0);
130 CONVERT_SMI_ARG_CHECKED(length, 1);
Ben Murdoch61f157c2016-09-16 13:49:30 +0100131 CHECK((length & 0xC0000000) == 0xC0000000 || (length & 0xC0000000) == 0x0);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400132 fun->shared()->set_length(length);
133 return isolate->heap()->undefined_value();
134}
135
136
137RUNTIME_FUNCTION(Runtime_FunctionSetPrototype) {
138 HandleScope scope(isolate);
139 DCHECK(args.length() == 2);
140
141 CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0);
142 CONVERT_ARG_HANDLE_CHECKED(Object, value, 1);
Ben Murdoch61f157c2016-09-16 13:49:30 +0100143 CHECK(fun->IsConstructor());
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400144 RETURN_FAILURE_ON_EXCEPTION(isolate,
145 Accessors::FunctionSetPrototype(fun, value));
146 return args[0]; // return TOS
147}
148
149
150RUNTIME_FUNCTION(Runtime_FunctionIsAPIFunction) {
151 SealHandleScope shs(isolate);
152 DCHECK(args.length() == 1);
153
154 CONVERT_ARG_CHECKED(JSFunction, f, 0);
155 return isolate->heap()->ToBoolean(f->shared()->IsApiFunction());
156}
157
158
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400159RUNTIME_FUNCTION(Runtime_SetCode) {
160 HandleScope scope(isolate);
161 DCHECK(args.length() == 2);
162
163 CONVERT_ARG_HANDLE_CHECKED(JSFunction, target, 0);
164 CONVERT_ARG_HANDLE_CHECKED(JSFunction, source, 1);
165
166 Handle<SharedFunctionInfo> target_shared(target->shared());
167 Handle<SharedFunctionInfo> source_shared(source->shared());
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400168
Ben Murdochda12d292016-06-02 14:46:10 +0100169 if (!Compiler::Compile(source, Compiler::KEEP_EXCEPTION)) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400170 return isolate->heap()->exception();
171 }
172
173 // Mark both, the source and the target, as un-flushable because the
174 // shared unoptimized code makes them impossible to enqueue in a list.
175 DCHECK(target_shared->code()->gc_metadata() == NULL);
176 DCHECK(source_shared->code()->gc_metadata() == NULL);
177 target_shared->set_dont_flush(true);
178 source_shared->set_dont_flush(true);
179
180 // Set the code, scope info, formal parameter count, and the length
181 // of the target shared function info.
182 target_shared->ReplaceCode(source_shared->code());
Ben Murdoch097c5b22016-05-18 11:27:45 +0100183 if (source_shared->HasBytecodeArray()) {
Ben Murdochda12d292016-06-02 14:46:10 +0100184 target_shared->set_bytecode_array(source_shared->bytecode_array());
Ben Murdoch097c5b22016-05-18 11:27:45 +0100185 }
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400186 target_shared->set_scope_info(source_shared->scope_info());
187 target_shared->set_length(source_shared->length());
Ben Murdoch61f157c2016-09-16 13:49:30 +0100188 target_shared->set_num_literals(source_shared->num_literals());
189 target_shared->set_feedback_metadata(source_shared->feedback_metadata());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000190 target_shared->set_internal_formal_parameter_count(
191 source_shared->internal_formal_parameter_count());
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400192 target_shared->set_start_position_and_type(
193 source_shared->start_position_and_type());
194 target_shared->set_end_position(source_shared->end_position());
195 bool was_native = target_shared->native();
196 target_shared->set_compiler_hints(source_shared->compiler_hints());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000197 target_shared->set_opt_count_and_bailout_reason(
198 source_shared->opt_count_and_bailout_reason());
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400199 target_shared->set_native(was_native);
200 target_shared->set_profiler_ticks(source_shared->profiler_ticks());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000201 SharedFunctionInfo::SetScript(
202 target_shared, Handle<Object>(source_shared->script(), isolate));
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400203
204 // Set the code of the target function.
205 target->ReplaceCode(source_shared->code());
Ben Murdoch61f157c2016-09-16 13:49:30 +0100206 DCHECK(target->next_function_link()->IsUndefined(isolate));
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400207
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400208 Handle<Context> context(source->context());
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400209 target->set_context(*context);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000210
Ben Murdoch61f157c2016-09-16 13:49:30 +0100211 // Make sure we get a fresh copy of the literal vector to avoid cross
212 // context contamination, and that the literal vector makes it's way into
213 // the target_shared optimized code map.
214 JSFunction::EnsureLiterals(target);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400215
Ben Murdoch61f157c2016-09-16 13:49:30 +0100216 if (isolate->logger()->is_logging_code_events() || isolate->is_profiling()) {
Ben Murdochda12d292016-06-02 14:46:10 +0100217 isolate->logger()->LogExistingFunction(
218 source_shared, Handle<AbstractCode>(source_shared->abstract_code()));
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400219 }
220
221 return *target;
222}
223
224
225// Set the native flag on the function.
226// This is used to decide if we should transform null and undefined
227// into the global object when doing call and apply.
228RUNTIME_FUNCTION(Runtime_SetNativeFlag) {
229 SealHandleScope shs(isolate);
Ben Murdoch61f157c2016-09-16 13:49:30 +0100230 DCHECK_EQ(1, args.length());
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400231
232 CONVERT_ARG_CHECKED(Object, object, 0);
233
234 if (object->IsJSFunction()) {
235 JSFunction* func = JSFunction::cast(object);
236 func->shared()->set_native(true);
237 }
238 return isolate->heap()->undefined_value();
239}
240
241
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000242RUNTIME_FUNCTION(Runtime_IsConstructor) {
243 SealHandleScope shs(isolate);
244 DCHECK_EQ(1, args.length());
245 CONVERT_ARG_CHECKED(Object, object, 0);
246 return isolate->heap()->ToBoolean(object->IsConstructor());
247}
248
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000249RUNTIME_FUNCTION(Runtime_SetForceInlineFlag) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400250 SealHandleScope shs(isolate);
Ben Murdoch61f157c2016-09-16 13:49:30 +0100251 DCHECK_EQ(1, args.length());
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400252 CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
253
254 if (object->IsJSFunction()) {
255 JSFunction* func = JSFunction::cast(*object);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000256 func->shared()->set_force_inline(true);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400257 }
258 return isolate->heap()->undefined_value();
259}
260
261
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400262RUNTIME_FUNCTION(Runtime_Call) {
263 HandleScope scope(isolate);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000264 DCHECK_LE(2, args.length());
265 int const argc = args.length() - 2;
Ben Murdochda12d292016-06-02 14:46:10 +0100266 CONVERT_ARG_HANDLE_CHECKED(Object, target, 0);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000267 CONVERT_ARG_HANDLE_CHECKED(Object, receiver, 1);
268 ScopedVector<Handle<Object>> argv(argc);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400269 for (int i = 0; i < argc; ++i) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000270 argv[i] = args.at<Object>(2 + i);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400271 }
Ben Murdoch61f157c2016-09-16 13:49:30 +0100272 RETURN_RESULT_OR_FAILURE(
273 isolate, Execution::Call(isolate, target, receiver, argc, argv.start()));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000274}
275
276
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000277// ES6 section 9.2.1.2, OrdinaryCallBindThis for sloppy callee.
278RUNTIME_FUNCTION(Runtime_ConvertReceiver) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400279 HandleScope scope(isolate);
280 DCHECK(args.length() == 1);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000281 CONVERT_ARG_HANDLE_CHECKED(Object, receiver, 0);
Ben Murdochc5610432016-08-08 18:44:38 +0100282 return *Object::ConvertReceiver(isolate, receiver).ToHandleChecked();
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400283}
284
285
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000286RUNTIME_FUNCTION(Runtime_IsFunction) {
287 SealHandleScope shs(isolate);
288 DCHECK_EQ(1, args.length());
289 CONVERT_ARG_CHECKED(Object, object, 0);
290 return isolate->heap()->ToBoolean(object->IsFunction());
291}
292
293
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000294RUNTIME_FUNCTION(Runtime_FunctionToString) {
295 HandleScope scope(isolate);
296 DCHECK_EQ(1, args.length());
297 CONVERT_ARG_HANDLE_CHECKED(JSReceiver, function, 0);
298 return function->IsJSBoundFunction()
299 ? *JSBoundFunction::ToString(
300 Handle<JSBoundFunction>::cast(function))
301 : *JSFunction::ToString(Handle<JSFunction>::cast(function));
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400302}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000303
304} // namespace internal
305} // namespace v8