OLD | NEW |
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 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 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
200 // triggered during environment creation there may be weak handle | 200 // triggered during environment creation there may be weak handle |
201 // processing callbacks which may create new environments. | 201 // processing callbacks which may create new environments. |
202 Genesis* previous_; | 202 Genesis* previous_; |
203 | 203 |
204 Handle<Context> global_context() { return global_context_; } | 204 Handle<Context> global_context() { return global_context_; } |
205 | 205 |
206 // Creates some basic objects. Used for creating a context from scratch. | 206 // Creates some basic objects. Used for creating a context from scratch. |
207 void CreateRoots(); | 207 void CreateRoots(); |
208 // Creates the empty function. Used for creating a context from scratch. | 208 // Creates the empty function. Used for creating a context from scratch. |
209 Handle<JSFunction> CreateEmptyFunction(); | 209 Handle<JSFunction> CreateEmptyFunction(); |
| 210 void CreateThrowTypeErrorCallbacks( |
| 211 Handle<FixedArray> callbacks, |
| 212 Builtins::Name builtin); |
| 213 void CreateThrowTypeError(Handle<JSFunction> empty); |
210 // Creates the global objects using the global and the template passed in | 214 // Creates the global objects using the global and the template passed in |
211 // through the API. We call this regardless of whether we are building a | 215 // through the API. We call this regardless of whether we are building a |
212 // context from scratch or using a deserialized one from the partial snapshot | 216 // context from scratch or using a deserialized one from the partial snapshot |
213 // but in the latter case we don't use the objects it produces directly, as | 217 // but in the latter case we don't use the objects it produces directly, as |
214 // we have to used the deserialized ones that are linked together with the | 218 // we have to used the deserialized ones that are linked together with the |
215 // rest of the context snapshot. | 219 // rest of the context snapshot. |
216 Handle<JSGlobalProxy> CreateNewGlobals( | 220 Handle<JSGlobalProxy> CreateNewGlobals( |
217 v8::Handle<v8::ObjectTemplate> global_template, | 221 v8::Handle<v8::ObjectTemplate> global_template, |
218 Handle<Object> global_object, | 222 Handle<Object> global_object, |
219 Handle<GlobalObject>* global_proxy_out); | 223 Handle<GlobalObject>* global_proxy_out); |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
256 void TransferIndexedProperties(Handle<JSObject> from, Handle<JSObject> to); | 260 void TransferIndexedProperties(Handle<JSObject> from, Handle<JSObject> to); |
257 | 261 |
258 enum PrototypePropertyMode { | 262 enum PrototypePropertyMode { |
259 DONT_ADD_PROTOTYPE, | 263 DONT_ADD_PROTOTYPE, |
260 ADD_READONLY_PROTOTYPE, | 264 ADD_READONLY_PROTOTYPE, |
261 ADD_WRITEABLE_PROTOTYPE | 265 ADD_WRITEABLE_PROTOTYPE |
262 }; | 266 }; |
263 Handle<DescriptorArray> ComputeFunctionInstanceDescriptor( | 267 Handle<DescriptorArray> ComputeFunctionInstanceDescriptor( |
264 PrototypePropertyMode prototypeMode); | 268 PrototypePropertyMode prototypeMode); |
265 void MakeFunctionInstancePrototypeWritable(); | 269 void MakeFunctionInstancePrototypeWritable(); |
| 270 Handle<DescriptorArray> ComputeStrictFunctionDescriptor( |
| 271 PrototypePropertyMode propertyMode, |
| 272 Handle<FixedArray> arguments, |
| 273 Handle<FixedArray> caller); |
266 | 274 |
267 static bool CompileBuiltin(int index); | 275 static bool CompileBuiltin(int index); |
268 static bool CompileNative(Vector<const char> name, Handle<String> source); | 276 static bool CompileNative(Vector<const char> name, Handle<String> source); |
269 static bool CompileScriptCached(Vector<const char> name, | 277 static bool CompileScriptCached(Vector<const char> name, |
270 Handle<String> source, | 278 Handle<String> source, |
271 SourceCodeCache* cache, | 279 SourceCodeCache* cache, |
272 v8::Extension* extension, | 280 v8::Extension* extension, |
273 Handle<Context> top_context, | 281 Handle<Context> top_context, |
274 bool use_runtime_context); | 282 bool use_runtime_context); |
275 | 283 |
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
492 Handle<Map> empty_fm = Factory::CopyMapDropDescriptors( | 500 Handle<Map> empty_fm = Factory::CopyMapDropDescriptors( |
493 function_without_prototype_map); | 501 function_without_prototype_map); |
494 empty_fm->set_instance_descriptors( | 502 empty_fm->set_instance_descriptors( |
495 *function_without_prototype_map_descriptors); | 503 *function_without_prototype_map_descriptors); |
496 empty_fm->set_prototype(global_context()->object_function()->prototype()); | 504 empty_fm->set_prototype(global_context()->object_function()->prototype()); |
497 empty_function->set_map(*empty_fm); | 505 empty_function->set_map(*empty_fm); |
498 return empty_function; | 506 return empty_function; |
499 } | 507 } |
500 | 508 |
501 | 509 |
| 510 Handle<DescriptorArray> Genesis::ComputeStrictFunctionDescriptor( |
| 511 PrototypePropertyMode prototypeMode, |
| 512 Handle<FixedArray> arguments, |
| 513 Handle<FixedArray> caller) { |
| 514 Handle<DescriptorArray> descriptors = |
| 515 Factory::NewDescriptorArray(prototypeMode == DONT_ADD_PROTOTYPE ? 4 : 5); |
| 516 PropertyAttributes attributes = static_cast<PropertyAttributes>( |
| 517 DONT_ENUM | DONT_DELETE | READ_ONLY); |
| 518 |
| 519 { // length |
| 520 Handle<Proxy> proxy = Factory::NewProxy(&Accessors::FunctionLength); |
| 521 CallbacksDescriptor d(*Factory::length_symbol(), *proxy, attributes); |
| 522 descriptors->Set(0, &d); |
| 523 } |
| 524 { // name |
| 525 Handle<Proxy> proxy = Factory::NewProxy(&Accessors::FunctionName); |
| 526 CallbacksDescriptor d(*Factory::name_symbol(), *proxy, attributes); |
| 527 descriptors->Set(1, &d); |
| 528 } |
| 529 { // arguments |
| 530 CallbacksDescriptor d(*Factory::arguments_symbol(), *arguments, attributes); |
| 531 descriptors->Set(2, &d); |
| 532 } |
| 533 { // caller |
| 534 CallbacksDescriptor d(*Factory::caller_symbol(), *caller, attributes); |
| 535 descriptors->Set(3, &d); |
| 536 } |
| 537 |
| 538 // prototype |
| 539 if (prototypeMode != DONT_ADD_PROTOTYPE) { |
| 540 if (prototypeMode == ADD_WRITEABLE_PROTOTYPE) { |
| 541 attributes = static_cast<PropertyAttributes>(attributes & ~READ_ONLY); |
| 542 } |
| 543 CallbacksDescriptor d( |
| 544 *Factory::prototype_symbol(), |
| 545 *Factory::NewProxy(&Accessors::FunctionPrototype), |
| 546 attributes); |
| 547 descriptors->Set(4, &d); |
| 548 } |
| 549 |
| 550 descriptors->Sort(); |
| 551 return descriptors; |
| 552 } |
| 553 |
| 554 |
| 555 void Genesis::CreateThrowTypeErrorCallbacks( |
| 556 Handle<FixedArray> callbacks, |
| 557 Builtins::Name builtin) { |
| 558 // Create the ThrowTypeError function. |
| 559 Handle<String> name = Factory::LookupAsciiSymbol("ThrowTypeError"); |
| 560 Handle<JSFunction> pill = Factory::NewFunctionWithoutPrototypeStrict(name); |
| 561 Handle<Code> code = Handle<Code>(Builtins::builtin(builtin)); |
| 562 pill->set_map(global_context()->function_map_strict()); |
| 563 pill->set_code(*code); |
| 564 pill->shared()->set_code(*code); |
| 565 pill->shared()->DontAdaptArguments(); |
| 566 |
| 567 // Install the poison pills into the calbacks array. |
| 568 callbacks->set(0, *pill); |
| 569 callbacks->set(1, *pill); |
| 570 |
| 571 PreventExtensions(pill); |
| 572 } |
| 573 |
| 574 |
| 575 // ECMAScript 5th Edition, 13.2.3 |
| 576 void Genesis::CreateThrowTypeError(Handle<JSFunction> empty) { |
| 577 // Create the pill callbacks arrays. The get/set callacks are installed |
| 578 // after the maps get created below. |
| 579 Handle<FixedArray> arguments = Factory::NewFixedArray(2, TENURED); |
| 580 Handle<FixedArray> caller = Factory::NewFixedArray(2, TENURED); |
| 581 |
| 582 { // Allocate map for the strict mode function instances. |
| 583 Handle<Map> map = Factory::NewMap(JS_FUNCTION_TYPE, JSFunction::kSize); |
| 584 global_context()->set_function_instance_map_strict(*map); |
| 585 Handle<DescriptorArray> descriptors = ComputeStrictFunctionDescriptor( |
| 586 ADD_WRITEABLE_PROTOTYPE, arguments, caller); |
| 587 map->set_instance_descriptors(*descriptors); |
| 588 map->set_function_with_prototype(true); |
| 589 map->set_prototype(*empty); |
| 590 } |
| 591 |
| 592 { // Allocate map for the prototype-less strict mode instances. |
| 593 Handle<Map> map = Factory::NewMap(JS_FUNCTION_TYPE, JSFunction::kSize); |
| 594 global_context()->set_function_without_prototype_map_strict(*map); |
| 595 Handle<DescriptorArray> descriptors = ComputeStrictFunctionDescriptor( |
| 596 DONT_ADD_PROTOTYPE, arguments, caller); |
| 597 map->set_instance_descriptors(*descriptors); |
| 598 map->set_function_with_prototype(false); |
| 599 map->set_prototype(*empty); |
| 600 } |
| 601 |
| 602 { // Allocate map for the strict mode functions. |
| 603 Handle<Map> map = Factory::NewMap(JS_FUNCTION_TYPE, JSFunction::kSize); |
| 604 global_context()->set_function_map_strict(*map); |
| 605 Handle<DescriptorArray> descriptors = ComputeStrictFunctionDescriptor( |
| 606 ADD_READONLY_PROTOTYPE, arguments, caller); |
| 607 map->set_instance_descriptors(*descriptors); |
| 608 map->set_function_with_prototype(true); |
| 609 map->set_prototype(*empty); |
| 610 } |
| 611 |
| 612 CreateThrowTypeErrorCallbacks(arguments, Builtins::StrictFunctionArguments); |
| 613 CreateThrowTypeErrorCallbacks(caller, Builtins::StrictFunctionCaller); |
| 614 } |
| 615 |
| 616 |
502 static void AddToWeakGlobalContextList(Context* context) { | 617 static void AddToWeakGlobalContextList(Context* context) { |
503 ASSERT(context->IsGlobalContext()); | 618 ASSERT(context->IsGlobalContext()); |
504 #ifdef DEBUG | 619 #ifdef DEBUG |
505 { // NOLINT | 620 { // NOLINT |
506 ASSERT(context->get(Context::NEXT_CONTEXT_LINK)->IsUndefined()); | 621 ASSERT(context->get(Context::NEXT_CONTEXT_LINK)->IsUndefined()); |
507 // Check that context is not in the list yet. | 622 // Check that context is not in the list yet. |
508 for (Object* current = Heap::global_contexts_list(); | 623 for (Object* current = Heap::global_contexts_list(); |
509 !current->IsUndefined(); | 624 !current->IsUndefined(); |
510 current = Context::cast(current)->get(Context::NEXT_CONTEXT_LINK)) { | 625 current = Context::cast(current)->get(Context::NEXT_CONTEXT_LINK)) { |
511 ASSERT(current != context); | 626 ASSERT(current != context); |
(...skipping 1294 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1806 new_to_map->set_prototype(from->map()->prototype()); | 1921 new_to_map->set_prototype(from->map()->prototype()); |
1807 to->set_map(*new_to_map); | 1922 to->set_map(*new_to_map); |
1808 } | 1923 } |
1809 | 1924 |
1810 | 1925 |
1811 void Genesis::MakeFunctionInstancePrototypeWritable() { | 1926 void Genesis::MakeFunctionInstancePrototypeWritable() { |
1812 // Make a new function map so all future functions | 1927 // Make a new function map so all future functions |
1813 // will have settable and enumerable prototype properties. | 1928 // will have settable and enumerable prototype properties. |
1814 HandleScope scope; | 1929 HandleScope scope; |
1815 | 1930 |
1816 Handle<DescriptorArray> function_map_descriptors = | 1931 { // function_map |
1817 ComputeFunctionInstanceDescriptor(ADD_WRITEABLE_PROTOTYPE); | 1932 Handle<DescriptorArray> function_map_descriptors = |
1818 Handle<Map> fm = Factory::CopyMapDropDescriptors(Top::function_map()); | 1933 ComputeFunctionInstanceDescriptor(ADD_WRITEABLE_PROTOTYPE); |
1819 fm->set_instance_descriptors(*function_map_descriptors); | 1934 Handle<Map> fm = Factory::CopyMapDropDescriptors(Top::function_map()); |
1820 fm->set_function_with_prototype(true); | 1935 fm->set_instance_descriptors(*function_map_descriptors); |
1821 Top::context()->global_context()->set_function_map(*fm); | 1936 fm->set_function_with_prototype(true); |
| 1937 Top::context()->global_context()->set_function_map(*fm); |
| 1938 } |
| 1939 |
| 1940 { // function_map_strict |
| 1941 // Extract arguments and caller from the original strict function map. |
| 1942 Handle<Map> old_map(global_context()->function_map_strict()); |
| 1943 Handle<DescriptorArray> old_descriptors(old_map->instance_descriptors()); |
| 1944 int arguments_index = old_descriptors->Search(*Factory::arguments_symbol()); |
| 1945 int caller_index = old_descriptors->Search(*Factory::caller_symbol()); |
| 1946 ASSERT(arguments_index != DescriptorArray::kNotFound); |
| 1947 ASSERT(caller_index != DescriptorArray::kNotFound); |
| 1948 Handle<FixedArray> arguments( |
| 1949 FixedArray::cast(old_descriptors->GetValue(arguments_index))); |
| 1950 Handle<FixedArray> caller( |
| 1951 FixedArray::cast(old_descriptors->GetValue(caller_index))); |
| 1952 |
| 1953 // Create the map with writeable prototype for strict mode functions. |
| 1954 Handle<Map> map = Factory::NewMap(JS_FUNCTION_TYPE, JSFunction::kSize); |
| 1955 global_context()->set_function_map_strict(*map); |
| 1956 Handle<DescriptorArray> descriptors = ComputeStrictFunctionDescriptor( |
| 1957 ADD_WRITEABLE_PROTOTYPE, arguments, caller); |
| 1958 map->set_instance_descriptors(*descriptors); |
| 1959 map->set_function_with_prototype(true); |
| 1960 map->set_prototype(old_map->prototype()); |
| 1961 } |
1822 } | 1962 } |
1823 | 1963 |
1824 | 1964 |
1825 Genesis::Genesis(Handle<Object> global_object, | 1965 Genesis::Genesis(Handle<Object> global_object, |
1826 v8::Handle<v8::ObjectTemplate> global_template, | 1966 v8::Handle<v8::ObjectTemplate> global_template, |
1827 v8::ExtensionConfiguration* extensions) { | 1967 v8::ExtensionConfiguration* extensions) { |
1828 result_ = Handle<Context>::null(); | 1968 result_ = Handle<Context>::null(); |
1829 // If V8 isn't running and cannot be initialized, just return. | 1969 // If V8 isn't running and cannot be initialized, just return. |
1830 if (!V8::IsRunning() && !V8::Initialize(NULL)) return; | 1970 if (!V8::IsRunning() && !V8::Initialize(NULL)) return; |
1831 | 1971 |
(...skipping 19 matching lines...) Expand all Loading... |
1851 &inner_global); | 1991 &inner_global); |
1852 | 1992 |
1853 HookUpGlobalProxy(inner_global, global_proxy); | 1993 HookUpGlobalProxy(inner_global, global_proxy); |
1854 HookUpInnerGlobal(inner_global); | 1994 HookUpInnerGlobal(inner_global); |
1855 | 1995 |
1856 if (!ConfigureGlobalObjects(global_template)) return; | 1996 if (!ConfigureGlobalObjects(global_template)) return; |
1857 } else { | 1997 } else { |
1858 // We get here if there was no context snapshot. | 1998 // We get here if there was no context snapshot. |
1859 CreateRoots(); | 1999 CreateRoots(); |
1860 Handle<JSFunction> empty_function = CreateEmptyFunction(); | 2000 Handle<JSFunction> empty_function = CreateEmptyFunction(); |
| 2001 CreateThrowTypeError(empty_function); |
1861 Handle<GlobalObject> inner_global; | 2002 Handle<GlobalObject> inner_global; |
1862 Handle<JSGlobalProxy> global_proxy = | 2003 Handle<JSGlobalProxy> global_proxy = |
1863 CreateNewGlobals(global_template, global_object, &inner_global); | 2004 CreateNewGlobals(global_template, global_object, &inner_global); |
1864 HookUpGlobalProxy(inner_global, global_proxy); | 2005 HookUpGlobalProxy(inner_global, global_proxy); |
1865 InitializeGlobal(inner_global, empty_function); | 2006 InitializeGlobal(inner_global, empty_function); |
1866 InstallJSFunctionResultCaches(); | 2007 InstallJSFunctionResultCaches(); |
1867 InitializeNormalizedMapCaches(); | 2008 InitializeNormalizedMapCaches(); |
1868 if (!InstallNatives()) return; | 2009 if (!InstallNatives()) return; |
1869 | 2010 |
1870 MakeFunctionInstancePrototypeWritable(); | 2011 MakeFunctionInstancePrototypeWritable(); |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1917 } | 2058 } |
1918 | 2059 |
1919 | 2060 |
1920 // Restore statics that are thread local. | 2061 // Restore statics that are thread local. |
1921 char* BootstrapperActive::RestoreState(char* from) { | 2062 char* BootstrapperActive::RestoreState(char* from) { |
1922 nesting_ = *reinterpret_cast<int*>(from); | 2063 nesting_ = *reinterpret_cast<int*>(from); |
1923 return from + sizeof(nesting_); | 2064 return from + sizeof(nesting_); |
1924 } | 2065 } |
1925 | 2066 |
1926 } } // namespace v8::internal | 2067 } } // namespace v8::internal |
OLD | NEW |