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) { | |
173 // Enter a try-block while executing the JavaScript code. To avoid | 166 // Enter a try-block while executing the JavaScript code. To avoid |
174 // duplicate error printing it must be non-verbose. Also, to avoid | 167 // duplicate error printing it must be non-verbose. Also, to avoid |
175 // creating message objects during stack overflow we shouldn't | 168 // creating message objects during stack overflow we shouldn't |
176 // capture messages. | 169 // capture messages. |
177 v8::TryCatch catcher; | 170 v8::TryCatch catcher; |
178 catcher.SetVerbose(false); | 171 catcher.SetVerbose(false); |
179 catcher.SetCaptureMessage(false); | 172 catcher.SetCaptureMessage(false); |
180 *caught_exception = false; | |
181 | 173 |
182 // Get isolate now, because handle might be persistent | 174 // Get isolate now, because handle might be persistent |
183 // and get destroyed in the next call. | 175 // and get destroyed in the next call. |
184 Isolate* isolate = func->GetIsolate(); | 176 Isolate* isolate = func->GetIsolate(); |
185 Handle<Object> result = Invoke(false, func, receiver, argc, args, | 177 MaybeHandle<Object> result = Invoke(false, func, receiver, argc, args); |
186 caught_exception); | |
187 | 178 |
188 if (*caught_exception) { | 179 if (result.is_null()) { |
189 ASSERT(catcher.HasCaught()); | 180 ASSERT(catcher.HasCaught()); |
190 ASSERT(isolate->has_pending_exception()); | 181 ASSERT(isolate->has_pending_exception()); |
191 ASSERT(isolate->external_caught_exception()); | 182 ASSERT(isolate->external_caught_exception()); |
192 if (isolate->pending_exception() == | 183 if (isolate->pending_exception() == |
193 isolate->heap()->termination_exception()) { | 184 isolate->heap()->termination_exception()) { |
194 result = isolate->factory()->termination_exception(); | 185 result = isolate->factory()->termination_exception(); |
195 } else { | 186 } else { |
196 result = v8::Utils::OpenHandle(*catcher.Exception()); | 187 result = v8::Utils::OpenHandle(*catcher.Exception()); |
Igor Sheludko
2014/04/10 15:14:42
TryCall() returns either result or exception and n
| |
197 } | 188 } |
198 isolate->OptionalRescheduleException(true); | 189 isolate->OptionalRescheduleException(true); |
199 } | 190 } |
200 | 191 |
201 ASSERT(!isolate->has_pending_exception()); | 192 ASSERT(!isolate->has_pending_exception()); |
202 ASSERT(!isolate->external_caught_exception()); | 193 ASSERT(!isolate->external_caught_exception()); |
203 return result; | 194 return result; |
204 } | 195 } |
205 | 196 |
206 | 197 |
(...skipping 17 matching lines...) Expand all Loading... | |
224 if (fun->IsHeapObject() && | 215 if (fun->IsHeapObject() && |
225 HeapObject::cast(fun)->map()->has_instance_call_handler()) { | 216 HeapObject::cast(fun)->map()->has_instance_call_handler()) { |
226 return Handle<JSFunction>( | 217 return Handle<JSFunction>( |
227 isolate->native_context()->call_as_function_delegate()); | 218 isolate->native_context()->call_as_function_delegate()); |
228 } | 219 } |
229 | 220 |
230 return factory->undefined_value(); | 221 return factory->undefined_value(); |
231 } | 222 } |
232 | 223 |
233 | 224 |
234 Handle<Object> Execution::TryGetFunctionDelegate(Isolate* isolate, | 225 MaybeHandle<Object> Execution::TryGetFunctionDelegate(Isolate* isolate, |
235 Handle<Object> object, | 226 Handle<Object> object) { |
236 bool* has_pending_exception) { | |
237 ASSERT(!object->IsJSFunction()); | 227 ASSERT(!object->IsJSFunction()); |
238 | 228 |
239 // If object is a function proxy, get its handler. Iterate if necessary. | 229 // If object is a function proxy, get its handler. Iterate if necessary. |
240 Object* fun = *object; | 230 Object* fun = *object; |
241 while (fun->IsJSFunctionProxy()) { | 231 while (fun->IsJSFunctionProxy()) { |
242 fun = JSFunctionProxy::cast(fun)->call_trap(); | 232 fun = JSFunctionProxy::cast(fun)->call_trap(); |
243 } | 233 } |
244 if (fun->IsJSFunction()) return Handle<Object>(fun, isolate); | 234 if (fun->IsJSFunction()) return Handle<Object>(fun, isolate); |
245 | 235 |
246 // Objects created through the API can have an instance-call handler | 236 // Objects created through the API can have an instance-call handler |
247 // that should be used when calling the object as a function. | 237 // that should be used when calling the object as a function. |
248 if (fun->IsHeapObject() && | 238 if (fun->IsHeapObject() && |
249 HeapObject::cast(fun)->map()->has_instance_call_handler()) { | 239 HeapObject::cast(fun)->map()->has_instance_call_handler()) { |
250 return Handle<JSFunction>( | 240 return Handle<JSFunction>( |
251 isolate->native_context()->call_as_function_delegate()); | 241 isolate->native_context()->call_as_function_delegate()); |
252 } | 242 } |
253 | 243 |
254 // If the Object doesn't have an instance-call handler we should | 244 // If the Object doesn't have an instance-call handler we should |
255 // throw a non-callable exception. | 245 // throw a non-callable exception. |
256 i::Handle<i::Object> error_obj = isolate->factory()->NewTypeError( | 246 i::Handle<i::Object> error_obj = isolate->factory()->NewTypeError( |
257 "called_non_callable", i::HandleVector<i::Object>(&object, 1)); | 247 "called_non_callable", i::HandleVector<i::Object>(&object, 1)); |
258 isolate->Throw(*error_obj); | |
259 *has_pending_exception = true; | |
260 | 248 |
261 return isolate->factory()->undefined_value(); | 249 return isolate->Throw<Object>(error_obj); |
262 } | 250 } |
263 | 251 |
264 | 252 |
265 Handle<Object> Execution::GetConstructorDelegate(Isolate* isolate, | 253 Handle<Object> Execution::GetConstructorDelegate(Isolate* isolate, |
266 Handle<Object> object) { | 254 Handle<Object> object) { |
267 ASSERT(!object->IsJSFunction()); | 255 ASSERT(!object->IsJSFunction()); |
268 | 256 |
269 // If you return a function from here, it will be called when an | 257 // 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. | 258 // attempt is made to call the given object as a constructor. |
271 | 259 |
272 // If object is a function proxies, get its handler. Iterate if necessary. | 260 // If object is a function proxies, get its handler. Iterate if necessary. |
273 Object* fun = *object; | 261 Object* fun = *object; |
274 while (fun->IsJSFunctionProxy()) { | 262 while (fun->IsJSFunctionProxy()) { |
275 fun = JSFunctionProxy::cast(fun)->call_trap(); | 263 fun = JSFunctionProxy::cast(fun)->call_trap(); |
276 } | 264 } |
277 if (fun->IsJSFunction()) return Handle<Object>(fun, isolate); | 265 if (fun->IsJSFunction()) return Handle<Object>(fun, isolate); |
278 | 266 |
279 // Objects created through the API can have an instance-call handler | 267 // Objects created through the API can have an instance-call handler |
280 // that should be used when calling the object as a function. | 268 // that should be used when calling the object as a function. |
281 if (fun->IsHeapObject() && | 269 if (fun->IsHeapObject() && |
282 HeapObject::cast(fun)->map()->has_instance_call_handler()) { | 270 HeapObject::cast(fun)->map()->has_instance_call_handler()) { |
283 return Handle<JSFunction>( | 271 return Handle<JSFunction>( |
284 isolate->native_context()->call_as_constructor_delegate()); | 272 isolate->native_context()->call_as_constructor_delegate()); |
285 } | 273 } |
286 | 274 |
287 return isolate->factory()->undefined_value(); | 275 return isolate->factory()->undefined_value(); |
288 } | 276 } |
289 | 277 |
290 | 278 |
291 Handle<Object> Execution::TryGetConstructorDelegate( | 279 MaybeHandle<Object> Execution::TryGetConstructorDelegate( |
292 Isolate* isolate, | 280 Isolate* isolate, Handle<Object> object) { |
293 Handle<Object> object, | |
294 bool* has_pending_exception) { | |
295 ASSERT(!object->IsJSFunction()); | 281 ASSERT(!object->IsJSFunction()); |
296 | 282 |
297 // If you return a function from here, it will be called when an | 283 // 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. | 284 // attempt is made to call the given object as a constructor. |
299 | 285 |
300 // If object is a function proxies, get its handler. Iterate if necessary. | 286 // If object is a function proxies, get its handler. Iterate if necessary. |
301 Object* fun = *object; | 287 Object* fun = *object; |
302 while (fun->IsJSFunctionProxy()) { | 288 while (fun->IsJSFunctionProxy()) { |
303 fun = JSFunctionProxy::cast(fun)->call_trap(); | 289 fun = JSFunctionProxy::cast(fun)->call_trap(); |
304 } | 290 } |
305 if (fun->IsJSFunction()) return Handle<Object>(fun, isolate); | 291 if (fun->IsJSFunction()) return Handle<Object>(fun, isolate); |
306 | 292 |
307 // Objects created through the API can have an instance-call handler | 293 // Objects created through the API can have an instance-call handler |
308 // that should be used when calling the object as a function. | 294 // that should be used when calling the object as a function. |
309 if (fun->IsHeapObject() && | 295 if (fun->IsHeapObject() && |
310 HeapObject::cast(fun)->map()->has_instance_call_handler()) { | 296 HeapObject::cast(fun)->map()->has_instance_call_handler()) { |
311 return Handle<JSFunction>( | 297 return Handle<JSFunction>( |
312 isolate->native_context()->call_as_constructor_delegate()); | 298 isolate->native_context()->call_as_constructor_delegate()); |
313 } | 299 } |
314 | 300 |
315 // If the Object doesn't have an instance-call handler we should | 301 // If the Object doesn't have an instance-call handler we should |
316 // throw a non-callable exception. | 302 // throw a non-callable exception. |
317 i::Handle<i::Object> error_obj = isolate->factory()->NewTypeError( | 303 i::Handle<i::Object> error_obj = isolate->factory()->NewTypeError( |
318 "called_non_callable", i::HandleVector<i::Object>(&object, 1)); | 304 "called_non_callable", i::HandleVector<i::Object>(&object, 1)); |
319 isolate->Throw(*error_obj); | 305 return isolate->Throw<Object>(error_obj); |
320 *has_pending_exception = true; | |
321 | |
322 return isolate->factory()->undefined_value(); | |
323 } | 306 } |
324 | 307 |
325 | 308 |
326 void Execution::RunMicrotasks(Isolate* isolate) { | 309 void Execution::RunMicrotasks(Isolate* isolate) { |
327 ASSERT(isolate->microtask_pending()); | 310 ASSERT(isolate->microtask_pending()); |
328 bool threw = false; | |
329 Execution::Call( | 311 Execution::Call( |
330 isolate, | 312 isolate, |
331 isolate->run_microtasks(), | 313 isolate->run_microtasks(), |
332 isolate->factory()->undefined_value(), | 314 isolate->factory()->undefined_value(), |
333 0, | 315 0, |
334 NULL, | 316 NULL).Assert(); |
335 &threw); | |
336 ASSERT(!threw); | |
337 } | 317 } |
338 | 318 |
339 | 319 |
340 void Execution::EnqueueMicrotask(Isolate* isolate, Handle<Object> microtask) { | 320 void Execution::EnqueueMicrotask(Isolate* isolate, Handle<Object> microtask) { |
341 bool threw = false; | |
342 Handle<Object> args[] = { microtask }; | 321 Handle<Object> args[] = { microtask }; |
343 Execution::Call( | 322 Execution::Call( |
344 isolate, | 323 isolate, |
345 isolate->enqueue_external_microtask(), | 324 isolate->enqueue_external_microtask(), |
346 isolate->factory()->undefined_value(), | 325 isolate->factory()->undefined_value(), |
347 1, | 326 1, |
348 args, | 327 args).Assert(); |
349 &threw); | |
350 ASSERT(!threw); | |
351 } | 328 } |
352 | 329 |
353 | 330 |
354 bool StackGuard::IsStackOverflow() { | 331 bool StackGuard::IsStackOverflow() { |
355 ExecutionAccess access(isolate_); | 332 ExecutionAccess access(isolate_); |
356 return (thread_local_.jslimit_ != kInterruptLimit && | 333 return (thread_local_.jslimit_ != kInterruptLimit && |
357 thread_local_.climit_ != kInterruptLimit); | 334 thread_local_.climit_ != kInterruptLimit); |
358 } | 335 } |
359 | 336 |
360 | 337 |
(...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
658 uintptr_t stored_limit = per_thread->stack_limit(); | 635 uintptr_t stored_limit = per_thread->stack_limit(); |
659 // You should hold the ExecutionAccess lock when you call this. | 636 // You should hold the ExecutionAccess lock when you call this. |
660 if (stored_limit != 0) { | 637 if (stored_limit != 0) { |
661 SetStackLimit(stored_limit); | 638 SetStackLimit(stored_limit); |
662 } | 639 } |
663 } | 640 } |
664 | 641 |
665 | 642 |
666 // --- C a l l s t o n a t i v e s --- | 643 // --- C a l l s t o n a t i v e s --- |
667 | 644 |
668 #define RETURN_NATIVE_CALL(name, args, has_pending_exception) \ | 645 #define RETURN_NATIVE_CALL(name, args) \ |
669 do { \ | 646 do { \ |
670 Handle<Object> argv[] = args; \ | 647 Handle<Object> argv[] = args; \ |
671 ASSERT(has_pending_exception != NULL); \ | |
672 return Call(isolate, \ | 648 return Call(isolate, \ |
673 isolate->name##_fun(), \ | 649 isolate->name##_fun(), \ |
674 isolate->js_builtins_object(), \ | 650 isolate->js_builtins_object(), \ |
675 ARRAY_SIZE(argv), argv, \ | 651 ARRAY_SIZE(argv), argv); \ |
676 has_pending_exception); \ | |
677 } while (false) | 652 } while (false) |
678 | 653 |
679 | 654 |
680 Handle<Object> Execution::ToNumber( | 655 MaybeHandle<Object> Execution::ToNumber( |
681 Isolate* isolate, Handle<Object> obj, bool* exc) { | 656 Isolate* isolate, Handle<Object> obj) { |
682 RETURN_NATIVE_CALL(to_number, { obj }, exc); | 657 RETURN_NATIVE_CALL(to_number, { obj }); |
683 } | 658 } |
684 | 659 |
685 | 660 |
686 Handle<Object> Execution::ToString( | 661 MaybeHandle<Object> Execution::ToString( |
687 Isolate* isolate, Handle<Object> obj, bool* exc) { | 662 Isolate* isolate, Handle<Object> obj) { |
688 RETURN_NATIVE_CALL(to_string, { obj }, exc); | 663 RETURN_NATIVE_CALL(to_string, { obj }); |
689 } | 664 } |
690 | 665 |
691 | 666 |
692 Handle<Object> Execution::ToDetailString( | 667 MaybeHandle<Object> Execution::ToDetailString( |
693 Isolate* isolate, Handle<Object> obj, bool* exc) { | 668 Isolate* isolate, Handle<Object> obj) { |
694 RETURN_NATIVE_CALL(to_detail_string, { obj }, exc); | 669 RETURN_NATIVE_CALL(to_detail_string, { obj }); |
695 } | 670 } |
696 | 671 |
697 | 672 |
698 Handle<Object> Execution::ToObject( | 673 MaybeHandle<Object> Execution::ToObject( |
699 Isolate* isolate, Handle<Object> obj, bool* exc) { | 674 Isolate* isolate, Handle<Object> obj) { |
700 if (obj->IsSpecObject()) return obj; | 675 if (obj->IsSpecObject()) return obj; |
701 RETURN_NATIVE_CALL(to_object, { obj }, exc); | 676 RETURN_NATIVE_CALL(to_object, { obj }); |
702 } | 677 } |
703 | 678 |
704 | 679 |
705 Handle<Object> Execution::ToInteger( | 680 MaybeHandle<Object> Execution::ToInteger( |
706 Isolate* isolate, Handle<Object> obj, bool* exc) { | 681 Isolate* isolate, Handle<Object> obj) { |
707 RETURN_NATIVE_CALL(to_integer, { obj }, exc); | 682 RETURN_NATIVE_CALL(to_integer, { obj }); |
708 } | 683 } |
709 | 684 |
710 | 685 |
711 Handle<Object> Execution::ToUint32( | 686 MaybeHandle<Object> Execution::ToUint32( |
712 Isolate* isolate, Handle<Object> obj, bool* exc) { | 687 Isolate* isolate, Handle<Object> obj) { |
713 RETURN_NATIVE_CALL(to_uint32, { obj }, exc); | 688 RETURN_NATIVE_CALL(to_uint32, { obj }); |
714 } | 689 } |
715 | 690 |
716 | 691 |
717 Handle<Object> Execution::ToInt32( | 692 MaybeHandle<Object> Execution::ToInt32( |
718 Isolate* isolate, Handle<Object> obj, bool* exc) { | 693 Isolate* isolate, Handle<Object> obj) { |
719 RETURN_NATIVE_CALL(to_int32, { obj }, exc); | 694 RETURN_NATIVE_CALL(to_int32, { obj }); |
720 } | 695 } |
721 | 696 |
722 | 697 |
723 Handle<Object> Execution::NewDate(Isolate* isolate, double time, bool* exc) { | 698 MaybeHandle<Object> Execution::NewDate(Isolate* isolate, double time) { |
724 Handle<Object> time_obj = isolate->factory()->NewNumber(time); | 699 Handle<Object> time_obj = isolate->factory()->NewNumber(time); |
725 RETURN_NATIVE_CALL(create_date, { time_obj }, exc); | 700 RETURN_NATIVE_CALL(create_date, { time_obj }); |
726 } | 701 } |
727 | 702 |
728 | 703 |
729 #undef RETURN_NATIVE_CALL | 704 #undef RETURN_NATIVE_CALL |
730 | 705 |
731 | 706 |
732 Handle<JSRegExp> Execution::NewJSRegExp(Handle<String> pattern, | 707 MaybeHandle<JSRegExp> Execution::NewJSRegExp(Handle<String> pattern, |
733 Handle<String> flags, | 708 Handle<String> flags) { |
734 bool* exc) { | 709 Isolate* isolate = pattern->GetIsolate(); |
735 Handle<JSFunction> function = Handle<JSFunction>( | 710 Handle<JSFunction> function = Handle<JSFunction>( |
736 pattern->GetIsolate()->native_context()->regexp_function()); | 711 isolate->native_context()->regexp_function()); |
737 Handle<Object> re_obj = RegExpImpl::CreateRegExpLiteral( | 712 Handle<Object> re_obj; |
738 function, pattern, flags, exc); | 713 ASSIGN_RETURN_ON_EXCEPTION( |
739 if (*exc) return Handle<JSRegExp>(); | 714 isolate, re_obj, |
715 RegExpImpl::CreateRegExpLiteral(function, pattern, flags), | |
716 JSRegExp); | |
740 return Handle<JSRegExp>::cast(re_obj); | 717 return Handle<JSRegExp>::cast(re_obj); |
741 } | 718 } |
742 | 719 |
743 | 720 |
744 Handle<Object> Execution::CharAt(Handle<String> string, uint32_t index) { | 721 Handle<Object> Execution::CharAt(Handle<String> string, uint32_t index) { |
745 Isolate* isolate = string->GetIsolate(); | 722 Isolate* isolate = string->GetIsolate(); |
746 Factory* factory = isolate->factory(); | 723 Factory* factory = isolate->factory(); |
747 | 724 |
748 int int_index = static_cast<int>(index); | 725 int int_index = static_cast<int>(index); |
749 if (int_index < 0 || int_index >= string->length()) { | 726 if (int_index < 0 || int_index >= string->length()) { |
750 return factory->undefined_value(); | 727 return factory->undefined_value(); |
751 } | 728 } |
752 | 729 |
753 Handle<Object> char_at = Object::GetProperty( | 730 Handle<Object> char_at = Object::GetProperty( |
754 isolate->js_builtins_object(), factory->char_at_string()); | 731 isolate->js_builtins_object(), factory->char_at_string()); |
755 if (!char_at->IsJSFunction()) { | 732 if (!char_at->IsJSFunction()) { |
756 return factory->undefined_value(); | 733 return factory->undefined_value(); |
757 } | 734 } |
758 | 735 |
759 bool caught_exception; | 736 bool caught_exception; |
760 Handle<Object> index_object = factory->NewNumberFromInt(int_index); | 737 Handle<Object> index_object = factory->NewNumberFromInt(int_index); |
761 Handle<Object> index_arg[] = { index_object }; | 738 Handle<Object> index_arg[] = { index_object }; |
762 Handle<Object> result = TryCall(Handle<JSFunction>::cast(char_at), | 739 Handle<Object> result; |
763 string, | 740 caught_exception = !TryCall(Handle<JSFunction>::cast(char_at), |
764 ARRAY_SIZE(index_arg), | 741 string, |
765 index_arg, | 742 ARRAY_SIZE(index_arg), |
766 &caught_exception); | 743 index_arg).ToHandle(&result); |
767 if (caught_exception) { | 744 if (caught_exception) { |
768 return factory->undefined_value(); | 745 return factory->undefined_value(); |
769 } | 746 } |
770 return result; | 747 return result; |
771 } | 748 } |
772 | 749 |
773 | 750 |
774 Handle<JSFunction> Execution::InstantiateFunction( | 751 MaybeHandle<JSFunction> Execution::InstantiateFunction( |
775 Handle<FunctionTemplateInfo> data, | 752 Handle<FunctionTemplateInfo> data) { |
776 bool* exc) { | |
777 Isolate* isolate = data->GetIsolate(); | 753 Isolate* isolate = data->GetIsolate(); |
778 if (!data->do_not_cache()) { | 754 if (!data->do_not_cache()) { |
779 // Fast case: see if the function has already been instantiated | 755 // Fast case: see if the function has already been instantiated |
780 int serial_number = Smi::cast(data->serial_number())->value(); | 756 int serial_number = Smi::cast(data->serial_number())->value(); |
781 Handle<JSObject> cache(isolate->native_context()->function_cache()); | 757 Handle<JSObject> cache(isolate->native_context()->function_cache()); |
782 Handle<Object> elm = | 758 Handle<Object> elm = |
783 Object::GetElementNoExceptionThrown(isolate, cache, serial_number); | 759 Object::GetElementNoExceptionThrown(isolate, cache, serial_number); |
784 if (elm->IsJSFunction()) return Handle<JSFunction>::cast(elm); | 760 if (elm->IsJSFunction()) return Handle<JSFunction>::cast(elm); |
785 } | 761 } |
786 // The function has not yet been instantiated in this context; do it. | 762 // The function has not yet been instantiated in this context; do it. |
787 Handle<Object> args[] = { data }; | 763 Handle<Object> args[] = { data }; |
788 Handle<Object> result = Call(isolate, | 764 Handle<Object> result; |
789 isolate->instantiate_fun(), | 765 ASSIGN_RETURN_ON_EXCEPTION( |
790 isolate->js_builtins_object(), | 766 isolate, result, |
791 ARRAY_SIZE(args), | 767 Call(isolate, |
792 args, | 768 isolate->instantiate_fun(), |
793 exc); | 769 isolate->js_builtins_object(), |
794 if (*exc) return Handle<JSFunction>::null(); | 770 ARRAY_SIZE(args), |
771 args), | |
772 JSFunction); | |
795 return Handle<JSFunction>::cast(result); | 773 return Handle<JSFunction>::cast(result); |
796 } | 774 } |
797 | 775 |
798 | 776 |
799 Handle<JSObject> Execution::InstantiateObject(Handle<ObjectTemplateInfo> data, | 777 MaybeHandle<JSObject> Execution::InstantiateObject( |
800 bool* exc) { | 778 Handle<ObjectTemplateInfo> data) { |
801 Isolate* isolate = data->GetIsolate(); | 779 Isolate* isolate = data->GetIsolate(); |
780 Handle<Object> result; | |
802 if (data->property_list()->IsUndefined() && | 781 if (data->property_list()->IsUndefined() && |
803 !data->constructor()->IsUndefined()) { | 782 !data->constructor()->IsUndefined()) { |
804 // Initialization to make gcc happy. | 783 Handle<FunctionTemplateInfo> cons_template = |
805 Object* result = NULL; | 784 Handle<FunctionTemplateInfo>( |
806 { | 785 FunctionTemplateInfo::cast(data->constructor())); |
807 HandleScope scope(isolate); | 786 Handle<JSFunction> cons; |
808 Handle<FunctionTemplateInfo> cons_template = | 787 ASSIGN_RETURN_ON_EXCEPTION( |
809 Handle<FunctionTemplateInfo>( | 788 isolate, cons, InstantiateFunction(cons_template), JSObject); |
810 FunctionTemplateInfo::cast(data->constructor())); | 789 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 { | 790 } else { |
820 Handle<Object> args[] = { data }; | 791 Handle<Object> args[] = { data }; |
821 Handle<Object> result = Call(isolate, | 792 ASSIGN_RETURN_ON_EXCEPTION( |
822 isolate->instantiate_fun(), | 793 isolate, result, |
823 isolate->js_builtins_object(), | 794 Call(isolate, |
824 ARRAY_SIZE(args), | 795 isolate->instantiate_fun(), |
825 args, | 796 isolate->js_builtins_object(), |
826 exc); | 797 ARRAY_SIZE(args), |
827 if (*exc) return Handle<JSObject>::null(); | 798 args), |
828 return Handle<JSObject>::cast(result); | 799 JSObject); |
829 } | 800 } |
801 return Handle<JSObject>::cast(result); | |
830 } | 802 } |
831 | 803 |
832 | 804 |
833 void Execution::ConfigureInstance(Isolate* isolate, | 805 MaybeHandle<Object> Execution::ConfigureInstance( |
834 Handle<Object> instance, | 806 Isolate* isolate, |
835 Handle<Object> instance_template, | 807 Handle<Object> instance, |
836 bool* exc) { | 808 Handle<Object> instance_template) { |
837 Handle<Object> args[] = { instance, instance_template }; | 809 Handle<Object> args[] = { instance, instance_template }; |
838 Execution::Call(isolate, | 810 return Execution::Call(isolate, |
839 isolate->configure_instance_fun(), | 811 isolate->configure_instance_fun(), |
840 isolate->js_builtins_object(), | 812 isolate->js_builtins_object(), |
841 ARRAY_SIZE(args), | 813 ARRAY_SIZE(args), |
842 args, | 814 args); |
843 exc); | |
844 } | 815 } |
845 | 816 |
846 | 817 |
847 Handle<String> Execution::GetStackTraceLine(Handle<Object> recv, | 818 Handle<String> Execution::GetStackTraceLine(Handle<Object> recv, |
848 Handle<JSFunction> fun, | 819 Handle<JSFunction> fun, |
849 Handle<Object> pos, | 820 Handle<Object> pos, |
850 Handle<Object> is_global) { | 821 Handle<Object> is_global) { |
851 Isolate* isolate = fun->GetIsolate(); | 822 Isolate* isolate = fun->GetIsolate(); |
852 Handle<Object> args[] = { recv, fun, pos, is_global }; | 823 Handle<Object> args[] = { recv, fun, pos, is_global }; |
853 bool caught_exception; | 824 Handle<Object> result; |
854 Handle<Object> result = TryCall(isolate->get_stack_trace_line_fun(), | 825 bool caught_exception = !TryCall(isolate->get_stack_trace_line_fun(), |
855 isolate->js_builtins_object(), | 826 isolate->js_builtins_object(), |
856 ARRAY_SIZE(args), | 827 ARRAY_SIZE(args), |
857 args, | 828 args).ToHandle(&result); |
858 &caught_exception); | |
859 if (caught_exception || !result->IsString()) { | 829 if (caught_exception || !result->IsString()) { |
860 return isolate->factory()->empty_string(); | 830 return isolate->factory()->empty_string(); |
861 } | 831 } |
862 | 832 |
863 return Handle<String>::cast(result); | 833 return Handle<String>::cast(result); |
864 } | 834 } |
865 | 835 |
866 | 836 |
867 static Object* RuntimePreempt(Isolate* isolate) { | 837 static Object* RuntimePreempt(Isolate* isolate) { |
868 // Clear the preempt request flag. | 838 // Clear the preempt request flag. |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1012 if (stack_guard->IsInstallCodeRequest()) { | 982 if (stack_guard->IsInstallCodeRequest()) { |
1013 ASSERT(isolate->concurrent_recompilation_enabled()); | 983 ASSERT(isolate->concurrent_recompilation_enabled()); |
1014 stack_guard->Continue(INSTALL_CODE); | 984 stack_guard->Continue(INSTALL_CODE); |
1015 isolate->optimizing_compiler_thread()->InstallOptimizedFunctions(); | 985 isolate->optimizing_compiler_thread()->InstallOptimizedFunctions(); |
1016 } | 986 } |
1017 isolate->runtime_profiler()->OptimizeNow(); | 987 isolate->runtime_profiler()->OptimizeNow(); |
1018 return isolate->heap()->undefined_value(); | 988 return isolate->heap()->undefined_value(); |
1019 } | 989 } |
1020 | 990 |
1021 } } // namespace v8::internal | 991 } } // namespace v8::internal |
OLD | NEW |