Home | History | Annotate | Download | only in src
      1 // Copyright 2006-2008 the V8 project authors. All rights reserved.
      2 // Redistribution and use in source and binary forms, with or without
      3 // modification, are permitted provided that the following conditions are
      4 // met:
      5 //
      6 //     * Redistributions of source code must retain the above copyright
      7 //       notice, this list of conditions and the following disclaimer.
      8 //     * Redistributions in binary form must reproduce the above
      9 //       copyright notice, this list of conditions and the following
     10 //       disclaimer in the documentation and/or other materials provided
     11 //       with the distribution.
     12 //     * Neither the name of Google Inc. nor the names of its
     13 //       contributors may be used to endorse or promote products derived
     14 //       from this software without specific prior written permission.
     15 //
     16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27 
     28 #include "v8.h"
     29 
     30 #include "accessors.h"
     31 #include "api.h"
     32 #include "bootstrapper.h"
     33 #include "compiler.h"
     34 #include "debug.h"
     35 #include "execution.h"
     36 #include "global-handles.h"
     37 #include "macro-assembler.h"
     38 #include "natives.h"
     39 #include "objects-visiting.h"
     40 #include "snapshot.h"
     41 #include "extensions/externalize-string-extension.h"
     42 #include "extensions/gc-extension.h"
     43 
     44 namespace v8 {
     45 namespace internal {
     46 
     47 
     48 NativesExternalStringResource::NativesExternalStringResource(
     49     Bootstrapper* bootstrapper,
     50     const char* source)
     51     : data_(source), length_(StrLength(source)) {
     52   if (bootstrapper->delete_these_non_arrays_on_tear_down_ == NULL) {
     53     bootstrapper->delete_these_non_arrays_on_tear_down_ = new List<char*>(2);
     54   }
     55   // The resources are small objects and we only make a fixed number of
     56   // them, but let's clean them up on exit for neatness.
     57   bootstrapper->delete_these_non_arrays_on_tear_down_->
     58       Add(reinterpret_cast<char*>(this));
     59 }
     60 
     61 
     62 Bootstrapper::Bootstrapper()
     63     : nesting_(0),
     64       extensions_cache_(Script::TYPE_EXTENSION),
     65       delete_these_non_arrays_on_tear_down_(NULL),
     66       delete_these_arrays_on_tear_down_(NULL) {
     67 }
     68 
     69 
     70 Handle<String> Bootstrapper::NativesSourceLookup(int index) {
     71   ASSERT(0 <= index && index < Natives::GetBuiltinsCount());
     72   Isolate* isolate = Isolate::Current();
     73   Factory* factory = isolate->factory();
     74   Heap* heap = isolate->heap();
     75   if (heap->natives_source_cache()->get(index)->IsUndefined()) {
     76     if (!Snapshot::IsEnabled() || FLAG_new_snapshot) {
     77       // We can use external strings for the natives.
     78       NativesExternalStringResource* resource =
     79           new NativesExternalStringResource(this,
     80               Natives::GetScriptSource(index).start());
     81       Handle<String> source_code =
     82           factory->NewExternalStringFromAscii(resource);
     83       heap->natives_source_cache()->set(index, *source_code);
     84     } else {
     85       // Old snapshot code can't cope with external strings at all.
     86       Handle<String> source_code =
     87         factory->NewStringFromAscii(Natives::GetScriptSource(index));
     88       heap->natives_source_cache()->set(index, *source_code);
     89     }
     90   }
     91   Handle<Object> cached_source(heap->natives_source_cache()->get(index));
     92   return Handle<String>::cast(cached_source);
     93 }
     94 
     95 
     96 void Bootstrapper::Initialize(bool create_heap_objects) {
     97   extensions_cache_.Initialize(create_heap_objects);
     98   GCExtension::Register();
     99   ExternalizeStringExtension::Register();
    100 }
    101 
    102 
    103 char* Bootstrapper::AllocateAutoDeletedArray(int bytes) {
    104   char* memory = new char[bytes];
    105   if (memory != NULL) {
    106     if (delete_these_arrays_on_tear_down_ == NULL) {
    107       delete_these_arrays_on_tear_down_ = new List<char*>(2);
    108     }
    109     delete_these_arrays_on_tear_down_->Add(memory);
    110   }
    111   return memory;
    112 }
    113 
    114 
    115 void Bootstrapper::TearDown() {
    116   if (delete_these_non_arrays_on_tear_down_ != NULL) {
    117     int len = delete_these_non_arrays_on_tear_down_->length();
    118     ASSERT(len < 20);  // Don't use this mechanism for unbounded allocations.
    119     for (int i = 0; i < len; i++) {
    120       delete delete_these_non_arrays_on_tear_down_->at(i);
    121       delete_these_non_arrays_on_tear_down_->at(i) = NULL;
    122     }
    123     delete delete_these_non_arrays_on_tear_down_;
    124     delete_these_non_arrays_on_tear_down_ = NULL;
    125   }
    126 
    127   if (delete_these_arrays_on_tear_down_ != NULL) {
    128     int len = delete_these_arrays_on_tear_down_->length();
    129     ASSERT(len < 1000);  // Don't use this mechanism for unbounded allocations.
    130     for (int i = 0; i < len; i++) {
    131       delete[] delete_these_arrays_on_tear_down_->at(i);
    132       delete_these_arrays_on_tear_down_->at(i) = NULL;
    133     }
    134     delete delete_these_arrays_on_tear_down_;
    135     delete_these_arrays_on_tear_down_ = NULL;
    136   }
    137 
    138   extensions_cache_.Initialize(false);  // Yes, symmetrical
    139 }
    140 
    141 
    142 class Genesis BASE_EMBEDDED {
    143  public:
    144   Genesis(Handle<Object> global_object,
    145           v8::Handle<v8::ObjectTemplate> global_template,
    146           v8::ExtensionConfiguration* extensions);
    147   ~Genesis() { }
    148 
    149   Handle<Context> result() { return result_; }
    150 
    151   Genesis* previous() { return previous_; }
    152 
    153  private:
    154   Handle<Context> global_context_;
    155 
    156   // There may be more than one active genesis object: When GC is
    157   // triggered during environment creation there may be weak handle
    158   // processing callbacks which may create new environments.
    159   Genesis* previous_;
    160 
    161   Handle<Context> global_context() { return global_context_; }
    162 
    163   // Creates some basic objects. Used for creating a context from scratch.
    164   void CreateRoots();
    165   // Creates the empty function.  Used for creating a context from scratch.
    166   Handle<JSFunction> CreateEmptyFunction();
    167   // Creates the ThrowTypeError function. ECMA 5th Ed. 13.2.3
    168   Handle<JSFunction> CreateThrowTypeErrorFunction(Builtins::Name builtin);
    169 
    170   void CreateStrictModeFunctionMaps(Handle<JSFunction> empty);
    171   // Creates the global objects using the global and the template passed in
    172   // through the API.  We call this regardless of whether we are building a
    173   // context from scratch or using a deserialized one from the partial snapshot
    174   // but in the latter case we don't use the objects it produces directly, as
    175   // we have to used the deserialized ones that are linked together with the
    176   // rest of the context snapshot.
    177   Handle<JSGlobalProxy> CreateNewGlobals(
    178       v8::Handle<v8::ObjectTemplate> global_template,
    179       Handle<Object> global_object,
    180       Handle<GlobalObject>* global_proxy_out);
    181   // Hooks the given global proxy into the context.  If the context was created
    182   // by deserialization then this will unhook the global proxy that was
    183   // deserialized, leaving the GC to pick it up.
    184   void HookUpGlobalProxy(Handle<GlobalObject> inner_global,
    185                          Handle<JSGlobalProxy> global_proxy);
    186   // Similarly, we want to use the inner global that has been created by the
    187   // templates passed through the API.  The inner global from the snapshot is
    188   // detached from the other objects in the snapshot.
    189   void HookUpInnerGlobal(Handle<GlobalObject> inner_global);
    190   // New context initialization.  Used for creating a context from scratch.
    191   void InitializeGlobal(Handle<GlobalObject> inner_global,
    192                         Handle<JSFunction> empty_function);
    193   // Installs the contents of the native .js files on the global objects.
    194   // Used for creating a context from scratch.
    195   void InstallNativeFunctions();
    196   bool InstallNatives();
    197   void InstallBuiltinFunctionIds();
    198   void InstallJSFunctionResultCaches();
    199   void InitializeNormalizedMapCaches();
    200   // Used both for deserialized and from-scratch contexts to add the extensions
    201   // provided.
    202   static bool InstallExtensions(Handle<Context> global_context,
    203                                 v8::ExtensionConfiguration* extensions);
    204   static bool InstallExtension(const char* name);
    205   static bool InstallExtension(v8::RegisteredExtension* current);
    206   static void InstallSpecialObjects(Handle<Context> global_context);
    207   bool InstallJSBuiltins(Handle<JSBuiltinsObject> builtins);
    208   bool ConfigureApiObject(Handle<JSObject> object,
    209                           Handle<ObjectTemplateInfo> object_template);
    210   bool ConfigureGlobalObjects(v8::Handle<v8::ObjectTemplate> global_template);
    211 
    212   // Migrates all properties from the 'from' object to the 'to'
    213   // object and overrides the prototype in 'to' with the one from
    214   // 'from'.
    215   void TransferObject(Handle<JSObject> from, Handle<JSObject> to);
    216   void TransferNamedProperties(Handle<JSObject> from, Handle<JSObject> to);
    217   void TransferIndexedProperties(Handle<JSObject> from, Handle<JSObject> to);
    218 
    219   enum PrototypePropertyMode {
    220     DONT_ADD_PROTOTYPE,
    221     ADD_READONLY_PROTOTYPE,
    222     ADD_WRITEABLE_PROTOTYPE
    223   };
    224 
    225   Handle<Map> CreateFunctionMap(PrototypePropertyMode prototype_mode);
    226 
    227   Handle<DescriptorArray> ComputeFunctionInstanceDescriptor(
    228       PrototypePropertyMode prototypeMode);
    229   void MakeFunctionInstancePrototypeWritable();
    230 
    231   Handle<Map> CreateStrictModeFunctionMap(
    232       PrototypePropertyMode prototype_mode,
    233       Handle<JSFunction> empty_function,
    234       Handle<FixedArray> arguments_callbacks,
    235       Handle<FixedArray> caller_callbacks);
    236 
    237   Handle<DescriptorArray> ComputeStrictFunctionInstanceDescriptor(
    238       PrototypePropertyMode propertyMode,
    239       Handle<FixedArray> arguments,
    240       Handle<FixedArray> caller);
    241 
    242   static bool CompileBuiltin(int index);
    243   static bool CompileNative(Vector<const char> name, Handle<String> source);
    244   static bool CompileScriptCached(Vector<const char> name,
    245                                   Handle<String> source,
    246                                   SourceCodeCache* cache,
    247                                   v8::Extension* extension,
    248                                   Handle<Context> top_context,
    249                                   bool use_runtime_context);
    250 
    251   Handle<Context> result_;
    252 
    253   // Function instance maps. Function literal maps are created initially with
    254   // a read only prototype for the processing of JS builtins. Later the function
    255   // instance maps are replaced in order to make prototype writable.
    256   // These are the final, writable prototype, maps.
    257   Handle<Map> function_instance_map_writable_prototype_;
    258   Handle<Map> strict_mode_function_instance_map_writable_prototype_;
    259 
    260   BootstrapperActive active_;
    261   friend class Bootstrapper;
    262 };
    263 
    264 
    265 void Bootstrapper::Iterate(ObjectVisitor* v) {
    266   extensions_cache_.Iterate(v);
    267   v->Synchronize("Extensions");
    268 }
    269 
    270 
    271 Handle<Context> Bootstrapper::CreateEnvironment(
    272     Handle<Object> global_object,
    273     v8::Handle<v8::ObjectTemplate> global_template,
    274     v8::ExtensionConfiguration* extensions) {
    275   HandleScope scope;
    276   Handle<Context> env;
    277   Genesis genesis(global_object, global_template, extensions);
    278   env = genesis.result();
    279   if (!env.is_null()) {
    280     if (InstallExtensions(env, extensions)) {
    281       return env;
    282     }
    283   }
    284   return Handle<Context>();
    285 }
    286 
    287 
    288 static void SetObjectPrototype(Handle<JSObject> object, Handle<Object> proto) {
    289   // object.__proto__ = proto;
    290   Handle<Map> old_to_map = Handle<Map>(object->map());
    291   Handle<Map> new_to_map = FACTORY->CopyMapDropTransitions(old_to_map);
    292   new_to_map->set_prototype(*proto);
    293   object->set_map(*new_to_map);
    294 }
    295 
    296 
    297 void Bootstrapper::DetachGlobal(Handle<Context> env) {
    298   Factory* factory = Isolate::Current()->factory();
    299   JSGlobalProxy::cast(env->global_proxy())->set_context(*factory->null_value());
    300   SetObjectPrototype(Handle<JSObject>(env->global_proxy()),
    301                      factory->null_value());
    302   env->set_global_proxy(env->global());
    303   env->global()->set_global_receiver(env->global());
    304 }
    305 
    306 
    307 void Bootstrapper::ReattachGlobal(Handle<Context> env,
    308                                   Handle<Object> global_object) {
    309   ASSERT(global_object->IsJSGlobalProxy());
    310   Handle<JSGlobalProxy> global = Handle<JSGlobalProxy>::cast(global_object);
    311   env->global()->set_global_receiver(*global);
    312   env->set_global_proxy(*global);
    313   SetObjectPrototype(global, Handle<JSObject>(env->global()));
    314   global->set_context(*env);
    315 }
    316 
    317 
    318 static Handle<JSFunction> InstallFunction(Handle<JSObject> target,
    319                                           const char* name,
    320                                           InstanceType type,
    321                                           int instance_size,
    322                                           Handle<JSObject> prototype,
    323                                           Builtins::Name call,
    324                                           bool is_ecma_native) {
    325   Isolate* isolate = Isolate::Current();
    326   Factory* factory = isolate->factory();
    327   Handle<String> symbol = factory->LookupAsciiSymbol(name);
    328   Handle<Code> call_code = Handle<Code>(isolate->builtins()->builtin(call));
    329   Handle<JSFunction> function = prototype.is_null() ?
    330     factory->NewFunctionWithoutPrototype(symbol, call_code) :
    331     factory->NewFunctionWithPrototype(symbol,
    332                                       type,
    333                                       instance_size,
    334                                       prototype,
    335                                       call_code,
    336                                       is_ecma_native);
    337   SetLocalPropertyNoThrow(target, symbol, function, DONT_ENUM);
    338   if (is_ecma_native) {
    339     function->shared()->set_instance_class_name(*symbol);
    340   }
    341   return function;
    342 }
    343 
    344 
    345 Handle<DescriptorArray> Genesis::ComputeFunctionInstanceDescriptor(
    346     PrototypePropertyMode prototypeMode) {
    347   Factory* factory = Isolate::Current()->factory();
    348   Handle<DescriptorArray> descriptors =
    349       factory->NewDescriptorArray(prototypeMode == DONT_ADD_PROTOTYPE ? 4 : 5);
    350   PropertyAttributes attributes =
    351       static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY);
    352 
    353   {  // Add length.
    354     Handle<Proxy> proxy = factory->NewProxy(&Accessors::FunctionLength);
    355     CallbacksDescriptor d(*factory->length_symbol(), *proxy, attributes);
    356     descriptors->Set(0, &d);
    357   }
    358   {  // Add name.
    359     Handle<Proxy> proxy = factory->NewProxy(&Accessors::FunctionName);
    360     CallbacksDescriptor d(*factory->name_symbol(), *proxy, attributes);
    361     descriptors->Set(1, &d);
    362   }
    363   {  // Add arguments.
    364     Handle<Proxy> proxy = factory->NewProxy(&Accessors::FunctionArguments);
    365     CallbacksDescriptor d(*factory->arguments_symbol(), *proxy, attributes);
    366     descriptors->Set(2, &d);
    367   }
    368   {  // Add caller.
    369     Handle<Proxy> proxy = factory->NewProxy(&Accessors::FunctionCaller);
    370     CallbacksDescriptor d(*factory->caller_symbol(), *proxy, attributes);
    371     descriptors->Set(3, &d);
    372   }
    373   if (prototypeMode != DONT_ADD_PROTOTYPE) {
    374     // Add prototype.
    375     if (prototypeMode == ADD_WRITEABLE_PROTOTYPE) {
    376       attributes = static_cast<PropertyAttributes>(attributes & ~READ_ONLY);
    377     }
    378     Handle<Proxy> proxy = factory->NewProxy(&Accessors::FunctionPrototype);
    379     CallbacksDescriptor d(*factory->prototype_symbol(), *proxy, attributes);
    380     descriptors->Set(4, &d);
    381   }
    382   descriptors->Sort();
    383   return descriptors;
    384 }
    385 
    386 
    387 Handle<Map> Genesis::CreateFunctionMap(PrototypePropertyMode prototype_mode) {
    388   Handle<Map> map = FACTORY->NewMap(JS_FUNCTION_TYPE, JSFunction::kSize);
    389   Handle<DescriptorArray> descriptors =
    390       ComputeFunctionInstanceDescriptor(prototype_mode);
    391   map->set_instance_descriptors(*descriptors);
    392   map->set_function_with_prototype(prototype_mode != DONT_ADD_PROTOTYPE);
    393   return map;
    394 }
    395 
    396 
    397 Handle<JSFunction> Genesis::CreateEmptyFunction() {
    398   // Allocate the map for function instances. Maps are allocated first and their
    399   // prototypes patched later, once empty function is created.
    400 
    401   // Please note that the prototype property for function instances must be
    402   // writable.
    403   Handle<Map> function_instance_map =
    404       CreateFunctionMap(ADD_WRITEABLE_PROTOTYPE);
    405   global_context()->set_function_instance_map(*function_instance_map);
    406 
    407   // Functions with this map will not have a 'prototype' property, and
    408   // can not be used as constructors.
    409   Handle<Map> function_without_prototype_map =
    410       CreateFunctionMap(DONT_ADD_PROTOTYPE);
    411   global_context()->set_function_without_prototype_map(
    412       *function_without_prototype_map);
    413 
    414   // Allocate the function map. This map is temporary, used only for processing
    415   // of builtins.
    416   // Later the map is replaced with writable prototype map, allocated below.
    417   Handle<Map> function_map = CreateFunctionMap(ADD_READONLY_PROTOTYPE);
    418   global_context()->set_function_map(*function_map);
    419 
    420   // The final map for functions. Writeable prototype.
    421   // This map is installed in MakeFunctionInstancePrototypeWritable.
    422   function_instance_map_writable_prototype_ =
    423       CreateFunctionMap(ADD_WRITEABLE_PROTOTYPE);
    424 
    425   Isolate* isolate = Isolate::Current();
    426   Factory* factory = isolate->factory();
    427   Heap* heap = isolate->heap();
    428 
    429   Handle<String> object_name = Handle<String>(heap->Object_symbol());
    430 
    431   {  // --- O b j e c t ---
    432     Handle<JSFunction> object_fun =
    433         factory->NewFunction(object_name, factory->null_value());
    434     Handle<Map> object_function_map =
    435         factory->NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize);
    436     object_fun->set_initial_map(*object_function_map);
    437     object_function_map->set_constructor(*object_fun);
    438 
    439     global_context()->set_object_function(*object_fun);
    440 
    441     // Allocate a new prototype for the object function.
    442     Handle<JSObject> prototype = factory->NewJSObject(
    443         isolate->object_function(),
    444         TENURED);
    445 
    446     global_context()->set_initial_object_prototype(*prototype);
    447     SetPrototype(object_fun, prototype);
    448     object_function_map->
    449       set_instance_descriptors(heap->empty_descriptor_array());
    450   }
    451 
    452   // Allocate the empty function as the prototype for function ECMAScript
    453   // 262 15.3.4.
    454   Handle<String> symbol = factory->LookupAsciiSymbol("Empty");
    455   Handle<JSFunction> empty_function =
    456       factory->NewFunctionWithoutPrototype(symbol, kNonStrictMode);
    457 
    458   // --- E m p t y ---
    459   Handle<Code> code =
    460       Handle<Code>(isolate->builtins()->builtin(
    461           Builtins::kEmptyFunction));
    462   empty_function->set_code(*code);
    463   empty_function->shared()->set_code(*code);
    464   Handle<String> source = factory->NewStringFromAscii(CStrVector("() {}"));
    465   Handle<Script> script = factory->NewScript(source);
    466   script->set_type(Smi::FromInt(Script::TYPE_NATIVE));
    467   empty_function->shared()->set_script(*script);
    468   empty_function->shared()->set_start_position(0);
    469   empty_function->shared()->set_end_position(source->length());
    470   empty_function->shared()->DontAdaptArguments();
    471 
    472   // Set prototypes for the function maps.
    473   global_context()->function_map()->set_prototype(*empty_function);
    474   global_context()->function_instance_map()->set_prototype(*empty_function);
    475   global_context()->function_without_prototype_map()->
    476       set_prototype(*empty_function);
    477   function_instance_map_writable_prototype_->set_prototype(*empty_function);
    478 
    479   // Allocate the function map first and then patch the prototype later
    480   Handle<Map> empty_fm = factory->CopyMapDropDescriptors(
    481       function_without_prototype_map);
    482   empty_fm->set_instance_descriptors(
    483       function_without_prototype_map->instance_descriptors());
    484   empty_fm->set_prototype(global_context()->object_function()->prototype());
    485   empty_function->set_map(*empty_fm);
    486   return empty_function;
    487 }
    488 
    489 
    490 Handle<DescriptorArray> Genesis::ComputeStrictFunctionInstanceDescriptor(
    491     PrototypePropertyMode prototypeMode,
    492     Handle<FixedArray> arguments,
    493     Handle<FixedArray> caller) {
    494   Factory* factory = Isolate::Current()->factory();
    495   Handle<DescriptorArray> descriptors =
    496       factory->NewDescriptorArray(prototypeMode == DONT_ADD_PROTOTYPE ? 4 : 5);
    497   PropertyAttributes attributes = static_cast<PropertyAttributes>(
    498       DONT_ENUM | DONT_DELETE | READ_ONLY);
    499 
    500   {  // length
    501     Handle<Proxy> proxy = factory->NewProxy(&Accessors::FunctionLength);
    502     CallbacksDescriptor d(*factory->length_symbol(), *proxy, attributes);
    503     descriptors->Set(0, &d);
    504   }
    505   {  // name
    506     Handle<Proxy> proxy = factory->NewProxy(&Accessors::FunctionName);
    507     CallbacksDescriptor d(*factory->name_symbol(), *proxy, attributes);
    508     descriptors->Set(1, &d);
    509   }
    510   {  // arguments
    511     CallbacksDescriptor d(*factory->arguments_symbol(), *arguments, attributes);
    512     descriptors->Set(2, &d);
    513   }
    514   {  // caller
    515     CallbacksDescriptor d(*factory->caller_symbol(), *caller, attributes);
    516     descriptors->Set(3, &d);
    517   }
    518 
    519   // prototype
    520   if (prototypeMode != DONT_ADD_PROTOTYPE) {
    521     if (prototypeMode == ADD_WRITEABLE_PROTOTYPE) {
    522       attributes = static_cast<PropertyAttributes>(attributes & ~READ_ONLY);
    523     }
    524     Handle<Proxy> proxy = factory->NewProxy(&Accessors::FunctionPrototype);
    525     CallbacksDescriptor d(*factory->prototype_symbol(), *proxy, attributes);
    526     descriptors->Set(4, &d);
    527   }
    528 
    529   descriptors->Sort();
    530   return descriptors;
    531 }
    532 
    533 
    534 // ECMAScript 5th Edition, 13.2.3
    535 Handle<JSFunction> Genesis::CreateThrowTypeErrorFunction(
    536     Builtins::Name builtin) {
    537   Isolate* isolate = Isolate::Current();
    538   Factory* factory = isolate->factory();
    539 
    540   Handle<String> name = factory->LookupAsciiSymbol("ThrowTypeError");
    541   Handle<JSFunction> throw_type_error =
    542       factory->NewFunctionWithoutPrototype(name, kStrictMode);
    543   Handle<Code> code = Handle<Code>(
    544       isolate->builtins()->builtin(builtin));
    545 
    546   throw_type_error->set_map(global_context()->strict_mode_function_map());
    547   throw_type_error->set_code(*code);
    548   throw_type_error->shared()->set_code(*code);
    549   throw_type_error->shared()->DontAdaptArguments();
    550 
    551   PreventExtensions(throw_type_error);
    552 
    553   return throw_type_error;
    554 }
    555 
    556 
    557 Handle<Map> Genesis::CreateStrictModeFunctionMap(
    558     PrototypePropertyMode prototype_mode,
    559     Handle<JSFunction> empty_function,
    560     Handle<FixedArray> arguments_callbacks,
    561     Handle<FixedArray> caller_callbacks) {
    562   Handle<Map> map = FACTORY->NewMap(JS_FUNCTION_TYPE, JSFunction::kSize);
    563   Handle<DescriptorArray> descriptors =
    564       ComputeStrictFunctionInstanceDescriptor(prototype_mode,
    565                                               arguments_callbacks,
    566                                               caller_callbacks);
    567   map->set_instance_descriptors(*descriptors);
    568   map->set_function_with_prototype(prototype_mode != DONT_ADD_PROTOTYPE);
    569   map->set_prototype(*empty_function);
    570   return map;
    571 }
    572 
    573 
    574 void Genesis::CreateStrictModeFunctionMaps(Handle<JSFunction> empty) {
    575   // Create the callbacks arrays for ThrowTypeError functions.
    576   // The get/set callacks are filled in after the maps are created below.
    577   Factory* factory = Isolate::Current()->factory();
    578   Handle<FixedArray> arguments = factory->NewFixedArray(2, TENURED);
    579   Handle<FixedArray> caller = factory->NewFixedArray(2, TENURED);
    580 
    581   // Allocate map for the strict mode function instances.
    582   Handle<Map> strict_mode_function_instance_map =
    583       CreateStrictModeFunctionMap(
    584           ADD_WRITEABLE_PROTOTYPE, empty, arguments, caller);
    585   global_context()->set_strict_mode_function_instance_map(
    586       *strict_mode_function_instance_map);
    587 
    588   // Allocate map for the prototype-less strict mode instances.
    589   Handle<Map> strict_mode_function_without_prototype_map =
    590       CreateStrictModeFunctionMap(
    591           DONT_ADD_PROTOTYPE, empty, arguments, caller);
    592   global_context()->set_strict_mode_function_without_prototype_map(
    593       *strict_mode_function_without_prototype_map);
    594 
    595   // Allocate map for the strict mode functions. This map is temporary, used
    596   // only for processing of builtins.
    597   // Later the map is replaced with writable prototype map, allocated below.
    598   Handle<Map> strict_mode_function_map =
    599       CreateStrictModeFunctionMap(
    600           ADD_READONLY_PROTOTYPE, empty, arguments, caller);
    601   global_context()->set_strict_mode_function_map(
    602       *strict_mode_function_map);
    603 
    604   // The final map for the strict mode functions. Writeable prototype.
    605   // This map is installed in MakeFunctionInstancePrototypeWritable.
    606   strict_mode_function_instance_map_writable_prototype_ =
    607       CreateStrictModeFunctionMap(
    608           ADD_WRITEABLE_PROTOTYPE, empty, arguments, caller);
    609 
    610   // Create the ThrowTypeError function instances.
    611   Handle<JSFunction> arguments_throw =
    612       CreateThrowTypeErrorFunction(Builtins::kStrictFunctionArguments);
    613   Handle<JSFunction> caller_throw =
    614       CreateThrowTypeErrorFunction(Builtins::kStrictFunctionCaller);
    615 
    616   // Complete the callback fixed arrays.
    617   arguments->set(0, *arguments_throw);
    618   arguments->set(1, *arguments_throw);
    619   caller->set(0, *caller_throw);
    620   caller->set(1, *caller_throw);
    621 }
    622 
    623 
    624 static void AddToWeakGlobalContextList(Context* context) {
    625   ASSERT(context->IsGlobalContext());
    626   Heap* heap = Isolate::Current()->heap();
    627 #ifdef DEBUG
    628   { // NOLINT
    629     ASSERT(context->get(Context::NEXT_CONTEXT_LINK)->IsUndefined());
    630     // Check that context is not in the list yet.
    631     for (Object* current = heap->global_contexts_list();
    632          !current->IsUndefined();
    633          current = Context::cast(current)->get(Context::NEXT_CONTEXT_LINK)) {
    634       ASSERT(current != context);
    635     }
    636   }
    637 #endif
    638   context->set(Context::NEXT_CONTEXT_LINK, heap->global_contexts_list());
    639   heap->set_global_contexts_list(context);
    640 }
    641 
    642 
    643 void Genesis::CreateRoots() {
    644   Isolate* isolate = Isolate::Current();
    645   // Allocate the global context FixedArray first and then patch the
    646   // closure and extension object later (we need the empty function
    647   // and the global object, but in order to create those, we need the
    648   // global context).
    649   global_context_ = Handle<Context>::cast(isolate->global_handles()->Create(
    650               *isolate->factory()->NewGlobalContext()));
    651   AddToWeakGlobalContextList(*global_context_);
    652   isolate->set_context(*global_context());
    653 
    654   // Allocate the message listeners object.
    655   {
    656     v8::NeanderArray listeners;
    657     global_context()->set_message_listeners(*listeners.value());
    658   }
    659 }
    660 
    661 
    662 Handle<JSGlobalProxy> Genesis::CreateNewGlobals(
    663     v8::Handle<v8::ObjectTemplate> global_template,
    664     Handle<Object> global_object,
    665     Handle<GlobalObject>* inner_global_out) {
    666   // The argument global_template aka data is an ObjectTemplateInfo.
    667   // It has a constructor pointer that points at global_constructor which is a
    668   // FunctionTemplateInfo.
    669   // The global_constructor is used to create or reinitialize the global_proxy.
    670   // The global_constructor also has a prototype_template pointer that points at
    671   // js_global_template which is an ObjectTemplateInfo.
    672   // That in turn has a constructor pointer that points at
    673   // js_global_constructor which is a FunctionTemplateInfo.
    674   // js_global_constructor is used to make js_global_function
    675   // js_global_function is used to make the new inner_global.
    676   //
    677   // --- G l o b a l ---
    678   // Step 1: Create a fresh inner JSGlobalObject.
    679   Handle<JSFunction> js_global_function;
    680   Handle<ObjectTemplateInfo> js_global_template;
    681   if (!global_template.IsEmpty()) {
    682     // Get prototype template of the global_template.
    683     Handle<ObjectTemplateInfo> data =
    684         v8::Utils::OpenHandle(*global_template);
    685     Handle<FunctionTemplateInfo> global_constructor =
    686         Handle<FunctionTemplateInfo>(
    687             FunctionTemplateInfo::cast(data->constructor()));
    688     Handle<Object> proto_template(global_constructor->prototype_template());
    689     if (!proto_template->IsUndefined()) {
    690       js_global_template =
    691           Handle<ObjectTemplateInfo>::cast(proto_template);
    692     }
    693   }
    694 
    695   Isolate* isolate = Isolate::Current();
    696   Factory* factory = isolate->factory();
    697   Heap* heap = isolate->heap();
    698 
    699   if (js_global_template.is_null()) {
    700     Handle<String> name = Handle<String>(heap->empty_symbol());
    701     Handle<Code> code = Handle<Code>(isolate->builtins()->builtin(
    702         Builtins::kIllegal));
    703     js_global_function =
    704         factory->NewFunction(name, JS_GLOBAL_OBJECT_TYPE,
    705                              JSGlobalObject::kSize, code, true);
    706     // Change the constructor property of the prototype of the
    707     // hidden global function to refer to the Object function.
    708     Handle<JSObject> prototype =
    709         Handle<JSObject>(
    710             JSObject::cast(js_global_function->instance_prototype()));
    711     SetLocalPropertyNoThrow(
    712         prototype,
    713         factory->constructor_symbol(),
    714         isolate->object_function(),
    715         NONE);
    716   } else {
    717     Handle<FunctionTemplateInfo> js_global_constructor(
    718         FunctionTemplateInfo::cast(js_global_template->constructor()));
    719     js_global_function =
    720         factory->CreateApiFunction(js_global_constructor,
    721                                    factory->InnerGlobalObject);
    722   }
    723 
    724   js_global_function->initial_map()->set_is_hidden_prototype();
    725   Handle<GlobalObject> inner_global =
    726       factory->NewGlobalObject(js_global_function);
    727   if (inner_global_out != NULL) {
    728     *inner_global_out = inner_global;
    729   }
    730 
    731   // Step 2: create or re-initialize the global proxy object.
    732   Handle<JSFunction> global_proxy_function;
    733   if (global_template.IsEmpty()) {
    734     Handle<String> name = Handle<String>(heap->empty_symbol());
    735     Handle<Code> code = Handle<Code>(isolate->builtins()->builtin(
    736         Builtins::kIllegal));
    737     global_proxy_function =
    738         factory->NewFunction(name, JS_GLOBAL_PROXY_TYPE,
    739                              JSGlobalProxy::kSize, code, true);
    740   } else {
    741     Handle<ObjectTemplateInfo> data =
    742         v8::Utils::OpenHandle(*global_template);
    743     Handle<FunctionTemplateInfo> global_constructor(
    744             FunctionTemplateInfo::cast(data->constructor()));
    745     global_proxy_function =
    746         factory->CreateApiFunction(global_constructor,
    747                                    factory->OuterGlobalObject);
    748   }
    749 
    750   Handle<String> global_name = factory->LookupAsciiSymbol("global");
    751   global_proxy_function->shared()->set_instance_class_name(*global_name);
    752   global_proxy_function->initial_map()->set_is_access_check_needed(true);
    753 
    754   // Set global_proxy.__proto__ to js_global after ConfigureGlobalObjects
    755   // Return the global proxy.
    756 
    757   if (global_object.location() != NULL) {
    758     ASSERT(global_object->IsJSGlobalProxy());
    759     return ReinitializeJSGlobalProxy(
    760         global_proxy_function,
    761         Handle<JSGlobalProxy>::cast(global_object));
    762   } else {
    763     return Handle<JSGlobalProxy>::cast(
    764         factory->NewJSObject(global_proxy_function, TENURED));
    765   }
    766 }
    767 
    768 
    769 void Genesis::HookUpGlobalProxy(Handle<GlobalObject> inner_global,
    770                                 Handle<JSGlobalProxy> global_proxy) {
    771   // Set the global context for the global object.
    772   inner_global->set_global_context(*global_context());
    773   inner_global->set_global_receiver(*global_proxy);
    774   global_proxy->set_context(*global_context());
    775   global_context()->set_global_proxy(*global_proxy);
    776 }
    777 
    778 
    779 void Genesis::HookUpInnerGlobal(Handle<GlobalObject> inner_global) {
    780   Handle<GlobalObject> inner_global_from_snapshot(
    781       GlobalObject::cast(global_context_->extension()));
    782   Handle<JSBuiltinsObject> builtins_global(global_context_->builtins());
    783   global_context_->set_extension(*inner_global);
    784   global_context_->set_global(*inner_global);
    785   global_context_->set_security_token(*inner_global);
    786   static const PropertyAttributes attributes =
    787       static_cast<PropertyAttributes>(READ_ONLY | DONT_DELETE);
    788   ForceSetProperty(builtins_global,
    789                    FACTORY->LookupAsciiSymbol("global"),
    790                    inner_global,
    791                    attributes);
    792   // Setup the reference from the global object to the builtins object.
    793   JSGlobalObject::cast(*inner_global)->set_builtins(*builtins_global);
    794   TransferNamedProperties(inner_global_from_snapshot, inner_global);
    795   TransferIndexedProperties(inner_global_from_snapshot, inner_global);
    796 }
    797 
    798 
    799 // This is only called if we are not using snapshots.  The equivalent
    800 // work in the snapshot case is done in HookUpInnerGlobal.
    801 void Genesis::InitializeGlobal(Handle<GlobalObject> inner_global,
    802                                Handle<JSFunction> empty_function) {
    803   // --- G l o b a l   C o n t e x t ---
    804   // Use the empty function as closure (no scope info).
    805   global_context()->set_closure(*empty_function);
    806   global_context()->set_fcontext(*global_context());
    807   global_context()->set_previous(NULL);
    808   // Set extension and global object.
    809   global_context()->set_extension(*inner_global);
    810   global_context()->set_global(*inner_global);
    811   // Security setup: Set the security token of the global object to
    812   // its the inner global. This makes the security check between two
    813   // different contexts fail by default even in case of global
    814   // object reinitialization.
    815   global_context()->set_security_token(*inner_global);
    816 
    817   Isolate* isolate = Isolate::Current();
    818   Factory* factory = isolate->factory();
    819   Heap* heap = isolate->heap();
    820 
    821   Handle<String> object_name = Handle<String>(heap->Object_symbol());
    822   SetLocalPropertyNoThrow(inner_global, object_name,
    823                           isolate->object_function(), DONT_ENUM);
    824 
    825   Handle<JSObject> global = Handle<JSObject>(global_context()->global());
    826 
    827   // Install global Function object
    828   InstallFunction(global, "Function", JS_FUNCTION_TYPE, JSFunction::kSize,
    829                   empty_function, Builtins::kIllegal, true);  // ECMA native.
    830 
    831   {  // --- A r r a y ---
    832     Handle<JSFunction> array_function =
    833         InstallFunction(global, "Array", JS_ARRAY_TYPE, JSArray::kSize,
    834                         isolate->initial_object_prototype(),
    835                         Builtins::kArrayCode, true);
    836     array_function->shared()->set_construct_stub(
    837         isolate->builtins()->builtin(Builtins::kArrayConstructCode));
    838     array_function->shared()->DontAdaptArguments();
    839 
    840     // This seems a bit hackish, but we need to make sure Array.length
    841     // is 1.
    842     array_function->shared()->set_length(1);
    843     Handle<DescriptorArray> array_descriptors =
    844         factory->CopyAppendProxyDescriptor(
    845             factory->empty_descriptor_array(),
    846             factory->length_symbol(),
    847             factory->NewProxy(&Accessors::ArrayLength),
    848             static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE));
    849 
    850     // Cache the fast JavaScript array map
    851     global_context()->set_js_array_map(array_function->initial_map());
    852     global_context()->js_array_map()->set_instance_descriptors(
    853         *array_descriptors);
    854     // array_function is used internally. JS code creating array object should
    855     // search for the 'Array' property on the global object and use that one
    856     // as the constructor. 'Array' property on a global object can be
    857     // overwritten by JS code.
    858     global_context()->set_array_function(*array_function);
    859   }
    860 
    861   {  // --- N u m b e r ---
    862     Handle<JSFunction> number_fun =
    863         InstallFunction(global, "Number", JS_VALUE_TYPE, JSValue::kSize,
    864                         isolate->initial_object_prototype(),
    865                         Builtins::kIllegal, true);
    866     global_context()->set_number_function(*number_fun);
    867   }
    868 
    869   {  // --- B o o l e a n ---
    870     Handle<JSFunction> boolean_fun =
    871         InstallFunction(global, "Boolean", JS_VALUE_TYPE, JSValue::kSize,
    872                         isolate->initial_object_prototype(),
    873                         Builtins::kIllegal, true);
    874     global_context()->set_boolean_function(*boolean_fun);
    875   }
    876 
    877   {  // --- S t r i n g ---
    878     Handle<JSFunction> string_fun =
    879         InstallFunction(global, "String", JS_VALUE_TYPE, JSValue::kSize,
    880                         isolate->initial_object_prototype(),
    881                         Builtins::kIllegal, true);
    882     string_fun->shared()->set_construct_stub(
    883         isolate->builtins()->builtin(Builtins::kStringConstructCode));
    884     global_context()->set_string_function(*string_fun);
    885     // Add 'length' property to strings.
    886     Handle<DescriptorArray> string_descriptors =
    887         factory->CopyAppendProxyDescriptor(
    888             factory->empty_descriptor_array(),
    889             factory->length_symbol(),
    890             factory->NewProxy(&Accessors::StringLength),
    891             static_cast<PropertyAttributes>(DONT_ENUM |
    892                                             DONT_DELETE |
    893                                             READ_ONLY));
    894 
    895     Handle<Map> string_map =
    896         Handle<Map>(global_context()->string_function()->initial_map());
    897     string_map->set_instance_descriptors(*string_descriptors);
    898   }
    899 
    900   {  // --- D a t e ---
    901     // Builtin functions for Date.prototype.
    902     Handle<JSFunction> date_fun =
    903         InstallFunction(global, "Date", JS_VALUE_TYPE, JSValue::kSize,
    904                         isolate->initial_object_prototype(),
    905                         Builtins::kIllegal, true);
    906 
    907     global_context()->set_date_function(*date_fun);
    908   }
    909 
    910 
    911   {  // -- R e g E x p
    912     // Builtin functions for RegExp.prototype.
    913     Handle<JSFunction> regexp_fun =
    914         InstallFunction(global, "RegExp", JS_REGEXP_TYPE, JSRegExp::kSize,
    915                         isolate->initial_object_prototype(),
    916                         Builtins::kIllegal, true);
    917     global_context()->set_regexp_function(*regexp_fun);
    918 
    919     ASSERT(regexp_fun->has_initial_map());
    920     Handle<Map> initial_map(regexp_fun->initial_map());
    921 
    922     ASSERT_EQ(0, initial_map->inobject_properties());
    923 
    924     Handle<DescriptorArray> descriptors = factory->NewDescriptorArray(5);
    925     PropertyAttributes final =
    926         static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY);
    927     int enum_index = 0;
    928     {
    929       // ECMA-262, section 15.10.7.1.
    930       FieldDescriptor field(heap->source_symbol(),
    931                             JSRegExp::kSourceFieldIndex,
    932                             final,
    933                             enum_index++);
    934       descriptors->Set(0, &field);
    935     }
    936     {
    937       // ECMA-262, section 15.10.7.2.
    938       FieldDescriptor field(heap->global_symbol(),
    939                             JSRegExp::kGlobalFieldIndex,
    940                             final,
    941                             enum_index++);
    942       descriptors->Set(1, &field);
    943     }
    944     {
    945       // ECMA-262, section 15.10.7.3.
    946       FieldDescriptor field(heap->ignore_case_symbol(),
    947                             JSRegExp::kIgnoreCaseFieldIndex,
    948                             final,
    949                             enum_index++);
    950       descriptors->Set(2, &field);
    951     }
    952     {
    953       // ECMA-262, section 15.10.7.4.
    954       FieldDescriptor field(heap->multiline_symbol(),
    955                             JSRegExp::kMultilineFieldIndex,
    956                             final,
    957                             enum_index++);
    958       descriptors->Set(3, &field);
    959     }
    960     {
    961       // ECMA-262, section 15.10.7.5.
    962       PropertyAttributes writable =
    963           static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE);
    964       FieldDescriptor field(heap->last_index_symbol(),
    965                             JSRegExp::kLastIndexFieldIndex,
    966                             writable,
    967                             enum_index++);
    968       descriptors->Set(4, &field);
    969     }
    970     descriptors->SetNextEnumerationIndex(enum_index);
    971     descriptors->Sort();
    972 
    973     initial_map->set_inobject_properties(5);
    974     initial_map->set_pre_allocated_property_fields(5);
    975     initial_map->set_unused_property_fields(0);
    976     initial_map->set_instance_size(
    977         initial_map->instance_size() + 5 * kPointerSize);
    978     initial_map->set_instance_descriptors(*descriptors);
    979     initial_map->set_visitor_id(StaticVisitorBase::GetVisitorId(*initial_map));
    980   }
    981 
    982   {  // -- J S O N
    983     Handle<String> name = factory->NewStringFromAscii(CStrVector("JSON"));
    984     Handle<JSFunction> cons = factory->NewFunction(
    985         name,
    986         factory->the_hole_value());
    987     cons->SetInstancePrototype(global_context()->initial_object_prototype());
    988     cons->SetInstanceClassName(*name);
    989     Handle<JSObject> json_object = factory->NewJSObject(cons, TENURED);
    990     ASSERT(json_object->IsJSObject());
    991     SetLocalPropertyNoThrow(global, name, json_object, DONT_ENUM);
    992     global_context()->set_json_object(*json_object);
    993   }
    994 
    995   {  // --- arguments_boilerplate_
    996     // Make sure we can recognize argument objects at runtime.
    997     // This is done by introducing an anonymous function with
    998     // class_name equals 'Arguments'.
    999     Handle<String> symbol = factory->LookupAsciiSymbol("Arguments");
   1000     Handle<Code> code = Handle<Code>(
   1001         isolate->builtins()->builtin(Builtins::kIllegal));
   1002     Handle<JSObject> prototype =
   1003         Handle<JSObject>(
   1004             JSObject::cast(global_context()->object_function()->prototype()));
   1005 
   1006     Handle<JSFunction> function =
   1007         factory->NewFunctionWithPrototype(symbol,
   1008                                           JS_OBJECT_TYPE,
   1009                                           JSObject::kHeaderSize,
   1010                                           prototype,
   1011                                           code,
   1012                                           false);
   1013     ASSERT(!function->has_initial_map());
   1014     function->shared()->set_instance_class_name(*symbol);
   1015     function->shared()->set_expected_nof_properties(2);
   1016     Handle<JSObject> result = factory->NewJSObject(function);
   1017 
   1018     global_context()->set_arguments_boilerplate(*result);
   1019     // Note: length must be added as the first property and
   1020     //       callee must be added as the second property.
   1021     SetLocalPropertyNoThrow(result, factory->length_symbol(),
   1022                             factory->undefined_value(),
   1023                             DONT_ENUM);
   1024     SetLocalPropertyNoThrow(result, factory->callee_symbol(),
   1025                             factory->undefined_value(),
   1026                             DONT_ENUM);
   1027 
   1028 #ifdef DEBUG
   1029     LookupResult lookup;
   1030     result->LocalLookup(heap->callee_symbol(), &lookup);
   1031     ASSERT(lookup.IsProperty() && (lookup.type() == FIELD));
   1032     ASSERT(lookup.GetFieldIndex() == Heap::kArgumentsCalleeIndex);
   1033 
   1034     result->LocalLookup(heap->length_symbol(), &lookup);
   1035     ASSERT(lookup.IsProperty() && (lookup.type() == FIELD));
   1036     ASSERT(lookup.GetFieldIndex() == Heap::kArgumentsLengthIndex);
   1037 
   1038     ASSERT(result->map()->inobject_properties() > Heap::kArgumentsCalleeIndex);
   1039     ASSERT(result->map()->inobject_properties() > Heap::kArgumentsLengthIndex);
   1040 
   1041     // Check the state of the object.
   1042     ASSERT(result->HasFastProperties());
   1043     ASSERT(result->HasFastElements());
   1044 #endif
   1045   }
   1046 
   1047   {  // --- strict mode arguments boilerplate
   1048     const PropertyAttributes attributes =
   1049       static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY);
   1050 
   1051     // Create the ThrowTypeError functions.
   1052     Handle<FixedArray> callee = factory->NewFixedArray(2, TENURED);
   1053     Handle<FixedArray> caller = factory->NewFixedArray(2, TENURED);
   1054 
   1055     Handle<JSFunction> callee_throw =
   1056         CreateThrowTypeErrorFunction(Builtins::kStrictArgumentsCallee);
   1057     Handle<JSFunction> caller_throw =
   1058         CreateThrowTypeErrorFunction(Builtins::kStrictArgumentsCaller);
   1059 
   1060     // Install the ThrowTypeError functions.
   1061     callee->set(0, *callee_throw);
   1062     callee->set(1, *callee_throw);
   1063     caller->set(0, *caller_throw);
   1064     caller->set(1, *caller_throw);
   1065 
   1066     // Create the descriptor array for the arguments object.
   1067     Handle<DescriptorArray> descriptors = factory->NewDescriptorArray(3);
   1068     {  // length
   1069       FieldDescriptor d(*factory->length_symbol(), 0, DONT_ENUM);
   1070       descriptors->Set(0, &d);
   1071     }
   1072     {  // callee
   1073       CallbacksDescriptor d(*factory->callee_symbol(), *callee, attributes);
   1074       descriptors->Set(1, &d);
   1075     }
   1076     {  // caller
   1077       CallbacksDescriptor d(*factory->caller_symbol(), *caller, attributes);
   1078       descriptors->Set(2, &d);
   1079     }
   1080     descriptors->Sort();
   1081 
   1082     // Create the map. Allocate one in-object field for length.
   1083     Handle<Map> map = factory->NewMap(JS_OBJECT_TYPE,
   1084                                       Heap::kArgumentsObjectSizeStrict);
   1085     map->set_instance_descriptors(*descriptors);
   1086     map->set_function_with_prototype(true);
   1087     map->set_prototype(global_context()->object_function()->prototype());
   1088     map->set_pre_allocated_property_fields(1);
   1089     map->set_inobject_properties(1);
   1090 
   1091     // Copy constructor from the non-strict arguments boilerplate.
   1092     map->set_constructor(
   1093       global_context()->arguments_boilerplate()->map()->constructor());
   1094 
   1095     // Allocate the arguments boilerplate object.
   1096     Handle<JSObject> result = factory->NewJSObjectFromMap(map);
   1097     global_context()->set_strict_mode_arguments_boilerplate(*result);
   1098 
   1099     // Add length property only for strict mode boilerplate.
   1100     SetLocalPropertyNoThrow(result, factory->length_symbol(),
   1101                             factory->undefined_value(),
   1102                             DONT_ENUM);
   1103 
   1104 #ifdef DEBUG
   1105     LookupResult lookup;
   1106     result->LocalLookup(heap->length_symbol(), &lookup);
   1107     ASSERT(lookup.IsProperty() && (lookup.type() == FIELD));
   1108     ASSERT(lookup.GetFieldIndex() == Heap::kArgumentsLengthIndex);
   1109 
   1110     ASSERT(result->map()->inobject_properties() > Heap::kArgumentsLengthIndex);
   1111 
   1112     // Check the state of the object.
   1113     ASSERT(result->HasFastProperties());
   1114     ASSERT(result->HasFastElements());
   1115 #endif
   1116   }
   1117 
   1118   {  // --- context extension
   1119     // Create a function for the context extension objects.
   1120     Handle<Code> code = Handle<Code>(
   1121         isolate->builtins()->builtin(Builtins::kIllegal));
   1122     Handle<JSFunction> context_extension_fun =
   1123         factory->NewFunction(factory->empty_symbol(),
   1124                              JS_CONTEXT_EXTENSION_OBJECT_TYPE,
   1125                              JSObject::kHeaderSize,
   1126                              code,
   1127                              true);
   1128 
   1129     Handle<String> name = factory->LookupAsciiSymbol("context_extension");
   1130     context_extension_fun->shared()->set_instance_class_name(*name);
   1131     global_context()->set_context_extension_function(*context_extension_fun);
   1132   }
   1133 
   1134 
   1135   {
   1136     // Setup the call-as-function delegate.
   1137     Handle<Code> code =
   1138         Handle<Code>(isolate->builtins()->builtin(
   1139             Builtins::kHandleApiCallAsFunction));
   1140     Handle<JSFunction> delegate =
   1141         factory->NewFunction(factory->empty_symbol(), JS_OBJECT_TYPE,
   1142                              JSObject::kHeaderSize, code, true);
   1143     global_context()->set_call_as_function_delegate(*delegate);
   1144     delegate->shared()->DontAdaptArguments();
   1145   }
   1146 
   1147   {
   1148     // Setup the call-as-constructor delegate.
   1149     Handle<Code> code =
   1150         Handle<Code>(isolate->builtins()->builtin(
   1151             Builtins::kHandleApiCallAsConstructor));
   1152     Handle<JSFunction> delegate =
   1153         factory->NewFunction(factory->empty_symbol(), JS_OBJECT_TYPE,
   1154                              JSObject::kHeaderSize, code, true);
   1155     global_context()->set_call_as_constructor_delegate(*delegate);
   1156     delegate->shared()->DontAdaptArguments();
   1157   }
   1158 
   1159   // Initialize the out of memory slot.
   1160   global_context()->set_out_of_memory(heap->false_value());
   1161 
   1162   // Initialize the data slot.
   1163   global_context()->set_data(heap->undefined_value());
   1164 }
   1165 
   1166 
   1167 bool Genesis::CompileBuiltin(int index) {
   1168   Vector<const char> name = Natives::GetScriptName(index);
   1169   Handle<String> source_code =
   1170       Isolate::Current()->bootstrapper()->NativesSourceLookup(index);
   1171   return CompileNative(name, source_code);
   1172 }
   1173 
   1174 
   1175 bool Genesis::CompileNative(Vector<const char> name, Handle<String> source) {
   1176   HandleScope scope;
   1177   Isolate* isolate = Isolate::Current();
   1178 #ifdef ENABLE_DEBUGGER_SUPPORT
   1179   isolate->debugger()->set_compiling_natives(true);
   1180 #endif
   1181   bool result = CompileScriptCached(name,
   1182                                     source,
   1183                                     NULL,
   1184                                     NULL,
   1185                                     Handle<Context>(isolate->context()),
   1186                                     true);
   1187   ASSERT(isolate->has_pending_exception() != result);
   1188   if (!result) isolate->clear_pending_exception();
   1189 #ifdef ENABLE_DEBUGGER_SUPPORT
   1190   isolate->debugger()->set_compiling_natives(false);
   1191 #endif
   1192   return result;
   1193 }
   1194 
   1195 
   1196 bool Genesis::CompileScriptCached(Vector<const char> name,
   1197                                   Handle<String> source,
   1198                                   SourceCodeCache* cache,
   1199                                   v8::Extension* extension,
   1200                                   Handle<Context> top_context,
   1201                                   bool use_runtime_context) {
   1202   Factory* factory = Isolate::Current()->factory();
   1203   HandleScope scope;
   1204   Handle<SharedFunctionInfo> function_info;
   1205 
   1206   // If we can't find the function in the cache, we compile a new
   1207   // function and insert it into the cache.
   1208   if (cache == NULL || !cache->Lookup(name, &function_info)) {
   1209     ASSERT(source->IsAsciiRepresentation());
   1210     Handle<String> script_name = factory->NewStringFromUtf8(name);
   1211     function_info = Compiler::Compile(
   1212         source,
   1213         script_name,
   1214         0,
   1215         0,
   1216         extension,
   1217         NULL,
   1218         Handle<String>::null(),
   1219         use_runtime_context ? NATIVES_CODE : NOT_NATIVES_CODE);
   1220     if (function_info.is_null()) return false;
   1221     if (cache != NULL) cache->Add(name, function_info);
   1222   }
   1223 
   1224   // Setup the function context. Conceptually, we should clone the
   1225   // function before overwriting the context but since we're in a
   1226   // single-threaded environment it is not strictly necessary.
   1227   ASSERT(top_context->IsGlobalContext());
   1228   Handle<Context> context =
   1229       Handle<Context>(use_runtime_context
   1230                       ? Handle<Context>(top_context->runtime_context())
   1231                       : top_context);
   1232   Handle<JSFunction> fun =
   1233       factory->NewFunctionFromSharedFunctionInfo(function_info, context);
   1234 
   1235   // Call function using either the runtime object or the global
   1236   // object as the receiver. Provide no parameters.
   1237   Handle<Object> receiver =
   1238       Handle<Object>(use_runtime_context
   1239                      ? top_context->builtins()
   1240                      : top_context->global());
   1241   bool has_pending_exception;
   1242   Handle<Object> result =
   1243       Execution::Call(fun, receiver, 0, NULL, &has_pending_exception);
   1244   if (has_pending_exception) return false;
   1245   return true;
   1246 }
   1247 
   1248 
   1249 #define INSTALL_NATIVE(Type, name, var)                                        \
   1250   Handle<String> var##_name = factory->LookupAsciiSymbol(name);                \
   1251   Object* var##_native =                                                       \
   1252       global_context()->builtins()->GetPropertyNoExceptionThrown(*var##_name); \
   1253   global_context()->set_##var(Type::cast(var##_native));
   1254 
   1255 
   1256 void Genesis::InstallNativeFunctions() {
   1257   Factory* factory = Isolate::Current()->factory();
   1258   HandleScope scope;
   1259   INSTALL_NATIVE(JSFunction, "CreateDate", create_date_fun);
   1260   INSTALL_NATIVE(JSFunction, "ToNumber", to_number_fun);
   1261   INSTALL_NATIVE(JSFunction, "ToString", to_string_fun);
   1262   INSTALL_NATIVE(JSFunction, "ToDetailString", to_detail_string_fun);
   1263   INSTALL_NATIVE(JSFunction, "ToObject", to_object_fun);
   1264   INSTALL_NATIVE(JSFunction, "ToInteger", to_integer_fun);
   1265   INSTALL_NATIVE(JSFunction, "ToUint32", to_uint32_fun);
   1266   INSTALL_NATIVE(JSFunction, "ToInt32", to_int32_fun);
   1267   INSTALL_NATIVE(JSFunction, "GlobalEval", global_eval_fun);
   1268   INSTALL_NATIVE(JSFunction, "Instantiate", instantiate_fun);
   1269   INSTALL_NATIVE(JSFunction, "ConfigureTemplateInstance",
   1270                  configure_instance_fun);
   1271   INSTALL_NATIVE(JSFunction, "GetStackTraceLine", get_stack_trace_line_fun);
   1272   INSTALL_NATIVE(JSObject, "functionCache", function_cache);
   1273 }
   1274 
   1275 #undef INSTALL_NATIVE
   1276 
   1277 
   1278 bool Genesis::InstallNatives() {
   1279   HandleScope scope;
   1280   Isolate* isolate = Isolate::Current();
   1281   Factory* factory = isolate->factory();
   1282   Heap* heap = isolate->heap();
   1283 
   1284   // Create a function for the builtins object. Allocate space for the
   1285   // JavaScript builtins, a reference to the builtins object
   1286   // (itself) and a reference to the global_context directly in the object.
   1287   Handle<Code> code = Handle<Code>(
   1288       isolate->builtins()->builtin(Builtins::kIllegal));
   1289   Handle<JSFunction> builtins_fun =
   1290       factory->NewFunction(factory->empty_symbol(), JS_BUILTINS_OBJECT_TYPE,
   1291                            JSBuiltinsObject::kSize, code, true);
   1292 
   1293   Handle<String> name = factory->LookupAsciiSymbol("builtins");
   1294   builtins_fun->shared()->set_instance_class_name(*name);
   1295 
   1296   // Allocate the builtins object.
   1297   Handle<JSBuiltinsObject> builtins =
   1298       Handle<JSBuiltinsObject>::cast(factory->NewGlobalObject(builtins_fun));
   1299   builtins->set_builtins(*builtins);
   1300   builtins->set_global_context(*global_context());
   1301   builtins->set_global_receiver(*builtins);
   1302 
   1303   // Setup the 'global' properties of the builtins object. The
   1304   // 'global' property that refers to the global object is the only
   1305   // way to get from code running in the builtins context to the
   1306   // global object.
   1307   static const PropertyAttributes attributes =
   1308       static_cast<PropertyAttributes>(READ_ONLY | DONT_DELETE);
   1309   Handle<String> global_symbol = factory->LookupAsciiSymbol("global");
   1310   Handle<Object> global_obj(global_context()->global());
   1311   SetLocalPropertyNoThrow(builtins, global_symbol, global_obj, attributes);
   1312 
   1313   // Setup the reference from the global object to the builtins object.
   1314   JSGlobalObject::cast(global_context()->global())->set_builtins(*builtins);
   1315 
   1316   // Create a bridge function that has context in the global context.
   1317   Handle<JSFunction> bridge =
   1318       factory->NewFunction(factory->empty_symbol(), factory->undefined_value());
   1319   ASSERT(bridge->context() == *isolate->global_context());
   1320 
   1321   // Allocate the builtins context.
   1322   Handle<Context> context =
   1323     factory->NewFunctionContext(Context::MIN_CONTEXT_SLOTS, bridge);
   1324   context->set_global(*builtins);  // override builtins global object
   1325 
   1326   global_context()->set_runtime_context(*context);
   1327 
   1328   {  // -- S c r i p t
   1329     // Builtin functions for Script.
   1330     Handle<JSFunction> script_fun =
   1331         InstallFunction(builtins, "Script", JS_VALUE_TYPE, JSValue::kSize,
   1332                         isolate->initial_object_prototype(),
   1333                         Builtins::kIllegal, false);
   1334     Handle<JSObject> prototype =
   1335         factory->NewJSObject(isolate->object_function(), TENURED);
   1336     SetPrototype(script_fun, prototype);
   1337     global_context()->set_script_function(*script_fun);
   1338 
   1339     // Add 'source' and 'data' property to scripts.
   1340     PropertyAttributes common_attributes =
   1341         static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY);
   1342     Handle<Proxy> proxy_source = factory->NewProxy(&Accessors::ScriptSource);
   1343     Handle<DescriptorArray> script_descriptors =
   1344         factory->CopyAppendProxyDescriptor(
   1345             factory->empty_descriptor_array(),
   1346             factory->LookupAsciiSymbol("source"),
   1347             proxy_source,
   1348             common_attributes);
   1349     Handle<Proxy> proxy_name = factory->NewProxy(&Accessors::ScriptName);
   1350     script_descriptors =
   1351         factory->CopyAppendProxyDescriptor(
   1352             script_descriptors,
   1353             factory->LookupAsciiSymbol("name"),
   1354             proxy_name,
   1355             common_attributes);
   1356     Handle<Proxy> proxy_id = factory->NewProxy(&Accessors::ScriptId);
   1357     script_descriptors =
   1358         factory->CopyAppendProxyDescriptor(
   1359             script_descriptors,
   1360             factory->LookupAsciiSymbol("id"),
   1361             proxy_id,
   1362             common_attributes);
   1363     Handle<Proxy> proxy_line_offset =
   1364         factory->NewProxy(&Accessors::ScriptLineOffset);
   1365     script_descriptors =
   1366         factory->CopyAppendProxyDescriptor(
   1367             script_descriptors,
   1368             factory->LookupAsciiSymbol("line_offset"),
   1369             proxy_line_offset,
   1370             common_attributes);
   1371     Handle<Proxy> proxy_column_offset =
   1372         factory->NewProxy(&Accessors::ScriptColumnOffset);
   1373     script_descriptors =
   1374         factory->CopyAppendProxyDescriptor(
   1375             script_descriptors,
   1376             factory->LookupAsciiSymbol("column_offset"),
   1377             proxy_column_offset,
   1378             common_attributes);
   1379     Handle<Proxy> proxy_data = factory->NewProxy(&Accessors::ScriptData);
   1380     script_descriptors =
   1381         factory->CopyAppendProxyDescriptor(
   1382             script_descriptors,
   1383             factory->LookupAsciiSymbol("data"),
   1384             proxy_data,
   1385             common_attributes);
   1386     Handle<Proxy> proxy_type = factory->NewProxy(&Accessors::ScriptType);
   1387     script_descriptors =
   1388         factory->CopyAppendProxyDescriptor(
   1389             script_descriptors,
   1390             factory->LookupAsciiSymbol("type"),
   1391             proxy_type,
   1392             common_attributes);
   1393     Handle<Proxy> proxy_compilation_type =
   1394         factory->NewProxy(&Accessors::ScriptCompilationType);
   1395     script_descriptors =
   1396         factory->CopyAppendProxyDescriptor(
   1397             script_descriptors,
   1398             factory->LookupAsciiSymbol("compilation_type"),
   1399             proxy_compilation_type,
   1400             common_attributes);
   1401     Handle<Proxy> proxy_line_ends =
   1402         factory->NewProxy(&Accessors::ScriptLineEnds);
   1403     script_descriptors =
   1404         factory->CopyAppendProxyDescriptor(
   1405             script_descriptors,
   1406             factory->LookupAsciiSymbol("line_ends"),
   1407             proxy_line_ends,
   1408             common_attributes);
   1409     Handle<Proxy> proxy_context_data =
   1410         factory->NewProxy(&Accessors::ScriptContextData);
   1411     script_descriptors =
   1412         factory->CopyAppendProxyDescriptor(
   1413             script_descriptors,
   1414             factory->LookupAsciiSymbol("context_data"),
   1415             proxy_context_data,
   1416             common_attributes);
   1417     Handle<Proxy> proxy_eval_from_script =
   1418         factory->NewProxy(&Accessors::ScriptEvalFromScript);
   1419     script_descriptors =
   1420         factory->CopyAppendProxyDescriptor(
   1421             script_descriptors,
   1422             factory->LookupAsciiSymbol("eval_from_script"),
   1423             proxy_eval_from_script,
   1424             common_attributes);
   1425     Handle<Proxy> proxy_eval_from_script_position =
   1426         factory->NewProxy(&Accessors::ScriptEvalFromScriptPosition);
   1427     script_descriptors =
   1428         factory->CopyAppendProxyDescriptor(
   1429             script_descriptors,
   1430             factory->LookupAsciiSymbol("eval_from_script_position"),
   1431             proxy_eval_from_script_position,
   1432             common_attributes);
   1433     Handle<Proxy> proxy_eval_from_function_name =
   1434         factory->NewProxy(&Accessors::ScriptEvalFromFunctionName);
   1435     script_descriptors =
   1436         factory->CopyAppendProxyDescriptor(
   1437             script_descriptors,
   1438             factory->LookupAsciiSymbol("eval_from_function_name"),
   1439             proxy_eval_from_function_name,
   1440             common_attributes);
   1441 
   1442     Handle<Map> script_map = Handle<Map>(script_fun->initial_map());
   1443     script_map->set_instance_descriptors(*script_descriptors);
   1444 
   1445     // Allocate the empty script.
   1446     Handle<Script> script = factory->NewScript(factory->empty_string());
   1447     script->set_type(Smi::FromInt(Script::TYPE_NATIVE));
   1448     heap->public_set_empty_script(*script);
   1449   }
   1450   {
   1451     // Builtin function for OpaqueReference -- a JSValue-based object,
   1452     // that keeps its field isolated from JavaScript code. It may store
   1453     // objects, that JavaScript code may not access.
   1454     Handle<JSFunction> opaque_reference_fun =
   1455         InstallFunction(builtins, "OpaqueReference", JS_VALUE_TYPE,
   1456                         JSValue::kSize,
   1457                         isolate->initial_object_prototype(),
   1458                         Builtins::kIllegal, false);
   1459     Handle<JSObject> prototype =
   1460         factory->NewJSObject(isolate->object_function(), TENURED);
   1461     SetPrototype(opaque_reference_fun, prototype);
   1462     global_context()->set_opaque_reference_function(*opaque_reference_fun);
   1463   }
   1464 
   1465   {  // --- I n t e r n a l   A r r a y ---
   1466     // An array constructor on the builtins object that works like
   1467     // the public Array constructor, except that its prototype
   1468     // doesn't inherit from Object.prototype.
   1469     // To be used only for internal work by builtins. Instances
   1470     // must not be leaked to user code.
   1471     // Only works correctly when called as a constructor. The normal
   1472     // Array code uses Array.prototype as prototype when called as
   1473     // a function.
   1474     Handle<JSFunction> array_function =
   1475         InstallFunction(builtins,
   1476                         "InternalArray",
   1477                         JS_ARRAY_TYPE,
   1478                         JSArray::kSize,
   1479                         isolate->initial_object_prototype(),
   1480                         Builtins::kArrayCode,
   1481                         true);
   1482     Handle<JSObject> prototype =
   1483         factory->NewJSObject(isolate->object_function(), TENURED);
   1484     SetPrototype(array_function, prototype);
   1485 
   1486     array_function->shared()->set_construct_stub(
   1487         isolate->builtins()->builtin(Builtins::kArrayConstructCode));
   1488     array_function->shared()->DontAdaptArguments();
   1489 
   1490     // Make "length" magic on instances.
   1491     Handle<DescriptorArray> array_descriptors =
   1492         factory->CopyAppendProxyDescriptor(
   1493             factory->empty_descriptor_array(),
   1494             factory->length_symbol(),
   1495             factory->NewProxy(&Accessors::ArrayLength),
   1496             static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE));
   1497 
   1498     array_function->initial_map()->set_instance_descriptors(
   1499         *array_descriptors);
   1500   }
   1501 
   1502   if (FLAG_disable_native_files) {
   1503     PrintF("Warning: Running without installed natives!\n");
   1504     return true;
   1505   }
   1506 
   1507   // Install natives.
   1508   for (int i = Natives::GetDebuggerCount();
   1509        i < Natives::GetBuiltinsCount();
   1510        i++) {
   1511     Vector<const char> name = Natives::GetScriptName(i);
   1512     if (!CompileBuiltin(i)) return false;
   1513     // TODO(ager): We really only need to install the JS builtin
   1514     // functions on the builtins object after compiling and running
   1515     // runtime.js.
   1516     if (!InstallJSBuiltins(builtins)) return false;
   1517   }
   1518 
   1519   InstallNativeFunctions();
   1520 
   1521   // Store the map for the string prototype after the natives has been compiled
   1522   // and the String function has been setup.
   1523   Handle<JSFunction> string_function(global_context()->string_function());
   1524   ASSERT(JSObject::cast(
   1525       string_function->initial_map()->prototype())->HasFastProperties());
   1526   global_context()->set_string_function_prototype_map(
   1527       HeapObject::cast(string_function->initial_map()->prototype())->map());
   1528 
   1529   // Install Function.prototype.call and apply.
   1530   { Handle<String> key = factory->function_class_symbol();
   1531     Handle<JSFunction> function =
   1532         Handle<JSFunction>::cast(GetProperty(isolate->global(), key));
   1533     Handle<JSObject> proto =
   1534         Handle<JSObject>(JSObject::cast(function->instance_prototype()));
   1535 
   1536     // Install the call and the apply functions.
   1537     Handle<JSFunction> call =
   1538         InstallFunction(proto, "call", JS_OBJECT_TYPE, JSObject::kHeaderSize,
   1539                         Handle<JSObject>::null(),
   1540                         Builtins::kFunctionCall,
   1541                         false);
   1542     Handle<JSFunction> apply =
   1543         InstallFunction(proto, "apply", JS_OBJECT_TYPE, JSObject::kHeaderSize,
   1544                         Handle<JSObject>::null(),
   1545                         Builtins::kFunctionApply,
   1546                         false);
   1547 
   1548     // Make sure that Function.prototype.call appears to be compiled.
   1549     // The code will never be called, but inline caching for call will
   1550     // only work if it appears to be compiled.
   1551     call->shared()->DontAdaptArguments();
   1552     ASSERT(call->is_compiled());
   1553 
   1554     // Set the expected parameters for apply to 2; required by builtin.
   1555     apply->shared()->set_formal_parameter_count(2);
   1556 
   1557     // Set the lengths for the functions to satisfy ECMA-262.
   1558     call->shared()->set_length(1);
   1559     apply->shared()->set_length(2);
   1560   }
   1561 
   1562   InstallBuiltinFunctionIds();
   1563 
   1564   // Create a constructor for RegExp results (a variant of Array that
   1565   // predefines the two properties index and match).
   1566   {
   1567     // RegExpResult initial map.
   1568 
   1569     // Find global.Array.prototype to inherit from.
   1570     Handle<JSFunction> array_constructor(global_context()->array_function());
   1571     Handle<JSObject> array_prototype(
   1572         JSObject::cast(array_constructor->instance_prototype()));
   1573 
   1574     // Add initial map.
   1575     Handle<Map> initial_map =
   1576         factory->NewMap(JS_ARRAY_TYPE, JSRegExpResult::kSize);
   1577     initial_map->set_constructor(*array_constructor);
   1578 
   1579     // Set prototype on map.
   1580     initial_map->set_non_instance_prototype(false);
   1581     initial_map->set_prototype(*array_prototype);
   1582 
   1583     // Update map with length accessor from Array and add "index" and "input".
   1584     Handle<Map> array_map(global_context()->js_array_map());
   1585     Handle<DescriptorArray> array_descriptors(
   1586         array_map->instance_descriptors());
   1587     ASSERT_EQ(1, array_descriptors->number_of_descriptors());
   1588 
   1589     Handle<DescriptorArray> reresult_descriptors =
   1590         factory->NewDescriptorArray(3);
   1591 
   1592     reresult_descriptors->CopyFrom(0, *array_descriptors, 0);
   1593 
   1594     int enum_index = 0;
   1595     {
   1596       FieldDescriptor index_field(heap->index_symbol(),
   1597                                   JSRegExpResult::kIndexIndex,
   1598                                   NONE,
   1599                                   enum_index++);
   1600       reresult_descriptors->Set(1, &index_field);
   1601     }
   1602 
   1603     {
   1604       FieldDescriptor input_field(heap->input_symbol(),
   1605                                   JSRegExpResult::kInputIndex,
   1606                                   NONE,
   1607                                   enum_index++);
   1608       reresult_descriptors->Set(2, &input_field);
   1609     }
   1610     reresult_descriptors->Sort();
   1611 
   1612     initial_map->set_inobject_properties(2);
   1613     initial_map->set_pre_allocated_property_fields(2);
   1614     initial_map->set_unused_property_fields(0);
   1615     initial_map->set_instance_descriptors(*reresult_descriptors);
   1616 
   1617     global_context()->set_regexp_result_map(*initial_map);
   1618   }
   1619 
   1620 
   1621 #ifdef DEBUG
   1622   builtins->Verify();
   1623 #endif
   1624 
   1625   return true;
   1626 }
   1627 
   1628 
   1629 static Handle<JSObject> ResolveBuiltinIdHolder(
   1630     Handle<Context> global_context,
   1631     const char* holder_expr) {
   1632   Factory* factory = Isolate::Current()->factory();
   1633   Handle<GlobalObject> global(global_context->global());
   1634   const char* period_pos = strchr(holder_expr, '.');
   1635   if (period_pos == NULL) {
   1636     return Handle<JSObject>::cast(
   1637         GetProperty(global, factory->LookupAsciiSymbol(holder_expr)));
   1638   }
   1639   ASSERT_EQ(".prototype", period_pos);
   1640   Vector<const char> property(holder_expr,
   1641                               static_cast<int>(period_pos - holder_expr));
   1642   Handle<JSFunction> function = Handle<JSFunction>::cast(
   1643       GetProperty(global, factory->LookupSymbol(property)));
   1644   return Handle<JSObject>(JSObject::cast(function->prototype()));
   1645 }
   1646 
   1647 
   1648 static void InstallBuiltinFunctionId(Handle<JSObject> holder,
   1649                                      const char* function_name,
   1650                                      BuiltinFunctionId id) {
   1651   Handle<String> name = FACTORY->LookupAsciiSymbol(function_name);
   1652   Object* function_object = holder->GetProperty(*name)->ToObjectUnchecked();
   1653   Handle<JSFunction> function(JSFunction::cast(function_object));
   1654   function->shared()->set_function_data(Smi::FromInt(id));
   1655 }
   1656 
   1657 
   1658 void Genesis::InstallBuiltinFunctionIds() {
   1659   HandleScope scope;
   1660 #define INSTALL_BUILTIN_ID(holder_expr, fun_name, name) \
   1661   {                                                     \
   1662     Handle<JSObject> holder = ResolveBuiltinIdHolder(   \
   1663         global_context(), #holder_expr);                \
   1664     BuiltinFunctionId id = k##name;                     \
   1665     InstallBuiltinFunctionId(holder, #fun_name, id);    \
   1666   }
   1667   FUNCTIONS_WITH_ID_LIST(INSTALL_BUILTIN_ID)
   1668 #undef INSTALL_BUILTIN_ID
   1669 }
   1670 
   1671 
   1672 // Do not forget to update macros.py with named constant
   1673 // of cache id.
   1674 #define JSFUNCTION_RESULT_CACHE_LIST(F) \
   1675   F(16, global_context()->regexp_function())
   1676 
   1677 
   1678 static FixedArray* CreateCache(int size, JSFunction* factory) {
   1679   // Caches are supposed to live for a long time, allocate in old space.
   1680   int array_size = JSFunctionResultCache::kEntriesIndex + 2 * size;
   1681   // Cannot use cast as object is not fully initialized yet.
   1682   JSFunctionResultCache* cache = reinterpret_cast<JSFunctionResultCache*>(
   1683       *FACTORY->NewFixedArrayWithHoles(array_size, TENURED));
   1684   cache->set(JSFunctionResultCache::kFactoryIndex, factory);
   1685   cache->MakeZeroSize();
   1686   return cache;
   1687 }
   1688 
   1689 
   1690 void Genesis::InstallJSFunctionResultCaches() {
   1691   const int kNumberOfCaches = 0 +
   1692 #define F(size, func) + 1
   1693     JSFUNCTION_RESULT_CACHE_LIST(F)
   1694 #undef F
   1695   ;
   1696 
   1697   Handle<FixedArray> caches = FACTORY->NewFixedArray(kNumberOfCaches, TENURED);
   1698 
   1699   int index = 0;
   1700 
   1701 #define F(size, func) do {                           \
   1702     FixedArray* cache = CreateCache((size), (func)); \
   1703     caches->set(index++, cache);                     \
   1704   } while (false)
   1705 
   1706   JSFUNCTION_RESULT_CACHE_LIST(F);
   1707 
   1708 #undef F
   1709 
   1710   global_context()->set_jsfunction_result_caches(*caches);
   1711 }
   1712 
   1713 
   1714 void Genesis::InitializeNormalizedMapCaches() {
   1715   Handle<FixedArray> array(
   1716       FACTORY->NewFixedArray(NormalizedMapCache::kEntries, TENURED));
   1717   global_context()->set_normalized_map_cache(NormalizedMapCache::cast(*array));
   1718 }
   1719 
   1720 
   1721 bool Bootstrapper::InstallExtensions(Handle<Context> global_context,
   1722                                      v8::ExtensionConfiguration* extensions) {
   1723   Isolate* isolate = Isolate::Current();
   1724   BootstrapperActive active;
   1725   SaveContext saved_context(isolate);
   1726   isolate->set_context(*global_context);
   1727   if (!Genesis::InstallExtensions(global_context, extensions)) return false;
   1728   Genesis::InstallSpecialObjects(global_context);
   1729   return true;
   1730 }
   1731 
   1732 
   1733 void Genesis::InstallSpecialObjects(Handle<Context> global_context) {
   1734   Factory* factory = Isolate::Current()->factory();
   1735   HandleScope scope;
   1736   Handle<JSGlobalObject> js_global(
   1737       JSGlobalObject::cast(global_context->global()));
   1738   // Expose the natives in global if a name for it is specified.
   1739   if (FLAG_expose_natives_as != NULL && strlen(FLAG_expose_natives_as) != 0) {
   1740     Handle<String> natives_string =
   1741         factory->LookupAsciiSymbol(FLAG_expose_natives_as);
   1742     SetLocalPropertyNoThrow(js_global, natives_string,
   1743                             Handle<JSObject>(js_global->builtins()), DONT_ENUM);
   1744   }
   1745 
   1746   Handle<Object> Error = GetProperty(js_global, "Error");
   1747   if (Error->IsJSObject()) {
   1748     Handle<String> name = factory->LookupAsciiSymbol("stackTraceLimit");
   1749     SetLocalPropertyNoThrow(Handle<JSObject>::cast(Error),
   1750                             name,
   1751                             Handle<Smi>(Smi::FromInt(FLAG_stack_trace_limit)),
   1752                             NONE);
   1753   }
   1754 
   1755 #ifdef ENABLE_DEBUGGER_SUPPORT
   1756   // Expose the debug global object in global if a name for it is specified.
   1757   if (FLAG_expose_debug_as != NULL && strlen(FLAG_expose_debug_as) != 0) {
   1758     Debug* debug = Isolate::Current()->debug();
   1759     // If loading fails we just bail out without installing the
   1760     // debugger but without tanking the whole context.
   1761     if (!debug->Load()) return;
   1762     // Set the security token for the debugger context to the same as
   1763     // the shell global context to allow calling between these (otherwise
   1764     // exposing debug global object doesn't make much sense).
   1765     debug->debug_context()->set_security_token(
   1766         global_context->security_token());
   1767 
   1768     Handle<String> debug_string =
   1769         factory->LookupAsciiSymbol(FLAG_expose_debug_as);
   1770     Handle<Object> global_proxy(debug->debug_context()->global_proxy());
   1771     SetLocalPropertyNoThrow(js_global, debug_string, global_proxy, DONT_ENUM);
   1772   }
   1773 #endif
   1774 }
   1775 
   1776 
   1777 bool Genesis::InstallExtensions(Handle<Context> global_context,
   1778                                 v8::ExtensionConfiguration* extensions) {
   1779   // TODO(isolates): Extensions on multiple isolates may take a little more
   1780   //                 effort. (The external API reads 'ignore'-- does that mean
   1781   //                 we can break the interface?)
   1782 
   1783   // Clear coloring of extension list
   1784   v8::RegisteredExtension* current = v8::RegisteredExtension::first_extension();
   1785   while (current != NULL) {
   1786     current->set_state(v8::UNVISITED);
   1787     current = current->next();
   1788   }
   1789   // Install auto extensions.
   1790   current = v8::RegisteredExtension::first_extension();
   1791   while (current != NULL) {
   1792     if (current->extension()->auto_enable())
   1793       InstallExtension(current);
   1794     current = current->next();
   1795   }
   1796 
   1797   if (FLAG_expose_gc) InstallExtension("v8/gc");
   1798   if (FLAG_expose_externalize_string) InstallExtension("v8/externalize");
   1799 
   1800   if (extensions == NULL) return true;
   1801   // Install required extensions
   1802   int count = v8::ImplementationUtilities::GetNameCount(extensions);
   1803   const char** names = v8::ImplementationUtilities::GetNames(extensions);
   1804   for (int i = 0; i < count; i++) {
   1805     if (!InstallExtension(names[i]))
   1806       return false;
   1807   }
   1808 
   1809   return true;
   1810 }
   1811 
   1812 
   1813 // Installs a named extension.  This methods is unoptimized and does
   1814 // not scale well if we want to support a large number of extensions.
   1815 bool Genesis::InstallExtension(const char* name) {
   1816   v8::RegisteredExtension* current = v8::RegisteredExtension::first_extension();
   1817   // Loop until we find the relevant extension
   1818   while (current != NULL) {
   1819     if (strcmp(name, current->extension()->name()) == 0) break;
   1820     current = current->next();
   1821   }
   1822   // Didn't find the extension; fail.
   1823   if (current == NULL) {
   1824     v8::Utils::ReportApiFailure(
   1825         "v8::Context::New()", "Cannot find required extension");
   1826     return false;
   1827   }
   1828   return InstallExtension(current);
   1829 }
   1830 
   1831 
   1832 bool Genesis::InstallExtension(v8::RegisteredExtension* current) {
   1833   HandleScope scope;
   1834 
   1835   if (current->state() == v8::INSTALLED) return true;
   1836   // The current node has already been visited so there must be a
   1837   // cycle in the dependency graph; fail.
   1838   if (current->state() == v8::VISITED) {
   1839     v8::Utils::ReportApiFailure(
   1840         "v8::Context::New()", "Circular extension dependency");
   1841     return false;
   1842   }
   1843   ASSERT(current->state() == v8::UNVISITED);
   1844   current->set_state(v8::VISITED);
   1845   v8::Extension* extension = current->extension();
   1846   // Install the extension's dependencies
   1847   for (int i = 0; i < extension->dependency_count(); i++) {
   1848     if (!InstallExtension(extension->dependencies()[i])) return false;
   1849   }
   1850   Isolate* isolate = Isolate::Current();
   1851   Vector<const char> source = CStrVector(extension->source());
   1852   Handle<String> source_code = isolate->factory()->NewStringFromAscii(source);
   1853   bool result = CompileScriptCached(CStrVector(extension->name()),
   1854                                     source_code,
   1855                                     isolate->bootstrapper()->extensions_cache(),
   1856                                     extension,
   1857                                     Handle<Context>(isolate->context()),
   1858                                     false);
   1859   ASSERT(isolate->has_pending_exception() != result);
   1860   if (!result) {
   1861     isolate->clear_pending_exception();
   1862   }
   1863   current->set_state(v8::INSTALLED);
   1864   return result;
   1865 }
   1866 
   1867 
   1868 bool Genesis::InstallJSBuiltins(Handle<JSBuiltinsObject> builtins) {
   1869   HandleScope scope;
   1870   for (int i = 0; i < Builtins::NumberOfJavaScriptBuiltins(); i++) {
   1871     Builtins::JavaScript id = static_cast<Builtins::JavaScript>(i);
   1872     Handle<String> name = FACTORY->LookupAsciiSymbol(Builtins::GetName(id));
   1873     Object* function_object = builtins->GetPropertyNoExceptionThrown(*name);
   1874     Handle<JSFunction> function
   1875         = Handle<JSFunction>(JSFunction::cast(function_object));
   1876     builtins->set_javascript_builtin(id, *function);
   1877     Handle<SharedFunctionInfo> shared
   1878         = Handle<SharedFunctionInfo>(function->shared());
   1879     if (!EnsureCompiled(shared, CLEAR_EXCEPTION)) return false;
   1880     // Set the code object on the function object.
   1881     function->ReplaceCode(function->shared()->code());
   1882     builtins->set_javascript_builtin_code(id, shared->code());
   1883   }
   1884   return true;
   1885 }
   1886 
   1887 
   1888 bool Genesis::ConfigureGlobalObjects(
   1889     v8::Handle<v8::ObjectTemplate> global_proxy_template) {
   1890   Handle<JSObject> global_proxy(
   1891       JSObject::cast(global_context()->global_proxy()));
   1892   Handle<JSObject> inner_global(JSObject::cast(global_context()->global()));
   1893 
   1894   if (!global_proxy_template.IsEmpty()) {
   1895     // Configure the global proxy object.
   1896     Handle<ObjectTemplateInfo> proxy_data =
   1897         v8::Utils::OpenHandle(*global_proxy_template);
   1898     if (!ConfigureApiObject(global_proxy, proxy_data)) return false;
   1899 
   1900     // Configure the inner global object.
   1901     Handle<FunctionTemplateInfo> proxy_constructor(
   1902         FunctionTemplateInfo::cast(proxy_data->constructor()));
   1903     if (!proxy_constructor->prototype_template()->IsUndefined()) {
   1904       Handle<ObjectTemplateInfo> inner_data(
   1905           ObjectTemplateInfo::cast(proxy_constructor->prototype_template()));
   1906       if (!ConfigureApiObject(inner_global, inner_data)) return false;
   1907     }
   1908   }
   1909 
   1910   SetObjectPrototype(global_proxy, inner_global);
   1911   return true;
   1912 }
   1913 
   1914 
   1915 bool Genesis::ConfigureApiObject(Handle<JSObject> object,
   1916     Handle<ObjectTemplateInfo> object_template) {
   1917   ASSERT(!object_template.is_null());
   1918   ASSERT(object->IsInstanceOf(
   1919       FunctionTemplateInfo::cast(object_template->constructor())));
   1920 
   1921   Isolate* isolate = Isolate::Current();
   1922   bool pending_exception = false;
   1923   Handle<JSObject> obj =
   1924       Execution::InstantiateObject(object_template, &pending_exception);
   1925   if (pending_exception) {
   1926     ASSERT(isolate->has_pending_exception());
   1927     isolate->clear_pending_exception();
   1928     return false;
   1929   }
   1930   TransferObject(obj, object);
   1931   return true;
   1932 }
   1933 
   1934 
   1935 void Genesis::TransferNamedProperties(Handle<JSObject> from,
   1936                                       Handle<JSObject> to) {
   1937   if (from->HasFastProperties()) {
   1938     Handle<DescriptorArray> descs =
   1939         Handle<DescriptorArray>(from->map()->instance_descriptors());
   1940     for (int i = 0; i < descs->number_of_descriptors(); i++) {
   1941       PropertyDetails details = PropertyDetails(descs->GetDetails(i));
   1942       switch (details.type()) {
   1943         case FIELD: {
   1944           HandleScope inner;
   1945           Handle<String> key = Handle<String>(descs->GetKey(i));
   1946           int index = descs->GetFieldIndex(i);
   1947           Handle<Object> value = Handle<Object>(from->FastPropertyAt(index));
   1948           SetLocalPropertyNoThrow(to, key, value, details.attributes());
   1949           break;
   1950         }
   1951         case CONSTANT_FUNCTION: {
   1952           HandleScope inner;
   1953           Handle<String> key = Handle<String>(descs->GetKey(i));
   1954           Handle<JSFunction> fun =
   1955               Handle<JSFunction>(descs->GetConstantFunction(i));
   1956           SetLocalPropertyNoThrow(to, key, fun, details.attributes());
   1957           break;
   1958         }
   1959         case CALLBACKS: {
   1960           LookupResult result;
   1961           to->LocalLookup(descs->GetKey(i), &result);
   1962           // If the property is already there we skip it
   1963           if (result.IsProperty()) continue;
   1964           HandleScope inner;
   1965           ASSERT(!to->HasFastProperties());
   1966           // Add to dictionary.
   1967           Handle<String> key = Handle<String>(descs->GetKey(i));
   1968           Handle<Object> callbacks(descs->GetCallbacksObject(i));
   1969           PropertyDetails d =
   1970               PropertyDetails(details.attributes(), CALLBACKS, details.index());
   1971           SetNormalizedProperty(to, key, callbacks, d);
   1972           break;
   1973         }
   1974         case MAP_TRANSITION:
   1975         case EXTERNAL_ARRAY_TRANSITION:
   1976         case CONSTANT_TRANSITION:
   1977         case NULL_DESCRIPTOR:
   1978           // Ignore non-properties.
   1979           break;
   1980         case NORMAL:
   1981           // Do not occur since the from object has fast properties.
   1982         case INTERCEPTOR:
   1983           // No element in instance descriptors have interceptor type.
   1984           UNREACHABLE();
   1985           break;
   1986       }
   1987     }
   1988   } else {
   1989     Handle<StringDictionary> properties =
   1990         Handle<StringDictionary>(from->property_dictionary());
   1991     int capacity = properties->Capacity();
   1992     for (int i = 0; i < capacity; i++) {
   1993       Object* raw_key(properties->KeyAt(i));
   1994       if (properties->IsKey(raw_key)) {
   1995         ASSERT(raw_key->IsString());
   1996         // If the property is already there we skip it.
   1997         LookupResult result;
   1998         to->LocalLookup(String::cast(raw_key), &result);
   1999         if (result.IsProperty()) continue;
   2000         // Set the property.
   2001         Handle<String> key = Handle<String>(String::cast(raw_key));
   2002         Handle<Object> value = Handle<Object>(properties->ValueAt(i));
   2003         if (value->IsJSGlobalPropertyCell()) {
   2004           value = Handle<Object>(JSGlobalPropertyCell::cast(*value)->value());
   2005         }
   2006         PropertyDetails details = properties->DetailsAt(i);
   2007         SetLocalPropertyNoThrow(to, key, value, details.attributes());
   2008       }
   2009     }
   2010   }
   2011 }
   2012 
   2013 
   2014 void Genesis::TransferIndexedProperties(Handle<JSObject> from,
   2015                                         Handle<JSObject> to) {
   2016   // Cloning the elements array is sufficient.
   2017   Handle<FixedArray> from_elements =
   2018       Handle<FixedArray>(FixedArray::cast(from->elements()));
   2019   Handle<FixedArray> to_elements = FACTORY->CopyFixedArray(from_elements);
   2020   to->set_elements(*to_elements);
   2021 }
   2022 
   2023 
   2024 void Genesis::TransferObject(Handle<JSObject> from, Handle<JSObject> to) {
   2025   HandleScope outer;
   2026 
   2027   ASSERT(!from->IsJSArray());
   2028   ASSERT(!to->IsJSArray());
   2029 
   2030   TransferNamedProperties(from, to);
   2031   TransferIndexedProperties(from, to);
   2032 
   2033   // Transfer the prototype (new map is needed).
   2034   Handle<Map> old_to_map = Handle<Map>(to->map());
   2035   Handle<Map> new_to_map = FACTORY->CopyMapDropTransitions(old_to_map);
   2036   new_to_map->set_prototype(from->map()->prototype());
   2037   to->set_map(*new_to_map);
   2038 }
   2039 
   2040 
   2041 void Genesis::MakeFunctionInstancePrototypeWritable() {
   2042   // The maps with writable prototype are created in CreateEmptyFunction
   2043   // and CreateStrictModeFunctionMaps respectively. Initially the maps are
   2044   // created with read-only prototype for JS builtins processing.
   2045   ASSERT(!function_instance_map_writable_prototype_.is_null());
   2046   ASSERT(!strict_mode_function_instance_map_writable_prototype_.is_null());
   2047 
   2048   // Replace function instance maps to make prototype writable.
   2049   global_context()->set_function_map(
   2050     *function_instance_map_writable_prototype_);
   2051   global_context()->set_strict_mode_function_map(
   2052     *strict_mode_function_instance_map_writable_prototype_);
   2053 }
   2054 
   2055 
   2056 Genesis::Genesis(Handle<Object> global_object,
   2057                  v8::Handle<v8::ObjectTemplate> global_template,
   2058                  v8::ExtensionConfiguration* extensions) {
   2059   Isolate* isolate = Isolate::Current();
   2060   result_ = Handle<Context>::null();
   2061   // If V8 isn't running and cannot be initialized, just return.
   2062   if (!V8::IsRunning() && !V8::Initialize(NULL)) return;
   2063 
   2064   // Before creating the roots we must save the context and restore it
   2065   // on all function exits.
   2066   HandleScope scope;
   2067   SaveContext saved_context(isolate);
   2068 
   2069   Handle<Context> new_context = Snapshot::NewContextFromSnapshot();
   2070   if (!new_context.is_null()) {
   2071     global_context_ =
   2072         Handle<Context>::cast(isolate->global_handles()->Create(*new_context));
   2073     AddToWeakGlobalContextList(*global_context_);
   2074     isolate->set_context(*global_context_);
   2075     isolate->counters()->contexts_created_by_snapshot()->Increment();
   2076     Handle<GlobalObject> inner_global;
   2077     Handle<JSGlobalProxy> global_proxy =
   2078         CreateNewGlobals(global_template,
   2079                          global_object,
   2080                          &inner_global);
   2081 
   2082     HookUpGlobalProxy(inner_global, global_proxy);
   2083     HookUpInnerGlobal(inner_global);
   2084 
   2085     if (!ConfigureGlobalObjects(global_template)) return;
   2086   } else {
   2087     // We get here if there was no context snapshot.
   2088     CreateRoots();
   2089     Handle<JSFunction> empty_function = CreateEmptyFunction();
   2090     CreateStrictModeFunctionMaps(empty_function);
   2091     Handle<GlobalObject> inner_global;
   2092     Handle<JSGlobalProxy> global_proxy =
   2093         CreateNewGlobals(global_template, global_object, &inner_global);
   2094     HookUpGlobalProxy(inner_global, global_proxy);
   2095     InitializeGlobal(inner_global, empty_function);
   2096     InstallJSFunctionResultCaches();
   2097     InitializeNormalizedMapCaches();
   2098     if (!InstallNatives()) return;
   2099 
   2100     MakeFunctionInstancePrototypeWritable();
   2101 
   2102     if (!ConfigureGlobalObjects(global_template)) return;
   2103     isolate->counters()->contexts_created_from_scratch()->Increment();
   2104   }
   2105 
   2106   result_ = global_context_;
   2107 }
   2108 
   2109 
   2110 // Support for thread preemption.
   2111 
   2112 // Reserve space for statics needing saving and restoring.
   2113 int Bootstrapper::ArchiveSpacePerThread() {
   2114   return sizeof(NestingCounterType);
   2115 }
   2116 
   2117 
   2118 // Archive statics that are thread local.
   2119 char* Bootstrapper::ArchiveState(char* to) {
   2120   *reinterpret_cast<NestingCounterType*>(to) = nesting_;
   2121   nesting_ = 0;
   2122   return to + sizeof(NestingCounterType);
   2123 }
   2124 
   2125 
   2126 // Restore statics that are thread local.
   2127 char* Bootstrapper::RestoreState(char* from) {
   2128   nesting_ = *reinterpret_cast<NestingCounterType*>(from);
   2129   return from + sizeof(NestingCounterType);
   2130 }
   2131 
   2132 
   2133 // Called when the top-level V8 mutex is destroyed.
   2134 void Bootstrapper::FreeThreadResources() {
   2135   ASSERT(!IsActive());
   2136 }
   2137 
   2138 } }  // namespace v8::internal
   2139