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