Chromium Code Reviews| 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 |