bootstrapper.cc 107 KB
Newer Older
1 2 3
// Copyright 2014 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
4

5
#include "src/bootstrapper.h"
6

7 8 9 10 11 12 13 14 15 16 17
#include "src/accessors.h"
#include "src/isolate-inl.h"
#include "src/natives.h"
#include "src/snapshot.h"
#include "src/trig-table.h"
#include "src/extensions/externalize-string-extension.h"
#include "src/extensions/free-buffer-extension.h"
#include "src/extensions/gc-extension.h"
#include "src/extensions/statistics-extension.h"
#include "src/extensions/trigger-failure-extension.h"
#include "src/code-stubs.h"
18

19 20
namespace v8 {
namespace internal {
21

22 23
NativesExternalStringResource::NativesExternalStringResource(
    Bootstrapper* bootstrapper,
24 25 26
    const char* source,
    size_t length)
    : data_(source), length_(length) {
27 28
  if (bootstrapper->delete_these_non_arrays_on_tear_down_ == NULL) {
    bootstrapper->delete_these_non_arrays_on_tear_down_ = new List<char*>(2);
29 30 31
  }
  // The resources are small objects and we only make a fixed number of
  // them, but let's clean them up on exit for neatness.
32
  bootstrapper->delete_these_non_arrays_on_tear_down_->
33 34 35 36
      Add(reinterpret_cast<char*>(this));
}


37 38 39
Bootstrapper::Bootstrapper(Isolate* isolate)
    : isolate_(isolate),
      nesting_(0),
40 41 42 43 44 45
      extensions_cache_(Script::TYPE_EXTENSION),
      delete_these_non_arrays_on_tear_down_(NULL),
      delete_these_arrays_on_tear_down_(NULL) {
}


46 47
Handle<String> Bootstrapper::NativesSourceLookup(int index) {
  ASSERT(0 <= index && index < Natives::GetBuiltinsCount());
48
  Heap* heap = isolate_->heap();
49
  if (heap->natives_source_cache()->get(index)->IsUndefined()) {
50 51 52 53 54 55
    // We can use external strings for the natives.
    Vector<const char> source = Natives::GetRawScriptSource(index);
    NativesExternalStringResource* resource =
        new NativesExternalStringResource(this,
                                          source.start(),
                                          source.length());
56
    // We do not expect this to throw an exception. Change this if it does.
57 58 59
    Handle<String> source_code =
        isolate_->factory()->NewExternalStringFromAscii(
            resource).ToHandleChecked();
60
    heap->natives_source_cache()->set(index, *source_code);
61
  }
62 63
  Handle<Object> cached_source(heap->natives_source_cache()->get(index),
                               isolate_);
64 65 66 67 68
  return Handle<String>::cast(cached_source);
}


void Bootstrapper::Initialize(bool create_heap_objects) {
69
  extensions_cache_.Initialize(isolate_, create_heap_objects);
70 71 72
}


73 74 75 76 77 78 79 80 81 82 83 84 85
static const char* GCFunctionName() {
  bool flag_given = FLAG_expose_gc_as != NULL && strlen(FLAG_expose_gc_as) != 0;
  return flag_given ? FLAG_expose_gc_as : "gc";
}


v8::Extension* Bootstrapper::free_buffer_extension_ = NULL;
v8::Extension* Bootstrapper::gc_extension_ = NULL;
v8::Extension* Bootstrapper::externalize_string_extension_ = NULL;
v8::Extension* Bootstrapper::statistics_extension_ = NULL;
v8::Extension* Bootstrapper::trigger_failure_extension_ = NULL;


86
void Bootstrapper::InitializeOncePerProcess() {
87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
  free_buffer_extension_ = new FreeBufferExtension;
  v8::RegisterExtension(free_buffer_extension_);
  gc_extension_ = new GCExtension(GCFunctionName());
  v8::RegisterExtension(gc_extension_);
  externalize_string_extension_ = new ExternalizeStringExtension;
  v8::RegisterExtension(externalize_string_extension_);
  statistics_extension_ = new StatisticsExtension;
  v8::RegisterExtension(statistics_extension_);
  trigger_failure_extension_ = new TriggerFailureExtension;
  v8::RegisterExtension(trigger_failure_extension_);
}


void Bootstrapper::TearDownExtensions() {
  delete free_buffer_extension_;
  delete gc_extension_;
  delete externalize_string_extension_;
  delete statistics_extension_;
  delete trigger_failure_extension_;
106 107 108
}


109 110 111
char* Bootstrapper::AllocateAutoDeletedArray(int bytes) {
  char* memory = new char[bytes];
  if (memory != NULL) {
112 113
    if (delete_these_arrays_on_tear_down_ == NULL) {
      delete_these_arrays_on_tear_down_ = new List<char*>(2);
114
    }
115
    delete_these_arrays_on_tear_down_->Add(memory);
116 117 118 119 120
  }
  return memory;
}


121
void Bootstrapper::TearDown() {
122 123
  if (delete_these_non_arrays_on_tear_down_ != NULL) {
    int len = delete_these_non_arrays_on_tear_down_->length();
124
    ASSERT(len < 24);  // Don't use this mechanism for unbounded allocations.
125
    for (int i = 0; i < len; i++) {
126 127
      delete delete_these_non_arrays_on_tear_down_->at(i);
      delete_these_non_arrays_on_tear_down_->at(i) = NULL;
128
    }
129 130
    delete delete_these_non_arrays_on_tear_down_;
    delete_these_non_arrays_on_tear_down_ = NULL;
131 132
  }

133 134
  if (delete_these_arrays_on_tear_down_ != NULL) {
    int len = delete_these_arrays_on_tear_down_->length();
135 136
    ASSERT(len < 1000);  // Don't use this mechanism for unbounded allocations.
    for (int i = 0; i < len; i++) {
137 138
      delete[] delete_these_arrays_on_tear_down_->at(i);
      delete_these_arrays_on_tear_down_->at(i) = NULL;
139
    }
140 141
    delete delete_these_arrays_on_tear_down_;
    delete_these_arrays_on_tear_down_ = NULL;
142 143
  }

144
  extensions_cache_.Initialize(isolate_, false);  // Yes, symmetrical
145 146 147 148 149
}


class Genesis BASE_EMBEDDED {
 public:
150 151
  Genesis(Isolate* isolate,
          Handle<Object> global_object,
152 153
          v8::Handle<v8::ObjectTemplate> global_template,
          v8::ExtensionConfiguration* extensions);
154
  ~Genesis() { }
155

156 157 158 159
  Isolate* isolate() const { return isolate_; }
  Factory* factory() const { return isolate_->factory(); }
  Heap* heap() const { return isolate_->heap(); }

160
  Handle<Context> result() { return result_; }
161

162
 private:
163
  Handle<Context> native_context() { return native_context_; }
164

165 166 167
  // Creates some basic objects. Used for creating a context from scratch.
  void CreateRoots();
  // Creates the empty function.  Used for creating a context from scratch.
168
  Handle<JSFunction> CreateEmptyFunction(Isolate* isolate);
169
  // Creates the ThrowTypeError function. ECMA 5th Ed. 13.2.3
170 171 172
  Handle<JSFunction> GetStrictPoisonFunction();
  // Poison for sloppy generator function arguments/callee.
  Handle<JSFunction> GetGeneratorPoisonFunction();
173 174

  void CreateStrictModeFunctionMaps(Handle<JSFunction> empty);
175 176 177 178

  // Make the "arguments" and "caller" properties throw a TypeError on access.
  void PoisonArgumentsAndCaller(Handle<Map> map);

179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198
  // Creates the global objects using the global and the template passed in
  // through the API.  We call this regardless of whether we are building a
  // context from scratch or using a deserialized one from the partial snapshot
  // but in the latter case we don't use the objects it produces directly, as
  // we have to used the deserialized ones that are linked together with the
  // rest of the context snapshot.
  Handle<JSGlobalProxy> CreateNewGlobals(
      v8::Handle<v8::ObjectTemplate> global_template,
      Handle<Object> global_object,
      Handle<GlobalObject>* global_proxy_out);
  // Hooks the given global proxy into the context.  If the context was created
  // by deserialization then this will unhook the global proxy that was
  // deserialized, leaving the GC to pick it up.
  void HookUpGlobalProxy(Handle<GlobalObject> inner_global,
                         Handle<JSGlobalProxy> global_proxy);
  // Similarly, we want to use the inner global that has been created by the
  // templates passed through the API.  The inner global from the snapshot is
  // detached from the other objects in the snapshot.
  void HookUpInnerGlobal(Handle<GlobalObject> inner_global);
  // New context initialization.  Used for creating a context from scratch.
199
  void InitializeGlobal(Handle<GlobalObject> inner_global,
200
                        Handle<JSFunction> empty_function);
201
  void InitializeExperimentalGlobal();
202 203
  // Installs the contents of the native .js files on the global objects.
  // Used for creating a context from scratch.
204
  void InstallNativeFunctions();
205
  void InstallExperimentalBuiltinFunctionIds();
206
  void InstallExperimentalNativeFunctions();
207 208 209
  Handle<JSFunction> InstallInternalArray(Handle<JSBuiltinsObject> builtins,
                                          const char* name,
                                          ElementsKind elements_kind);
210
  bool InstallNatives();
211

212 213 214 215 216
  void InstallTypedArray(
      const char* name,
      ElementsKind elements_kind,
      Handle<JSFunction>* fun,
      Handle<Map>* external_map);
217
  bool InstallExperimentalNatives();
218
  void InstallBuiltinFunctionIds();
219
  void InstallJSFunctionResultCaches();
220
  void InitializeNormalizedMapCaches();
221

222 223 224 225 226
  enum ExtensionTraversalState {
    UNVISITED, VISITED, INSTALLED
  };

  class ExtensionStates {
227
   public:
228 229 230 231
    ExtensionStates();
    ExtensionTraversalState get_state(RegisteredExtension* extension);
    void set_state(RegisteredExtension* extension,
                   ExtensionTraversalState state);
232
   private:
233
    HashMap map_;
234
    DISALLOW_COPY_AND_ASSIGN(ExtensionStates);
235 236
  };

237 238
  // Used both for deserialized and from-scratch contexts to add the extensions
  // provided.
239
  static bool InstallExtensions(Handle<Context> native_context,
240
                                v8::ExtensionConfiguration* extensions);
241 242 243 244 245
  static bool InstallAutoExtensions(Isolate* isolate,
                                    ExtensionStates* extension_states);
  static bool InstallRequestedExtensions(Isolate* isolate,
                                         v8::ExtensionConfiguration* extensions,
                                         ExtensionStates* extension_states);
246 247
  static bool InstallExtension(Isolate* isolate,
                               const char* name,
248
                               ExtensionStates* extension_states);
249 250
  static bool InstallExtension(Isolate* isolate,
                               v8::RegisteredExtension* current,
251
                               ExtensionStates* extension_states);
252
  static bool InstallSpecialObjects(Handle<Context> native_context);
253
  bool InstallJSBuiltins(Handle<JSBuiltinsObject> builtins);
254 255 256
  bool ConfigureApiObject(Handle<JSObject> object,
                          Handle<ObjectTemplateInfo> object_template);
  bool ConfigureGlobalObjects(v8::Handle<v8::ObjectTemplate> global_template);
257 258 259 260 261 262 263 264

  // Migrates all properties from the 'from' object to the 'to'
  // object and overrides the prototype in 'to' with the one from
  // 'from'.
  void TransferObject(Handle<JSObject> from, Handle<JSObject> to);
  void TransferNamedProperties(Handle<JSObject> from, Handle<JSObject> to);
  void TransferIndexedProperties(Handle<JSObject> from, Handle<JSObject> to);

265 266 267 268 269
  enum PrototypePropertyMode {
    DONT_ADD_PROTOTYPE,
    ADD_READONLY_PROTOTYPE,
    ADD_WRITEABLE_PROTOTYPE
  };
270 271 272

