blob: 979641a9de53c1cd7ebfce9be9bf069699b0fe9f [file] [log] [blame]
yangguo@chromium.org56454712012-02-16 15:33:53 +00001// Copyright 2012 the V8 project authors. All rights reserved.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +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"
kmillikin@chromium.org13bd2942009-12-16 15:36:05 +000033#include "bootstrapper.h"
karlklose@chromium.org44bc7082011-04-11 12:33:05 +000034#include "codegen.h"
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +000035#include "debug.h"
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +000036#include "deoptimizer.h"
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +000037#include "isolate-inl.h"
kasperl@chromium.orga5551262010-12-07 12:49:48 +000038#include "runtime-profiler.h"
ager@chromium.orgc4c92722009-11-18 14:12:51 +000039#include "simulator.h"
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +000040#include "v8threads.h"
kasperl@chromium.orga5551262010-12-07 12:49:48 +000041#include "vm-state-inl.h"
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +000042
kasperl@chromium.org71affb52009-05-26 05:44:31 +000043namespace v8 {
44namespace internal {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000045
46
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000047StackGuard::StackGuard()
48 : isolate_(NULL) {
49}
50
51
52void StackGuard::set_interrupt_limits(const ExecutionAccess& lock) {
53 ASSERT(isolate_ != NULL);
54 // Ignore attempts to interrupt when interrupts are postponed.
55 if (should_postpone_interrupts(lock)) return;
56 thread_local_.jslimit_ = kInterruptLimit;
57 thread_local_.climit_ = kInterruptLimit;
58 isolate_->heap()->SetStackLimits();
59}
60
61
62void StackGuard::reset_limits(const ExecutionAccess& lock) {
63 ASSERT(isolate_ != NULL);
64 thread_local_.jslimit_ = thread_local_.real_jslimit_;
65 thread_local_.climit_ = thread_local_.real_climit_;
66 isolate_->heap()->SetStackLimits();
67}
68
69
svenpanne@chromium.orga8bb4d92011-10-10 13:20:40 +000070static Handle<Object> Invoke(bool is_construct,
71 Handle<JSFunction> function,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000072 Handle<Object> receiver,
73 int argc,
svenpanne@chromium.orga8bb4d92011-10-10 13:20:40 +000074 Handle<Object> args[],
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000075 bool* has_pending_exception) {
svenpanne@chromium.orga8bb4d92011-10-10 13:20:40 +000076 Isolate* isolate = function->GetIsolate();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000077
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000078 // Entering JavaScript.
danno@chromium.orgca29dd82013-04-26 11:59:48 +000079 VMState<JS> state(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000080
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000081 // Placeholder for return value.
lrn@chromium.org303ada72010-10-27 09:33:13 +000082 MaybeObject* value = reinterpret_cast<Object*>(kZapValue);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000083
svenpanne@chromium.orga8bb4d92011-10-10 13:20:40 +000084 typedef Object* (*JSEntryFunction)(byte* entry,
85 Object* function,
86 Object* receiver,
87 int argc,
88 Object*** args);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000089
svenpanne@chromium.orga8bb4d92011-10-10 13:20:40 +000090 Handle<Code> code = is_construct
91 ? isolate->factory()->js_construct_entry_code()
92 : isolate->factory()->js_entry_code();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000093
sgjesse@chromium.org8d96e6d2009-08-07 10:18:15 +000094 // Convert calls on global objects to be calls on the global
95 // receiver instead to avoid having a 'this' pointer which refers
96 // directly to a global object.
97 if (receiver->IsGlobalObject()) {
98 Handle<GlobalObject> global = Handle<GlobalObject>::cast(receiver);
99 receiver = Handle<JSObject>(global->global_receiver());
100 }
101
kasperl@chromium.org7b9eafd2009-12-21 15:20:30 +0000102 // Make sure that the global object of the context we're about to
103 // make the current one is indeed a global object.
yangguo@chromium.org46839fb2012-08-28 09:06:19 +0000104 ASSERT(function->context()->global_object()->IsGlobalObject());
kasperl@chromium.org7b9eafd2009-12-21 15:20:30 +0000105
kasper.lund44510672008-07-25 07:37:58 +0000106 {
107 // Save and restore context around invocation and block the
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000108 // allocation of handles without explicit handle scopes.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000109 SaveContext save(isolate);
rossberg@chromium.org79e79022013-06-03 15:43:46 +0000110 SealHandleScope shs(isolate);
svenpanne@chromium.orga8bb4d92011-10-10 13:20:40 +0000111 JSEntryFunction stub_entry = FUNCTION_CAST<JSEntryFunction>(code->entry());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000112
113 // Call the function through the right JS entry stub.
svenpanne@chromium.orga8bb4d92011-10-10 13:20:40 +0000114 byte* function_entry = function->code()->entry();
115 JSFunction* func = *function;
116 Object* recv = *receiver;
117 Object*** argv = reinterpret_cast<Object***>(args);
118 value =
119 CALL_GENERATED_CODE(stub_entry, function_entry, func, recv, argc, argv);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000120 }
121
svenpanne@chromium.orgc859c4f2012-10-15 11:51:39 +0000122#ifdef VERIFY_HEAP
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000123 value->Verify();
124#endif
125
126 // Update the pending exception flag and return the value.
127 *has_pending_exception = value->IsException();
ulan@chromium.org09d7ab52013-02-25 15:50:35 +0000128 ASSERT(*has_pending_exception == isolate->has_pending_exception());
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000129 if (*has_pending_exception) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000130 isolate->ReportPendingMessages();
jkummerow@chromium.org59297c72013-01-09 16:32:23 +0000131 if (isolate->pending_exception()->IsOutOfMemory()) {
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +0000132 if (!isolate->ignore_out_of_memory()) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000133 V8::FatalProcessOutOfMemory("JS", true);
134 }
135 }
danno@chromium.org81cac2b2012-07-10 11:28:27 +0000136#ifdef ENABLE_DEBUGGER_SUPPORT
137 // Reset stepping state when script exits with uncaught exception.
138 if (isolate->debugger()->IsDebuggerActive()) {
139 isolate->debug()->ClearStepping();
140 }
141#endif // ENABLE_DEBUGGER_SUPPORT
ager@chromium.org3bf7b912008-11-17 09:09:45 +0000142 return Handle<Object>();
ager@chromium.org8bb60582008-12-11 12:02:20 +0000143 } else {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000144 isolate->clear_pending_message();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000145 }
146
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000147 return Handle<Object>(value->ToObjectUnchecked(), isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000148}
149
150
jkummerow@chromium.org2c9426b2013-09-05 16:31:13 +0000151Handle<Object> Execution::Call(Isolate* isolate,
152 Handle<Object> callable,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000153 Handle<Object> receiver,
154 int argc,
svenpanne@chromium.orga8bb4d92011-10-10 13:20:40 +0000155 Handle<Object> argv[],
lrn@chromium.org34e60782011-09-15 07:25:40 +0000156 bool* pending_exception,
157 bool convert_receiver) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000158 *pending_exception = false;
159
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +0000160 if (!callable->IsJSFunction()) {
mstarzinger@chromium.orge9000182013-09-03 11:25:39 +0000161 callable = TryGetFunctionDelegate(isolate, callable, pending_exception);
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +0000162 if (*pending_exception) return callable;
163 }
164 Handle<JSFunction> func = Handle<JSFunction>::cast(callable);
lrn@chromium.org34e60782011-09-15 07:25:40 +0000165
166 // In non-strict mode, convert receiver.
167 if (convert_receiver && !receiver->IsJSReceiver() &&
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +0000168 !func->shared()->native() && func->shared()->is_classic_mode()) {
lrn@chromium.org34e60782011-09-15 07:25:40 +0000169 if (receiver->IsUndefined() || receiver->IsNull()) {
yangguo@chromium.org46839fb2012-08-28 09:06:19 +0000170 Object* global = func->context()->global_object()->global_receiver();
lrn@chromium.org34e60782011-09-15 07:25:40 +0000171 // Under some circumstances, 'global' can be the JSBuiltinsObject
yangguo@chromium.org46839fb2012-08-28 09:06:19 +0000172 // In that case, don't rewrite. (FWIW, the same holds for
173 // GetIsolate()->global_object()->global_receiver().)
ulan@chromium.org09d7ab52013-02-25 15:50:35 +0000174 if (!global->IsJSBuiltinsObject()) {
175 receiver = Handle<Object>(global, func->GetIsolate());
176 }
lrn@chromium.org34e60782011-09-15 07:25:40 +0000177 } else {
mstarzinger@chromium.orge9000182013-09-03 11:25:39 +0000178 receiver = ToObject(isolate, receiver, pending_exception);
lrn@chromium.org34e60782011-09-15 07:25:40 +0000179 }
180 if (*pending_exception) return callable;
181 }
182
svenpanne@chromium.orga8bb4d92011-10-10 13:20:40 +0000183 return Invoke(false, func, receiver, argc, argv, pending_exception);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000184}
185
186
svenpanne@chromium.orga8bb4d92011-10-10 13:20:40 +0000187Handle<Object> Execution::New(Handle<JSFunction> func,
188 int argc,
189 Handle<Object> argv[],
190 bool* pending_exception) {
ulan@chromium.org09d7ab52013-02-25 15:50:35 +0000191 return Invoke(true, func, func->GetIsolate()->global_object(), argc, argv,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000192 pending_exception);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000193}
194
195
196Handle<Object> Execution::TryCall(Handle<JSFunction> func,
197 Handle<Object> receiver,
198 int argc,
svenpanne@chromium.orga8bb4d92011-10-10 13:20:40 +0000199 Handle<Object> args[],
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000200 bool* caught_exception) {
201 // Enter a try-block while executing the JavaScript code. To avoid
ager@chromium.org9258b6b2008-09-11 09:11:10 +0000202 // duplicate error printing it must be non-verbose. Also, to avoid
203 // creating message objects during stack overflow we shouldn't
204 // capture messages.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000205 v8::TryCatch catcher;
206 catcher.SetVerbose(false);
ager@chromium.org9258b6b2008-09-11 09:11:10 +0000207 catcher.SetCaptureMessage(false);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000208 *caught_exception = false;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000209
danno@chromium.org59400602013-08-13 17:09:37 +0000210 // Get isolate now, because handle might be persistent
211 // and get destroyed in the next call.
212 Isolate* isolate = func->GetIsolate();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000213 Handle<Object> result = Invoke(false, func, receiver, argc, args,
214 caught_exception);
215
216 if (*caught_exception) {
217 ASSERT(catcher.HasCaught());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000218 ASSERT(isolate->has_pending_exception());
219 ASSERT(isolate->external_caught_exception());
mmassi@chromium.org49a44672012-12-04 13:52:03 +0000220 if (isolate->is_out_of_memory() && !isolate->ignore_out_of_memory()) {
221 V8::FatalProcessOutOfMemory("OOM during Execution::TryCall");
222 }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000223 if (isolate->pending_exception() ==
224 isolate->heap()->termination_exception()) {
225 result = isolate->factory()->termination_exception();
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000226 } else {
227 result = v8::Utils::OpenHandle(*catcher.Exception());
228 }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000229 isolate->OptionalRescheduleException(true);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000230 }
231
ulan@chromium.org09d7ab52013-02-25 15:50:35 +0000232 ASSERT(!isolate->has_pending_exception());
233 ASSERT(!isolate->external_caught_exception());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000234 return result;
235}
236
237
mstarzinger@chromium.orge9000182013-09-03 11:25:39 +0000238Handle<Object> Execution::GetFunctionDelegate(Isolate* isolate,
239 Handle<Object> object) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000240 ASSERT(!object->IsJSFunction());
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +0000241 Factory* factory = isolate->factory();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000242
243 // If you return a function from here, it will be called when an
244 // attempt is made to call the given object as a function.
245
lrn@chromium.org34e60782011-09-15 07:25:40 +0000246 // If object is a function proxy, get its handler. Iterate if necessary.
247 Object* fun = *object;
248 while (fun->IsJSFunctionProxy()) {
249 fun = JSFunctionProxy::cast(fun)->call_trap();
250 }
ulan@chromium.org09d7ab52013-02-25 15:50:35 +0000251 if (fun->IsJSFunction()) return Handle<Object>(fun, isolate);
lrn@chromium.org34e60782011-09-15 07:25:40 +0000252
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000253 // Objects created through the API can have an instance-call handler
254 // that should be used when calling the object as a function.
lrn@chromium.org34e60782011-09-15 07:25:40 +0000255 if (fun->IsHeapObject() &&
256 HeapObject::cast(fun)->map()->has_instance_call_handler()) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000257 return Handle<JSFunction>(
yangguo@chromium.org46839fb2012-08-28 09:06:19 +0000258 isolate->native_context()->call_as_function_delegate());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000259 }
260
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +0000261 return factory->undefined_value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000262}
263
264
mstarzinger@chromium.orge9000182013-09-03 11:25:39 +0000265Handle<Object> Execution::TryGetFunctionDelegate(Isolate* isolate,
266 Handle<Object> object,
lrn@chromium.org1c092762011-05-09 09:42:16 +0000267 bool* has_pending_exception) {
268 ASSERT(!object->IsJSFunction());
lrn@chromium.org1c092762011-05-09 09:42:16 +0000269
lrn@chromium.org34e60782011-09-15 07:25:40 +0000270 // If object is a function proxy, get its handler. Iterate if necessary.
271 Object* fun = *object;
272 while (fun->IsJSFunctionProxy()) {
273 fun = JSFunctionProxy::cast(fun)->call_trap();
274 }
ulan@chromium.org09d7ab52013-02-25 15:50:35 +0000275 if (fun->IsJSFunction()) return Handle<Object>(fun, isolate);
lrn@chromium.org34e60782011-09-15 07:25:40 +0000276
lrn@chromium.org1c092762011-05-09 09:42:16 +0000277 // Objects created through the API can have an instance-call handler
278 // that should be used when calling the object as a function.
lrn@chromium.org34e60782011-09-15 07:25:40 +0000279 if (fun->IsHeapObject() &&
280 HeapObject::cast(fun)->map()->has_instance_call_handler()) {
lrn@chromium.org1c092762011-05-09 09:42:16 +0000281 return Handle<JSFunction>(
yangguo@chromium.org46839fb2012-08-28 09:06:19 +0000282 isolate->native_context()->call_as_function_delegate());
lrn@chromium.org1c092762011-05-09 09:42:16 +0000283 }
284
285 // If the Object doesn't have an instance-call handler we should
286 // throw a non-callable exception.
287 i::Handle<i::Object> error_obj = isolate->factory()->NewTypeError(
288 "called_non_callable", i::HandleVector<i::Object>(&object, 1));
289 isolate->Throw(*error_obj);
290 *has_pending_exception = true;
291
292 return isolate->factory()->undefined_value();
293}
294
295
mstarzinger@chromium.orge9000182013-09-03 11:25:39 +0000296Handle<Object> Execution::GetConstructorDelegate(Isolate* isolate,
297 Handle<Object> object) {
sgjesse@chromium.org05521fc2009-05-21 07:37:44 +0000298 ASSERT(!object->IsJSFunction());
299
300 // If you return a function from here, it will be called when an
301 // attempt is made to call the given object as a constructor.
302
lrn@chromium.org34e60782011-09-15 07:25:40 +0000303 // If object is a function proxies, get its handler. Iterate if necessary.
304 Object* fun = *object;
305 while (fun->IsJSFunctionProxy()) {
306 fun = JSFunctionProxy::cast(fun)->call_trap();
307 }
ulan@chromium.org09d7ab52013-02-25 15:50:35 +0000308 if (fun->IsJSFunction()) return Handle<Object>(fun, isolate);
lrn@chromium.org34e60782011-09-15 07:25:40 +0000309
sgjesse@chromium.org05521fc2009-05-21 07:37:44 +0000310 // Objects created through the API can have an instance-call handler
311 // that should be used when calling the object as a function.
lrn@chromium.org34e60782011-09-15 07:25:40 +0000312 if (fun->IsHeapObject() &&
313 HeapObject::cast(fun)->map()->has_instance_call_handler()) {
sgjesse@chromium.org05521fc2009-05-21 07:37:44 +0000314 return Handle<JSFunction>(
yangguo@chromium.org46839fb2012-08-28 09:06:19 +0000315 isolate->native_context()->call_as_constructor_delegate());
sgjesse@chromium.org05521fc2009-05-21 07:37:44 +0000316 }
317
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +0000318 return isolate->factory()->undefined_value();
sgjesse@chromium.org05521fc2009-05-21 07:37:44 +0000319}
320
321
lrn@chromium.org1c092762011-05-09 09:42:16 +0000322Handle<Object> Execution::TryGetConstructorDelegate(
mstarzinger@chromium.orge9000182013-09-03 11:25:39 +0000323 Isolate* isolate,
lrn@chromium.org1c092762011-05-09 09:42:16 +0000324 Handle<Object> object,
325 bool* has_pending_exception) {
326 ASSERT(!object->IsJSFunction());
lrn@chromium.org1c092762011-05-09 09:42:16 +0000327
328 // If you return a function from here, it will be called when an
329 // attempt is made to call the given object as a constructor.
330
lrn@chromium.org34e60782011-09-15 07:25:40 +0000331 // If object is a function proxies, get its handler. Iterate if necessary.
332 Object* fun = *object;
333 while (fun->IsJSFunctionProxy()) {
334 fun = JSFunctionProxy::cast(fun)->call_trap();
335 }
ulan@chromium.org09d7ab52013-02-25 15:50:35 +0000336 if (fun->IsJSFunction()) return Handle<Object>(fun, isolate);
lrn@chromium.org34e60782011-09-15 07:25:40 +0000337
lrn@chromium.org1c092762011-05-09 09:42:16 +0000338 // Objects created through the API can have an instance-call handler
339 // that should be used when calling the object as a function.
lrn@chromium.org34e60782011-09-15 07:25:40 +0000340 if (fun->IsHeapObject() &&
341 HeapObject::cast(fun)->map()->has_instance_call_handler()) {
lrn@chromium.org1c092762011-05-09 09:42:16 +0000342 return Handle<JSFunction>(
yangguo@chromium.org46839fb2012-08-28 09:06:19 +0000343 isolate->native_context()->call_as_constructor_delegate());
lrn@chromium.org1c092762011-05-09 09:42:16 +0000344 }
345
346 // If the Object doesn't have an instance-call handler we should
347 // throw a non-callable exception.
348 i::Handle<i::Object> error_obj = isolate->factory()->NewTypeError(
349 "called_non_callable", i::HandleVector<i::Object>(&object, 1));
350 isolate->Throw(*error_obj);
351 *has_pending_exception = true;
352
353 return isolate->factory()->undefined_value();
354}
355
356
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000357bool StackGuard::IsStackOverflow() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000358 ExecutionAccess access(isolate_);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000359 return (thread_local_.jslimit_ != kInterruptLimit &&
360 thread_local_.climit_ != kInterruptLimit);
361}
362
363
364void StackGuard::EnableInterrupts() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000365 ExecutionAccess access(isolate_);
whesse@chromium.orgb6e43bb2010-04-14 09:36:28 +0000366 if (has_pending_interrupts(access)) {
367 set_interrupt_limits(access);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000368 }
369}
370
371
372void StackGuard::SetStackLimit(uintptr_t limit) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000373 ExecutionAccess access(isolate_);
ulan@chromium.org2efb9002012-01-19 15:36:35 +0000374 // If the current limits are special (e.g. due to a pending interrupt) then
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000375 // leave them alone.
lrn@chromium.org1c092762011-05-09 09:42:16 +0000376 uintptr_t jslimit = SimulatorStack::JsLimitFromCLimit(isolate_, limit);
ager@chromium.orgc4c92722009-11-18 14:12:51 +0000377 if (thread_local_.jslimit_ == thread_local_.real_jslimit_) {
sgjesse@chromium.orgc5145742009-10-07 09:00:33 +0000378 thread_local_.jslimit_ = jslimit;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000379 }
ager@chromium.orgc4c92722009-11-18 14:12:51 +0000380 if (thread_local_.climit_ == thread_local_.real_climit_) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000381 thread_local_.climit_ = limit;
382 }
ager@chromium.orgc4c92722009-11-18 14:12:51 +0000383 thread_local_.real_climit_ = limit;
384 thread_local_.real_jslimit_ = jslimit;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000385}
386
387
388void StackGuard::DisableInterrupts() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000389 ExecutionAccess access(isolate_);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000390 reset_limits(access);
391}
392
393
erik.corry@gmail.combbceb572012-03-09 10:52:05 +0000394bool StackGuard::ShouldPostponeInterrupts() {
395 ExecutionAccess access(isolate_);
396 return should_postpone_interrupts(access);
397}
398
399
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000400bool StackGuard::IsInterrupted() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000401 ExecutionAccess access(isolate_);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000402 return (thread_local_.interrupt_flags_ & INTERRUPT) != 0;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000403}
404
405
406void StackGuard::Interrupt() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000407 ExecutionAccess access(isolate_);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000408 thread_local_.interrupt_flags_ |= INTERRUPT;
whesse@chromium.orgb6e43bb2010-04-14 09:36:28 +0000409 set_interrupt_limits(access);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000410}
411
412
413bool StackGuard::IsPreempted() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000414 ExecutionAccess access(isolate_);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000415 return thread_local_.interrupt_flags_ & PREEMPT;
416}
417
418
419void StackGuard::Preempt() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000420 ExecutionAccess access(isolate_);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000421 thread_local_.interrupt_flags_ |= PREEMPT;
whesse@chromium.orgb6e43bb2010-04-14 09:36:28 +0000422 set_interrupt_limits(access);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000423}
424
425
sgjesse@chromium.orgc81c8942009-08-21 10:54:26 +0000426bool StackGuard::IsTerminateExecution() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000427 ExecutionAccess access(isolate_);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000428 return (thread_local_.interrupt_flags_ & TERMINATE) != 0;
sgjesse@chromium.orgc81c8942009-08-21 10:54:26 +0000429}
430
431
ulan@chromium.org32d7dba2013-04-24 10:59:06 +0000432void StackGuard::CancelTerminateExecution() {
433 ExecutionAccess access(isolate_);
434 Continue(TERMINATE);
435 isolate_->CancelTerminateExecution();
436}
437
438
sgjesse@chromium.orgc81c8942009-08-21 10:54:26 +0000439void StackGuard::TerminateExecution() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000440 ExecutionAccess access(isolate_);
sgjesse@chromium.orgc81c8942009-08-21 10:54:26 +0000441 thread_local_.interrupt_flags_ |= TERMINATE;
whesse@chromium.orgb6e43bb2010-04-14 09:36:28 +0000442 set_interrupt_limits(access);
sgjesse@chromium.orgc81c8942009-08-21 10:54:26 +0000443}
444
445
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000446bool StackGuard::IsGCRequest() {
447 ExecutionAccess access(isolate_);
448 return (thread_local_.interrupt_flags_ & GC_REQUEST) != 0;
449}
450
451
452void StackGuard::RequestGC() {
453 ExecutionAccess access(isolate_);
454 thread_local_.interrupt_flags_ |= GC_REQUEST;
455 if (thread_local_.postpone_interrupts_nesting_ == 0) {
456 thread_local_.jslimit_ = thread_local_.climit_ = kInterruptLimit;
457 isolate_->heap()->SetStackLimits();
458 }
459}
460
461
dslomov@chromium.org4a35c5a2013-09-13 07:28:52 +0000462bool StackGuard::IsInstallCodeRequest() {
463 ExecutionAccess access(isolate_);
464 return (thread_local_.interrupt_flags_ & INSTALL_CODE) != 0;
465}
466
467
468void StackGuard::RequestInstallCode() {
469 ExecutionAccess access(isolate_);
470 thread_local_.interrupt_flags_ |= INSTALL_CODE;
471 if (thread_local_.postpone_interrupts_nesting_ == 0) {
472 thread_local_.jslimit_ = thread_local_.climit_ = kInterruptLimit;
473 isolate_->heap()->SetStackLimits();
474 }
475}
476
477
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +0000478bool StackGuard::IsFullDeopt() {
479 ExecutionAccess access(isolate_);
480 return (thread_local_.interrupt_flags_ & FULL_DEOPT) != 0;
481}
482
483
484void StackGuard::FullDeopt() {
485 ExecutionAccess access(isolate_);
486 thread_local_.interrupt_flags_ |= FULL_DEOPT;
487 set_interrupt_limits(access);
488}
489
490
ager@chromium.org65dad4b2009-04-23 08:48:43 +0000491#ifdef ENABLE_DEBUGGER_SUPPORT
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000492bool StackGuard::IsDebugBreak() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000493 ExecutionAccess access(isolate_);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000494 return thread_local_.interrupt_flags_ & DEBUGBREAK;
495}
496
kasper.lund44510672008-07-25 07:37:58 +0000497
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000498void StackGuard::DebugBreak() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000499 ExecutionAccess access(isolate_);
kasper.lund7276f142008-07-30 08:49:36 +0000500 thread_local_.interrupt_flags_ |= DEBUGBREAK;
whesse@chromium.orgb6e43bb2010-04-14 09:36:28 +0000501 set_interrupt_limits(access);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000502}
503
504
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000505bool StackGuard::IsDebugCommand() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000506 ExecutionAccess access(isolate_);
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000507 return thread_local_.interrupt_flags_ & DEBUGCOMMAND;
508}
509
510
511void StackGuard::DebugCommand() {
512 if (FLAG_debugger_auto_break) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000513 ExecutionAccess access(isolate_);
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000514 thread_local_.interrupt_flags_ |= DEBUGCOMMAND;
whesse@chromium.orgb6e43bb2010-04-14 09:36:28 +0000515 set_interrupt_limits(access);
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000516 }
517}
ager@chromium.org65dad4b2009-04-23 08:48:43 +0000518#endif
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000519
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000520void StackGuard::Continue(InterruptFlag after_what) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000521 ExecutionAccess access(isolate_);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000522 thread_local_.interrupt_flags_ &= ~static_cast<int>(after_what);
whesse@chromium.orgb6e43bb2010-04-14 09:36:28 +0000523 if (!should_postpone_interrupts(access) && !has_pending_interrupts(access)) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000524 reset_limits(access);
525 }
526}
527
528
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000529char* StackGuard::ArchiveStackGuard(char* to) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000530 ExecutionAccess access(isolate_);
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +0000531 OS::MemCopy(to, reinterpret_cast<char*>(&thread_local_), sizeof(ThreadLocal));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000532 ThreadLocal blank;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000533
534 // Set the stack limits using the old thread_local_.
535 // TODO(isolates): This was the old semantics of constructing a ThreadLocal
536 // (as the ctor called SetStackLimits, which looked at the
537 // current thread_local_ from StackGuard)-- but is this
538 // really what was intended?
539 isolate_->heap()->SetStackLimits();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000540 thread_local_ = blank;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000541
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000542 return to + sizeof(ThreadLocal);
543}
544
545
546char* StackGuard::RestoreStackGuard(char* from) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000547 ExecutionAccess access(isolate_);
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +0000548 OS::MemCopy(
549 reinterpret_cast<char*>(&thread_local_), from, sizeof(ThreadLocal));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000550 isolate_->heap()->SetStackLimits();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000551 return from + sizeof(ThreadLocal);
552}
553
554
sgjesse@chromium.orgc5145742009-10-07 09:00:33 +0000555void StackGuard::FreeThreadResources() {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +0000556 Isolate::PerIsolateThreadData* per_thread =
557 isolate_->FindOrAllocatePerThreadDataForThisThread();
558 per_thread->set_stack_limit(thread_local_.real_climit_);
sgjesse@chromium.orgc5145742009-10-07 09:00:33 +0000559}
560
561
562void StackGuard::ThreadLocal::Clear() {
ager@chromium.orgc4c92722009-11-18 14:12:51 +0000563 real_jslimit_ = kIllegalLimit;
sgjesse@chromium.orgc5145742009-10-07 09:00:33 +0000564 jslimit_ = kIllegalLimit;
ager@chromium.orgc4c92722009-11-18 14:12:51 +0000565 real_climit_ = kIllegalLimit;
sgjesse@chromium.orgc5145742009-10-07 09:00:33 +0000566 climit_ = kIllegalLimit;
567 nesting_ = 0;
568 postpone_interrupts_nesting_ = 0;
569 interrupt_flags_ = 0;
sgjesse@chromium.orgc5145742009-10-07 09:00:33 +0000570}
571
572
lrn@chromium.org1c092762011-05-09 09:42:16 +0000573bool StackGuard::ThreadLocal::Initialize(Isolate* isolate) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000574 bool should_set_stack_limits = false;
ager@chromium.orgc4c92722009-11-18 14:12:51 +0000575 if (real_climit_ == kIllegalLimit) {
sgjesse@chromium.orgc5145742009-10-07 09:00:33 +0000576 // Takes the address of the limit variable in order to find out where
577 // the top of stack is right now.
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +0000578 const uintptr_t kLimitSize = FLAG_stack_size * KB;
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000579 uintptr_t limit = reinterpret_cast<uintptr_t>(&limit) - kLimitSize;
580 ASSERT(reinterpret_cast<uintptr_t>(&limit) > kLimitSize);
lrn@chromium.org1c092762011-05-09 09:42:16 +0000581 real_jslimit_ = SimulatorStack::JsLimitFromCLimit(isolate, limit);
582 jslimit_ = SimulatorStack::JsLimitFromCLimit(isolate, limit);
ager@chromium.orgc4c92722009-11-18 14:12:51 +0000583 real_climit_ = limit;
sgjesse@chromium.orgc5145742009-10-07 09:00:33 +0000584 climit_ = limit;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000585 should_set_stack_limits = true;
sgjesse@chromium.orgc5145742009-10-07 09:00:33 +0000586 }
587 nesting_ = 0;
588 postpone_interrupts_nesting_ = 0;
589 interrupt_flags_ = 0;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000590 return should_set_stack_limits;
sgjesse@chromium.orgc5145742009-10-07 09:00:33 +0000591}
592
593
594void StackGuard::ClearThread(const ExecutionAccess& lock) {
595 thread_local_.Clear();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000596 isolate_->heap()->SetStackLimits();
sgjesse@chromium.orgc5145742009-10-07 09:00:33 +0000597}
598
599
600void StackGuard::InitThread(const ExecutionAccess& lock) {
lrn@chromium.org1c092762011-05-09 09:42:16 +0000601 if (thread_local_.Initialize(isolate_)) isolate_->heap()->SetStackLimits();
602 Isolate::PerIsolateThreadData* per_thread =
603 isolate_->FindOrAllocatePerThreadDataForThisThread();
604 uintptr_t stored_limit = per_thread->stack_limit();
sgjesse@chromium.orgc5145742009-10-07 09:00:33 +0000605 // You should hold the ExecutionAccess lock when you call this.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000606 if (stored_limit != 0) {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +0000607 SetStackLimit(stored_limit);
sgjesse@chromium.orgc5145742009-10-07 09:00:33 +0000608 }
609}
610
611
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000612// --- C a l l s t o n a t i v e s ---
613
svenpanne@chromium.orga8bb4d92011-10-10 13:20:40 +0000614#define RETURN_NATIVE_CALL(name, args, has_pending_exception) \
615 do { \
svenpanne@chromium.orga8bb4d92011-10-10 13:20:40 +0000616 Handle<Object> argv[] = args; \
617 ASSERT(has_pending_exception != NULL); \
jkummerow@chromium.org2c9426b2013-09-05 16:31:13 +0000618 return Call(isolate, \
619 isolate->name##_fun(), \
svenpanne@chromium.orga8bb4d92011-10-10 13:20:40 +0000620 isolate->js_builtins_object(), \
621 ARRAY_SIZE(argv), argv, \
622 has_pending_exception); \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000623 } while (false)
624
625
mstarzinger@chromium.orge9000182013-09-03 11:25:39 +0000626Handle<Object> Execution::ToNumber(
627 Isolate* isolate, Handle<Object> obj, bool* exc) {
svenpanne@chromium.orga8bb4d92011-10-10 13:20:40 +0000628 RETURN_NATIVE_CALL(to_number, { obj }, exc);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000629}
630
631
mstarzinger@chromium.orge9000182013-09-03 11:25:39 +0000632Handle<Object> Execution::ToString(
633 Isolate* isolate, Handle<Object> obj, bool* exc) {
svenpanne@chromium.orga8bb4d92011-10-10 13:20:40 +0000634 RETURN_NATIVE_CALL(to_string, { obj }, exc);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000635}
636
637
mstarzinger@chromium.orge9000182013-09-03 11:25:39 +0000638Handle<Object> Execution::ToDetailString(
639 Isolate* isolate, Handle<Object> obj, bool* exc) {
svenpanne@chromium.orga8bb4d92011-10-10 13:20:40 +0000640 RETURN_NATIVE_CALL(to_detail_string, { obj }, exc);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000641}
642
643
mstarzinger@chromium.orge9000182013-09-03 11:25:39 +0000644Handle<Object> Execution::ToObject(
645 Isolate* isolate, Handle<Object> obj, bool* exc) {
lrn@chromium.org34e60782011-09-15 07:25:40 +0000646 if (obj->IsSpecObject()) return obj;
svenpanne@chromium.orga8bb4d92011-10-10 13:20:40 +0000647 RETURN_NATIVE_CALL(to_object, { obj }, exc);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000648}
649
650
mstarzinger@chromium.orge9000182013-09-03 11:25:39 +0000651Handle<Object> Execution::ToInteger(
652 Isolate* isolate, Handle<Object> obj, bool* exc) {
svenpanne@chromium.orga8bb4d92011-10-10 13:20:40 +0000653 RETURN_NATIVE_CALL(to_integer, { obj }, exc);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000654}
655
656
mstarzinger@chromium.orge9000182013-09-03 11:25:39 +0000657Handle<Object> Execution::ToUint32(
658 Isolate* isolate, Handle<Object> obj, bool* exc) {
svenpanne@chromium.orga8bb4d92011-10-10 13:20:40 +0000659 RETURN_NATIVE_CALL(to_uint32, { obj }, exc);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000660}
661
662
mstarzinger@chromium.orge9000182013-09-03 11:25:39 +0000663Handle<Object> Execution::ToInt32(
664 Isolate* isolate, Handle<Object> obj, bool* exc) {
svenpanne@chromium.orga8bb4d92011-10-10 13:20:40 +0000665 RETURN_NATIVE_CALL(to_int32, { obj }, exc);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000666}
667
668
mstarzinger@chromium.orge9000182013-09-03 11:25:39 +0000669Handle<Object> Execution::NewDate(Isolate* isolate, double time, bool* exc) {
verwaest@chromium.orgd4be0f02013-06-05 13:39:03 +0000670 Handle<Object> time_obj = isolate->factory()->NewNumber(time);
svenpanne@chromium.orga8bb4d92011-10-10 13:20:40 +0000671 RETURN_NATIVE_CALL(create_date, { time_obj }, exc);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000672}
673
674
675#undef RETURN_NATIVE_CALL
676
677
ager@chromium.orgb61a0d12010-10-13 08:35:23 +0000678Handle<JSRegExp> Execution::NewJSRegExp(Handle<String> pattern,
679 Handle<String> flags,
680 bool* exc) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000681 Handle<JSFunction> function = Handle<JSFunction>(
yangguo@chromium.org46839fb2012-08-28 09:06:19 +0000682 pattern->GetIsolate()->native_context()->regexp_function());
ager@chromium.orgb61a0d12010-10-13 08:35:23 +0000683 Handle<Object> re_obj = RegExpImpl::CreateRegExpLiteral(
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000684 function, pattern, flags, exc);
ager@chromium.orgb61a0d12010-10-13 08:35:23 +0000685 if (*exc) return Handle<JSRegExp>();
686 return Handle<JSRegExp>::cast(re_obj);
687}
688
689
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000690Handle<Object> Execution::CharAt(Handle<String> string, uint32_t index) {
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +0000691 Isolate* isolate = string->GetIsolate();
692 Factory* factory = isolate->factory();
693
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000694 int int_index = static_cast<int>(index);
695 if (int_index < 0 || int_index >= string->length()) {
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +0000696 return factory->undefined_value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000697 }
698
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +0000699 Handle<Object> char_at = GetProperty(
700 isolate, isolate->js_builtins_object(), factory->char_at_string());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000701 if (!char_at->IsJSFunction()) {
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +0000702 return factory->undefined_value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000703 }
704
705 bool caught_exception;
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +0000706 Handle<Object> index_object = factory->NewNumberFromInt(int_index);
svenpanne@chromium.orga8bb4d92011-10-10 13:20:40 +0000707 Handle<Object> index_arg[] = { index_object };
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000708 Handle<Object> result = TryCall(Handle<JSFunction>::cast(char_at),
709 string,
710 ARRAY_SIZE(index_arg),
711 index_arg,
712 &caught_exception);
713 if (caught_exception) {
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +0000714 return factory->undefined_value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000715 }
716 return result;
717}
718
719
720Handle<JSFunction> Execution::InstantiateFunction(
svenpanne@chromium.orga8bb4d92011-10-10 13:20:40 +0000721 Handle<FunctionTemplateInfo> data,
722 bool* exc) {
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +0000723 Isolate* isolate = data->GetIsolate();
dslomov@chromium.org639bac02013-09-09 11:58:54 +0000724 if (!data->do_not_cache()) {
725 // Fast case: see if the function has already been instantiated
726 int serial_number = Smi::cast(data->serial_number())->value();
727 Object* elm =
728 isolate->native_context()->function_cache()->
729 GetElementNoExceptionThrown(isolate, serial_number);
730 if (elm->IsJSFunction()) return Handle<JSFunction>(JSFunction::cast(elm));
731 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000732 // The function has not yet been instantiated in this context; do it.
svenpanne@chromium.orga8bb4d92011-10-10 13:20:40 +0000733 Handle<Object> args[] = { data };
jkummerow@chromium.org2c9426b2013-09-05 16:31:13 +0000734 Handle<Object> result = Call(isolate,
735 isolate->instantiate_fun(),
svenpanne@chromium.orga8bb4d92011-10-10 13:20:40 +0000736 isolate->js_builtins_object(),
737 ARRAY_SIZE(args),
738 args,
739 exc);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000740 if (*exc) return Handle<JSFunction>::null();
741 return Handle<JSFunction>::cast(result);
742}
743
744
745Handle<JSObject> Execution::InstantiateObject(Handle<ObjectTemplateInfo> data,
746 bool* exc) {
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +0000747 Isolate* isolate = data->GetIsolate();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000748 if (data->property_list()->IsUndefined() &&
749 !data->constructor()->IsUndefined()) {
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000750 // Initialization to make gcc happy.
751 Object* result = NULL;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000752 {
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +0000753 HandleScope scope(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000754 Handle<FunctionTemplateInfo> cons_template =
755 Handle<FunctionTemplateInfo>(
756 FunctionTemplateInfo::cast(data->constructor()));
757 Handle<JSFunction> cons = InstantiateFunction(cons_template, exc);
758 if (*exc) return Handle<JSObject>::null();
759 Handle<Object> value = New(cons, 0, NULL, exc);
760 if (*exc) return Handle<JSObject>::null();
761 result = *value;
762 }
763 ASSERT(!*exc);
764 return Handle<JSObject>(JSObject::cast(result));
765 } else {
svenpanne@chromium.orga8bb4d92011-10-10 13:20:40 +0000766 Handle<Object> args[] = { data };
jkummerow@chromium.org2c9426b2013-09-05 16:31:13 +0000767 Handle<Object> result = Call(isolate,
768 isolate->instantiate_fun(),
svenpanne@chromium.orga8bb4d92011-10-10 13:20:40 +0000769 isolate->js_builtins_object(),
770 ARRAY_SIZE(args),
771 args,
772 exc);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000773 if (*exc) return Handle<JSObject>::null();
774 return Handle<JSObject>::cast(result);
775 }
776}
777
778
mstarzinger@chromium.orge9000182013-09-03 11:25:39 +0000779void Execution::ConfigureInstance(Isolate* isolate,
780 Handle<Object> instance,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000781 Handle<Object> instance_template,
782 bool* exc) {
svenpanne@chromium.orga8bb4d92011-10-10 13:20:40 +0000783 Handle<Object> args[] = { instance, instance_template };
jkummerow@chromium.org2c9426b2013-09-05 16:31:13 +0000784 Execution::Call(isolate,
785 isolate->configure_instance_fun(),
svenpanne@chromium.orga8bb4d92011-10-10 13:20:40 +0000786 isolate->js_builtins_object(),
787 ARRAY_SIZE(args),
788 args,
789 exc);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000790}
791
792
793Handle<String> Execution::GetStackTraceLine(Handle<Object> recv,
794 Handle<JSFunction> fun,
795 Handle<Object> pos,
796 Handle<Object> is_global) {
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +0000797 Isolate* isolate = fun->GetIsolate();
svenpanne@chromium.orga8bb4d92011-10-10 13:20:40 +0000798 Handle<Object> args[] = { recv, fun, pos, is_global };
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000799 bool caught_exception;
svenpanne@chromium.orga8bb4d92011-10-10 13:20:40 +0000800 Handle<Object> result = TryCall(isolate->get_stack_trace_line_fun(),
801 isolate->js_builtins_object(),
802 ARRAY_SIZE(args),
803 args,
804 &caught_exception);
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +0000805 if (caught_exception || !result->IsString()) {
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +0000806 return isolate->factory()->empty_string();
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +0000807 }
808
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000809 return Handle<String>::cast(result);
810}
811
812
mstarzinger@chromium.orge9000182013-09-03 11:25:39 +0000813static Object* RuntimePreempt(Isolate* isolate) {
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +0000814 // Clear the preempt request flag.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000815 isolate->stack_guard()->Continue(PREEMPT);
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +0000816
817 ContextSwitcher::PreemptionReceived();
818
ager@chromium.org65dad4b2009-04-23 08:48:43 +0000819#ifdef ENABLE_DEBUGGER_SUPPORT
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000820 if (isolate->debug()->InDebugger()) {
kasperl@chromium.org7be3c992009-03-12 07:19:55 +0000821 // If currently in the debugger don't do any actual preemption but record
822 // that preemption occoured while in the debugger.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000823 isolate->debug()->PreemptionWhileInDebugger();
kasperl@chromium.org7be3c992009-03-12 07:19:55 +0000824 } else {
825 // Perform preemption.
lrn@chromium.org1c092762011-05-09 09:42:16 +0000826 v8::Unlocker unlocker(reinterpret_cast<v8::Isolate*>(isolate));
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +0000827 Thread::YieldCPU();
828 }
ager@chromium.org65dad4b2009-04-23 08:48:43 +0000829#else
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000830 { // NOLINT
831 // Perform preemption.
lrn@chromium.org1c092762011-05-09 09:42:16 +0000832 v8::Unlocker unlocker(reinterpret_cast<v8::Isolate*>(isolate));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000833 Thread::YieldCPU();
834 }
ager@chromium.org65dad4b2009-04-23 08:48:43 +0000835#endif
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +0000836
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000837 return isolate->heap()->undefined_value();
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +0000838}
839
840
ager@chromium.org65dad4b2009-04-23 08:48:43 +0000841#ifdef ENABLE_DEBUGGER_SUPPORT
mstarzinger@chromium.orge9000182013-09-03 11:25:39 +0000842Object* Execution::DebugBreakHelper(Isolate* isolate) {
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +0000843 // Just continue if breaks are disabled.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000844 if (isolate->debug()->disable_break()) {
845 return isolate->heap()->undefined_value();
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +0000846 }
847
kmillikin@chromium.org13bd2942009-12-16 15:36:05 +0000848 // Ignore debug break during bootstrapping.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000849 if (isolate->bootstrapper()->IsActive()) {
850 return isolate->heap()->undefined_value();
kmillikin@chromium.org13bd2942009-12-16 15:36:05 +0000851 }
852
jkummerow@chromium.org28583c92012-07-16 11:31:55 +0000853 // Ignore debug break if debugger is not active.
854 if (!isolate->debugger()->IsDebuggerActive()) {
855 return isolate->heap()->undefined_value();
856 }
857
fschneider@chromium.org7d10be52012-04-10 12:30:14 +0000858 StackLimitCheck check(isolate);
859 if (check.HasOverflowed()) {
860 return isolate->heap()->undefined_value();
861 }
862
kasperl@chromium.orge959c182009-07-27 08:59:04 +0000863 {
vegorov@chromium.org74f333b2011-04-06 11:17:46 +0000864 JavaScriptFrameIterator it(isolate);
kasperl@chromium.orge959c182009-07-27 08:59:04 +0000865 ASSERT(!it.done());
866 Object* fun = it.frame()->function();
867 if (fun && fun->IsJSFunction()) {
kasperl@chromium.orge959c182009-07-27 08:59:04 +0000868 // Don't stop in builtin functions.
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +0000869 if (JSFunction::cast(fun)->IsBuiltin()) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000870 return isolate->heap()->undefined_value();
kasperl@chromium.orge959c182009-07-27 08:59:04 +0000871 }
yangguo@chromium.org46839fb2012-08-28 09:06:19 +0000872 GlobalObject* global = JSFunction::cast(fun)->context()->global_object();
kasperl@chromium.orge959c182009-07-27 08:59:04 +0000873 // Don't stop in debugger functions.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000874 if (isolate->debug()->IsDebugGlobal(global)) {
875 return isolate->heap()->undefined_value();
kasperl@chromium.orge959c182009-07-27 08:59:04 +0000876 }
877 }
878 }
879
sgjesse@chromium.org755c5b12009-05-29 11:04:38 +0000880 // Collect the break state before clearing the flags.
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000881 bool debug_command_only =
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000882 isolate->stack_guard()->IsDebugCommand() &&
883 !isolate->stack_guard()->IsDebugBreak();
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000884
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +0000885 // Clear the debug break request flag.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000886 isolate->stack_guard()->Continue(DEBUGBREAK);
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +0000887
mstarzinger@chromium.orge9000182013-09-03 11:25:39 +0000888 ProcessDebugMessages(isolate, debug_command_only);
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +0000889
890 // Return to continue execution.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000891 return isolate->heap()->undefined_value();
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +0000892}
893
mstarzinger@chromium.orge0e1b0d2013-07-08 08:38:06 +0000894
mstarzinger@chromium.orge9000182013-09-03 11:25:39 +0000895void Execution::ProcessDebugMessages(Isolate* isolate,
896 bool debug_command_only) {
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +0000897 // Clear the debug command request flag.
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +0000898 isolate->stack_guard()->Continue(DEBUGCOMMAND);
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000899
fschneider@chromium.org7d10be52012-04-10 12:30:14 +0000900 StackLimitCheck check(isolate);
901 if (check.HasOverflowed()) {
902 return;
903 }
904
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +0000905 HandleScope scope(isolate);
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +0000906 // Enter the debugger. Just continue if we fail to enter the debugger.
mstarzinger@chromium.orge9000182013-09-03 11:25:39 +0000907 EnterDebugger debugger(isolate);
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +0000908 if (debugger.FailedToEnter()) {
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +0000909 return;
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +0000910 }
911
sgjesse@chromium.org755c5b12009-05-29 11:04:38 +0000912 // Notify the debug event listeners. Indicate auto continue if the break was
913 // a debug command break.
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +0000914 isolate->debugger()->OnDebugBreak(isolate->factory()->undefined_value(),
915 debug_command_only);
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +0000916}
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +0000917
918
ager@chromium.org65dad4b2009-04-23 08:48:43 +0000919#endif
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +0000920
ulan@chromium.org812308e2012-02-29 15:58:45 +0000921MaybeObject* Execution::HandleStackGuardInterrupt(Isolate* isolate) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000922 StackGuard* stack_guard = isolate->stack_guard();
erik.corry@gmail.combbceb572012-03-09 10:52:05 +0000923 if (stack_guard->ShouldPostponeInterrupts()) {
924 return isolate->heap()->undefined_value();
925 }
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000926
927 if (stack_guard->IsGCRequest()) {
mstarzinger@chromium.org3233d2f2012-03-14 11:16:03 +0000928 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags,
929 "StackGuard GC request");
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000930 stack_guard->Continue(GC_REQUEST);
931 }
932
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000933 isolate->counters()->stack_interrupts()->Increment();
rossberg@chromium.orgcddc71f2012-12-07 12:40:13 +0000934 isolate->counters()->runtime_profiler_ticks()->Increment();
ager@chromium.org65dad4b2009-04-23 08:48:43 +0000935#ifdef ENABLE_DEBUGGER_SUPPORT
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000936 if (stack_guard->IsDebugBreak() || stack_guard->IsDebugCommand()) {
mstarzinger@chromium.orge9000182013-09-03 11:25:39 +0000937 DebugBreakHelper(isolate);
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000938 }
ager@chromium.org65dad4b2009-04-23 08:48:43 +0000939#endif
mstarzinger@chromium.orge9000182013-09-03 11:25:39 +0000940 if (stack_guard->IsPreempted()) RuntimePreempt(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000941 if (stack_guard->IsTerminateExecution()) {
942 stack_guard->Continue(TERMINATE);
943 return isolate->TerminateExecution();
sgjesse@chromium.orgc81c8942009-08-21 10:54:26 +0000944 }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000945 if (stack_guard->IsInterrupted()) {
946 stack_guard->Continue(INTERRUPT);
947 return isolate->StackOverflow();
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +0000948 }
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +0000949 if (stack_guard->IsFullDeopt()) {
950 stack_guard->Continue(FULL_DEOPT);
951 Deoptimizer::DeoptimizeAll(isolate);
952 }
dslomov@chromium.org4a35c5a2013-09-13 07:28:52 +0000953 if (stack_guard->IsInstallCodeRequest()) {
954 ASSERT(FLAG_concurrent_recompilation);
955 stack_guard->Continue(INSTALL_CODE);
956 isolate->optimizing_compiler_thread()->InstallOptimizedFunctions();
957 }
958 isolate->runtime_profiler()->OptimizeNow();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000959 return isolate->heap()->undefined_value();
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +0000960}
961
yangguo@chromium.org56454712012-02-16 15:33:53 +0000962
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000963} } // namespace v8::internal