blob: 561897567378e90e0d6011334aaf3ffbd65648cb [file] [log] [blame]
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001// Copyright 2012 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 Murdoch3ef787d2012-04-12 10:51:47 +010036#include "isolate-inl.h"
Ben Murdochb0fe1622011-05-05 13:52:32 +010037#include "runtime-profiler.h"
Steve Blockd0582a62009-12-15 09:54:21 +000038#include "simulator.h"
Steve Blocka7e24c12009-10-30 11:49:00 +000039#include "v8threads.h"
Ben Murdochb0fe1622011-05-05 13:52:32 +010040#include "vm-state-inl.h"
Steve Blocka7e24c12009-10-30 11:49:00 +000041
42namespace v8 {
43namespace internal {
44
45
Steve Block44f0eee2011-05-26 01:26:41 +010046StackGuard::StackGuard()
47 : isolate_(NULL) {
48}
49
50
51void StackGuard::set_interrupt_limits(const ExecutionAccess& lock) {
52 ASSERT(isolate_ != NULL);
53 // Ignore attempts to interrupt when interrupts are postponed.
54 if (should_postpone_interrupts(lock)) return;
55 thread_local_.jslimit_ = kInterruptLimit;
56 thread_local_.climit_ = kInterruptLimit;
57 isolate_->heap()->SetStackLimits();
58}
59
60
61void StackGuard::reset_limits(const ExecutionAccess& lock) {
62 ASSERT(isolate_ != NULL);
63 thread_local_.jslimit_ = thread_local_.real_jslimit_;
64 thread_local_.climit_ = thread_local_.real_climit_;
65 isolate_->heap()->SetStackLimits();
66}
67
68
Ben Murdoch3ef787d2012-04-12 10:51:47 +010069static Handle<Object> Invoke(bool is_construct,
70 Handle<JSFunction> function,
Steve Blocka7e24c12009-10-30 11:49:00 +000071 Handle<Object> receiver,
72 int argc,
Ben Murdoch3ef787d2012-04-12 10:51:47 +010073 Handle<Object> args[],
Steve Blocka7e24c12009-10-30 11:49:00 +000074 bool* has_pending_exception) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +010075 Isolate* isolate = function->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +010076
Steve Blocka7e24c12009-10-30 11:49:00 +000077 // Entering JavaScript.
Steve Block44f0eee2011-05-26 01:26:41 +010078 VMState state(isolate, JS);
Steve Blocka7e24c12009-10-30 11:49:00 +000079
80 // Placeholder for return value.
John Reck59135872010-11-02 12:39:01 -070081 MaybeObject* value = reinterpret_cast<Object*>(kZapValue);
Steve Blocka7e24c12009-10-30 11:49:00 +000082
Ben Murdoch3ef787d2012-04-12 10:51:47 +010083 typedef Object* (*JSEntryFunction)(byte* entry,
84 Object* function,
85 Object* receiver,
86 int argc,
87 Object*** args);
Steve Blocka7e24c12009-10-30 11:49:00 +000088
Ben Murdoch3ef787d2012-04-12 10:51:47 +010089 Handle<Code> code = is_construct
90 ? isolate->factory()->js_construct_entry_code()
91 : isolate->factory()->js_entry_code();
Steve Blocka7e24c12009-10-30 11:49:00 +000092
93 // Convert calls on global objects to be calls on the global
94 // receiver instead to avoid having a 'this' pointer which refers
95 // directly to a global object.
96 if (receiver->IsGlobalObject()) {
97 Handle<GlobalObject> global = Handle<GlobalObject>::cast(receiver);
98 receiver = Handle<JSObject>(global->global_receiver());
99 }
100
Leon Clarkee46be812010-01-19 14:06:41 +0000101 // Make sure that the global object of the context we're about to
102 // make the current one is indeed a global object.
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100103 ASSERT(function->context()->global()->IsGlobalObject());
Leon Clarkee46be812010-01-19 14:06:41 +0000104
Steve Blocka7e24c12009-10-30 11:49:00 +0000105 {
106 // Save and restore context around invocation and block the
107 // allocation of handles without explicit handle scopes.
Steve Block44f0eee2011-05-26 01:26:41 +0100108 SaveContext save(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +0000109 NoHandleAllocation na;
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100110 JSEntryFunction stub_entry = FUNCTION_CAST<JSEntryFunction>(code->entry());
Steve Blocka7e24c12009-10-30 11:49:00 +0000111
112 // Call the function through the right JS entry stub.
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100113 byte* function_entry = function->code()->entry();
114 JSFunction* func = *function;
115 Object* recv = *receiver;
116 Object*** argv = reinterpret_cast<Object***>(args);
117 value =
118 CALL_GENERATED_CODE(stub_entry, function_entry, func, recv, argc, argv);
Steve Blocka7e24c12009-10-30 11:49:00 +0000119 }
120
121#ifdef DEBUG
122 value->Verify();
123#endif
124
125 // Update the pending exception flag and return the value.
126 *has_pending_exception = value->IsException();
Steve Block44f0eee2011-05-26 01:26:41 +0100127 ASSERT(*has_pending_exception == Isolate::Current()->has_pending_exception());
Steve Blocka7e24c12009-10-30 11:49:00 +0000128 if (*has_pending_exception) {
Steve Block44f0eee2011-05-26 01:26:41 +0100129 isolate->ReportPendingMessages();
130 if (isolate->pending_exception() == Failure::OutOfMemoryException()) {
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000131 if (!isolate->ignore_out_of_memory()) {
Ben Murdoche0cee9b2011-05-25 10:26:03 +0100132 V8::FatalProcessOutOfMemory("JS", true);
133 }
134 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000135 return Handle<Object>();
136 } else {
Steve Block44f0eee2011-05-26 01:26:41 +0100137 isolate->clear_pending_message();
Steve Blocka7e24c12009-10-30 11:49:00 +0000138 }
139
Steve Block44f0eee2011-05-26 01:26:41 +0100140 return Handle<Object>(value->ToObjectUnchecked(), isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +0000141}
142
143
Ben Murdoch257744e2011-11-30 15:57:28 +0000144Handle<Object> Execution::Call(Handle<Object> callable,
Steve Blocka7e24c12009-10-30 11:49:00 +0000145 Handle<Object> receiver,
146 int argc,
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100147 Handle<Object> argv[],
Ben Murdoch589d6972011-11-30 16:04:58 +0000148 bool* pending_exception,
149 bool convert_receiver) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100150 *pending_exception = false;
151
Ben Murdoch257744e2011-11-30 15:57:28 +0000152 if (!callable->IsJSFunction()) {
153 callable = TryGetFunctionDelegate(callable, pending_exception);
154 if (*pending_exception) return callable;
155 }
156 Handle<JSFunction> func = Handle<JSFunction>::cast(callable);
Ben Murdoch589d6972011-11-30 16:04:58 +0000157
158 // In non-strict mode, convert receiver.
159 if (convert_receiver && !receiver->IsJSReceiver() &&
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100160 !func->shared()->native() && func->shared()->is_classic_mode()) {
Ben Murdoch589d6972011-11-30 16:04:58 +0000161 if (receiver->IsUndefined() || receiver->IsNull()) {
162 Object* global = func->context()->global()->global_receiver();
163 // Under some circumstances, 'global' can be the JSBuiltinsObject
164 // In that case, don't rewrite.
165 // (FWIW, the same holds for GetIsolate()->global()->global_receiver().)
166 if (!global->IsJSBuiltinsObject()) receiver = Handle<Object>(global);
167 } else {
168 receiver = ToObject(receiver, pending_exception);
169 }
170 if (*pending_exception) return callable;
171 }
172
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100173 return Invoke(false, func, receiver, argc, argv, pending_exception);
Steve Blocka7e24c12009-10-30 11:49:00 +0000174}
175
176
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100177Handle<Object> Execution::New(Handle<JSFunction> func,
178 int argc,
179 Handle<Object> argv[],
180 bool* pending_exception) {
181 return Invoke(true, func, Isolate::Current()->global(), argc, argv,
Steve Block44f0eee2011-05-26 01:26:41 +0100182 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,
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100189 Handle<Object> args[],
Steve Blocka7e24c12009-10-30 11:49:00 +0000190 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);
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100198 *caught_exception = false;
Steve Blocka7e24c12009-10-30 11:49:00 +0000199
200 Handle<Object> result = Invoke(false, func, receiver, argc, args,
201 caught_exception);
202
203 if (*caught_exception) {
204 ASSERT(catcher.HasCaught());
Steve Block44f0eee2011-05-26 01:26:41 +0100205 Isolate* isolate = Isolate::Current();
206 ASSERT(isolate->has_pending_exception());
207 ASSERT(isolate->external_caught_exception());
208 if (isolate->pending_exception() ==
209 isolate->heap()->termination_exception()) {
210 result = isolate->factory()->termination_exception();
Steve Blocka7e24c12009-10-30 11:49:00 +0000211 } else {
212 result = v8::Utils::OpenHandle(*catcher.Exception());
213 }
Steve Block44f0eee2011-05-26 01:26:41 +0100214 isolate->OptionalRescheduleException(true);
Steve Blocka7e24c12009-10-30 11:49:00 +0000215 }
216
Steve Block44f0eee2011-05-26 01:26:41 +0100217 ASSERT(!Isolate::Current()->has_pending_exception());
218 ASSERT(!Isolate::Current()->external_caught_exception());
Steve Blocka7e24c12009-10-30 11:49:00 +0000219 return result;
220}
221
222
223Handle<Object> Execution::GetFunctionDelegate(Handle<Object> object) {
224 ASSERT(!object->IsJSFunction());
Ben Murdoch8b112d22011-06-08 16:22:53 +0100225 Isolate* isolate = Isolate::Current();
226 Factory* factory = isolate->factory();
Steve Blocka7e24c12009-10-30 11:49:00 +0000227
228 // If you return a function from here, it will be called when an
229 // attempt is made to call the given object as a function.
230
Ben Murdoch589d6972011-11-30 16:04:58 +0000231 // If object is a function proxy, get its handler. Iterate if necessary.
232 Object* fun = *object;
233 while (fun->IsJSFunctionProxy()) {
234 fun = JSFunctionProxy::cast(fun)->call_trap();
235 }
236 if (fun->IsJSFunction()) return Handle<Object>(fun);
237
Steve Blocka7e24c12009-10-30 11:49:00 +0000238 // Objects created through the API can have an instance-call handler
239 // that should be used when calling the object as a function.
Ben Murdoch589d6972011-11-30 16:04:58 +0000240 if (fun->IsHeapObject() &&
241 HeapObject::cast(fun)->map()->has_instance_call_handler()) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000242 return Handle<JSFunction>(
Ben Murdoch8b112d22011-06-08 16:22:53 +0100243 isolate->global_context()->call_as_function_delegate());
Steve Blocka7e24c12009-10-30 11:49:00 +0000244 }
245
Ben Murdoch8b112d22011-06-08 16:22:53 +0100246 return factory->undefined_value();
Steve Blocka7e24c12009-10-30 11:49:00 +0000247}
248
249
Ben Murdoch257744e2011-11-30 15:57:28 +0000250Handle<Object> Execution::TryGetFunctionDelegate(Handle<Object> object,
251 bool* has_pending_exception) {
252 ASSERT(!object->IsJSFunction());
253 Isolate* isolate = Isolate::Current();
254
Ben Murdoch589d6972011-11-30 16:04:58 +0000255 // If object is a function proxy, get its handler. Iterate if necessary.
256 Object* fun = *object;
257 while (fun->IsJSFunctionProxy()) {
258 fun = JSFunctionProxy::cast(fun)->call_trap();
259 }
260 if (fun->IsJSFunction()) return Handle<Object>(fun);
261
Ben Murdoch257744e2011-11-30 15:57:28 +0000262 // Objects created through the API can have an instance-call handler
263 // that should be used when calling the object as a function.
Ben Murdoch589d6972011-11-30 16:04:58 +0000264 if (fun->IsHeapObject() &&
265 HeapObject::cast(fun)->map()->has_instance_call_handler()) {
Ben Murdoch257744e2011-11-30 15:57:28 +0000266 return Handle<JSFunction>(
267 isolate->global_context()->call_as_function_delegate());
268 }
269
270 // If the Object doesn't have an instance-call handler we should
271 // throw a non-callable exception.
272 i::Handle<i::Object> error_obj = isolate->factory()->NewTypeError(
273 "called_non_callable", i::HandleVector<i::Object>(&object, 1));
274 isolate->Throw(*error_obj);
275 *has_pending_exception = true;
276
277 return isolate->factory()->undefined_value();
278}
279
280
Steve Blocka7e24c12009-10-30 11:49:00 +0000281Handle<Object> Execution::GetConstructorDelegate(Handle<Object> object) {
282 ASSERT(!object->IsJSFunction());
Ben Murdoch8b112d22011-06-08 16:22:53 +0100283 Isolate* isolate = Isolate::Current();
Steve Blocka7e24c12009-10-30 11:49:00 +0000284
285 // If you return a function from here, it will be called when an
286 // attempt is made to call the given object as a constructor.
287
Ben Murdoch589d6972011-11-30 16:04:58 +0000288 // If object is a function proxies, get its handler. Iterate if necessary.
289 Object* fun = *object;
290 while (fun->IsJSFunctionProxy()) {
291 fun = JSFunctionProxy::cast(fun)->call_trap();
292 }
293 if (fun->IsJSFunction()) return Handle<Object>(fun);
294
Steve Blocka7e24c12009-10-30 11:49:00 +0000295 // Objects created through the API can have an instance-call handler
296 // that should be used when calling the object as a function.
Ben Murdoch589d6972011-11-30 16:04:58 +0000297 if (fun->IsHeapObject() &&
298 HeapObject::cast(fun)->map()->has_instance_call_handler()) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000299 return Handle<JSFunction>(
Ben Murdoch8b112d22011-06-08 16:22:53 +0100300 isolate->global_context()->call_as_constructor_delegate());
Steve Blocka7e24c12009-10-30 11:49:00 +0000301 }
302
Ben Murdoch8b112d22011-06-08 16:22:53 +0100303 return isolate->factory()->undefined_value();
Steve Blocka7e24c12009-10-30 11:49:00 +0000304}
305
306
Ben Murdoch257744e2011-11-30 15:57:28 +0000307Handle<Object> Execution::TryGetConstructorDelegate(
308 Handle<Object> object,
309 bool* has_pending_exception) {
310 ASSERT(!object->IsJSFunction());
311 Isolate* isolate = Isolate::Current();
312
313 // If you return a function from here, it will be called when an
314 // attempt is made to call the given object as a constructor.
315
Ben Murdoch589d6972011-11-30 16:04:58 +0000316 // If object is a function proxies, get its handler. Iterate if necessary.
317 Object* fun = *object;
318 while (fun->IsJSFunctionProxy()) {
319 fun = JSFunctionProxy::cast(fun)->call_trap();
320 }
321 if (fun->IsJSFunction()) return Handle<Object>(fun);
322
Ben Murdoch257744e2011-11-30 15:57:28 +0000323 // Objects created through the API can have an instance-call handler
324 // that should be used when calling the object as a function.
Ben Murdoch589d6972011-11-30 16:04:58 +0000325 if (fun->IsHeapObject() &&
326 HeapObject::cast(fun)->map()->has_instance_call_handler()) {
Ben Murdoch257744e2011-11-30 15:57:28 +0000327 return Handle<JSFunction>(
328 isolate->global_context()->call_as_constructor_delegate());
329 }
330
331 // If the Object doesn't have an instance-call handler we should
332 // throw a non-callable exception.
333 i::Handle<i::Object> error_obj = isolate->factory()->NewTypeError(
334 "called_non_callable", i::HandleVector<i::Object>(&object, 1));
335 isolate->Throw(*error_obj);
336 *has_pending_exception = true;
337
338 return isolate->factory()->undefined_value();
339}
340
341
Steve Blocka7e24c12009-10-30 11:49:00 +0000342bool StackGuard::IsStackOverflow() {
Steve Block44f0eee2011-05-26 01:26:41 +0100343 ExecutionAccess access(isolate_);
Steve Blocka7e24c12009-10-30 11:49:00 +0000344 return (thread_local_.jslimit_ != kInterruptLimit &&
345 thread_local_.climit_ != kInterruptLimit);
346}
347
348
349void StackGuard::EnableInterrupts() {
Steve Block44f0eee2011-05-26 01:26:41 +0100350 ExecutionAccess access(isolate_);
Steve Block6ded16b2010-05-10 14:33:55 +0100351 if (has_pending_interrupts(access)) {
352 set_interrupt_limits(access);
Steve Blocka7e24c12009-10-30 11:49:00 +0000353 }
354}
355
356
357void StackGuard::SetStackLimit(uintptr_t limit) {
Steve Block44f0eee2011-05-26 01:26:41 +0100358 ExecutionAccess access(isolate_);
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100359 // If the current limits are special (e.g. due to a pending interrupt) then
Steve Blocka7e24c12009-10-30 11:49:00 +0000360 // leave them alone.
Ben Murdoch257744e2011-11-30 15:57:28 +0000361 uintptr_t jslimit = SimulatorStack::JsLimitFromCLimit(isolate_, limit);
Steve Blockd0582a62009-12-15 09:54:21 +0000362 if (thread_local_.jslimit_ == thread_local_.real_jslimit_) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000363 thread_local_.jslimit_ = jslimit;
Steve Blocka7e24c12009-10-30 11:49:00 +0000364 }
Steve Blockd0582a62009-12-15 09:54:21 +0000365 if (thread_local_.climit_ == thread_local_.real_climit_) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000366 thread_local_.climit_ = limit;
367 }
Steve Blockd0582a62009-12-15 09:54:21 +0000368 thread_local_.real_climit_ = limit;
369 thread_local_.real_jslimit_ = jslimit;
Steve Blocka7e24c12009-10-30 11:49:00 +0000370}
371
372
373void StackGuard::DisableInterrupts() {
Steve Block44f0eee2011-05-26 01:26:41 +0100374 ExecutionAccess access(isolate_);
Steve Blocka7e24c12009-10-30 11:49:00 +0000375 reset_limits(access);
376}
377
378
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100379bool StackGuard::ShouldPostponeInterrupts() {
380 ExecutionAccess access(isolate_);
381 return should_postpone_interrupts(access);
382}
383
384
Steve Blocka7e24c12009-10-30 11:49:00 +0000385bool StackGuard::IsInterrupted() {
Steve Block44f0eee2011-05-26 01:26:41 +0100386 ExecutionAccess access(isolate_);
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100387 return (thread_local_.interrupt_flags_ & INTERRUPT) != 0;
Steve Blocka7e24c12009-10-30 11:49:00 +0000388}
389
390
391void StackGuard::Interrupt() {
Steve Block44f0eee2011-05-26 01:26:41 +0100392 ExecutionAccess access(isolate_);
Steve Blocka7e24c12009-10-30 11:49:00 +0000393 thread_local_.interrupt_flags_ |= INTERRUPT;
Steve Block6ded16b2010-05-10 14:33:55 +0100394 set_interrupt_limits(access);
Steve Blocka7e24c12009-10-30 11:49:00 +0000395}
396
397
398bool StackGuard::IsPreempted() {
Steve Block44f0eee2011-05-26 01:26:41 +0100399 ExecutionAccess access(isolate_);
Steve Blocka7e24c12009-10-30 11:49:00 +0000400 return thread_local_.interrupt_flags_ & PREEMPT;
401}
402
403
404void StackGuard::Preempt() {
Steve Block44f0eee2011-05-26 01:26:41 +0100405 ExecutionAccess access(isolate_);
Steve Blocka7e24c12009-10-30 11:49:00 +0000406 thread_local_.interrupt_flags_ |= PREEMPT;
Steve Block6ded16b2010-05-10 14:33:55 +0100407 set_interrupt_limits(access);
Steve Blocka7e24c12009-10-30 11:49:00 +0000408}
409
410
411bool StackGuard::IsTerminateExecution() {
Steve Block44f0eee2011-05-26 01:26:41 +0100412 ExecutionAccess access(isolate_);
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100413 return (thread_local_.interrupt_flags_ & TERMINATE) != 0;
Steve Blocka7e24c12009-10-30 11:49:00 +0000414}
415
416
417void StackGuard::TerminateExecution() {
Steve Block44f0eee2011-05-26 01:26:41 +0100418 ExecutionAccess access(isolate_);
Steve Blocka7e24c12009-10-30 11:49:00 +0000419 thread_local_.interrupt_flags_ |= TERMINATE;
Steve Block6ded16b2010-05-10 14:33:55 +0100420 set_interrupt_limits(access);
Steve Blocka7e24c12009-10-30 11:49:00 +0000421}
422
423
Ben Murdochb0fe1622011-05-05 13:52:32 +0100424bool StackGuard::IsRuntimeProfilerTick() {
Steve Block44f0eee2011-05-26 01:26:41 +0100425 ExecutionAccess access(isolate_);
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100426 return (thread_local_.interrupt_flags_ & RUNTIME_PROFILER_TICK) != 0;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100427}
428
429
430void StackGuard::RequestRuntimeProfilerTick() {
431 // Ignore calls if we're not optimizing or if we can't get the lock.
Steve Block44f0eee2011-05-26 01:26:41 +0100432 if (FLAG_opt && ExecutionAccess::TryLock(isolate_)) {
Ben Murdochb0fe1622011-05-05 13:52:32 +0100433 thread_local_.interrupt_flags_ |= RUNTIME_PROFILER_TICK;
434 if (thread_local_.postpone_interrupts_nesting_ == 0) {
435 thread_local_.jslimit_ = thread_local_.climit_ = kInterruptLimit;
Steve Block44f0eee2011-05-26 01:26:41 +0100436 isolate_->heap()->SetStackLimits();
Ben Murdochb0fe1622011-05-05 13:52:32 +0100437 }
Steve Block44f0eee2011-05-26 01:26:41 +0100438 ExecutionAccess::Unlock(isolate_);
Ben Murdochb0fe1622011-05-05 13:52:32 +0100439 }
440}
441
442
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100443bool StackGuard::IsGCRequest() {
444 ExecutionAccess access(isolate_);
445 return (thread_local_.interrupt_flags_ & GC_REQUEST) != 0;
446}
447
448
449void StackGuard::RequestGC() {
450 ExecutionAccess access(isolate_);
451 thread_local_.interrupt_flags_ |= GC_REQUEST;
452 if (thread_local_.postpone_interrupts_nesting_ == 0) {
453 thread_local_.jslimit_ = thread_local_.climit_ = kInterruptLimit;
454 isolate_->heap()->SetStackLimits();
455 }
456}
457
458
Steve Blocka7e24c12009-10-30 11:49:00 +0000459#ifdef ENABLE_DEBUGGER_SUPPORT
460bool StackGuard::IsDebugBreak() {
Steve Block44f0eee2011-05-26 01:26:41 +0100461 ExecutionAccess access(isolate_);
Steve Blocka7e24c12009-10-30 11:49:00 +0000462 return thread_local_.interrupt_flags_ & DEBUGBREAK;
463}
464
465
466void StackGuard::DebugBreak() {
Steve Block44f0eee2011-05-26 01:26:41 +0100467 ExecutionAccess access(isolate_);
Steve Blocka7e24c12009-10-30 11:49:00 +0000468 thread_local_.interrupt_flags_ |= DEBUGBREAK;
Steve Block6ded16b2010-05-10 14:33:55 +0100469 set_interrupt_limits(access);
Steve Blocka7e24c12009-10-30 11:49:00 +0000470}
471
472
473bool StackGuard::IsDebugCommand() {
Steve Block44f0eee2011-05-26 01:26:41 +0100474 ExecutionAccess access(isolate_);
Steve Blocka7e24c12009-10-30 11:49:00 +0000475 return thread_local_.interrupt_flags_ & DEBUGCOMMAND;
476}
477
478
479void StackGuard::DebugCommand() {
480 if (FLAG_debugger_auto_break) {
Steve Block44f0eee2011-05-26 01:26:41 +0100481 ExecutionAccess access(isolate_);
Steve Blocka7e24c12009-10-30 11:49:00 +0000482 thread_local_.interrupt_flags_ |= DEBUGCOMMAND;
Steve Block6ded16b2010-05-10 14:33:55 +0100483 set_interrupt_limits(access);
Steve Blocka7e24c12009-10-30 11:49:00 +0000484 }
485}
486#endif
487
488void StackGuard::Continue(InterruptFlag after_what) {
Steve Block44f0eee2011-05-26 01:26:41 +0100489 ExecutionAccess access(isolate_);
Steve Blocka7e24c12009-10-30 11:49:00 +0000490 thread_local_.interrupt_flags_ &= ~static_cast<int>(after_what);
Steve Block6ded16b2010-05-10 14:33:55 +0100491 if (!should_postpone_interrupts(access) && !has_pending_interrupts(access)) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000492 reset_limits(access);
493 }
494}
495
496
Steve Blocka7e24c12009-10-30 11:49:00 +0000497char* StackGuard::ArchiveStackGuard(char* to) {
Steve Block44f0eee2011-05-26 01:26:41 +0100498 ExecutionAccess access(isolate_);
Steve Blocka7e24c12009-10-30 11:49:00 +0000499 memcpy(to, reinterpret_cast<char*>(&thread_local_), sizeof(ThreadLocal));
500 ThreadLocal blank;
Steve Block44f0eee2011-05-26 01:26:41 +0100501
502 // Set the stack limits using the old thread_local_.
503 // TODO(isolates): This was the old semantics of constructing a ThreadLocal
504 // (as the ctor called SetStackLimits, which looked at the
505 // current thread_local_ from StackGuard)-- but is this
506 // really what was intended?
507 isolate_->heap()->SetStackLimits();
Steve Blocka7e24c12009-10-30 11:49:00 +0000508 thread_local_ = blank;
Steve Block44f0eee2011-05-26 01:26:41 +0100509
Steve Blocka7e24c12009-10-30 11:49:00 +0000510 return to + sizeof(ThreadLocal);
511}
512
513
514char* StackGuard::RestoreStackGuard(char* from) {
Steve Block44f0eee2011-05-26 01:26:41 +0100515 ExecutionAccess access(isolate_);
Steve Blocka7e24c12009-10-30 11:49:00 +0000516 memcpy(reinterpret_cast<char*>(&thread_local_), from, sizeof(ThreadLocal));
Steve Block44f0eee2011-05-26 01:26:41 +0100517 isolate_->heap()->SetStackLimits();
Steve Blocka7e24c12009-10-30 11:49:00 +0000518 return from + sizeof(ThreadLocal);
519}
520
521
Steve Blocka7e24c12009-10-30 11:49:00 +0000522void StackGuard::FreeThreadResources() {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000523 Isolate::PerIsolateThreadData* per_thread =
524 isolate_->FindOrAllocatePerThreadDataForThisThread();
525 per_thread->set_stack_limit(thread_local_.real_climit_);
Steve Blocka7e24c12009-10-30 11:49:00 +0000526}
527
528
529void StackGuard::ThreadLocal::Clear() {
Steve Blockd0582a62009-12-15 09:54:21 +0000530 real_jslimit_ = kIllegalLimit;
Steve Blocka7e24c12009-10-30 11:49:00 +0000531 jslimit_ = kIllegalLimit;
Steve Blockd0582a62009-12-15 09:54:21 +0000532 real_climit_ = kIllegalLimit;
Steve Blocka7e24c12009-10-30 11:49:00 +0000533 climit_ = kIllegalLimit;
534 nesting_ = 0;
535 postpone_interrupts_nesting_ = 0;
536 interrupt_flags_ = 0;
Steve Blocka7e24c12009-10-30 11:49:00 +0000537}
538
539
Ben Murdoch257744e2011-11-30 15:57:28 +0000540bool StackGuard::ThreadLocal::Initialize(Isolate* isolate) {
Steve Block44f0eee2011-05-26 01:26:41 +0100541 bool should_set_stack_limits = false;
Steve Blockd0582a62009-12-15 09:54:21 +0000542 if (real_climit_ == kIllegalLimit) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000543 // Takes the address of the limit variable in order to find out where
544 // the top of stack is right now.
Steve Block1e0659c2011-05-24 12:43:12 +0100545 const uintptr_t kLimitSize = FLAG_stack_size * KB;
Steve Block3ce2e202009-11-05 08:53:23 +0000546 uintptr_t limit = reinterpret_cast<uintptr_t>(&limit) - kLimitSize;
547 ASSERT(reinterpret_cast<uintptr_t>(&limit) > kLimitSize);
Ben Murdoch257744e2011-11-30 15:57:28 +0000548 real_jslimit_ = SimulatorStack::JsLimitFromCLimit(isolate, limit);
549 jslimit_ = SimulatorStack::JsLimitFromCLimit(isolate, limit);
Steve Blockd0582a62009-12-15 09:54:21 +0000550 real_climit_ = limit;
Steve Blocka7e24c12009-10-30 11:49:00 +0000551 climit_ = limit;
Steve Block44f0eee2011-05-26 01:26:41 +0100552 should_set_stack_limits = true;
Steve Blocka7e24c12009-10-30 11:49:00 +0000553 }
554 nesting_ = 0;
555 postpone_interrupts_nesting_ = 0;
556 interrupt_flags_ = 0;
Steve Block44f0eee2011-05-26 01:26:41 +0100557 return should_set_stack_limits;
Steve Blocka7e24c12009-10-30 11:49:00 +0000558}
559
560
561void StackGuard::ClearThread(const ExecutionAccess& lock) {
562 thread_local_.Clear();
Steve Block44f0eee2011-05-26 01:26:41 +0100563 isolate_->heap()->SetStackLimits();
Steve Blocka7e24c12009-10-30 11:49:00 +0000564}
565
566
567void StackGuard::InitThread(const ExecutionAccess& lock) {
Ben Murdoch257744e2011-11-30 15:57:28 +0000568 if (thread_local_.Initialize(isolate_)) isolate_->heap()->SetStackLimits();
569 Isolate::PerIsolateThreadData* per_thread =
570 isolate_->FindOrAllocatePerThreadDataForThisThread();
571 uintptr_t stored_limit = per_thread->stack_limit();
Steve Blocka7e24c12009-10-30 11:49:00 +0000572 // You should hold the ExecutionAccess lock when you call this.
Steve Block44f0eee2011-05-26 01:26:41 +0100573 if (stored_limit != 0) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000574 SetStackLimit(stored_limit);
Steve Blocka7e24c12009-10-30 11:49:00 +0000575 }
576}
577
578
579// --- C a l l s t o n a t i v e s ---
580
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100581#define RETURN_NATIVE_CALL(name, args, has_pending_exception) \
582 do { \
583 Isolate* isolate = Isolate::Current(); \
584 Handle<Object> argv[] = args; \
585 ASSERT(has_pending_exception != NULL); \
586 return Call(isolate->name##_fun(), \
587 isolate->js_builtins_object(), \
588 ARRAY_SIZE(argv), argv, \
589 has_pending_exception); \
Steve Blocka7e24c12009-10-30 11:49:00 +0000590 } while (false)
591
592
593Handle<Object> Execution::ToBoolean(Handle<Object> obj) {
594 // See the similar code in runtime.js:ToBoolean.
595 if (obj->IsBoolean()) return obj;
596 bool result = true;
597 if (obj->IsString()) {
598 result = Handle<String>::cast(obj)->length() != 0;
599 } else if (obj->IsNull() || obj->IsUndefined()) {
600 result = false;
601 } else if (obj->IsNumber()) {
602 double value = obj->Number();
603 result = !((value == 0) || isnan(value));
604 }
Steve Block44f0eee2011-05-26 01:26:41 +0100605 return Handle<Object>(HEAP->ToBoolean(result));
Steve Blocka7e24c12009-10-30 11:49:00 +0000606}
607
608
609Handle<Object> Execution::ToNumber(Handle<Object> obj, bool* exc) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100610 RETURN_NATIVE_CALL(to_number, { obj }, exc);
Steve Blocka7e24c12009-10-30 11:49:00 +0000611}
612
613
614Handle<Object> Execution::ToString(Handle<Object> obj, bool* exc) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100615 RETURN_NATIVE_CALL(to_string, { obj }, exc);
Steve Blocka7e24c12009-10-30 11:49:00 +0000616}
617
618
619Handle<Object> Execution::ToDetailString(Handle<Object> obj, bool* exc) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100620 RETURN_NATIVE_CALL(to_detail_string, { obj }, exc);
Steve Blocka7e24c12009-10-30 11:49:00 +0000621}
622
623
624Handle<Object> Execution::ToObject(Handle<Object> obj, bool* exc) {
Ben Murdoch589d6972011-11-30 16:04:58 +0000625 if (obj->IsSpecObject()) return obj;
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100626 RETURN_NATIVE_CALL(to_object, { obj }, exc);
Steve Blocka7e24c12009-10-30 11:49:00 +0000627}
628
629
630Handle<Object> Execution::ToInteger(Handle<Object> obj, bool* exc) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100631 RETURN_NATIVE_CALL(to_integer, { obj }, exc);
Steve Blocka7e24c12009-10-30 11:49:00 +0000632}
633
634
635Handle<Object> Execution::ToUint32(Handle<Object> obj, bool* exc) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100636 RETURN_NATIVE_CALL(to_uint32, { obj }, exc);
Steve Blocka7e24c12009-10-30 11:49:00 +0000637}
638
639
640Handle<Object> Execution::ToInt32(Handle<Object> obj, bool* exc) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100641 RETURN_NATIVE_CALL(to_int32, { obj }, exc);
Steve Blocka7e24c12009-10-30 11:49:00 +0000642}
643
644
645Handle<Object> Execution::NewDate(double time, bool* exc) {
Steve Block44f0eee2011-05-26 01:26:41 +0100646 Handle<Object> time_obj = FACTORY->NewNumber(time);
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100647 RETURN_NATIVE_CALL(create_date, { time_obj }, exc);
Steve Blocka7e24c12009-10-30 11:49:00 +0000648}
649
650
651#undef RETURN_NATIVE_CALL
652
653
Ben Murdochf87a2032010-10-22 12:50:53 +0100654Handle<JSRegExp> Execution::NewJSRegExp(Handle<String> pattern,
655 Handle<String> flags,
656 bool* exc) {
Steve Block44f0eee2011-05-26 01:26:41 +0100657 Handle<JSFunction> function = Handle<JSFunction>(
658 pattern->GetIsolate()->global_context()->regexp_function());
Ben Murdochf87a2032010-10-22 12:50:53 +0100659 Handle<Object> re_obj = RegExpImpl::CreateRegExpLiteral(
Steve Block44f0eee2011-05-26 01:26:41 +0100660 function, pattern, flags, exc);
Ben Murdochf87a2032010-10-22 12:50:53 +0100661 if (*exc) return Handle<JSRegExp>();
662 return Handle<JSRegExp>::cast(re_obj);
663}
664
665
Steve Blocka7e24c12009-10-30 11:49:00 +0000666Handle<Object> Execution::CharAt(Handle<String> string, uint32_t index) {
Ben Murdoch8b112d22011-06-08 16:22:53 +0100667 Isolate* isolate = string->GetIsolate();
668 Factory* factory = isolate->factory();
669
Steve Blocka7e24c12009-10-30 11:49:00 +0000670 int int_index = static_cast<int>(index);
671 if (int_index < 0 || int_index >= string->length()) {
Ben Murdoch8b112d22011-06-08 16:22:53 +0100672 return factory->undefined_value();
Steve Blocka7e24c12009-10-30 11:49:00 +0000673 }
674
675 Handle<Object> char_at =
Ben Murdoch8b112d22011-06-08 16:22:53 +0100676 GetProperty(isolate->js_builtins_object(),
677 factory->char_at_symbol());
Steve Blocka7e24c12009-10-30 11:49:00 +0000678 if (!char_at->IsJSFunction()) {
Ben Murdoch8b112d22011-06-08 16:22:53 +0100679 return factory->undefined_value();
Steve Blocka7e24c12009-10-30 11:49:00 +0000680 }
681
682 bool caught_exception;
Ben Murdoch8b112d22011-06-08 16:22:53 +0100683 Handle<Object> index_object = factory->NewNumberFromInt(int_index);
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100684 Handle<Object> index_arg[] = { index_object };
Steve Blocka7e24c12009-10-30 11:49:00 +0000685 Handle<Object> result = TryCall(Handle<JSFunction>::cast(char_at),
686 string,
687 ARRAY_SIZE(index_arg),
688 index_arg,
689 &caught_exception);
690 if (caught_exception) {
Ben Murdoch8b112d22011-06-08 16:22:53 +0100691 return factory->undefined_value();
Steve Blocka7e24c12009-10-30 11:49:00 +0000692 }
693 return result;
694}
695
696
697Handle<JSFunction> Execution::InstantiateFunction(
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100698 Handle<FunctionTemplateInfo> data,
699 bool* exc) {
Ben Murdoch8b112d22011-06-08 16:22:53 +0100700 Isolate* isolate = data->GetIsolate();
Steve Blocka7e24c12009-10-30 11:49:00 +0000701 // Fast case: see if the function has already been instantiated
702 int serial_number = Smi::cast(data->serial_number())->value();
Steve Block44f0eee2011-05-26 01:26:41 +0100703 Object* elm =
Ben Murdoch8b112d22011-06-08 16:22:53 +0100704 isolate->global_context()->function_cache()->
Steve Block44f0eee2011-05-26 01:26:41 +0100705 GetElementNoExceptionThrown(serial_number);
Steve Blocka7e24c12009-10-30 11:49:00 +0000706 if (elm->IsJSFunction()) return Handle<JSFunction>(JSFunction::cast(elm));
707 // The function has not yet been instantiated in this context; do it.
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100708 Handle<Object> args[] = { data };
709 Handle<Object> result = Call(isolate->instantiate_fun(),
710 isolate->js_builtins_object(),
711 ARRAY_SIZE(args),
712 args,
713 exc);
Steve Blocka7e24c12009-10-30 11:49:00 +0000714 if (*exc) return Handle<JSFunction>::null();
715 return Handle<JSFunction>::cast(result);
716}
717
718
719Handle<JSObject> Execution::InstantiateObject(Handle<ObjectTemplateInfo> data,
720 bool* exc) {
Ben Murdoch8b112d22011-06-08 16:22:53 +0100721 Isolate* isolate = data->GetIsolate();
Steve Blocka7e24c12009-10-30 11:49:00 +0000722 if (data->property_list()->IsUndefined() &&
723 !data->constructor()->IsUndefined()) {
724 // Initialization to make gcc happy.
725 Object* result = NULL;
726 {
Ben Murdoch8b112d22011-06-08 16:22:53 +0100727 HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +0000728 Handle<FunctionTemplateInfo> cons_template =
729 Handle<FunctionTemplateInfo>(
730 FunctionTemplateInfo::cast(data->constructor()));
731 Handle<JSFunction> cons = InstantiateFunction(cons_template, exc);
732 if (*exc) return Handle<JSObject>::null();
733 Handle<Object> value = New(cons, 0, NULL, exc);
734 if (*exc) return Handle<JSObject>::null();
735 result = *value;
736 }
737 ASSERT(!*exc);
738 return Handle<JSObject>(JSObject::cast(result));
739 } else {
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100740 Handle<Object> args[] = { data };
741 Handle<Object> result = Call(isolate->instantiate_fun(),
742 isolate->js_builtins_object(),
743 ARRAY_SIZE(args),
744 args,
745 exc);
Steve Blocka7e24c12009-10-30 11:49:00 +0000746 if (*exc) return Handle<JSObject>::null();
747 return Handle<JSObject>::cast(result);
748 }
749}
750
751
752void Execution::ConfigureInstance(Handle<Object> instance,
753 Handle<Object> instance_template,
754 bool* exc) {
Ben Murdoch8b112d22011-06-08 16:22:53 +0100755 Isolate* isolate = Isolate::Current();
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100756 Handle<Object> args[] = { instance, instance_template };
Ben Murdoch8b112d22011-06-08 16:22:53 +0100757 Execution::Call(isolate->configure_instance_fun(),
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100758 isolate->js_builtins_object(),
759 ARRAY_SIZE(args),
760 args,
761 exc);
Steve Blocka7e24c12009-10-30 11:49:00 +0000762}
763
764
765Handle<String> Execution::GetStackTraceLine(Handle<Object> recv,
766 Handle<JSFunction> fun,
767 Handle<Object> pos,
768 Handle<Object> is_global) {
Ben Murdoch8b112d22011-06-08 16:22:53 +0100769 Isolate* isolate = fun->GetIsolate();
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100770 Handle<Object> args[] = { recv, fun, pos, is_global };
771 bool caught_exception;
772 Handle<Object> result = TryCall(isolate->get_stack_trace_line_fun(),
773 isolate->js_builtins_object(),
774 ARRAY_SIZE(args),
775 args,
776 &caught_exception);
Ben Murdoch8b112d22011-06-08 16:22:53 +0100777 if (caught_exception || !result->IsString()) {
778 return isolate->factory()->empty_symbol();
779 }
780
Steve Blocka7e24c12009-10-30 11:49:00 +0000781 return Handle<String>::cast(result);
782}
783
784
785static Object* RuntimePreempt() {
Steve Block44f0eee2011-05-26 01:26:41 +0100786 Isolate* isolate = Isolate::Current();
787
Steve Blocka7e24c12009-10-30 11:49:00 +0000788 // Clear the preempt request flag.
Steve Block44f0eee2011-05-26 01:26:41 +0100789 isolate->stack_guard()->Continue(PREEMPT);
Steve Blocka7e24c12009-10-30 11:49:00 +0000790
791 ContextSwitcher::PreemptionReceived();
792
793#ifdef ENABLE_DEBUGGER_SUPPORT
Steve Block44f0eee2011-05-26 01:26:41 +0100794 if (isolate->debug()->InDebugger()) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000795 // If currently in the debugger don't do any actual preemption but record
796 // that preemption occoured while in the debugger.
Steve Block44f0eee2011-05-26 01:26:41 +0100797 isolate->debug()->PreemptionWhileInDebugger();
Steve Blocka7e24c12009-10-30 11:49:00 +0000798 } else {
799 // Perform preemption.
Ben Murdoch257744e2011-11-30 15:57:28 +0000800 v8::Unlocker unlocker(reinterpret_cast<v8::Isolate*>(isolate));
Steve Blocka7e24c12009-10-30 11:49:00 +0000801 Thread::YieldCPU();
802 }
803#else
Steve Block44f0eee2011-05-26 01:26:41 +0100804 { // NOLINT
805 // Perform preemption.
Ben Murdoch257744e2011-11-30 15:57:28 +0000806 v8::Unlocker unlocker(reinterpret_cast<v8::Isolate*>(isolate));
Steve Block44f0eee2011-05-26 01:26:41 +0100807 Thread::YieldCPU();
808 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000809#endif
810
Steve Block44f0eee2011-05-26 01:26:41 +0100811 return isolate->heap()->undefined_value();
Steve Blocka7e24c12009-10-30 11:49:00 +0000812}
813
814
815#ifdef ENABLE_DEBUGGER_SUPPORT
816Object* Execution::DebugBreakHelper() {
Steve Block44f0eee2011-05-26 01:26:41 +0100817 Isolate* isolate = Isolate::Current();
818
Steve Blocka7e24c12009-10-30 11:49:00 +0000819 // Just continue if breaks are disabled.
Steve Block44f0eee2011-05-26 01:26:41 +0100820 if (isolate->debug()->disable_break()) {
821 return isolate->heap()->undefined_value();
Steve Blocka7e24c12009-10-30 11:49:00 +0000822 }
823
Leon Clarkee46be812010-01-19 14:06:41 +0000824 // Ignore debug break during bootstrapping.
Steve Block44f0eee2011-05-26 01:26:41 +0100825 if (isolate->bootstrapper()->IsActive()) {
826 return isolate->heap()->undefined_value();
Leon Clarkee46be812010-01-19 14:06:41 +0000827 }
828
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100829 StackLimitCheck check(isolate);
830 if (check.HasOverflowed()) {
831 return isolate->heap()->undefined_value();
832 }
833
Steve Blocka7e24c12009-10-30 11:49:00 +0000834 {
Ben Murdoch8b112d22011-06-08 16:22:53 +0100835 JavaScriptFrameIterator it(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +0000836 ASSERT(!it.done());
837 Object* fun = it.frame()->function();
838 if (fun && fun->IsJSFunction()) {
839 // Don't stop in builtin functions.
840 if (JSFunction::cast(fun)->IsBuiltin()) {
Steve Block44f0eee2011-05-26 01:26:41 +0100841 return isolate->heap()->undefined_value();
Steve Blocka7e24c12009-10-30 11:49:00 +0000842 }
843 GlobalObject* global = JSFunction::cast(fun)->context()->global();
844 // Don't stop in debugger functions.
Steve Block44f0eee2011-05-26 01:26:41 +0100845 if (isolate->debug()->IsDebugGlobal(global)) {
846 return isolate->heap()->undefined_value();
Steve Blocka7e24c12009-10-30 11:49:00 +0000847 }
848 }
849 }
850
851 // Collect the break state before clearing the flags.
852 bool debug_command_only =
Steve Block44f0eee2011-05-26 01:26:41 +0100853 isolate->stack_guard()->IsDebugCommand() &&
854 !isolate->stack_guard()->IsDebugBreak();
Steve Blocka7e24c12009-10-30 11:49:00 +0000855
Leon Clarkee46be812010-01-19 14:06:41 +0000856 // Clear the debug break request flag.
Steve Block44f0eee2011-05-26 01:26:41 +0100857 isolate->stack_guard()->Continue(DEBUGBREAK);
Leon Clarkee46be812010-01-19 14:06:41 +0000858
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100859 ProcessDebugMessages(debug_command_only);
Leon Clarkee46be812010-01-19 14:06:41 +0000860
861 // Return to continue execution.
Steve Block44f0eee2011-05-26 01:26:41 +0100862 return isolate->heap()->undefined_value();
Leon Clarkee46be812010-01-19 14:06:41 +0000863}
864
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100865void Execution::ProcessDebugMessages(bool debug_command_only) {
Ben Murdoch8b112d22011-06-08 16:22:53 +0100866 Isolate* isolate = Isolate::Current();
Leon Clarkee46be812010-01-19 14:06:41 +0000867 // Clear the debug command request flag.
Ben Murdoch8b112d22011-06-08 16:22:53 +0100868 isolate->stack_guard()->Continue(DEBUGCOMMAND);
Steve Blocka7e24c12009-10-30 11:49:00 +0000869
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100870 StackLimitCheck check(isolate);
871 if (check.HasOverflowed()) {
872 return;
873 }
874
Ben Murdoch8b112d22011-06-08 16:22:53 +0100875 HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +0000876 // Enter the debugger. Just continue if we fail to enter the debugger.
877 EnterDebugger debugger;
878 if (debugger.FailedToEnter()) {
Leon Clarkee46be812010-01-19 14:06:41 +0000879 return;
Steve Blocka7e24c12009-10-30 11:49:00 +0000880 }
881
882 // Notify the debug event listeners. Indicate auto continue if the break was
883 // a debug command break.
Ben Murdoch8b112d22011-06-08 16:22:53 +0100884 isolate->debugger()->OnDebugBreak(isolate->factory()->undefined_value(),
885 debug_command_only);
Steve Blocka7e24c12009-10-30 11:49:00 +0000886}
Leon Clarkee46be812010-01-19 14:06:41 +0000887
888
Steve Blocka7e24c12009-10-30 11:49:00 +0000889#endif
890
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100891MaybeObject* Execution::HandleStackGuardInterrupt(Isolate* isolate) {
Steve Block44f0eee2011-05-26 01:26:41 +0100892 StackGuard* stack_guard = isolate->stack_guard();
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100893 if (stack_guard->ShouldPostponeInterrupts()) {
894 return isolate->heap()->undefined_value();
895 }
896
897 if (stack_guard->IsGCRequest()) {
898 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags,
899 "StackGuard GC request");
900 stack_guard->Continue(GC_REQUEST);
901 }
902
Steve Block44f0eee2011-05-26 01:26:41 +0100903 isolate->counters()->stack_interrupts()->Increment();
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100904 // If FLAG_count_based_interrupts, every interrupt is a profiler interrupt.
905 if (FLAG_count_based_interrupts ||
906 stack_guard->IsRuntimeProfilerTick()) {
Steve Block44f0eee2011-05-26 01:26:41 +0100907 isolate->counters()->runtime_profiler_ticks()->Increment();
908 stack_guard->Continue(RUNTIME_PROFILER_TICK);
909 isolate->runtime_profiler()->OptimizeNow();
Ben Murdochb0fe1622011-05-05 13:52:32 +0100910 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000911#ifdef ENABLE_DEBUGGER_SUPPORT
Steve Block44f0eee2011-05-26 01:26:41 +0100912 if (stack_guard->IsDebugBreak() || stack_guard->IsDebugCommand()) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000913 DebugBreakHelper();
914 }
915#endif
Steve Block44f0eee2011-05-26 01:26:41 +0100916 if (stack_guard->IsPreempted()) RuntimePreempt();
917 if (stack_guard->IsTerminateExecution()) {
918 stack_guard->Continue(TERMINATE);
919 return isolate->TerminateExecution();
Steve Blocka7e24c12009-10-30 11:49:00 +0000920 }
Steve Block44f0eee2011-05-26 01:26:41 +0100921 if (stack_guard->IsInterrupted()) {
922 stack_guard->Continue(INTERRUPT);
923 return isolate->StackOverflow();
Steve Blocka7e24c12009-10-30 11:49:00 +0000924 }
Steve Block44f0eee2011-05-26 01:26:41 +0100925 return isolate->heap()->undefined_value();
Steve Blocka7e24c12009-10-30 11:49:00 +0000926}
927
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100928
Steve Blocka7e24c12009-10-30 11:49:00 +0000929} } // namespace v8::internal