  Handle<Map> CreateFunctionMap(PrototypePropertyMode prototype_mode);

273 274
  void SetFunctionInstanceDescriptor(Handle<Map> map,
                                     PrototypePropertyMode prototypeMode);
275 276
  void MakeFunctionInstancePrototypeWritable();

277
  Handle<Map> CreateStrictFunctionMap(
278
      PrototypePropertyMode prototype_mode,
279
      Handle<JSFunction> empty_function);
280

281 282
  void SetStrictFunctionInstanceDescriptor(Handle<Map> map,
                                           PrototypePropertyMode propertyMode);
283

284
  static bool CompileBuiltin(Isolate* isolate, int index);
285
  static bool CompileExperimentalBuiltin(Isolate* isolate, int index);
286 287 288 289 290
  static bool CompileNative(Isolate* isolate,
                            Vector<const char> name,
                            Handle<String> source);
  static bool CompileScriptCached(Isolate* isolate,
                                  Vector<const char> name,
291 292 293
                                  Handle<String> source,
                                  SourceCodeCache* cache,
                                  v8::Extension* extension,
294
                                  Handle<Context> top_context,
295 296
                                  bool use_runtime_context);

297
  Isolate* isolate_;
298
  Handle<Context> result_;
299
  Handle<Context> native_context_;
300

301 302 303 304
  // Function maps. Function maps are created initially with a read only
  // prototype for the processing of JS builtins. Later the function maps are
  // replaced in order to make prototype writable. These are the final, writable
  // prototype, maps.
305 306
  Handle<Map> sloppy_function_map_writable_prototype_;
  Handle<Map> strict_function_map_writable_prototype_;
307 308
  Handle<JSFunction> strict_poison_function;
  Handle<JSFunction> generator_poison_function;
309

310 311
  BootstrapperActive active_;
  friend class Bootstrapper;
312 313 314 315
};


void Bootstrapper::Iterate(ObjectVisitor* v) {
316
  extensions_cache_.Iterate(v);
317
  v->Synchronize(VisitorSynchronization::kExtensions);
318 319 320 321 322 323 324
}


Handle<Context> Bootstrapper::CreateEnvironment(
    Handle<Object> global_object,
    v8::Handle<v8::ObjectTemplate> global_template,
    v8::ExtensionConfiguration* extensions) {
325 326
  HandleScope scope(isolate_);
  Genesis genesis(isolate_, global_object, global_template, extensions);
327 328 329
  Handle<Context> env = genesis.result();
  if (env.is_null() || !InstallExtensions(env, extensions)) {
    return Handle<Context>();
330
  }
331
  return scope.CloseAndEscape(env);
332 333 334
}


335 336 337
static void SetObjectPrototype(Handle<JSObject> object, Handle<Object> proto) {
  // object.__proto__ = proto;
  Handle<Map> old_to_map = Handle<Map>(object->map());
338
  Handle<Map> new_to_map = Map::Copy(old_to_map);
339 340 341 342 343 344
  new_to_map->set_prototype(*proto);
  object->set_map(*new_to_map);
}


void Bootstrapper::DetachGlobal(Handle<Context> env) {
345
  Factory* factory = env->GetIsolate()->factory();
346 347 348
  Handle<JSGlobalProxy> global_proxy(JSGlobalProxy::cast(env->global_proxy()));
  global_proxy->set_native_context(*factory->null_value());
  SetObjectPrototype(global_proxy, factory->null_value());
349 350 351
}


352 353 354 355
static Handle<JSFunction> InstallFunction(Handle<JSObject> target,
                                          const char* name,
                                          InstanceType type,
                                          int instance_size,
356
                                          MaybeHandle<JSObject> maybe_prototype,
357
                                          Builtins::Name call) {
358
  Isolate* isolate = target->GetIsolate();
359
  Factory* factory = isolate->factory();
360
  Handle<String> internalized_name = factory->InternalizeUtf8String(name);
361
  Handle<Code> call_code = Handle<Code>(isolate->builtins()->builtin(call));
362 363
  Handle<JSObject> prototype;
  Handle<JSFunction> function = maybe_prototype.ToHandle(&prototype)
364 365 366
      ? factory->NewFunction(internalized_name, call_code, prototype,
                             type, instance_size)
      : factory->NewFunctionWithoutPrototype(internalized_name, call_code);
367 368 369 370 371 372 373
  PropertyAttributes attributes;
  if (target->IsJSBuiltinsObject()) {
    attributes =
        static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY);
  } else {
    attributes = DONT_ENUM;
  }
374
  JSObject::SetOwnPropertyIgnoreAttributes(
375
      target, internalized_name, function, attributes).Check();
376
  if (target->IsJSGlobalObject()) {
377
    function->shared()->set_instance_class_name(*internalized_name);
378
  }
379
  function->shared()->set_native(true);
380 381 382 383
  return function;
}


384 385
void Genesis::SetFunctionInstanceDescriptor(
    Handle<Map> map, PrototypePropertyMode prototypeMode) {
386
  int size = (prototypeMode == DONT_ADD_PROTOTYPE) ? 4 : 5;
387
  Map::EnsureDescriptorSlack(map, size);
388

389 390
  PropertyAttributes attribs = static_cast<PropertyAttributes>(
      DONT_ENUM | DONT_DELETE | READ_ONLY);
391

392
  Handle<AccessorInfo> length =
393
      Accessors::FunctionLengthInfo(isolate(), attribs);
394
  {  // Add length.
395
    CallbacksDescriptor d(Handle<Name>(Name::cast(length->name())),
396
                          length, attribs);
397
    map->AppendDescriptor(&d);
398
  }
399
  Handle<AccessorInfo> name =
400
      Accessors::FunctionNameInfo(isolate(), attribs);
401
  {  // Add name.
402
    CallbacksDescriptor d(Handle<Name>(Name::cast(name->name())),
403
                          name, attribs);
404
    map->AppendDescriptor(&d);
405
  }
406
  Handle<AccessorInfo> args =
407
      Accessors::FunctionArgumentsInfo(isolate(), attribs);
408
  {  // Add arguments.
409
    CallbacksDescriptor d(Handle<Name>(Name::cast(args->name())),
410
                          args, attribs);
411
    map->AppendDescriptor(&d);
412
  }
413
  Handle<AccessorInfo> caller =
414
      Accessors::FunctionCallerInfo(isolate(), attribs);
415
  {  // Add caller.
416
    CallbacksDescriptor d(Handle<Name>(Name::cast(caller->name())),
417
                          caller, attribs);
418
    map->AppendDescriptor(&d);
419
  }
420
  if (prototypeMode != DONT_ADD_PROTOTYPE) {
421
    if (prototypeMode == ADD_WRITEABLE_PROTOTYPE) {
422
      attribs = static_cast<PropertyAttributes>(attribs & ~READ_ONLY);
423
    }
424
    Handle<AccessorInfo> prototype =
425
        Accessors::FunctionPrototypeInfo(isolate(), attribs);
426
    CallbacksDescriptor d(Handle<Name>(Name::cast(prototype->name())),
427
                          prototype, attribs);
428
    map->AppendDescriptor(&d);
429
  }
430
}
431 432


433
Handle<Map> Genesis::CreateFunctionMap(PrototypePropertyMode prototype_mode) {
434
  Handle<Map> map = factory()->NewMap(JS_FUNCTION_TYPE, JSFunction::kSize);
435
  SetFunctionInstanceDescriptor(map, prototype_mode);
436 437
  map->set_function_with_prototype(prototype_mode != DONT_ADD_PROTOTYPE);
  return map;
438 439 440
}


441
Handle<JSFunction> Genesis::CreateEmptyFunction(Isolate* isolate) {
442 443 444
  // Allocate the map for function instances. Maps are allocated first and their
  // prototypes patched later, once empty function is created.

445 446
  // Functions with this map will not have a 'prototype' property, and
  // can not be used as constructors.
447 448
  Handle<Map> function_without_prototype_map =
      CreateFunctionMap(DONT_ADD_PROTOTYPE);
449
  native_context()->set_sloppy_function_without_prototype_map(
450
      *function_without_prototype_map);
451

452 453 454
  // Allocate the function map. This map is temporary, used only for processing
  // of builtins.
  // Later the map is replaced with writable prototype map, allocated below.
455
  Handle<Map> function_map = CreateFunctionMap(ADD_READONLY_PROTOTYPE);
456
  native_context()->set_sloppy_function_map(*function_map);
457 458
  native_context()->set_sloppy_function_with_readonly_prototype_map(
      *function_map);
459 460 461

  // The final map for functions. Writeable prototype.
  // This map is installed in MakeFunctionInstancePrototypeWritable.
462 463
  sloppy_function_map_writable_prototype_ =
      CreateFunctionMap(ADD_WRITEABLE_PROTOTYPE);
464

465 466
  Factory* factory = isolate->factory();

467
  Handle<String> object_name = factory->Object_string();
468 469

  {  // --- O b j e c t ---
470
    Handle<JSFunction> object_fun = factory->NewFunction(object_name);
471
    Handle<Map> object_function_map =
472
        factory->NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize);
473 474
    object_fun->set_initial_map(*object_function_map);
    object_function_map->set_constructor(*object_fun);
475 476
    object_function_map->set_unused_property_fields(
        JSObject::kInitialGlobalObjectUnusedPropertiesCount);
477

478
    native_context()->set_object_function(*object_fun);
479 480

    // Allocate a new prototype for the object function.
481 482
    Handle<JSObject> prototype = factory->NewJSObject(
        isolate->object_function(),
483
        TENURED);
484

485
    native_context()->set_initial_object_prototype(*prototype);
486 487 488 489
    // For bootstrapping set the array prototype to be the same as the object
    // prototype, otherwise the missing initial_array_prototype will cause
    // assertions during startup.
    native_context()->set_initial_array_prototype(*prototype);
490
    Accessors::FunctionSetPrototype(object_fun, prototype);
491 492 493 494
  }

  // Allocate the empty function as the prototype for function ECMAScript
  // 262 15.3.4.
495 496
  Handle<String> empty_string =
      factory->InternalizeOneByteString(STATIC_ASCII_VECTOR("Empty"));
497
  Handle<Code> code(isolate->builtins()->builtin(Builtins::kEmptyFunction));
498 499
  Handle<JSFunction> empty_function = factory->NewFunctionWithoutPrototype(
      empty_string, code);
500

501
  // --- E m p t y ---
502
  Handle<String> source = factory->NewStringFromStaticAscii("() {}");
503
  Handle<Script> script = factory->NewScript(source);
504 505 506 507 508
  script->set_type(Smi::FromInt(Script::TYPE_NATIVE));
  empty_function->shared()->set_script(*script);
  empty_function->shared()->set_start_position(0);
  empty_function->shared()->set_end_position(source->length());
  empty_function->shared()->DontAdaptArguments();
509 510

  // Set prototypes for the function maps.
511 512
  native_context()->sloppy_function_map()->set_prototype(*empty_function);
  native_context()->sloppy_function_without_prototype_map()->
513
      set_prototype(*empty_function);
514
  sloppy_function_map_writable_prototype_->set_prototype(*empty_function);
515

516
  // Allocate the function map first and then patch the prototype later
517 518
  Handle<Map> empty_function_map = CreateFunctionMap(DONT_ADD_PROTOTYPE);
  empty_function_map->set_prototype(
519
      native_context()->object_function()->prototype());
520
  empty_function->set_map(*empty_function_map);
521 522
  return empty_function;
}
523 524


525 526
void Genesis::SetStrictFunctionInstanceDescriptor(
    Handle<Map> map, PrototypePropertyMode prototypeMode) {
527
  int size = (prototypeMode == DONT_ADD_PROTOTYPE) ? 4 : 5;
528
  Map::EnsureDescriptorSlack(map, size);
529 530 531

  Handle<AccessorPair> arguments(factory()->NewAccessorPair());
  Handle<AccessorPair> caller(factory()->NewAccessorPair());
532 533 534 535
  PropertyAttributes rw_attribs =
      static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE);
  PropertyAttributes ro_attribs =
      static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY);
536

537 538
  Handle<AccessorInfo> length =
      Accessors::FunctionLengthInfo(isolate(), ro_attribs);
539
  {  // Add length.
540 541
    CallbacksDescriptor d(Handle<Name>(Name::cast(length->name())),
                          length, ro_attribs);
542
    map->AppendDescriptor(&d);
543
  }
544
  Handle<AccessorInfo> name =
545
      Accessors::FunctionNameInfo(isolate(), ro_attribs);
546
  {  // Add name.
547
    CallbacksDescriptor d(Handle<Name>(Name::cast(name->name())),
548
                          name, ro_attribs);
549
    map->AppendDescriptor(&d);
550
  }
551
  {  // Add arguments.
552
    CallbacksDescriptor d(factory()->arguments_string(), arguments,
553
                          rw_attribs);
554
    map->AppendDescriptor(&d);
555
  }
556
  {  // Add caller.
557
    CallbacksDescriptor d(factory()->caller_string(), caller, rw_attribs);
558
    map->AppendDescriptor(&d);
559 560
  }
  if (prototypeMode != DONT_ADD_PROTOTYPE) {
561
    // Add prototype.
562 563
    PropertyAttributes attribs =
        prototypeMode == ADD_WRITEABLE_PROTOTYPE ? rw_attribs : ro_attribs;
564 565 566 567
    Handle<AccessorInfo> prototype =
        Accessors::FunctionPrototypeInfo(isolate(), attribs);
    CallbacksDescriptor d(Handle<Name>(Name::cast(prototype->name())),
                          prototype, attribs);
568
    map->AppendDescriptor(&d);
569 570 571 572 573
  }
}


// ECMAScript 5th Edition, 13.2.3
574 575
Handle<JSFunction> Genesis::GetStrictPoisonFunction() {
  if (strict_poison_function.is_null()) {
576
    Handle<String> name = factory()->InternalizeOneByteString(
577
        STATIC_ASCII_VECTOR("ThrowTypeError"));
578 579
    Handle<Code> code(isolate()->builtins()->builtin(
        Builtins::kStrictModePoisonPill));
580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596
    strict_poison_function = factory()->NewFunctionWithoutPrototype(name, code);
    strict_poison_function->set_map(native_context()->sloppy_function_map());
    strict_poison_function->shared()->DontAdaptArguments();

    JSObject::PreventExtensions(strict_poison_function).Assert();
  }
  return strict_poison_function;
}


Handle<JSFunction> Genesis::GetGeneratorPoisonFunction() {
  if (generator_poison_function.is_null()) {
    Handle<String> name = factory()->InternalizeOneByteString(
        STATIC_ASCII_VECTOR("ThrowTypeError"));
    Handle<Code> code(isolate()->builtins()->builtin(
        Builtins::kGeneratorPoisonPill));
    generator_poison_function = factory()->NewFunctionWithoutPrototype(
597
        name, code);
598 599
    generator_poison_function->set_map(native_context()->sloppy_function_map());
    generator_poison_function->shared()->DontAdaptArguments();
600

601
    JSObject::PreventExtensions(generator_poison_function).Assert();
602
  }
603
  return generator_poison_function;
604 605 606
}


607
Handle<Map> Genesis::CreateStrictFunctionMap(
608
    PrototypePropertyMode prototype_mode,
609
    Handle<JSFunction> empty_function) {
610
  Handle<Map> map = factory()->NewMap(JS_FUNCTION_TYPE, JSFunction::kSize);
611
  SetStrictFunctionInstanceDescriptor(map, prototype_mode);
612 613 614 615 616 617 618 619
  map->set_function_with_prototype(prototype_mode != DONT_ADD_PROTOTYPE);
  map->set_prototype(*empty_function);
  return map;
}


void Genesis::CreateStrictModeFunctionMaps(Handle<JSFunction> empty) {
  // Allocate map for the prototype-less strict mode instances.
620 621 622 623
  Handle<Map> strict_function_without_prototype_map =
      CreateStrictFunctionMap(DONT_ADD_PROTOTYPE, empty);
  native_context()->set_strict_function_without_prototype_map(
      *strict_function_without_prototype_map);
624 625 626 627

  // Allocate map for the strict mode functions. This map is temporary, used
  // only for processing of builtins.
  // Later the map is replaced with writable prototype map, allocated below.
628 629 630
  Handle<Map> strict_function_map =
      CreateStrictFunctionMap(ADD_READONLY_PROTOTYPE, empty);
  native_context()->set_strict_function_map(*strict_function_map);
631 632 633

  // The final map for the strict mode functions. Writeable prototype.
  // This map is installed in MakeFunctionInstancePrototypeWritable.
634 635
  strict_function_map_writable_prototype_ =
      CreateStrictFunctionMap(ADD_WRITEABLE_PROTOTYPE, empty);
636

637
  // Complete the callbacks.
638 639 640
  PoisonArgumentsAndCaller(strict_function_without_prototype_map);
  PoisonArgumentsAndCaller(strict_function_map);
  PoisonArgumentsAndCaller(strict_function_map_writable_prototype_);
641 642 643 644 645 646 647
}


static void SetAccessors(Handle<Map> map,
                         Handle<String> name,
                         Handle<JSFunction> func) {
  DescriptorArray* descs = map->instance_descriptors();
648
  int number = descs->SearchWithCache(*name, *map);
649 650 651 652 653 654
  AccessorPair* accessors = AccessorPair::cast(descs->GetValue(number));
  accessors->set_getter(*func);
  accessors->set_setter(*func);
}


655 656 657 658 659 660 661 662 663 664 665
static void ReplaceAccessors(Handle<Map> map,
                             Handle<String> name,
                             PropertyAttributes attributes,
                             Handle<AccessorPair> accessor_pair) {
  DescriptorArray* descriptors = map->instance_descriptors();
  int idx = descriptors->SearchWithCache(*name, *map);
  CallbacksDescriptor descriptor(name, accessor_pair, attributes);
  descriptors->Replace(idx, &descriptor);
}


666
void Genesis::PoisonArgumentsAndCaller(Handle<Map> map) {
667 668
  SetAccessors(map, factory()->arguments_string(), GetStrictPoisonFunction());
  SetAccessors(map, factory()->caller_string(), GetStrictPoisonFunction());
669 670 671
}


672 673
static void AddToWeakNativeContextList(Context* context) {
  ASSERT(context->IsNativeContext());
674
  Heap* heap = context->GetIsolate()->heap();
675 676 677 678
#ifdef DEBUG
  { // NOLINT
    ASSERT(context->get(Context::NEXT_CONTEXT_LINK)->IsUndefined());
    // Check that context is not in the list yet.
679
    for (Object* current = heap->native_contexts_list();
680 681 682 683 684 685
         !current->IsUndefined();
         current = Context::cast(current)->get(Context::NEXT_CONTEXT_LINK)) {
      ASSERT(current != context);
    }
  }
#endif
686 687
  context->set(Context::NEXT_CONTEXT_LINK, heap->native_contexts_list());
  heap->set_native_contexts_list(context);
688 689 690
}


691
void Genesis::CreateRoots() {
692
  // Allocate the native context FixedArray first and then patch the
693 694
  // closure and extension object later (we need the empty function
  // and the global object, but in order to create those, we need the
695
  // native context).
696 697
  native_context_ = factory()->NewNativeContext();
  AddToWeakNativeContextList(*native_context());
698
  isolate()->set_context(*native_context());
699

700 701
  // Allocate the message listeners object.
  {
702
    v8::NeanderArray listeners(isolate());
703
    native_context()->set_message_listeners(*listeners.value());
704 705
  }
}
706 707


