Line data Source code
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/frames-inl.h"
11 : #include "src/isolate-inl.h"
12 : #include "src/messages.h"
13 : #include "src/wasm/wasm-module.h"
14 :
15 : namespace v8 {
16 : namespace internal {
17 :
18 938 : RUNTIME_FUNCTION(Runtime_FunctionGetName) {
19 469 : HandleScope scope(isolate);
20 : DCHECK_EQ(1, args.length());
21 :
22 938 : CONVERT_ARG_HANDLE_CHECKED(JSReceiver, function, 0);
23 469 : if (function->IsJSBoundFunction()) {
24 0 : RETURN_RESULT_OR_FAILURE(
25 : isolate, JSBoundFunction::GetName(
26 : isolate, Handle<JSBoundFunction>::cast(function)));
27 : } else {
28 938 : return *JSFunction::GetName(isolate, Handle<JSFunction>::cast(function));
29 469 : }
30 : }
31 :
32 :
33 93192 : RUNTIME_FUNCTION(Runtime_FunctionSetName) {
34 46596 : HandleScope scope(isolate);
35 : DCHECK_EQ(2, args.length());
36 :
37 93192 : CONVERT_ARG_HANDLE_CHECKED(JSFunction, f, 0);
38 93192 : CONVERT_ARG_HANDLE_CHECKED(String, name, 1);
39 :
40 46596 : name = String::Flatten(name);
41 46596 : f->shared()->set_name(*name);
42 46596 : return isolate->heap()->undefined_value();
43 : }
44 :
45 :
46 93982 : RUNTIME_FUNCTION(Runtime_FunctionRemovePrototype) {
47 : SealHandleScope shs(isolate);
48 : DCHECK_EQ(1, args.length());
49 :
50 93982 : CONVERT_ARG_CHECKED(JSFunction, f, 0);
51 46991 : CHECK(f->RemovePrototype());
52 : f->shared()->SetConstructStub(
53 93982 : *isolate->builtins()->ConstructedNonConstructable());
54 :
55 46991 : return isolate->heap()->undefined_value();
56 : }
57 :
58 : // TODO(5530): Remove once uses in debug.js are gone.
59 645020 : RUNTIME_FUNCTION(Runtime_FunctionGetScript) {
60 322510 : HandleScope scope(isolate);
61 : DCHECK_EQ(1, args.length());
62 645020 : CONVERT_ARG_HANDLE_CHECKED(JSReceiver, function, 0);
63 :
64 322510 : if (function->IsJSFunction()) {
65 : Handle<Object> script(
66 967485 : Handle<JSFunction>::cast(function)->shared()->script(), isolate);
67 322495 : if (script->IsScript()) {
68 644990 : return *Script::GetWrapper(Handle<Script>::cast(script));
69 : }
70 : }
71 15 : return isolate->heap()->undefined_value();
72 : }
73 :
74 10868 : RUNTIME_FUNCTION(Runtime_FunctionGetScriptId) {
75 5434 : HandleScope scope(isolate);
76 : DCHECK_EQ(1, args.length());
77 10868 : CONVERT_ARG_HANDLE_CHECKED(JSReceiver, function, 0);
78 :
79 5434 : if (function->IsJSFunction()) {
80 : Handle<Object> script(
81 16302 : Handle<JSFunction>::cast(function)->shared()->script(), isolate);
82 5434 : if (script->IsScript()) {
83 10868 : return Smi::FromInt(Handle<Script>::cast(script)->id());
84 : }
85 : }
86 0 : return Smi::FromInt(-1);
87 : }
88 :
89 814 : RUNTIME_FUNCTION(Runtime_FunctionGetSourceCode) {
90 407 : HandleScope scope(isolate);
91 : DCHECK_EQ(1, args.length());
92 814 : CONVERT_ARG_HANDLE_CHECKED(JSReceiver, function, 0);
93 407 : if (function->IsJSFunction()) {
94 1176 : return *Handle<JSFunction>::cast(function)->shared()->GetSourceCode();
95 : }
96 15 : return isolate->heap()->undefined_value();
97 : }
98 :
99 :
100 387418 : RUNTIME_FUNCTION(Runtime_FunctionGetScriptSourcePosition) {
101 : SealHandleScope shs(isolate);
102 : DCHECK_EQ(1, args.length());
103 :
104 387418 : CONVERT_ARG_CHECKED(JSFunction, fun, 0);
105 193709 : int pos = fun->shared()->start_position();
106 193709 : return Smi::FromInt(pos);
107 : }
108 :
109 382088 : RUNTIME_FUNCTION(Runtime_FunctionGetContextData) {
110 : SealHandleScope shs(isolate);
111 : DCHECK_EQ(1, args.length());
112 :
113 382088 : CONVERT_ARG_CHECKED(JSFunction, fun, 0);
114 191044 : return fun->native_context()->debug_context_id();
115 : }
116 :
117 474 : RUNTIME_FUNCTION(Runtime_FunctionSetInstanceClassName) {
118 : SealHandleScope shs(isolate);
119 : DCHECK_EQ(2, args.length());
120 :
121 474 : CONVERT_ARG_CHECKED(JSFunction, fun, 0);
122 474 : CONVERT_ARG_CHECKED(String, name, 1);
123 237 : fun->shared()->set_instance_class_name(name);
124 237 : return isolate->heap()->undefined_value();
125 : }
126 :
127 :
128 5688 : RUNTIME_FUNCTION(Runtime_FunctionSetLength) {
129 : SealHandleScope shs(isolate);
130 : DCHECK_EQ(2, args.length());
131 :
132 5688 : CONVERT_ARG_CHECKED(JSFunction, fun, 0);
133 5688 : CONVERT_SMI_ARG_CHECKED(length, 1);
134 2844 : CHECK((length & 0xC0000000) == 0xC0000000 || (length & 0xC0000000) == 0x0);
135 2844 : fun->shared()->set_length(length);
136 2844 : return isolate->heap()->undefined_value();
137 : }
138 :
139 :
140 2054 : RUNTIME_FUNCTION(Runtime_FunctionSetPrototype) {
141 1027 : HandleScope scope(isolate);
142 : DCHECK_EQ(2, args.length());
143 :
144 2054 : CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0);
145 1027 : CONVERT_ARG_HANDLE_CHECKED(Object, value, 1);
146 1027 : CHECK(fun->IsConstructor());
147 1027 : JSFunction::SetPrototype(fun, value);
148 1027 : return args[0]; // return TOS
149 : }
150 :
151 :
152 3510 : RUNTIME_FUNCTION(Runtime_FunctionIsAPIFunction) {
153 : SealHandleScope shs(isolate);
154 : DCHECK_EQ(1, args.length());
155 :
156 3510 : CONVERT_ARG_CHECKED(JSFunction, f, 0);
157 1755 : return isolate->heap()->ToBoolean(f->shared()->IsApiFunction());
158 : }
159 :
160 :
161 6636 : RUNTIME_FUNCTION(Runtime_SetCode) {
162 1659 : HandleScope scope(isolate);
163 : DCHECK_EQ(2, args.length());
164 :
165 3318 : CONVERT_ARG_HANDLE_CHECKED(JSFunction, target, 0);
166 3318 : CONVERT_ARG_HANDLE_CHECKED(JSFunction, source, 1);
167 :
168 1659 : Handle<SharedFunctionInfo> target_shared(target->shared());
169 1659 : Handle<SharedFunctionInfo> source_shared(source->shared());
170 :
171 1659 : if (!Compiler::Compile(source, Compiler::KEEP_EXCEPTION)) {
172 0 : return isolate->heap()->exception();
173 : }
174 :
175 : // Mark both, the source and the target, as un-flushable because the
176 : // shared unoptimized code makes them impossible to enqueue in a list.
177 : DCHECK(target_shared->code()->gc_metadata() == NULL);
178 : DCHECK(source_shared->code()->gc_metadata() == NULL);
179 1659 : target_shared->set_dont_flush(true);
180 1659 : source_shared->set_dont_flush(true);
181 :
182 : // Set the code, scope info, formal parameter count, and the length
183 : // of the target shared function info.
184 3318 : target_shared->ReplaceCode(source_shared->code());
185 1659 : if (source_shared->HasBytecodeArray()) {
186 3162 : target_shared->set_bytecode_array(source_shared->bytecode_array());
187 : }
188 3318 : target_shared->set_scope_info(source_shared->scope_info());
189 3318 : target_shared->set_outer_scope_info(source_shared->outer_scope_info());
190 3318 : target_shared->set_length(source_shared->GetLength());
191 3318 : target_shared->set_feedback_metadata(source_shared->feedback_metadata());
192 : target_shared->set_internal_formal_parameter_count(
193 3318 : source_shared->internal_formal_parameter_count());
194 : target_shared->set_start_position_and_type(
195 3318 : source_shared->start_position_and_type());
196 3318 : target_shared->set_end_position(source_shared->end_position());
197 1659 : bool was_native = target_shared->native();
198 1659 : target_shared->set_compiler_hints(source_shared->compiler_hints());
199 : target_shared->set_opt_count_and_bailout_reason(
200 3318 : source_shared->opt_count_and_bailout_reason());
201 3318 : target_shared->set_native(was_native);
202 3318 : target_shared->set_profiler_ticks(source_shared->profiler_ticks());
203 3318 : target_shared->set_function_literal_id(source_shared->function_literal_id());
204 :
205 1659 : Handle<Object> source_script(source_shared->script(), isolate);
206 1659 : if (source_script->IsScript()) {
207 : SharedFunctionInfo::SetScript(source_shared,
208 3318 : isolate->factory()->undefined_value());
209 : }
210 1659 : SharedFunctionInfo::SetScript(target_shared, source_script);
211 :
212 : // Set the code of the target function.
213 3318 : target->ReplaceCode(source_shared->code());
214 : DCHECK(target->next_function_link()->IsUndefined(isolate));
215 :
216 1659 : Handle<Context> context(source->context());
217 1659 : target->set_context(*context);
218 :
219 : // Make sure we get a fresh copy of the literal vector to avoid cross
220 : // context contamination, and that the literal vector makes it's way into
221 : // the target_shared optimized code map.
222 1659 : JSFunction::EnsureLiterals(target);
223 :
224 3318 : if (isolate->logger()->is_logging_code_events() || isolate->is_profiling()) {
225 : isolate->logger()->LogExistingFunction(
226 0 : source_shared, Handle<AbstractCode>(source_shared->abstract_code()));
227 : }
228 :
229 1659 : return *target;
230 : }
231 :
232 :
233 : // Set the native flag on the function.
234 : // This is used to decide if we should transform null and undefined
235 : // into the global object when doing call and apply.
236 98420 : RUNTIME_FUNCTION(Runtime_SetNativeFlag) {
237 : SealHandleScope shs(isolate);
238 : DCHECK_EQ(1, args.length());
239 :
240 49210 : CONVERT_ARG_CHECKED(Object, object, 0);
241 :
242 49210 : if (object->IsJSFunction()) {
243 : JSFunction* func = JSFunction::cast(object);
244 49210 : func->shared()->set_native(true);
245 : }
246 49210 : return isolate->heap()->undefined_value();
247 : }
248 :
249 :
250 54152 : RUNTIME_FUNCTION(Runtime_IsConstructor) {
251 : SealHandleScope shs(isolate);
252 : DCHECK_EQ(1, args.length());
253 27076 : CONVERT_ARG_CHECKED(Object, object, 0);
254 27076 : return isolate->heap()->ToBoolean(object->IsConstructor());
255 : }
256 :
257 2868 : RUNTIME_FUNCTION(Runtime_SetForceInlineFlag) {
258 : SealHandleScope shs(isolate);
259 : DCHECK_EQ(1, args.length());
260 1434 : CONVERT_ARG_CHECKED(Object, object, 0);
261 :
262 1434 : if (object->IsJSFunction()) {
263 : JSFunction* func = JSFunction::cast(object);
264 1434 : func->shared()->set_force_inline(true);
265 : }
266 1434 : return isolate->heap()->undefined_value();
267 : }
268 :
269 :
270 1598 : RUNTIME_FUNCTION(Runtime_Call) {
271 799 : HandleScope scope(isolate);
272 : DCHECK_LE(2, args.length());
273 799 : int const argc = args.length() - 2;
274 799 : CONVERT_ARG_HANDLE_CHECKED(Object, target, 0);
275 799 : CONVERT_ARG_HANDLE_CHECKED(Object, receiver, 1);
276 1598 : ScopedVector<Handle<Object>> argv(argc);
277 1092 : for (int i = 0; i < argc; ++i) {
278 1092 : argv[i] = args.at(2 + i);
279 : }
280 1598 : RETURN_RESULT_OR_FAILURE(
281 799 : isolate, Execution::Call(isolate, target, receiver, argc, argv.start()));
282 : }
283 :
284 :
285 : // ES6 section 9.2.1.2, OrdinaryCallBindThis for sloppy callee.
286 0 : RUNTIME_FUNCTION(Runtime_ConvertReceiver) {
287 0 : HandleScope scope(isolate);
288 : DCHECK_EQ(1, args.length());
289 0 : CONVERT_ARG_HANDLE_CHECKED(Object, receiver, 0);
290 0 : return *Object::ConvertReceiver(isolate, receiver).ToHandleChecked();
291 : }
292 :
293 :
294 2326896 : RUNTIME_FUNCTION(Runtime_IsFunction) {
295 : SealHandleScope shs(isolate);
296 : DCHECK_EQ(1, args.length());
297 1163448 : CONVERT_ARG_CHECKED(Object, object, 0);
298 1163448 : return isolate->heap()->ToBoolean(object->IsFunction());
299 : }
300 :
301 :
302 0 : RUNTIME_FUNCTION(Runtime_FunctionToString) {
303 0 : HandleScope scope(isolate);
304 : DCHECK_EQ(1, args.length());
305 0 : CONVERT_ARG_HANDLE_CHECKED(JSReceiver, function, 0);
306 : return function->IsJSBoundFunction()
307 : ? *JSBoundFunction::ToString(
308 0 : Handle<JSBoundFunction>::cast(function))
309 0 : : *JSFunction::ToString(Handle<JSFunction>::cast(function));
310 : }
311 :
312 : } // namespace internal
313 : } // namespace v8
|