• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
RUNTIME_FUNCTION(Runtime_FunctionGetName)18 RUNTIME_FUNCTION(Runtime_FunctionGetName) {
19   HandleScope scope(isolate);
20   DCHECK(args.length() == 1);
21 
22   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, function, 0);
23   if (function->IsJSBoundFunction()) {
24     RETURN_RESULT_OR_FAILURE(
25         isolate, JSBoundFunction::GetName(
26                      isolate, Handle<JSBoundFunction>::cast(function)));
27   } else {
28     return *JSFunction::GetName(isolate, Handle<JSFunction>::cast(function));
29   }
30 }
31 
32 
RUNTIME_FUNCTION(Runtime_FunctionSetName)33 RUNTIME_FUNCTION(Runtime_FunctionSetName) {
34   HandleScope scope(isolate);
35   DCHECK(args.length() == 2);
36 
37   CONVERT_ARG_HANDLE_CHECKED(JSFunction, f, 0);
38   CONVERT_ARG_HANDLE_CHECKED(String, name, 1);
39 
40   name = String::Flatten(name);
41   f->shared()->set_name(*name);
42   return isolate->heap()->undefined_value();
43 }
44 
45 
RUNTIME_FUNCTION(Runtime_FunctionRemovePrototype)46 RUNTIME_FUNCTION(Runtime_FunctionRemovePrototype) {
47   SealHandleScope shs(isolate);
48   DCHECK(args.length() == 1);
49 
50   CONVERT_ARG_CHECKED(JSFunction, f, 0);
51   CHECK(f->RemovePrototype());
52   f->shared()->set_construct_stub(
53       *isolate->builtins()->ConstructedNonConstructable());
54 
55   return isolate->heap()->undefined_value();
56 }
57 
58 
RUNTIME_FUNCTION(Runtime_FunctionGetScript)59 RUNTIME_FUNCTION(Runtime_FunctionGetScript) {
60   HandleScope scope(isolate);
61   DCHECK_EQ(1, args.length());
62   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, function, 0);
63 
64   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();
72 }
73 
74 
RUNTIME_FUNCTION(Runtime_FunctionGetSourceCode)75 RUNTIME_FUNCTION(Runtime_FunctionGetSourceCode) {
76   HandleScope scope(isolate);
77   DCHECK_EQ(1, args.length());
78   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, function, 0);
79   if (function->IsJSFunction()) {
80     return *Handle<JSFunction>::cast(function)->shared()->GetSourceCode();
81   }
82   return isolate->heap()->undefined_value();
83 }
84 
85 
RUNTIME_FUNCTION(Runtime_FunctionGetScriptSourcePosition)86 RUNTIME_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 
RUNTIME_FUNCTION(Runtime_FunctionGetPositionForOffset)96 RUNTIME_FUNCTION(Runtime_FunctionGetPositionForOffset) {
97   SealHandleScope shs(isolate);
98   DCHECK(args.length() == 2);
99 
100   CONVERT_ARG_CHECKED(AbstractCode, abstract_code, 0);
101   CONVERT_NUMBER_CHECKED(int, offset, Int32, args[1]);
102   return Smi::FromInt(abstract_code->SourcePosition(offset));
103 }
104 
RUNTIME_FUNCTION(Runtime_FunctionGetContextData)105 RUNTIME_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 }
113 
RUNTIME_FUNCTION(Runtime_FunctionSetInstanceClassName)114 RUNTIME_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);
120   fun->shared()->set_instance_class_name(name);
121   return isolate->heap()->undefined_value();
122 }
123 
124 
RUNTIME_FUNCTION(Runtime_FunctionSetLength)125 RUNTIME_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);
131   CHECK((length & 0xC0000000) == 0xC0000000 || (length & 0xC0000000) == 0x0);
132   fun->shared()->set_length(length);
133   return isolate->heap()->undefined_value();
134 }
135 
136 
RUNTIME_FUNCTION(Runtime_FunctionSetPrototype)137 RUNTIME_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);
143   CHECK(fun->IsConstructor());
144   RETURN_FAILURE_ON_EXCEPTION(isolate,
145                               Accessors::FunctionSetPrototype(fun, value));
146   return args[0];  // return TOS
147 }
148 
149 
RUNTIME_FUNCTION(Runtime_FunctionIsAPIFunction)150 RUNTIME_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 
RUNTIME_FUNCTION(Runtime_SetCode)159 RUNTIME_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());
168 
169   if (!Compiler::Compile(source, Compiler::KEEP_EXCEPTION)) {
170     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());
183   if (source_shared->HasBytecodeArray()) {
184     target_shared->set_bytecode_array(source_shared->bytecode_array());
185   }
186   target_shared->set_scope_info(source_shared->scope_info());
187   target_shared->set_length(source_shared->length());
188   target_shared->set_num_literals(source_shared->num_literals());
189   target_shared->set_feedback_metadata(source_shared->feedback_metadata());
190   target_shared->set_internal_formal_parameter_count(
191       source_shared->internal_formal_parameter_count());
192   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());
197   target_shared->set_opt_count_and_bailout_reason(
198       source_shared->opt_count_and_bailout_reason());
199   target_shared->set_native(was_native);
200   target_shared->set_profiler_ticks(source_shared->profiler_ticks());
201   SharedFunctionInfo::SetScript(
202       target_shared, Handle<Object>(source_shared->script(), isolate));
203 
204   // Set the code of the target function.
205   target->ReplaceCode(source_shared->code());
206   DCHECK(target->next_function_link()->IsUndefined(isolate));
207 
208   Handle<Context> context(source->context());
209   target->set_context(*context);
210 
211   // 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);
215 
216   if (isolate->logger()->is_logging_code_events() || isolate->is_profiling()) {
217     isolate->logger()->LogExistingFunction(
218         source_shared, Handle<AbstractCode>(source_shared->abstract_code()));
219   }
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.
RUNTIME_FUNCTION(Runtime_SetNativeFlag)228 RUNTIME_FUNCTION(Runtime_SetNativeFlag) {
229   SealHandleScope shs(isolate);
230   DCHECK_EQ(1, args.length());
231 
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 
RUNTIME_FUNCTION(Runtime_IsConstructor)242 RUNTIME_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 
RUNTIME_FUNCTION(Runtime_SetForceInlineFlag)249 RUNTIME_FUNCTION(Runtime_SetForceInlineFlag) {
250   SealHandleScope shs(isolate);
251   DCHECK_EQ(1, args.length());
252   CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
253 
254   if (object->IsJSFunction()) {
255     JSFunction* func = JSFunction::cast(*object);
256     func->shared()->set_force_inline(true);
257   }
258   return isolate->heap()->undefined_value();
259 }
260 
261 
RUNTIME_FUNCTION(Runtime_Call)262 RUNTIME_FUNCTION(Runtime_Call) {
263   HandleScope scope(isolate);
264   DCHECK_LE(2, args.length());
265   int const argc = args.length() - 2;
266   CONVERT_ARG_HANDLE_CHECKED(Object, target, 0);
267   CONVERT_ARG_HANDLE_CHECKED(Object, receiver, 1);
268   ScopedVector<Handle<Object>> argv(argc);
269   for (int i = 0; i < argc; ++i) {
270     argv[i] = args.at<Object>(2 + i);
271   }
272   RETURN_RESULT_OR_FAILURE(
273       isolate, Execution::Call(isolate, target, receiver, argc, argv.start()));
274 }
275 
276 
277 // ES6 section 9.2.1.2, OrdinaryCallBindThis for sloppy callee.
RUNTIME_FUNCTION(Runtime_ConvertReceiver)278 RUNTIME_FUNCTION(Runtime_ConvertReceiver) {
279   HandleScope scope(isolate);
280   DCHECK(args.length() == 1);
281   CONVERT_ARG_HANDLE_CHECKED(Object, receiver, 0);
282   return *Object::ConvertReceiver(isolate, receiver).ToHandleChecked();
283 }
284 
285 
RUNTIME_FUNCTION(Runtime_IsFunction)286 RUNTIME_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 
RUNTIME_FUNCTION(Runtime_FunctionToString)294 RUNTIME_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));
302 }
303 
304 }  // namespace internal
305 }  // namespace v8
306