708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733
Handle<JSGlobalProxy> Genesis::CreateNewGlobals(
    v8::Handle<v8::ObjectTemplate> global_template,
    Handle<Object> global_object,
    Handle<GlobalObject>* inner_global_out) {
  // The argument global_template aka data is an ObjectTemplateInfo.
  // It has a constructor pointer that points at global_constructor which is a
  // FunctionTemplateInfo.
  // The global_constructor is used to create or reinitialize the global_proxy.
  // The global_constructor also has a prototype_template pointer that points at
  // js_global_template which is an ObjectTemplateInfo.
  // That in turn has a constructor pointer that points at
  // js_global_constructor which is a FunctionTemplateInfo.
  // js_global_constructor is used to make js_global_function
  // js_global_function is used to make the new inner_global.
  //
  // --- G l o b a l ---
  // Step 1: Create a fresh inner JSGlobalObject.
  Handle<JSFunction> js_global_function;
  Handle<ObjectTemplateInfo> js_global_template;
  if (!global_template.IsEmpty()) {
    // Get prototype template of the global_template.
    Handle<ObjectTemplateInfo> data =
        v8::Utils::OpenHandle(*global_template);
    Handle<FunctionTemplateInfo> global_constructor =
        Handle<FunctionTemplateInfo>(
            FunctionTemplateInfo::cast(data->constructor()));
734 735
    Handle<Object> proto_template(global_constructor->prototype_template(),
                                  isolate());
736 737 738
    if (!proto_template->IsUndefined()) {
      js_global_template =
          Handle<ObjectTemplateInfo>::cast(proto_template);
739
    }
740
  }
741

742
  if (js_global_template.is_null()) {
743
    Handle<String> name = Handle<String>(heap()->empty_string());
744
    Handle<Code> code = Handle<Code>(isolate()->builtins()->builtin(
745
        Builtins::kIllegal));
746
    js_global_function = factory()->NewFunction(
747
        name, code, JS_GLOBAL_OBJECT_TYPE, JSGlobalObject::kSize);
748 749 750 751 752
    // Change the constructor property of the prototype of the
    // hidden global function to refer to the Object function.
    Handle<JSObject> prototype =
        Handle<JSObject>(
            JSObject::cast(js_global_function->instance_prototype()));
753
    JSObject::SetOwnPropertyIgnoreAttributes(
754 755
        prototype, factory()->constructor_string(),
        isolate()->object_function(), NONE).Check();
756 757 758 759
  } else {
    Handle<FunctionTemplateInfo> js_global_constructor(
        FunctionTemplateInfo::cast(js_global_template->constructor()));
    js_global_function =
760
        factory()->CreateApiFunction(js_global_constructor,
761
                                     factory()->the_hole_value(),
762
                                     factory()->InnerGlobalObject);
763
  }
764

765
  js_global_function->initial_map()->set_is_hidden_prototype();
766
  js_global_function->initial_map()->set_dictionary_map(true);
767
  Handle<GlobalObject> inner_global =
768
      factory()->NewGlobalObject(js_global_function);
769 770
  if (inner_global_out != NULL) {
    *inner_global_out = inner_global;
771 772
  }

773 774 775
  // Step 2: create or re-initialize the global proxy object.
  Handle<JSFunction> global_proxy_function;
  if (global_template.IsEmpty()) {
776
    Handle<String> name = Handle<String>(heap()->empty_string());
777
    Handle<Code> code = Handle<Code>(isolate()->builtins()->builtin(
778
        Builtins::kIllegal));
779
    global_proxy_function = factory()->NewFunction(
780
        name, code, JS_GLOBAL_PROXY_TYPE, JSGlobalProxy::kSize);
781 782 783 784 785 786
  } else {
    Handle<ObjectTemplateInfo> data =
        v8::Utils::OpenHandle(*global_template);
    Handle<FunctionTemplateInfo> global_constructor(
            FunctionTemplateInfo::cast(data->constructor()));
    global_proxy_function =
787
        factory()->CreateApiFunction(global_constructor,
788
                                     factory()->the_hole_value(),
789
                                     factory()->OuterGlobalObject);
790 791
  }

792
  Handle<String> global_name = factory()->InternalizeOneByteString(
793
      STATIC_ASCII_VECTOR("global"));
794 795 796 797 798 799
  global_proxy_function->shared()->set_instance_class_name(*global_name);
  global_proxy_function->initial_map()->set_is_access_check_needed(true);

  // Set global_proxy.__proto__ to js_global after ConfigureGlobalObjects
  // Return the global proxy.

800
  Handle<JSGlobalProxy> global_proxy;
801 802
  if (global_object.location() != NULL) {
    ASSERT(global_object->IsJSGlobalProxy());
803
    global_proxy = Handle<JSGlobalProxy>::cast(global_object);
804
    factory()->ReinitializeJSGlobalProxy(global_proxy, global_proxy_function);
805
  } else {
806
    global_proxy = Handle<JSGlobalProxy>::cast(
807
        factory()->NewJSObject(global_proxy_function, TENURED));
808
    global_proxy->set_hash(heap()->undefined_value());
809
  }
810
  return global_proxy;
811 812 813 814 815
}


void Genesis::HookUpGlobalProxy(Handle<GlobalObject> inner_global,
                                Handle<JSGlobalProxy> global_proxy) {
816 817
  // Set the native context for the global object.
  inner_global->set_native_context(*native_context());
818
  inner_global->set_global_context(*native_context());
819
  inner_global->set_global_receiver(*global_proxy);
820
  global_proxy->set_native_context(*native_context());
821
  native_context()->set_global_proxy(*global_proxy);
822 823 824 825 826
}


void Genesis::HookUpInnerGlobal(Handle<GlobalObject> inner_global) {
  Handle<GlobalObject> inner_global_from_snapshot(
827 828 829 830 831
      GlobalObject::cast(native_context()->extension()));
  Handle<JSBuiltinsObject> builtins_global(native_context()->builtins());
  native_context()->set_extension(*inner_global);
  native_context()->set_global_object(*inner_global);
  native_context()->set_security_token(*inner_global);
832 833
  static const PropertyAttributes attributes =
      static_cast<PropertyAttributes>(READ_ONLY | DONT_DELETE);
834 835 836 837 838
  Runtime::ForceSetObjectProperty(builtins_global,
                                  factory()->InternalizeOneByteString(
                                      STATIC_ASCII_VECTOR("global")),
                                  inner_global,
                                  attributes).Assert();
839
  // Set up the reference from the global object to the builtins object.
840 841 842 843 844 845 846 847
  JSGlobalObject::cast(*inner_global)->set_builtins(*builtins_global);
  TransferNamedProperties(inner_global_from_snapshot, inner_global);
  TransferIndexedProperties(inner_global_from_snapshot, inner_global);
}


// This is only called if we are not using snapshots.  The equivalent
// work in the snapshot case is done in HookUpInnerGlobal.
848
void Genesis::InitializeGlobal(Handle<GlobalObject> inner_global,
849
                               Handle<JSFunction> empty_function) {
850
  // --- N a t i v e   C o n t e x t ---
851
  // Use the empty function as closure (no scope info).
852 853
  native_context()->set_closure(*empty_function);
  native_context()->set_previous(NULL);
854
  // Set extension and global object.
855
  native_context()->set_extension(*inner_global);
856
  native_context()->set_global_object(*inner_global);
857 858 859 860
  // Security setup: Set the security token of the global object to
  // its the inner global. This makes the security check between two
  // different contexts fail by default even in case of global
  // object reinitialization.
861
  native_context()->set_security_token(*inner_global);
862

863
  Isolate* isolate = inner_global->GetIsolate();
864 865 866
  Factory* factory = isolate->factory();
  Heap* heap = isolate->heap();

867
  Handle<String> object_name = factory->Object_string();
868
  JSObject::SetOwnPropertyIgnoreAttributes(
869 870
      inner_global, object_name,
      isolate->object_function(), DONT_ENUM).Check();
871

872
  Handle<JSObject> global(native_context()->global_object());
873 874 875

  // Install global Function object
  InstallFunction(global, "Function", JS_FUNCTION_TYPE, JSFunction::kSize,
876
                  empty_function, Builtins::kIllegal);
877 878 879 880

  {  // --- A r r a y ---
    Handle<JSFunction> array_function =
        InstallFunction(global, "Array", JS_ARRAY_TYPE, JSArray::kSize,
881
                        isolate->initial_object_prototype(),
882
                        Builtins::kArrayCode);
883
    array_function->shared()->DontAdaptArguments();
884
    array_function->shared()->set_function_data(Smi::FromInt(kArrayCode));
885 886 887 888

    // This seems a bit hackish, but we need to make sure Array.length
    // is 1.
    array_function->shared()->set_length(1);
889

890
    Handle<Map> initial_map(array_function->initial_map());
891 892 893 894

    // This assert protects an optimization in
    // HGraphBuilder::JSArrayBuilder::EmitMapCode()
    ASSERT(initial_map->elements_kind() == GetInitialFastElementsKind());
895
    Map::EnsureDescriptorSlack(initial_map, 1);
896

897 898 899
    PropertyAttributes attribs = static_cast<PropertyAttributes>(
        DONT_ENUM | DONT_DELETE);

900 901
    Handle<AccessorInfo> array_length =
        Accessors::ArrayLengthInfo(isolate, attribs);
902
    {  // Add length.
903 904 905
      CallbacksDescriptor d(
          Handle<Name>(Name::cast(array_length->name())),
          array_length, attribs);
906
      array_function->initial_map()->AppendDescriptor(&d);
907
    }
908 909 910 911 912

    // array_function is used internally. JS code creating array object should
    // search for the 'Array' property on the global object and use that one
    // as the constructor. 'Array' property on a global object can be
    // overwritten by JS code.
913
    native_context()->set_array_function(*array_function);
914

915 916 917
    // Cache the array maps, needed by ArrayConstructorStub
    CacheInitialJSArrayMaps(native_context(), initial_map);
    ArrayConstructorStub array_constructor_stub(isolate);
918
    Handle<Code> code = array_constructor_stub.GetCode();
919
    array_function->shared()->set_construct_stub(*code);
920 921 922 923 924
  }

  {  // --- N u m b e r ---
    Handle<JSFunction> number_fun =
        InstallFunction(global, "Number", JS_VALUE_TYPE, JSValue::kSize,
925
                        isolate->initial_object_prototype(),
926
                        Builtins::kIllegal);
927
    native_context()->set_number_function(*number_fun);
928 929 930 931 932
  }

  {  // --- B o o l e a n ---
    Handle<JSFunction> boolean_fun =
        InstallFunction(global, "Boolean", JS_VALUE_TYPE, JSValue::kSize,
933
                        isolate->initial_object_prototype(),
934
                        Builtins::kIllegal);
935
    native_context()->set_boolean_function(*boolean_fun);
936 937 938 939 940
  }

  {  // --- S t r i n g ---
    Handle<JSFunction> string_fun =
        InstallFunction(global, "String", JS_VALUE_TYPE, JSValue::kSize,
941
                        isolate->initial_object_prototype(),
942
                        Builtins::kIllegal);
943
    string_fun->shared()->set_construct_stub(
944
        isolate->builtins()->builtin(Builtins::kStringConstructCode));
945
    native_context()->set_string_function(*string_fun);
946

947
    Handle<Map> string_map =
948
        Handle<Map>(native_context()->string_function()->initial_map());
949
    Map::EnsureDescriptorSlack(string_map, 1);
950

951 952
    PropertyAttributes attribs = static_cast<PropertyAttributes>(
        DONT_ENUM | DONT_DELETE | READ_ONLY);
953 954
    Handle<AccessorInfo> string_length(
        Accessors::StringLengthInfo(isolate, attribs));
955 956

    {  // Add length.
957
      CallbacksDescriptor d(factory->length_string(), string_length, attribs);
958
      string_map->AppendDescriptor(&d);
959
    }
960 961 962 963 964
  }

  {  // --- D a t e ---
    // Builtin functions for Date.prototype.
    Handle<JSFunction> date_fun =
965
        InstallFunction(global, "Date", JS_DATE_TYPE, JSDate::kSize,
966
                        isolate->initial_object_prototype(),
967
                        Builtins::kIllegal);
968

969
    native_context()->set_date_function(*date_fun);
970 971 972 973 974 975
  }


  {  // -- R e g E x p
    // Builtin functions for RegExp.prototype.
    Handle<JSFunction> regexp_fun =
976
        InstallFunction(global, "RegExp", JS_REGEXP_TYPE, JSRegExp::kSize,
977
                        isolate->initial_object_prototype(),
978
                        Builtins::kIllegal);
979
    native_context()->set_regexp_function(*regexp_fun);
980 981 982 983 984 985 986 987

    ASSERT(regexp_fun->has_initial_map());
    Handle<Map> initial_map(regexp_fun->initial_map());

    ASSERT_EQ(0, initial_map->inobject_properties());

    PropertyAttributes final =
        static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY);
988
    Map::EnsureDescriptorSlack(initial_map, 5);
989

990 991
    {
      // ECMA-262, section 15.10.7.1.
992
      FieldDescriptor field(factory->source_string(),
993
                            JSRegExp::kSourceFieldIndex,
994 995
                            final,
                            Representation::Tagged());
996
      initial_map->AppendDescriptor(&field);
997 998 999
    }
    {
      // ECMA-262, section 15.10.7.2.
1000
      FieldDescriptor field(factory->global_string(),
1001
                            JSRegExp::kGlobalFieldIndex,
1002 1003
                            final,
                            Representation::Tagged());
1004
      initial_map->AppendDescriptor(&field);
1005 1006 1007
    }
    {
      // ECMA-262, section 15.10.7.3.
1008
      FieldDescriptor field(factory->ignore_case_string(),
1009
                            JSRegExp::kIgnoreCaseFieldIndex,
1010 1011
                            final,
                            Representation::Tagged());
1012
      initial_map->AppendDescriptor(&field);
1013 1014 1015
    }
    {
      // ECMA-262, section 15.10.7.4.
1016
      FieldDescriptor field(factory->multiline_string(),
1017
                            JSRegExp::kMultilineFieldIndex,
1018 1019
                            final,
                            Representation::Tagged());
1020
      initial_map->AppendDescriptor(&field);
1021 1022 1023 1024 1025
    }
    {
      // ECMA-262, section 15.10.7.5.
      PropertyAttributes writable =
          static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE);
1026
      FieldDescriptor field(factory->last_index_string(),
1027
                            JSRegExp::kLastIndexFieldIndex,
1028 1029
                            writable,
                            Representation::Tagged());
1030
      initial_map->AppendDescriptor(&field);
1031 1032 1033 1034 1035 1036 1037
    }

    initial_map->set_inobject_properties(5);
    initial_map->set_pre_allocated_property_fields(5);
    initial_map->set_unused_property_fields(0);
    initial_map->set_instance_size(
        initial_map->instance_size() + 5 * kPointerSize);
1038
    initial_map->set_visitor_id(StaticVisitorBase::GetVisitorId(*initial_map));
1039 1040

    // RegExp prototype object is itself a RegExp.
1041
    Handle<Map> proto_map = Map::Copy(initial_map);
1042
    proto_map->set_prototype(native_context()->initial_object_prototype());
1043 1044
    Handle<JSObject> proto = factory->NewJSObjectFromMap(proto_map);
    proto->InObjectPropertyAtPut(JSRegExp::kSourceFieldIndex,
1045
                                 heap->query_colon_string());
1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058
    proto->InObjectPropertyAtPut(JSRegExp::kGlobalFieldIndex,
                                 heap->false_value());
    proto->InObjectPropertyAtPut(JSRegExp::kIgnoreCaseFieldIndex,
                                 heap->false_value());
    proto->InObjectPropertyAtPut(JSRegExp::kMultilineFieldIndex,
                                 heap->false_value());
    proto->InObjectPropertyAtPut(JSRegExp::kLastIndexFieldIndex,
                                 Smi::FromInt(0),
                                 SKIP_WRITE_BARRIER);  // It's a Smi.
    initial_map->set_prototype(*proto);
    factory->SetRegExpIrregexpData(Handle<JSRegExp>::cast(proto),
                                   JSRegExp::IRREGEXP, factory->empty_string(),
                                   JSRegExp::Flags(0), 0);
