blob: a85effd4033ea459032d69486dcdbff3b8d62b74 [file] [log] [blame]
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001// 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.
Steve Blocka7e24c12009-10-30 11:49:00 +00004
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005#include "src/execution.h"
Steve Blocka7e24c12009-10-30 11:49:00 +00006
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007#include "src/bootstrapper.h"
8#include "src/codegen.h"
9#include "src/deoptimizer.h"
10#include "src/isolate-inl.h"
11#include "src/vm-state-inl.h"
Steve Blocka7e24c12009-10-30 11:49:00 +000012
13namespace v8 {
14namespace internal {
15
Steve Block44f0eee2011-05-26 01:26:41 +010016StackGuard::StackGuard()
17 : isolate_(NULL) {
18}
19
20
21void StackGuard::set_interrupt_limits(const ExecutionAccess& lock) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000022 DCHECK(isolate_ != NULL);
Steve Block44f0eee2011-05-26 01:26:41 +010023 thread_local_.jslimit_ = kInterruptLimit;
24 thread_local_.climit_ = kInterruptLimit;
25 isolate_->heap()->SetStackLimits();
26}
27
28
29void StackGuard::reset_limits(const ExecutionAccess& lock) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000030 DCHECK(isolate_ != NULL);
Steve Block44f0eee2011-05-26 01:26:41 +010031 thread_local_.jslimit_ = thread_local_.real_jslimit_;
32 thread_local_.climit_ = thread_local_.real_climit_;
33 isolate_->heap()->SetStackLimits();
34}
35
36
Emily Bernierd0a1eb72015-03-24 16:35:39 -040037static void PrintDeserializedCodeInfo(Handle<JSFunction> function) {
38 if (function->code() == function->shared()->code() &&
39 function->shared()->deserialized()) {
40 PrintF("Running deserialized script ");
41 Object* script = function->shared()->script();
42 if (script->IsScript()) Script::cast(script)->name()->ShortPrint();
43 PrintF("\n");
44 }
45}
46
47
Ben Murdochb8a8cc12014-11-26 15:28:44 +000048MUST_USE_RESULT static MaybeHandle<Object> Invoke(
49 bool is_construct,
50 Handle<JSFunction> function,
51 Handle<Object> receiver,
52 int argc,
53 Handle<Object> args[]) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +010054 Isolate* isolate = function->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +010055
Steve Blocka7e24c12009-10-30 11:49:00 +000056 // Entering JavaScript.
Ben Murdochb8a8cc12014-11-26 15:28:44 +000057 VMState<JS> state(isolate);
58 CHECK(AllowJavascriptExecution::IsAllowed(isolate));
59 if (!ThrowOnJavascriptExecution::IsAllowed(isolate)) {
60 isolate->ThrowIllegalOperation();
61 isolate->ReportPendingMessages();
62 return MaybeHandle<Object>();
63 }
Steve Blocka7e24c12009-10-30 11:49:00 +000064
65 // Placeholder for return value.
Ben Murdochb8a8cc12014-11-26 15:28:44 +000066 Object* value = NULL;
Steve Blocka7e24c12009-10-30 11:49:00 +000067
Ben Murdoch3ef787d2012-04-12 10:51:47 +010068 typedef Object* (*JSEntryFunction)(byte* entry,
69 Object* function,
70 Object* receiver,
71 int argc,
72 Object*** args);
Steve Blocka7e24c12009-10-30 11:49:00 +000073
Ben Murdoch3ef787d2012-04-12 10:51:47 +010074 Handle<Code> code = is_construct
75 ? isolate->factory()->js_construct_entry_code()
76 : isolate->factory()->js_entry_code();
Steve Blocka7e24c12009-10-30 11:49:00 +000077
78 // Convert calls on global objects to be calls on the global
79 // receiver instead to avoid having a 'this' pointer which refers
80 // directly to a global object.
81 if (receiver->IsGlobalObject()) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000082 receiver = handle(Handle<GlobalObject>::cast(receiver)->global_proxy());
Steve Blocka7e24c12009-10-30 11:49:00 +000083 }
84
Leon Clarkee46be812010-01-19 14:06:41 +000085 // Make sure that the global object of the context we're about to
86 // make the current one is indeed a global object.
Ben Murdochb8a8cc12014-11-26 15:28:44 +000087 DCHECK(function->context()->global_object()->IsGlobalObject());
Leon Clarkee46be812010-01-19 14:06:41 +000088
Steve Blocka7e24c12009-10-30 11:49:00 +000089 {
90 // Save and restore context around invocation and block the
91 // allocation of handles without explicit handle scopes.
Steve Block44f0eee2011-05-26 01:26:41 +010092 SaveContext save(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +000093 SealHandleScope shs(isolate);
Ben Murdoch3ef787d2012-04-12 10:51:47 +010094 JSEntryFunction stub_entry = FUNCTION_CAST<JSEntryFunction>(code->entry());
Steve Blocka7e24c12009-10-30 11:49:00 +000095
96 // Call the function through the right JS entry stub.
Ben Murdoch3ef787d2012-04-12 10:51:47 +010097 byte* function_entry = function->code()->entry();
98 JSFunction* func = *function;
99 Object* recv = *receiver;
100 Object*** argv = reinterpret_cast<Object***>(args);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400101 if (FLAG_profile_deserialization) PrintDeserializedCodeInfo(function);
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100102 value =
103 CALL_GENERATED_CODE(stub_entry, function_entry, func, recv, argc, argv);
Steve Blocka7e24c12009-10-30 11:49:00 +0000104 }
105
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000106#ifdef VERIFY_HEAP
107 value->ObjectVerify();
Steve Blocka7e24c12009-10-30 11:49:00 +0000108#endif
109
110 // Update the pending exception flag and return the value.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000111 bool has_exception = value->IsException();
112 DCHECK(has_exception == isolate->has_pending_exception());
113 if (has_exception) {
Steve Block44f0eee2011-05-26 01:26:41 +0100114 isolate->ReportPendingMessages();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000115 // Reset stepping state when script exits with uncaught exception.
116 if (isolate->debug()->is_active()) {
117 isolate->debug()->ClearStepping();
Ben Murdoche0cee9b2011-05-25 10:26:03 +0100118 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000119 return MaybeHandle<Object>();
Steve Blocka7e24c12009-10-30 11:49:00 +0000120 } else {
Steve Block44f0eee2011-05-26 01:26:41 +0100121 isolate->clear_pending_message();
Steve Blocka7e24c12009-10-30 11:49:00 +0000122 }
123
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000124 return Handle<Object>(value, isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +0000125}
126
127
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000128MaybeHandle<Object> Execution::Call(Isolate* isolate,
129 Handle<Object> callable,
130 Handle<Object> receiver,
131 int argc,
132 Handle<Object> argv[],
133 bool convert_receiver) {
Ben Murdoch257744e2011-11-30 15:57:28 +0000134 if (!callable->IsJSFunction()) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000135 ASSIGN_RETURN_ON_EXCEPTION(
136 isolate, callable, TryGetFunctionDelegate(isolate, callable), Object);
Ben Murdoch257744e2011-11-30 15:57:28 +0000137 }
138 Handle<JSFunction> func = Handle<JSFunction>::cast(callable);
Ben Murdoch589d6972011-11-30 16:04:58 +0000139
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000140 // In sloppy mode, convert receiver.
Ben Murdoch589d6972011-11-30 16:04:58 +0000141 if (convert_receiver && !receiver->IsJSReceiver() &&
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000142 !func->shared()->native() &&
143 func->shared()->strict_mode() == SLOPPY) {
Ben Murdoch589d6972011-11-30 16:04:58 +0000144 if (receiver->IsUndefined() || receiver->IsNull()) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000145 receiver = handle(func->global_proxy());
146 DCHECK(!receiver->IsJSBuiltinsObject());
Ben Murdoch589d6972011-11-30 16:04:58 +0000147 } else {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000148 ASSIGN_RETURN_ON_EXCEPTION(
149 isolate, receiver, ToObject(isolate, receiver), Object);
Ben Murdoch589d6972011-11-30 16:04:58 +0000150 }
Ben Murdoch589d6972011-11-30 16:04:58 +0000151 }
152
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000153 return Invoke(false, func, receiver, argc, argv);
Steve Blocka7e24c12009-10-30 11:49:00 +0000154}
155
156
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000157MaybeHandle<Object> Execution::New(Handle<JSFunction> func,
158 int argc,
159 Handle<Object> argv[]) {
160 return Invoke(true, func, handle(func->global_proxy()), argc, argv);
Steve Blocka7e24c12009-10-30 11:49:00 +0000161}
162
163
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000164MaybeHandle<Object> Execution::TryCall(Handle<JSFunction> func,
165 Handle<Object> receiver, int argc,
166 Handle<Object> args[],
167 MaybeHandle<Object>* exception_out) {
168 bool is_termination = false;
169 Isolate* isolate = func->GetIsolate();
170 MaybeHandle<Object> maybe_result;
171 if (exception_out != NULL) *exception_out = MaybeHandle<Object>();
Steve Blocka7e24c12009-10-30 11:49:00 +0000172 // Enter a try-block while executing the JavaScript code. To avoid
173 // duplicate error printing it must be non-verbose. Also, to avoid
174 // creating message objects during stack overflow we shouldn't
175 // capture messages.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000176 {
177 v8::TryCatch catcher;
178 catcher.SetVerbose(false);
179 catcher.SetCaptureMessage(false);
Steve Blocka7e24c12009-10-30 11:49:00 +0000180
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000181 maybe_result = Invoke(false, func, receiver, argc, args);
Steve Blocka7e24c12009-10-30 11:49:00 +0000182
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000183 if (maybe_result.is_null()) {
184 DCHECK(catcher.HasCaught());
185 DCHECK(isolate->has_pending_exception());
186 DCHECK(isolate->external_caught_exception());
187 if (exception_out != NULL) {
188 if (isolate->pending_exception() ==
189 isolate->heap()->termination_exception()) {
190 is_termination = true;
191 } else {
192 *exception_out = v8::Utils::OpenHandle(*catcher.Exception());
193 }
194 }
195 isolate->OptionalRescheduleException(true);
Steve Blocka7e24c12009-10-30 11:49:00 +0000196 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000197
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000198 DCHECK(!isolate->has_pending_exception());
199 DCHECK(!isolate->external_caught_exception());
200 }
201 if (is_termination) isolate->TerminateExecution();
202 return maybe_result;
Steve Blocka7e24c12009-10-30 11:49:00 +0000203}
204
205
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000206Handle<Object> Execution::GetFunctionDelegate(Isolate* isolate,
207 Handle<Object> object) {
208 DCHECK(!object->IsJSFunction());
Ben Murdoch8b112d22011-06-08 16:22:53 +0100209 Factory* factory = isolate->factory();
Steve Blocka7e24c12009-10-30 11:49:00 +0000210
211 // If you return a function from here, it will be called when an
212 // attempt is made to call the given object as a function.
213
Ben Murdoch589d6972011-11-30 16:04:58 +0000214 // If object is a function proxy, get its handler. Iterate if necessary.
215 Object* fun = *object;
216 while (fun->IsJSFunctionProxy()) {
217 fun = JSFunctionProxy::cast(fun)->call_trap();
218 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000219 if (fun->IsJSFunction()) return Handle<Object>(fun, isolate);
Ben Murdoch589d6972011-11-30 16:04:58 +0000220
Steve Blocka7e24c12009-10-30 11:49:00 +0000221 // Objects created through the API can have an instance-call handler
222 // that should be used when calling the object as a function.
Ben Murdoch589d6972011-11-30 16:04:58 +0000223 if (fun->IsHeapObject() &&
224 HeapObject::cast(fun)->map()->has_instance_call_handler()) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000225 return Handle<JSFunction>(
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000226 isolate->native_context()->call_as_function_delegate());
Steve Blocka7e24c12009-10-30 11:49:00 +0000227 }
228
Ben Murdoch8b112d22011-06-08 16:22:53 +0100229 return factory->undefined_value();
Steve Blocka7e24c12009-10-30 11:49:00 +0000230}
231
232
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000233MaybeHandle<Object> Execution::TryGetFunctionDelegate(Isolate* isolate,
234 Handle<Object> object) {
235 DCHECK(!object->IsJSFunction());
Ben Murdoch257744e2011-11-30 15:57:28 +0000236
Ben Murdoch589d6972011-11-30 16:04:58 +0000237 // If object is a function proxy, get its handler. Iterate if necessary.
238 Object* fun = *object;
239 while (fun->IsJSFunctionProxy()) {
240 fun = JSFunctionProxy::cast(fun)->call_trap();
241 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000242 if (fun->IsJSFunction()) return Handle<Object>(fun, isolate);
Ben Murdoch589d6972011-11-30 16:04:58 +0000243
Ben Murdoch257744e2011-11-30 15:57:28 +0000244 // Objects created through the API can have an instance-call handler
245 // that should be used when calling the object as a function.
Ben Murdoch589d6972011-11-30 16:04:58 +0000246 if (fun->IsHeapObject() &&
247 HeapObject::cast(fun)->map()->has_instance_call_handler()) {
Ben Murdoch257744e2011-11-30 15:57:28 +0000248 return Handle<JSFunction>(
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000249 isolate->native_context()->call_as_function_delegate());
Ben Murdoch257744e2011-11-30 15:57:28 +0000250 }
251
252 // If the Object doesn't have an instance-call handler we should
253 // throw a non-callable exception.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000254 THROW_NEW_ERROR(isolate, NewTypeError("called_non_callable",
255 i::HandleVector<i::Object>(&object, 1)),
256 Object);
Ben Murdoch257744e2011-11-30 15:57:28 +0000257}
258
259
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000260Handle<Object> Execution::GetConstructorDelegate(Isolate* isolate,
261 Handle<Object> object) {
262 DCHECK(!object->IsJSFunction());
Steve Blocka7e24c12009-10-30 11:49:00 +0000263
264 // If you return a function from here, it will be called when an
265 // attempt is made to call the given object as a constructor.
266
Ben Murdoch589d6972011-11-30 16:04:58 +0000267 // If object is a function proxies, get its handler. Iterate if necessary.
268 Object* fun = *object;
269 while (fun->IsJSFunctionProxy()) {
270 fun = JSFunctionProxy::cast(fun)->call_trap();
271 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000272 if (fun->IsJSFunction()) return Handle<Object>(fun, isolate);
Ben Murdoch589d6972011-11-30 16:04:58 +0000273
Steve Blocka7e24c12009-10-30 11:49:00 +0000274 // Objects created through the API can have an instance-call handler
275 // that should be used when calling the object as a function.
Ben Murdoch589d6972011-11-30 16:04:58 +0000276 if (fun->IsHeapObject() &&
277 HeapObject::cast(fun)->map()->has_instance_call_handler()) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000278 return Handle<JSFunction>(
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000279 isolate->native_context()->call_as_constructor_delegate());
Steve Blocka7e24c12009-10-30 11:49:00 +0000280 }
281
Ben Murdoch8b112d22011-06-08 16:22:53 +0100282 return isolate->factory()->undefined_value();
Steve Blocka7e24c12009-10-30 11:49:00 +0000283}
284
285
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000286MaybeHandle<Object> Execution::TryGetConstructorDelegate(
287 Isolate* isolate, Handle<Object> object) {
288 DCHECK(!object->IsJSFunction());
Ben Murdoch257744e2011-11-30 15:57:28 +0000289
290 // If you return a function from here, it will be called when an
291 // attempt is made to call the given object as a constructor.
292
Ben Murdoch589d6972011-11-30 16:04:58 +0000293 // If object is a function proxies, get its handler. Iterate if necessary.
294 Object* fun = *object;
295 while (fun->IsJSFunctionProxy()) {
296 fun = JSFunctionProxy::cast(fun)->call_trap();
297 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000298 if (fun->IsJSFunction()) return Handle<Object>(fun, isolate);
Ben Murdoch589d6972011-11-30 16:04:58 +0000299
Ben Murdoch257744e2011-11-30 15:57:28 +0000300 // Objects created through the API can have an instance-call handler
301 // that should be used when calling the object as a function.
Ben Murdoch589d6972011-11-30 16:04:58 +0000302 if (fun->IsHeapObject() &&
303 HeapObject::cast(fun)->map()->has_instance_call_handler()) {
Ben Murdoch257744e2011-11-30 15:57:28 +0000304 return Handle<JSFunction>(
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000305 isolate->native_context()->call_as_constructor_delegate());
Ben Murdoch257744e2011-11-30 15:57:28 +0000306 }
307
308 // If the Object doesn't have an instance-call handler we should
309 // throw a non-callable exception.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000310 THROW_NEW_ERROR(isolate, NewTypeError("called_non_callable",
311 i::HandleVector<i::Object>(&object, 1)),
312 Object);
Steve Blocka7e24c12009-10-30 11:49:00 +0000313}
314
315
316void StackGuard::EnableInterrupts() {
Steve Block44f0eee2011-05-26 01:26:41 +0100317 ExecutionAccess access(isolate_);
Steve Block6ded16b2010-05-10 14:33:55 +0100318 if (has_pending_interrupts(access)) {
319 set_interrupt_limits(access);
Steve Blocka7e24c12009-10-30 11:49:00 +0000320 }
321}
322
323
324void StackGuard::SetStackLimit(uintptr_t limit) {
Steve Block44f0eee2011-05-26 01:26:41 +0100325 ExecutionAccess access(isolate_);
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100326 // If the current limits are special (e.g. due to a pending interrupt) then
Steve Blocka7e24c12009-10-30 11:49:00 +0000327 // leave them alone.
Ben Murdoch257744e2011-11-30 15:57:28 +0000328 uintptr_t jslimit = SimulatorStack::JsLimitFromCLimit(isolate_, limit);
Steve Blockd0582a62009-12-15 09:54:21 +0000329 if (thread_local_.jslimit_ == thread_local_.real_jslimit_) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000330 thread_local_.jslimit_ = jslimit;
Steve Blocka7e24c12009-10-30 11:49:00 +0000331 }
Steve Blockd0582a62009-12-15 09:54:21 +0000332 if (thread_local_.climit_ == thread_local_.real_climit_) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000333 thread_local_.climit_ = limit;
334 }
Steve Blockd0582a62009-12-15 09:54:21 +0000335 thread_local_.real_climit_ = limit;
336 thread_local_.real_jslimit_ = jslimit;
Steve Blocka7e24c12009-10-30 11:49:00 +0000337}
338
339
340void StackGuard::DisableInterrupts() {
Steve Block44f0eee2011-05-26 01:26:41 +0100341 ExecutionAccess access(isolate_);
Steve Blocka7e24c12009-10-30 11:49:00 +0000342 reset_limits(access);
343}
344
345
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000346void StackGuard::PushPostponeInterruptsScope(PostponeInterruptsScope* scope) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100347 ExecutionAccess access(isolate_);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000348 // Intercept already requested interrupts.
349 int intercepted = thread_local_.interrupt_flags_ & scope->intercept_mask_;
350 scope->intercepted_flags_ = intercepted;
351 thread_local_.interrupt_flags_ &= ~intercepted;
352 if (!has_pending_interrupts(access)) reset_limits(access);
353 // Add scope to the chain.
354 scope->prev_ = thread_local_.postpone_interrupts_;
355 thread_local_.postpone_interrupts_ = scope;
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100356}
357
358
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000359void StackGuard::PopPostponeInterruptsScope() {
Steve Block44f0eee2011-05-26 01:26:41 +0100360 ExecutionAccess access(isolate_);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000361 PostponeInterruptsScope* top = thread_local_.postpone_interrupts_;
362 // Make intercepted interrupts active.
363 DCHECK((thread_local_.interrupt_flags_ & top->intercept_mask_) == 0);
364 thread_local_.interrupt_flags_ |= top->intercepted_flags_;
365 if (has_pending_interrupts(access)) set_interrupt_limits(access);
366 // Remove scope from chain.
367 thread_local_.postpone_interrupts_ = top->prev_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000368}
369
370
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000371bool StackGuard::CheckInterrupt(InterruptFlag flag) {
Steve Block44f0eee2011-05-26 01:26:41 +0100372 ExecutionAccess access(isolate_);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000373 return thread_local_.interrupt_flags_ & flag;
374}
375
376
377void StackGuard::RequestInterrupt(InterruptFlag flag) {
378 ExecutionAccess access(isolate_);
379 // Check the chain of PostponeInterruptsScopes for interception.
380 if (thread_local_.postpone_interrupts_ &&
381 thread_local_.postpone_interrupts_->Intercept(flag)) {
382 return;
383 }
384
385 // Not intercepted. Set as active interrupt flag.
386 thread_local_.interrupt_flags_ |= flag;
Steve Block6ded16b2010-05-10 14:33:55 +0100387 set_interrupt_limits(access);
Steve Blocka7e24c12009-10-30 11:49:00 +0000388}
389
390
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000391void StackGuard::ClearInterrupt(InterruptFlag flag) {
Steve Block44f0eee2011-05-26 01:26:41 +0100392 ExecutionAccess access(isolate_);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000393 // Clear the interrupt flag from the chain of PostponeInterruptsScopes.
394 for (PostponeInterruptsScope* current = thread_local_.postpone_interrupts_;
395 current != NULL;
396 current = current->prev_) {
397 current->intercepted_flags_ &= ~flag;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100398 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000399
400 // Clear the interrupt flag from the active interrupt flags.
401 thread_local_.interrupt_flags_ &= ~flag;
402 if (!has_pending_interrupts(access)) reset_limits(access);
Ben Murdochb0fe1622011-05-05 13:52:32 +0100403}
404
405
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000406bool StackGuard::CheckAndClearInterrupt(InterruptFlag flag) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100407 ExecutionAccess access(isolate_);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000408 bool result = (thread_local_.interrupt_flags_ & flag);
409 thread_local_.interrupt_flags_ &= ~flag;
410 if (!has_pending_interrupts(access)) reset_limits(access);
411 return result;
Steve Blocka7e24c12009-10-30 11:49:00 +0000412}
413
414
Steve Blocka7e24c12009-10-30 11:49:00 +0000415char* StackGuard::ArchiveStackGuard(char* to) {
Steve Block44f0eee2011-05-26 01:26:41 +0100416 ExecutionAccess access(isolate_);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000417 MemCopy(to, reinterpret_cast<char*>(&thread_local_), sizeof(ThreadLocal));
Steve Blocka7e24c12009-10-30 11:49:00 +0000418 ThreadLocal blank;
Steve Block44f0eee2011-05-26 01:26:41 +0100419
420 // Set the stack limits using the old thread_local_.
421 // TODO(isolates): This was the old semantics of constructing a ThreadLocal
422 // (as the ctor called SetStackLimits, which looked at the
423 // current thread_local_ from StackGuard)-- but is this
424 // really what was intended?
425 isolate_->heap()->SetStackLimits();
Steve Blocka7e24c12009-10-30 11:49:00 +0000426 thread_local_ = blank;
Steve Block44f0eee2011-05-26 01:26:41 +0100427
Steve Blocka7e24c12009-10-30 11:49:00 +0000428 return to + sizeof(ThreadLocal);
429}
430
431
432char* StackGuard::RestoreStackGuard(char* from) {
Steve Block44f0eee2011-05-26 01:26:41 +0100433 ExecutionAccess access(isolate_);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000434 MemCopy(reinterpret_cast<char*>(&thread_local_), from, sizeof(ThreadLocal));
Steve Block44f0eee2011-05-26 01:26:41 +0100435 isolate_->heap()->SetStackLimits();
Steve Blocka7e24c12009-10-30 11:49:00 +0000436 return from + sizeof(ThreadLocal);
437}
438
439
Steve Blocka7e24c12009-10-30 11:49:00 +0000440void StackGuard::FreeThreadResources() {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000441 Isolate::PerIsolateThreadData* per_thread =
442 isolate_->FindOrAllocatePerThreadDataForThisThread();
443 per_thread->set_stack_limit(thread_local_.real_climit_);
Steve Blocka7e24c12009-10-30 11:49:00 +0000444}
445
446
447void StackGuard::ThreadLocal::Clear() {
Steve Blockd0582a62009-12-15 09:54:21 +0000448 real_jslimit_ = kIllegalLimit;
Steve Blocka7e24c12009-10-30 11:49:00 +0000449 jslimit_ = kIllegalLimit;
Steve Blockd0582a62009-12-15 09:54:21 +0000450 real_climit_ = kIllegalLimit;
Steve Blocka7e24c12009-10-30 11:49:00 +0000451 climit_ = kIllegalLimit;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000452 postpone_interrupts_ = NULL;
Steve Blocka7e24c12009-10-30 11:49:00 +0000453 interrupt_flags_ = 0;
Steve Blocka7e24c12009-10-30 11:49:00 +0000454}
455
456
Ben Murdoch257744e2011-11-30 15:57:28 +0000457bool StackGuard::ThreadLocal::Initialize(Isolate* isolate) {
Steve Block44f0eee2011-05-26 01:26:41 +0100458 bool should_set_stack_limits = false;
Steve Blockd0582a62009-12-15 09:54:21 +0000459 if (real_climit_ == kIllegalLimit) {
Steve Block1e0659c2011-05-24 12:43:12 +0100460 const uintptr_t kLimitSize = FLAG_stack_size * KB;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000461 DCHECK(GetCurrentStackPosition() > kLimitSize);
462 uintptr_t limit = GetCurrentStackPosition() - kLimitSize;
Ben Murdoch257744e2011-11-30 15:57:28 +0000463 real_jslimit_ = SimulatorStack::JsLimitFromCLimit(isolate, limit);
464 jslimit_ = SimulatorStack::JsLimitFromCLimit(isolate, limit);
Steve Blockd0582a62009-12-15 09:54:21 +0000465 real_climit_ = limit;
Steve Blocka7e24c12009-10-30 11:49:00 +0000466 climit_ = limit;
Steve Block44f0eee2011-05-26 01:26:41 +0100467 should_set_stack_limits = true;
Steve Blocka7e24c12009-10-30 11:49:00 +0000468 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000469 postpone_interrupts_ = NULL;
Steve Blocka7e24c12009-10-30 11:49:00 +0000470 interrupt_flags_ = 0;
Steve Block44f0eee2011-05-26 01:26:41 +0100471 return should_set_stack_limits;
Steve Blocka7e24c12009-10-30 11:49:00 +0000472}
473
474
475void StackGuard::ClearThread(const ExecutionAccess& lock) {
476 thread_local_.Clear();
Steve Block44f0eee2011-05-26 01:26:41 +0100477 isolate_->heap()->SetStackLimits();
Steve Blocka7e24c12009-10-30 11:49:00 +0000478}
479
480
481void StackGuard::InitThread(const ExecutionAccess& lock) {
Ben Murdoch257744e2011-11-30 15:57:28 +0000482 if (thread_local_.Initialize(isolate_)) isolate_->heap()->SetStackLimits();
483 Isolate::PerIsolateThreadData* per_thread =
484 isolate_->FindOrAllocatePerThreadDataForThisThread();
485 uintptr_t stored_limit = per_thread->stack_limit();
Steve Blocka7e24c12009-10-30 11:49:00 +0000486 // You should hold the ExecutionAccess lock when you call this.
Steve Block44f0eee2011-05-26 01:26:41 +0100487 if (stored_limit != 0) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000488 SetStackLimit(stored_limit);
Steve Blocka7e24c12009-10-30 11:49:00 +0000489 }
490}
491
492
493// --- C a l l s t o n a t i v e s ---
494
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000495#define RETURN_NATIVE_CALL(name, args) \
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100496 do { \
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100497 Handle<Object> argv[] = args; \
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000498 return Call(isolate, \
499 isolate->name##_fun(), \
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100500 isolate->js_builtins_object(), \
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000501 arraysize(argv), argv); \
Steve Blocka7e24c12009-10-30 11:49:00 +0000502 } while (false)
503
504
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000505MaybeHandle<Object> Execution::ToNumber(
506 Isolate* isolate, Handle<Object> obj) {
507 RETURN_NATIVE_CALL(to_number, { obj });
Steve Blocka7e24c12009-10-30 11:49:00 +0000508}
509
510
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000511MaybeHandle<Object> Execution::ToString(
512 Isolate* isolate, Handle<Object> obj) {
513 RETURN_NATIVE_CALL(to_string, { obj });
Steve Blocka7e24c12009-10-30 11:49:00 +0000514}
515
516
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000517MaybeHandle<Object> Execution::ToDetailString(
518 Isolate* isolate, Handle<Object> obj) {
519 RETURN_NATIVE_CALL(to_detail_string, { obj });
Steve Blocka7e24c12009-10-30 11:49:00 +0000520}
521
522
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000523MaybeHandle<Object> Execution::ToObject(
524 Isolate* isolate, Handle<Object> obj) {
Ben Murdoch589d6972011-11-30 16:04:58 +0000525 if (obj->IsSpecObject()) return obj;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000526 RETURN_NATIVE_CALL(to_object, { obj });
Steve Blocka7e24c12009-10-30 11:49:00 +0000527}
528
529
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000530MaybeHandle<Object> Execution::ToInteger(
531 Isolate* isolate, Handle<Object> obj) {
532 RETURN_NATIVE_CALL(to_integer, { obj });
Steve Blocka7e24c12009-10-30 11:49:00 +0000533}
534
535
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000536MaybeHandle<Object> Execution::ToUint32(
537 Isolate* isolate, Handle<Object> obj) {
538 RETURN_NATIVE_CALL(to_uint32, { obj });
Steve Blocka7e24c12009-10-30 11:49:00 +0000539}
540
541
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000542MaybeHandle<Object> Execution::ToInt32(
543 Isolate* isolate, Handle<Object> obj) {
544 RETURN_NATIVE_CALL(to_int32, { obj });
Steve Blocka7e24c12009-10-30 11:49:00 +0000545}
546
547
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400548MaybeHandle<Object> Execution::ToLength(
549 Isolate* isolate, Handle<Object> obj) {
550 RETURN_NATIVE_CALL(to_length, { obj });
551}
552
553
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000554MaybeHandle<Object> Execution::NewDate(Isolate* isolate, double time) {
555 Handle<Object> time_obj = isolate->factory()->NewNumber(time);
556 RETURN_NATIVE_CALL(create_date, { time_obj });
Steve Blocka7e24c12009-10-30 11:49:00 +0000557}
558
559
560#undef RETURN_NATIVE_CALL
561
562
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000563MaybeHandle<JSRegExp> Execution::NewJSRegExp(Handle<String> pattern,
564 Handle<String> flags) {
565 Isolate* isolate = pattern->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +0100566 Handle<JSFunction> function = Handle<JSFunction>(
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000567 isolate->native_context()->regexp_function());
568 Handle<Object> re_obj;
569 ASSIGN_RETURN_ON_EXCEPTION(
570 isolate, re_obj,
571 RegExpImpl::CreateRegExpLiteral(function, pattern, flags),
572 JSRegExp);
Ben Murdochf87a2032010-10-22 12:50:53 +0100573 return Handle<JSRegExp>::cast(re_obj);
574}
575
576
Steve Blocka7e24c12009-10-30 11:49:00 +0000577Handle<Object> Execution::CharAt(Handle<String> string, uint32_t index) {
Ben Murdoch8b112d22011-06-08 16:22:53 +0100578 Isolate* isolate = string->GetIsolate();
579 Factory* factory = isolate->factory();
580
Steve Blocka7e24c12009-10-30 11:49:00 +0000581 int int_index = static_cast<int>(index);
582 if (int_index < 0 || int_index >= string->length()) {
Ben Murdoch8b112d22011-06-08 16:22:53 +0100583 return factory->undefined_value();
Steve Blocka7e24c12009-10-30 11:49:00 +0000584 }
585
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000586 Handle<Object> char_at = Object::GetProperty(
587 isolate->js_builtins_object(),
588 factory->char_at_string()).ToHandleChecked();
Steve Blocka7e24c12009-10-30 11:49:00 +0000589 if (!char_at->IsJSFunction()) {
Ben Murdoch8b112d22011-06-08 16:22:53 +0100590 return factory->undefined_value();
Steve Blocka7e24c12009-10-30 11:49:00 +0000591 }
592
Ben Murdoch8b112d22011-06-08 16:22:53 +0100593 Handle<Object> index_object = factory->NewNumberFromInt(int_index);
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100594 Handle<Object> index_arg[] = { index_object };
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000595 Handle<Object> result;
596 if (!TryCall(Handle<JSFunction>::cast(char_at),
597 string,
598 arraysize(index_arg),
599 index_arg).ToHandle(&result)) {
Ben Murdoch8b112d22011-06-08 16:22:53 +0100600 return factory->undefined_value();
Steve Blocka7e24c12009-10-30 11:49:00 +0000601 }
602 return result;
603}
604
605
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000606MaybeHandle<JSFunction> Execution::InstantiateFunction(
607 Handle<FunctionTemplateInfo> data) {
Ben Murdoch8b112d22011-06-08 16:22:53 +0100608 Isolate* isolate = data->GetIsolate();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000609 if (!data->do_not_cache()) {
610 // Fast case: see if the function has already been instantiated
611 int serial_number = Smi::cast(data->serial_number())->value();
612 Handle<JSObject> cache(isolate->native_context()->function_cache());
613 Handle<Object> elm =
614 Object::GetElement(isolate, cache, serial_number).ToHandleChecked();
615 if (elm->IsJSFunction()) return Handle<JSFunction>::cast(elm);
616 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000617 // The function has not yet been instantiated in this context; do it.
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100618 Handle<Object> args[] = { data };
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000619 Handle<Object> result;
620 ASSIGN_RETURN_ON_EXCEPTION(
621 isolate, result,
622 Call(isolate,
623 isolate->instantiate_fun(),
624 isolate->js_builtins_object(),
625 arraysize(args),
626 args),
627 JSFunction);
Steve Blocka7e24c12009-10-30 11:49:00 +0000628 return Handle<JSFunction>::cast(result);
629}
630
631
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000632MaybeHandle<JSObject> Execution::InstantiateObject(
633 Handle<ObjectTemplateInfo> data) {
Ben Murdoch8b112d22011-06-08 16:22:53 +0100634 Isolate* isolate = data->GetIsolate();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000635 Handle<Object> result;
Steve Blocka7e24c12009-10-30 11:49:00 +0000636 if (data->property_list()->IsUndefined() &&
637 !data->constructor()->IsUndefined()) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000638 Handle<FunctionTemplateInfo> cons_template =
639 Handle<FunctionTemplateInfo>(
640 FunctionTemplateInfo::cast(data->constructor()));
641 Handle<JSFunction> cons;
642 ASSIGN_RETURN_ON_EXCEPTION(
643 isolate, cons, InstantiateFunction(cons_template), JSObject);
644 ASSIGN_RETURN_ON_EXCEPTION(isolate, result, New(cons, 0, NULL), JSObject);
Steve Blocka7e24c12009-10-30 11:49:00 +0000645 } else {
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100646 Handle<Object> args[] = { data };
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000647 ASSIGN_RETURN_ON_EXCEPTION(
648 isolate, result,
649 Call(isolate,
650 isolate->instantiate_fun(),
651 isolate->js_builtins_object(),
652 arraysize(args),
653 args),
654 JSObject);
Steve Blocka7e24c12009-10-30 11:49:00 +0000655 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000656 return Handle<JSObject>::cast(result);
Steve Blocka7e24c12009-10-30 11:49:00 +0000657}
658
659
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000660MaybeHandle<Object> Execution::ConfigureInstance(
661 Isolate* isolate,
662 Handle<Object> instance,
663 Handle<Object> instance_template) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100664 Handle<Object> args[] = { instance, instance_template };
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000665 return Execution::Call(isolate,
666 isolate->configure_instance_fun(),
667 isolate->js_builtins_object(),
668 arraysize(args),
669 args);
Steve Blocka7e24c12009-10-30 11:49:00 +0000670}
671
672
673Handle<String> Execution::GetStackTraceLine(Handle<Object> recv,
674 Handle<JSFunction> fun,
675 Handle<Object> pos,
676 Handle<Object> is_global) {
Ben Murdoch8b112d22011-06-08 16:22:53 +0100677 Isolate* isolate = fun->GetIsolate();
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100678 Handle<Object> args[] = { recv, fun, pos, is_global };
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000679 MaybeHandle<Object> maybe_result =
680 TryCall(isolate->get_stack_trace_line_fun(),
681 isolate->js_builtins_object(),
682 arraysize(args),
683 args);
684 Handle<Object> result;
685 if (!maybe_result.ToHandle(&result) || !result->IsString()) {
686 return isolate->factory()->empty_string();
Ben Murdoch8b112d22011-06-08 16:22:53 +0100687 }
688
Steve Blocka7e24c12009-10-30 11:49:00 +0000689 return Handle<String>::cast(result);
690}
691
692
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000693Object* StackGuard::HandleInterrupts() {
694 if (CheckAndClearInterrupt(GC_REQUEST)) {
695 isolate_->heap()->CollectAllGarbage(Heap::kNoGCFlags, "GC interrupt");
Steve Blocka7e24c12009-10-30 11:49:00 +0000696 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000697
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000698 if (CheckDebugBreak() || CheckDebugCommand()) {
699 isolate_->debug()->HandleDebugBreak();
700 }
701
702 if (CheckAndClearInterrupt(TERMINATE_EXECUTION)) {
703 return isolate_->TerminateExecution();
704 }
705
706 if (CheckAndClearInterrupt(DEOPT_MARKED_ALLOCATION_SITES)) {
707 isolate_->heap()->DeoptMarkedAllocationSites();
708 }
709
710 if (CheckAndClearInterrupt(INSTALL_CODE)) {
711 DCHECK(isolate_->concurrent_recompilation_enabled());
712 isolate_->optimizing_compiler_thread()->InstallOptimizedFunctions();
713 }
714
715 if (CheckAndClearInterrupt(API_INTERRUPT)) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400716 // Callbacks must be invoked outside of ExecusionAccess lock.
717 isolate_->InvokeApiInterruptCallbacks();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000718 }
719
720 isolate_->counters()->stack_interrupts()->Increment();
721 isolate_->counters()->runtime_profiler_ticks()->Increment();
722 isolate_->runtime_profiler()->OptimizeNow();
723
724 return isolate_->heap()->undefined_value();
Steve Blocka7e24c12009-10-30 11:49:00 +0000725}
726
Steve Blocka7e24c12009-10-30 11:49:00 +0000727} } // namespace v8::internal