blob: f36d4e4911f52c3ed8edcb0371db0046d0b6d33e [file] [log] [blame]
Ben Murdoch8b112d22011-06-08 16:22:53 +01001// Copyright 2011 the V8 project authors. All rights reserved.
Steve Blocka7e24c12009-10-30 11:49:00 +00002// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions are
4// met:
5//
6// * Redistributions of source code must retain the above copyright
7// notice, this list of conditions and the following disclaimer.
8// * Redistributions in binary form must reproduce the above
9// copyright notice, this list of conditions and the following
10// disclaimer in the documentation and/or other materials provided
11// with the distribution.
12// * Neither the name of Google Inc. nor the names of its
13// contributors may be used to endorse or promote products derived
14// from this software without specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28#include <stdlib.h>
29
30#include "v8.h"
31
32#include "api.h"
Leon Clarkee46be812010-01-19 14:06:41 +000033#include "bootstrapper.h"
Ben Murdoch8b112d22011-06-08 16:22:53 +010034#include "codegen.h"
Steve Blocka7e24c12009-10-30 11:49:00 +000035#include "debug.h"
Ben Murdochb0fe1622011-05-05 13:52:32 +010036#include "runtime-profiler.h"
Steve Blockd0582a62009-12-15 09:54:21 +000037#include "simulator.h"
Steve Blocka7e24c12009-10-30 11:49:00 +000038#include "v8threads.h"
Ben Murdochb0fe1622011-05-05 13:52:32 +010039#include "vm-state-inl.h"
Steve Blocka7e24c12009-10-30 11:49:00 +000040
41namespace v8 {
42namespace internal {
43
44
Steve Block44f0eee2011-05-26 01:26:41 +010045StackGuard::StackGuard()
46 : isolate_(NULL) {
47}
48
49
50void StackGuard::set_interrupt_limits(const ExecutionAccess& lock) {
51 ASSERT(isolate_ != NULL);
52 // Ignore attempts to interrupt when interrupts are postponed.
53 if (should_postpone_interrupts(lock)) return;
54 thread_local_.jslimit_ = kInterruptLimit;
55 thread_local_.climit_ = kInterruptLimit;
56 isolate_->heap()->SetStackLimits();
57}
58
59
60void StackGuard::reset_limits(const ExecutionAccess& lock) {
61 ASSERT(isolate_ != NULL);
62 thread_local_.jslimit_ = thread_local_.real_jslimit_;
63 thread_local_.climit_ = thread_local_.real_climit_;
64 isolate_->heap()->SetStackLimits();
65}
66
67
Steve Blocka7e24c12009-10-30 11:49:00 +000068static Handle<Object> Invoke(bool construct,
69 Handle<JSFunction> func,
70 Handle<Object> receiver,
71 int argc,
72 Object*** args,
73 bool* has_pending_exception) {
Steve Block44f0eee2011-05-26 01:26:41 +010074 Isolate* isolate = func->GetIsolate();
75
Steve Blocka7e24c12009-10-30 11:49:00 +000076 // Entering JavaScript.
Steve Block44f0eee2011-05-26 01:26:41 +010077 VMState state(isolate, JS);
Steve Blocka7e24c12009-10-30 11:49:00 +000078
79 // Placeholder for return value.
John Reck59135872010-11-02 12:39:01 -070080 MaybeObject* value = reinterpret_cast<Object*>(kZapValue);
Steve Blocka7e24c12009-10-30 11:49:00 +000081
82 typedef Object* (*JSEntryFunction)(
83 byte* entry,
84 Object* function,
85 Object* receiver,
86 int argc,
87 Object*** args);
88
89 Handle<Code> code;
90 if (construct) {
91 JSConstructEntryStub stub;
92 code = stub.GetCode();
93 } else {
94 JSEntryStub stub;
95 code = stub.GetCode();
96 }
97
98 // Convert calls on global objects to be calls on the global
99 // receiver instead to avoid having a 'this' pointer which refers
100 // directly to a global object.
101 if (receiver->IsGlobalObject()) {
102 Handle<GlobalObject> global = Handle<GlobalObject>::cast(receiver);
103 receiver = Handle<JSObject>(global->global_receiver());
104 }
105
Leon Clarkee46be812010-01-19 14:06:41 +0000106 // Make sure that the global object of the context we're about to
107 // make the current one is indeed a global object.
108 ASSERT(func->context()->global()->IsGlobalObject());
109
Steve Blocka7e24c12009-10-30 11:49:00 +0000110 {
111 // Save and restore context around invocation and block the
112 // allocation of handles without explicit handle scopes.
Steve Block44f0eee2011-05-26 01:26:41 +0100113 SaveContext save(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +0000114 NoHandleAllocation na;
115 JSEntryFunction entry = FUNCTION_CAST<JSEntryFunction>(code->entry());
116
117 // Call the function through the right JS entry stub.
Andrei Popescu402d9372010-02-26 13:31:12 +0000118 byte* entry_address = func->code()->entry();
Steve Block3ce2e202009-11-05 08:53:23 +0000119 JSFunction* function = *func;
120 Object* receiver_pointer = *receiver;
121 value = CALL_GENERATED_CODE(entry, entry_address, function,
122 receiver_pointer, argc, args);
Steve Blocka7e24c12009-10-30 11:49:00 +0000123 }
124
125#ifdef DEBUG
126 value->Verify();
127#endif
128
129 // Update the pending exception flag and return the value.
130 *has_pending_exception = value->IsException();
Steve Block44f0eee2011-05-26 01:26:41 +0100131 ASSERT(*has_pending_exception == Isolate::Current()->has_pending_exception());
Steve Blocka7e24c12009-10-30 11:49:00 +0000132 if (*has_pending_exception) {
Steve Block44f0eee2011-05-26 01:26:41 +0100133 isolate->ReportPendingMessages();
134 if (isolate->pending_exception() == Failure::OutOfMemoryException()) {
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000135 if (!isolate->ignore_out_of_memory()) {
Ben Murdoche0cee9b2011-05-25 10:26:03 +0100136 V8::FatalProcessOutOfMemory("JS", true);
137 }
138 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000139 return Handle<Object>();
140 } else {
Steve Block44f0eee2011-05-26 01:26:41 +0100141 isolate->clear_pending_message();
Steve Blocka7e24c12009-10-30 11:49:00 +0000142 }
143
Steve Block44f0eee2011-05-26 01:26:41 +0100144 return Handle<Object>(value->ToObjectUnchecked(), isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +0000145}
146
147
Ben Murdoch257744e2011-11-30 15:57:28 +0000148Handle<Object> Execution::Call(Handle<Object> callable,
Steve Blocka7e24c12009-10-30 11:49:00 +0000149 Handle<Object> receiver,
150 int argc,
151 Object*** args,
Ben Murdoch589d6972011-11-30 16:04:58 +0000152 bool* pending_exception,
153 bool convert_receiver) {
Ben Murdoch257744e2011-11-30 15:57:28 +0000154 if (!callable->IsJSFunction()) {
155 callable = TryGetFunctionDelegate(callable, pending_exception);
156 if (*pending_exception) return callable;
157 }
158 Handle<JSFunction> func = Handle<JSFunction>::cast(callable);
Ben Murdoch589d6972011-11-30 16:04:58 +0000159
160 // In non-strict mode, convert receiver.
161 if (convert_receiver && !receiver->IsJSReceiver() &&
162 !func->shared()->native() && !func->shared()->strict_mode()) {
163 if (receiver->IsUndefined() || receiver->IsNull()) {
164 Object* global = func->context()->global()->global_receiver();
165 // Under some circumstances, 'global' can be the JSBuiltinsObject
166 // In that case, don't rewrite.
167 // (FWIW, the same holds for GetIsolate()->global()->global_receiver().)
168 if (!global->IsJSBuiltinsObject()) receiver = Handle<Object>(global);
169 } else {
170 receiver = ToObject(receiver, pending_exception);
171 }
172 if (*pending_exception) return callable;
173 }
174
Steve Blocka7e24c12009-10-30 11:49:00 +0000175 return Invoke(false, func, receiver, argc, args, pending_exception);
176}
177
178
179Handle<Object> Execution::New(Handle<JSFunction> func, int argc,
180 Object*** args, bool* pending_exception) {
Steve Block44f0eee2011-05-26 01:26:41 +0100181 return Invoke(true, func, Isolate::Current()->global(), argc, args,
182 pending_exception);
Steve Blocka7e24c12009-10-30 11:49:00 +0000183}
184
185
186Handle<Object> Execution::TryCall(Handle<JSFunction> func,
187 Handle<Object> receiver,
188 int argc,
189 Object*** args,
190 bool* caught_exception) {
191 // Enter a try-block while executing the JavaScript code. To avoid
192 // duplicate error printing it must be non-verbose. Also, to avoid
193 // creating message objects during stack overflow we shouldn't
194 // capture messages.
195 v8::TryCatch catcher;
196 catcher.SetVerbose(false);
197 catcher.SetCaptureMessage(false);
198
199 Handle<Object> result = Invoke(false, func, receiver, argc, args,
200 caught_exception);
201
202 if (*caught_exception) {
203 ASSERT(catcher.HasCaught());
Steve Block44f0eee2011-05-26 01:26:41 +0100204 Isolate* isolate = Isolate::Current();
205 ASSERT(isolate->has_pending_exception());
206 ASSERT(isolate->external_caught_exception());
207 if (isolate->pending_exception() ==
208 isolate->heap()->termination_exception()) {
209 result = isolate->factory()->termination_exception();
Steve Blocka7e24c12009-10-30 11:49:00 +0000210 } else {
211 result = v8::Utils::OpenHandle(*catcher.Exception());
212 }
Steve Block44f0eee2011-05-26 01:26:41 +0100213 isolate->OptionalRescheduleException(true);
Steve Blocka7e24c12009-10-30 11:49:00 +0000214 }
215
Steve Block44f0eee2011-05-26 01:26:41 +0100216 ASSERT(!Isolate::Current()->has_pending_exception());
217 ASSERT(!Isolate::Current()->external_caught_exception());
Steve Blocka7e24c12009-10-30 11:49:00 +0000218 return result;
219}
220
221
222Handle<Object> Execution::GetFunctionDelegate(Handle<Object> object) {
223 ASSERT(!object->IsJSFunction());
Ben Murdoch8b112d22011-06-08 16:22:53 +0100224 Isolate* isolate = Isolate::Current();
225 Factory* factory = isolate->factory();
Steve Blocka7e24c12009-10-30 11:49:00 +0000226
227 // If you return a function from here, it will be called when an
228 // attempt is made to call the given object as a function.
229
Ben Murdoch589d6972011-11-30 16:04:58 +0000230 // If object is a function proxy, get its handler. Iterate if necessary.
231 Object* fun = *object;
232 while (fun->IsJSFunctionProxy()) {
233 fun = JSFunctionProxy::cast(fun)->call_trap();
234 }
235 if (fun->IsJSFunction()) return Handle<Object>(fun);
236
Steve Blocka7e24c12009-10-30 11:49:00 +0000237 // Objects created through the API can have an instance-call handler
238 // that should be used when calling the object as a function.
Ben Murdoch589d6972011-11-30 16:04:58 +0000239 if (fun->IsHeapObject() &&
240 HeapObject::cast(fun)->map()->has_instance_call_handler()) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000241 return Handle<JSFunction>(
Ben Murdoch8b112d22011-06-08 16:22:53 +0100242 isolate->global_context()->call_as_function_delegate());
Steve Blocka7e24c12009-10-30 11:49:00 +0000243 }
244
Ben Murdoch8b112d22011-06-08 16:22:53 +0100245 return factory->undefined_value();
Steve Blocka7e24c12009-10-30 11:49:00 +0000246}
247
248
Ben Murdoch257744e2011-11-30 15:57:28 +0000249Handle<Object> Execution::TryGetFunctionDelegate(Handle<Object> object,
250 bool* has_pending_exception) {
251 ASSERT(!object->IsJSFunction());
252 Isolate* isolate = Isolate::Current();
253
Ben Murdoch589d6972011-11-30 16:04:58 +0000254 // If object is a function proxy, get its handler. Iterate if necessary.
255 Object* fun = *object;
256 while (fun->IsJSFunctionProxy()) {
257 fun = JSFunctionProxy::cast(fun)->call_trap();
258 }
259 if (fun->IsJSFunction()) return Handle<Object>(fun);
260
Ben Murdoch257744e2011-11-30 15:57:28 +0000261 // Objects created through the API can have an instance-call handler
262 // that should be used when calling the object as a function.
Ben Murdoch589d6972011-11-30 16:04:58 +0000263 if (fun->IsHeapObject() &&
264 HeapObject::cast(fun)->map()->has_instance_call_handler()) {
Ben Murdoch257744e2011-11-30 15:57:28 +0000265 return Handle<JSFunction>(
266 isolate->global_context()->call_as_function_delegate());
267 }
268
269 // If the Object doesn't have an instance-call handler we should
270 // throw a non-callable exception.
271 i::Handle<i::Object> error_obj = isolate->factory()->NewTypeError(
272 "called_non_callable", i::HandleVector<i::Object>(&object, 1));
273 isolate->Throw(*error_obj);
274 *has_pending_exception = true;
275
276 return isolate->factory()->undefined_value();
277}
278
279
Steve Blocka7e24c12009-10-30 11:49:00 +0000280Handle<Object> Execution::GetConstructorDelegate(Handle<Object> object) {
281 ASSERT(!object->IsJSFunction());
Ben Murdoch8b112d22011-06-08 16:22:53 +0100282 Isolate* isolate = Isolate::Current();
Steve Blocka7e24c12009-10-30 11:49:00 +0000283
284 // If you return a function from here, it will be called when an
285 // attempt is made to call the given object as a constructor.
286
Ben Murdoch589d6972011-11-30 16:04:58 +0000287 // If object is a function proxies, get its handler. Iterate if necessary.
288 Object* fun = *object;
289 while (fun->IsJSFunctionProxy()) {
290 fun = JSFunctionProxy::cast(fun)->call_trap();
291 }
292 if (fun->IsJSFunction()) return Handle<Object>(fun);
293
Steve Blocka7e24c12009-10-30 11:49:00 +0000294 // Objects created through the API can have an instance-call handler
295 // that should be used when calling the object as a function.
Ben Murdoch589d6972011-11-30 16:04:58 +0000296 if (fun->IsHeapObject() &&
297 HeapObject::cast(fun)->map()->has_instance_call_handler()) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000298 return Handle<JSFunction>(
Ben Murdoch8b112d22011-06-08 16:22:53 +0100299 isolate->global_context()->call_as_constructor_delegate());
Steve Blocka7e24c12009-10-30 11:49:00 +0000300 }
301
Ben Murdoch8b112d22011-06-08 16:22:53 +0100302 return isolate->factory()->undefined_value();
Steve Blocka7e24c12009-10-30 11:49:00 +0000303}
304
305
Ben Murdoch257744e2011-11-30 15:57:28 +0000306Handle<Object> Execution::TryGetConstructorDelegate(
307 Handle<Object> object,
308 bool* has_pending_exception) {
309 ASSERT(!object->IsJSFunction());
310 Isolate* isolate = Isolate::Current();
311
312 // If you return a function from here, it will be called when an
313 // attempt is made to call the given object as a constructor.
314
Ben Murdoch589d6972011-11-30 16:04:58 +0000315 // If object is a function proxies, get its handler. Iterate if necessary.
316 Object* fun = *object;
317 while (fun->IsJSFunctionProxy()) {
318 fun = JSFunctionProxy::cast(fun)->call_trap();
319 }
320 if (fun->IsJSFunction()) return Handle<Object>(fun);
321
Ben Murdoch257744e2011-11-30 15:57:28 +0000322 // Objects created through the API can have an instance-call handler
323 // that should be used when calling the object as a function.
Ben Murdoch589d6972011-11-30 16:04:58 +0000324 if (fun->IsHeapObject() &&
325 HeapObject::cast(fun)->map()->has_instance_call_handler()) {
Ben Murdoch257744e2011-11-30 15:57:28 +0000326 return Handle<JSFunction>(
327 isolate->global_context()->call_as_constructor_delegate());
328 }
329
330 // If the Object doesn't have an instance-call handler we should
331 // throw a non-callable exception.
332 i::Handle<i::Object> error_obj = isolate->factory()->NewTypeError(
333 "called_non_callable", i::HandleVector<i::Object>(&object, 1));
334 isolate->Throw(*error_obj);
335 *has_pending_exception = true;
336
337 return isolate->factory()->undefined_value();
338}
339
340
Steve Blocka7e24c12009-10-30 11:49:00 +0000341bool StackGuard::IsStackOverflow() {
Steve Block44f0eee2011-05-26 01:26:41 +0100342 ExecutionAccess access(isolate_);
Steve Blocka7e24c12009-10-30 11:49:00 +0000343 return (thread_local_.jslimit_ != kInterruptLimit &&
344 thread_local_.climit_ != kInterruptLimit);
345}
346
347
348void StackGuard::EnableInterrupts() {
Steve Block44f0eee2011-05-26 01:26:41 +0100349 ExecutionAccess access(isolate_);
Steve Block6ded16b2010-05-10 14:33:55 +0100350 if (has_pending_interrupts(access)) {
351 set_interrupt_limits(access);
Steve Blocka7e24c12009-10-30 11:49:00 +0000352 }
353}
354
355
356void StackGuard::SetStackLimit(uintptr_t limit) {
Steve Block44f0eee2011-05-26 01:26:41 +0100357 ExecutionAccess access(isolate_);
Steve Blocka7e24c12009-10-30 11:49:00 +0000358 // If the current limits are special (eg due to a pending interrupt) then
359 // leave them alone.
Ben Murdoch257744e2011-11-30 15:57:28 +0000360 uintptr_t jslimit = SimulatorStack::JsLimitFromCLimit(isolate_, limit);
Steve Blockd0582a62009-12-15 09:54:21 +0000361 if (thread_local_.jslimit_ == thread_local_.real_jslimit_) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000362 thread_local_.jslimit_ = jslimit;
Steve Blocka7e24c12009-10-30 11:49:00 +0000363 }
Steve Blockd0582a62009-12-15 09:54:21 +0000364 if (thread_local_.climit_ == thread_local_.real_climit_) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000365 thread_local_.climit_ = limit;
366 }
Steve Blockd0582a62009-12-15 09:54:21 +0000367 thread_local_.real_climit_ = limit;
368 thread_local_.real_jslimit_ = jslimit;
Steve Blocka7e24c12009-10-30 11:49:00 +0000369}
370
371
372void StackGuard::DisableInterrupts() {
Steve Block44f0eee2011-05-26 01:26:41 +0100373 ExecutionAccess access(isolate_);
Steve Blocka7e24c12009-10-30 11:49:00 +0000374 reset_limits(access);
375}
376
377
Steve Blocka7e24c12009-10-30 11:49:00 +0000378bool StackGuard::IsInterrupted() {
Steve Block44f0eee2011-05-26 01:26:41 +0100379 ExecutionAccess access(isolate_);
Steve Blocka7e24c12009-10-30 11:49:00 +0000380 return thread_local_.interrupt_flags_ & INTERRUPT;
381}
382
383
384void StackGuard::Interrupt() {
Steve Block44f0eee2011-05-26 01:26:41 +0100385 ExecutionAccess access(isolate_);
Steve Blocka7e24c12009-10-30 11:49:00 +0000386 thread_local_.interrupt_flags_ |= INTERRUPT;
Steve Block6ded16b2010-05-10 14:33:55 +0100387 set_interrupt_limits(access);
Steve Blocka7e24c12009-10-30 11:49:00 +0000388}
389
390
391bool StackGuard::IsPreempted() {
Steve Block44f0eee2011-05-26 01:26:41 +0100392 ExecutionAccess access(isolate_);
Steve Blocka7e24c12009-10-30 11:49:00 +0000393 return thread_local_.interrupt_flags_ & PREEMPT;
394}
395
396
397void StackGuard::Preempt() {
Steve Block44f0eee2011-05-26 01:26:41 +0100398 ExecutionAccess access(isolate_);
Steve Blocka7e24c12009-10-30 11:49:00 +0000399 thread_local_.interrupt_flags_ |= PREEMPT;
Steve Block6ded16b2010-05-10 14:33:55 +0100400 set_interrupt_limits(access);
Steve Blocka7e24c12009-10-30 11:49:00 +0000401}
402
403
404bool StackGuard::IsTerminateExecution() {
Steve Block44f0eee2011-05-26 01:26:41 +0100405 ExecutionAccess access(isolate_);
Steve Blocka7e24c12009-10-30 11:49:00 +0000406 return thread_local_.interrupt_flags_ & TERMINATE;
407}
408
409
410void StackGuard::TerminateExecution() {
Steve Block44f0eee2011-05-26 01:26:41 +0100411 ExecutionAccess access(isolate_);
Steve Blocka7e24c12009-10-30 11:49:00 +0000412 thread_local_.interrupt_flags_ |= TERMINATE;
Steve Block6ded16b2010-05-10 14:33:55 +0100413 set_interrupt_limits(access);
Steve Blocka7e24c12009-10-30 11:49:00 +0000414}
415
416
Ben Murdochb0fe1622011-05-05 13:52:32 +0100417bool StackGuard::IsRuntimeProfilerTick() {
Steve Block44f0eee2011-05-26 01:26:41 +0100418 ExecutionAccess access(isolate_);
Ben Murdochb0fe1622011-05-05 13:52:32 +0100419 return thread_local_.interrupt_flags_ & RUNTIME_PROFILER_TICK;
420}
421
422
423void StackGuard::RequestRuntimeProfilerTick() {
424 // Ignore calls if we're not optimizing or if we can't get the lock.
Steve Block44f0eee2011-05-26 01:26:41 +0100425 if (FLAG_opt && ExecutionAccess::TryLock(isolate_)) {
Ben Murdochb0fe1622011-05-05 13:52:32 +0100426 thread_local_.interrupt_flags_ |= RUNTIME_PROFILER_TICK;
427 if (thread_local_.postpone_interrupts_nesting_ == 0) {
428 thread_local_.jslimit_ = thread_local_.climit_ = kInterruptLimit;
Steve Block44f0eee2011-05-26 01:26:41 +0100429 isolate_->heap()->SetStackLimits();
Ben Murdochb0fe1622011-05-05 13:52:32 +0100430 }
Steve Block44f0eee2011-05-26 01:26:41 +0100431 ExecutionAccess::Unlock(isolate_);
Ben Murdochb0fe1622011-05-05 13:52:32 +0100432 }
433}
434
435
Steve Blocka7e24c12009-10-30 11:49:00 +0000436#ifdef ENABLE_DEBUGGER_SUPPORT
437bool StackGuard::IsDebugBreak() {
Steve Block44f0eee2011-05-26 01:26:41 +0100438 ExecutionAccess access(isolate_);
Steve Blocka7e24c12009-10-30 11:49:00 +0000439 return thread_local_.interrupt_flags_ & DEBUGBREAK;
440}
441
442
443void StackGuard::DebugBreak() {
Steve Block44f0eee2011-05-26 01:26:41 +0100444 ExecutionAccess access(isolate_);
Steve Blocka7e24c12009-10-30 11:49:00 +0000445 thread_local_.interrupt_flags_ |= DEBUGBREAK;
Steve Block6ded16b2010-05-10 14:33:55 +0100446 set_interrupt_limits(access);
Steve Blocka7e24c12009-10-30 11:49:00 +0000447}
448
449
450bool StackGuard::IsDebugCommand() {
Steve Block44f0eee2011-05-26 01:26:41 +0100451 ExecutionAccess access(isolate_);
Steve Blocka7e24c12009-10-30 11:49:00 +0000452 return thread_local_.interrupt_flags_ & DEBUGCOMMAND;
453}
454
455
456void StackGuard::DebugCommand() {
457 if (FLAG_debugger_auto_break) {
Steve Block44f0eee2011-05-26 01:26:41 +0100458 ExecutionAccess access(isolate_);
Steve Blocka7e24c12009-10-30 11:49:00 +0000459 thread_local_.interrupt_flags_ |= DEBUGCOMMAND;
Steve Block6ded16b2010-05-10 14:33:55 +0100460 set_interrupt_limits(access);
Steve Blocka7e24c12009-10-30 11:49:00 +0000461 }
462}
463#endif
464
465void StackGuard::Continue(InterruptFlag after_what) {
Steve Block44f0eee2011-05-26 01:26:41 +0100466 ExecutionAccess access(isolate_);
Steve Blocka7e24c12009-10-30 11:49:00 +0000467 thread_local_.interrupt_flags_ &= ~static_cast<int>(after_what);
Steve Block6ded16b2010-05-10 14:33:55 +0100468 if (!should_postpone_interrupts(access) && !has_pending_interrupts(access)) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000469 reset_limits(access);
470 }
471}
472
473
Steve Blocka7e24c12009-10-30 11:49:00 +0000474char* StackGuard::ArchiveStackGuard(char* to) {
Steve Block44f0eee2011-05-26 01:26:41 +0100475 ExecutionAccess access(isolate_);
Steve Blocka7e24c12009-10-30 11:49:00 +0000476 memcpy(to, reinterpret_cast<char*>(&thread_local_), sizeof(ThreadLocal));
477 ThreadLocal blank;
Steve Block44f0eee2011-05-26 01:26:41 +0100478
479 // Set the stack limits using the old thread_local_.
480 // TODO(isolates): This was the old semantics of constructing a ThreadLocal
481 // (as the ctor called SetStackLimits, which looked at the
482 // current thread_local_ from StackGuard)-- but is this
483 // really what was intended?
484 isolate_->heap()->SetStackLimits();
Steve Blocka7e24c12009-10-30 11:49:00 +0000485 thread_local_ = blank;
Steve Block44f0eee2011-05-26 01:26:41 +0100486
Steve Blocka7e24c12009-10-30 11:49:00 +0000487 return to + sizeof(ThreadLocal);
488}
489
490
491char* StackGuard::RestoreStackGuard(char* from) {
Steve Block44f0eee2011-05-26 01:26:41 +0100492 ExecutionAccess access(isolate_);
Steve Blocka7e24c12009-10-30 11:49:00 +0000493 memcpy(reinterpret_cast<char*>(&thread_local_), from, sizeof(ThreadLocal));
Steve Block44f0eee2011-05-26 01:26:41 +0100494 isolate_->heap()->SetStackLimits();
Steve Blocka7e24c12009-10-30 11:49:00 +0000495 return from + sizeof(ThreadLocal);
496}
497
498
Steve Blocka7e24c12009-10-30 11:49:00 +0000499void StackGuard::FreeThreadResources() {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000500 Isolate::PerIsolateThreadData* per_thread =
501 isolate_->FindOrAllocatePerThreadDataForThisThread();
502 per_thread->set_stack_limit(thread_local_.real_climit_);
Steve Blocka7e24c12009-10-30 11:49:00 +0000503}
504
505
506void StackGuard::ThreadLocal::Clear() {
Steve Blockd0582a62009-12-15 09:54:21 +0000507 real_jslimit_ = kIllegalLimit;
Steve Blocka7e24c12009-10-30 11:49:00 +0000508 jslimit_ = kIllegalLimit;
Steve Blockd0582a62009-12-15 09:54:21 +0000509 real_climit_ = kIllegalLimit;
Steve Blocka7e24c12009-10-30 11:49:00 +0000510 climit_ = kIllegalLimit;
511 nesting_ = 0;
512 postpone_interrupts_nesting_ = 0;
513 interrupt_flags_ = 0;
Steve Blocka7e24c12009-10-30 11:49:00 +0000514}
515
516
Ben Murdoch257744e2011-11-30 15:57:28 +0000517bool StackGuard::ThreadLocal::Initialize(Isolate* isolate) {
Steve Block44f0eee2011-05-26 01:26:41 +0100518 bool should_set_stack_limits = false;
Steve Blockd0582a62009-12-15 09:54:21 +0000519 if (real_climit_ == kIllegalLimit) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000520 // Takes the address of the limit variable in order to find out where
521 // the top of stack is right now.
Steve Block1e0659c2011-05-24 12:43:12 +0100522 const uintptr_t kLimitSize = FLAG_stack_size * KB;
Steve Block3ce2e202009-11-05 08:53:23 +0000523 uintptr_t limit = reinterpret_cast<uintptr_t>(&limit) - kLimitSize;
524 ASSERT(reinterpret_cast<uintptr_t>(&limit) > kLimitSize);
Ben Murdoch257744e2011-11-30 15:57:28 +0000525 real_jslimit_ = SimulatorStack::JsLimitFromCLimit(isolate, limit);
526 jslimit_ = SimulatorStack::JsLimitFromCLimit(isolate, limit);
Steve Blockd0582a62009-12-15 09:54:21 +0000527 real_climit_ = limit;
Steve Blocka7e24c12009-10-30 11:49:00 +0000528 climit_ = limit;
Steve Block44f0eee2011-05-26 01:26:41 +0100529 should_set_stack_limits = true;
Steve Blocka7e24c12009-10-30 11:49:00 +0000530 }
531 nesting_ = 0;
532 postpone_interrupts_nesting_ = 0;
533 interrupt_flags_ = 0;
Steve Block44f0eee2011-05-26 01:26:41 +0100534 return should_set_stack_limits;
Steve Blocka7e24c12009-10-30 11:49:00 +0000535}
536
537
538void StackGuard::ClearThread(const ExecutionAccess& lock) {
539 thread_local_.Clear();
Steve Block44f0eee2011-05-26 01:26:41 +0100540 isolate_->heap()->SetStackLimits();
Steve Blocka7e24c12009-10-30 11:49:00 +0000541}
542
543
544void StackGuard::InitThread(const ExecutionAccess& lock) {
Ben Murdoch257744e2011-11-30 15:57:28 +0000545 if (thread_local_.Initialize(isolate_)) isolate_->heap()->SetStackLimits();
546 Isolate::PerIsolateThreadData* per_thread =
547 isolate_->FindOrAllocatePerThreadDataForThisThread();
548 uintptr_t stored_limit = per_thread->stack_limit();
Steve Blocka7e24c12009-10-30 11:49:00 +0000549 // You should hold the ExecutionAccess lock when you call this.
Steve Block44f0eee2011-05-26 01:26:41 +0100550 if (stored_limit != 0) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000551 SetStackLimit(stored_limit);
Steve Blocka7e24c12009-10-30 11:49:00 +0000552 }
553}
554
555
556// --- C a l l s t o n a t i v e s ---
557
Steve Block44f0eee2011-05-26 01:26:41 +0100558#define RETURN_NATIVE_CALL(name, argc, argv, has_pending_exception) \
559 do { \
Ben Murdoch8b112d22011-06-08 16:22:53 +0100560 Isolate* isolate = Isolate::Current(); \
Steve Block44f0eee2011-05-26 01:26:41 +0100561 Object** args[argc] = argv; \
562 ASSERT(has_pending_exception != NULL); \
Ben Murdoch8b112d22011-06-08 16:22:53 +0100563 return Call(isolate->name##_fun(), \
564 isolate->js_builtins_object(), argc, args, \
Steve Block44f0eee2011-05-26 01:26:41 +0100565 has_pending_exception); \
Steve Blocka7e24c12009-10-30 11:49:00 +0000566 } while (false)
567
568
569Handle<Object> Execution::ToBoolean(Handle<Object> obj) {
570 // See the similar code in runtime.js:ToBoolean.
571 if (obj->IsBoolean()) return obj;
572 bool result = true;
573 if (obj->IsString()) {
574 result = Handle<String>::cast(obj)->length() != 0;
575 } else if (obj->IsNull() || obj->IsUndefined()) {
576 result = false;
577 } else if (obj->IsNumber()) {
578 double value = obj->Number();
579 result = !((value == 0) || isnan(value));
580 }
Steve Block44f0eee2011-05-26 01:26:41 +0100581 return Handle<Object>(HEAP->ToBoolean(result));
Steve Blocka7e24c12009-10-30 11:49:00 +0000582}
583
584
585Handle<Object> Execution::ToNumber(Handle<Object> obj, bool* exc) {
586 RETURN_NATIVE_CALL(to_number, 1, { obj.location() }, exc);
587}
588
589
590Handle<Object> Execution::ToString(Handle<Object> obj, bool* exc) {
591 RETURN_NATIVE_CALL(to_string, 1, { obj.location() }, exc);
592}
593
594
595Handle<Object> Execution::ToDetailString(Handle<Object> obj, bool* exc) {
596 RETURN_NATIVE_CALL(to_detail_string, 1, { obj.location() }, exc);
597}
598
599
600Handle<Object> Execution::ToObject(Handle<Object> obj, bool* exc) {
Ben Murdoch589d6972011-11-30 16:04:58 +0000601 if (obj->IsSpecObject()) return obj;
Steve Blocka7e24c12009-10-30 11:49:00 +0000602 RETURN_NATIVE_CALL(to_object, 1, { obj.location() }, exc);
603}
604
605
606Handle<Object> Execution::ToInteger(Handle<Object> obj, bool* exc) {
607 RETURN_NATIVE_CALL(to_integer, 1, { obj.location() }, exc);
608}
609
610
611Handle<Object> Execution::ToUint32(Handle<Object> obj, bool* exc) {
612 RETURN_NATIVE_CALL(to_uint32, 1, { obj.location() }, exc);
613}
614
615
616Handle<Object> Execution::ToInt32(Handle<Object> obj, bool* exc) {
617 RETURN_NATIVE_CALL(to_int32, 1, { obj.location() }, exc);
618}
619
620
621Handle<Object> Execution::NewDate(double time, bool* exc) {
Steve Block44f0eee2011-05-26 01:26:41 +0100622 Handle<Object> time_obj = FACTORY->NewNumber(time);
Steve Blocka7e24c12009-10-30 11:49:00 +0000623 RETURN_NATIVE_CALL(create_date, 1, { time_obj.location() }, exc);
624}
625
626
627#undef RETURN_NATIVE_CALL
628
629
Ben Murdochf87a2032010-10-22 12:50:53 +0100630Handle<JSRegExp> Execution::NewJSRegExp(Handle<String> pattern,
631 Handle<String> flags,
632 bool* exc) {
Steve Block44f0eee2011-05-26 01:26:41 +0100633 Handle<JSFunction> function = Handle<JSFunction>(
634 pattern->GetIsolate()->global_context()->regexp_function());
Ben Murdochf87a2032010-10-22 12:50:53 +0100635 Handle<Object> re_obj = RegExpImpl::CreateRegExpLiteral(
Steve Block44f0eee2011-05-26 01:26:41 +0100636 function, pattern, flags, exc);
Ben Murdochf87a2032010-10-22 12:50:53 +0100637 if (*exc) return Handle<JSRegExp>();
638 return Handle<JSRegExp>::cast(re_obj);
639}
640
641
Steve Blocka7e24c12009-10-30 11:49:00 +0000642Handle<Object> Execution::CharAt(Handle<String> string, uint32_t index) {
Ben Murdoch8b112d22011-06-08 16:22:53 +0100643 Isolate* isolate = string->GetIsolate();
644 Factory* factory = isolate->factory();
645
Steve Blocka7e24c12009-10-30 11:49:00 +0000646 int int_index = static_cast<int>(index);
647 if (int_index < 0 || int_index >= string->length()) {
Ben Murdoch8b112d22011-06-08 16:22:53 +0100648 return factory->undefined_value();
Steve Blocka7e24c12009-10-30 11:49:00 +0000649 }
650
651 Handle<Object> char_at =
Ben Murdoch8b112d22011-06-08 16:22:53 +0100652 GetProperty(isolate->js_builtins_object(),
653 factory->char_at_symbol());
Steve Blocka7e24c12009-10-30 11:49:00 +0000654 if (!char_at->IsJSFunction()) {
Ben Murdoch8b112d22011-06-08 16:22:53 +0100655 return factory->undefined_value();
Steve Blocka7e24c12009-10-30 11:49:00 +0000656 }
657
658 bool caught_exception;
Ben Murdoch8b112d22011-06-08 16:22:53 +0100659 Handle<Object> index_object = factory->NewNumberFromInt(int_index);
Steve Blocka7e24c12009-10-30 11:49:00 +0000660 Object** index_arg[] = { index_object.location() };
661 Handle<Object> result = TryCall(Handle<JSFunction>::cast(char_at),
662 string,
663 ARRAY_SIZE(index_arg),
664 index_arg,
665 &caught_exception);
666 if (caught_exception) {
Ben Murdoch8b112d22011-06-08 16:22:53 +0100667 return factory->undefined_value();
Steve Blocka7e24c12009-10-30 11:49:00 +0000668 }
669 return result;
670}
671
672
673Handle<JSFunction> Execution::InstantiateFunction(
674 Handle<FunctionTemplateInfo> data, bool* exc) {
Ben Murdoch8b112d22011-06-08 16:22:53 +0100675 Isolate* isolate = data->GetIsolate();
Steve Blocka7e24c12009-10-30 11:49:00 +0000676 // Fast case: see if the function has already been instantiated
677 int serial_number = Smi::cast(data->serial_number())->value();
Steve Block44f0eee2011-05-26 01:26:41 +0100678 Object* elm =
Ben Murdoch8b112d22011-06-08 16:22:53 +0100679 isolate->global_context()->function_cache()->
Steve Block44f0eee2011-05-26 01:26:41 +0100680 GetElementNoExceptionThrown(serial_number);
Steve Blocka7e24c12009-10-30 11:49:00 +0000681 if (elm->IsJSFunction()) return Handle<JSFunction>(JSFunction::cast(elm));
682 // The function has not yet been instantiated in this context; do it.
683 Object** args[1] = { Handle<Object>::cast(data).location() };
684 Handle<Object> result =
Ben Murdoch8b112d22011-06-08 16:22:53 +0100685 Call(isolate->instantiate_fun(),
686 isolate->js_builtins_object(), 1, args, exc);
Steve Blocka7e24c12009-10-30 11:49:00 +0000687 if (*exc) return Handle<JSFunction>::null();
688 return Handle<JSFunction>::cast(result);
689}
690
691
692Handle<JSObject> Execution::InstantiateObject(Handle<ObjectTemplateInfo> data,
693 bool* exc) {
Ben Murdoch8b112d22011-06-08 16:22:53 +0100694 Isolate* isolate = data->GetIsolate();
Steve Blocka7e24c12009-10-30 11:49:00 +0000695 if (data->property_list()->IsUndefined() &&
696 !data->constructor()->IsUndefined()) {
697 // Initialization to make gcc happy.
698 Object* result = NULL;
699 {
Ben Murdoch8b112d22011-06-08 16:22:53 +0100700 HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +0000701 Handle<FunctionTemplateInfo> cons_template =
702 Handle<FunctionTemplateInfo>(
703 FunctionTemplateInfo::cast(data->constructor()));
704 Handle<JSFunction> cons = InstantiateFunction(cons_template, exc);
705 if (*exc) return Handle<JSObject>::null();
706 Handle<Object> value = New(cons, 0, NULL, exc);
707 if (*exc) return Handle<JSObject>::null();
708 result = *value;
709 }
710 ASSERT(!*exc);
711 return Handle<JSObject>(JSObject::cast(result));
712 } else {
713 Object** args[1] = { Handle<Object>::cast(data).location() };
714 Handle<Object> result =
Ben Murdoch8b112d22011-06-08 16:22:53 +0100715 Call(isolate->instantiate_fun(),
716 isolate->js_builtins_object(), 1, args, exc);
Steve Blocka7e24c12009-10-30 11:49:00 +0000717 if (*exc) return Handle<JSObject>::null();
718 return Handle<JSObject>::cast(result);
719 }
720}
721
722
723void Execution::ConfigureInstance(Handle<Object> instance,
724 Handle<Object> instance_template,
725 bool* exc) {
Ben Murdoch8b112d22011-06-08 16:22:53 +0100726 Isolate* isolate = Isolate::Current();
Steve Blocka7e24c12009-10-30 11:49:00 +0000727 Object** args[2] = { instance.location(), instance_template.location() };
Ben Murdoch8b112d22011-06-08 16:22:53 +0100728 Execution::Call(isolate->configure_instance_fun(),
729 isolate->js_builtins_object(), 2, args, exc);
Steve Blocka7e24c12009-10-30 11:49:00 +0000730}
731
732
733Handle<String> Execution::GetStackTraceLine(Handle<Object> recv,
734 Handle<JSFunction> fun,
735 Handle<Object> pos,
736 Handle<Object> is_global) {
Ben Murdoch8b112d22011-06-08 16:22:53 +0100737 Isolate* isolate = fun->GetIsolate();
Steve Blocka7e24c12009-10-30 11:49:00 +0000738 const int argc = 4;
739 Object** args[argc] = { recv.location(),
740 Handle<Object>::cast(fun).location(),
741 pos.location(),
742 is_global.location() };
743 bool caught_exception = false;
Steve Block44f0eee2011-05-26 01:26:41 +0100744 Handle<Object> result =
Ben Murdoch8b112d22011-06-08 16:22:53 +0100745 TryCall(isolate->get_stack_trace_line_fun(),
746 isolate->js_builtins_object(), argc, args,
Steve Block44f0eee2011-05-26 01:26:41 +0100747 &caught_exception);
Ben Murdoch8b112d22011-06-08 16:22:53 +0100748 if (caught_exception || !result->IsString()) {
749 return isolate->factory()->empty_symbol();
750 }
751
Steve Blocka7e24c12009-10-30 11:49:00 +0000752 return Handle<String>::cast(result);
753}
754
755
756static Object* RuntimePreempt() {
Steve Block44f0eee2011-05-26 01:26:41 +0100757 Isolate* isolate = Isolate::Current();
758
Steve Blocka7e24c12009-10-30 11:49:00 +0000759 // Clear the preempt request flag.
Steve Block44f0eee2011-05-26 01:26:41 +0100760 isolate->stack_guard()->Continue(PREEMPT);
Steve Blocka7e24c12009-10-30 11:49:00 +0000761
762 ContextSwitcher::PreemptionReceived();
763
764#ifdef ENABLE_DEBUGGER_SUPPORT
Steve Block44f0eee2011-05-26 01:26:41 +0100765 if (isolate->debug()->InDebugger()) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000766 // If currently in the debugger don't do any actual preemption but record
767 // that preemption occoured while in the debugger.
Steve Block44f0eee2011-05-26 01:26:41 +0100768 isolate->debug()->PreemptionWhileInDebugger();
Steve Blocka7e24c12009-10-30 11:49:00 +0000769 } else {
770 // Perform preemption.
Ben Murdoch257744e2011-11-30 15:57:28 +0000771 v8::Unlocker unlocker(reinterpret_cast<v8::Isolate*>(isolate));
Steve Blocka7e24c12009-10-30 11:49:00 +0000772 Thread::YieldCPU();
773 }
774#else
Steve Block44f0eee2011-05-26 01:26:41 +0100775 { // NOLINT
776 // Perform preemption.
Ben Murdoch257744e2011-11-30 15:57:28 +0000777 v8::Unlocker unlocker(reinterpret_cast<v8::Isolate*>(isolate));
Steve Block44f0eee2011-05-26 01:26:41 +0100778 Thread::YieldCPU();
779 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000780#endif
781
Steve Block44f0eee2011-05-26 01:26:41 +0100782 return isolate->heap()->undefined_value();
Steve Blocka7e24c12009-10-30 11:49:00 +0000783}
784
785
786#ifdef ENABLE_DEBUGGER_SUPPORT
787Object* Execution::DebugBreakHelper() {
Steve Block44f0eee2011-05-26 01:26:41 +0100788 Isolate* isolate = Isolate::Current();
789
Steve Blocka7e24c12009-10-30 11:49:00 +0000790 // Just continue if breaks are disabled.
Steve Block44f0eee2011-05-26 01:26:41 +0100791 if (isolate->debug()->disable_break()) {
792 return isolate->heap()->undefined_value();
Steve Blocka7e24c12009-10-30 11:49:00 +0000793 }
794
Leon Clarkee46be812010-01-19 14:06:41 +0000795 // Ignore debug break during bootstrapping.
Steve Block44f0eee2011-05-26 01:26:41 +0100796 if (isolate->bootstrapper()->IsActive()) {
797 return isolate->heap()->undefined_value();
Leon Clarkee46be812010-01-19 14:06:41 +0000798 }
799
Steve Blocka7e24c12009-10-30 11:49:00 +0000800 {
Ben Murdoch8b112d22011-06-08 16:22:53 +0100801 JavaScriptFrameIterator it(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +0000802 ASSERT(!it.done());
803 Object* fun = it.frame()->function();
804 if (fun && fun->IsJSFunction()) {
805 // Don't stop in builtin functions.
806 if (JSFunction::cast(fun)->IsBuiltin()) {
Steve Block44f0eee2011-05-26 01:26:41 +0100807 return isolate->heap()->undefined_value();
Steve Blocka7e24c12009-10-30 11:49:00 +0000808 }
809 GlobalObject* global = JSFunction::cast(fun)->context()->global();
810 // Don't stop in debugger functions.
Steve Block44f0eee2011-05-26 01:26:41 +0100811 if (isolate->debug()->IsDebugGlobal(global)) {
812 return isolate->heap()->undefined_value();
Steve Blocka7e24c12009-10-30 11:49:00 +0000813 }
814 }
815 }
816
817 // Collect the break state before clearing the flags.
818 bool debug_command_only =
Steve Block44f0eee2011-05-26 01:26:41 +0100819 isolate->stack_guard()->IsDebugCommand() &&
820 !isolate->stack_guard()->IsDebugBreak();
Steve Blocka7e24c12009-10-30 11:49:00 +0000821
Leon Clarkee46be812010-01-19 14:06:41 +0000822 // Clear the debug break request flag.
Steve Block44f0eee2011-05-26 01:26:41 +0100823 isolate->stack_guard()->Continue(DEBUGBREAK);
Leon Clarkee46be812010-01-19 14:06:41 +0000824
825 ProcessDebugMesssages(debug_command_only);
826
827 // Return to continue execution.
Steve Block44f0eee2011-05-26 01:26:41 +0100828 return isolate->heap()->undefined_value();
Leon Clarkee46be812010-01-19 14:06:41 +0000829}
830
831void Execution::ProcessDebugMesssages(bool debug_command_only) {
Ben Murdoch8b112d22011-06-08 16:22:53 +0100832 Isolate* isolate = Isolate::Current();
Leon Clarkee46be812010-01-19 14:06:41 +0000833 // Clear the debug command request flag.
Ben Murdoch8b112d22011-06-08 16:22:53 +0100834 isolate->stack_guard()->Continue(DEBUGCOMMAND);
Steve Blocka7e24c12009-10-30 11:49:00 +0000835
Ben Murdoch8b112d22011-06-08 16:22:53 +0100836 HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +0000837 // Enter the debugger. Just continue if we fail to enter the debugger.
838 EnterDebugger debugger;
839 if (debugger.FailedToEnter()) {
Leon Clarkee46be812010-01-19 14:06:41 +0000840 return;
Steve Blocka7e24c12009-10-30 11:49:00 +0000841 }
842
843 // Notify the debug event listeners. Indicate auto continue if the break was
844 // a debug command break.
Ben Murdoch8b112d22011-06-08 16:22:53 +0100845 isolate->debugger()->OnDebugBreak(isolate->factory()->undefined_value(),
846 debug_command_only);
Steve Blocka7e24c12009-10-30 11:49:00 +0000847}
Leon Clarkee46be812010-01-19 14:06:41 +0000848
849
Steve Blocka7e24c12009-10-30 11:49:00 +0000850#endif
851
John Reck59135872010-11-02 12:39:01 -0700852MaybeObject* Execution::HandleStackGuardInterrupt() {
Steve Block44f0eee2011-05-26 01:26:41 +0100853 Isolate* isolate = Isolate::Current();
854 StackGuard* stack_guard = isolate->stack_guard();
855 isolate->counters()->stack_interrupts()->Increment();
856 if (stack_guard->IsRuntimeProfilerTick()) {
857 isolate->counters()->runtime_profiler_ticks()->Increment();
858 stack_guard->Continue(RUNTIME_PROFILER_TICK);
859 isolate->runtime_profiler()->OptimizeNow();
Ben Murdochb0fe1622011-05-05 13:52:32 +0100860 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000861#ifdef ENABLE_DEBUGGER_SUPPORT
Steve Block44f0eee2011-05-26 01:26:41 +0100862 if (stack_guard->IsDebugBreak() || stack_guard->IsDebugCommand()) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000863 DebugBreakHelper();
864 }
865#endif
Steve Block44f0eee2011-05-26 01:26:41 +0100866 if (stack_guard->IsPreempted()) RuntimePreempt();
867 if (stack_guard->IsTerminateExecution()) {
868 stack_guard->Continue(TERMINATE);
869 return isolate->TerminateExecution();
Steve Blocka7e24c12009-10-30 11:49:00 +0000870 }
Steve Block44f0eee2011-05-26 01:26:41 +0100871 if (stack_guard->IsInterrupted()) {
872 stack_guard->Continue(INTERRUPT);
873 return isolate->StackOverflow();
Steve Blocka7e24c12009-10-30 11:49:00 +0000874 }
Steve Block44f0eee2011-05-26 01:26:41 +0100875 return isolate->heap()->undefined_value();
Steve Blocka7e24c12009-10-30 11:49:00 +0000876}
877
Steve Blocka7e24c12009-10-30 11:49:00 +0000878} } // namespace v8::internal