1059 1060
  }

1061
  {  // -- J S O N
1062
    Handle<String> name = factory->InternalizeUtf8String("JSON");
1063
    Handle<JSFunction> cons = factory->NewFunction(name);
1064 1065
    JSFunction::SetInstancePrototype(cons,
        Handle<Object>(native_context()->initial_object_prototype(), isolate));
1066
    cons->SetInstanceClassName(*name);
1067
    Handle<JSObject> json_object = factory->NewJSObject(cons, TENURED);
1068
    ASSERT(json_object->IsJSObject());
1069
    JSObject::SetOwnPropertyIgnoreAttributes(
1070
        global, name, json_object, DONT_ENUM).Check();
1071
    native_context()->set_json_object(*json_object);
1072 1073
  }

1074 1075 1076 1077 1078 1079
  { // -- A r r a y B u f f e r
    Handle<JSFunction> array_buffer_fun =
        InstallFunction(
            global, "ArrayBuffer", JS_ARRAY_BUFFER_TYPE,
            JSArrayBuffer::kSizeWithInternalFields,
            isolate->initial_object_prototype(),
1080
            Builtins::kIllegal);
1081 1082 1083 1084
    native_context()->set_array_buffer_fun(*array_buffer_fun);
  }

  { // -- T y p e d A r r a y s
1085 1086
#define INSTALL_TYPED_ARRAY(Type, type, TYPE, ctype, size)                    \
    {                                                                         \
1087 1088 1089 1090 1091 1092
      Handle<JSFunction> fun;                                                 \
      Handle<Map> external_map;                                               \
      InstallTypedArray(#Type "Array",                                        \
          TYPE##_ELEMENTS,                                                    \
          &fun,                                                               \
          &external_map);                                                     \
1093
      native_context()->set_##type##_array_fun(*fun);                         \
1094
      native_context()->set_##type##_array_external_map(*external_map);       \
1095 1096 1097
    }
    TYPED_ARRAYS(INSTALL_TYPED_ARRAY)
#undef INSTALL_TYPED_ARRAY
1098 1099 1100 1101 1102 1103

    Handle<JSFunction> data_view_fun =
        InstallFunction(
            global, "DataView", JS_DATA_VIEW_TYPE,
            JSDataView::kSizeWithInternalFields,
            isolate->initial_object_prototype(),
1104
            Builtins::kIllegal);
1105 1106 1107
    native_context()->set_data_view_fun(*data_view_fun);
  }

1108 1109
  // -- W e a k M a p
  InstallFunction(global, "WeakMap", JS_WEAK_MAP_TYPE, JSWeakMap::kSize,
1110
                  isolate->initial_object_prototype(), Builtins::kIllegal);
1111 1112
  // -- W e a k S e t
  InstallFunction(global, "WeakSet", JS_WEAK_SET_TYPE, JSWeakSet::kSize,
1113
                  isolate->initial_object_prototype(), Builtins::kIllegal);
1114

1115 1116 1117 1118
  {  // --- arguments_boilerplate_
    // Make sure we can recognize argument objects at runtime.
    // This is done by introducing an anonymous function with
    // class_name equals 'Arguments'.
1119
    Handle<String> arguments_string = factory->InternalizeOneByteString(
1120
        STATIC_ASCII_VECTOR("Arguments"));
1121
    Handle<Code> code(isolate->builtins()->builtin(Builtins::kIllegal));
1122

1123 1124
    Handle<JSFunction> function = factory->NewFunctionWithoutPrototype(
        arguments_string, code);
1125
    ASSERT(!function->has_initial_map());
1126
    function->shared()->set_instance_class_name(*arguments_string);
1127
    function->shared()->set_expected_nof_properties(2);
1128 1129
    function->set_prototype_or_initial_map(
        native_context()->object_function()->prototype());
1130
    Handle<JSObject> result = factory->NewJSObject(function);
1131

1132
    native_context()->set_sloppy_arguments_boilerplate(*result);
1133 1134
    // Note: length must be added as the first property and
    //       callee must be added as the second property.
1135
    JSObject::SetOwnPropertyIgnoreAttributes(
1136 1137 1138
        result, factory->length_string(),
        factory->undefined_value(), DONT_ENUM,
        Object::FORCE_TAGGED, FORCE_FIELD).Check();
1139
    JSObject::SetOwnPropertyIgnoreAttributes(
1140 1141 1142
        result, factory->callee_string(),
        factory->undefined_value(), DONT_ENUM,
        Object::FORCE_TAGGED, FORCE_FIELD).Check();
1143

1144
#ifdef DEBUG
1145
    LookupResult lookup(isolate);
1146
    result->LookupOwn(factory->callee_string(), &lookup);
1147
    ASSERT(lookup.IsField());
1148
    ASSERT(lookup.GetFieldIndex().field_index() == Heap::kArgumentsCalleeIndex);
1149

1150
    result->LookupOwn(factory->length_string(), &lookup);
1151
    ASSERT(lookup.IsField());
1152
    ASSERT(lookup.GetFieldIndex().field_index() == Heap::kArgumentsLengthIndex);
1153 1154 1155 1156 1157 1158

    ASSERT(result->map()->inobject_properties() > Heap::kArgumentsCalleeIndex);
    ASSERT(result->map()->inobject_properties() > Heap::kArgumentsLengthIndex);

    // Check the state of the object.
    ASSERT(result->HasFastProperties());
1159
    ASSERT(result->HasFastObjectElements());
1160 1161 1162
#endif
  }

1163 1164 1165
  {  // --- aliased_arguments_boilerplate_
    // Set up a well-formed parameter map to make assertions happy.
    Handle<FixedArray> elements = factory->NewFixedArray(2);
1166
    elements->set_map(heap->sloppy_arguments_elements_map());
1167 1168 1169 1170 1171
    Handle<FixedArray> array;
    array = factory->NewFixedArray(0);
    elements->set(0, *array);
    array = factory->NewFixedArray(0);
    elements->set(1, *array);
1172

1173 1174
    Handle<Map> old_map(
        native_context()->sloppy_arguments_boilerplate()->map());
1175
    Handle<Map> new_map = Map::Copy(old_map);
1176 1177 1178 1179
    new_map->set_pre_allocated_property_fields(2);
    Handle<JSObject> result = factory->NewJSObjectFromMap(new_map);
    // Set elements kind after allocating the object because
    // NewJSObjectFromMap assumes a fast elements map.
1180
    new_map->set_elements_kind(SLOPPY_ARGUMENTS_ELEMENTS);
1181
    result->set_elements(*elements);
1182
    ASSERT(result->HasSloppyArgumentsElements());
1183
    native_context()->set_aliased_arguments_boilerplate(*result);
1184 1185
  }

1186 1187 1188 1189 1190
  {  // --- strict mode arguments boilerplate
    const PropertyAttributes attributes =
      static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY);

    // Create the ThrowTypeError functions.
1191 1192
    Handle<AccessorPair> callee = factory->NewAccessorPair();
    Handle<AccessorPair> caller = factory->NewAccessorPair();
1193

1194
    Handle<JSFunction> poison = GetStrictPoisonFunction();
1195 1196

    // Install the ThrowTypeError functions.
1197 1198 1199 1200
    callee->set_getter(*poison);
    callee->set_setter(*poison);
    caller->set_getter(*poison);
    caller->set_setter(*poison);
1201

1202 1203
    // Create the map. Allocate one in-object field for length.
    Handle<Map> map = factory->NewMap(JS_OBJECT_TYPE,
1204
                                      Heap::kStrictArgumentsObjectSize);
1205
    // Create the descriptor array for the arguments object.
1206
    Map::EnsureDescriptorSlack(map, 3);
1207

1208
    {  // length
1209
      FieldDescriptor d(
1210
          factory->length_string(), 0, DONT_ENUM, Representation::Tagged());
1211
      map->AppendDescriptor(&d);
1212 1213
    }
    {  // callee
1214 1215
      CallbacksDescriptor d(factory->callee_string(),
                            callee,
1216
                            attributes);
1217
      map->AppendDescriptor(&d);
1218 1219
    }
    {  // caller
1220 1221
      CallbacksDescriptor d(factory->caller_string(),
                            caller,
1222
                            attributes);
1223
      map->AppendDescriptor(&d);
1224
    }
1225

1226
    map->set_function_with_prototype(true);
1227
    map->set_prototype(native_context()->object_function()->prototype());
1228 1229 1230
    map->set_pre_allocated_property_fields(1);
    map->set_inobject_properties(1);

1231
    // Copy constructor from the sloppy arguments boilerplate.
1232
    map->set_constructor(
1233
      native_context()->sloppy_arguments_boilerplate()->map()->constructor());
1234

1235
    // Allocate the arguments boilerplate object.
1236
    Handle<JSObject> result = factory->NewJSObjectFromMap(map);
1237
    native_context()->set_strict_arguments_boilerplate(*result);
1238 1239

    // Add length property only for strict mode boilerplate.
1240
    JSObject::SetOwnPropertyIgnoreAttributes(
1241 1242
        result, factory->length_string(),
        factory->undefined_value(), DONT_ENUM).Check();
1243 1244

#ifdef DEBUG
1245
    LookupResult lookup(isolate);
1246
    result->LookupOwn(factory->length_string(), &lookup);
1247
    ASSERT(lookup.IsField());
1248
    ASSERT(lookup.GetFieldIndex().field_index() == Heap::kArgumentsLengthIndex);
1249

1250
    ASSERT(result->map()->inobject_properties() > Heap::kArgumentsLengthIndex);
1251

1252 1253
    // Check the state of the object.
    ASSERT(result->HasFastProperties());
1254
    ASSERT(result->HasFastObjectElements());
1255
#endif
1256 1257 1258 1259
  }

  {  // --- context extension
    // Create a function for the context extension objects.
1260
    Handle<Code> code = Handle<Code>(
1261
        isolate->builtins()->builtin(Builtins::kIllegal));
1262
    Handle<JSFunction> context_extension_fun = factory->NewFunction(
1263 1264
        factory->empty_string(), code, JS_CONTEXT_EXTENSION_OBJECT_TYPE,
        JSObject::kHeaderSize);
1265

1266 1267
    Handle<String> name = factory->InternalizeOneByteString(
        STATIC_ASCII_VECTOR("context_extension"));
1268
    context_extension_fun->shared()->set_instance_class_name(*name);
1269
    native_context()->set_context_extension_function(*context_extension_fun);
1270 1271
  }

1272 1273

  {
1274
    // Set up the call-as-function delegate.
1275
    Handle<Code> code =
1276
        Handle<Code>(isolate->builtins()->builtin(
1277
            Builtins::kHandleApiCallAsFunction));
1278
    Handle<JSFunction> delegate = factory->NewFunction(
1279
        factory->empty_string(), code, JS_OBJECT_TYPE, JSObject::kHeaderSize);
1280
    native_context()->set_call_as_function_delegate(*delegate);
1281 1282 1283 1284
    delegate->shared()->DontAdaptArguments();
  }

  {
1285
    // Set up the call-as-constructor delegate.
1286
    Handle<Code> code =
1287
        Handle<Code>(isolate->builtins()->builtin(
1288
            Builtins::kHandleApiCallAsConstructor));
1289
    Handle<JSFunction> delegate = factory->NewFunction(
1290
        factory->empty_string(), code, JS_OBJECT_TYPE, JSObject::kHeaderSize);
1291
    native_context()->set_call_as_constructor_delegate(*delegate);
1292 1293
    delegate->shared()->DontAdaptArguments();
  }
1294

1295
  // Initialize the embedder data slot.
1296
  Handle<FixedArray> embedder_data = factory->NewFixedArray(3);
1297
  native_context()->set_embedder_data(*embedder_data);
1298 1299 1300
}


1301 1302 1303 1304 1305
void Genesis::InstallTypedArray(
    const char* name,
    ElementsKind elements_kind,
    Handle<JSFunction>* fun,
    Handle<Map>* external_map) {
1306
  Handle<JSObject> global = Handle<JSObject>(native_context()->global_object());
1307 1308 1309
  Handle<JSFunction> result = InstallFunction(
      global, name, JS_TYPED_ARRAY_TYPE, JSTypedArray::kSize,
      isolate()->initial_object_prototype(), Builtins::kIllegal);
1310 1311

  Handle<Map> initial_map = isolate()->factory()->NewMap(
1312 1313 1314
      JS_TYPED_ARRAY_TYPE,
      JSTypedArray::kSizeWithInternalFields,
      elements_kind);
1315 1316
  result->set_initial_map(*initial_map);
  initial_map->set_constructor(*result);
1317 1318 1319 1320
  *fun = result;

  ElementsKind external_kind = GetNextTransitionElementsKind(elements_kind);
  *external_map = Map::AsElementsKind(initial_map, external_kind);
1321 1322 1323
}


