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