0127f2381e5cd8443670ad07d0a05a1a89adbe32
[platform/upstream/v8.git] / src / runtime / runtime-internal.cc
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/arguments.h"
8 #include "src/bootstrapper.h"
9 #include "src/conversions.h"
10 #include "src/debug/debug.h"
11 #include "src/frames-inl.h"
12 #include "src/isolate-inl.h"
13 #include "src/messages.h"
14
15 namespace v8 {
16 namespace internal {
17
18 RUNTIME_FUNCTION(Runtime_CheckIsBootstrapping) {
19   SealHandleScope shs(isolate);
20   DCHECK(args.length() == 0);
21   RUNTIME_ASSERT(isolate->bootstrapper()->IsActive());
22   return isolate->heap()->undefined_value();
23 }
24
25
26 RUNTIME_FUNCTION(Runtime_ExportFromRuntime) {
27   HandleScope scope(isolate);
28   DCHECK(args.length() == 1);
29   CONVERT_ARG_HANDLE_CHECKED(JSObject, container, 0);
30   RUNTIME_ASSERT(isolate->bootstrapper()->IsActive());
31   JSObject::NormalizeProperties(container, KEEP_INOBJECT_PROPERTIES, 10,
32                                 "ExportFromRuntime");
33   Bootstrapper::ExportFromRuntime(isolate, container);
34   JSObject::MigrateSlowToFast(container, 0, "ExportFromRuntime");
35   return *container;
36 }
37
38
39 RUNTIME_FUNCTION(Runtime_ExportExperimentalFromRuntime) {
40   HandleScope scope(isolate);
41   DCHECK(args.length() == 1);
42   CONVERT_ARG_HANDLE_CHECKED(JSObject, container, 0);
43   RUNTIME_ASSERT(isolate->bootstrapper()->IsActive());
44   JSObject::NormalizeProperties(container, KEEP_INOBJECT_PROPERTIES, 10,
45                                 "ExportExperimentalFromRuntime");
46   Bootstrapper::ExportExperimentalFromRuntime(isolate, container);
47   JSObject::MigrateSlowToFast(container, 0, "ExportExperimentalFromRuntime");
48   return *container;
49 }
50
51
52 RUNTIME_FUNCTION(Runtime_InstallToContext) {
53   HandleScope scope(isolate);
54   DCHECK(args.length() == 1);
55   CONVERT_ARG_HANDLE_CHECKED(JSArray, array, 0);
56   RUNTIME_ASSERT(array->HasFastElements());
57   RUNTIME_ASSERT(isolate->bootstrapper()->IsActive());
58   Handle<Context> native_context = isolate->native_context();
59   Handle<FixedArray> fixed_array(FixedArray::cast(array->elements()));
60   int length = Smi::cast(array->length())->value();
61   for (int i = 0; i < length; i += 2) {
62     RUNTIME_ASSERT(fixed_array->get(i)->IsString());
63     Handle<String> name(String::cast(fixed_array->get(i)));
64     RUNTIME_ASSERT(fixed_array->get(i + 1)->IsJSObject());
65     Handle<JSObject> object(JSObject::cast(fixed_array->get(i + 1)));
66     int index = Context::ImportedFieldIndexForName(name);
67     if (index == Context::kNotFound) {
68       index = Context::IntrinsicIndexForName(name);
69     }
70     RUNTIME_ASSERT(index != Context::kNotFound);
71     native_context->set(index, *object);
72   }
73   return isolate->heap()->undefined_value();
74 }
75
76
77 RUNTIME_FUNCTION(Runtime_Throw) {
78   HandleScope scope(isolate);
79   DCHECK(args.length() == 1);
80   return isolate->Throw(args[0]);
81 }
82
83
84 RUNTIME_FUNCTION(Runtime_ReThrow) {
85   HandleScope scope(isolate);
86   DCHECK(args.length() == 1);
87   return isolate->ReThrow(args[0]);
88 }
89
90
91 RUNTIME_FUNCTION(Runtime_UnwindAndFindExceptionHandler) {
92   SealHandleScope shs(isolate);
93   DCHECK(args.length() == 0);
94   return isolate->UnwindAndFindHandler();
95 }
96
97
98 RUNTIME_FUNCTION(Runtime_PromoteScheduledException) {
99   SealHandleScope shs(isolate);
100   DCHECK(args.length() == 0);
101   return isolate->PromoteScheduledException();
102 }
103
104
105 RUNTIME_FUNCTION(Runtime_ThrowReferenceError) {
106   HandleScope scope(isolate);
107   DCHECK(args.length() == 1);
108   CONVERT_ARG_HANDLE_CHECKED(Object, name, 0);
109   THROW_NEW_ERROR_RETURN_FAILURE(
110       isolate, NewReferenceError(MessageTemplate::kNotDefined, name));
111 }
112
113
114 RUNTIME_FUNCTION(Runtime_NewTypeError) {
115   HandleScope scope(isolate);
116   DCHECK(args.length() == 2);
117   CONVERT_INT32_ARG_CHECKED(template_index, 0);
118   CONVERT_ARG_HANDLE_CHECKED(Object, arg0, 1);
119   auto message_template =
120       static_cast<MessageTemplate::Template>(template_index);
121   return *isolate->factory()->NewTypeError(message_template, arg0);
122 }
123
124
125 RUNTIME_FUNCTION(Runtime_NewReferenceError) {
126   HandleScope scope(isolate);
127   DCHECK(args.length() == 2);
128   CONVERT_INT32_ARG_CHECKED(template_index, 0);
129   CONVERT_ARG_HANDLE_CHECKED(Object, arg0, 1);
130   auto message_template =
131       static_cast<MessageTemplate::Template>(template_index);
132   return *isolate->factory()->NewReferenceError(message_template, arg0);
133 }
134
135
136 RUNTIME_FUNCTION(Runtime_NewSyntaxError) {
137   HandleScope scope(isolate);
138   DCHECK(args.length() == 2);
139   CONVERT_INT32_ARG_CHECKED(template_index, 0);
140   CONVERT_ARG_HANDLE_CHECKED(Object, arg0, 1);
141   auto message_template =
142       static_cast<MessageTemplate::Template>(template_index);
143   return *isolate->factory()->NewSyntaxError(message_template, arg0);
144 }
145
146
147 RUNTIME_FUNCTION(Runtime_ThrowIteratorResultNotAnObject) {
148   HandleScope scope(isolate);
149   DCHECK(args.length() == 1);
150   CONVERT_ARG_HANDLE_CHECKED(Object, value, 0);
151   THROW_NEW_ERROR_RETURN_FAILURE(
152       isolate,
153       NewTypeError(MessageTemplate::kIteratorResultNotAnObject, value));
154 }
155
156
157 RUNTIME_FUNCTION(Runtime_ThrowStrongModeImplicitConversion) {
158   HandleScope scope(isolate);
159   DCHECK(args.length() == 0);
160   THROW_NEW_ERROR_RETURN_FAILURE(
161       isolate, NewTypeError(MessageTemplate::kStrongImplicitConversion));
162 }
163
164
165 RUNTIME_FUNCTION(Runtime_PromiseRejectEvent) {
166   DCHECK(args.length() == 3);
167   HandleScope scope(isolate);
168   CONVERT_ARG_HANDLE_CHECKED(JSObject, promise, 0);
169   CONVERT_ARG_HANDLE_CHECKED(Object, value, 1);
170   CONVERT_BOOLEAN_ARG_CHECKED(debug_event, 2);
171   if (debug_event) isolate->debug()->OnPromiseReject(promise, value);
172   Handle<Symbol> key = isolate->factory()->promise_has_handler_symbol();
173   // Do not report if we actually have a handler.
174   if (JSReceiver::GetDataProperty(promise, key)->IsUndefined()) {
175     isolate->ReportPromiseReject(promise, value,
176                                  v8::kPromiseRejectWithNoHandler);
177   }
178   return isolate->heap()->undefined_value();
179 }
180
181
182 RUNTIME_FUNCTION(Runtime_PromiseRevokeReject) {
183   DCHECK(args.length() == 1);
184   HandleScope scope(isolate);
185   CONVERT_ARG_HANDLE_CHECKED(JSObject, promise, 0);
186   Handle<Symbol> key = isolate->factory()->promise_has_handler_symbol();
187   // At this point, no revocation has been issued before
188   RUNTIME_ASSERT(JSReceiver::GetDataProperty(promise, key)->IsUndefined());
189   isolate->ReportPromiseReject(promise, Handle<Object>(),
190                                v8::kPromiseHandlerAddedAfterReject);
191   return isolate->heap()->undefined_value();
192 }
193
194
195 RUNTIME_FUNCTION(Runtime_StackGuard) {
196   SealHandleScope shs(isolate);
197   DCHECK(args.length() == 0);
198
199   // First check if this is a real stack overflow.
200   StackLimitCheck check(isolate);
201   if (check.JsHasOverflowed()) {
202     return isolate->StackOverflow();
203   }
204
205   return isolate->stack_guard()->HandleInterrupts();
206 }
207
208
209 RUNTIME_FUNCTION(Runtime_Interrupt) {
210   SealHandleScope shs(isolate);
211   DCHECK(args.length() == 0);
212   return isolate->stack_guard()->HandleInterrupts();
213 }
214
215
216 RUNTIME_FUNCTION(Runtime_AllocateInNewSpace) {
217   HandleScope scope(isolate);
218   DCHECK(args.length() == 1);
219   CONVERT_SMI_ARG_CHECKED(size, 0);
220   RUNTIME_ASSERT(IsAligned(size, kPointerSize));
221   RUNTIME_ASSERT(size > 0);
222   RUNTIME_ASSERT(size <= Page::kMaxRegularHeapObjectSize);
223   return *isolate->factory()->NewFillerObject(size, false, NEW_SPACE);
224 }
225
226
227 RUNTIME_FUNCTION(Runtime_AllocateInTargetSpace) {
228   HandleScope scope(isolate);
229   DCHECK(args.length() == 2);
230   CONVERT_SMI_ARG_CHECKED(size, 0);
231   CONVERT_SMI_ARG_CHECKED(flags, 1);
232   RUNTIME_ASSERT(IsAligned(size, kPointerSize));
233   RUNTIME_ASSERT(size > 0);
234   RUNTIME_ASSERT(size <= Page::kMaxRegularHeapObjectSize);
235   bool double_align = AllocateDoubleAlignFlag::decode(flags);
236   AllocationSpace space = AllocateTargetSpace::decode(flags);
237   return *isolate->factory()->NewFillerObject(size, double_align, space);
238 }
239
240
241 // Collect the raw data for a stack trace.  Returns an array of 4
242 // element segments each containing a receiver, function, code and
243 // native code offset.
244 RUNTIME_FUNCTION(Runtime_CollectStackTrace) {
245   HandleScope scope(isolate);
246   DCHECK(args.length() == 2);
247   CONVERT_ARG_HANDLE_CHECKED(JSObject, error_object, 0);
248   CONVERT_ARG_HANDLE_CHECKED(Object, caller, 1);
249
250   if (!isolate->bootstrapper()->IsActive()) {
251     // Optionally capture a more detailed stack trace for the message.
252     RETURN_FAILURE_ON_EXCEPTION(
253         isolate, isolate->CaptureAndSetDetailedStackTrace(error_object));
254     // Capture a simple stack trace for the stack property.
255     RETURN_FAILURE_ON_EXCEPTION(
256         isolate, isolate->CaptureAndSetSimpleStackTrace(error_object, caller));
257   }
258   return isolate->heap()->undefined_value();
259 }
260
261
262 RUNTIME_FUNCTION(Runtime_MessageGetStartPosition) {
263   SealHandleScope shs(isolate);
264   DCHECK(args.length() == 1);
265   CONVERT_ARG_CHECKED(JSMessageObject, message, 0);
266   return Smi::FromInt(message->start_position());
267 }
268
269
270 RUNTIME_FUNCTION(Runtime_MessageGetScript) {
271   SealHandleScope shs(isolate);
272   DCHECK(args.length() == 1);
273   CONVERT_ARG_CHECKED(JSMessageObject, message, 0);
274   return message->script();
275 }
276
277
278 RUNTIME_FUNCTION(Runtime_ErrorToStringRT) {
279   HandleScope scope(isolate);
280   DCHECK(args.length() == 1);
281   CONVERT_ARG_HANDLE_CHECKED(JSObject, error, 0);
282   Handle<String> result;
283   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
284       isolate, result,
285       isolate->error_tostring_helper()->Stringify(isolate, error));
286   return *result;
287 }
288
289
290 RUNTIME_FUNCTION(Runtime_FormatMessageString) {
291   HandleScope scope(isolate);
292   DCHECK(args.length() == 4);
293   CONVERT_INT32_ARG_CHECKED(template_index, 0);
294   CONVERT_ARG_HANDLE_CHECKED(String, arg0, 1);
295   CONVERT_ARG_HANDLE_CHECKED(String, arg1, 2);
296   CONVERT_ARG_HANDLE_CHECKED(String, arg2, 3);
297   Handle<String> result;
298   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
299       isolate, result,
300       MessageTemplate::FormatMessage(template_index, arg0, arg1, arg2));
301   return *result;
302 }
303
304
305 #define CALLSITE_GET(NAME, RETURN)                          \
306   RUNTIME_FUNCTION(Runtime_CallSite##NAME##RT) {            \
307     HandleScope scope(isolate);                             \
308     DCHECK(args.length() == 1);                             \
309     CONVERT_ARG_HANDLE_CHECKED(JSObject, call_site_obj, 0); \
310     Handle<String> result;                                  \
311     CallSite call_site(isolate, call_site_obj);             \
312     return RETURN(call_site.NAME(), isolate);               \
313   }
314
315 static inline Object* ReturnDereferencedHandle(Handle<Object> obj,
316                                                Isolate* isolate) {
317   return *obj;
318 }
319
320
321 static inline Object* ReturnPositiveSmiOrNull(int value, Isolate* isolate) {
322   if (value >= 0) return Smi::FromInt(value);
323   return isolate->heap()->null_value();
324 }
325
326
327 static inline Object* ReturnBoolean(bool value, Isolate* isolate) {
328   return isolate->heap()->ToBoolean(value);
329 }
330
331
332 CALLSITE_GET(GetFileName, ReturnDereferencedHandle)
333 CALLSITE_GET(GetFunctionName, ReturnDereferencedHandle)
334 CALLSITE_GET(GetScriptNameOrSourceUrl, ReturnDereferencedHandle)
335 CALLSITE_GET(GetMethodName, ReturnDereferencedHandle)
336 CALLSITE_GET(GetLineNumber, ReturnPositiveSmiOrNull)
337 CALLSITE_GET(GetColumnNumber, ReturnPositiveSmiOrNull)
338 CALLSITE_GET(IsNative, ReturnBoolean)
339 CALLSITE_GET(IsToplevel, ReturnBoolean)
340 CALLSITE_GET(IsEval, ReturnBoolean)
341 CALLSITE_GET(IsConstructor, ReturnBoolean)
342
343 #undef CALLSITE_GET
344
345
346 RUNTIME_FUNCTION(Runtime_IS_VAR) {
347   UNREACHABLE();  // implemented as macro in the parser
348   return NULL;
349 }
350
351
352 RUNTIME_FUNCTION(Runtime_IncrementStatsCounter) {
353   SealHandleScope shs(isolate);
354   DCHECK(args.length() == 1);
355   CONVERT_ARG_CHECKED(String, name, 0);
356
357   if (FLAG_native_code_counters) {
358     StatsCounter(isolate, name->ToCString().get()).Increment();
359   }
360   return isolate->heap()->undefined_value();
361 }
362
363
364 RUNTIME_FUNCTION(Runtime_Likely) {
365   DCHECK(args.length() == 1);
366   return args[0];
367 }
368
369
370 RUNTIME_FUNCTION(Runtime_Unlikely) {
371   DCHECK(args.length() == 1);
372   return args[0];
373 }
374
375
376 RUNTIME_FUNCTION(Runtime_HarmonyToString) {
377   // TODO(caitp): Delete this runtime method when removing --harmony-tostring
378   return isolate->heap()->ToBoolean(FLAG_harmony_tostring);
379 }
380
381
382 RUNTIME_FUNCTION(Runtime_GetTypeFeedbackVector) {
383   SealHandleScope shs(isolate);
384   DCHECK(args.length() == 1);
385   CONVERT_ARG_CHECKED(JSFunction, function, 0);
386   return function->shared()->feedback_vector();
387 }
388
389
390 RUNTIME_FUNCTION(Runtime_GetCallerJSFunction) {
391   SealHandleScope shs(isolate);
392   StackFrameIterator it(isolate);
393   RUNTIME_ASSERT(it.frame()->type() == StackFrame::STUB);
394   it.Advance();
395   RUNTIME_ASSERT(it.frame()->type() == StackFrame::JAVA_SCRIPT);
396   return JavaScriptFrame::cast(it.frame())->function();
397 }
398
399
400 RUNTIME_FUNCTION(Runtime_GetCodeStubExportsObject) {
401   HandleScope shs(isolate);
402   return isolate->heap()->code_stub_exports_object();
403 }
404
405 }  // namespace internal
406 }  // namespace v8