1324
void Genesis::InitializeExperimentalGlobal() {
1325
  Handle<JSObject> global = Handle<JSObject>(native_context()->global_object());
1326

1327
  // TODO(mstarzinger): Move this into Genesis::InitializeGlobal once we no
1328 1329 1330 1331
  // longer need to live behind flags, so functions get added to the snapshot.

  if (FLAG_harmony_symbols) {
    // --- S y m b o l ---
1332 1333 1334
    Handle<JSFunction> symbol_fun = InstallFunction(
        global, "Symbol", JS_VALUE_TYPE, JSValue::kSize,
        isolate()->initial_object_prototype(), Builtins::kIllegal);
1335 1336 1337
    native_context()->set_symbol_function(*symbol_fun);
  }

1338
  if (FLAG_harmony_collections) {
1339 1340
    // -- M a p
    InstallFunction(global, "Map", JS_MAP_TYPE, JSMap::kSize,
1341
                    isolate()->initial_object_prototype(), Builtins::kIllegal);
1342 1343
    // -- S e t
    InstallFunction(global, "Set", JS_SET_TYPE, JSSet::kSize,
1344
                    isolate()->initial_object_prototype(), Builtins::kIllegal);
1345
    {   // -- S e t I t e r a t o r
1346 1347 1348 1349 1350 1351 1352 1353
      Handle<JSObject> builtins(native_context()->builtins());
      Handle<JSFunction> set_iterator_function =
          InstallFunction(builtins, "SetIterator", JS_SET_ITERATOR_TYPE,
                          JSSetIterator::kSize,
                          isolate()->initial_object_prototype(),
                          Builtins::kIllegal);
      native_context()->set_set_iterator_map(
          set_iterator_function->initial_map());
1354 1355
    }
    {   // -- M a p I t e r a t o r
1356 1357 1358 1359 1360 1361 1362 1363
      Handle<JSObject> builtins(native_context()->builtins());
      Handle<JSFunction> map_iterator_function =
          InstallFunction(builtins, "MapIterator", JS_MAP_ITERATOR_TYPE,
                          JSMapIterator::kSize,
                          isolate()->initial_object_prototype(),
                          Builtins::kIllegal);
      native_context()->set_map_iterator_map(
          map_iterator_function->initial_map());
1364
    }
1365 1366
  }

1367 1368 1369 1370 1371
  if (FLAG_harmony_generators) {
    // Create generator meta-objects and install them on the builtins object.
    Handle<JSObject> builtins(native_context()->builtins());
    Handle<JSObject> generator_object_prototype =
        factory()->NewJSObject(isolate()->object_function(), TENURED);
1372 1373 1374 1375
    Handle<JSFunction> generator_function_prototype = InstallFunction(
        builtins, "GeneratorFunctionPrototype", JS_FUNCTION_TYPE,
        JSFunction::kHeaderSize, generator_object_prototype,
        Builtins::kIllegal);
1376 1377
    InstallFunction(builtins, "GeneratorFunction",
                    JS_FUNCTION_TYPE, JSFunction::kSize,
1378
                    generator_function_prototype, Builtins::kIllegal);
1379 1380 1381

    // Create maps for generator functions and their prototypes.  Store those
    // maps in the native context.
1382 1383
    Handle<Map> sloppy_function_map(native_context()->sloppy_function_map());
    Handle<Map> generator_function_map = Map::Copy(sloppy_function_map);
1384
    generator_function_map->set_prototype(*generator_function_prototype);
1385 1386
    native_context()->set_sloppy_generator_function_map(
        *generator_function_map);
1387

1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404
    // The "arguments" and "caller" instance properties aren't specified, so
    // technically we could leave them out.  They make even less sense for
    // generators than for functions.  Still, the same argument that it makes
    // sense to keep them around but poisoned in strict mode applies to
    // generators as well.  With poisoned accessors, naive callers can still
    // iterate over the properties without accessing them.
    //
    // We can't use PoisonArgumentsAndCaller because that mutates accessor pairs
    // in place, and the initial state of the generator function map shares the
    // accessor pair with sloppy functions.  Also the error message should be
    // different.  Also unhappily, we can't use the API accessors to implement
    // poisoning, because API accessors present themselves as data properties,
    // not accessor properties, and so getOwnPropertyDescriptor raises an
    // exception as it tries to get the values.  Sadness.
    Handle<AccessorPair> poison_pair(factory()->NewAccessorPair());
    PropertyAttributes rw_attribs =
        static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE);
1405 1406 1407
    Handle<JSFunction> poison_function = GetGeneratorPoisonFunction();
    poison_pair->set_getter(*poison_function);
    poison_pair->set_setter(*poison_function);
1408 1409 1410 1411 1412 1413 1414 1415 1416
    ReplaceAccessors(generator_function_map, factory()->arguments_string(),
        rw_attribs, poison_pair);
    ReplaceAccessors(generator_function_map, factory()->caller_string(),
        rw_attribs, poison_pair);

    Handle<Map> strict_function_map(native_context()->strict_function_map());
    Handle<Map> strict_generator_function_map = Map::Copy(strict_function_map);
    // "arguments" and "caller" already poisoned.
    strict_generator_function_map->set_prototype(*generator_function_prototype);
1417
    native_context()->set_strict_generator_function_map(
1418
        *strict_generator_function_map);
1419

1420 1421 1422
    Handle<JSFunction> object_function(native_context()->object_function());
    Handle<Map> generator_object_prototype_map = Map::Create(
        object_function, 0);
1423 1424 1425 1426
    generator_object_prototype_map->set_prototype(
        *generator_object_prototype);
    native_context()->set_generator_object_prototype_map(
        *generator_object_prototype_map);
1427 1428 1429 1430 1431
  }

  if (FLAG_harmony_collections || FLAG_harmony_generators) {
    // Collection forEach uses an iterator result object.
    // Generators return iteraror result objects.
1432

1433
    STATIC_ASSERT(JSGeneratorObject::kResultPropertyCount == 2);
1434 1435 1436
    Handle<JSFunction> object_function(native_context()->object_function());
    ASSERT(object_function->initial_map()->inobject_properties() == 0);
    Handle<Map> iterator_result_map = Map::Create(
1437
        object_function, JSGeneratorObject::kResultPropertyCount);
1438
    ASSERT(iterator_result_map->inobject_properties() ==
1439
        JSGeneratorObject::kResultPropertyCount);
1440
    Map::EnsureDescriptorSlack(
1441
        iterator_result_map, JSGeneratorObject::kResultPropertyCount);
1442

1443
    FieldDescriptor value_descr(isolate()->factory()->value_string(),
1444 1445 1446
                                JSGeneratorObject::kResultValuePropertyIndex,
                                NONE,
                                Representation::Tagged());
1447
    iterator_result_map->AppendDescriptor(&value_descr);
1448

1449
    FieldDescriptor done_descr(isolate()->factory()->done_string(),
1450 1451 1452
                               JSGeneratorObject::kResultDonePropertyIndex,
                               NONE,
                               Representation::Tagged());
1453
    iterator_result_map->AppendDescriptor(&done_descr);
1454

1455
    iterator_result_map->set_unused_property_fields(0);
1456
    ASSERT_EQ(JSGeneratorObject::kResultSize,
1457 1458
              iterator_result_map->instance_size());
    native_context()->set_iterator_result_map(*iterator_result_map);
1459
  }
1460 1461 1462
}


1463
bool Genesis::CompileBuiltin(Isolate* isolate, int index) {
1464
  Vector<const char> name = Natives::GetScriptName(index);
1465
  Handle<String> source_code =
1466
      isolate->bootstrapper()->NativesSourceLookup(index);
1467
  return CompileNative(isolate, name, source_code);
1468 1469 1470
}


1471 1472 1473
bool Genesis::CompileExperimentalBuiltin(Isolate* isolate, int index) {
  Vector<const char> name = ExperimentalNatives::GetScriptName(index);
  Factory* factory = isolate->factory();
1474 1475 1476
  Handle<String> source_code;
  ASSIGN_RETURN_ON_EXCEPTION_VALUE(
      isolate, source_code,
1477
      factory->NewStringFromAscii(
1478 1479
          ExperimentalNatives::GetRawScriptSource(index)),
      false);
1480
  return CompileNative(isolate, name, source_code);
1481 1482 1483
}


1484 1485 1486 1487
bool Genesis::CompileNative(Isolate* isolate,
                            Vector<const char> name,
                            Handle<String> source) {
  HandleScope scope(isolate);
1488
  SuppressDebug compiling_natives(isolate->debug());
1489 1490 1491 1492 1493
  // During genesis, the boilerplate for stack overflow won't work until the
  // environment has been at least partially initialized. Add a stack check
  // before entering JS code to catch overflow early.
  StackLimitCheck check(isolate);
  if (check.HasOverflowed()) return false;
1494

1495 1496
  bool result = CompileScriptCached(isolate,
                                    name,
1497 1498 1499
                                    source,
                                    NULL,
                                    NULL,
1500
                                    Handle<Context>(isolate->context()),
1501
                                    true);
1502 1503
  ASSERT(isolate->has_pending_exception() != result);
  if (!result) isolate->clear_pending_exception();
1504 1505 1506 1507
  return result;
}


1508 1509
bool Genesis::CompileScriptCached(Isolate* isolate,
                                  Vector<const char> name,
1510 1511 1512
                                  Handle<String> source,
                                  SourceCodeCache* cache,
                                  v8::Extension* extension,
1513
                                  Handle<Context> top_context,
1514
                                  bool use_runtime_context) {
1515 1516
  Factory* factory = isolate->factory();
  HandleScope scope(isolate);
1517
  Handle<SharedFunctionInfo> function_info;
1518 1519 1520

  // If we can't find the function in the cache, we compile a new
  // function and insert it into the cache.
1521
  if (cache == NULL || !cache->Lookup(name, &function_info)) {
1522
    ASSERT(source->IsOneByteRepresentation());
1523 1524
    Handle<String> script_name =
        factory->NewStringFromUtf8(name).ToHandleChecked();
1525
    function_info = Compiler::CompileScript(
1526 1527 1528 1529
        source,
        script_name,
        0,
        0,
1530
        false,
1531
        top_context,
1532 1533
        extension,
        NULL,
1534
        NO_CACHED_DATA,
1535 1536
        use_runtime_context ? NATIVES_CODE : NOT_NATIVES_CODE);
    if (function_info.is_null()) return false;
1537
    if (cache != NULL) cache->Add(name, function_info);
1538 1539
  }

1540
  // Set up the function context. Conceptually, we should clone the
1541 1542
  // function before overwriting the context but since we're in a
  // single-threaded environment it is not strictly necessary.
1543
  ASSERT(top_context->IsNativeContext());
1544 1545
  Handle<Context> context =
      Handle<Context>(use_runtime_context
1546 1547
                      ? Handle<Context>(top_context->runtime_context())
                      : top_context);
1548
  Handle<JSFunction> fun =
1549
      factory->NewFunctionFromSharedFunctionInfo(function_info, context);
1550

sgjesse@chromium.org's avatar
sgjesse@chromium.org committed
1551
  // Call function using either the runtime object or the global
1552 1553 1554
  // object as the receiver. Provide no parameters.
  Handle<Object> receiver =
      Handle<Object>(use_runtime_context
1555
                     ? top_context->builtins()
1556 1557
                     : top_context->global_object(),
                     isolate);
1558 1559
  return !Execution::Call(
      isolate, fun, receiver, 0, NULL).is_null();
1560 1561 1562
}


1563 1564
#define INSTALL_NATIVE(Type, name, var)                                        \
  Handle<String> var##_name =                                                  \
1565 1566 1567
      factory()->InternalizeOneByteString(STATIC_ASCII_VECTOR(name));          \
  Handle<Object> var##_native = Object::GetProperty(                           \
      handle(native_context()->builtins()), var##_name).ToHandleChecked();     \
1568
  native_context()->set_##var(Type::cast(*var##_native));
1569

1570

1571
void Genesis::InstallNativeFunctions() {
1572
  HandleScope scope(isolate());
1573
  INSTALL_NATIVE(JSFunction, "CreateDate", create_date_fun);
1574

1575 1576 1577 1578 1579 1580 1581
  INSTALL_NATIVE(JSFunction, "ToNumber", to_number_fun);
  INSTALL_NATIVE(JSFunction, "ToString", to_string_fun);
  INSTALL_NATIVE(JSFunction, "ToDetailString", to_detail_string_fun);
  INSTALL_NATIVE(JSFunction, "ToObject", to_object_fun);
  INSTALL_NATIVE(JSFunction, "ToInteger", to_integer_fun);
  INSTALL_NATIVE(JSFunction, "ToUint32", to_uint32_fun);
  INSTALL_NATIVE(JSFunction, "ToInt32", to_int32_fun);
1582

1583
  INSTALL_NATIVE(JSFunction, "GlobalEval", global_eval_fun);
1584 1585 1586 1587 1588
  INSTALL_NATIVE(JSFunction, "Instantiate", instantiate_fun);
  INSTALL_NATIVE(JSFunction, "ConfigureTemplateInstance",
                 configure_instance_fun);
  INSTALL_NATIVE(JSFunction, "GetStackTraceLine", get_stack_trace_line_fun);
  INSTALL_NATIVE(JSObject, "functionCache", function_cache);
1589 1590
  INSTALL_NATIVE(JSFunction, "ToCompletePropertyDescriptor",
                 to_complete_property_descriptor);
1591 1592 1593 1594 1595 1596 1597 1598

  INSTALL_NATIVE(JSFunction, "IsPromise", is_promise);
  INSTALL_NATIVE(JSFunction, "PromiseCreate", promise_create);
  INSTALL_NATIVE(JSFunction, "PromiseResolve", promise_resolve);
  INSTALL_NATIVE(JSFunction, "PromiseReject", promise_reject);
  INSTALL_NATIVE(JSFunction, "PromiseChain", promise_chain);
  INSTALL_NATIVE(JSFunction, "PromiseCatch", promise_catch);

1599 1600 1601 1602 1603 1604
  INSTALL_NATIVE(JSFunction, "NotifyChange", observers_notify_change);
  INSTALL_NATIVE(JSFunction, "EnqueueSpliceRecord", observers_enqueue_splice);
  INSTALL_NATIVE(JSFunction, "BeginPerformSplice",
                 observers_begin_perform_splice);
  INSTALL_NATIVE(JSFunction, "EndPerformSplice",
                 observers_end_perform_splice);
1605 1606 1607 1608 1609 1610
  INSTALL_NATIVE(JSFunction, "NativeObjectObserve",
                 native_object_observe);
  INSTALL_NATIVE(JSFunction, "NativeObjectGetNotifier",
                 native_object_get_notifier);
  INSTALL_NATIVE(JSFunction, "NativeObjectNotifierPerformChange",
                 native_object_notifier_perform_change);
1611 1612
}

1613

1614 1615
void Genesis::InstallExperimentalNativeFunctions() {
  if (FLAG_harmony_proxies) {
1616
    INSTALL_NATIVE(JSFunction, "DerivedHasTrap", derived_has_trap);
1617
    INSTALL_NATIVE(JSFunction, "DerivedGetTrap", derived_get_trap);
1618
    INSTALL_NATIVE(JSFunction, "DerivedSetTrap", derived_set_trap);
1619
    INSTALL_NATIVE(JSFunction, "ProxyEnumerate", proxy_enumerate);
1620 1621 1622
  }
}

1623 1624 1625
#undef INSTALL_NATIVE


1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637
Handle<JSFunction> Genesis::InstallInternalArray(
    Handle<JSBuiltinsObject> builtins,
    const char* name,
    ElementsKind elements_kind) {
  // --- I n t e r n a l   A r r a y ---
  // An array constructor on the builtins object that works like
  // the public Array constructor, except that its prototype
  // doesn't inherit from Object.prototype.
  // To be used only for internal work by builtins. Instances
  // must not be leaked to user code.
  Handle<JSObject> prototype =
      factory()->NewJSObject(isolate()->object_function(), TENURED);
1638 1639 1640
  Handle<JSFunction> array_function = InstallFunction(
      builtins, name, JS_ARRAY_TYPE, JSArray::kSize,
      prototype, Builtins::kInternalArrayCode);
1641

1642
  InternalArrayConstructorStub internal_array_constructor_stub(isolate());
1643
  Handle<Code> code = internal_array_constructor_stub.GetCode();
1644
  array_function->shared()->set_construct_stub(*code);
1645 1646
  array_function->shared()->DontAdaptArguments();

1647
  Handle<Map> original_map(array_function->initial_map());
1648
  Handle<Map> initial_map = Map::Copy(original_map);
1649 1650
  initial_map->set_elements_kind(elements_kind);
  array_function->set_initial_map(*initial_map);
1651 1652

  // Make "length" magic on instances.
1653
  Map::EnsureDescriptorSlack(initial_map, 1);
1654 1655 1656 1657

  PropertyAttributes attribs = static_cast<PropertyAttributes>(
      DONT_ENUM | DONT_DELETE);

1658 1659
  Handle<AccessorInfo> array_length =
      Accessors::ArrayLengthInfo(isolate(), attribs);
1660 1661
  {  // Add length.
    CallbacksDescriptor d(
1662
        Handle<Name>(Name::cast(array_length->name())), array_length, attribs);
1663
    array_function->initial_map()->AppendDescriptor(&d);
1664 1665 1666 1667 1668 1669
  }

  return array_function;
}


