OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "execution.h" | 5 #include "execution.h" |
6 | 6 |
7 #include "bootstrapper.h" | 7 #include "bootstrapper.h" |
8 #include "codegen.h" | 8 #include "codegen.h" |
9 #include "deoptimizer.h" | 9 #include "deoptimizer.h" |
10 #include "isolate-inl.h" | 10 #include "isolate-inl.h" |
(...skipping 18 matching lines...) Expand all Loading... |
29 | 29 |
30 | 30 |
31 void StackGuard::reset_limits(const ExecutionAccess& lock) { | 31 void StackGuard::reset_limits(const ExecutionAccess& lock) { |
32 ASSERT(isolate_ != NULL); | 32 ASSERT(isolate_ != NULL); |
33 thread_local_.jslimit_ = thread_local_.real_jslimit_; | 33 thread_local_.jslimit_ = thread_local_.real_jslimit_; |
34 thread_local_.climit_ = thread_local_.real_climit_; | 34 thread_local_.climit_ = thread_local_.real_climit_; |
35 isolate_->heap()->SetStackLimits(); | 35 isolate_->heap()->SetStackLimits(); |
36 } | 36 } |
37 | 37 |
38 | 38 |
39 static Handle<Object> Invoke(bool is_construct, | 39 MUST_USE_RESULT static MaybeHandle<Object> Invoke( |
40 Handle<JSFunction> function, | 40 bool is_construct, |
41 Handle<Object> receiver, | 41 Handle<JSFunction> function, |
42 int argc, | 42 Handle<Object> receiver, |
43 Handle<Object> args[], | 43 int argc, |
44 bool* has_pending_exception) { | 44 Handle<Object> args[]) { |
45 Isolate* isolate = function->GetIsolate(); | 45 Isolate* isolate = function->GetIsolate(); |
46 | 46 |
47 // Entering JavaScript. | 47 // Entering JavaScript. |
48 VMState<JS> state(isolate); | 48 VMState<JS> state(isolate); |
49 CHECK(AllowJavascriptExecution::IsAllowed(isolate)); | 49 CHECK(AllowJavascriptExecution::IsAllowed(isolate)); |
50 if (!ThrowOnJavascriptExecution::IsAllowed(isolate)) { | 50 if (!ThrowOnJavascriptExecution::IsAllowed(isolate)) { |
51 isolate->ThrowIllegalOperation(); | 51 isolate->ThrowIllegalOperation(); |
52 *has_pending_exception = true; | |
53 isolate->ReportPendingMessages(); | 52 isolate->ReportPendingMessages(); |
54 return Handle<Object>(); | 53 return MaybeHandle<Object>(); |
55 } | 54 } |
56 | 55 |
57 // Placeholder for return value. | 56 // Placeholder for return value. |
58 MaybeObject* value = reinterpret_cast<Object*>(kZapValue); | 57 MaybeObject* value = reinterpret_cast<Object*>(kZapValue); |
59 | 58 |
60 typedef Object* (*JSEntryFunction)(byte* entry, | 59 typedef Object* (*JSEntryFunction)(byte* entry, |
61 Object* function, | 60 Object* function, |
62 Object* receiver, | 61 Object* receiver, |
63 int argc, | 62 int argc, |
64 Object*** args); | 63 Object*** args); |
(...skipping 28 matching lines...) Expand all Loading... |
93 Object*** argv = reinterpret_cast<Object***>(args); | 92 Object*** argv = reinterpret_cast<Object***>(args); |
94 value = | 93 value = |
95 CALL_GENERATED_CODE(stub_entry, function_entry, func, recv, argc, argv); | 94 CALL_GENERATED_CODE(stub_entry, function_entry, func, recv, argc, argv); |
96 } | 95 } |
97 | 96 |
98 #ifdef VERIFY_HEAP | 97 #ifdef VERIFY_HEAP |
99 value->Verify(); | 98 value->Verify(); |
100 #endif | 99 #endif |
101 | 100 |
102 // Update the pending exception flag and return the value. | 101 // Update the pending exception flag and return the value. |
103 *has_pending_exception = value->IsException(); | 102 bool has_exception = value->IsException(); |
104 ASSERT(*has_pending_exception == isolate->has_pending_exception()); | 103 ASSERT(has_exception == isolate->has_pending_exception()); |
105 if (*has_pending_exception) { | 104 if (has_exception) { |
106 isolate->ReportPendingMessages(); | 105 isolate->ReportPendingMessages(); |
107 #ifdef ENABLE_DEBUGGER_SUPPORT | 106 #ifdef ENABLE_DEBUGGER_SUPPORT |
108 // Reset stepping state when script exits with uncaught exception. | 107 // Reset stepping state when script exits with uncaught exception. |
109 if (isolate->debugger()->IsDebuggerActive()) { | 108 if (isolate->debugger()->IsDebuggerActive()) { |
110 isolate->debug()->ClearStepping(); | 109 isolate->debug()->ClearStepping(); |
111 } | 110 } |
112 #endif // ENABLE_DEBUGGER_SUPPORT | 111 #endif // ENABLE_DEBUGGER_SUPPORT |
113 return Handle<Object>(); | 112 return MaybeHandle<Object>(); |
114 } else { | 113 } else { |
115 isolate->clear_pending_message(); | 114 isolate->clear_pending_message(); |
116 } | 115 } |
117 | 116 |
118 return Handle<Object>(value->ToObjectUnchecked(), isolate); | 117 return Handle<Object>(value->ToObjectUnchecked(), isolate); |
119 } | 118 } |
120 | 119 |
121 | 120 |
122 Handle<Object> Execution::Call(Isolate* isolate, | 121 MaybeHandle<Object> Execution::Call(Isolate* isolate, |
123 Handle<Object> callable, | 122 Handle<Object> callable, |
124 Handle<Object> receiver, | 123 Handle<Object> receiver, |
125 int argc, | 124 int argc, |
126 Handle<Object> argv[], | 125 Handle<Object> argv[], |
127 bool* pending_exception, | 126 bool convert_receiver) { |
128 bool convert_receiver) { | |
129 *pending_exception = false; | |
130 | |
131 if (!callable->IsJSFunction()) { | 127 if (!callable->IsJSFunction()) { |
132 callable = TryGetFunctionDelegate(isolate, callable, pending_exception); | 128 ASSIGN_RETURN_ON_EXCEPTION( |
133 if (*pending_exception) return callable; | 129 isolate, callable, TryGetFunctionDelegate(isolate, callable), Object); |
134 } | 130 } |
135 Handle<JSFunction> func = Handle<JSFunction>::cast(callable); | 131 Handle<JSFunction> func = Handle<JSFunction>::cast(callable); |
136 | 132 |
137 // In sloppy mode, convert receiver. | 133 // In sloppy mode, convert receiver. |
138 if (convert_receiver && !receiver->IsJSReceiver() && | 134 if (convert_receiver && !receiver->IsJSReceiver() && |
139 !func->shared()->native() && | 135 !func->shared()->native() && |
140 func->shared()->strict_mode() == SLOPPY) { | 136 func->shared()->strict_mode() == SLOPPY) { |
141 if (receiver->IsUndefined() || receiver->IsNull()) { | 137 if (receiver->IsUndefined() || receiver->IsNull()) { |
142 Object* global = func->context()->global_object()->global_receiver(); | 138 Object* global = func->context()->global_object()->global_receiver(); |
143 // Under some circumstances, 'global' can be the JSBuiltinsObject | 139 // Under some circumstances, 'global' can be the JSBuiltinsObject |
144 // In that case, don't rewrite. (FWIW, the same holds for | 140 // In that case, don't rewrite. (FWIW, the same holds for |
145 // GetIsolate()->global_object()->global_receiver().) | 141 // GetIsolate()->global_object()->global_receiver().) |
146 if (!global->IsJSBuiltinsObject()) { | 142 if (!global->IsJSBuiltinsObject()) { |
147 receiver = Handle<Object>(global, func->GetIsolate()); | 143 receiver = Handle<Object>(global, func->GetIsolate()); |
148 } | 144 } |
149 } else { | 145 } else { |
150 receiver = ToObject(isolate, receiver, pending_exception); | 146 ASSIGN_RETURN_ON_EXCEPTION( |
| 147 isolate, receiver, ToObject(isolate, receiver), Object); |
151 } | 148 } |
152 if (*pending_exception) return callable; | |
153 } | 149 } |
154 | 150 |
155 return Invoke(false, func, receiver, argc, argv, pending_exception); | 151 return Invoke(false, func, receiver, argc, argv); |
156 } | 152 } |
157 | 153 |
158 | 154 |
159 Handle<Object> Execution::New(Handle<JSFunction> func, | 155 MaybeHandle<Object> Execution::New(Handle<JSFunction> func, |
160 int argc, | 156 int argc, |
161 Handle<Object> argv[], | 157 Handle<Object> argv[]) { |
162 bool* pending_exception) { | 158 return Invoke(true, func, func->GetIsolate()->global_object(), argc, argv); |
163 return Invoke(true, func, func->GetIsolate()->global_object(), argc, argv, | |
164 pending_exception); | |
165 } | 159 } |
166 | 160 |
167 | 161 |
168 Handle<Object> Execution::TryCall(Handle<JSFunction> func, | 162 MaybeHandle<Object> Execution::TryCall(Handle<JSFunction> func, |
169 Handle<Object> receiver, | 163 Handle<Object> receiver, |
170 int argc, | 164 int argc, |
171 Handle<Object> args[], | 165 Handle<Object> args[], |
172 bool* caught_exception) { | 166 Handle<Object>* exception_out) { |
173 // Enter a try-block while executing the JavaScript code. To avoid | 167 // Enter a try-block while executing the JavaScript code. To avoid |
174 // duplicate error printing it must be non-verbose. Also, to avoid | 168 // duplicate error printing it must be non-verbose. Also, to avoid |
175 // creating message objects during stack overflow we shouldn't | 169 // creating message objects during stack overflow we shouldn't |
176 // capture messages. | 170 // capture messages. |
177 v8::TryCatch catcher; | 171 v8::TryCatch catcher; |
178 catcher.SetVerbose(false); | 172 catcher.SetVerbose(false); |
179 catcher.SetCaptureMessage(false); | 173 catcher.SetCaptureMessage(false); |
180 *caught_exception = false; | |
181 | 174 |
182 // Get isolate now, because handle might be persistent | 175 // Get isolate now, because handle might be persistent |
183 // and get destroyed in the next call. | 176 // and get destroyed in the next call. |
184 Isolate* isolate = func->GetIsolate(); | 177 Isolate* isolate = func->GetIsolate(); |
185 Handle<Object> result = Invoke(false, func, receiver, argc, args, | 178 MaybeHandle<Object> maybe_result = Invoke(false, func, receiver, argc, args); |
186 caught_exception); | |
187 | 179 |
188 if (*caught_exception) { | 180 if (maybe_result.is_null()) { |
189 ASSERT(catcher.HasCaught()); | 181 ASSERT(catcher.HasCaught()); |
190 ASSERT(isolate->has_pending_exception()); | 182 ASSERT(isolate->has_pending_exception()); |
191 ASSERT(isolate->external_caught_exception()); | 183 ASSERT(isolate->external_caught_exception()); |
192 if (isolate->pending_exception() == | 184 if (exception_out != NULL) { |
193 isolate->heap()->termination_exception()) { | 185 if (isolate->pending_exception() == |
194 result = isolate->factory()->termination_exception(); | 186 isolate->heap()->termination_exception()) { |
195 } else { | 187 *exception_out = isolate->factory()->termination_exception(); |
196 result = v8::Utils::OpenHandle(*catcher.Exception()); | 188 } else { |
| 189 *exception_out = v8::Utils::OpenHandle(*catcher.Exception()); |
| 190 } |
197 } | 191 } |
198 isolate->OptionalRescheduleException(true); | 192 isolate->OptionalRescheduleException(true); |
199 } | 193 } |
200 | 194 |
201 ASSERT(!isolate->has_pending_exception()); | 195 ASSERT(!isolate->has_pending_exception()); |
202 ASSERT(!isolate->external_caught_exception()); | 196 ASSERT(!isolate->external_caught_exception()); |
203 return result; | 197 return maybe_result; |
204 } | 198 } |
205 | 199 |
206 | 200 |
207 Handle<Object> Execution::GetFunctionDelegate(Isolate* isolate, | 201 Handle<Object> Execution::GetFunctionDelegate(Isolate* isolate, |
208 Handle<Object> object) { | 202 Handle<Object> object) { |
209 ASSERT(!object->IsJSFunction()); | 203 ASSERT(!object->IsJSFunction()); |
210 Factory* factory = isolate->factory(); | 204 Factory* factory = isolate->factory(); |
211 | 205 |
212 // If you return a function from here, it will be called when an | 206 // If you return a function from here, it will be called when an |
213 // attempt is made to call the given object as a function. | 207 // attempt is made to call the given object as a function. |
(...skipping 10 matching lines...) Expand all Loading... |
224 if (fun->IsHeapObject() && | 218 if (fun->IsHeapObject() && |
225 HeapObject::cast(fun)->map()->has_instance_call_handler()) { | 219 HeapObject::cast(fun)->map()->has_instance_call_handler()) { |
226 return Handle<JSFunction>( | 220 return Handle<JSFunction>( |
227 isolate->native_context()->call_as_function_delegate()); | 221 isolate->native_context()->call_as_function_delegate()); |
228 } | 222 } |
229 | 223 |
230 return factory->undefined_value(); | 224 return factory->undefined_value(); |
231 } | 225 } |
232 | 226 |
233 | 227 |
234 Handle<Object> Execution::TryGetFunctionDelegate(Isolate* isolate, | 228 MaybeHandle<Object> Execution::TryGetFunctionDelegate(Isolate* isolate, |
235 Handle<Object> object, | 229 Handle<Object> object) { |
236 bool* has_pending_exception) { | |
237 ASSERT(!object->IsJSFunction()); | 230 ASSERT(!object->IsJSFunction()); |
238 | 231 |
239 // If object is a function proxy, get its handler. Iterate if necessary. | 232 // If object is a function proxy, get its handler. Iterate if necessary. |
240 Object* fun = *object; | 233 Object* fun = *object; |
241 while (fun->IsJSFunctionProxy()) { | 234 while (fun->IsJSFunctionProxy()) { |
242 fun = JSFunctionProxy::cast(fun)->call_trap(); | 235 fun = JSFunctionProxy::cast(fun)->call_trap(); |
243 } | 236 } |
244 if (fun->IsJSFunction()) return Handle<Object>(fun, isolate); | 237 if (fun->IsJSFunction()) return Handle<Object>(fun, isolate); |
245 | 238 |
246 // Objects created through the API can have an instance-call handler | 239 // Objects created through the API can have an instance-call handler |
247 // that should be used when calling the object as a function. | 240 // that should be used when calling the object as a function. |
248 if (fun->IsHeapObject() && | 241 if (fun->IsHeapObject() && |
249 HeapObject::cast(fun)->map()->has_instance_call_handler()) { | 242 HeapObject::cast(fun)->map()->has_instance_call_handler()) { |
250 return Handle<JSFunction>( | 243 return Handle<JSFunction>( |
251 isolate->native_context()->call_as_function_delegate()); | 244 isolate->native_context()->call_as_function_delegate()); |
252 } | 245 } |
253 | 246 |
254 // If the Object doesn't have an instance-call handler we should | 247 // If the Object doesn't have an instance-call handler we should |
255 // throw a non-callable exception. | 248 // throw a non-callable exception. |
256 i::Handle<i::Object> error_obj = isolate->factory()->NewTypeError( | 249 i::Handle<i::Object> error_obj = isolate->factory()->NewTypeError( |
257 "called_non_callable", i::HandleVector<i::Object>(&object, 1)); | 250 "called_non_callable", i::HandleVector<i::Object>(&object, 1)); |
258 isolate->Throw(*error_obj); | |
259 *has_pending_exception = true; | |
260 | 251 |
261 return isolate->factory()->undefined_value(); | 252 return isolate->Throw<Object>(error_obj); |
262 } | 253 } |
263 | 254 |
264 | 255 |
265 Handle<Object> Execution::GetConstructorDelegate(Isolate* isolate, | 256 Handle<Object> Execution::GetConstructorDelegate(Isolate* isolate, |
266 Handle<Object> object) { | 257 Handle<Object> object) { |
267 ASSERT(!object->IsJSFunction()); | 258 ASSERT(!object->IsJSFunction()); |
268 | 259 |
269 // If you return a function from here, it will be called when an | 260 // If you return a function from here, it will be called when an |
270 // attempt is made to call the given object as a constructor. | 261 // attempt is made to call the given object as a constructor. |
271 | 262 |
272 // If object is a function proxies, get its handler. Iterate if necessary. | 263 // If object is a function proxies, get its handler. Iterate if necessary. |
273 Object* fun = *object; | 264 Object* fun = *object; |
274 while (fun->IsJSFunctionProxy()) { | 265 while (fun->IsJSFunctionProxy()) { |
275 fun = JSFunctionProxy::cast(fun)->call_trap(); | 266 fun = JSFunctionProxy::cast(fun)->call_trap(); |
276 } | 267 } |
277 if (fun->IsJSFunction()) return Handle<Object>(fun, isolate); | 268 if (fun->IsJSFunction()) return Handle<Object>(fun, isolate); |
278 | 269 |
279 // Objects created through the API can have an instance-call handler | 270 // Objects created through the API can have an instance-call handler |
280 // that should be used when calling the object as a function. | 271 // that should be used when calling the object as a function. |
281 if (fun->IsHeapObject() && | 272 if (fun->IsHeapObject() && |
282 HeapObject::cast(fun)->map()->has_instance_call_handler()) { | 273 HeapObject::cast(fun)->map()->has_instance_call_handler()) { |
283 return Handle<JSFunction>( | 274 return Handle<JSFunction>( |
284 isolate->native_context()->call_as_constructor_delegate()); | 275 isolate->native_context()->call_as_constructor_delegate()); |
285 } | 276 } |
286 | 277 |
287 return isolate->factory()->undefined_value(); | 278 return isolate->factory()->undefined_value(); |
288 } | 279 } |
289 | 280 |
290 | 281 |
291 Handle<Object> Execution::TryGetConstructorDelegate( | 282 MaybeHandle<Object> Execution::TryGetConstructorDelegate( |
292 Isolate* isolate, | 283 Isolate* isolate, Handle<Object> object) { |
293 Handle<Object> object, | |
294 bool* has_pending_exception) { | |
295 ASSERT(!object->IsJSFunction()); | 284 ASSERT(!object->IsJSFunction()); |
296 | 285 |
297 // If you return a function from here, it will be called when an | 286 // If you return a function from here, it will be called when an |
298 // attempt is made to call the given object as a constructor. | 287 // attempt is made to call the given object as a constructor. |
299 | 288 |
300 // If object is a function proxies, get its handler. Iterate if necessary. | 289 // If object is a function proxies, get its handler. Iterate if necessary. |
301 Object* fun = *object; | 290 Object* fun = *object; |
302 while (fun->IsJSFunctionProxy()) { | 291 while (fun->IsJSFunctionProxy()) { |
303 fun = JSFunctionProxy::cast(fun)->call_trap(); | 292 fun = JSFunctionProxy::cast(fun)->call_trap(); |
304 } | 293 } |
305 if (fun->IsJSFunction()) return Handle<Object>(fun, isolate); | 294 if (fun->IsJSFunction()) return Handle<Object>(fun, isolate); |
306 | 295 |
307 // Objects created through the API can have an instance-call handler | 296 // Objects created through the API can have an instance-call handler |
308 // that should be used when calling the object as a function. | 297 // that should be used when calling the object as a function. |
309 if (fun->IsHeapObject() && | 298 if (fun->IsHeapObject() && |
310 HeapObject::cast(fun)->map()->has_instance_call_handler()) { | 299 HeapObject::cast(fun)->map()->has_instance_call_handler()) { |
311 return Handle<JSFunction>( | 300 return Handle<JSFunction>( |
312 isolate->native_context()->call_as_constructor_delegate()); | 301 isolate->native_context()->call_as_constructor_delegate()); |
313 } | 302 } |
314 | 303 |
315 // If the Object doesn't have an instance-call handler we should | 304 // If the Object doesn't have an instance-call handler we should |
316 // throw a non-callable exception. | 305 // throw a non-callable exception. |
317 i::Handle<i::Object> error_obj = isolate->factory()->NewTypeError( | 306 i::Handle<i::Object> error_obj = isolate->factory()->NewTypeError( |
318 "called_non_callable", i::HandleVector<i::Object>(&object, 1)); | 307 "called_non_callable", i::HandleVector<i::Object>(&object, 1)); |
319 isolate->Throw(*error_obj); | 308 return isolate->Throw<Object>(error_obj); |
320 *has_pending_exception = true; | |
321 | |
322 return isolate->factory()->undefined_value(); | |
323 } | 309 } |
324 | 310 |
325 | 311 |
326 void Execution::RunMicrotasks(Isolate* isolate) { | 312 void Execution::RunMicrotasks(Isolate* isolate) { |
327 ASSERT(isolate->microtask_pending()); | 313 ASSERT(isolate->microtask_pending()); |
328 bool threw = false; | |
329 Execution::Call( | 314 Execution::Call( |
330 isolate, | 315 isolate, |
331 isolate->run_microtasks(), | 316 isolate->run_microtasks(), |
332 isolate->factory()->undefined_value(), | 317 isolate->factory()->undefined_value(), |
333 0, | 318 0, |
334 NULL, | 319 NULL).Assert(); |
335 &threw); | |
336 ASSERT(!threw); | |
337 } | 320 } |
338 | 321 |
339 | 322 |
340 void Execution::EnqueueMicrotask(Isolate* isolate, Handle<Object> microtask) { | 323 void Execution::EnqueueMicrotask(Isolate* isolate, Handle<Object> microtask) { |
341 bool threw = false; | |
342 Handle<Object> args[] = { microtask }; | 324 Handle<Object> args[] = { microtask }; |
343 Execution::Call( | 325 Execution::Call( |
344 isolate, | 326 isolate, |
345 isolate->enqueue_external_microtask(), | 327 isolate->enqueue_external_microtask(), |
346 isolate->factory()->undefined_value(), | 328 isolate->factory()->undefined_value(), |
347 1, | 329 1, |
348 args, | 330 args).Assert(); |
349 &threw); | |
350 ASSERT(!threw); | |
351 } | 331 } |
352 | 332 |
353 | 333 |
354 bool StackGuard::IsStackOverflow() { | 334 bool StackGuard::IsStackOverflow() { |
355 ExecutionAccess access(isolate_); | 335 ExecutionAccess access(isolate_); |
356 return (thread_local_.jslimit_ != kInterruptLimit && | 336 return (thread_local_.jslimit_ != kInterruptLimit && |
357 thread_local_.climit_ != kInterruptLimit); | 337 thread_local_.climit_ != kInterruptLimit); |
358 } | 338 } |
359 | 339 |
360 | 340 |
(...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
658 uintptr_t stored_limit = per_thread->stack_limit(); | 638 uintptr_t stored_limit = per_thread->stack_limit(); |
659 // You should hold the ExecutionAccess lock when you call this. | 639 // You should hold the ExecutionAccess lock when you call this. |
660 if (stored_limit != 0) { | 640 if (stored_limit != 0) { |
661 SetStackLimit(stored_limit); | 641 SetStackLimit(stored_limit); |
662 } | 642 } |
663 } | 643 } |
664 | 644 |
665 | 645 |
666 // --- C a l l s t o n a t i v e s --- | 646 // --- C a l l s t o n a t i v e s --- |
667 | 647 |
668 #define RETURN_NATIVE_CALL(name, args, has_pending_exception) \ | 648 #define RETURN_NATIVE_CALL(name, args) \ |
669 do { \ | 649 do { \ |
670 Handle<Object> argv[] = args; \ | 650 Handle<Object> argv[] = args; \ |
671 ASSERT(has_pending_exception != NULL); \ | |
672 return Call(isolate, \ | 651 return Call(isolate, \ |
673 isolate->name##_fun(), \ | 652 isolate->name##_fun(), \ |
674 isolate->js_builtins_object(), \ | 653 isolate->js_builtins_object(), \ |
675 ARRAY_SIZE(argv), argv, \ | 654 ARRAY_SIZE(argv), argv); \ |
676 has_pending_exception); \ | |
677 } while (false) | 655 } while (false) |
678 | 656 |
679 | 657 |
680 Handle<Object> Execution::ToNumber( | 658 MaybeHandle<Object> Execution::ToNumber( |
681 Isolate* isolate, Handle<Object> obj, bool* exc) { | 659 Isolate* isolate, Handle<Object> obj) { |
682 RETURN_NATIVE_CALL(to_number, { obj }, exc); | 660 RETURN_NATIVE_CALL(to_number, { obj }); |
683 } | 661 } |
684 | 662 |
685 | 663 |
686 Handle<Object> Execution::ToString( | 664 MaybeHandle<Object> Execution::ToString( |
687 Isolate* isolate, Handle<Object> obj, bool* exc) { | 665 Isolate* isolate, Handle<Object> obj) { |
688 RETURN_NATIVE_CALL(to_string, { obj }, exc); | 666 RETURN_NATIVE_CALL(to_string, { obj }); |
689 } | 667 } |
690 | 668 |
691 | 669 |
692 Handle<Object> Execution::ToDetailString( | 670 MaybeHandle<Object> Execution::ToDetailString( |
693 Isolate* isolate, Handle<Object> obj, bool* exc) { | 671 Isolate* isolate, Handle<Object> obj) { |
694 RETURN_NATIVE_CALL(to_detail_string, { obj }, exc); | 672 RETURN_NATIVE_CALL(to_detail_string, { obj }); |
695 } | 673 } |
696 | 674 |
697 | 675 |
698 Handle<Object> Execution::ToObject( | 676 MaybeHandle<Object> Execution::ToObject( |
699 Isolate* isolate, Handle<Object> obj, bool* exc) { | 677 Isolate* isolate, Handle<Object> obj) { |
700 if (obj->IsSpecObject()) return obj; | 678 if (obj->IsSpecObject()) return obj; |
701 RETURN_NATIVE_CALL(to_object, { obj }, exc); | 679 RETURN_NATIVE_CALL(to_object, { obj }); |
702 } | 680 } |
703 | 681 |
704 | 682 |
705 Handle<Object> Execution::ToInteger( | 683 MaybeHandle<Object> Execution::ToInteger( |
706 Isolate* isolate, Handle<Object> obj, bool* exc) { | 684 Isolate* isolate, Handle<Object> obj) { |
707 RETURN_NATIVE_CALL(to_integer, { obj }, exc); | 685 RETURN_NATIVE_CALL(to_integer, { obj }); |
708 } | 686 } |
709 | 687 |
710 | 688 |
711 Handle<Object> Execution::ToUint32( | 689 MaybeHandle<Object> Execution::ToUint32( |
712 Isolate* isolate, Handle<Object> obj, bool* exc) { | 690 Isolate* isolate, Handle<Object> obj) { |
713 RETURN_NATIVE_CALL(to_uint32, { obj }, exc); | 691 RETURN_NATIVE_CALL(to_uint32, { obj }); |
714 } | 692 } |
715 | 693 |
716 | 694 |
717 Handle<Object> Execution::ToInt32( | 695 MaybeHandle<Object> Execution::ToInt32( |
718 Isolate* isolate, Handle<Object> obj, bool* exc) { | 696 Isolate* isolate, Handle<Object> obj) { |
719 RETURN_NATIVE_CALL(to_int32, { obj }, exc); | 697 RETURN_NATIVE_CALL(to_int32, { obj }); |
720 } | 698 } |
721 | 699 |
722 | 700 |
723 Handle<Object> Execution::NewDate(Isolate* isolate, double time, bool* exc) { | 701 MaybeHandle<Object> Execution::NewDate(Isolate* isolate, double time) { |
724 Handle<Object> time_obj = isolate->factory()->NewNumber(time); | 702 Handle<Object> time_obj = isolate->factory()->NewNumber(time); |
725 RETURN_NATIVE_CALL(create_date, { time_obj }, exc); | 703 RETURN_NATIVE_CALL(create_date, { time_obj }); |
726 } | 704 } |
727 | 705 |
728 | 706 |
729 #undef RETURN_NATIVE_CALL | 707 #undef RETURN_NATIVE_CALL |
730 | 708 |
731 | 709 |
732 Handle<JSRegExp> Execution::NewJSRegExp(Handle<String> pattern, | 710 MaybeHandle<JSRegExp> Execution::NewJSRegExp(Handle<String> pattern, |
733 Handle<String> flags, | 711 Handle<String> flags) { |
734 bool* exc) { | 712 Isolate* isolate = pattern->GetIsolate(); |
735 Handle<JSFunction> function = Handle<JSFunction>( | 713 Handle<JSFunction> function = Handle<JSFunction>( |
736 pattern->GetIsolate()->native_context()->regexp_function()); | 714 isolate->native_context()->regexp_function()); |
737 Handle<Object> re_obj = RegExpImpl::CreateRegExpLiteral( | 715 Handle<Object> re_obj; |
738 function, pattern, flags, exc); | 716 ASSIGN_RETURN_ON_EXCEPTION( |
739 if (*exc) return Handle<JSRegExp>(); | 717 isolate, re_obj, |
| 718 RegExpImpl::CreateRegExpLiteral(function, pattern, flags), |
| 719 JSRegExp); |
740 return Handle<JSRegExp>::cast(re_obj); | 720 return Handle<JSRegExp>::cast(re_obj); |
741 } | 721 } |
742 | 722 |
743 | 723 |
744 Handle<Object> Execution::CharAt(Handle<String> string, uint32_t index) { | 724 Handle<Object> Execution::CharAt(Handle<String> string, uint32_t index) { |
745 Isolate* isolate = string->GetIsolate(); | 725 Isolate* isolate = string->GetIsolate(); |
746 Factory* factory = isolate->factory(); | 726 Factory* factory = isolate->factory(); |
747 | 727 |
748 int int_index = static_cast<int>(index); | 728 int int_index = static_cast<int>(index); |
749 if (int_index < 0 || int_index >= string->length()) { | 729 if (int_index < 0 || int_index >= string->length()) { |
750 return factory->undefined_value(); | 730 return factory->undefined_value(); |
751 } | 731 } |
752 | 732 |
753 Handle<Object> char_at = Object::GetProperty( | 733 Handle<Object> char_at = Object::GetProperty( |
754 isolate->js_builtins_object(), factory->char_at_string()); | 734 isolate->js_builtins_object(), factory->char_at_string()); |
755 if (!char_at->IsJSFunction()) { | 735 if (!char_at->IsJSFunction()) { |
756 return factory->undefined_value(); | 736 return factory->undefined_value(); |
757 } | 737 } |
758 | 738 |
759 bool caught_exception; | |
760 Handle<Object> index_object = factory->NewNumberFromInt(int_index); | 739 Handle<Object> index_object = factory->NewNumberFromInt(int_index); |
761 Handle<Object> index_arg[] = { index_object }; | 740 Handle<Object> index_arg[] = { index_object }; |
762 Handle<Object> result = TryCall(Handle<JSFunction>::cast(char_at), | 741 Handle<Object> result; |
763 string, | 742 ASSIGN_RETURN_ON_EXCEPTION_VALUE( |
764 ARRAY_SIZE(index_arg), | 743 isolate, result, |
765 index_arg, | 744 TryCall(Handle<JSFunction>::cast(char_at), |
766 &caught_exception); | 745 string, |
767 if (caught_exception) { | 746 ARRAY_SIZE(index_arg), |
768 return factory->undefined_value(); | 747 index_arg), |
769 } | 748 factory->undefined_value()); |
770 return result; | 749 return result; |
771 } | 750 } |
772 | 751 |
773 | 752 |
774 Handle<JSFunction> Execution::InstantiateFunction( | 753 MaybeHandle<JSFunction> Execution::InstantiateFunction( |
775 Handle<FunctionTemplateInfo> data, | 754 Handle<FunctionTemplateInfo> data) { |
776 bool* exc) { | |
777 Isolate* isolate = data->GetIsolate(); | 755 Isolate* isolate = data->GetIsolate(); |
778 if (!data->do_not_cache()) { | 756 if (!data->do_not_cache()) { |
779 // Fast case: see if the function has already been instantiated | 757 // Fast case: see if the function has already been instantiated |
780 int serial_number = Smi::cast(data->serial_number())->value(); | 758 int serial_number = Smi::cast(data->serial_number())->value(); |
781 Handle<JSObject> cache(isolate->native_context()->function_cache()); | 759 Handle<JSObject> cache(isolate->native_context()->function_cache()); |
782 Handle<Object> elm = | 760 Handle<Object> elm = |
783 Object::GetElementNoExceptionThrown(isolate, cache, serial_number); | 761 Object::GetElementNoExceptionThrown(isolate, cache, serial_number); |
784 if (elm->IsJSFunction()) return Handle<JSFunction>::cast(elm); | 762 if (elm->IsJSFunction()) return Handle<JSFunction>::cast(elm); |
785 } | 763 } |
786 // The function has not yet been instantiated in this context; do it. | 764 // The function has not yet been instantiated in this context; do it. |
787 Handle<Object> args[] = { data }; | 765 Handle<Object> args[] = { data }; |
788 Handle<Object> result = Call(isolate, | 766 Handle<Object> result; |
789 isolate->instantiate_fun(), | 767 ASSIGN_RETURN_ON_EXCEPTION( |
790 isolate->js_builtins_object(), | 768 isolate, result, |
791 ARRAY_SIZE(args), | 769 Call(isolate, |
792 args, | 770 isolate->instantiate_fun(), |
793 exc); | 771 isolate->js_builtins_object(), |
794 if (*exc) return Handle<JSFunction>::null(); | 772 ARRAY_SIZE(args), |
| 773 args), |
| 774 JSFunction); |
795 return Handle<JSFunction>::cast(result); | 775 return Handle<JSFunction>::cast(result); |
796 } | 776 } |
797 | 777 |
798 | 778 |
799 Handle<JSObject> Execution::InstantiateObject(Handle<ObjectTemplateInfo> data, | 779 MaybeHandle<JSObject> Execution::InstantiateObject( |
800 bool* exc) { | 780 Handle<ObjectTemplateInfo> data) { |
801 Isolate* isolate = data->GetIsolate(); | 781 Isolate* isolate = data->GetIsolate(); |
| 782 Handle<Object> result; |
802 if (data->property_list()->IsUndefined() && | 783 if (data->property_list()->IsUndefined() && |
803 !data->constructor()->IsUndefined()) { | 784 !data->constructor()->IsUndefined()) { |
804 // Initialization to make gcc happy. | 785 Handle<FunctionTemplateInfo> cons_template = |
805 Object* result = NULL; | 786 Handle<FunctionTemplateInfo>( |
806 { | 787 FunctionTemplateInfo::cast(data->constructor())); |
807 HandleScope scope(isolate); | 788 Handle<JSFunction> cons; |
808 Handle<FunctionTemplateInfo> cons_template = | 789 ASSIGN_RETURN_ON_EXCEPTION( |
809 Handle<FunctionTemplateInfo>( | 790 isolate, cons, InstantiateFunction(cons_template), JSObject); |
810 FunctionTemplateInfo::cast(data->constructor())); | 791 ASSIGN_RETURN_ON_EXCEPTION(isolate, result, New(cons, 0, NULL), JSObject); |
811 Handle<JSFunction> cons = InstantiateFunction(cons_template, exc); | |
812 if (*exc) return Handle<JSObject>::null(); | |
813 Handle<Object> value = New(cons, 0, NULL, exc); | |
814 if (*exc) return Handle<JSObject>::null(); | |
815 result = *value; | |
816 } | |
817 ASSERT(!*exc); | |
818 return Handle<JSObject>(JSObject::cast(result)); | |
819 } else { | 792 } else { |
820 Handle<Object> args[] = { data }; | 793 Handle<Object> args[] = { data }; |
821 Handle<Object> result = Call(isolate, | 794 ASSIGN_RETURN_ON_EXCEPTION( |
822 isolate->instantiate_fun(), | 795 isolate, result, |
823 isolate->js_builtins_object(), | 796 Call(isolate, |
824 ARRAY_SIZE(args), | 797 isolate->instantiate_fun(), |
825 args, | 798 isolate->js_builtins_object(), |
826 exc); | 799 ARRAY_SIZE(args), |
827 if (*exc) return Handle<JSObject>::null(); | 800 args), |
828 return Handle<JSObject>::cast(result); | 801 JSObject); |
829 } | 802 } |
| 803 return Handle<JSObject>::cast(result); |
830 } | 804 } |
831 | 805 |
832 | 806 |
833 void Execution::ConfigureInstance(Isolate* isolate, | 807 MaybeHandle<Object> Execution::ConfigureInstance( |
834 Handle<Object> instance, | 808 Isolate* isolate, |
835 Handle<Object> instance_template, | 809 Handle<Object> instance, |
836 bool* exc) { | 810 Handle<Object> instance_template) { |
837 Handle<Object> args[] = { instance, instance_template }; | 811 Handle<Object> args[] = { instance, instance_template }; |
838 Execution::Call(isolate, | 812 return Execution::Call(isolate, |
839 isolate->configure_instance_fun(), | 813 isolate->configure_instance_fun(), |
840 isolate->js_builtins_object(), | 814 isolate->js_builtins_object(), |
841 ARRAY_SIZE(args), | 815 ARRAY_SIZE(args), |
842 args, | 816 args); |
843 exc); | |
844 } | 817 } |
845 | 818 |
846 | 819 |
847 Handle<String> Execution::GetStackTraceLine(Handle<Object> recv, | 820 Handle<String> Execution::GetStackTraceLine(Handle<Object> recv, |
848 Handle<JSFunction> fun, | 821 Handle<JSFunction> fun, |
849 Handle<Object> pos, | 822 Handle<Object> pos, |
850 Handle<Object> is_global) { | 823 Handle<Object> is_global) { |
851 Isolate* isolate = fun->GetIsolate(); | 824 Isolate* isolate = fun->GetIsolate(); |
852 Handle<Object> args[] = { recv, fun, pos, is_global }; | 825 Handle<Object> args[] = { recv, fun, pos, is_global }; |
853 bool caught_exception; | 826 MaybeHandle<Object> maybe_result = |
854 Handle<Object> result = TryCall(isolate->get_stack_trace_line_fun(), | 827 TryCall(isolate->get_stack_trace_line_fun(), |
855 isolate->js_builtins_object(), | 828 isolate->js_builtins_object(), |
856 ARRAY_SIZE(args), | 829 ARRAY_SIZE(args), |
857 args, | 830 args); |
858 &caught_exception); | 831 Handle<Object> result; |
859 if (caught_exception || !result->IsString()) { | 832 if (!maybe_result.ToHandle(&result) || !result->IsString()) { |
860 return isolate->factory()->empty_string(); | 833 return isolate->factory()->empty_string(); |
861 } | 834 } |
862 | 835 |
863 return Handle<String>::cast(result); | 836 return Handle<String>::cast(result); |
864 } | 837 } |
865 | 838 |
866 | 839 |
867 static Object* RuntimePreempt(Isolate* isolate) { | 840 static Object* RuntimePreempt(Isolate* isolate) { |
868 // Clear the preempt request flag. | 841 // Clear the preempt request flag. |
869 isolate->stack_guard()->Continue(PREEMPT); | 842 isolate->stack_guard()->Continue(PREEMPT); |
870 | 843 |
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1012 if (stack_guard->IsInstallCodeRequest()) { | 985 if (stack_guard->IsInstallCodeRequest()) { |
1013 ASSERT(isolate->concurrent_recompilation_enabled()); | 986 ASSERT(isolate->concurrent_recompilation_enabled()); |
1014 stack_guard->Continue(INSTALL_CODE); | 987 stack_guard->Continue(INSTALL_CODE); |
1015 isolate->optimizing_compiler_thread()->InstallOptimizedFunctions(); | 988 isolate->optimizing_compiler_thread()->InstallOptimizedFunctions(); |
1016 } | 989 } |
1017 isolate->runtime_profiler()->OptimizeNow(); | 990 isolate->runtime_profiler()->OptimizeNow(); |
1018 return isolate->heap()->undefined_value(); | 991 return isolate->heap()->undefined_value(); |
1019 } | 992 } |
1020 | 993 |
1021 } } // namespace v8::internal | 994 } } // namespace v8::internal |
OLD | NEW |