OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
99 } | 99 } |
100 | 100 |
101 // Make sure that the global object of the context we're about to | 101 // Make sure that the global object of the context we're about to |
102 // make the current one is indeed a global object. | 102 // make the current one is indeed a global object. |
103 ASSERT(function->context()->global_object()->IsGlobalObject()); | 103 ASSERT(function->context()->global_object()->IsGlobalObject()); |
104 | 104 |
105 { | 105 { |
106 // Save and restore context around invocation and block the | 106 // Save and restore context around invocation and block the |
107 // allocation of handles without explicit handle scopes. | 107 // allocation of handles without explicit handle scopes. |
108 SaveContext save(isolate); | 108 SaveContext save(isolate); |
109 NoHandleAllocation na; | 109 NoHandleAllocation na(isolate); |
110 JSEntryFunction stub_entry = FUNCTION_CAST<JSEntryFunction>(code->entry()); | 110 JSEntryFunction stub_entry = FUNCTION_CAST<JSEntryFunction>(code->entry()); |
111 | 111 |
112 // Call the function through the right JS entry stub. | 112 // Call the function through the right JS entry stub. |
113 byte* function_entry = function->code()->entry(); | 113 byte* function_entry = function->code()->entry(); |
114 JSFunction* func = *function; | 114 JSFunction* func = *function; |
115 Object* recv = *receiver; | 115 Object* recv = *receiver; |
116 Object*** argv = reinterpret_cast<Object***>(args); | 116 Object*** argv = reinterpret_cast<Object***>(args); |
117 value = | 117 value = |
118 CALL_GENERATED_CODE(stub_entry, function_entry, func, recv, argc, argv); | 118 CALL_GENERATED_CODE(stub_entry, function_entry, func, recv, argc, argv); |
119 } | 119 } |
120 | 120 |
121 #ifdef VERIFY_HEAP | 121 #ifdef VERIFY_HEAP |
122 value->Verify(); | 122 value->Verify(); |
123 #endif | 123 #endif |
124 | 124 |
125 // Update the pending exception flag and return the value. | 125 // Update the pending exception flag and return the value. |
126 *has_pending_exception = value->IsException(); | 126 *has_pending_exception = value->IsException(); |
127 ASSERT(*has_pending_exception == Isolate::Current()->has_pending_exception()); | 127 ASSERT(*has_pending_exception == isolate->has_pending_exception()); |
128 if (*has_pending_exception) { | 128 if (*has_pending_exception) { |
129 isolate->ReportPendingMessages(); | 129 isolate->ReportPendingMessages(); |
130 if (isolate->pending_exception()->IsOutOfMemory()) { | 130 if (isolate->pending_exception()->IsOutOfMemory()) { |
131 if (!isolate->ignore_out_of_memory()) { | 131 if (!isolate->ignore_out_of_memory()) { |
132 V8::FatalProcessOutOfMemory("JS", true); | 132 V8::FatalProcessOutOfMemory("JS", true); |
133 } | 133 } |
134 } | 134 } |
135 #ifdef ENABLE_DEBUGGER_SUPPORT | 135 #ifdef ENABLE_DEBUGGER_SUPPORT |
136 // Reset stepping state when script exits with uncaught exception. | 136 // Reset stepping state when script exits with uncaught exception. |
137 if (isolate->debugger()->IsDebuggerActive()) { | 137 if (isolate->debugger()->IsDebuggerActive()) { |
(...skipping 24 matching lines...) Expand all Loading... |
162 Handle<JSFunction> func = Handle<JSFunction>::cast(callable); | 162 Handle<JSFunction> func = Handle<JSFunction>::cast(callable); |
163 | 163 |
164 // In non-strict mode, convert receiver. | 164 // In non-strict mode, convert receiver. |
165 if (convert_receiver && !receiver->IsJSReceiver() && | 165 if (convert_receiver && !receiver->IsJSReceiver() && |
166 !func->shared()->native() && func->shared()->is_classic_mode()) { | 166 !func->shared()->native() && func->shared()->is_classic_mode()) { |
167 if (receiver->IsUndefined() || receiver->IsNull()) { | 167 if (receiver->IsUndefined() || receiver->IsNull()) { |
168 Object* global = func->context()->global_object()->global_receiver(); | 168 Object* global = func->context()->global_object()->global_receiver(); |
169 // Under some circumstances, 'global' can be the JSBuiltinsObject | 169 // Under some circumstances, 'global' can be the JSBuiltinsObject |
170 // In that case, don't rewrite. (FWIW, the same holds for | 170 // In that case, don't rewrite. (FWIW, the same holds for |
171 // GetIsolate()->global_object()->global_receiver().) | 171 // GetIsolate()->global_object()->global_receiver().) |
172 if (!global->IsJSBuiltinsObject()) receiver = Handle<Object>(global); | 172 if (!global->IsJSBuiltinsObject()) { |
| 173 receiver = Handle<Object>(global, func->GetIsolate()); |
| 174 } |
173 } else { | 175 } else { |
174 receiver = ToObject(receiver, pending_exception); | 176 receiver = ToObject(receiver, pending_exception); |
175 } | 177 } |
176 if (*pending_exception) return callable; | 178 if (*pending_exception) return callable; |
177 } | 179 } |
178 | 180 |
179 return Invoke(false, func, receiver, argc, argv, pending_exception); | 181 return Invoke(false, func, receiver, argc, argv, pending_exception); |
180 } | 182 } |
181 | 183 |
182 | 184 |
183 Handle<Object> Execution::New(Handle<JSFunction> func, | 185 Handle<Object> Execution::New(Handle<JSFunction> func, |
184 int argc, | 186 int argc, |
185 Handle<Object> argv[], | 187 Handle<Object> argv[], |
186 bool* pending_exception) { | 188 bool* pending_exception) { |
187 return Invoke(true, func, Isolate::Current()->global_object(), argc, argv, | 189 return Invoke(true, func, func->GetIsolate()->global_object(), argc, argv, |
188 pending_exception); | 190 pending_exception); |
189 } | 191 } |
190 | 192 |
191 | 193 |
192 Handle<Object> Execution::TryCall(Handle<JSFunction> func, | 194 Handle<Object> Execution::TryCall(Handle<JSFunction> func, |
193 Handle<Object> receiver, | 195 Handle<Object> receiver, |
194 int argc, | 196 int argc, |
195 Handle<Object> args[], | 197 Handle<Object> args[], |
196 bool* caught_exception) { | 198 bool* caught_exception) { |
197 // Enter a try-block while executing the JavaScript code. To avoid | 199 // Enter a try-block while executing the JavaScript code. To avoid |
198 // duplicate error printing it must be non-verbose. Also, to avoid | 200 // duplicate error printing it must be non-verbose. Also, to avoid |
199 // creating message objects during stack overflow we shouldn't | 201 // creating message objects during stack overflow we shouldn't |
200 // capture messages. | 202 // capture messages. |
201 v8::TryCatch catcher; | 203 v8::TryCatch catcher; |
202 catcher.SetVerbose(false); | 204 catcher.SetVerbose(false); |
203 catcher.SetCaptureMessage(false); | 205 catcher.SetCaptureMessage(false); |
204 *caught_exception = false; | 206 *caught_exception = false; |
205 | 207 |
206 Handle<Object> result = Invoke(false, func, receiver, argc, args, | 208 Handle<Object> result = Invoke(false, func, receiver, argc, args, |
207 caught_exception); | 209 caught_exception); |
208 | 210 |
| 211 Isolate* isolate = func->GetIsolate(); |
209 if (*caught_exception) { | 212 if (*caught_exception) { |
210 ASSERT(catcher.HasCaught()); | 213 ASSERT(catcher.HasCaught()); |
211 Isolate* isolate = Isolate::Current(); | |
212 ASSERT(isolate->has_pending_exception()); | 214 ASSERT(isolate->has_pending_exception()); |
213 ASSERT(isolate->external_caught_exception()); | 215 ASSERT(isolate->external_caught_exception()); |
214 if (isolate->is_out_of_memory() && !isolate->ignore_out_of_memory()) { | 216 if (isolate->is_out_of_memory() && !isolate->ignore_out_of_memory()) { |
215 V8::FatalProcessOutOfMemory("OOM during Execution::TryCall"); | 217 V8::FatalProcessOutOfMemory("OOM during Execution::TryCall"); |
216 } | 218 } |
217 if (isolate->pending_exception() == | 219 if (isolate->pending_exception() == |
218 isolate->heap()->termination_exception()) { | 220 isolate->heap()->termination_exception()) { |
219 result = isolate->factory()->termination_exception(); | 221 result = isolate->factory()->termination_exception(); |
220 } else { | 222 } else { |
221 result = v8::Utils::OpenHandle(*catcher.Exception()); | 223 result = v8::Utils::OpenHandle(*catcher.Exception()); |
222 } | 224 } |
223 isolate->OptionalRescheduleException(true); | 225 isolate->OptionalRescheduleException(true); |
224 } | 226 } |
225 | 227 |
226 ASSERT(!Isolate::Current()->has_pending_exception()); | 228 ASSERT(!isolate->has_pending_exception()); |
227 ASSERT(!Isolate::Current()->external_caught_exception()); | 229 ASSERT(!isolate->external_caught_exception()); |
228 return result; | 230 return result; |
229 } | 231 } |
230 | 232 |
231 | 233 |
232 Handle<Object> Execution::GetFunctionDelegate(Handle<Object> object) { | 234 Handle<Object> Execution::GetFunctionDelegate(Handle<Object> object) { |
233 ASSERT(!object->IsJSFunction()); | 235 ASSERT(!object->IsJSFunction()); |
234 Isolate* isolate = Isolate::Current(); | 236 Isolate* isolate = Isolate::Current(); |
235 Factory* factory = isolate->factory(); | 237 Factory* factory = isolate->factory(); |
236 | 238 |
237 // If you return a function from here, it will be called when an | 239 // If you return a function from here, it will be called when an |
238 // attempt is made to call the given object as a function. | 240 // attempt is made to call the given object as a function. |
239 | 241 |
240 // If object is a function proxy, get its handler. Iterate if necessary. | 242 // If object is a function proxy, get its handler. Iterate if necessary. |
241 Object* fun = *object; | 243 Object* fun = *object; |
242 while (fun->IsJSFunctionProxy()) { | 244 while (fun->IsJSFunctionProxy()) { |
243 fun = JSFunctionProxy::cast(fun)->call_trap(); | 245 fun = JSFunctionProxy::cast(fun)->call_trap(); |
244 } | 246 } |
245 if (fun->IsJSFunction()) return Handle<Object>(fun); | 247 if (fun->IsJSFunction()) return Handle<Object>(fun, isolate); |
246 | 248 |
247 // Objects created through the API can have an instance-call handler | 249 // Objects created through the API can have an instance-call handler |
248 // that should be used when calling the object as a function. | 250 // that should be used when calling the object as a function. |
249 if (fun->IsHeapObject() && | 251 if (fun->IsHeapObject() && |
250 HeapObject::cast(fun)->map()->has_instance_call_handler()) { | 252 HeapObject::cast(fun)->map()->has_instance_call_handler()) { |
251 return Handle<JSFunction>( | 253 return Handle<JSFunction>( |
252 isolate->native_context()->call_as_function_delegate()); | 254 isolate->native_context()->call_as_function_delegate()); |
253 } | 255 } |
254 | 256 |
255 return factory->undefined_value(); | 257 return factory->undefined_value(); |
256 } | 258 } |
257 | 259 |
258 | 260 |
259 Handle<Object> Execution::TryGetFunctionDelegate(Handle<Object> object, | 261 Handle<Object> Execution::TryGetFunctionDelegate(Handle<Object> object, |
260 bool* has_pending_exception) { | 262 bool* has_pending_exception) { |
261 ASSERT(!object->IsJSFunction()); | 263 ASSERT(!object->IsJSFunction()); |
262 Isolate* isolate = Isolate::Current(); | 264 Isolate* isolate = Isolate::Current(); |
263 | 265 |
264 // If object is a function proxy, get its handler. Iterate if necessary. | 266 // If object is a function proxy, get its handler. Iterate if necessary. |
265 Object* fun = *object; | 267 Object* fun = *object; |
266 while (fun->IsJSFunctionProxy()) { | 268 while (fun->IsJSFunctionProxy()) { |
267 fun = JSFunctionProxy::cast(fun)->call_trap(); | 269 fun = JSFunctionProxy::cast(fun)->call_trap(); |
268 } | 270 } |
269 if (fun->IsJSFunction()) return Handle<Object>(fun); | 271 if (fun->IsJSFunction()) return Handle<Object>(fun, isolate); |
270 | 272 |
271 // Objects created through the API can have an instance-call handler | 273 // Objects created through the API can have an instance-call handler |
272 // that should be used when calling the object as a function. | 274 // that should be used when calling the object as a function. |
273 if (fun->IsHeapObject() && | 275 if (fun->IsHeapObject() && |
274 HeapObject::cast(fun)->map()->has_instance_call_handler()) { | 276 HeapObject::cast(fun)->map()->has_instance_call_handler()) { |
275 return Handle<JSFunction>( | 277 return Handle<JSFunction>( |
276 isolate->native_context()->call_as_function_delegate()); | 278 isolate->native_context()->call_as_function_delegate()); |
277 } | 279 } |
278 | 280 |
279 // If the Object doesn't have an instance-call handler we should | 281 // If the Object doesn't have an instance-call handler we should |
(...skipping 12 matching lines...) Expand all Loading... |
292 Isolate* isolate = Isolate::Current(); | 294 Isolate* isolate = Isolate::Current(); |
293 | 295 |
294 // If you return a function from here, it will be called when an | 296 // If you return a function from here, it will be called when an |
295 // attempt is made to call the given object as a constructor. | 297 // attempt is made to call the given object as a constructor. |
296 | 298 |
297 // If object is a function proxies, get its handler. Iterate if necessary. | 299 // If object is a function proxies, get its handler. Iterate if necessary. |
298 Object* fun = *object; | 300 Object* fun = *object; |
299 while (fun->IsJSFunctionProxy()) { | 301 while (fun->IsJSFunctionProxy()) { |
300 fun = JSFunctionProxy::cast(fun)->call_trap(); | 302 fun = JSFunctionProxy::cast(fun)->call_trap(); |
301 } | 303 } |
302 if (fun->IsJSFunction()) return Handle<Object>(fun); | 304 if (fun->IsJSFunction()) return Handle<Object>(fun, isolate); |
303 | 305 |
304 // Objects created through the API can have an instance-call handler | 306 // Objects created through the API can have an instance-call handler |
305 // that should be used when calling the object as a function. | 307 // that should be used when calling the object as a function. |
306 if (fun->IsHeapObject() && | 308 if (fun->IsHeapObject() && |
307 HeapObject::cast(fun)->map()->has_instance_call_handler()) { | 309 HeapObject::cast(fun)->map()->has_instance_call_handler()) { |
308 return Handle<JSFunction>( | 310 return Handle<JSFunction>( |
309 isolate->native_context()->call_as_constructor_delegate()); | 311 isolate->native_context()->call_as_constructor_delegate()); |
310 } | 312 } |
311 | 313 |
312 return isolate->factory()->undefined_value(); | 314 return isolate->factory()->undefined_value(); |
313 } | 315 } |
314 | 316 |
315 | 317 |
316 Handle<Object> Execution::TryGetConstructorDelegate( | 318 Handle<Object> Execution::TryGetConstructorDelegate( |
317 Handle<Object> object, | 319 Handle<Object> object, |
318 bool* has_pending_exception) { | 320 bool* has_pending_exception) { |
319 ASSERT(!object->IsJSFunction()); | 321 ASSERT(!object->IsJSFunction()); |
320 Isolate* isolate = Isolate::Current(); | 322 Isolate* isolate = Isolate::Current(); |
321 | 323 |
322 // If you return a function from here, it will be called when an | 324 // If you return a function from here, it will be called when an |
323 // attempt is made to call the given object as a constructor. | 325 // attempt is made to call the given object as a constructor. |
324 | 326 |
325 // If object is a function proxies, get its handler. Iterate if necessary. | 327 // If object is a function proxies, get its handler. Iterate if necessary. |
326 Object* fun = *object; | 328 Object* fun = *object; |
327 while (fun->IsJSFunctionProxy()) { | 329 while (fun->IsJSFunctionProxy()) { |
328 fun = JSFunctionProxy::cast(fun)->call_trap(); | 330 fun = JSFunctionProxy::cast(fun)->call_trap(); |
329 } | 331 } |
330 if (fun->IsJSFunction()) return Handle<Object>(fun); | 332 if (fun->IsJSFunction()) return Handle<Object>(fun, isolate); |
331 | 333 |
332 // Objects created through the API can have an instance-call handler | 334 // Objects created through the API can have an instance-call handler |
333 // that should be used when calling the object as a function. | 335 // that should be used when calling the object as a function. |
334 if (fun->IsHeapObject() && | 336 if (fun->IsHeapObject() && |
335 HeapObject::cast(fun)->map()->has_instance_call_handler()) { | 337 HeapObject::cast(fun)->map()->has_instance_call_handler()) { |
336 return Handle<JSFunction>( | 338 return Handle<JSFunction>( |
337 isolate->native_context()->call_as_constructor_delegate()); | 339 isolate->native_context()->call_as_constructor_delegate()); |
338 } | 340 } |
339 | 341 |
340 // If the Object doesn't have an instance-call handler we should | 342 // If the Object doesn't have an instance-call handler we should |
(...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
592 Isolate* isolate = Isolate::Current(); \ | 594 Isolate* isolate = Isolate::Current(); \ |
593 Handle<Object> argv[] = args; \ | 595 Handle<Object> argv[] = args; \ |
594 ASSERT(has_pending_exception != NULL); \ | 596 ASSERT(has_pending_exception != NULL); \ |
595 return Call(isolate->name##_fun(), \ | 597 return Call(isolate->name##_fun(), \ |
596 isolate->js_builtins_object(), \ | 598 isolate->js_builtins_object(), \ |
597 ARRAY_SIZE(argv), argv, \ | 599 ARRAY_SIZE(argv), argv, \ |
598 has_pending_exception); \ | 600 has_pending_exception); \ |
599 } while (false) | 601 } while (false) |
600 | 602 |
601 | 603 |
602 Handle<Object> Execution::ToBoolean(Handle<Object> obj) { | 604 Handle<Object> Execution::ToBoolean(Isolate* isolate, Handle<Object> obj) { |
603 // See the similar code in runtime.js:ToBoolean. | 605 // See the similar code in runtime.js:ToBoolean. |
604 if (obj->IsBoolean()) return obj; | 606 if (obj->IsBoolean()) return obj; |
605 bool result = true; | 607 bool result = true; |
606 if (obj->IsString()) { | 608 if (obj->IsString()) { |
607 result = Handle<String>::cast(obj)->length() != 0; | 609 result = Handle<String>::cast(obj)->length() != 0; |
608 } else if (obj->IsNull() || obj->IsUndefined()) { | 610 } else if (obj->IsNull() || obj->IsUndefined()) { |
609 result = false; | 611 result = false; |
610 } else if (obj->IsNumber()) { | 612 } else if (obj->IsNumber()) { |
611 double value = obj->Number(); | 613 double value = obj->Number(); |
612 result = !((value == 0) || isnan(value)); | 614 result = !((value == 0) || isnan(value)); |
613 } | 615 } |
614 return Handle<Object>(HEAP->ToBoolean(result)); | 616 return Handle<Object>(isolate->heap()->ToBoolean(result), isolate); |
615 } | 617 } |
616 | 618 |
617 | 619 |
618 Handle<Object> Execution::ToNumber(Handle<Object> obj, bool* exc) { | 620 Handle<Object> Execution::ToNumber(Handle<Object> obj, bool* exc) { |
619 RETURN_NATIVE_CALL(to_number, { obj }, exc); | 621 RETURN_NATIVE_CALL(to_number, { obj }, exc); |
620 } | 622 } |
621 | 623 |
622 | 624 |
623 Handle<Object> Execution::ToString(Handle<Object> obj, bool* exc) { | 625 Handle<Object> Execution::ToString(Handle<Object> obj, bool* exc) { |
624 RETURN_NATIVE_CALL(to_string, { obj }, exc); | 626 RETURN_NATIVE_CALL(to_string, { obj }, exc); |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
675 Handle<Object> Execution::CharAt(Handle<String> string, uint32_t index) { | 677 Handle<Object> Execution::CharAt(Handle<String> string, uint32_t index) { |
676 Isolate* isolate = string->GetIsolate(); | 678 Isolate* isolate = string->GetIsolate(); |
677 Factory* factory = isolate->factory(); | 679 Factory* factory = isolate->factory(); |
678 | 680 |
679 int int_index = static_cast<int>(index); | 681 int int_index = static_cast<int>(index); |
680 if (int_index < 0 || int_index >= string->length()) { | 682 if (int_index < 0 || int_index >= string->length()) { |
681 return factory->undefined_value(); | 683 return factory->undefined_value(); |
682 } | 684 } |
683 | 685 |
684 Handle<Object> char_at = | 686 Handle<Object> char_at = |
685 GetProperty(isolate->js_builtins_object(), | 687 GetProperty(isolate, |
| 688 isolate->js_builtins_object(), |
686 factory->char_at_symbol()); | 689 factory->char_at_symbol()); |
687 if (!char_at->IsJSFunction()) { | 690 if (!char_at->IsJSFunction()) { |
688 return factory->undefined_value(); | 691 return factory->undefined_value(); |
689 } | 692 } |
690 | 693 |
691 bool caught_exception; | 694 bool caught_exception; |
692 Handle<Object> index_object = factory->NewNumberFromInt(int_index); | 695 Handle<Object> index_object = factory->NewNumberFromInt(int_index); |
693 Handle<Object> index_arg[] = { index_object }; | 696 Handle<Object> index_arg[] = { index_object }; |
694 Handle<Object> result = TryCall(Handle<JSFunction>::cast(char_at), | 697 Handle<Object> result = TryCall(Handle<JSFunction>::cast(char_at), |
695 string, | 698 string, |
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
941 } | 944 } |
942 if (stack_guard->IsInterrupted()) { | 945 if (stack_guard->IsInterrupted()) { |
943 stack_guard->Continue(INTERRUPT); | 946 stack_guard->Continue(INTERRUPT); |
944 return isolate->StackOverflow(); | 947 return isolate->StackOverflow(); |
945 } | 948 } |
946 return isolate->heap()->undefined_value(); | 949 return isolate->heap()->undefined_value(); |
947 } | 950 } |
948 | 951 |
949 | 952 |
950 } } // namespace v8::internal | 953 } } // namespace v8::internal |
OLD | NEW |