1670
bool Genesis::InstallNatives() {
1671
  HandleScope scope(isolate());
1672 1673 1674

  // Create a function for the builtins object. Allocate space for the
  // JavaScript builtins, a reference to the builtins object
1675
  // (itself) and a reference to the native_context directly in the object.
1676
  Handle<Code> code = Handle<Code>(
1677
      isolate()->builtins()->builtin(Builtins::kIllegal));
1678
  Handle<JSFunction> builtins_fun = factory()->NewFunction(
1679 1680
      factory()->empty_string(), code, JS_BUILTINS_OBJECT_TYPE,
      JSBuiltinsObject::kSize);
1681

1682
  Handle<String> name =
1683
      factory()->InternalizeOneByteString(STATIC_ASCII_VECTOR("builtins"));
1684
  builtins_fun->shared()->set_instance_class_name(*name);
1685
  builtins_fun->initial_map()->set_dictionary_map(true);
1686
  builtins_fun->initial_map()->set_prototype(heap()->null_value());
1687 1688 1689

  // Allocate the builtins object.
  Handle<JSBuiltinsObject> builtins =
1690
      Handle<JSBuiltinsObject>::cast(factory()->NewGlobalObject(builtins_fun));
1691
  builtins->set_builtins(*builtins);
1692
  builtins->set_native_context(*native_context());
1693
  builtins->set_global_context(*native_context());
1694
  builtins->set_global_receiver(*builtins);
1695 1696
  builtins->set_global_receiver(native_context()->global_proxy());

1697

1698
  // Set up the 'global' properties of the builtins object. The
1699 1700 1701 1702 1703
  // 'global' property that refers to the global object is the only
  // way to get from code running in the builtins context to the
  // global object.
  static const PropertyAttributes attributes =
      static_cast<PropertyAttributes>(READ_ONLY | DONT_DELETE);
1704 1705
  Handle<String> global_string =
      factory()->InternalizeOneByteString(STATIC_ASCII_VECTOR("global"));
1706
  Handle<Object> global_obj(native_context()->global_object(), isolate());
1707
  JSObject::SetOwnPropertyIgnoreAttributes(
1708
      builtins, global_string, global_obj, attributes).Check();
1709 1710
  Handle<String> builtins_string =
      factory()->InternalizeOneByteString(STATIC_ASCII_VECTOR("builtins"));
1711
  JSObject::SetOwnPropertyIgnoreAttributes(
1712
      builtins, builtins_string, builtins, attributes).Check();
1713

1714
  // Set up the reference from the global object to the builtins object.
1715 1716
  JSGlobalObject::cast(native_context()->global_object())->
      set_builtins(*builtins);
1717

1718
  // Create a bridge function that has context in the native context.
1719
  Handle<JSFunction> bridge = factory()->NewFunction(factory()->empty_string());
1720
  ASSERT(bridge->context() == *isolate()->native_context());
1721 1722 1723

  // Allocate the builtins context.
  Handle<Context> context =
1724
    factory()->NewFunctionContext(Context::MIN_CONTEXT_SLOTS, bridge);
1725
  context->set_global_object(*builtins);  // override builtins global object
1726

1727
  native_context()->set_runtime_context(*context);
1728 1729 1730

  {  // -- S c r i p t
    // Builtin functions for Script.
1731 1732
    Handle<JSFunction> script_fun = InstallFunction(
        builtins, "Script", JS_VALUE_TYPE, JSValue::kSize,
1733
        isolate()->initial_object_prototype(), Builtins::kIllegal);
1734
    Handle<JSObject> prototype =
1735
        factory()->NewJSObject(isolate()->object_function(), TENURED);
1736
    Accessors::FunctionSetPrototype(script_fun, prototype);
1737
    native_context()->set_script_function(*script_fun);
1738

1739
    Handle<Map> script_map = Handle<Map>(script_fun->initial_map());
1740
    Map::EnsureDescriptorSlack(script_map, 13);
1741 1742 1743

    PropertyAttributes attribs =
        static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY);
1744

1745 1746
    Handle<AccessorInfo> script_column =
        Accessors::ScriptColumnOffsetInfo(isolate(), attribs);
1747
    {
1748 1749
      CallbacksDescriptor d(Handle<Name>(Name::cast(script_column->name())),
                           script_column, attribs);
1750
      script_map->AppendDescriptor(&d);
1751 1752
    }

1753 1754
    Handle<AccessorInfo> script_id =
        Accessors::ScriptIdInfo(isolate(), attribs);
1755
    {
1756 1757
      CallbacksDescriptor d(Handle<Name>(Name::cast(script_id->name())),
                            script_id, attribs);
1758
      script_map->AppendDescriptor(&d);
1759 1760
    }

1761 1762 1763

    Handle<AccessorInfo> script_name =
        Accessors::ScriptNameInfo(isolate(), attribs);
1764
    {
1765 1766
      CallbacksDescriptor d(Handle<Name>(Name::cast(script_name->name())),
                            script_name, attribs);
1767
      script_map->AppendDescriptor(&d);
1768 1769
    }

1770 1771
    Handle<AccessorInfo> script_line =
        Accessors::ScriptLineOffsetInfo(isolate(), attribs);
1772
    {
1773 1774
      CallbacksDescriptor d(Handle<Name>(Name::cast(script_line->name())),
                           script_line, attribs);
1775
      script_map->AppendDescriptor(&d);
1776 1777
    }

1778 1779
    Handle<AccessorInfo> script_source =
        Accessors::ScriptSourceInfo(isolate(), attribs);
1780
    {
1781 1782
      CallbacksDescriptor d(Handle<Name>(Name::cast(script_source->name())),
                            script_source, attribs);
1783
      script_map->AppendDescriptor(&d);
1784 1785
    }

1786 1787
    Handle<AccessorInfo> script_type =
        Accessors::ScriptTypeInfo(isolate(), attribs);
1788
    {
1789 1790
      CallbacksDescriptor d(Handle<Name>(Name::cast(script_type->name())),
                            script_type, attribs);
1791
      script_map->AppendDescriptor(&d);
1792 1793
    }

1794 1795
    Handle<AccessorInfo> script_compilation_type =
        Accessors::ScriptCompilationTypeInfo(isolate(), attribs);
1796 1797
    {
      CallbacksDescriptor d(
1798 1799
          Handle<Name>(Name::cast(script_compilation_type->name())),
          script_compilation_type, attribs);
1800
      script_map->AppendDescriptor(&d);
1801 1802
    }

1803 1804
    Handle<AccessorInfo> script_line_ends =
        Accessors::ScriptLineEndsInfo(isolate(), attribs);
1805
    {
1806 1807
      CallbacksDescriptor d(Handle<Name>(Name::cast(script_line_ends->name())),
                            script_line_ends, attribs);
1808
      script_map->AppendDescriptor(&d);
1809 1810
    }

1811 1812
    Handle<AccessorInfo> script_context_data =
        Accessors::ScriptContextDataInfo(isolate(), attribs);
1813 1814
    {
      CallbacksDescriptor d(
1815 1816
          Handle<Name>(Name::cast(script_context_data->name())),
          script_context_data, attribs);
1817
      script_map->AppendDescriptor(&d);
1818 1819
    }

1820 1821
    Handle<AccessorInfo> script_eval_from_script =
        Accessors::ScriptEvalFromScriptInfo(isolate(), attribs);
1822 1823
    {
      CallbacksDescriptor d(
1824 1825
          Handle<Name>(Name::cast(script_eval_from_script->name())),
          script_eval_from_script, attribs);
1826
      script_map->AppendDescriptor(&d);
1827 1828
    }

1829 1830
    Handle<AccessorInfo> script_eval_from_script_position =
        Accessors::ScriptEvalFromScriptPositionInfo(isolate(), attribs);
1831 1832
    {
      CallbacksDescriptor d(
1833 1834
          Handle<Name>(Name::cast(script_eval_from_script_position->name())),
          script_eval_from_script_position, attribs);
1835
      script_map->AppendDescriptor(&d);
1836 1837
    }

1838 1839
    Handle<AccessorInfo> script_eval_from_function_name =
        Accessors::ScriptEvalFromFunctionNameInfo(isolate(), attribs);
1840 1841
    {
      CallbacksDescriptor d(
1842 1843
          Handle<Name>(Name::cast(script_eval_from_function_name->name())),
          script_eval_from_function_name, attribs);
1844
      script_map->AppendDescriptor(&d);
1845 1846
    }

1847
    // Allocate the empty script.
1848
    Handle<Script> script = factory()->NewScript(factory()->empty_string());
1849
    script->set_type(Smi::FromInt(Script::TYPE_NATIVE));
1850
    heap()->public_set_empty_script(*script);
1851
  }
1852 1853 1854 1855
  {
    // Builtin function for OpaqueReference -- a JSValue-based object,
    // that keeps its field isolated from JavaScript code. It may store
    // objects, that JavaScript code may not access.
1856 1857
    Handle<JSFunction> opaque_reference_fun = InstallFunction(
        builtins, "OpaqueReference", JS_VALUE_TYPE, JSValue::kSize,
1858
        isolate()->initial_object_prototype(), Builtins::kIllegal);
1859
    Handle<JSObject> prototype =
1860
        factory()->NewJSObject(isolate()->object_function(), TENURED);
1861
    Accessors::FunctionSetPrototype(opaque_reference_fun, prototype);
1862
    native_context()->set_opaque_reference_function(*opaque_reference_fun);
1863
  }
1864

1865 1866 1867 1868 1869 1870 1871 1872
  // InternalArrays should not use Smi-Only array optimizations. There are too
  // many places in the C++ runtime code (e.g. RegEx) that assume that
  // elements in InternalArrays can be set to non-Smi values without going
  // through a common bottleneck that would make the SMI_ONLY -> FAST_ELEMENT
  // transition easy to trap. Moreover, they rarely are smi-only.
  {
    Handle<JSFunction> array_function =
        InstallInternalArray(builtins, "InternalArray", FAST_HOLEY_ELEMENTS);
1873
    native_context()->set_internal_array_function(*array_function);
1874 1875
  }

1876
  {
1877
    InstallInternalArray(builtins, "InternalPackedArray", FAST_ELEMENTS);
1878 1879
  }

1880 1881 1882 1883 1884
  if (FLAG_disable_native_files) {
    PrintF("Warning: Running without installed natives!\n");
    return true;
  }

1885 1886 1887 1888
  // Install natives.
  for (int i = Natives::GetDebuggerCount();
       i < Natives::GetBuiltinsCount();
       i++) {
1889
    if (!CompileBuiltin(isolate(), i)) return false;
1890 1891 1892 1893
    // TODO(ager): We really only need to install the JS builtin
    // functions on the builtins object after compiling and running
    // runtime.js.
    if (!InstallJSBuiltins(builtins)) return false;
1894 1895 1896 1897
  }

  InstallNativeFunctions();

1898
  // Store the map for the string prototype after the natives has been compiled
1899
  // and the String function has been set up.
1900
  Handle<JSFunction> string_function(native_context()->string_function());
1901 1902
  ASSERT(JSObject::cast(
      string_function->initial_map()->prototype())->HasFastProperties());
1903
  native_context()->set_string_function_prototype_map(
1904 1905
      HeapObject::cast(string_function->initial_map()->prototype())->map());

1906
  // Install Function.prototype.call and apply.
1907
  { Handle<String> key = factory()->function_class_string();
1908
    Handle<JSFunction> function =
1909
        Handle<JSFunction>::cast(Object::GetProperty(
1910
            isolate()->global_object(), key).ToHandleChecked());
1911 1912
    Handle<JSObject> proto =
        Handle<JSObject>(JSObject::cast(function->instance_prototype()));
1913 1914

    // Install the call and the apply functions.
1915
    Handle<JSFunction> call =
1916
        InstallFunction(proto, "call", JS_OBJECT_TYPE, JSObject::kHeaderSize,
1917
                        MaybeHandle<JSObject>(), Builtins::kFunctionCall);
1918 1919
    Handle<JSFunction> apply =
        InstallFunction(proto, "apply", JS_OBJECT_TYPE, JSObject::kHeaderSize,
1920
                        MaybeHandle<JSObject>(), Builtins::kFunctionApply);
1921 1922 1923 1924

    // Make sure that Function.prototype.call appears to be compiled.
    // The code will never be called, but inline caching for call will
    // only work if it appears to be compiled.
1925
    call->shared()->DontAdaptArguments();
1926 1927
    ASSERT(call->is_compiled());

1928
    // Set the expected parameters for apply to 2; required by builtin.
1929 1930 1931 1932 1933
    apply->shared()->set_formal_parameter_count(2);

    // Set the lengths for the functions to satisfy ECMA-262.
    call->shared()->set_length(1);
    apply->shared()->set_length(2);
1934 1935
  }

1936 1937
  InstallBuiltinFunctionIds();

1938 1939 1940 1941 1942 1943
  // Create a constructor for RegExp results (a variant of Array that
  // predefines the two properties index and match).
  {
    // RegExpResult initial map.

    // Find global.Array.prototype to inherit from.
1944
    Handle<JSFunction> array_constructor(native_context()->array_function());
1945 1946 1947 1948 1949
    Handle<JSObject> array_prototype(
        JSObject::cast(array_constructor->instance_prototype()));

    // Add initial map.
    Handle<Map> initial_map =
1950
        factory()->NewMap(JS_ARRAY_TYPE, JSRegExpResult::kSize);
1951 1952 1953 1954 1955 1956 1957
    initial_map->set_constructor(*array_constructor);

    // Set prototype on map.
    initial_map->set_non_instance_prototype(false);
    initial_map->set_prototype(*array_prototype);

    // Update map with length accessor from Array and add "index" and "input".
1958
    Map::EnsureDescriptorSlack(initial_map, 3);
1959

1960
    {
1961
      JSFunction* array_function = native_context()->array_function();
1962 1963
      Handle<DescriptorArray> array_descriptors(
          array_function->initial_map()->instance_descriptors());
1964
      Handle<String> length = factory()->length_string();
1965
      int old = array_descriptors->SearchWithCache(
1966
          *length, array_function->initial_map());
1967 1968
      ASSERT(old != DescriptorArray::kNotFound);
      CallbacksDescriptor desc(length,
1969 1970
                               handle(array_descriptors->GetValue(old),
                                      isolate()),
1971
                               array_descriptors->GetDetails(old).attributes());
1972
      initial_map->AppendDescriptor(&desc);
1973
    }
1974
    {
1975
      FieldDescriptor index_field(factory()->index_string(),
1976
                                  JSRegExpResult::kIndexIndex,
1977 1978
                                  NONE,
                                  Representation::Tagged());
1979
      initial_map->AppendDescriptor(&index_field);
1980 1981 1982
    }

    {
1983
      FieldDescriptor input_field(factory()->input_string(),
1984
                                  JSRegExpResult::kInputIndex,
1985 1986
                                  NONE,
                                  Representation::Tagged());
1987
      initial_map->AppendDescriptor(&input_field);
1988 1989 1990 1991 1992 1993
    }

    initial_map->set_inobject_properties(2);
    initial_map->set_pre_allocated_property_fields(2);
    initial_map->set_unused_property_fields(0);

1994
    native_context()->set_regexp_result_map(*initial_map);
1995 1996
  }

1997
#ifdef VERIFY_HEAP
1998
  builtins->ObjectVerify();
1999
#endif
2000 2001 2002 2003 2004

  return true;
}


rossberg@chromium.org's avatar
rossberg@chromium.org committed
2005 2006 2007 2008 2009 2010 2011 2012
#define INSTALL_EXPERIMENTAL_NATIVE(i, flag, file)                \
  if (FLAG_harmony_##flag &&                                      \
      strcmp(ExperimentalNatives::GetScriptName(i).start(),       \
          "native " file) == 0) {                                 \
    if (!CompileExperimentalBuiltin(isolate(), i)) return false;  \
  }


2013
bool Genesis::InstallExperimentalNatives() {
2014 2015 2016
  for (int i = ExperimentalNatives::GetDebuggerCount();
       i < ExperimentalNatives::GetBuiltinsCount();
       i++) {
rossberg@chromium.org's avatar
rossberg@chromium.org committed
2017 2018 2019
    INSTALL_EXPERIMENTAL_NATIVE(i, symbols, "symbol.js")
    INSTALL_EXPERIMENTAL_NATIVE(i, proxies, "proxy.js")
    INSTALL_EXPERIMENTAL_NATIVE(i, collections, "collection.js")
2020
    INSTALL_EXPERIMENTAL_NATIVE(i, collections, "collection-iterator.js")
rossberg@chromium.org's avatar
rossberg@chromium.org committed
2021 2022 2023 2024 2025
    INSTALL_EXPERIMENTAL_NATIVE(i, generators, "generator.js")
    INSTALL_EXPERIMENTAL_NATIVE(i, iteration, "array-iterator.js")
    INSTALL_EXPERIMENTAL_NATIVE(i, strings, "harmony-string.js")
    INSTALL_EXPERIMENTAL_NATIVE(i, arrays, "harmony-array.js")
    INSTALL_EXPERIMENTAL_NATIVE(i, maths, "harmony-math.js")
2026
  }
2027 2028

  InstallExperimentalNativeFunctions();
2029
  InstallExperimentalBuiltinFunctionIds();
2030 2031 2032 2033
  return true;
}


