| 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 |