2034
static Handle<JSObject> ResolveBuiltinIdHolder(
2035
    Handle<Context> native_context,
2036
    const char* holder_expr) {
2037 2038
  Isolate* isolate = native_context->GetIsolate();
  Factory* factory = isolate->factory();
2039
  Handle<GlobalObject> global(native_context->global_object());
2040 2041
  const char* period_pos = strchr(holder_expr, '.');
  if (period_pos == NULL) {
2042
    return Handle<JSObject>::cast(Object::GetPropertyOrElement(
2043
        global, factory->InternalizeUtf8String(holder_expr)).ToHandleChecked());
2044
  }
2045
  ASSERT_EQ(".prototype", period_pos);
2046 2047
  Vector<const char> property(holder_expr,
                              static_cast<int>(period_pos - holder_expr));
2048 2049
  Handle<String> property_string = factory->InternalizeUtf8String(property);
  ASSERT(!property_string.is_null());
2050
  Handle<JSFunction> function = Handle<JSFunction>::cast(
2051
      Object::GetProperty(global, property_string).ToHandleChecked());
2052 2053 2054 2055
  return Handle<JSObject>(JSObject::cast(function->prototype()));
}


2056 2057 2058
static void InstallBuiltinFunctionId(Handle<JSObject> holder,
                                     const char* function_name,
                                     BuiltinFunctionId id) {
2059
  Isolate* isolate = holder->GetIsolate();
2060
  Handle<Object> function_object =
2061
      Object::GetProperty(isolate, holder, function_name).ToHandleChecked();
2062
  Handle<JSFunction> function = Handle<JSFunction>::cast(function_object);
2063 2064 2065 2066
  function->shared()->set_function_data(Smi::FromInt(id));
}


2067
void Genesis::InstallBuiltinFunctionIds() {
2068
  HandleScope scope(isolate());
2069 2070 2071
#define INSTALL_BUILTIN_ID(holder_expr, fun_name, name) \
  {                                                     \
    Handle<JSObject> holder = ResolveBuiltinIdHolder(   \
2072
        native_context(), #holder_expr);                \
2073 2074
    BuiltinFunctionId id = k##name;                     \
    InstallBuiltinFunctionId(holder, #fun_name, id);    \
2075
  }
2076 2077
  FUNCTIONS_WITH_ID_LIST(INSTALL_BUILTIN_ID)
#undef INSTALL_BUILTIN_ID
2078 2079 2080
}


2081 2082 2083 2084 2085 2086 2087 2088 2089
void Genesis::InstallExperimentalBuiltinFunctionIds() {
  HandleScope scope(isolate());
  if (FLAG_harmony_maths) {
    Handle<JSObject> holder = ResolveBuiltinIdHolder(native_context(), "Math");
    InstallBuiltinFunctionId(holder, "clz32", kMathClz32);
  }
}


2090 2091 2092
// Do not forget to update macros.py with named constant
// of cache id.
#define JSFUNCTION_RESULT_CACHE_LIST(F) \
2093
  F(16, native_context()->regexp_function())
2094 2095


2096
static FixedArray* CreateCache(int size, Handle<JSFunction> factory_function) {
2097
  Factory* factory = factory_function->GetIsolate()->factory();
2098 2099
  // Caches are supposed to live for a long time, allocate in old space.
  int array_size = JSFunctionResultCache::kEntriesIndex + 2 * size;
2100 2101
  // Cannot use cast as object is not fully initialized yet.
  JSFunctionResultCache* cache = reinterpret_cast<JSFunctionResultCache*>(
2102
      *factory->NewFixedArrayWithHoles(array_size, TENURED));
2103
  cache->set(JSFunctionResultCache::kFactoryIndex, *factory_function);
2104 2105
  cache->MakeZeroSize();
  return cache;
2106 2107 2108 2109 2110 2111 2112 2113 2114 2115
}


void Genesis::InstallJSFunctionResultCaches() {
  const int kNumberOfCaches = 0 +
#define F(size, func) + 1
    JSFUNCTION_RESULT_CACHE_LIST(F)
#undef F
  ;

2116 2117
  Handle<FixedArray> caches =
      factory()->NewFixedArray(kNumberOfCaches, TENURED);
2118 2119

  int index = 0;
2120

2121 2122 2123
#define F(size, func) do {                                              \
    FixedArray* cache = CreateCache((size), Handle<JSFunction>(func));  \
    caches->set(index++, cache);                                        \
2124 2125 2126 2127
  } while (false)

  JSFUNCTION_RESULT_CACHE_LIST(F);

2128 2129
#undef F

2130
  native_context()->set_jsfunction_result_caches(*caches);
2131 2132 2133
}


2134
void Genesis::InitializeNormalizedMapCaches() {
2135 2136
  Handle<NormalizedMapCache> cache = NormalizedMapCache::New(isolate());
  native_context()->set_normalized_map_cache(*cache);
2137 2138 2139
}


2140
bool Bootstrapper::InstallExtensions(Handle<Context> native_context,
2141
                                     v8::ExtensionConfiguration* extensions) {
2142 2143 2144
  BootstrapperActive active(this);
  SaveContext saved_context(isolate_);
  isolate_->set_context(*native_context);
2145 2146
  return Genesis::InstallExtensions(native_context, extensions) &&
      Genesis::InstallSpecialObjects(native_context);
2147 2148 2149
}


2150
bool Genesis::InstallSpecialObjects(Handle<Context> native_context) {
2151
  Isolate* isolate = native_context->GetIsolate();
2152
  Factory* factory = isolate->factory();
2153
  HandleScope scope(isolate);
2154 2155
  Handle<JSGlobalObject> global(JSGlobalObject::cast(
      native_context->global_object()));
2156 2157
  // Expose the natives in global if a name for it is specified.
  if (FLAG_expose_natives_as != NULL && strlen(FLAG_expose_natives_as) != 0) {
2158 2159
    Handle<String> natives =
        factory->InternalizeUtf8String(FLAG_expose_natives_as);
2160 2161
    RETURN_ON_EXCEPTION_VALUE(
        isolate,
2162
        JSObject::SetOwnPropertyIgnoreAttributes(
2163 2164
            global, natives, Handle<JSObject>(global->builtins()), DONT_ENUM),
        false);
2165 2166
  }

2167 2168
  Handle<Object> Error = Object::GetProperty(
      isolate, global, "Error").ToHandleChecked();
2169
  if (Error->IsJSObject()) {
2170 2171 2172 2173
    Handle<String> name = factory->InternalizeOneByteString(
        STATIC_ASCII_VECTOR("stackTraceLimit"));
    Handle<Smi> stack_trace_limit(
        Smi::FromInt(FLAG_stack_trace_limit), isolate);
2174 2175
    RETURN_ON_EXCEPTION_VALUE(
        isolate,
2176
        JSObject::SetOwnPropertyIgnoreAttributes(
2177 2178
            Handle<JSObject>::cast(Error), name, stack_trace_limit, NONE),
        false);
2179 2180
  }

2181 2182 2183 2184
  // Expose the debug global object in global if a name for it is specified.
  if (FLAG_expose_debug_as != NULL && strlen(FLAG_expose_debug_as) != 0) {
    // If loading fails we just bail out without installing the
    // debugger but without tanking the whole context.
2185
    Debug* debug = isolate->debug();
2186
    if (!debug->Load()) return true;
2187
    Handle<Context> debug_context = debug->debug_context();
2188
    // Set the security token for the debugger context to the same as
2189
    // the shell native context to allow calling between these (otherwise
2190
    // exposing debug global object doesn't make much sense).
2191
    debug_context->set_security_token(native_context->security_token());
2192
    Handle<String> debug_string =
2193
        factory->InternalizeUtf8String(FLAG_expose_debug_as);
2194
    Handle<Object> global_proxy(debug_context->global_proxy(), isolate);
2195 2196
    RETURN_ON_EXCEPTION_VALUE(
        isolate,
2197
        JSObject::SetOwnPropertyIgnoreAttributes(
2198 2199
            global, debug_string, global_proxy, DONT_ENUM),
        false);
2200
  }
2201
  return true;
2202 2203
}

2204

2205 2206 2207 2208
static uint32_t Hash(RegisteredExtension* extension) {
  return v8::internal::ComputePointerHash(extension);
}

2209

2210
Genesis::ExtensionStates::ExtensionStates() : map_(HashMap::PointersMatch, 8) {}
2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226

Genesis::ExtensionTraversalState Genesis::ExtensionStates::get_state(
    RegisteredExtension* extension) {
  i::HashMap::Entry* entry = map_.Lookup(extension, Hash(extension), false);
  if (entry == NULL) {
    return UNVISITED;
  }
  return static_cast<ExtensionTraversalState>(
      reinterpret_cast<intptr_t>(entry->value));
}

void Genesis::ExtensionStates::set_state(RegisteredExtension* extension,
                                         ExtensionTraversalState state) {
  map_.Lookup(extension, Hash(extension), true)->value =
      reinterpret_cast<void*>(static_cast<intptr_t>(state));
}
2227

2228

2229
bool Genesis::InstallExtensions(Handle<Context> native_context,
2230
                                v8::ExtensionConfiguration* extensions) {
2231
  Isolate* isolate = native_context->GetIsolate();
2232
  ExtensionStates extension_states;  // All extensions have state UNVISITED.
2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245
  return InstallAutoExtensions(isolate, &extension_states) &&
      (!FLAG_expose_free_buffer ||
       InstallExtension(isolate, "v8/free-buffer", &extension_states)) &&
      (!FLAG_expose_gc ||
       InstallExtension(isolate, "v8/gc", &extension_states)) &&
      (!FLAG_expose_externalize_string ||
       InstallExtension(isolate, "v8/externalize", &extension_states)) &&
      (!FLAG_track_gc_object_stats ||
       InstallExtension(isolate, "v8/statistics", &extension_states)) &&
      (!FLAG_expose_trigger_failure ||
       InstallExtension(isolate, "v8/trigger-failure", &extension_states)) &&
      InstallRequestedExtensions(isolate, extensions, &extension_states);
}
2246

2247 2248 2249 2250 2251 2252 2253 2254 2255 2256

bool Genesis::InstallAutoExtensions(Isolate* isolate,
                                    ExtensionStates* extension_states) {
  for (v8::RegisteredExtension* it = v8::RegisteredExtension::first_extension();
       it != NULL;
       it = it->next()) {
    if (it->extension()->auto_enable() &&
        !InstallExtension(isolate, it, extension_states)) {
      return false;
    }
2257
  }
2258 2259 2260
  return true;
}

2261

2262 2263 2264
bool Genesis::InstallRequestedExtensions(Isolate* isolate,
                                         v8::ExtensionConfiguration* extensions,
                                         ExtensionStates* extension_states) {
2265
  for (const char** it = extensions->begin(); it != extensions->end(); ++it) {
2266
    if (!InstallExtension(isolate, *it, extension_states)) return false;
2267 2268 2269 2270 2271 2272 2273
  }
  return true;
}


// Installs a named extension.  This methods is unoptimized and does
// not scale well if we want to support a large number of extensions.
2274 2275
bool Genesis::InstallExtension(Isolate* isolate,
                               const char* name,
2276
                               ExtensionStates* extension_states) {
2277 2278 2279 2280 2281 2282
  for (v8::RegisteredExtension* it = v8::RegisteredExtension::first_extension();
       it != NULL;
       it = it->next()) {
    if (strcmp(name, it->extension()->name()) == 0) {
      return InstallExtension(isolate, it, extension_states);
    }
2283
  }
2284 2285 2286
  return Utils::ApiCheck(false,
                         "v8::Context::New()",
                         "Cannot find required extension");
2287 2288 2289
}


2290 2291
bool Genesis::InstallExtension(Isolate* isolate,
                               v8::RegisteredExtension* current,
2292
                               ExtensionStates* extension_states) {
2293
  HandleScope scope(isolate);
2294

2295
  if (extension_states->get_state(current) == INSTALLED) return true;
2296 2297
  // The current node has already been visited so there must be a
  // cycle in the dependency graph; fail.
2298 2299 2300
  if (!Utils::ApiCheck(extension_states->get_state(current) != VISITED,
                       "v8::Context::New()",
                       "Circular extension dependency")) {
2301 2302
    return false;
  }
2303 2304
  ASSERT(extension_states->get_state(current) == UNVISITED);
  extension_states->set_state(current, VISITED);
2305 2306 2307
  v8::Extension* extension = current->extension();
  // Install the extension's dependencies
  for (int i = 0; i < extension->dependency_count(); i++) {
2308 2309 2310
    if (!InstallExtension(isolate,
                          extension->dependencies()[i],
                          extension_states)) {
2311
      return false;
2312
    }
2313
  }
2314
  // We do not expect this to throw an exception. Change this if it does.
2315 2316 2317
  Handle<String> source_code =
      isolate->factory()->NewExternalStringFromAscii(
          extension->source()).ToHandleChecked();
2318 2319 2320 2321 2322 2323 2324
  bool result = CompileScriptCached(isolate,
                                    CStrVector(extension->name()),
                                    source_code,
                                    isolate->bootstrapper()->extensions_cache(),
                                    extension,
                                    Handle<Context>(isolate->context()),
                                    false);
2325
  ASSERT(isolate->has_pending_exception() != result);
2326
  if (!result) {
2327 2328 2329 2330 2331 2332
    // We print out the name of the extension that fail to install.
    // When an error is thrown during bootstrapping we automatically print
    // the line number at which this happened to the console in the isolate
    // error throwing functionality.
    OS::PrintError("Error installing extension '%s'.\n",
                   current->extension()->name());
2333
    isolate->clear_pending_exception();
2334
  }
2335 2336
  extension_states->set_state(current, INSTALLED);
  isolate->NotifyExtensionInstalled();
2337 2338 2339 2340
  return result;
}


2341
bool Genesis::InstallJSBuiltins(Handle<JSBuiltinsObject> builtins) {
2342
  HandleScope scope(isolate());
2343 2344
  for (int i = 0; i < Builtins::NumberOfJavaScriptBuiltins(); i++) {
    Builtins::JavaScript id = static_cast<Builtins::JavaScript>(i);
2345 2346
    Handle<Object> function_object = Object::GetProperty(
        isolate(), builtins, Builtins::GetName(id)).ToHandleChecked();
2347
    Handle<JSFunction> function = Handle<JSFunction>::cast(function_object);
2348
    builtins->set_javascript_builtin(id, *function);
2349
    if (!Compiler::EnsureCompiled(function, CLEAR_EXCEPTION)) {
2350 2351
      return false;
    }
2352
    builtins->set_javascript_builtin_code(id, function->shared()->code());
2353 2354 2355 2356 2357
  }
  return true;
}


2358 2359 2360
bool Genesis::ConfigureGlobalObjects(
    v8::Handle<v8::ObjectTemplate> global_proxy_template) {
  Handle<JSObject> global_proxy(
2361
      JSObject::cast(native_context()->global_proxy()));
2362 2363
  Handle<JSObject> inner_global(
      JSObject::cast(native_context()->global_object()));
2364 2365

  if (!global_proxy_template.IsEmpty()) {
feng@chromium.org's avatar
feng@chromium.org committed
2366
    // Configure the global proxy object.
2367 2368 2369 2370 2371 2372 2373 2374
    Handle<ObjectTemplateInfo> proxy_data =
        v8::Utils::OpenHandle(*global_proxy_template);
    if (!ConfigureApiObject(global_proxy, proxy_data)) return false;

    // Configure the inner global object.
    Handle<FunctionTemplateInfo> proxy_constructor(
        FunctionTemplateInfo::cast(proxy_data->constructor()));
    if (!proxy_constructor->prototype_template()->IsUndefined()) {
feng@chromium.org's avatar
feng@chromium.org committed
2375
      Handle<ObjectTemplateInfo> inner_data(
2376
          ObjectTemplateInfo::cast(proxy_constructor->prototype_template()));
2377
      if (!ConfigureApiObject(inner_global, inner_data)) return false;
2378 2379
    }
  }
2380

2381
  SetObjectPrototype(global_proxy, inner_global);
2382 2383 2384 2385

  native_context()->set_initial_array_prototype(
      JSArray::cast(native_context()->array_function()->prototype()));

2386 2387 2388
  return true;
}

feng@chromium.org's avatar
feng@chromium.org committed
2389

2390 2391 2392
bool Genesis::ConfigureApiObject(Handle<JSObject> object,
    Handle<ObjectTemplateInfo> object_template) {
  ASSERT(!object_template.is_null());
2393 2394
  ASSERT(FunctionTemplateInfo::cast(object_template->constructor())
             ->IsTemplateFor(object->map()));;
2395

2396 2397 2398 2399
  MaybeHandle<JSObject> maybe_obj =
      Execution::InstantiateObject(object_template);
  Handle<JSObject> obj;
  if (!maybe_obj.ToHandle(&obj)) {
2400 2401
    ASSERT(isolate()->has_pending_exception());
    isolate()->clear_pending_exception();
2402 2403 2404
    return false;
  }
  TransferObject(obj, object);
2405 2406 2407 2408 2409 2410 2411 2412 2413
  return true;
}


void Genesis::TransferNamedProperties(Handle<JSObject> from,
                                      Handle<JSObject> to) {
  if (from->HasFastProperties()) {
    Handle<DescriptorArray> descs =
        Handle<DescriptorArray>(from->map()->instance_descriptors());
2414
    for (int i = 0; i < from->map()->NumberOfOwnDescriptors(); i++) {
2415
      PropertyDetails details = descs->GetDetails(i);
2416 2417
      switch (details.type()) {
        case FIELD: {
2418
          HandleScope inner(isolate());
2419
          Handle<Name> key = Handle<Name>(descs->GetKey(i));
2420
          int index = descs->GetFieldIndex(i);
2421 2422
          ASSERT(!descs->GetDetails(i).representation().IsDouble());
          Handle<Object> value = Handle<Object>(from->RawFastPropertyAt(index),
2423
                                                isolate());
2424
          JSObject::SetOwnPropertyIgnoreAttributes(
2425
              to, key, value, details.attributes()).Check();
2426 2427
          break;
        }
2428
        case CONSTANT: {
2429
          HandleScope inner(isolate());
2430
          Handle<Name> key = Handle<Name>(descs->GetKey(i));
2431
          Handle<Object> constant(descs->GetConstant(i), isolate());
2432
          JSObject::SetOwnPropertyIgnoreAttributes(
2433
              to, key, constant, details.attributes()).Check();
2434 2435 2436
          break;
        }
        case CALLBACKS: {
2437
          LookupResult result(isolate());
2438
          Handle<Name> key(Name::cast(descs->GetKey(i)), isolate());
2439
          to->LookupOwn(key, &result);
2440
          // If the property is already there we skip it
2441
          if (result.IsFound()) continue;
2442
          HandleScope inner(isolate());
2443 2444
          ASSERT(!to->HasFastProperties());
          // Add to dictionary.
2445
          Handle<Object> callbacks(descs->GetCallbacksObject(i), isolate());
2446 2447
          PropertyDetails d = PropertyDetails(
              details.attributes(), CALLBACKS, i + 1);
2448
          JSObject::SetNormalizedProperty(to, key, callbacks, d);
2449 2450 2451 2452
          break;
        }
        case NORMAL:
          // Do not occur since the from object has fast properties.
2453
        case HANDLER:
2454
        case INTERCEPTOR:
2455
        case NONEXISTENT:
2456
          // No element in instance descriptors have proxy or interceptor type.
2457 2458 2459 2460 2461
          UNREACHABLE();
          break;
      }
    }
  } else {
2462 2463
    Handle<NameDictionary> properties =
        Handle<NameDictionary>(from->property_dictionary());
2464 2465 2466 2467
    int capacity = properties->Capacity();
    for (int i = 0; i < capacity; i++) {
      Object* raw_key(properties->KeyAt(i));
      if (properties->IsKey(raw_key)) {
2468
        ASSERT(raw_key->IsName());
2469
        // If the property is already there we skip it.
2470
        LookupResult result(isolate());
2471
        Handle<Name> key(Name::cast(raw_key));
2472
        to->LookupOwn(key, &result);
2473
        if (result.IsFound()) continue;
2474
        // Set the property.
2475 2476
        Handle<Object> value = Handle<Object>(properties->ValueAt(i),
                                              isolate());
2477
        ASSERT(!value->IsCell());
2478 2479
        if (value->IsPropertyCell()) {
          value = Handle<Object>(PropertyCell::cast(*value)->value(),
2480
                                 isolate());
2481
        }
2482
        PropertyDetails details = properties->DetailsAt(i);
2483
        JSObject::SetOwnPropertyIgnoreAttributes(
2484
            to, key, value, details.attributes()).Check();
2485 2486 2487 2488 2489 2490 2491 2492 2493 2494 2495
      }
    }
  }
}


void Genesis::TransferIndexedProperties(Handle<JSObject> from,
                                        Handle<JSObject> to) {
  // Cloning the elements array is sufficient.
  Handle<FixedArray> from_elements =
      Handle<FixedArray>(FixedArray::cast(from->elements()));
2496
  Handle<FixedArray> to_elements = factory()->CopyFixedArray(from_elements);
2497 2498 2499 2500 2501
  to->set_elements(*to_elements);
}


void Genesis::TransferObject(Handle<JSObject> from, Handle<JSObject> to) {
2502
  HandleScope outer(isolate());
2503 2504 2505 2506 2507 2508 2509 2510 2511

  ASSERT(!from->IsJSArray());
  ASSERT(!to->IsJSArray());

  TransferNamedProperties(from, to);
  TransferIndexedProperties(from, to);

  // Transfer the prototype (new map is needed).
  Handle<Map> old_to_map = Handle<Map>(to->map());
2512
  Handle<Map> new_to_map = Map::Copy(old_to_map);
2513 2514 2515 2516 2517 2518
  new_to_map->set_prototype(from->map()->prototype());
  to->set_map(*new_to_map);
}


void Genesis::MakeFunctionInstancePrototypeWritable() {
2519 2520 2521
  // The maps with writable prototype are created in CreateEmptyFunction
  // and CreateStrictModeFunctionMaps respectively. Initially the maps are
  // created with read-only prototype for JS builtins processing.
2522 2523
  ASSERT(!sloppy_function_map_writable_prototype_.is_null());
  ASSERT(!strict_function_map_writable_prototype_.is_null());
2524 2525

  // Replace function instance maps to make prototype writable.
2526 2527 2528 2529
  native_context()->set_sloppy_function_map(
      *sloppy_function_map_writable_prototype_);
  native_context()->set_strict_function_map(
      *strict_function_map_writable_prototype_);
2530 2531 2532
}


2533 2534
class NoTrackDoubleFieldsForSerializerScope {
 public:
2535
  explicit NoTrackDoubleFieldsForSerializerScope(Isolate* isolate)
2536 2537
      : flag_(FLAG_track_double_fields) {
    if (isolate->serializer_enabled()) {
2538 2539 2540 2541 2542
      // Disable tracking double fields because heap numbers treated as
      // immutable by the serializer.
      FLAG_track_double_fields = false;
    }
  }
2543

2544
  ~NoTrackDoubleFieldsForSerializerScope() {
2545
    FLAG_track_double_fields = flag_;
2546 2547 2548 2549 2550 2551 2552
  }

 private:
  bool flag_;
};


2553 2554
Genesis::Genesis(Isolate* isolate,
                 Handle<Object> global_object,
2555
                 v8::Handle<v8::ObjectTemplate> global_template,
2556 2557 2558
                 v8::ExtensionConfiguration* extensions)
    : isolate_(isolate),
      active_(isolate->bootstrapper()) {
2559
  NoTrackDoubleFieldsForSerializerScope disable_scope(isolate);
2560
  result_ = Handle<Context>::null();
2561 2562
  // If V8 cannot be initialized, just return.
  if (!V8::Initialize(NULL)) return;
2563 2564 2565

  // Before creating the roots we must save the context and restore it
  // on all function exits.
2566
  SaveContext saved_context(isolate);
2567

2568 2569 2570
  // During genesis, the boilerplate for stack overflow won't work until the
  // environment has been at least partially initialized. Add a stack check
  // before entering JS code to catch overflow early.
2571
  StackLimitCheck check(isolate);
2572
  if (check.HasOverflowed()) return;
2573

2574 2575 2576
  // We can only de-serialize a context if the isolate was initialized from
  // a snapshot. Otherwise we have to build the context from scratch.
  if (isolate->initialized_from_snapshot()) {
2577
    native_context_ = Snapshot::NewContextFromSnapshot(isolate);
2578 2579 2580 2581
  } else {
    native_context_ = Handle<Context>();
  }

2582 2583 2584
  if (!native_context().is_null()) {
    AddToWeakNativeContextList(*native_context());
    isolate->set_context(*native_context());
2585
    isolate->counters()->contexts_created_by_snapshot()->Increment();
2586 2587 2588 2589 2590 2591 2592 2593
    Handle<GlobalObject> inner_global;
    Handle<JSGlobalProxy> global_proxy =
        CreateNewGlobals(global_template,
                         global_object,
                         &inner_global);

    HookUpGlobalProxy(inner_global, global_proxy);
    HookUpInnerGlobal(inner_global);
2594 2595
    native_context()->builtins()->set_global_receiver(
        native_context()->global_proxy());
2596 2597 2598 2599 2600

    if (!ConfigureGlobalObjects(global_template)) return;
  } else {
    // We get here if there was no context snapshot.
    CreateRoots();
2601
    Handle<JSFunction> empty_function = CreateEmptyFunction(isolate);
2602
    CreateStrictModeFunctionMaps(empty_function);
2603 2604 2605 2606
    Handle<GlobalObject> inner_global;
    Handle<JSGlobalProxy> global_proxy =
        CreateNewGlobals(global_template, global_object, &inner_global);
    HookUpGlobalProxy(inner_global, global_proxy);
2607
    InitializeGlobal(inner_global, empty_function);
2608
    InstallJSFunctionResultCaches();
2609
    InitializeNormalizedMapCaches();
2610
    if (!InstallNatives()) return;
2611 2612 2613

    MakeFunctionInstancePrototypeWritable();

2614 2615
    if (!ConfigureGlobalObjects(global_template)) return;
    isolate->counters()->contexts_created_from_scratch()->Increment();
2616
  }
2617

2618 2619
  // Initialize experimental globals and install experimental natives.
  InitializeExperimentalGlobal();
2620 2621
  if (!InstallExperimentalNatives()) return;

2622 2623 2624
  // We can't (de-)serialize typed arrays currently, but we are lucky: The state
  // of the random number generator needs no initialization during snapshot
  // creation time and we don't need trigonometric functions then.
2625
  if (!isolate->serializer_enabled()) {
2626 2627 2628 2629 2630 2631 2632 2633 2634 2635
    // Initially seed the per-context random number generator using the
    // per-isolate random number generator.
    const int num_elems = 2;
    const int num_bytes = num_elems * sizeof(uint32_t);
    uint32_t* state = reinterpret_cast<uint32_t*>(malloc(num_bytes));

    do {
      isolate->random_number_generator()->NextBytes(state, num_bytes);
    } while (state[0] == 0 || state[1] == 0);

2636 2637
    v8::Local<v8::ArrayBuffer> buffer = v8::ArrayBuffer::New(
        reinterpret_cast<v8::Isolate*>(isolate), state, num_bytes);
2638 2639
    Utils::OpenHandle(*buffer)->set_should_be_freed(true);
    v8::Local<v8::Uint32Array> ta = v8::Uint32Array::New(buffer, 0, num_elems);
2640
    Handle<JSBuiltinsObject> builtins(native_context()->builtins());
2641 2642 2643 2644 2645
    Runtime::ForceSetObjectProperty(builtins,
                                    factory()->InternalizeOneByteString(
                                        STATIC_ASCII_VECTOR("rngstate")),
                                    Utils::OpenHandle(*ta),
                                    NONE).Assert();
2646

2647 2648 2649
    // Initialize trigonometric lookup tables and constants.
    const int table_num_bytes = TrigonometricLookupTable::table_num_bytes();
    v8::Local<v8::ArrayBuffer> sin_buffer = v8::ArrayBuffer::New(
2650
        reinterpret_cast<v8::Isolate*>(isolate),
2651 2652
        TrigonometricLookupTable::sin_table(), table_num_bytes);
    v8::Local<v8::ArrayBuffer> cos_buffer = v8::ArrayBuffer::New(
2653
        reinterpret_cast<v8::Isolate*>(isolate),
2654 2655 2656 2657 2658 2659
        TrigonometricLookupTable::cos_x_interval_table(), table_num_bytes);
    v8::Local<v8::Float64Array> sin_table = v8::Float64Array::New(
        sin_buffer, 0, TrigonometricLookupTable::table_size());
    v8::Local<v8::Float64Array> cos_table = v8::Float64Array::New(
        cos_buffer, 0, TrigonometricLookupTable::table_size());

2660 2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684
    Runtime::ForceSetObjectProperty(builtins,
                                    factory()->InternalizeOneByteString(
                                        STATIC_ASCII_VECTOR("kSinTable")),
                                    Utils::OpenHandle(*sin_table),
                                    NONE).Assert();
    Runtime::ForceSetObjectProperty(
        builtins,
        factory()->InternalizeOneByteString(
            STATIC_ASCII_VECTOR("kCosXIntervalTable")),
        Utils::OpenHandle(*cos_table),
        NONE).Assert();
    Runtime::ForceSetObjectProperty(
        builtins,
        factory()->InternalizeOneByteString(
            STATIC_ASCII_VECTOR("kSamples")),
        factory()->NewHeapNumber(
            TrigonometricLookupTable::samples()),
        NONE).Assert();
    Runtime::ForceSetObjectProperty(
        builtins,
        factory()->InternalizeOneByteString(
            STATIC_ASCII_VECTOR("kIndexConvert")),
        factory()->NewHeapNumber(
            TrigonometricLookupTable::samples_over_pi_half()),
        NONE).Assert();
2685 2686
  }

2687
  result_ = native_context();
2688 2689
}

2690 2691 2692 2693 2694

// Support for thread preemption.

// Reserve space for statics needing saving and restoring.
int Bootstrapper::ArchiveSpacePerThread() {
2695
  return sizeof(NestingCounterType);
2696 2697 2698
}


2699
// Archive statics that are thread-local.
2700
char* Bootstrapper::ArchiveState(char* to) {
2701 2702 2703
  *reinterpret_cast<NestingCounterType*>(to) = nesting_;
  nesting_ = 0;
  return to + sizeof(NestingCounterType);
2704 2705 2706
}


2707
// Restore statics that are thread-local.
2708
char* Bootstrapper::RestoreState(char* from) {
2709 2710
  nesting_ = *reinterpret_cast<NestingCounterType*>(from);
  return from + sizeof(NestingCounterType);
2711 2712 2713
}


2714 2715
// Called when the top-level V8 mutex is destroyed.
void Bootstrapper::FreeThreadResources() {
2716
  ASSERT(!IsActive());
2717 2718
}

2719
} }  // namespace v8::internal