bootstrapper.cc 201 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
#include "src/accessors.h"
8
#include "src/api-natives.h"
9
#include "src/base/ieee754.h"
10
#include "src/code-stubs.h"
11
#include "src/compiler.h"
12 13 14
#include "src/extensions/externalize-string-extension.h"
#include "src/extensions/free-buffer-extension.h"
#include "src/extensions/gc-extension.h"
15
#include "src/extensions/ignition-statistics-extension.h"
16 17
#include "src/extensions/statistics-extension.h"
#include "src/extensions/trigger-failure-extension.h"
18
#include "src/heap/heap.h"
19
#include "src/isolate-inl.h"
20 21
#include "src/snapshot/natives.h"
#include "src/snapshot/snapshot.h"
22 23
#include "src/wasm/wasm-js.h"

24 25
namespace v8 {
namespace internal {
26

27 28 29
Bootstrapper::Bootstrapper(Isolate* isolate)
    : isolate_(isolate),
      nesting_(0),
30
      extensions_cache_(Script::TYPE_EXTENSION) {}
31

32 33 34
template <class Source>
Handle<String> Bootstrapper::SourceLookup(int index) {
  DCHECK(0 <= index && index < Source::GetBuiltinsCount());
35
  Heap* heap = isolate_->heap();
36
  if (Source::GetSourceCache(heap)->get(index)->IsUndefined(isolate_)) {
37
    // We can use external strings for the natives.
38
    Vector<const char> source = Source::GetScriptSource(index);
39
    NativesExternalStringResource* resource =
40
        new NativesExternalStringResource(source.start(), source.length());
41 42
    Handle<ExternalOneByteString> source_code =
        isolate_->factory()->NewNativeSourceString(resource);
43
    // Mark this external string with a special map.
44
    DCHECK(source_code->is_short());
45
    Source::GetSourceCache(heap)->set(index, *source_code);
46
  }
47 48
  Handle<Object> cached_source(Source::GetSourceCache(heap)->get(index),
                               isolate_);
49 50 51 52
  return Handle<String>::cast(cached_source);
}


53 54 55
template Handle<String> Bootstrapper::SourceLookup<Natives>(int index);
template Handle<String> Bootstrapper::SourceLookup<ExperimentalNatives>(
    int index);
56 57
template Handle<String> Bootstrapper::SourceLookup<ExperimentalExtraNatives>(
    int index);
58
template Handle<String> Bootstrapper::SourceLookup<ExtraNatives>(int index);
59 60


61
void Bootstrapper::Initialize(bool create_heap_objects) {
62
  extensions_cache_.Initialize(isolate_, create_heap_objects);
63 64 65
}


66 67 68 69 70 71 72 73 74 75 76
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;
77
v8::Extension* Bootstrapper::ignition_statistics_extension_ = NULL;
78

79
void Bootstrapper::InitializeOncePerProcess() {
80 81 82 83 84 85 86 87 88 89
  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_);
90 91
  ignition_statistics_extension_ = new IgnitionStatisticsExtension;
  v8::RegisterExtension(ignition_statistics_extension_);
92 93 94 95 96
}


void Bootstrapper::TearDownExtensions() {
  delete free_buffer_extension_;
97
  free_buffer_extension_ = NULL;
98
  delete gc_extension_;
99
  gc_extension_ = NULL;
100
  delete externalize_string_extension_;
101
  externalize_string_extension_ = NULL;
102
  delete statistics_extension_;
103
  statistics_extension_ = NULL;
104
  delete trigger_failure_extension_;
105
  trigger_failure_extension_ = NULL;
106 107
  delete ignition_statistics_extension_;
  ignition_statistics_extension_ = NULL;
108 109 110
}


111 112 113
void DeleteNativeSources(Object* maybe_array) {
  if (maybe_array->IsFixedArray()) {
    FixedArray* array = FixedArray::cast(maybe_array);
114
    Isolate* isolate = array->GetIsolate();
115 116
    for (int i = 0; i < array->length(); i++) {
      Object* natives_source = array->get(i);
117
      if (!natives_source->IsUndefined(isolate)) {
118 119 120 121 122
        const NativesExternalStringResource* resource =
            reinterpret_cast<const NativesExternalStringResource*>(
                ExternalOneByteString::cast(natives_source)->resource());
        delete resource;
      }
123 124
    }
  }
125
}
126

127 128

void Bootstrapper::TearDown() {
129 130 131
  DeleteNativeSources(Natives::GetSourceCache(isolate_->heap()));
  DeleteNativeSources(ExperimentalNatives::GetSourceCache(isolate_->heap()));
  DeleteNativeSources(ExtraNatives::GetSourceCache(isolate_->heap()));
132 133 134
  DeleteNativeSources(
      ExperimentalExtraNatives::GetSourceCache(isolate_->heap()));

135
  extensions_cache_.Initialize(isolate_, false);  // Yes, symmetrical
136 137 138 139 140
}


class Genesis BASE_EMBEDDED {
 public:
141 142
  Genesis(Isolate* isolate, MaybeHandle<JSGlobalProxy> maybe_global_proxy,
          v8::Local<v8::ObjectTemplate> global_proxy_template,
143
          size_t context_snapshot_index, GlobalContextType context_type);
144 145
  Genesis(Isolate* isolate, MaybeHandle<JSGlobalProxy> maybe_global_proxy,
          v8::Local<v8::ObjectTemplate> global_proxy_template);
146
  ~Genesis() { }
147

148 149 150 151
  Isolate* isolate() const { return isolate_; }
  Factory* factory() const { return isolate_->factory(); }
  Heap* heap() const { return isolate_->heap(); }

152
  Handle<Context> result() { return result_; }
153

154 155
  Handle<JSGlobalProxy> global_proxy() { return global_proxy_; }

156
 private:
157
  Handle<Context> native_context() { return native_context_; }
158

159 160 161
  // Creates some basic objects. Used for creating a context from scratch.
  void CreateRoots();
  // Creates the empty function.  Used for creating a context from scratch.
162
  Handle<JSFunction> CreateEmptyFunction(Isolate* isolate);
163
  // Creates the ThrowTypeError function. ECMA 5th Ed. 13.2.3
164 165
  Handle<JSFunction> GetRestrictedFunctionPropertiesThrower();
  Handle<JSFunction> GetStrictArgumentsPoisonFunction();
166
  Handle<JSFunction> GetThrowTypeErrorIntrinsic(Builtins::Name builtin_name);
167 168

  void CreateStrictModeFunctionMaps(Handle<JSFunction> empty);
169
  void CreateIteratorMaps(Handle<JSFunction> empty);
170
  void CreateAsyncFunctionMaps(Handle<JSFunction> empty);
171
  void CreateJSProxyMaps();
172 173

  // Make the "arguments" and "caller" properties throw a TypeError on access.
174
  void AddRestrictedFunctionProperties(Handle<JSFunction> empty);
175

176 177
  // Creates the global objects using the global proxy and the template passed
  // in through the API.  We call this regardless of whether we are building a
178 179
  // 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
180 181 182
  // we have to use the deserialized ones that are linked together with the
  // rest of the context snapshot. At the end we link the global proxy and the
  // context to each other.
183
  Handle<JSGlobalObject> CreateNewGlobals(
184
      v8::Local<v8::ObjectTemplate> global_proxy_template,
185
      Handle<JSGlobalProxy> global_proxy);
186 187 188
  // Similarly, we want to use the global that has been created by the templates
  // passed through the API.  The global from the snapshot is detached from the
  // other objects in the snapshot.
189
  void HookUpGlobalObject(Handle<JSGlobalObject> global_object);
190 191 192
  // Hooks the given global proxy into the context in the case we do not
  // replace the global object from the deserialized native context.
  void HookUpGlobalProxy(Handle<JSGlobalProxy> global_proxy);
193 194 195 196
  // The native context has a ScriptContextTable that store declarative bindings
  // made in script scopes.  Add a "this" binding to that table pointing to the
  // global proxy.
  void InstallGlobalThisBinding();
197
  // New context initialization.  Used for creating a context from scratch.
198
  void InitializeGlobal(Handle<JSGlobalObject> global_object,
199
                        Handle<JSFunction> empty_function,
200
                        GlobalContextType context_type);
201
  void InitializeExperimentalGlobal();
202
  // Depending on the situation, expose and/or get rid of the utils object.
203
  void ConfigureUtilsObject(GlobalContextType context_type);
204 205 206 207

#define DECLARE_FEATURE_INITIALIZATION(id, descr) \
  void InitializeGlobal_##id();

208 209 210
  HARMONY_INPROGRESS(DECLARE_FEATURE_INITIALIZATION)
  HARMONY_STAGED(DECLARE_FEATURE_INITIALIZATION)
  HARMONY_SHIPPING(DECLARE_FEATURE_INITIALIZATION)
211 212
#undef DECLARE_FEATURE_INITIALIZATION

213
  Handle<JSFunction> InstallArrayBuffer(Handle<JSObject> target,
214 215
                                        const char* name, Builtins::Name call,
                                        BuiltinFunctionId id);
216
  Handle<JSFunction> InstallInternalArray(Handle<JSObject> target,
217 218
                                          const char* name,
                                          ElementsKind elements_kind);
219
  bool InstallNatives(GlobalContextType context_type);
220

221 222
  void InstallTypedArray(const char* name, ElementsKind elements_kind,
                         Handle<JSFunction>* fun);
223
  bool InstallExperimentalNatives();
224
  bool InstallExtraNatives();
225
  bool InstallExperimentalExtraNatives();
226
  bool InstallDebuggerNatives();
227
  void InstallBuiltinFunctionIds();
binji's avatar
binji committed
228
  void InstallExperimentalBuiltinFunctionIds();
229
  void InitializeNormalizedMapCaches();
230

231 232 233 234 235
  enum ExtensionTraversalState {
    UNVISITED, VISITED, INSTALLED
  };

  class ExtensionStates {
236
   public:
237 238 239 240
    ExtensionStates();
    ExtensionTraversalState get_state(RegisteredExtension* extension);
    void set_state(RegisteredExtension* extension,
                   ExtensionTraversalState state);
241
   private:
lpy's avatar
lpy committed
242
    base::HashMap map_;
243
    DISALLOW_COPY_AND_ASSIGN(ExtensionStates);
244 245
  };

246 247
  // Used both for deserialized and from-scratch contexts to add the extensions
  // provided.
248
  static bool InstallExtensions(Handle<Context> native_context,
249
                                v8::ExtensionConfiguration* extensions);
250 251 252 253 254
  static bool InstallAutoExtensions(Isolate* isolate,
                                    ExtensionStates* extension_states);
  static bool InstallRequestedExtensions(Isolate* isolate,
                                         v8::ExtensionConfiguration* extensions,
                                         ExtensionStates* extension_states);
255 256
  static bool InstallExtension(Isolate* isolate,
                               const char* name,
257
                               ExtensionStates* extension_states);
258 259
  static bool InstallExtension(Isolate* isolate,
                               v8::RegisteredExtension* current,
260
                               ExtensionStates* extension_states);
261
  static bool InstallSpecialObjects(Handle<Context> native_context);
262 263
  bool ConfigureApiObject(Handle<JSObject> object,
                          Handle<ObjectTemplateInfo> object_template);
264
  bool ConfigureGlobalObjects(
265
      v8::Local<v8::ObjectTemplate> global_proxy_template);
266 267 268 269 270 271 272 273 274 275

  // 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);

  void MakeFunctionInstancePrototypeWritable();

276
  void SetStrictFunctionInstanceDescriptor(Handle<Map> map,
277
                                           FunctionMode function_mode);
278

279 280
  static bool CallUtilsFunction(Isolate* isolate, const char* name);

281
  static bool CompileExtension(Isolate* isolate, v8::Extension* extension);
282

283
  Isolate* isolate_;
284
  Handle<Context> result_;
285
  Handle<Context> native_context_;
286
  Handle<JSGlobalProxy> global_proxy_;
287

288 289 290 291
  // 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.
292 293
  Handle<Map> sloppy_function_map_writable_prototype_;
  Handle<Map> strict_function_map_writable_prototype_;
294
  Handle<Map> class_function_map_;
295 296
  Handle<JSFunction> strict_poison_function_;
  Handle<JSFunction> restricted_function_properties_thrower_;
297

298 299
  BootstrapperActive active_;
  friend class Bootstrapper;
300 301 302 303
};


void Bootstrapper::Iterate(ObjectVisitor* v) {
304
  extensions_cache_.Iterate(v);
305
  v->Synchronize(VisitorSynchronization::kExtensions);
306 307 308
}

Handle<Context> Bootstrapper::CreateEnvironment(
309
    MaybeHandle<JSGlobalProxy> maybe_global_proxy,
310
    v8::Local<v8::ObjectTemplate> global_proxy_template,
311 312
    v8::ExtensionConfiguration* extensions, size_t context_snapshot_index,
    GlobalContextType context_type) {
313
  HandleScope scope(isolate_);
314
  Genesis genesis(isolate_, maybe_global_proxy, global_proxy_template,
315
                  context_snapshot_index, context_type);
316
  Handle<Context> env = genesis.result();
317
  if (env.is_null() || !InstallExtensions(env, extensions)) {
318
    return Handle<Context>();
319
  }
320
  return scope.CloseAndEscape(env);
321 322
}

323 324 325 326 327 328 329 330 331
Handle<JSGlobalProxy> Bootstrapper::NewRemoteContext(
    MaybeHandle<JSGlobalProxy> maybe_global_proxy,
    v8::Local<v8::ObjectTemplate> global_proxy_template) {
  HandleScope scope(isolate_);
  Genesis genesis(isolate_, maybe_global_proxy, global_proxy_template);
  Handle<JSGlobalProxy> global_proxy = genesis.global_proxy();
  if (global_proxy.is_null()) return Handle<JSGlobalProxy>();
  return scope.CloseAndEscape(global_proxy);
}
332

333
void Bootstrapper::DetachGlobal(Handle<Context> env) {
334 335 336
  env->GetIsolate()->counters()->errors_thrown_per_context()->AddSample(
    env->GetErrorsThrown());

337
  Factory* factory = env->GetIsolate()->factory();
338 339
  Handle<JSGlobalProxy> global_proxy(JSGlobalProxy::cast(env->global_proxy()));
  global_proxy->set_native_context(*factory->null_value());
340
  JSObject::ForceSetPrototype(global_proxy, factory->null_value());
341
  global_proxy->map()->SetConstructor(*factory->null_value());
342 343 344
  if (FLAG_track_detached_contexts) {
    env->GetIsolate()->AddDetachedContext(env);
  }
345 346
}

347 348
namespace {

349 350 351
void InstallFunction(Handle<JSObject> target, Handle<Name> property_name,
                     Handle<JSFunction> function, Handle<String> function_name,
                     PropertyAttributes attributes = DONT_ENUM) {
352 353 354 355 356
  JSObject::AddProperty(target, property_name, function, attributes);
  if (target->IsJSGlobalObject()) {
    function->shared()->set_instance_class_name(*function_name);
  }
  function->shared()->set_native(true);
357 358
}

359 360 361
void InstallFunction(Handle<JSObject> target, Handle<JSFunction> function,
                     Handle<Name> name,
                     PropertyAttributes attributes = DONT_ENUM) {
362 363 364 365
  Handle<String> name_string = Name::ToFunctionName(name).ToHandleChecked();
  InstallFunction(target, name, function, name_string, attributes);
}

366 367 368 369 370
Handle<JSFunction> CreateFunction(Isolate* isolate, Handle<String> name,
                                  InstanceType type, int instance_size,
                                  MaybeHandle<JSObject> maybe_prototype,
                                  Builtins::Name call,
                                  bool strict_function_map = false) {
371 372 373 374 375
  Factory* factory = isolate->factory();
  Handle<Code> call_code(isolate->builtins()->builtin(call));
  Handle<JSObject> prototype;
  return maybe_prototype.ToHandle(&prototype)
             ? factory->NewFunction(name, call_code, prototype, type,
376
                                    instance_size, strict_function_map)
377 378
             : factory->NewFunctionWithoutPrototype(name, call_code,
                                                    strict_function_map);
379 380
}

381 382 383 384 385 386 387
Handle<JSFunction> InstallFunction(Handle<JSObject> target, Handle<Name> name,
                                   InstanceType type, int instance_size,
                                   MaybeHandle<JSObject> maybe_prototype,
                                   Builtins::Name call,
                                   PropertyAttributes attributes,
                                   bool strict_function_map = false) {
  Handle<String> name_string = Name::ToFunctionName(name).ToHandleChecked();
388
  Handle<JSFunction> function =
389 390 391 392
      CreateFunction(target->GetIsolate(), name_string, type, instance_size,
                     maybe_prototype, call, strict_function_map);
  InstallFunction(target, name, function, name_string, attributes);
  return function;
393 394 395 396 397 398 399 400
}

Handle<JSFunction> InstallFunction(Handle<JSObject> target, const char* name,
                                   InstanceType type, int instance_size,
                                   MaybeHandle<JSObject> maybe_prototype,
                                   Builtins::Name call,
                                   bool strict_function_map = false) {
  Factory* const factory = target->GetIsolate()->factory();
yangguo's avatar
yangguo committed
401
  PropertyAttributes attributes = DONT_ENUM;
402 403 404
  return InstallFunction(target, factory->InternalizeUtf8String(name), type,
                         instance_size, maybe_prototype, call, attributes,
                         strict_function_map);
405 406
}

407 408 409 410 411 412 413 414 415 416 417 418 419 420
Handle<JSFunction> SimpleCreateFunction(Isolate* isolate, Handle<String> name,
                                        Builtins::Name call, int len,
                                        bool adapt) {
  Handle<JSFunction> fun =
      CreateFunction(isolate, name, JS_OBJECT_TYPE, JSObject::kHeaderSize,
                     MaybeHandle<JSObject>(), call);
  if (adapt) {
    fun->shared()->set_internal_formal_parameter_count(len);
  } else {
    fun->shared()->DontAdaptArguments();
  }
  fun->shared()->set_length(len);
  return fun;
}
421

422 423 424
Handle<JSFunction> SimpleInstallFunction(Handle<JSObject> base,
                                         Handle<String> name,
                                         Builtins::Name call, int len,
425 426
                                         bool adapt,
                                         PropertyAttributes attrs = DONT_ENUM) {
427 428
  Handle<JSFunction> fun =
      SimpleCreateFunction(base->GetIsolate(), name, call, len, adapt);
429
  InstallFunction(base, fun, name, attrs);
430 431 432 433 434
  return fun;
}

Handle<JSFunction> SimpleInstallFunction(Handle<JSObject> base,
                                         const char* name, Builtins::Name call,
435 436
                                         int len, bool adapt,
                                         PropertyAttributes attrs = DONT_ENUM) {
437 438
  Factory* const factory = base->GetIsolate()->factory();
  return SimpleInstallFunction(base, factory->InternalizeUtf8String(name), call,
439
                               len, adapt, attrs);
440 441
}

442 443 444 445 446 447 448 449 450
Handle<JSFunction> SimpleInstallFunction(Handle<JSObject> base,
                                         const char* name, Builtins::Name call,
                                         int len, bool adapt,
                                         BuiltinFunctionId id) {
  Handle<JSFunction> fun = SimpleInstallFunction(base, name, call, len, adapt);
  fun->shared()->set_builtin_function_id(id);
  return fun;
}

451 452 453 454 455 456 457 458 459 460
void SimpleInstallGetterSetter(Handle<JSObject> base, Handle<String> name,
                               Builtins::Name call_getter,
                               Builtins::Name call_setter,
                               PropertyAttributes attribs) {
  Isolate* const isolate = base->GetIsolate();

  Handle<String> getter_name =
      Name::ToFunctionName(name, isolate->factory()->get_string())
          .ToHandleChecked();
  Handle<JSFunction> getter =
461
      SimpleCreateFunction(isolate, getter_name, call_getter, 0, true);
462 463 464 465 466 467
  getter->shared()->set_native(true);

  Handle<String> setter_name =
      Name::ToFunctionName(name, isolate->factory()->set_string())
          .ToHandleChecked();
  Handle<JSFunction> setter =
468
      SimpleCreateFunction(isolate, setter_name, call_setter, 1, true);
469 470 471 472 473
  setter->shared()->set_native(true);

  JSObject::DefineAccessor(base, name, getter, setter, attribs).Check();
}

474
Handle<JSFunction> SimpleInstallGetter(Handle<JSObject> base,
475 476 477
                                       Handle<String> name,
                                       Handle<Name> property_name,
                                       Builtins::Name call, bool adapt) {
478
  Isolate* const isolate = base->GetIsolate();
479 480

  Handle<String> getter_name =
481 482
      Name::ToFunctionName(name, isolate->factory()->get_string())
          .ToHandleChecked();
483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498
  Handle<JSFunction> getter =
      SimpleCreateFunction(isolate, getter_name, call, 0, adapt);
  getter->shared()->set_native(true);

  Handle<Object> setter = isolate->factory()->undefined_value();

  JSObject::DefineAccessor(base, property_name, getter, setter, DONT_ENUM)
      .Check();

  return getter;
}

Handle<JSFunction> SimpleInstallGetter(Handle<JSObject> base,
                                       Handle<String> name, Builtins::Name call,
                                       bool adapt) {
  return SimpleInstallGetter(base, name, name, call, adapt);
499 500 501 502 503 504 505 506 507 508
}

Handle<JSFunction> SimpleInstallGetter(Handle<JSObject> base,
                                       Handle<String> name, Builtins::Name call,
                                       bool adapt, BuiltinFunctionId id) {
  Handle<JSFunction> fun = SimpleInstallGetter(base, name, call, adapt);
  fun->shared()->set_builtin_function_id(id);
  return fun;
}

509 510 511 512 513 514 515
void InstallConstant(Isolate* isolate, Handle<JSObject> holder,
                     const char* name, Handle<Object> value) {
  JSObject::AddProperty(
      holder, isolate->factory()->NewStringFromAsciiChecked(name), value,
      static_cast<PropertyAttributes>(DONT_DELETE | DONT_ENUM | READ_ONLY));
}

516
}  // namespace
517

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

522 523
  // Functions with this map will not have a 'prototype' property, and
  // can not be used as constructors.
524
  Handle<Map> function_without_prototype_map =
525
      factory()->CreateSloppyFunctionMap(FUNCTION_WITHOUT_PROTOTYPE);
526
  native_context()->set_sloppy_function_without_prototype_map(
527
      *function_without_prototype_map);
528

529 530 531
  // 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.
532
  Handle<Map> function_map =
533
      factory()->CreateSloppyFunctionMap(FUNCTION_WITH_READONLY_PROTOTYPE);
534
  native_context()->set_sloppy_function_map(*function_map);
535 536
  native_context()->set_sloppy_function_with_readonly_prototype_map(
      *function_map);
537 538 539

  // The final map for functions. Writeable prototype.
  // This map is installed in MakeFunctionInstancePrototypeWritable.
540
  sloppy_function_map_writable_prototype_ =
541
      factory()->CreateSloppyFunctionMap(FUNCTION_WITH_WRITEABLE_PROTOTYPE);
542 543
  Factory* factory = isolate->factory();

544
  Handle<String> object_name = factory->Object_string();
545

546 547
  Handle<JSObject> object_function_prototype;

548
  {  // --- O b j e c t ---
549
    Handle<JSFunction> object_fun = factory->NewFunction(object_name);
550 551
    int unused = JSObject::kInitialGlobalObjectUnusedPropertiesCount;
    int instance_size = JSObject::kHeaderSize + kPointerSize * unused;
552
    Handle<Map> object_function_map =
553
        factory->NewMap(JS_OBJECT_TYPE, instance_size);
554
    object_function_map->SetInObjectProperties(unused);
555 556
    JSFunction::SetInitialMap(object_fun, object_function_map,
                              isolate->factory()->null_value());
557
    object_function_map->set_unused_property_fields(unused);
558

559
    native_context()->set_object_function(*object_fun);
560 561

    // Allocate a new prototype for the object function.
562 563 564 565
    object_function_prototype =
        factory->NewJSObject(isolate->object_function(), TENURED);
    Handle<Map> map = Map::Copy(handle(object_function_prototype->map()),
                                "EmptyObjectPrototype");
566
    map->set_is_prototype_map(true);
567 568
    // Ban re-setting Object.prototype.__proto__ to prevent Proxy security bug
    map->set_immutable_proto(true);
569
    object_function_prototype->set_map(*map);
570

571
    native_context()->set_initial_object_prototype(*object_function_prototype);
572 573 574
    // 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.
575 576 577
    native_context()->set_initial_array_prototype(*object_function_prototype);
    Accessors::FunctionSetPrototype(object_fun, object_function_prototype)
        .Assert();
578 579
  }

580
  // Allocate the empty function as the prototype for function - ES6 19.2.3
581
  Handle<Code> code(isolate->builtins()->EmptyFunction());
582 583
  Handle<JSFunction> empty_function =
      factory->NewFunctionWithoutPrototype(factory->empty_string(), code);
584

585 586
  // Allocate the function map first and then patch the prototype later
  Handle<Map> empty_function_map =
587
      factory->CreateSloppyFunctionMap(FUNCTION_WITHOUT_PROTOTYPE);
588
  DCHECK(!empty_function_map->is_dictionary_map());
589
  Map::SetPrototype(empty_function_map, object_function_prototype);
590
  empty_function_map->set_is_prototype_map(true);
591

592 593
  empty_function->set_map(*empty_function_map);

594
  // --- E m p t y ---
595
  Handle<String> source = factory->NewStringFromStaticChars("() {}");
596
  Handle<Script> script = factory->NewScript(source);
597
  script->set_type(Script::TYPE_NATIVE);
598 599
  Handle<FixedArray> infos = factory->NewFixedArray(2);
  script->set_shared_function_infos(*infos);
600 601
  empty_function->shared()->set_start_position(0);
  empty_function->shared()->set_end_position(source->length());
602
  empty_function->shared()->set_function_literal_id(1);
603
  empty_function->shared()->DontAdaptArguments();
604
  SharedFunctionInfo::SetScript(handle(empty_function->shared()), script);
605 606

  // Set prototypes for the function maps.
607 608 609 610 611 612 613
  Handle<Map> sloppy_function_map(native_context()->sloppy_function_map(),
                                  isolate);
  Handle<Map> sloppy_function_without_prototype_map(
      native_context()->sloppy_function_without_prototype_map(), isolate);
  Map::SetPrototype(sloppy_function_map, empty_function);
  Map::SetPrototype(sloppy_function_without_prototype_map, empty_function);
  Map::SetPrototype(sloppy_function_map_writable_prototype_, empty_function);
614

615 616
  return empty_function;
}
617 618


619 620 621 622 623 624 625
// Creates the %ThrowTypeError% function.
Handle<JSFunction> Genesis::GetThrowTypeErrorIntrinsic(
    Builtins::Name builtin_name) {
  Handle<String> name =
      factory()->InternalizeOneByteString(STATIC_CHAR_VECTOR("ThrowTypeError"));
  Handle<Code> code(isolate()->builtins()->builtin(builtin_name));
  Handle<JSFunction> function =
626
      factory()->NewFunctionWithoutPrototype(name, code, true);
627 628 629
  function->shared()->DontAdaptArguments();

  // %ThrowTypeError% must not have a name property.
neis's avatar
neis committed
630
  if (JSReceiver::DeleteProperty(function, factory()->name_string())
631
          .IsNothing()) {
neis's avatar
neis committed
632
    DCHECK(false);
633
  }
634 635 636 637 638 639 640 641

  // length needs to be non configurable.
  Handle<Object> value(Smi::FromInt(function->shared()->length()), isolate());
  JSObject::SetOwnPropertyIgnoreAttributes(
      function, factory()->length_string(), value,
      static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY))
      .Assert();

642 643
  if (JSObject::PreventExtensions(function, Object::THROW_ON_ERROR)
          .IsNothing()) {
644
    DCHECK(false);
645
  }
646 647 648 649 650

  return function;
}


651
// ECMAScript 5th Edition, 13.2.3
652
Handle<JSFunction> Genesis::GetRestrictedFunctionPropertiesThrower() {
653 654 655
  if (restricted_function_properties_thrower_.is_null()) {
    restricted_function_properties_thrower_ = GetThrowTypeErrorIntrinsic(
        Builtins::kRestrictedFunctionPropertiesThrower);
656
  }
657
  return restricted_function_properties_thrower_;
658 659 660
}


661
Handle<JSFunction> Genesis::GetStrictArgumentsPoisonFunction() {
662 663 664
  if (strict_poison_function_.is_null()) {
    strict_poison_function_ = GetThrowTypeErrorIntrinsic(
        Builtins::kRestrictedStrictArgumentsPropertiesThrower);
665
  }
666
  return strict_poison_function_;
667 668 669 670 671
}


void Genesis::CreateStrictModeFunctionMaps(Handle<JSFunction> empty) {
  // Allocate map for the prototype-less strict mode instances.
672
  Handle<Map> strict_function_without_prototype_map =
673
      factory()->CreateStrictFunctionMap(FUNCTION_WITHOUT_PROTOTYPE, empty);
674 675
  native_context()->set_strict_function_without_prototype_map(
      *strict_function_without_prototype_map);
676 677 678 679

  // 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.
680 681
  Handle<Map> strict_function_map = factory()->CreateStrictFunctionMap(
      FUNCTION_WITH_READONLY_PROTOTYPE, empty);
682
  native_context()->set_strict_function_map(*strict_function_map);
683 684 685

  // The final map for the strict mode functions. Writeable prototype.
  // This map is installed in MakeFunctionInstancePrototypeWritable.
686 687
  strict_function_map_writable_prototype_ = factory()->CreateStrictFunctionMap(
      FUNCTION_WITH_WRITEABLE_PROTOTYPE, empty);
688

689 690 691 692
  // Allocate map for classes
  class_function_map_ = factory()->CreateClassFunctionMap(empty);
  native_context()->set_class_function_map(*class_function_map_);

693 694 695
  // Now that the strict mode function map is available, set up the
  // restricted "arguments" and "caller" getters.
  AddRestrictedFunctionProperties(empty);
696 697
}

698
void Genesis::CreateIteratorMaps(Handle<JSFunction> empty) {
699 700 701
  // Create iterator-related meta-objects.
  Handle<JSObject> iterator_prototype =
      factory()->NewJSObject(isolate()->object_function(), TENURED);
702 703 704

  Handle<JSFunction> iterator_prototype_iterator = SimpleCreateFunction(
      isolate(), factory()->NewStringFromAsciiChecked("[Symbol.iterator]"),
705
      Builtins::kIteratorPrototypeIterator, 0, true);
706 707 708 709 710 711
  iterator_prototype_iterator->shared()->set_native(true);

  JSObject::AddProperty(iterator_prototype, factory()->iterator_symbol(),
                        iterator_prototype_iterator, DONT_ENUM);
  native_context()->set_initial_iterator_prototype(*iterator_prototype);

712 713
  Handle<JSObject> generator_object_prototype =
      factory()->NewJSObject(isolate()->object_function(), TENURED);
714 715
  native_context()->set_initial_generator_prototype(
      *generator_object_prototype);
716
  JSObject::ForceSetPrototype(generator_object_prototype, iterator_prototype);
717 718
  Handle<JSObject> generator_function_prototype =
      factory()->NewJSObject(isolate()->object_function(), TENURED);
719
  JSObject::ForceSetPrototype(generator_function_prototype, empty);
720

721 722 723 724
  JSObject::AddProperty(
      generator_function_prototype, factory()->to_string_tag_symbol(),
      factory()->NewStringFromAsciiChecked("GeneratorFunction"),
      static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY));
725
  JSObject::AddProperty(generator_function_prototype,
726
                        factory()->prototype_string(),
727 728 729
                        generator_object_prototype,
                        static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY));

730 731 732 733 734 735 736 737 738 739 740 741 742 743 744
  JSObject::AddProperty(generator_object_prototype,
                        factory()->constructor_string(),
                        generator_function_prototype,
                        static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY));
  JSObject::AddProperty(generator_object_prototype,
                        factory()->to_string_tag_symbol(),
                        factory()->NewStringFromAsciiChecked("Generator"),
                        static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY));
  SimpleInstallFunction(generator_object_prototype, "next",
                        Builtins::kGeneratorPrototypeNext, 1, true);
  SimpleInstallFunction(generator_object_prototype, "return",
                        Builtins::kGeneratorPrototypeReturn, 1, true);
  SimpleInstallFunction(generator_object_prototype, "throw",
                        Builtins::kGeneratorPrototypeThrow, 1, true);

745 746 747 748 749 750
  // Internal version of generator_prototype_next, flagged as non-native.
  Handle<JSFunction> generator_next_internal =
      SimpleCreateFunction(isolate(), factory()->next_string(),
                           Builtins::kGeneratorPrototypeNext, 1, true);
  native_context()->set_generator_next_internal(*generator_next_internal);

751 752 753 754 755 756 757 758
  // Create maps for generator functions and their prototypes.  Store those
  // maps in the native context. The "prototype" property descriptor is
  // writable, non-enumerable, and non-configurable (as per ES6 draft
  // 04-14-15, section 25.2.4.3).
  Handle<Map> strict_function_map(strict_function_map_writable_prototype_);
  // Generator functions do not have "caller" or "arguments" accessors.
  Handle<Map> sloppy_generator_function_map =
      Map::Copy(strict_function_map, "SloppyGeneratorFunction");
759
  sloppy_generator_function_map->set_is_constructor(false);
760 761 762 763 764 765 766
  Map::SetPrototype(sloppy_generator_function_map,
                    generator_function_prototype);
  native_context()->set_sloppy_generator_function_map(
      *sloppy_generator_function_map);

  Handle<Map> strict_generator_function_map =
      Map::Copy(strict_function_map, "StrictGeneratorFunction");
767
  strict_generator_function_map->set_is_constructor(false);
768 769 770 771 772 773 774 775 776 777 778 779
  Map::SetPrototype(strict_generator_function_map,
                    generator_function_prototype);
  native_context()->set_strict_generator_function_map(
      *strict_generator_function_map);

  Handle<JSFunction> object_function(native_context()->object_function());
  Handle<Map> generator_object_prototype_map = Map::Create(isolate(), 0);
  Map::SetPrototype(generator_object_prototype_map, generator_object_prototype);
  native_context()->set_generator_object_prototype_map(
      *generator_object_prototype_map);
}

780 781 782 783
void Genesis::CreateAsyncFunctionMaps(Handle<JSFunction> empty) {
  // %AsyncFunctionPrototype% intrinsic
  Handle<JSObject> async_function_prototype =
      factory()->NewJSObject(isolate()->object_function(), TENURED);
784
  JSObject::ForceSetPrototype(async_function_prototype, empty);
785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805

  JSObject::AddProperty(async_function_prototype,
                        factory()->to_string_tag_symbol(),
                        factory()->NewStringFromAsciiChecked("AsyncFunction"),
                        static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY));

  Handle<Map> strict_function_map(
      native_context()->strict_function_without_prototype_map());
  Handle<Map> sloppy_async_function_map =
      Map::Copy(strict_function_map, "SloppyAsyncFunction");
  sloppy_async_function_map->set_is_constructor(false);
  Map::SetPrototype(sloppy_async_function_map, async_function_prototype);
  native_context()->set_sloppy_async_function_map(*sloppy_async_function_map);

  Handle<Map> strict_async_function_map =
      Map::Copy(strict_function_map, "StrictAsyncFunction");
  strict_async_function_map->set_is_constructor(false);
  Map::SetPrototype(strict_async_function_map, async_function_prototype);
  native_context()->set_strict_async_function_map(*strict_async_function_map);
}

806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829
void Genesis::CreateJSProxyMaps() {
  // Allocate the different maps for all Proxy types.
  // Next to the default proxy, we need maps indicating callable and
  // constructable proxies.
  Handle<Map> proxy_function_map =
      Map::Copy(isolate()->sloppy_function_without_prototype_map(), "Proxy");
  proxy_function_map->set_is_constructor(true);
  native_context()->set_proxy_function_map(*proxy_function_map);

  Handle<Map> proxy_map =
      factory()->NewMap(JS_PROXY_TYPE, JSProxy::kSize, FAST_ELEMENTS);
  proxy_map->set_dictionary_map(true);
  native_context()->set_proxy_map(*proxy_map);

  Handle<Map> proxy_callable_map = Map::Copy(proxy_map, "callable Proxy");
  proxy_callable_map->set_is_callable();
  native_context()->set_proxy_callable_map(*proxy_callable_map);
  proxy_callable_map->SetConstructor(native_context()->function_function());

  Handle<Map> proxy_constructor_map =
      Map::Copy(proxy_callable_map, "constructor Proxy");
  proxy_constructor_map->set_is_constructor(true);
  native_context()->set_proxy_constructor_map(*proxy_constructor_map);
}
830

831 832 833 834 835
static void ReplaceAccessors(Handle<Map> map,
                             Handle<String> name,
                             PropertyAttributes attributes,
                             Handle<AccessorPair> accessor_pair) {
  DescriptorArray* descriptors = map->instance_descriptors();
836
  int idx = descriptors->SearchWithCache(map->GetIsolate(), *name, *map);
837
  AccessorConstantDescriptor descriptor(name, accessor_pair, attributes);
838 839 840
  descriptors->Replace(idx, &descriptor);
}

841
void Genesis::AddRestrictedFunctionProperties(Handle<JSFunction> empty) {
842 843 844 845 846 847
  PropertyAttributes rw_attribs = static_cast<PropertyAttributes>(DONT_ENUM);
  Handle<JSFunction> thrower = GetRestrictedFunctionPropertiesThrower();
  Handle<AccessorPair> accessors = factory()->NewAccessorPair();
  accessors->set_getter(*thrower);
  accessors->set_setter(*thrower);

848
  Handle<Map> map(empty->map());
849 850
  ReplaceAccessors(map, factory()->arguments_string(), rw_attribs, accessors);
  ReplaceAccessors(map, factory()->caller_string(), rw_attribs, accessors);
851 852 853
}


854
static void AddToWeakNativeContextList(Context* context) {
855
  DCHECK(context->IsNativeContext());
856 857
  Isolate* isolate = context->GetIsolate();
  Heap* heap = isolate->heap();
858 859
#ifdef DEBUG
  { // NOLINT
860
    DCHECK(context->next_context_link()->IsUndefined(isolate));
861
    // Check that context is not in the list yet.
862
    for (Object* current = heap->native_contexts_list();
863
         !current->IsUndefined(isolate);
864
         current = Context::cast(current)->next_context_link()) {
865
      DCHECK(current != context);
866 867 868
    }
  }
#endif
869 870
  context->set(Context::NEXT_CONTEXT_LINK, heap->native_contexts_list(),
               UPDATE_WEAK_WRITE_BARRIER);
871
  heap->set_native_contexts_list(context);
872 873 874
}


875
void Genesis::CreateRoots() {
876
  // Allocate the native context FixedArray first and then patch the
877 878
  // closure and extension object later (we need the empty function
  // and the global object, but in order to create those, we need the
879
  // native context).
880 881
  native_context_ = factory()->NewNativeContext();
  AddToWeakNativeContextList(*native_context());
882
  isolate()->set_context(*native_context());
883

884 885
  // Allocate the message listeners object.
  {
886 887
    Handle<TemplateList> list = TemplateList::New(isolate(), 1);
    native_context()->set_message_listeners(*list);
888 889
  }
}
890 891


892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909
void Genesis::InstallGlobalThisBinding() {
  Handle<ScriptContextTable> script_contexts(
      native_context()->script_context_table());
  Handle<ScopeInfo> scope_info = ScopeInfo::CreateGlobalThisBinding(isolate());
  Handle<JSFunction> closure(native_context()->closure());
  Handle<Context> context = factory()->NewScriptContext(closure, scope_info);

  // Go ahead and hook it up while we're at it.
  int slot = scope_info->ReceiverContextSlotIndex();
  DCHECK_EQ(slot, Context::MIN_CONTEXT_SLOTS);
  context->set(slot, native_context()->global_proxy());

  Handle<ScriptContextTable> new_script_contexts =
      ScriptContextTable::Extend(script_contexts, context);
  native_context()->set_script_context_table(*new_script_contexts);
}


910
Handle<JSGlobalObject> Genesis::CreateNewGlobals(
911
    v8::Local<v8::ObjectTemplate> global_proxy_template,
912
    Handle<JSGlobalProxy> global_proxy) {
913
  // The argument global_proxy_template aka data is an ObjectTemplateInfo.
914 915
  // It has a constructor pointer that points at global_constructor which is a
  // FunctionTemplateInfo.
916
  // The global_proxy_constructor is used to (re)initialize the
917 918 919
  // global_proxy. The global_proxy_constructor also has a prototype_template
  // pointer that points at js_global_object_template which is an
  // ObjectTemplateInfo.
920
  // That in turn has a constructor pointer that points at
921 922 923
  // js_global_object_constructor which is a FunctionTemplateInfo.
  // js_global_object_constructor is used to make js_global_object_function
  // js_global_object_function is used to make the new global_object.
924 925
  //
  // --- G l o b a l ---
926 927 928 929 930
  // Step 1: Create a fresh JSGlobalObject.
  Handle<JSFunction> js_global_object_function;
  Handle<ObjectTemplateInfo> js_global_object_template;
  if (!global_proxy_template.IsEmpty()) {
    // Get prototype template of the global_proxy_template.
931
    Handle<ObjectTemplateInfo> data =
932
        v8::Utils::OpenHandle(*global_proxy_template);
933 934 935
    Handle<FunctionTemplateInfo> global_constructor =
        Handle<FunctionTemplateInfo>(
            FunctionTemplateInfo::cast(data->constructor()));
936 937
    Handle<Object> proto_template(global_constructor->prototype_template(),
                                  isolate());
938
    if (!proto_template->IsUndefined(isolate())) {
939
      js_global_object_template =
940
          Handle<ObjectTemplateInfo>::cast(proto_template);
941
    }
942
  }
943

944
  if (js_global_object_template.is_null()) {
945
    Handle<String> name = Handle<String>(heap()->empty_string());
946
    Handle<Code> code = isolate()->builtins()->Illegal();
947 948
    Handle<JSObject> prototype =
        factory()->NewFunctionPrototype(isolate()->object_function());
949
    js_global_object_function = factory()->NewFunction(
950 951 952 953 954 955 956 957
        name, code, prototype, JS_GLOBAL_OBJECT_TYPE, JSGlobalObject::kSize);
#ifdef DEBUG
    LookupIterator it(prototype, factory()->constructor_string(),
                      LookupIterator::OWN_SKIP_INTERCEPTOR);
    Handle<Object> value = Object::GetProperty(&it).ToHandleChecked();
    DCHECK(it.IsFound());
    DCHECK_EQ(*isolate()->object_function(), *value);
#endif
958
  } else {
959 960
    Handle<FunctionTemplateInfo> js_global_object_constructor(
        FunctionTemplateInfo::cast(js_global_object_template->constructor()));
961
    js_global_object_function = ApiNatives::CreateApiFunction(
962 963
        isolate(), js_global_object_constructor, factory()->the_hole_value(),
        ApiNatives::GlobalObjectType);
964
  }
965

966
  js_global_object_function->initial_map()->set_is_prototype_map(true);
967
  js_global_object_function->initial_map()->set_dictionary_map(true);
968 969
  Handle<JSGlobalObject> global_object =
      factory()->NewJSGlobalObject(js_global_object_function);
970

971
  // Step 2: (re)initialize the global proxy object.
972
  Handle<JSFunction> global_proxy_function;
973
  if (global_proxy_template.IsEmpty()) {
974
    Handle<String> name = Handle<String>(heap()->empty_string());
975
    Handle<Code> code = isolate()->builtins()->Illegal();
976 977
    global_proxy_function =
        factory()->NewFunction(name, code, JS_GLOBAL_PROXY_TYPE,
978
                               JSGlobalProxy::SizeWithInternalFields(0));
979 980
  } else {
    Handle<ObjectTemplateInfo> data =
981
        v8::Utils::OpenHandle(*global_proxy_template);
982 983
    Handle<FunctionTemplateInfo> global_constructor(
            FunctionTemplateInfo::cast(data->constructor()));
984
    global_proxy_function = ApiNatives::CreateApiFunction(
985 986
        isolate(), global_constructor, factory()->the_hole_value(),
        ApiNatives::GlobalProxyType);
987
  }
988
  Handle<String> global_name = factory()->global_string();
989 990
  global_proxy_function->shared()->set_instance_class_name(*global_name);
  global_proxy_function->initial_map()->set_is_access_check_needed(true);
991
  global_proxy_function->initial_map()->set_has_hidden_prototype(true);
992
  native_context()->set_global_proxy_function(*global_proxy_function);
993 994 995 996

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

997
  factory()->ReinitializeJSGlobalProxy(global_proxy, global_proxy_function);
998

999
  // Set the native context for the global object.
1000 1001
  global_object->set_native_context(*native_context());
  global_object->set_global_proxy(*global_proxy);
1002
  // Set the native context of the global proxy.
1003
  global_proxy->set_native_context(*native_context());
1004 1005 1006
  // Set the global proxy of the native context. If the native context has been
  // deserialized, the global proxy is already correctly set up by the
  // deserializer. Otherwise it's undefined.
1007 1008 1009
  DCHECK(native_context()
             ->get(Context::GLOBAL_PROXY_INDEX)
             ->IsUndefined(isolate()) ||
1010
         native_context()->global_proxy() == *global_proxy);
1011
  native_context()->set_global_proxy(*global_proxy);
1012 1013

  return global_object;
1014 1015
}

1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027
void Genesis::HookUpGlobalProxy(Handle<JSGlobalProxy> global_proxy) {
  // Re-initialize the global proxy with the global proxy function from the
  // snapshot, and then set up the link to the native context.
  Handle<JSFunction> global_proxy_function(
      native_context()->global_proxy_function());
  factory()->ReinitializeJSGlobalProxy(global_proxy, global_proxy_function);
  Handle<JSObject> global_object(
      JSObject::cast(native_context()->global_object()));
  JSObject::ForceSetPrototype(global_proxy, global_object);
  global_proxy->set_native_context(*native_context());
  DCHECK(native_context()->global_proxy() == *global_proxy);
}
1028

1029
void Genesis::HookUpGlobalObject(Handle<JSGlobalObject> global_object) {
1030 1031
  Handle<JSGlobalObject> global_object_from_snapshot(
      JSGlobalObject::cast(native_context()->extension()));
1032 1033
  native_context()->set_extension(*global_object);
  native_context()->set_security_token(*global_object);
1034

1035 1036
  TransferNamedProperties(global_object_from_snapshot, global_object);
  TransferIndexedProperties(global_object_from_snapshot, global_object);
1037 1038
}

1039 1040 1041 1042 1043 1044 1045 1046 1047
static void InstallWithIntrinsicDefaultProto(Isolate* isolate,
                                             Handle<JSFunction> function,
                                             int context_index) {
  Handle<Smi> index(Smi::FromInt(context_index), isolate);
  JSObject::AddProperty(
      function, isolate->factory()->native_context_index_symbol(), index, NONE);
  isolate->native_context()->set(context_index, *function);
}

jgruber's avatar
jgruber committed
1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062
static void InstallError(Isolate* isolate, Handle<JSObject> global,
                         Handle<String> name, int context_index) {
  Factory* factory = isolate->factory();

  Handle<JSFunction> error_fun =
      InstallFunction(global, name, JS_ERROR_TYPE, JSObject::kHeaderSize,
                      isolate->initial_object_prototype(),
                      Builtins::kErrorConstructor, DONT_ENUM);
  error_fun->shared()->set_instance_class_name(*factory->Error_string());
  error_fun->shared()->DontAdaptArguments();
  error_fun->shared()->set_construct_stub(
      *isolate->builtins()->ErrorConstructor());
  error_fun->shared()->set_length(1);

  if (context_index == Context::ERROR_FUNCTION_INDEX) {
1063 1064
    SimpleInstallFunction(error_fun, "captureStackTrace",
                          Builtins::kErrorCaptureStackTrace, 2, false);
jgruber's avatar
jgruber committed
1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078
  }

  InstallWithIntrinsicDefaultProto(isolate, error_fun, context_index);

  {
    Handle<JSObject> prototype =
        factory->NewJSObject(isolate->object_function(), TENURED);

    JSObject::AddProperty(prototype, factory->name_string(), name, DONT_ENUM);
    JSObject::AddProperty(prototype, factory->message_string(),
                          factory->empty_string(), DONT_ENUM);
    JSObject::AddProperty(prototype, factory->constructor_string(), error_fun,
                          DONT_ENUM);

1079 1080 1081 1082 1083 1084 1085 1086 1087 1088
    if (context_index == Context::ERROR_FUNCTION_INDEX) {
      Handle<JSFunction> to_string_fun =
          SimpleInstallFunction(prototype, factory->toString_string(),
                                Builtins::kErrorPrototypeToString, 0, true);
      isolate->native_context()->set_error_to_string(*to_string_fun);
    } else {
      DCHECK(isolate->native_context()->error_to_string()->IsJSFunction());

      InstallFunction(prototype, isolate->error_to_string(),
                      factory->toString_string(), DONT_ENUM);
jgruber's avatar
jgruber committed
1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114

      Handle<JSFunction> global_error = isolate->error_function();
      CHECK(JSReceiver::SetPrototype(error_fun, global_error, false,
                                     Object::THROW_ON_ERROR)
                .FromMaybe(false));
      CHECK(JSReceiver::SetPrototype(prototype,
                                     handle(global_error->prototype(), isolate),
                                     false, Object::THROW_ON_ERROR)
                .FromMaybe(false));
    }

    Accessors::FunctionSetPrototype(error_fun, prototype).Assert();
  }

  Handle<Map> initial_map(error_fun->initial_map());
  Map::EnsureDescriptorSlack(initial_map, 1);

  PropertyAttributes attribs = DONT_ENUM;
  Handle<AccessorInfo> error_stack =
      Accessors::ErrorStackInfo(isolate, attribs);
  {
    AccessorConstantDescriptor d(Handle<Name>(Name::cast(error_stack->name())),
                                 error_stack, attribs);
    initial_map->AppendDescriptor(&d);
  }
}
1115

1116 1117 1118 1119 1120 1121 1122 1123 1124
static void InstallMakeError(Isolate* isolate, Handle<Code> code,
                             int context_index) {
  Handle<JSFunction> function =
      isolate->factory()->NewFunction(isolate->factory()->empty_string(), code,
                                      JS_OBJECT_TYPE, JSObject::kHeaderSize);
  function->shared()->DontAdaptArguments();
  isolate->native_context()->set(context_index, *function);
}

1125
// This is only called if we are not using snapshots.  The equivalent
1126
// work in the snapshot case is done in HookUpGlobalObject.
1127
void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object,
1128
                               Handle<JSFunction> empty_function,
1129
                               GlobalContextType context_type) {
1130
  // --- N a t i v e   C o n t e x t ---
1131
  // Use the empty function as closure (no scope info).
1132 1133
  native_context()->set_closure(*empty_function);
  native_context()->set_previous(NULL);
1134
  // Set extension and global object.
1135 1136 1137 1138 1139 1140 1141
  native_context()->set_extension(*global_object);
  // Security setup: Set the security token of the native context to the global
  // object. This makes the security check between two different contexts fail
  // by default even in case of global object reinitialization.
  native_context()->set_security_token(*global_object);

  Isolate* isolate = global_object->GetIsolate();
1142 1143
  Factory* factory = isolate->factory();

1144 1145
  native_context()->set_osr_code_table(*factory->empty_fixed_array());

1146 1147 1148
  Handle<ScriptContextTable> script_context_table =
      factory->NewScriptContextTable();
  native_context()->set_script_context_table(*script_context_table);
1149
  InstallGlobalThisBinding();
1150

1151 1152 1153 1154 1155
  {  // --- O b j e c t ---
    Handle<String> object_name = factory->Object_string();
    Handle<JSFunction> object_function = isolate->object_function();
    JSObject::AddProperty(global_object, object_name, object_function,
                          DONT_ENUM);
1156

1157 1158
    SimpleInstallFunction(object_function, factory->assign_string(),
                          Builtins::kObjectAssign, 2, false);
1159 1160
    SimpleInstallFunction(object_function, "getOwnPropertyDescriptor",
                          Builtins::kObjectGetOwnPropertyDescriptor, 2, false);
1161 1162 1163
    SimpleInstallFunction(object_function,
                          factory->getOwnPropertyDescriptors_string(),
                          Builtins::kObjectGetOwnPropertyDescriptors, 1, false);
1164 1165
    SimpleInstallFunction(object_function, "getOwnPropertyNames",
                          Builtins::kObjectGetOwnPropertyNames, 1, false);
1166 1167
    SimpleInstallFunction(object_function, "getOwnPropertySymbols",
                          Builtins::kObjectGetOwnPropertySymbols, 1, false);
1168 1169 1170 1171 1172 1173 1174
    SimpleInstallFunction(object_function, "is",
                          Builtins::kObjectIs, 2, true);
    SimpleInstallFunction(object_function, "preventExtensions",
                          Builtins::kObjectPreventExtensions, 1, false);
    SimpleInstallFunction(object_function, "seal",
                          Builtins::kObjectSeal, 1, false);

1175 1176 1177 1178 1179
    Handle<JSFunction> object_create =
        SimpleInstallFunction(object_function, factory->create_string(),
                              Builtins::kObjectCreate, 2, true);
    native_context()->set_object_create(*object_create);

1180 1181 1182 1183 1184 1185 1186 1187 1188 1189
    Handle<JSFunction> object_define_properties = SimpleInstallFunction(
        object_function, "defineProperties",
        Builtins::kObjectDefineProperties, 2, true);
    native_context()->set_object_define_properties(*object_define_properties);

    Handle<JSFunction> object_define_property = SimpleInstallFunction(
        object_function, factory->defineProperty_string(),
        Builtins::kObjectDefineProperty, 3, true);
    native_context()->set_object_define_property(*object_define_property);

1190 1191 1192 1193 1194 1195 1196 1197
    Handle<JSFunction> object_freeze = SimpleInstallFunction(
        object_function, "freeze", Builtins::kObjectFreeze, 1, false);
    native_context()->set_object_freeze(*object_freeze);

    Handle<JSFunction> object_get_prototype_of = SimpleInstallFunction(
        object_function, "getPrototypeOf", Builtins::kObjectGetPrototypeOf,
        1, false);
    native_context()->set_object_get_prototype_of(*object_get_prototype_of);
1198 1199
    SimpleInstallFunction(object_function, "setPrototypeOf",
                          Builtins::kObjectSetPrototypeOf, 2, false);
1200 1201 1202 1203

    Handle<JSFunction> object_is_extensible = SimpleInstallFunction(
        object_function, "isExtensible", Builtins::kObjectIsExtensible,
        1, false);
1204
    native_context()->set_object_is_extensible(*object_is_extensible);
1205

1206 1207 1208
    Handle<JSFunction> object_is_frozen = SimpleInstallFunction(
        object_function, "isFrozen", Builtins::kObjectIsFrozen, 1, false);
    native_context()->set_object_is_frozen(*object_is_frozen);
1209

1210 1211 1212
    Handle<JSFunction> object_is_sealed = SimpleInstallFunction(
        object_function, "isSealed", Builtins::kObjectIsSealed, 1, false);
    native_context()->set_object_is_sealed(*object_is_sealed);
1213

1214 1215 1216
    Handle<JSFunction> object_keys = SimpleInstallFunction(
        object_function, "keys", Builtins::kObjectKeys, 1, false);
    native_context()->set_object_keys(*object_keys);
1217 1218 1219 1220
    SimpleInstallFunction(object_function, factory->entries_string(),
                          Builtins::kObjectEntries, 1, false);
    SimpleInstallFunction(object_function, factory->values_string(),
                          Builtins::kObjectValues, 1, false);
1221

1222 1223 1224 1225 1226 1227
    SimpleInstallFunction(isolate->initial_object_prototype(),
                          "__defineGetter__", Builtins::kObjectDefineGetter, 2,
                          true);
    SimpleInstallFunction(isolate->initial_object_prototype(),
                          "__defineSetter__", Builtins::kObjectDefineSetter, 2,
                          true);
1228
    SimpleInstallFunction(isolate->initial_object_prototype(), "hasOwnProperty",
1229
                          Builtins::kObjectHasOwnProperty, 1, true);
1230 1231 1232 1233 1234 1235
    SimpleInstallFunction(isolate->initial_object_prototype(),
                          "__lookupGetter__", Builtins::kObjectLookupGetter, 1,
                          true);
    SimpleInstallFunction(isolate->initial_object_prototype(),
                          "__lookupSetter__", Builtins::kObjectLookupSetter, 1,
                          true);
1236 1237 1238
    SimpleInstallFunction(
        isolate->initial_object_prototype(), "propertyIsEnumerable",
        Builtins::kObjectPrototypePropertyIsEnumerable, 1, false);
1239 1240 1241 1242 1243

    SimpleInstallGetterSetter(isolate->initial_object_prototype(),
                              factory->proto_string(),
                              Builtins::kObjectPrototypeGetProto,
                              Builtins::kObjectPrototypeSetProto, DONT_ENUM);
1244
  }
1245

1246
  Handle<JSObject> global(native_context()->global_object());
1247

ishell's avatar
ishell committed
1248
  {  // --- F u n c t i o n ---
1249 1250
    Handle<JSFunction> prototype = empty_function;
    Handle<JSFunction> function_fun =
1251
        InstallFunction(global, "Function", JS_FUNCTION_TYPE, JSFunction::kSize,
1252 1253
                        prototype, Builtins::kFunctionConstructor);
    function_fun->set_prototype_or_initial_map(
ishell's avatar
ishell committed
1254
        *sloppy_function_map_writable_prototype_);
1255
    function_fun->shared()->DontAdaptArguments();
1256
    function_fun->shared()->SetConstructStub(
1257
        *isolate->builtins()->FunctionConstructor());
1258 1259
    function_fun->shared()->set_length(1);
    InstallWithIntrinsicDefaultProto(isolate, function_fun,
1260
                                     Context::FUNCTION_FUNCTION_INDEX);
ishell's avatar
ishell committed
1261

1262 1263 1264
    // Setup the methods on the %FunctionPrototype%.
    SimpleInstallFunction(prototype, factory->apply_string(),
                          Builtins::kFunctionPrototypeApply, 2, false);
1265 1266
    SimpleInstallFunction(prototype, factory->bind_string(),
                          Builtins::kFastFunctionPrototypeBind, 1, false);
1267 1268 1269 1270 1271
    SimpleInstallFunction(prototype, factory->call_string(),
                          Builtins::kFunctionPrototypeCall, 1, false);
    SimpleInstallFunction(prototype, factory->toString_string(),
                          Builtins::kFunctionPrototypeToString, 0, false);

1272 1273 1274 1275
    // Install the @@hasInstance function.
    Handle<JSFunction> has_instance = InstallFunction(
        prototype, factory->has_instance_symbol(), JS_OBJECT_TYPE,
        JSObject::kHeaderSize, MaybeHandle<JSObject>(),
1276
        Builtins::kFunctionPrototypeHasInstance,
1277
        static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY));
1278
    has_instance->shared()->set_builtin_function_id(kFunctionHasInstance);
1279
    native_context()->set_function_has_instance(*has_instance);
1280 1281 1282 1283 1284 1285 1286

    // Set the expected parameters for @@hasInstance to 1; required by builtin.
    has_instance->shared()->set_internal_formal_parameter_count(1);

    // Set the length for the function to satisfy ECMA-262.
    has_instance->shared()->set_length(1);

1287 1288 1289 1290 1291 1292
    // Install the "constructor" property on the %FunctionPrototype%.
    JSObject::AddProperty(prototype, factory->constructor_string(),
                          function_fun, DONT_ENUM);

    sloppy_function_map_writable_prototype_->SetConstructor(*function_fun);
    strict_function_map_writable_prototype_->SetConstructor(*function_fun);
1293
    class_function_map_->SetConstructor(*function_fun);
1294
  }
1295 1296

  {  // --- A r r a y ---
1297 1298 1299 1300
    Handle<JSFunction> array_function =
        InstallFunction(global, "Array", JS_ARRAY_TYPE, JSArray::kSize,
                        isolate->initial_object_prototype(),
                        Builtins::kArrayCode);
1301
    array_function->shared()->DontAdaptArguments();
1302
    array_function->shared()->set_builtin_function_id(kArrayCode);
1303 1304 1305 1306

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

1308
    Handle<Map> initial_map(array_function->initial_map());
1309 1310 1311

    // This assert protects an optimization in
    // HGraphBuilder::JSArrayBuilder::EmitMapCode()
1312
    DCHECK(initial_map->elements_kind() == GetInitialFastElementsKind());
1313
    Map::EnsureDescriptorSlack(initial_map, 1);
1314

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

1318 1319
    Handle<AccessorInfo> array_length =
        Accessors::ArrayLengthInfo(isolate, attribs);
1320
    {  // Add length.
1321 1322 1323
      AccessorConstantDescriptor d(
          Handle<Name>(Name::cast(array_length->name())), array_length,
          attribs);
1324
      initial_map->AppendDescriptor(&d);
1325
    }
1326

1327 1328
    InstallWithIntrinsicDefaultProto(isolate, array_function,
                                     Context::ARRAY_FUNCTION_INDEX);
1329

1330 1331 1332
    // Cache the array maps, needed by ArrayConstructorStub
    CacheInitialJSArrayMaps(native_context(), initial_map);
    ArrayConstructorStub array_constructor_stub(isolate);
1333
    Handle<Code> code = array_constructor_stub.GetCode();
1334
    array_function->shared()->SetConstructStub(*code);
1335

1336 1337 1338 1339
    Handle<JSFunction> is_arraylike = SimpleInstallFunction(
        array_function, isolate->factory()->InternalizeUtf8String("isArray"),
        Builtins::kArrayIsArray, 1, true);
    native_context()->set_is_arraylike(*is_arraylike);
1340 1341
  }

1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357
  {  // --- A r r a y I t e r a t o r ---
    Handle<JSObject> iterator_prototype(
        native_context()->initial_iterator_prototype());

    Handle<JSObject> array_iterator_prototype =
        factory->NewJSObject(isolate->object_function(), TENURED);
    JSObject::ForceSetPrototype(array_iterator_prototype, iterator_prototype);

    JSObject::AddProperty(
        array_iterator_prototype, factory->to_string_tag_symbol(),
        factory->ArrayIterator_string(),
        static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY));

    Handle<JSFunction> next = InstallFunction(
        array_iterator_prototype, "next", JS_OBJECT_TYPE, JSObject::kHeaderSize,
        MaybeHandle<JSObject>(), Builtins::kArrayIteratorPrototypeNext);
1358
    next->shared()->set_builtin_function_id(kArrayIteratorNext);
1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373

    // Set the expected parameters for %ArrayIteratorPrototype%.next to 0 (not
    // including the receiver), as required by the builtin.
    next->shared()->set_internal_formal_parameter_count(0);

    // Set the length for the function to satisfy ECMA-262.
    next->shared()->set_length(0);

    Handle<JSFunction> array_iterator_function = CreateFunction(
        isolate, factory->ArrayIterator_string(),
        JS_FAST_ARRAY_VALUE_ITERATOR_TYPE, JSArrayIterator::kSize,
        array_iterator_prototype, Builtins::kIllegal);
    array_iterator_function->shared()->set_instance_class_name(
        isolate->heap()->ArrayIterator_string());

1374 1375 1376 1377 1378
    native_context()->set_initial_array_iterator_prototype(
        *array_iterator_prototype);
    native_context()->set_initial_array_iterator_prototype_map(
        array_iterator_prototype->map());

1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432
    Handle<Map> initial_map(array_iterator_function->initial_map(), isolate);

#define ARRAY_ITERATOR_LIST(V)                                              \
  V(TYPED_ARRAY, KEY, typed_array, key)                                     \
  V(FAST_ARRAY, KEY, fast_array, key)                                       \
  V(GENERIC_ARRAY, KEY, array, key)                                         \
  V(UINT8_ARRAY, KEY_VALUE, uint8_array, key_value)                         \
  V(INT8_ARRAY, KEY_VALUE, int8_array, key_value)                           \
  V(UINT16_ARRAY, KEY_VALUE, uint16_array, key_value)                       \
  V(INT16_ARRAY, KEY_VALUE, int16_array, key_value)                         \
  V(UINT32_ARRAY, KEY_VALUE, uint32_array, key_value)                       \
  V(INT32_ARRAY, KEY_VALUE, int32_array, key_value)                         \
  V(FLOAT32_ARRAY, KEY_VALUE, float32_array, key_value)                     \
  V(FLOAT64_ARRAY, KEY_VALUE, float64_array, key_value)                     \
  V(UINT8_CLAMPED_ARRAY, KEY_VALUE, uint8_clamped_array, key_value)         \
  V(FAST_SMI_ARRAY, KEY_VALUE, fast_smi_array, key_value)                   \
  V(FAST_HOLEY_SMI_ARRAY, KEY_VALUE, fast_holey_smi_array, key_value)       \
  V(FAST_ARRAY, KEY_VALUE, fast_array, key_value)                           \
  V(FAST_HOLEY_ARRAY, KEY_VALUE, fast_holey_array, key_value)               \
  V(FAST_DOUBLE_ARRAY, KEY_VALUE, fast_double_array, key_value)             \
  V(FAST_HOLEY_DOUBLE_ARRAY, KEY_VALUE, fast_holey_double_array, key_value) \
  V(GENERIC_ARRAY, KEY_VALUE, array, key_value)                             \
  V(UINT8_ARRAY, VALUE, uint8_array, value)                                 \
  V(INT8_ARRAY, VALUE, int8_array, value)                                   \
  V(UINT16_ARRAY, VALUE, uint16_array, value)                               \
  V(INT16_ARRAY, VALUE, int16_array, value)                                 \
  V(UINT32_ARRAY, VALUE, uint32_array, value)                               \
  V(INT32_ARRAY, VALUE, int32_array, value)                                 \
  V(FLOAT32_ARRAY, VALUE, float32_array, value)                             \
  V(FLOAT64_ARRAY, VALUE, float64_array, value)                             \
  V(UINT8_CLAMPED_ARRAY, VALUE, uint8_clamped_array, value)                 \
  V(FAST_SMI_ARRAY, VALUE, fast_smi_array, value)                           \
  V(FAST_HOLEY_SMI_ARRAY, VALUE, fast_holey_smi_array, value)               \
  V(FAST_ARRAY, VALUE, fast_array, value)                                   \
  V(FAST_HOLEY_ARRAY, VALUE, fast_holey_array, value)                       \
  V(FAST_DOUBLE_ARRAY, VALUE, fast_double_array, value)                     \
  V(FAST_HOLEY_DOUBLE_ARRAY, VALUE, fast_holey_double_array, value)         \
  V(GENERIC_ARRAY, VALUE, array, value)

#define CREATE_ARRAY_ITERATOR_MAP(PREFIX, SUFFIX, prefix, suffix)           \
  do {                                                                      \
    const InstanceType type = JS_##PREFIX##_##SUFFIX##_ITERATOR_TYPE;       \
    Handle<Map> map =                                                       \
        Map::Copy(initial_map, "JS_" #PREFIX "_" #SUFFIX "_ITERATOR_TYPE"); \
    map->set_instance_type(type);                                           \
    native_context()->set_##prefix##_##suffix##_iterator_map(*map);         \
  } while (0);

    ARRAY_ITERATOR_LIST(CREATE_ARRAY_ITERATOR_MAP)

#undef CREATE_ARRAY_ITERATOR_MAP
#undef ARRAY_ITERATOR_LIST
  }

1433
  {  // --- N u m b e r ---
1434 1435 1436 1437
    Handle<JSFunction> number_fun = InstallFunction(
        global, "Number", JS_VALUE_TYPE, JSValue::kSize,
        isolate->initial_object_prototype(), Builtins::kNumberConstructor);
    number_fun->shared()->DontAdaptArguments();
1438
    number_fun->shared()->SetConstructStub(
1439 1440
        *isolate->builtins()->NumberConstructor_ConstructStub());
    number_fun->shared()->set_length(1);
1441 1442
    InstallWithIntrinsicDefaultProto(isolate, number_fun,
                                     Context::NUMBER_FUNCTION_INDEX);
1443 1444 1445 1446

    // Create the %NumberPrototype%
    Handle<JSValue> prototype =
        Handle<JSValue>::cast(factory->NewJSObject(number_fun, TENURED));
1447
    prototype->set_value(Smi::kZero);
1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468
    Accessors::FunctionSetPrototype(number_fun, prototype).Assert();

    // Install the "constructor" property on the {prototype}.
    JSObject::AddProperty(prototype, factory->constructor_string(), number_fun,
                          DONT_ENUM);

    // Install the Number.prototype methods.
    SimpleInstallFunction(prototype, "toExponential",
                          Builtins::kNumberPrototypeToExponential, 1, false);
    SimpleInstallFunction(prototype, "toFixed",
                          Builtins::kNumberPrototypeToFixed, 1, false);
    SimpleInstallFunction(prototype, "toPrecision",
                          Builtins::kNumberPrototypeToPrecision, 1, false);
    SimpleInstallFunction(prototype, "toString",
                          Builtins::kNumberPrototypeToString, 1, false);
    SimpleInstallFunction(prototype, "valueOf",
                          Builtins::kNumberPrototypeValueOf, 0, true);

    // Install i18n fallback functions.
    SimpleInstallFunction(prototype, "toLocaleString",
                          Builtins::kNumberPrototypeToLocaleString, 0, false);
1469 1470 1471 1472 1473 1474 1475 1476 1477

    // Install the Number functions.
    SimpleInstallFunction(number_fun, "isFinite", Builtins::kNumberIsFinite, 1,
                          true);
    SimpleInstallFunction(number_fun, "isInteger", Builtins::kNumberIsInteger,
                          1, true);
    SimpleInstallFunction(number_fun, "isNaN", Builtins::kNumberIsNaN, 1, true);
    SimpleInstallFunction(number_fun, "isSafeInteger",
                          Builtins::kNumberIsSafeInteger, 1, true);
1478 1479 1480 1481 1482 1483 1484

    // Install Number.parseFloat and Global.parseFloat.
    Handle<JSFunction> parse_float_fun = SimpleInstallFunction(
        number_fun, "parseFloat", Builtins::kNumberParseFloat, 1, true);
    JSObject::AddProperty(global_object,
                          factory->NewStringFromAsciiChecked("parseFloat"),
                          parse_float_fun, DONT_ENUM);
1485 1486 1487 1488 1489 1490 1491

    // Install Number.parseInt and Global.parseInt.
    Handle<JSFunction> parse_int_fun = SimpleInstallFunction(
        number_fun, "parseInt", Builtins::kNumberParseInt, 2, true);
    JSObject::AddProperty(global_object,
                          factory->NewStringFromAsciiChecked("parseInt"),
                          parse_int_fun, DONT_ENUM);
1492 1493 1494
  }

  {  // --- B o o l e a n ---
1495 1496 1497
    Handle<JSFunction> boolean_fun =
        InstallFunction(global, "Boolean", JS_VALUE_TYPE, JSValue::kSize,
                        isolate->initial_object_prototype(),
1498 1499
                        Builtins::kBooleanConstructor);
    boolean_fun->shared()->DontAdaptArguments();
1500
    boolean_fun->shared()->SetConstructStub(
1501 1502
        *isolate->builtins()->BooleanConstructor_ConstructStub());
    boolean_fun->shared()->set_length(1);
1503 1504
    InstallWithIntrinsicDefaultProto(isolate, boolean_fun,
                                     Context::BOOLEAN_FUNCTION_INDEX);
1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517

    // Create the %BooleanPrototype%
    Handle<JSValue> prototype =
        Handle<JSValue>::cast(factory->NewJSObject(boolean_fun, TENURED));
    prototype->set_value(isolate->heap()->false_value());
    Accessors::FunctionSetPrototype(boolean_fun, prototype).Assert();

    // Install the "constructor" property on the {prototype}.
    JSObject::AddProperty(prototype, factory->constructor_string(), boolean_fun,
                          DONT_ENUM);

    // Install the Boolean.prototype methods.
    SimpleInstallFunction(prototype, "toString",
1518
                          Builtins::kBooleanPrototypeToString, 0, true);
1519
    SimpleInstallFunction(prototype, "valueOf",
1520
                          Builtins::kBooleanPrototypeValueOf, 0, true);
1521 1522 1523
  }

  {  // --- S t r i n g ---
1524 1525 1526
    Handle<JSFunction> string_fun = InstallFunction(
        global, "String", JS_VALUE_TYPE, JSValue::kSize,
        isolate->initial_object_prototype(), Builtins::kStringConstructor);
1527
    string_fun->shared()->SetConstructStub(
1528
        *isolate->builtins()->StringConstructor_ConstructStub());
1529 1530
    string_fun->shared()->DontAdaptArguments();
    string_fun->shared()->set_length(1);
1531 1532
    InstallWithIntrinsicDefaultProto(isolate, string_fun,
                                     Context::STRING_FUNCTION_INDEX);
1533

1534
    Handle<Map> string_map =
1535
        Handle<Map>(native_context()->string_function()->initial_map());
1536
    string_map->set_elements_kind(FAST_STRING_WRAPPER_ELEMENTS);
1537
    Map::EnsureDescriptorSlack(string_map, 1);
1538

1539 1540
    PropertyAttributes attribs = static_cast<PropertyAttributes>(
        DONT_ENUM | DONT_DELETE | READ_ONLY);
1541 1542
    Handle<AccessorInfo> string_length(
        Accessors::StringLengthInfo(isolate, attribs));
1543 1544

    {  // Add length.
1545 1546
      AccessorConstantDescriptor d(factory->length_string(), string_length,
                                   attribs);
1547
      string_map->AppendDescriptor(&d);
1548
    }
1549

1550 1551
    // Install the String.fromCharCode function.
    SimpleInstallFunction(string_fun, "fromCharCode",
1552
                          Builtins::kStringFromCharCode, 1, false);
1553

1554 1555 1556 1557
    // Install the String.fromCodePoint function.
    SimpleInstallFunction(string_fun, "fromCodePoint",
                          Builtins::kStringFromCodePoint, 1, false);

1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572
    // Create the %StringPrototype%
    Handle<JSValue> prototype =
        Handle<JSValue>::cast(factory->NewJSObject(string_fun, TENURED));
    prototype->set_value(isolate->heap()->empty_string());
    Accessors::FunctionSetPrototype(string_fun, prototype).Assert();

    // Install the "constructor" property on the {prototype}.
    JSObject::AddProperty(prototype, factory->constructor_string(), string_fun,
                          DONT_ENUM);

    // Install the String.prototype methods.
    SimpleInstallFunction(prototype, "charAt", Builtins::kStringPrototypeCharAt,
                          1, true);
    SimpleInstallFunction(prototype, "charCodeAt",
                          Builtins::kStringPrototypeCharCodeAt, 1, true);
1573 1574
    SimpleInstallFunction(prototype, "endsWith",
                          Builtins::kStringPrototypeEndsWith, 1, false);
1575 1576
    SimpleInstallFunction(prototype, "includes",
                          Builtins::kStringPrototypeIncludes, 1, false);
1577 1578
    SimpleInstallFunction(prototype, "indexOf",
                          Builtins::kStringPrototypeIndexOf, 1, false);
1579 1580
    SimpleInstallFunction(prototype, "lastIndexOf",
                          Builtins::kStringPrototypeLastIndexOf, 1, false);
1581 1582
    SimpleInstallFunction(prototype, "localeCompare",
                          Builtins::kStringPrototypeLocaleCompare, 1, true);
1583 1584
    SimpleInstallFunction(prototype, "normalize",
                          Builtins::kStringPrototypeNormalize, 0, false);
1585 1586
    SimpleInstallFunction(prototype, "substr", Builtins::kStringPrototypeSubstr,
                          2, true);
1587 1588
    SimpleInstallFunction(prototype, "substring",
                          Builtins::kStringPrototypeSubstring, 2, true);
1589 1590
    SimpleInstallFunction(prototype, "startsWith",
                          Builtins::kStringPrototypeStartsWith, 1, false);
1591 1592
    SimpleInstallFunction(prototype, "toString",
                          Builtins::kStringPrototypeToString, 0, true);
1593 1594 1595 1596 1597 1598
    SimpleInstallFunction(prototype, "trim", Builtins::kStringPrototypeTrim, 0,
                          false);
    SimpleInstallFunction(prototype, "trimLeft",
                          Builtins::kStringPrototypeTrimLeft, 0, false);
    SimpleInstallFunction(prototype, "trimRight",
                          Builtins::kStringPrototypeTrimRight, 0, false);
1599 1600
    SimpleInstallFunction(prototype, "valueOf",
                          Builtins::kStringPrototypeValueOf, 0, true);
1601 1602 1603 1604 1605

    Handle<JSFunction> iterator = SimpleCreateFunction(
        isolate, factory->NewStringFromAsciiChecked("[Symbol.iterator]"),
        Builtins::kStringPrototypeIterator, 0, true);
    iterator->shared()->set_native(true);
1606
    iterator->shared()->set_builtin_function_id(kStringIterator);
1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623
    JSObject::AddProperty(prototype, factory->iterator_symbol(), iterator,
                          static_cast<PropertyAttributes>(DONT_ENUM));
  }

  {  // --- S t r i n g I t e r a t o r ---
    Handle<JSObject> iterator_prototype(
        native_context()->initial_iterator_prototype());

    Handle<JSObject> string_iterator_prototype =
        factory->NewJSObject(isolate->object_function(), TENURED);
    JSObject::ForceSetPrototype(string_iterator_prototype, iterator_prototype);

    JSObject::AddProperty(
        string_iterator_prototype, factory->to_string_tag_symbol(),
        factory->NewStringFromAsciiChecked("String Iterator"),
        static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY));

1624 1625 1626 1627
    Handle<JSFunction> next =
        InstallFunction(string_iterator_prototype, "next", JS_OBJECT_TYPE,
                        JSObject::kHeaderSize, MaybeHandle<JSObject>(),
                        Builtins::kStringIteratorPrototypeNext);
1628
    next->shared()->set_builtin_function_id(kStringIteratorNext);
1629 1630 1631 1632 1633 1634 1635

    // Set the expected parameters for %StringIteratorPrototype%.next to 0 (not
    // including the receiver), as required by the builtin.
    next->shared()->set_internal_formal_parameter_count(0);

    // Set the length for the function to satisfy ECMA-262.
    next->shared()->set_length(0);
1636 1637 1638 1639 1640 1641 1642

    Handle<JSFunction> string_iterator_function = CreateFunction(
        isolate, factory->NewStringFromAsciiChecked("StringIterator"),
        JS_STRING_ITERATOR_TYPE, JSStringIterator::kSize,
        string_iterator_prototype, Builtins::kIllegal);
    native_context()->set_string_iterator_map(
        string_iterator_function->initial_map());
1643 1644
  }

1645 1646
  {
    // --- S y m b o l ---
1647 1648 1649 1650 1651
    Handle<JSObject> prototype =
        factory->NewJSObject(isolate->object_function(), TENURED);
    Handle<JSFunction> symbol_fun =
        InstallFunction(global, "Symbol", JS_VALUE_TYPE, JSValue::kSize,
                        prototype, Builtins::kSymbolConstructor);
1652
    symbol_fun->shared()->SetConstructStub(
1653
        *isolate->builtins()->SymbolConstructor_ConstructStub());
1654
    symbol_fun->shared()->set_length(0);
1655
    symbol_fun->shared()->DontAdaptArguments();
1656
    native_context()->set_symbol_function(*symbol_fun);
1657

1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681
    // Install the Symbol.for and Symbol.keyFor functions.
    SimpleInstallFunction(symbol_fun, "for", Builtins::kSymbolFor, 1, false);
    SimpleInstallFunction(symbol_fun, "keyFor", Builtins::kSymbolKeyFor, 1,
                          false);

    // Install well-known symbols.
    InstallConstant(isolate, symbol_fun, "hasInstance",
                    factory->has_instance_symbol());
    InstallConstant(isolate, symbol_fun, "isConcatSpreadable",
                    factory->is_concat_spreadable_symbol());
    InstallConstant(isolate, symbol_fun, "iterator",
                    factory->iterator_symbol());
    InstallConstant(isolate, symbol_fun, "match", factory->match_symbol());
    InstallConstant(isolate, symbol_fun, "replace", factory->replace_symbol());
    InstallConstant(isolate, symbol_fun, "search", factory->search_symbol());
    InstallConstant(isolate, symbol_fun, "species", factory->species_symbol());
    InstallConstant(isolate, symbol_fun, "split", factory->split_symbol());
    InstallConstant(isolate, symbol_fun, "toPrimitive",
                    factory->to_primitive_symbol());
    InstallConstant(isolate, symbol_fun, "toStringTag",
                    factory->to_string_tag_symbol());
    InstallConstant(isolate, symbol_fun, "unscopables",
                    factory->unscopables_symbol());

1682 1683 1684 1685 1686 1687
    // Install the @@toStringTag property on the {prototype}.
    JSObject::AddProperty(
        prototype, factory->to_string_tag_symbol(),
        factory->NewStringFromAsciiChecked("Symbol"),
        static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY));

1688 1689 1690
    // Install the "constructor" property on the {prototype}.
    JSObject::AddProperty(prototype, factory->constructor_string(), symbol_fun,
                          DONT_ENUM);
1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709

    // Install the Symbol.prototype methods.
    SimpleInstallFunction(prototype, "toString",
                          Builtins::kSymbolPrototypeToString, 0, true);
    SimpleInstallFunction(prototype, "valueOf",
                          Builtins::kSymbolPrototypeValueOf, 0, true);

    // Install the @@toPrimitive function.
    Handle<JSFunction> to_primitive = InstallFunction(
        prototype, factory->to_primitive_symbol(), JS_OBJECT_TYPE,
        JSObject::kHeaderSize, MaybeHandle<JSObject>(),
        Builtins::kSymbolPrototypeToPrimitive,
        static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY));

    // Set the expected parameters for @@toPrimitive to 1; required by builtin.
    to_primitive->shared()->set_internal_formal_parameter_count(1);

    // Set the length for the function to satisfy ECMA-262.
    to_primitive->shared()->set_length(1);
1710 1711
  }

1712 1713
  {  // --- D a t e ---
    // Builtin functions for Date.prototype.
1714 1715 1716 1717 1718
    Handle<JSObject> prototype =
        factory->NewJSObject(isolate->object_function(), TENURED);
    Handle<JSFunction> date_fun =
        InstallFunction(global, "Date", JS_DATE_TYPE, JSDate::kSize, prototype,
                        Builtins::kDateConstructor);
1719 1720
    InstallWithIntrinsicDefaultProto(isolate, date_fun,
                                     Context::DATE_FUNCTION_INDEX);
1721
    date_fun->shared()->SetConstructStub(
1722 1723 1724
        *isolate->builtins()->DateConstructor_ConstructStub());
    date_fun->shared()->set_length(7);
    date_fun->shared()->DontAdaptArguments();
1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743

    // Install the Date.now, Date.parse and Date.UTC functions.
    SimpleInstallFunction(date_fun, "now", Builtins::kDateNow, 0, false);
    SimpleInstallFunction(date_fun, "parse", Builtins::kDateParse, 1, false);
    SimpleInstallFunction(date_fun, "UTC", Builtins::kDateUTC, 7, false);

    // Install the "constructor" property on the {prototype}.
    JSObject::AddProperty(prototype, factory->constructor_string(), date_fun,
                          DONT_ENUM);

    // Install the Date.prototype methods.
    SimpleInstallFunction(prototype, "toString",
                          Builtins::kDatePrototypeToString, 0, false);
    SimpleInstallFunction(prototype, "toDateString",
                          Builtins::kDatePrototypeToDateString, 0, false);
    SimpleInstallFunction(prototype, "toTimeString",
                          Builtins::kDatePrototypeToTimeString, 0, false);
    SimpleInstallFunction(prototype, "toISOString",
                          Builtins::kDatePrototypeToISOString, 0, false);
1744 1745 1746 1747 1748
    Handle<JSFunction> to_utc_string =
        SimpleInstallFunction(prototype, "toUTCString",
                              Builtins::kDatePrototypeToUTCString, 0, false);
    InstallFunction(prototype, to_utc_string,
                    factory->InternalizeUtf8String("toGMTString"), DONT_ENUM);
1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820
    SimpleInstallFunction(prototype, "getDate", Builtins::kDatePrototypeGetDate,
                          0, true);
    SimpleInstallFunction(prototype, "setDate", Builtins::kDatePrototypeSetDate,
                          1, false);
    SimpleInstallFunction(prototype, "getDay", Builtins::kDatePrototypeGetDay,
                          0, true);
    SimpleInstallFunction(prototype, "getFullYear",
                          Builtins::kDatePrototypeGetFullYear, 0, true);
    SimpleInstallFunction(prototype, "setFullYear",
                          Builtins::kDatePrototypeSetFullYear, 3, false);
    SimpleInstallFunction(prototype, "getHours",
                          Builtins::kDatePrototypeGetHours, 0, true);
    SimpleInstallFunction(prototype, "setHours",
                          Builtins::kDatePrototypeSetHours, 4, false);
    SimpleInstallFunction(prototype, "getMilliseconds",
                          Builtins::kDatePrototypeGetMilliseconds, 0, true);
    SimpleInstallFunction(prototype, "setMilliseconds",
                          Builtins::kDatePrototypeSetMilliseconds, 1, false);
    SimpleInstallFunction(prototype, "getMinutes",
                          Builtins::kDatePrototypeGetMinutes, 0, true);
    SimpleInstallFunction(prototype, "setMinutes",
                          Builtins::kDatePrototypeSetMinutes, 3, false);
    SimpleInstallFunction(prototype, "getMonth",
                          Builtins::kDatePrototypeGetMonth, 0, true);
    SimpleInstallFunction(prototype, "setMonth",
                          Builtins::kDatePrototypeSetMonth, 2, false);
    SimpleInstallFunction(prototype, "getSeconds",
                          Builtins::kDatePrototypeGetSeconds, 0, true);
    SimpleInstallFunction(prototype, "setSeconds",
                          Builtins::kDatePrototypeSetSeconds, 2, false);
    SimpleInstallFunction(prototype, "getTime", Builtins::kDatePrototypeGetTime,
                          0, true);
    SimpleInstallFunction(prototype, "setTime", Builtins::kDatePrototypeSetTime,
                          1, false);
    SimpleInstallFunction(prototype, "getTimezoneOffset",
                          Builtins::kDatePrototypeGetTimezoneOffset, 0, true);
    SimpleInstallFunction(prototype, "getUTCDate",
                          Builtins::kDatePrototypeGetUTCDate, 0, true);
    SimpleInstallFunction(prototype, "setUTCDate",
                          Builtins::kDatePrototypeSetUTCDate, 1, false);
    SimpleInstallFunction(prototype, "getUTCDay",
                          Builtins::kDatePrototypeGetUTCDay, 0, true);
    SimpleInstallFunction(prototype, "getUTCFullYear",
                          Builtins::kDatePrototypeGetUTCFullYear, 0, true);
    SimpleInstallFunction(prototype, "setUTCFullYear",
                          Builtins::kDatePrototypeSetUTCFullYear, 3, false);
    SimpleInstallFunction(prototype, "getUTCHours",
                          Builtins::kDatePrototypeGetUTCHours, 0, true);
    SimpleInstallFunction(prototype, "setUTCHours",
                          Builtins::kDatePrototypeSetUTCHours, 4, false);
    SimpleInstallFunction(prototype, "getUTCMilliseconds",
                          Builtins::kDatePrototypeGetUTCMilliseconds, 0, true);
    SimpleInstallFunction(prototype, "setUTCMilliseconds",
                          Builtins::kDatePrototypeSetUTCMilliseconds, 1, false);
    SimpleInstallFunction(prototype, "getUTCMinutes",
                          Builtins::kDatePrototypeGetUTCMinutes, 0, true);
    SimpleInstallFunction(prototype, "setUTCMinutes",
                          Builtins::kDatePrototypeSetUTCMinutes, 3, false);
    SimpleInstallFunction(prototype, "getUTCMonth",
                          Builtins::kDatePrototypeGetUTCMonth, 0, true);
    SimpleInstallFunction(prototype, "setUTCMonth",
                          Builtins::kDatePrototypeSetUTCMonth, 2, false);
    SimpleInstallFunction(prototype, "getUTCSeconds",
                          Builtins::kDatePrototypeGetUTCSeconds, 0, true);
    SimpleInstallFunction(prototype, "setUTCSeconds",
                          Builtins::kDatePrototypeSetUTCSeconds, 2, false);
    SimpleInstallFunction(prototype, "valueOf", Builtins::kDatePrototypeValueOf,
                          0, false);
    SimpleInstallFunction(prototype, "getYear", Builtins::kDatePrototypeGetYear,
                          0, true);
    SimpleInstallFunction(prototype, "setYear", Builtins::kDatePrototypeSetYear,
                          1, false);
1821 1822
    SimpleInstallFunction(prototype, "toJSON", Builtins::kDatePrototypeToJson,
                          1, false);
1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843

    // Install i18n fallback functions.
    SimpleInstallFunction(prototype, "toLocaleString",
                          Builtins::kDatePrototypeToString, 0, false);
    SimpleInstallFunction(prototype, "toLocaleDateString",
                          Builtins::kDatePrototypeToDateString, 0, false);
    SimpleInstallFunction(prototype, "toLocaleTimeString",
                          Builtins::kDatePrototypeToTimeString, 0, false);

    // Install the @@toPrimitive function.
    Handle<JSFunction> to_primitive = InstallFunction(
        prototype, factory->to_primitive_symbol(), JS_OBJECT_TYPE,
        JSObject::kHeaderSize, MaybeHandle<JSObject>(),
        Builtins::kDatePrototypeToPrimitive,
        static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY));

    // Set the expected parameters for @@toPrimitive to 1; required by builtin.
    to_primitive->shared()->set_internal_formal_parameter_count(1);

    // Set the length for the function to satisfy ECMA-262.
    to_primitive->shared()->set_length(1);
1844 1845
  }

1846 1847 1848 1849 1850 1851 1852
  {  // -- P r o m i s e
    // Set catch prediction
    Handle<Code> promise_code = isolate->builtins()->PromiseConstructor();
    promise_code->set_is_promise_rejection(true);

    Handle<JSObject> prototype =
        factory->NewJSObject(isolate->object_function(), TENURED);
1853 1854 1855
    Handle<JSFunction> promise_fun =
        InstallFunction(global, "Promise", JS_PROMISE_TYPE, JSPromise::kSize,
                        prototype, Builtins::kPromiseConstructor);
1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873
    InstallWithIntrinsicDefaultProto(isolate, promise_fun,
                                     Context::PROMISE_FUNCTION_INDEX);

    Handle<SharedFunctionInfo> shared(promise_fun->shared(), isolate);
    shared->SetConstructStub(*isolate->builtins()->JSBuiltinsConstructStub());
    shared->set_instance_class_name(isolate->heap()->Object_string());
    shared->set_internal_formal_parameter_count(1);
    shared->set_length(1);

    // Install the "constructor" property on the {prototype}.
    JSObject::AddProperty(prototype, factory->constructor_string(), promise_fun,
                          DONT_ENUM);

    // Install the @@toStringTag property on the {prototype}.
    JSObject::AddProperty(
        prototype, factory->to_string_tag_symbol(), factory->Promise_string(),
        static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY));

1874 1875 1876 1877 1878 1879 1880 1881 1882 1883
    Handle<JSFunction> promise_then =
        SimpleCreateFunction(isolate, isolate->factory()->then_string(),
                             Builtins::kPromiseThen, 2, true);
    JSObject::AddProperty(prototype, isolate->factory()->then_string(),
                          promise_then, DONT_ENUM);
    InstallWithIntrinsicDefaultProto(isolate, promise_then,
                                     Context::PROMISE_THEN_INDEX);

    // TODO(gsathya): Move to TF
    SimpleInstallFunction(prototype, "catch", Builtins::kIllegal, 1, true,
1884 1885
                          DONT_ENUM);

1886 1887 1888 1889 1890 1891 1892
    Handle<Map> prototype_map(prototype->map());
    Map::SetShouldBeFastPrototypeMap(prototype_map, true, isolate);

    // Store the initial Promise.prototype map. This is used in fast-path
    // checks. Do not alter the prototype after this point.
    native_context()->set_promise_prototype_map(*prototype_map);

1893 1894 1895
    {  // Internal: PromiseInternalConstructor
      Handle<JSFunction> function =
          SimpleCreateFunction(isolate, factory->empty_string(),
1896
                               Builtins::kPromiseInternalConstructor, 1, false);
1897 1898 1899 1900
      InstallWithIntrinsicDefaultProto(
          isolate, function, Context::PROMISE_INTERNAL_CONSTRUCTOR_INDEX);
    }

1901 1902 1903 1904 1905 1906 1907 1908
    {  // Internal: PromiseCreateAndSet
      Handle<JSFunction> function =
          SimpleCreateFunction(isolate, factory->empty_string(),
                               Builtins::kPromiseCreateAndSet, 2, false);
      InstallWithIntrinsicDefaultProto(isolate, function,
                                       Context::PROMISE_CREATE_AND_SET_INDEX);
    }

1909 1910 1911 1912 1913 1914 1915
    {  // Internal: IsPromise
      Handle<JSFunction> function = SimpleCreateFunction(
          isolate, factory->empty_string(), Builtins::kIsPromise, 1, false);
      InstallWithIntrinsicDefaultProto(isolate, function,
                                       Context::IS_PROMISE_INDEX);
    }

1916 1917 1918 1919 1920 1921 1922 1923
    {  // Internal: PerformPromiseThen
      Handle<JSFunction> function =
          SimpleCreateFunction(isolate, factory->empty_string(),
                               Builtins::kPerformPromiseThen, 4, false);
      InstallWithIntrinsicDefaultProto(isolate, function,
                                       Context::PERFORM_PROMISE_THEN_INDEX);
    }

1924 1925 1926 1927 1928 1929 1930 1931
    {  // Internal: ResolvePromise
      Handle<JSFunction> function =
          SimpleCreateFunction(isolate, factory->empty_string(),
                               Builtins::kResolvePromise, 2, false);
      InstallWithIntrinsicDefaultProto(isolate, function,
                                       Context::PROMISE_RESOLVE_INDEX);
    }

gsathya's avatar
gsathya committed
1932 1933
    {  // Internal: PromiseHandle
      Handle<JSFunction> function = SimpleCreateFunction(
1934
          isolate, factory->empty_string(), Builtins::kPromiseHandle, 4, true);
gsathya's avatar
gsathya committed
1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952
      InstallWithIntrinsicDefaultProto(isolate, function,
                                       Context::PROMISE_HANDLE_INDEX);
      // Set up catch prediction
      Handle<Code> promise_handle = isolate->builtins()->PromiseHandle();
      promise_handle->set_is_promise_rejection(true);
    }

    {  // Internal: PromiseHandleReject
      Handle<JSFunction> function =
          SimpleCreateFunction(isolate, factory->empty_string(),
                               Builtins::kPromiseHandleReject, 3, false);
      InstallWithIntrinsicDefaultProto(isolate, function,
                                       Context::PROMISE_HANDLE_REJECT_INDEX);
      // Set up catch prediction
      Handle<Code> promise_handle = isolate->builtins()->PromiseHandleReject();
      promise_handle->set_is_exception_caught(true);
    }

1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979
    {
      Handle<Code> code =
          handle(isolate->builtins()->builtin(Builtins::kPromiseResolveClosure),
                 isolate);
      Handle<SharedFunctionInfo> info =
          factory->NewSharedFunctionInfo(factory->empty_string(), code, false);
      info->set_internal_formal_parameter_count(1);
      info->set_length(1);
      native_context()->set_promise_resolve_shared_fun(*info);

      code =
          handle(isolate->builtins()->builtin(Builtins::kPromiseRejectClosure),
                 isolate);
      info =
          factory->NewSharedFunctionInfo(factory->empty_string(), code, false);
      info->set_internal_formal_parameter_count(2);
      info->set_length(1);
      native_context()->set_promise_reject_shared_fun(*info);
    }

    Handle<JSFunction> create_resolving_functions =
        SimpleCreateFunction(isolate, factory->empty_string(),
                             Builtins::kCreateResolvingFunctions, 2, false);
    native_context()->set_create_resolving_functions(
        *create_resolving_functions);
  }

1980 1981
  {  // -- R e g E x p
    // Builtin functions for RegExp.prototype.
1982 1983 1984 1985
    Handle<JSObject> prototype =
        factory->NewJSObject(isolate->object_function(), TENURED);
    Handle<JSFunction> regexp_fun =
        InstallFunction(global, "RegExp", JS_REGEXP_TYPE, JSRegExp::kSize,
1986
                        prototype, Builtins::kRegExpConstructor);
1987 1988
    InstallWithIntrinsicDefaultProto(isolate, regexp_fun,
                                     Context::REGEXP_FUNCTION_INDEX);
1989 1990

    Handle<SharedFunctionInfo> shared(regexp_fun->shared(), isolate);
1991
    shared->SetConstructStub(*isolate->builtins()->JSBuiltinsConstructStub());
1992
    shared->set_instance_class_name(isolate->heap()->RegExp_string());
1993
    shared->set_internal_formal_parameter_count(2);
1994
    shared->set_length(2);
1995

1996 1997 1998 1999 2000 2001 2002
    {
      // RegExp.prototype setup.

      // Install the "constructor" property on the {prototype}.
      JSObject::AddProperty(prototype, factory->constructor_string(),
                            regexp_fun, DONT_ENUM);

2003 2004
      {
        Handle<JSFunction> fun = SimpleInstallFunction(
2005 2006
            prototype, factory->exec_string(), Builtins::kRegExpPrototypeExec,
            1, true, DONT_ENUM);
2007 2008
        native_context()->set_regexp_exec_function(*fun);
      }
2009 2010 2011 2012 2013 2014 2015 2016 2017 2018

      SimpleInstallGetter(prototype, factory->flags_string(),
                          Builtins::kRegExpPrototypeFlagsGetter, true);
      SimpleInstallGetter(prototype, factory->global_string(),
                          Builtins::kRegExpPrototypeGlobalGetter, true);
      SimpleInstallGetter(prototype, factory->ignoreCase_string(),
                          Builtins::kRegExpPrototypeIgnoreCaseGetter, true);
      SimpleInstallGetter(prototype, factory->multiline_string(),
                          Builtins::kRegExpPrototypeMultilineGetter, true);
      SimpleInstallGetter(prototype, factory->source_string(),
2019
                          Builtins::kRegExpPrototypeSourceGetter, true);
2020 2021 2022 2023
      SimpleInstallGetter(prototype, factory->sticky_string(),
                          Builtins::kRegExpPrototypeStickyGetter, true);
      SimpleInstallGetter(prototype, factory->unicode_string(),
                          Builtins::kRegExpPrototypeUnicodeGetter, true);
2024 2025

      SimpleInstallFunction(prototype, "compile",
2026
                            Builtins::kRegExpPrototypeCompile, 2, true,
2027 2028 2029 2030
                            DONT_ENUM);
      SimpleInstallFunction(prototype, factory->toString_string(),
                            Builtins::kRegExpPrototypeToString, 0, false,
                            DONT_ENUM);
2031
      SimpleInstallFunction(prototype, "test", Builtins::kRegExpPrototypeTest,
2032
                            1, true, DONT_ENUM);
2033 2034 2035 2036

      {
        Handle<JSFunction> fun = SimpleCreateFunction(
            isolate, factory->InternalizeUtf8String("[Symbol.match]"),
2037
            Builtins::kRegExpPrototypeMatch, 1, true);
2038 2039 2040
        InstallFunction(prototype, fun, factory->match_symbol(), DONT_ENUM);
      }

2041 2042 2043 2044 2045 2046 2047
      {
        Handle<JSFunction> fun = SimpleCreateFunction(
            isolate, factory->InternalizeUtf8String("[Symbol.replace]"),
            Builtins::kRegExpPrototypeReplace, 2, true);
        InstallFunction(prototype, fun, factory->replace_symbol(), DONT_ENUM);
      }

2048 2049 2050
      {
        Handle<JSFunction> fun = SimpleCreateFunction(
            isolate, factory->InternalizeUtf8String("[Symbol.search]"),
2051
            Builtins::kRegExpPrototypeSearch, 1, true);
2052 2053
        InstallFunction(prototype, fun, factory->search_symbol(), DONT_ENUM);
      }
jgruber's avatar
jgruber committed
2054 2055 2056 2057

      {
        Handle<JSFunction> fun = SimpleCreateFunction(
            isolate, factory->InternalizeUtf8String("[Symbol.split]"),
2058
            Builtins::kRegExpPrototypeSplit, 2, true);
jgruber's avatar
jgruber committed
2059 2060
        InstallFunction(prototype, fun, factory->split_symbol(), DONT_ENUM);
      }
2061

2062 2063 2064
      Handle<Map> prototype_map(prototype->map());
      Map::SetShouldBeFastPrototypeMap(prototype_map, true, isolate);

2065 2066
      // Store the initial RegExp.prototype map. This is used in fast-path
      // checks. Do not alter the prototype after this point.
2067
      native_context()->set_regexp_prototype_map(*prototype_map);
2068
    }
2069

2070 2071 2072 2073 2074 2075
    {
      // RegExp getters and setters.

      SimpleInstallGetter(regexp_fun,
                          factory->InternalizeUtf8String("[Symbol.species]"),
                          factory->species_symbol(),
2076
                          Builtins::kRegExpPrototypeSpeciesGetter, true);
2077 2078 2079

      // Static properties set by a successful match.

2080
      const PropertyAttributes no_enum = DONT_ENUM;
2081 2082
      SimpleInstallGetterSetter(regexp_fun, factory->input_string(),
                                Builtins::kRegExpInputGetter,
2083
                                Builtins::kRegExpInputSetter, no_enum);
2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119
      SimpleInstallGetterSetter(
          regexp_fun, factory->InternalizeUtf8String("$_"),
          Builtins::kRegExpInputGetter, Builtins::kRegExpInputSetter, no_enum);

      SimpleInstallGetterSetter(
          regexp_fun, factory->InternalizeUtf8String("lastMatch"),
          Builtins::kRegExpLastMatchGetter, Builtins::kEmptyFunction, no_enum);
      SimpleInstallGetterSetter(
          regexp_fun, factory->InternalizeUtf8String("$&"),
          Builtins::kRegExpLastMatchGetter, Builtins::kEmptyFunction, no_enum);

      SimpleInstallGetterSetter(
          regexp_fun, factory->InternalizeUtf8String("lastParen"),
          Builtins::kRegExpLastParenGetter, Builtins::kEmptyFunction, no_enum);
      SimpleInstallGetterSetter(
          regexp_fun, factory->InternalizeUtf8String("$+"),
          Builtins::kRegExpLastParenGetter, Builtins::kEmptyFunction, no_enum);

      SimpleInstallGetterSetter(regexp_fun,
                                factory->InternalizeUtf8String("leftContext"),
                                Builtins::kRegExpLeftContextGetter,
                                Builtins::kEmptyFunction, no_enum);
      SimpleInstallGetterSetter(regexp_fun,
                                factory->InternalizeUtf8String("$`"),
                                Builtins::kRegExpLeftContextGetter,
                                Builtins::kEmptyFunction, no_enum);

      SimpleInstallGetterSetter(regexp_fun,
                                factory->InternalizeUtf8String("rightContext"),
                                Builtins::kRegExpRightContextGetter,
                                Builtins::kEmptyFunction, no_enum);
      SimpleInstallGetterSetter(regexp_fun,
                                factory->InternalizeUtf8String("$'"),
                                Builtins::kRegExpRightContextGetter,
                                Builtins::kEmptyFunction, no_enum);

2120 2121 2122 2123
#define INSTALL_CAPTURE_GETTER(i)                         \
  SimpleInstallGetterSetter(                              \
      regexp_fun, factory->InternalizeUtf8String("$" #i), \
      Builtins::kRegExpCapture##i##Getter, Builtins::kEmptyFunction, no_enum)
2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134
      INSTALL_CAPTURE_GETTER(1);
      INSTALL_CAPTURE_GETTER(2);
      INSTALL_CAPTURE_GETTER(3);
      INSTALL_CAPTURE_GETTER(4);
      INSTALL_CAPTURE_GETTER(5);
      INSTALL_CAPTURE_GETTER(6);
      INSTALL_CAPTURE_GETTER(7);
      INSTALL_CAPTURE_GETTER(8);
      INSTALL_CAPTURE_GETTER(9);
#undef INSTALL_CAPTURE_GETTER
    }
2135

2136
    DCHECK(regexp_fun->has_initial_map());
2137 2138
    Handle<Map> initial_map(regexp_fun->initial_map());

2139
    DCHECK_EQ(0, initial_map->GetInObjectProperties());
2140

2141 2142 2143 2144 2145
    Map::EnsureDescriptorSlack(initial_map, 1);

    // ECMA-262, section 15.10.7.5.
    PropertyAttributes writable =
        static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE);
2146
    DataDescriptor field(factory->lastIndex_string(),
2147 2148 2149
                         JSRegExp::kLastIndexFieldIndex, writable,
                         Representation::Tagged());
    initial_map->AppendDescriptor(&field);
2150

2151
    static const int num_fields = JSRegExp::kInObjectFieldCount;
2152
    initial_map->SetInObjectProperties(num_fields);
2153
    initial_map->set_unused_property_fields(0);
2154 2155
    initial_map->set_instance_size(initial_map->instance_size() +
                                   num_fields * kPointerSize);
2156 2157 2158 2159 2160 2161 2162 2163 2164

    {  // Internal: RegExpInternalMatch
      Handle<JSFunction> function =
          factory->NewFunction(isolate->factory()->empty_string(),
                               isolate->builtins()->RegExpInternalMatch(),
                               JS_OBJECT_TYPE, JSObject::kHeaderSize);
      function->shared()->set_internal_formal_parameter_count(2);
      function->shared()->set_length(2);
      function->shared()->set_native(true);
2165
      native_context()->set(Context::REGEXP_INTERNAL_MATCH, *function);
2166
    }
2167 2168 2169 2170 2171 2172 2173

    // Create the last match info. One for external use, and one for internal
    // use when we don't want to modify the externally visible match info.
    Handle<RegExpMatchInfo> last_match_info = factory->NewRegExpMatchInfo();
    native_context()->set_regexp_last_match_info(*last_match_info);
    Handle<RegExpMatchInfo> internal_match_info = factory->NewRegExpMatchInfo();
    native_context()->set_regexp_internal_match_info(*internal_match_info);
2174 2175
  }

2176
  {  // -- E r r o r
jgruber's avatar
jgruber committed
2177 2178
    InstallError(isolate, global, factory->Error_string(),
                 Context::ERROR_FUNCTION_INDEX);
2179 2180
    InstallMakeError(isolate, isolate->builtins()->MakeError(),
                     Context::MAKE_ERROR_INDEX);
2181 2182 2183
  }

  {  // -- E v a l E r r o r
jgruber's avatar
jgruber committed
2184 2185
    InstallError(isolate, global, factory->EvalError_string(),
                 Context::EVAL_ERROR_FUNCTION_INDEX);
2186 2187 2188
  }

  {  // -- R a n g e E r r o r
jgruber's avatar
jgruber committed
2189 2190
    InstallError(isolate, global, factory->RangeError_string(),
                 Context::RANGE_ERROR_FUNCTION_INDEX);
2191 2192
    InstallMakeError(isolate, isolate->builtins()->MakeRangeError(),
                     Context::MAKE_RANGE_ERROR_INDEX);
2193 2194 2195
  }

  {  // -- R e f e r e n c e E r r o r
jgruber's avatar
jgruber committed
2196 2197
    InstallError(isolate, global, factory->ReferenceError_string(),
                 Context::REFERENCE_ERROR_FUNCTION_INDEX);
2198 2199 2200
  }

  {  // -- S y n t a x E r r o r
jgruber's avatar
jgruber committed
2201 2202
    InstallError(isolate, global, factory->SyntaxError_string(),
                 Context::SYNTAX_ERROR_FUNCTION_INDEX);
2203 2204
    InstallMakeError(isolate, isolate->builtins()->MakeSyntaxError(),
                     Context::MAKE_SYNTAX_ERROR_INDEX);
2205 2206 2207
  }

  {  // -- T y p e E r r o r
jgruber's avatar
jgruber committed
2208 2209
    InstallError(isolate, global, factory->TypeError_string(),
                 Context::TYPE_ERROR_FUNCTION_INDEX);
2210 2211
    InstallMakeError(isolate, isolate->builtins()->MakeTypeError(),
                     Context::MAKE_TYPE_ERROR_INDEX);
2212 2213 2214
  }

  {  // -- U R I E r r o r
jgruber's avatar
jgruber committed
2215 2216
    InstallError(isolate, global, factory->URIError_string(),
                 Context::URI_ERROR_FUNCTION_INDEX);
2217 2218
    InstallMakeError(isolate, isolate->builtins()->MakeURIError(),
                     Context::MAKE_URI_ERROR_INDEX);
2219 2220
  }

2221 2222 2223 2224 2225
  {  // -- C o m p i l e E r r o r
    Handle<JSObject> dummy = factory->NewJSObject(isolate->object_function());
    InstallError(isolate, dummy, factory->CompileError_string(),
                 Context::WASM_COMPILE_ERROR_FUNCTION_INDEX);

2226 2227 2228 2229
    // -- L i n k E r r o r
    InstallError(isolate, dummy, factory->LinkError_string(),
                 Context::WASM_LINK_ERROR_FUNCTION_INDEX);

2230 2231 2232 2233 2234
    // -- R u n t i m e E r r o r
    InstallError(isolate, dummy, factory->RuntimeError_string(),
                 Context::WASM_RUNTIME_ERROR_FUNCTION_INDEX);
  }

2235 2236 2237 2238
  // Initialize the embedder data slot.
  Handle<FixedArray> embedder_data = factory->NewFixedArray(3);
  native_context()->set_embedder_data(*embedder_data);

2239
  {  // -- J S O N
2240
    Handle<String> name = factory->InternalizeUtf8String("JSON");
2241
    Handle<JSFunction> cons = factory->NewFunction(name);
2242 2243
    JSFunction::SetInstancePrototype(cons,
        Handle<Object>(native_context()->initial_object_prototype(), isolate));
2244
    Handle<JSObject> json_object = factory->NewJSObject(cons, TENURED);
2245
    DCHECK(json_object->IsJSObject());
2246
    JSObject::AddProperty(global, name, json_object, DONT_ENUM);
2247
    SimpleInstallFunction(json_object, "parse", Builtins::kJsonParse, 2, false);
2248 2249
    SimpleInstallFunction(json_object, "stringify", Builtins::kJsonStringify, 3,
                          true);
2250 2251 2252 2253
    JSObject::AddProperty(
        json_object, factory->to_string_tag_symbol(),
        factory->NewStringFromAsciiChecked("JSON"),
        static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY));
2254 2255 2256 2257 2258 2259 2260 2261
  }

  {  // -- M a t h
    Handle<String> name = factory->InternalizeUtf8String("Math");
    Handle<JSFunction> cons = factory->NewFunction(name);
    JSFunction::SetInstancePrototype(
        cons,
        Handle<Object>(native_context()->initial_object_prototype(), isolate));
2262 2263 2264
    Handle<JSObject> math = factory->NewJSObject(cons, TENURED);
    DCHECK(math->IsJSObject());
    JSObject::AddProperty(global, name, math, DONT_ENUM);
2265
    SimpleInstallFunction(math, "abs", Builtins::kMathAbs, 1, true);
2266
    SimpleInstallFunction(math, "acos", Builtins::kMathAcos, 1, true);
2267
    SimpleInstallFunction(math, "acosh", Builtins::kMathAcosh, 1, true);
2268
    SimpleInstallFunction(math, "asin", Builtins::kMathAsin, 1, true);
2269
    SimpleInstallFunction(math, "asinh", Builtins::kMathAsinh, 1, true);
2270
    SimpleInstallFunction(math, "atan", Builtins::kMathAtan, 1, true);
2271
    SimpleInstallFunction(math, "atanh", Builtins::kMathAtanh, 1, true);
2272
    SimpleInstallFunction(math, "atan2", Builtins::kMathAtan2, 2, true);
2273
    SimpleInstallFunction(math, "ceil", Builtins::kMathCeil, 1, true);
2274 2275
    SimpleInstallFunction(math, "cbrt", Builtins::kMathCbrt, 1, true);
    SimpleInstallFunction(math, "expm1", Builtins::kMathExpm1, 1, true);
2276
    SimpleInstallFunction(math, "clz32", Builtins::kMathClz32, 1, true);
2277
    SimpleInstallFunction(math, "cos", Builtins::kMathCos, 1, true);
2278
    SimpleInstallFunction(math, "cosh", Builtins::kMathCosh, 1, true);
2279
    SimpleInstallFunction(math, "exp", Builtins::kMathExp, 1, true);
2280 2281 2282
    Handle<JSFunction> math_floor =
        SimpleInstallFunction(math, "floor", Builtins::kMathFloor, 1, true);
    native_context()->set_math_floor(*math_floor);
2283
    SimpleInstallFunction(math, "fround", Builtins::kMathFround, 1, true);
2284
    SimpleInstallFunction(math, "hypot", Builtins::kMathHypot, 2, false);
2285
    SimpleInstallFunction(math, "imul", Builtins::kMathImul, 2, true);
2286
    SimpleInstallFunction(math, "log", Builtins::kMathLog, 1, true);
2287
    SimpleInstallFunction(math, "log1p", Builtins::kMathLog1p, 1, true);
2288 2289
    SimpleInstallFunction(math, "log2", Builtins::kMathLog2, 1, true);
    SimpleInstallFunction(math, "log10", Builtins::kMathLog10, 1, true);
2290 2291
    SimpleInstallFunction(math, "max", Builtins::kMathMax, 2, false);
    SimpleInstallFunction(math, "min", Builtins::kMathMin, 2, false);
2292 2293 2294
    Handle<JSFunction> math_pow =
        SimpleInstallFunction(math, "pow", Builtins::kMathPow, 2, true);
    native_context()->set_math_pow(*math_pow);
2295
    SimpleInstallFunction(math, "random", Builtins::kMathRandom, 0, true);
2296
    SimpleInstallFunction(math, "round", Builtins::kMathRound, 1, true);
2297
    SimpleInstallFunction(math, "sign", Builtins::kMathSign, 1, true);
2298
    SimpleInstallFunction(math, "sin", Builtins::kMathSin, 1, true);
2299
    SimpleInstallFunction(math, "sinh", Builtins::kMathSinh, 1, true);
2300
    SimpleInstallFunction(math, "sqrt", Builtins::kMathSqrt, 1, true);
2301
    SimpleInstallFunction(math, "tan", Builtins::kMathTan, 1, true);
2302
    SimpleInstallFunction(math, "tanh", Builtins::kMathTanh, 1, true);
2303
    SimpleInstallFunction(math, "trunc", Builtins::kMathTrunc, 1, true);
2304 2305 2306

    // Install math constants.
    double const kE = base::ieee754::exp(1.0);
2307
    double const kPI = 3.1415926535897932;
2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320
    InstallConstant(isolate, math, "E", factory->NewNumber(kE));
    InstallConstant(isolate, math, "LN10",
                    factory->NewNumber(base::ieee754::log(10.0)));
    InstallConstant(isolate, math, "LN2",
                    factory->NewNumber(base::ieee754::log(2.0)));
    InstallConstant(isolate, math, "LOG10E",
                    factory->NewNumber(base::ieee754::log10(kE)));
    InstallConstant(isolate, math, "LOG2E",
                    factory->NewNumber(base::ieee754::log2(kE)));
    InstallConstant(isolate, math, "PI", factory->NewNumber(kPI));
    InstallConstant(isolate, math, "SQRT1_2",
                    factory->NewNumber(std::sqrt(0.5)));
    InstallConstant(isolate, math, "SQRT2", factory->NewNumber(std::sqrt(2.0)));
2321 2322 2323 2324
    JSObject::AddProperty(
        math, factory->to_string_tag_symbol(),
        factory->NewStringFromAsciiChecked("Math"),
        static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY));
2325 2326
  }

2327
  {  // -- A r r a y B u f f e r
2328 2329 2330
    Handle<JSFunction> array_buffer_fun = InstallArrayBuffer(
        global, "ArrayBuffer", Builtins::kArrayBufferPrototypeGetByteLength,
        BuiltinFunctionId::kArrayBufferByteLength);
2331 2332
    InstallWithIntrinsicDefaultProto(isolate, array_buffer_fun,
                                     Context::ARRAY_BUFFER_FUN_INDEX);
2333 2334
  }

2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362
  {  // -- T y p e d A r r a y
    Handle<JSObject> prototype =
        factory->NewJSObject(isolate->object_function(), TENURED);
    native_context()->set_typed_array_prototype(*prototype);

    Handle<JSFunction> typed_array_fun =
        CreateFunction(isolate, factory->InternalizeUtf8String("TypedArray"),
                       JS_TYPED_ARRAY_TYPE, JSTypedArray::kSize, prototype,
                       Builtins::kIllegal);

    // Install the "constructor" property on the {prototype}.
    JSObject::AddProperty(prototype, factory->constructor_string(),
                          typed_array_fun, DONT_ENUM);
    native_context()->set_typed_array_function(*typed_array_fun);

    // Install the "buffer", "byteOffset", "byteLength" and "length"
    // getters on the {prototype}.
    SimpleInstallGetter(prototype, factory->buffer_string(),
                        Builtins::kTypedArrayPrototypeBuffer, false);
    SimpleInstallGetter(prototype, factory->byte_length_string(),
                        Builtins::kTypedArrayPrototypeByteLength, true,
                        kTypedArrayByteLength);
    SimpleInstallGetter(prototype, factory->byte_offset_string(),
                        Builtins::kTypedArrayPrototypeByteOffset, true,
                        kTypedArrayByteOffset);
    SimpleInstallGetter(prototype, factory->length_string(),
                        Builtins::kTypedArrayPrototypeLength, true,
                        kTypedArrayLength);
2363 2364

    // Install "keys", "values" and "entries" methods on the {prototype}.
2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375
    Handle<JSFunction> entries =
        SimpleInstallFunction(prototype, factory->entries_string(),
                              Builtins::kTypedArrayPrototypeEntries, 0, true);
    entries->shared()->set_builtin_function_id(kTypedArrayEntries);

    Handle<JSFunction> keys =
        SimpleInstallFunction(prototype, factory->keys_string(),
                              Builtins::kTypedArrayPrototypeKeys, 0, true);
    keys->shared()->set_builtin_function_id(kTypedArrayKeys);

    Handle<JSFunction> values =
2376 2377
        SimpleInstallFunction(prototype, factory->values_string(),
                              Builtins::kTypedArrayPrototypeValues, 0, true);
2378 2379
    values->shared()->set_builtin_function_id(kTypedArrayValues);
    JSObject::AddProperty(prototype, factory->iterator_symbol(), values,
2380
                          DONT_ENUM);
2381 2382
  }

2383
  {  // -- T y p e d A r r a y s
2384 2385 2386 2387 2388 2389
#define INSTALL_TYPED_ARRAY(Type, type, TYPE, ctype, size)             \
  {                                                                    \
    Handle<JSFunction> fun;                                            \
    InstallTypedArray(#Type "Array", TYPE##_ELEMENTS, &fun);           \
    InstallWithIntrinsicDefaultProto(isolate, fun,                     \
                                     Context::TYPE##_ARRAY_FUN_INDEX); \
2390
  }
2391 2392
    TYPED_ARRAYS(INSTALL_TYPED_ARRAY)
#undef INSTALL_TYPED_ARRAY
2393
  }
2394

2395 2396 2397 2398 2399 2400 2401
  {  // -- D a t a V i e w
    Handle<JSObject> prototype =
        factory->NewJSObject(isolate->object_function(), TENURED);
    Handle<JSFunction> data_view_fun =
        InstallFunction(global, "DataView", JS_DATA_VIEW_TYPE,
                        JSDataView::kSizeWithInternalFields, prototype,
                        Builtins::kDataViewConstructor);
2402 2403
    InstallWithIntrinsicDefaultProto(isolate, data_view_fun,
                                     Context::DATA_VIEW_FUN_INDEX);
2404
    data_view_fun->shared()->SetConstructStub(
2405 2406 2407
        *isolate->builtins()->DataViewConstructor_ConstructStub());
    data_view_fun->shared()->set_length(3);
    data_view_fun->shared()->DontAdaptArguments();
2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429

    // Install the @@toStringTag property on the {prototype}.
    JSObject::AddProperty(
        prototype, factory->to_string_tag_symbol(),
        factory->NewStringFromAsciiChecked("DataView"),
        static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY));

    // Install the "constructor" property on the {prototype}.
    JSObject::AddProperty(prototype, factory->constructor_string(),
                          data_view_fun, DONT_ENUM);

    // Install the "buffer", "byteOffset" and "byteLength" getters
    // on the {prototype}.
    SimpleInstallGetter(prototype, factory->buffer_string(),
                        Builtins::kDataViewPrototypeGetBuffer, false,
                        kDataViewBuffer);
    SimpleInstallGetter(prototype, factory->byte_length_string(),
                        Builtins::kDataViewPrototypeGetByteLength, false,
                        kDataViewByteLength);
    SimpleInstallGetter(prototype, factory->byte_offset_string(),
                        Builtins::kDataViewPrototypeGetByteOffset, false,
                        kDataViewByteOffset);
2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462

    SimpleInstallFunction(prototype, "getInt8",
                          Builtins::kDataViewPrototypeGetInt8, 1, false);
    SimpleInstallFunction(prototype, "setInt8",
                          Builtins::kDataViewPrototypeSetInt8, 2, false);
    SimpleInstallFunction(prototype, "getUint8",
                          Builtins::kDataViewPrototypeGetUint8, 1, false);
    SimpleInstallFunction(prototype, "setUint8",
                          Builtins::kDataViewPrototypeSetUint8, 2, false);
    SimpleInstallFunction(prototype, "getInt16",
                          Builtins::kDataViewPrototypeGetInt16, 1, false);
    SimpleInstallFunction(prototype, "setInt16",
                          Builtins::kDataViewPrototypeSetInt16, 2, false);
    SimpleInstallFunction(prototype, "getUint16",
                          Builtins::kDataViewPrototypeGetUint16, 1, false);
    SimpleInstallFunction(prototype, "setUint16",
                          Builtins::kDataViewPrototypeSetUint16, 2, false);
    SimpleInstallFunction(prototype, "getInt32",
                          Builtins::kDataViewPrototypeGetInt32, 1, false);
    SimpleInstallFunction(prototype, "setInt32",
                          Builtins::kDataViewPrototypeSetInt32, 2, false);
    SimpleInstallFunction(prototype, "getUint32",
                          Builtins::kDataViewPrototypeGetUint32, 1, false);
    SimpleInstallFunction(prototype, "setUint32",
                          Builtins::kDataViewPrototypeSetUint32, 2, false);
    SimpleInstallFunction(prototype, "getFloat32",
                          Builtins::kDataViewPrototypeGetFloat32, 1, false);
    SimpleInstallFunction(prototype, "setFloat32",
                          Builtins::kDataViewPrototypeSetFloat32, 2, false);
    SimpleInstallFunction(prototype, "getFloat64",
                          Builtins::kDataViewPrototypeGetFloat64, 1, false);
    SimpleInstallFunction(prototype, "setFloat64",
                          Builtins::kDataViewPrototypeSetFloat64, 2, false);
2463 2464
  }

2465
  {  // -- M a p
2466
    Handle<JSFunction> js_map_fun = InstallFunction(
2467 2468
        global, "Map", JS_MAP_TYPE, JSMap::kSize,
        isolate->initial_object_prototype(), Builtins::kIllegal);
2469 2470
    InstallWithIntrinsicDefaultProto(isolate, js_map_fun,
                                     Context::JS_MAP_FUN_INDEX);
2471
  }
2472

2473
  {  // -- S e t
2474
    Handle<JSFunction> js_set_fun = InstallFunction(
2475 2476
        global, "Set", JS_SET_TYPE, JSSet::kSize,
        isolate->initial_object_prototype(), Builtins::kIllegal);
2477 2478
    InstallWithIntrinsicDefaultProto(isolate, js_set_fun,
                                     Context::JS_SET_FUN_INDEX);
2479
  }
2480

2481 2482 2483 2484
  {  // -- J S M o d u l e N a m e s p a c e
    Handle<Map> map =
        factory->NewMap(JS_MODULE_NAMESPACE_TYPE, JSModuleNamespace::kSize);
    Map::SetPrototype(map, isolate->factory()->null_value());
2485
    Map::EnsureDescriptorSlack(map, 1);
2486 2487
    native_context()->set_js_module_namespace_map(*map);

2488 2489 2490 2491 2492 2493 2494 2495
    {  // Install @@toStringTag.
      PropertyAttributes attribs =
          static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY);
      DataConstantDescriptor d(factory->to_string_tag_symbol(),
                               factory->NewStringFromAsciiChecked("Module"),
                               attribs);
      map->AppendDescriptor(&d);
    }
2496 2497
  }

2498 2499
  {  // -- I t e r a t o r R e s u l t
    Handle<Map> map =
2500
        factory->NewMap(JS_OBJECT_TYPE, JSIteratorResult::kSize);
2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515
    Map::SetPrototype(map, isolate->initial_object_prototype());
    Map::EnsureDescriptorSlack(map, 2);

    {  // value
      DataDescriptor d(factory->value_string(), JSIteratorResult::kValueIndex,
                       NONE, Representation::Tagged());
      map->AppendDescriptor(&d);
    }

    {  // done
      DataDescriptor d(factory->done_string(), JSIteratorResult::kDoneIndex,
                       NONE, Representation::Tagged());
      map->AppendDescriptor(&d);
    }

2516
    map->SetConstructor(native_context()->object_function());
2517 2518
    map->SetInObjectProperties(2);
    native_context()->set_iterator_result_map(*map);
2519 2520
  }

2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535
  {  // -- W e a k M a p
    Handle<JSFunction> js_weak_map_fun = InstallFunction(
        global, "WeakMap", JS_WEAK_MAP_TYPE, JSWeakMap::kSize,
        isolate->initial_object_prototype(), Builtins::kIllegal);
    InstallWithIntrinsicDefaultProto(isolate, js_weak_map_fun,
                                     Context::JS_WEAK_MAP_FUN_INDEX);
  }

  {  // -- W e a k S e t
    Handle<JSFunction> js_weak_set_fun = InstallFunction(
        global, "WeakSet", JS_WEAK_SET_TYPE, JSWeakSet::kSize,
        isolate->initial_object_prototype(), Builtins::kIllegal);
    InstallWithIntrinsicDefaultProto(isolate, js_weak_set_fun,
                                     Context::JS_WEAK_SET_FUN_INDEX);
  }
2536

2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550
  {  // -- P r o x y
    CreateJSProxyMaps();

    Handle<String> name = factory->Proxy_string();
    Handle<Code> code(isolate->builtins()->ProxyConstructor());

    Handle<JSFunction> proxy_function =
        factory->NewFunction(isolate->proxy_function_map(),
                             factory->Proxy_string(), MaybeHandle<Code>(code));

    JSFunction::SetInitialMap(
        proxy_function, Handle<Map>(native_context()->proxy_map(), isolate),
        factory->null_value());

2551
    proxy_function->shared()->SetConstructStub(
2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 2597 2598 2599 2600 2601 2602 2603 2604
        *isolate->builtins()->ProxyConstructor_ConstructStub());
    proxy_function->shared()->set_internal_formal_parameter_count(2);
    proxy_function->shared()->set_length(2);

    native_context()->set_proxy_function(*proxy_function);
    InstallFunction(global, name, proxy_function, factory->Object_string());
  }

  {  // -- R e f l e c t
    Handle<String> reflect_string = factory->InternalizeUtf8String("Reflect");
    Handle<JSObject> reflect =
        factory->NewJSObject(isolate->object_function(), TENURED);
    JSObject::AddProperty(global, reflect_string, reflect, DONT_ENUM);

    Handle<JSFunction> define_property =
        SimpleInstallFunction(reflect, factory->defineProperty_string(),
                              Builtins::kReflectDefineProperty, 3, true);
    native_context()->set_reflect_define_property(*define_property);

    Handle<JSFunction> delete_property =
        SimpleInstallFunction(reflect, factory->deleteProperty_string(),
                              Builtins::kReflectDeleteProperty, 2, true);
    native_context()->set_reflect_delete_property(*delete_property);

    Handle<JSFunction> apply = SimpleInstallFunction(
        reflect, factory->apply_string(), Builtins::kReflectApply, 3, false);
    native_context()->set_reflect_apply(*apply);

    Handle<JSFunction> construct =
        SimpleInstallFunction(reflect, factory->construct_string(),
                              Builtins::kReflectConstruct, 2, false);
    native_context()->set_reflect_construct(*construct);

    SimpleInstallFunction(reflect, factory->get_string(), Builtins::kReflectGet,
                          2, false);
    SimpleInstallFunction(reflect, factory->getOwnPropertyDescriptor_string(),
                          Builtins::kReflectGetOwnPropertyDescriptor, 2, true);
    SimpleInstallFunction(reflect, factory->getPrototypeOf_string(),
                          Builtins::kReflectGetPrototypeOf, 1, true);
    SimpleInstallFunction(reflect, factory->has_string(), Builtins::kReflectHas,
                          2, true);
    SimpleInstallFunction(reflect, factory->isExtensible_string(),
                          Builtins::kReflectIsExtensible, 1, true);
    SimpleInstallFunction(reflect, factory->ownKeys_string(),
                          Builtins::kReflectOwnKeys, 1, true);
    SimpleInstallFunction(reflect, factory->preventExtensions_string(),
                          Builtins::kReflectPreventExtensions, 1, true);
    SimpleInstallFunction(reflect, factory->set_string(), Builtins::kReflectSet,
                          3, false);
    SimpleInstallFunction(reflect, factory->setPrototypeOf_string(),
                          Builtins::kReflectSetPrototypeOf, 2, true);
  }

2605 2606 2607 2608 2609 2610 2611 2612 2613 2614
  {  // --- B o u n d F u n c t i o n
    Handle<Map> map =
        factory->NewMap(JS_BOUND_FUNCTION_TYPE, JSBoundFunction::kSize);
    map->set_is_callable();
    Map::SetPrototype(map, empty_function);

    PropertyAttributes roc_attribs =
        static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY);
    Map::EnsureDescriptorSlack(map, 2);

2615 2616
    Handle<AccessorInfo> bound_length =
        Accessors::BoundFunctionLengthInfo(isolate, roc_attribs);
2617
    {  // length
2618 2619
      AccessorConstantDescriptor d(factory->length_string(), bound_length,
                                   roc_attribs);
2620 2621
      map->AppendDescriptor(&d);
    }
2622 2623 2624 2625 2626
    Handle<AccessorInfo> bound_name =
        Accessors::BoundFunctionNameInfo(isolate, roc_attribs);
    {  // length
      AccessorConstantDescriptor d(factory->name_string(), bound_name,
                                   roc_attribs);
2627 2628
      map->AppendDescriptor(&d);
    }
2629
    map->SetInObjectProperties(0);
2630 2631 2632
    native_context()->set_bound_function_without_constructor_map(*map);

    map = Map::Copy(map, "IsConstructor");
2633
    map->set_is_constructor(true);
2634 2635 2636
    native_context()->set_bound_function_with_constructor_map(*map);
  }

2637
  {  // --- sloppy arguments map
2638 2639 2640
    // Make sure we can recognize argument objects at runtime.
    // This is done by introducing an anonymous function with
    // class_name equals 'Arguments'.
2641
    Handle<String> arguments_string = factory->Arguments_string();
2642
    Handle<Code> code = isolate->builtins()->Illegal();
2643 2644
    Handle<JSFunction> function = factory->NewFunctionWithoutPrototype(
        arguments_string, code);
2645
    function->shared()->set_instance_class_name(*arguments_string);
2646

2647
    Handle<Map> map = factory->NewMap(
2648
        JS_ARGUMENTS_TYPE, JSSloppyArgumentsObject::kSize, FAST_ELEMENTS);
2649 2650 2651 2652
    // Create the descriptor array for the arguments object.
    Map::EnsureDescriptorSlack(map, 2);

    {  // length
2653 2654 2655
      DataDescriptor d(factory->length_string(),
                       JSSloppyArgumentsObject::kLengthIndex, DONT_ENUM,
                       Representation::Tagged());
2656 2657 2658
      map->AppendDescriptor(&d);
    }
    {  // callee
2659 2660 2661
      DataDescriptor d(factory->callee_string(),
                       JSSloppyArgumentsObject::kCalleeIndex, DONT_ENUM,
                       Representation::Tagged());
2662 2663
      map->AppendDescriptor(&d);
    }
2664
    // @@iterator method is added later.
2665

2666
    map->SetInObjectProperties(2);
2667 2668
    native_context()->set_sloppy_arguments_map(*map);

2669
    DCHECK(!function->has_initial_map());
2670 2671
    JSFunction::SetInitialMap(function, map,
                              isolate->initial_object_prototype());
2672

2673 2674
    DCHECK(!map->is_dictionary_map());
    DCHECK(IsFastObjectElementsKind(map->elements_kind()));
2675 2676
  }

2677 2678 2679 2680
  {  // --- fast and slow aliased arguments map
    Handle<Map> map = isolate->sloppy_arguments_map();
    map = Map::Copy(map, "FastAliasedArguments");
    map->set_elements_kind(FAST_SLOPPY_ARGUMENTS_ELEMENTS);
2681
    DCHECK_EQ(2, map->GetInObjectProperties());
2682 2683 2684 2685
    native_context()->set_fast_aliased_arguments_map(*map);

    map = Map::Copy(map, "SlowAliasedArguments");
    map->set_elements_kind(SLOW_SLOPPY_ARGUMENTS_ELEMENTS);
2686
    DCHECK_EQ(2, map->GetInObjectProperties());
2687
    native_context()->set_slow_aliased_arguments_map(*map);
2688 2689 2690
  }

  {  // --- strict mode arguments map
2691 2692 2693
    const PropertyAttributes attributes =
      static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY);

2694
    // Create the ThrowTypeError function.
2695
    Handle<AccessorPair> callee = factory->NewAccessorPair();
2696

2697
    Handle<JSFunction> poison = GetStrictArgumentsPoisonFunction();
2698

2699
    // Install the ThrowTypeError function.
2700 2701
    callee->set_getter(*poison);
    callee->set_setter(*poison);
2702

2703
    // Create the map. Allocate one in-object field for length.
2704
    Handle<Map> map = factory->NewMap(
2705
        JS_ARGUMENTS_TYPE, JSStrictArgumentsObject::kSize, FAST_ELEMENTS);
2706
    // Create the descriptor array for the arguments object.
2707
    Map::EnsureDescriptorSlack(map, 2);
2708

2709
    {  // length
2710 2711 2712
      DataDescriptor d(factory->length_string(),
                       JSStrictArgumentsObject::kLengthIndex, DONT_ENUM,
                       Representation::Tagged());
2713
      map->AppendDescriptor(&d);
2714 2715
    }
    {  // callee
2716 2717
      AccessorConstantDescriptor d(factory->callee_string(), callee,
                                   attributes);
2718
      map->AppendDescriptor(&d);
2719
    }
2720
    // @@iterator method is added later.
2721

2722 2723
    DCHECK_EQ(native_context()->object_function()->prototype(),
              *isolate->initial_object_prototype());
2724
    Map::SetPrototype(map, isolate->initial_object_prototype());
2725
    map->SetInObjectProperties(1);
2726

2727
    // Copy constructor from the sloppy arguments boilerplate.
2728 2729
    map->SetConstructor(
        native_context()->sloppy_arguments_map()->GetConstructor());
2730

2731
    native_context()->set_strict_arguments_map(*map);
2732

2733 2734
    DCHECK(!map->is_dictionary_map());
    DCHECK(IsFastObjectElementsKind(map->elements_kind()));
2735 2736 2737 2738
  }

  {  // --- context extension
    // Create a function for the context extension objects.
2739
    Handle<Code> code = isolate->builtins()->Illegal();
2740
    Handle<JSFunction> context_extension_fun = factory->NewFunction(
2741 2742
        factory->empty_string(), code, JS_CONTEXT_EXTENSION_OBJECT_TYPE,
        JSObject::kHeaderSize);
2743

2744
    Handle<String> name = factory->InternalizeOneByteString(
2745
        STATIC_CHAR_VECTOR("context_extension"));
2746
    context_extension_fun->shared()->set_instance_class_name(*name);
2747
    native_context()->set_context_extension_function(*context_extension_fun);
2748 2749
  }

2750 2751

  {
2752
    // Set up the call-as-function delegate.
2753
    Handle<Code> code = isolate->builtins()->HandleApiCallAsFunction();
2754
    Handle<JSFunction> delegate = factory->NewFunction(
2755
        factory->empty_string(), code, JS_OBJECT_TYPE, JSObject::kHeaderSize);
2756
    native_context()->set_call_as_function_delegate(*delegate);
2757 2758 2759 2760
    delegate->shared()->DontAdaptArguments();
  }

  {
2761
    // Set up the call-as-constructor delegate.
2762
    Handle<Code> code = isolate->builtins()->HandleApiCallAsConstructor();
2763
    Handle<JSFunction> delegate = factory->NewFunction(
2764
        factory->empty_string(), code, JS_OBJECT_TYPE, JSObject::kHeaderSize);
2765
    native_context()->set_call_as_constructor_delegate(*delegate);
2766 2767
    delegate->shared()->DontAdaptArguments();
  }
2768
}  // NOLINT(readability/fn_size)
2769

2770 2771
void Genesis::InstallTypedArray(const char* name, ElementsKind elements_kind,
                                Handle<JSFunction>* fun) {
2772
  Handle<JSObject> global = Handle<JSObject>(native_context()->global_object());
2773 2774 2775 2776 2777 2778 2779 2780

  Handle<JSObject> typed_array_prototype =
      Handle<JSObject>(isolate()->typed_array_prototype());
  Handle<JSFunction> typed_array_function =
      Handle<JSFunction>(isolate()->typed_array_function());

  Handle<JSObject> prototype =
      factory()->NewJSObject(isolate()->object_function(), TENURED);
2781 2782 2783 2784
  Handle<JSFunction> result = InstallFunction(
      global, name, JS_TYPED_ARRAY_TYPE, JSTypedArray::kSizeWithInternalFields,
      prototype, Builtins::kIllegal);
  result->initial_map()->set_elements_kind(elements_kind);
2785 2786 2787 2788 2789 2790 2791 2792

  CHECK(JSObject::SetPrototype(result, typed_array_function, false,
                               Object::DONT_THROW)
            .FromJust());

  CHECK(JSObject::SetPrototype(prototype, typed_array_prototype, false,
                               Object::DONT_THROW)
            .FromJust());
2793
  *fun = result;
2794 2795 2796
}


2797
void Genesis::InitializeExperimentalGlobal() {
2798
#define FEATURE_INITIALIZE_GLOBAL(id, descr) InitializeGlobal_##id();
2799

2800 2801
  HARMONY_INPROGRESS(FEATURE_INITIALIZE_GLOBAL)
  HARMONY_STAGED(FEATURE_INITIALIZE_GLOBAL)
2802
  HARMONY_SHIPPING(FEATURE_INITIALIZE_GLOBAL)
2803
#undef FEATURE_INITIALIZE_GLOBAL
2804 2805 2806
}


2807
bool Bootstrapper::CompileBuiltin(Isolate* isolate, int index) {
2808
  Vector<const char> name = Natives::GetScriptName(index);
2809
  Handle<String> source_code =
2810
      isolate->bootstrapper()->SourceLookup<Natives>(index);
2811 2812 2813

  // We pass in extras_utils so that builtin code can set it up for later use
  // by actual extras code, compiled with CompileExtraBuiltin.
2814
  Handle<Object> global = isolate->global_object();
2815
  Handle<Object> utils = isolate->natives_utils_object();
2816 2817
  Handle<Object> extras_utils = isolate->extras_utils_object();
  Handle<Object> args[] = {global, utils, extras_utils};
2818

yangguo's avatar
yangguo committed
2819
  return Bootstrapper::CompileNative(isolate, name, source_code,
2820
                                     arraysize(args), args, NATIVES_CODE);
2821 2822 2823
}


2824
bool Bootstrapper::CompileExperimentalBuiltin(Isolate* isolate, int index) {
2825
  HandleScope scope(isolate);
2826
  Vector<const char> name = ExperimentalNatives::GetScriptName(index);
2827 2828
  Handle<String> source_code =
      isolate->bootstrapper()->SourceLookup<ExperimentalNatives>(index);
2829
  Handle<Object> global = isolate->global_object();
2830 2831
  Handle<Object> utils = isolate->natives_utils_object();
  Handle<Object> args[] = {global, utils};
yangguo's avatar
yangguo committed
2832
  return Bootstrapper::CompileNative(isolate, name, source_code,
2833
                                     arraysize(args), args, NATIVES_CODE);
2834 2835 2836
}


2837
bool Bootstrapper::CompileExtraBuiltin(Isolate* isolate, int index) {
2838
  HandleScope scope(isolate);
2839 2840 2841
  Vector<const char> name = ExtraNatives::GetScriptName(index);
  Handle<String> source_code =
      isolate->bootstrapper()->SourceLookup<ExtraNatives>(index);
2842
  Handle<Object> global = isolate->global_object();
2843
  Handle<Object> binding = isolate->extras_binding_object();
2844 2845
  Handle<Object> extras_utils = isolate->extras_utils_object();
  Handle<Object> args[] = {global, binding, extras_utils};
yangguo's avatar
yangguo committed
2846
  return Bootstrapper::CompileNative(isolate, name, source_code,
2847
                                     arraysize(args), args, EXTENSION_CODE);
2848 2849 2850
}


2851 2852 2853 2854 2855 2856 2857 2858
bool Bootstrapper::CompileExperimentalExtraBuiltin(Isolate* isolate,
                                                   int index) {
  HandleScope scope(isolate);
  Vector<const char> name = ExperimentalExtraNatives::GetScriptName(index);
  Handle<String> source_code =
      isolate->bootstrapper()->SourceLookup<ExperimentalExtraNatives>(index);
  Handle<Object> global = isolate->global_object();
  Handle<Object> binding = isolate->extras_binding_object();
2859 2860
  Handle<Object> extras_utils = isolate->extras_utils_object();
  Handle<Object> args[] = {global, binding, extras_utils};
yangguo's avatar
yangguo committed
2861
  return Bootstrapper::CompileNative(isolate, name, source_code,
2862
                                     arraysize(args), args, EXTENSION_CODE);
2863 2864
}

2865 2866
bool Bootstrapper::CompileNative(Isolate* isolate, Vector<const char> name,
                                 Handle<String> source, int argc,
2867 2868
                                 Handle<Object> argv[],
                                 NativesFlag natives_flag) {
2869
  SuppressDebug compiling_natives(isolate->debug());
2870 2871 2872 2873
  // 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);
2874
  if (check.JsHasOverflowed(1 * KB)) {
2875 2876 2877
    isolate->StackOverflow();
    return false;
  }
2878

2879 2880 2881 2882
  Handle<Context> context(isolate->context());

  Handle<String> script_name =
      isolate->factory()->NewStringFromUtf8(name).ToHandleChecked();
2883 2884 2885 2886 2887
  Handle<SharedFunctionInfo> function_info =
      Compiler::GetSharedFunctionInfoForScript(
          source, script_name, 0, 0, ScriptOriginOptions(), Handle<Object>(),
          context, NULL, NULL, ScriptCompiler::kNoCompileOptions, natives_flag,
          false);
2888
  if (function_info.is_null()) return false;
2889 2890 2891 2892 2893

  DCHECK(context->IsNativeContext());

  Handle<JSFunction> fun =
      isolate->factory()->NewFunctionFromSharedFunctionInfo(function_info,
2894
                                                            context);
yangguo's avatar
yangguo committed
2895
  Handle<Object> receiver = isolate->factory()->undefined_value();
2896 2897 2898 2899 2900 2901 2902 2903 2904

  // For non-extension scripts, run script to get the function wrapper.
  Handle<Object> wrapper;
  if (!Execution::Call(isolate, fun, receiver, 0, NULL).ToHandle(&wrapper)) {
    return false;
  }
  // Then run the function wrapper.
  return !Execution::Call(isolate, Handle<JSFunction>::cast(wrapper), receiver,
                          argc, argv).is_null();
2905 2906 2907
}


2908 2909 2910
bool Genesis::CallUtilsFunction(Isolate* isolate, const char* name) {
  Handle<JSObject> utils =
      Handle<JSObject>::cast(isolate->natives_utils_object());
2911 2912
  Handle<String> name_string =
      isolate->factory()->NewStringFromAsciiChecked(name);
2913 2914
  Handle<Object> fun = JSObject::GetDataProperty(utils, name_string);
  Handle<Object> receiver = isolate->factory()->undefined_value();
2915 2916
  Handle<Object> args[] = {utils};
  return !Execution::Call(isolate, fun, receiver, 1, args).is_null();
2917 2918 2919
}


2920
bool Genesis::CompileExtension(Isolate* isolate, v8::Extension* extension) {
2921 2922
  Factory* factory = isolate->factory();
  HandleScope scope(isolate);
2923
  Handle<SharedFunctionInfo> function_info;
2924

2925 2926 2927 2928 2929 2930
  Handle<String> source =
      isolate->factory()
          ->NewExternalStringFromOneByte(extension->source())
          .ToHandleChecked();
  DCHECK(source->IsOneByteRepresentation());

2931 2932
  // If we can't find the function in the cache, we compile a new
  // function and insert it into the cache.
2933 2934 2935 2936 2937 2938
  Vector<const char> name = CStrVector(extension->name());
  SourceCodeCache* cache = isolate->bootstrapper()->extensions_cache();
  Handle<Context> context(isolate->context());
  DCHECK(context->IsNativeContext());

  if (!cache->Lookup(name, &function_info)) {
2939 2940
    Handle<String> script_name =
        factory->NewStringFromUtf8(name).ToHandleChecked();
2941
    function_info = Compiler::GetSharedFunctionInfoForScript(
2942 2943
        source, script_name, 0, 0, ScriptOriginOptions(), Handle<Object>(),
        context, extension, NULL, ScriptCompiler::kNoCompileOptions,
2944
        EXTENSION_CODE, false);
2945
    if (function_info.is_null()) return false;
2946
    cache->Add(name, function_info);
2947 2948
  }

2949
  // Set up the function context. Conceptually, we should clone the
2950 2951 2952
  // function before overwriting the context but since we're in a
  // single-threaded environment it is not strictly necessary.
  Handle<JSFunction> fun =
2953
      factory->NewFunctionFromSharedFunctionInfo(function_info, context);
2954

sgjesse@chromium.org's avatar
sgjesse@chromium.org committed
2955
  // Call function using either the runtime object or the global
2956
  // object as the receiver. Provide no parameters.
2957 2958
  Handle<Object> receiver = isolate->global_object();
  return !Execution::Call(isolate, fun, receiver, 0, NULL).is_null();
2959 2960 2961
}


2962 2963 2964 2965
static Handle<JSObject> ResolveBuiltinIdHolder(Handle<Context> native_context,
                                               const char* holder_expr) {
  Isolate* isolate = native_context->GetIsolate();
  Factory* factory = isolate->factory();
2966
  Handle<JSGlobalObject> global(native_context->global_object());
2967 2968 2969 2970 2971 2972 2973 2974
  const char* period_pos = strchr(holder_expr, '.');
  if (period_pos == NULL) {
    return Handle<JSObject>::cast(
        Object::GetPropertyOrElement(
            global, factory->InternalizeUtf8String(holder_expr))
            .ToHandleChecked());
  }
  const char* inner = period_pos + 1;
2975
  DCHECK(!strchr(inner, '.'));
2976 2977 2978
  Vector<const char> property(holder_expr,
                              static_cast<int>(period_pos - holder_expr));
  Handle<String> property_string = factory->InternalizeUtf8String(property);
2979
  DCHECK(!property_string.is_null());
2980
  Handle<JSObject> object = Handle<JSObject>::cast(
2981
      JSReceiver::GetProperty(global, property_string).ToHandleChecked());
2982 2983 2984 2985 2986
  if (strcmp("prototype", inner) == 0) {
    Handle<JSFunction> function = Handle<JSFunction>::cast(object);
    return Handle<JSObject>(JSObject::cast(function->prototype()));
  }
  Handle<String> inner_string = factory->InternalizeUtf8String(inner);
2987
  DCHECK(!inner_string.is_null());
2988
  Handle<Object> value =
2989
      JSReceiver::GetProperty(object, inner_string).ToHandleChecked();
2990 2991 2992
  return Handle<JSObject>::cast(value);
}

2993
void Genesis::ConfigureUtilsObject(GlobalContextType context_type) {
2994 2995 2996 2997 2998 2999 3000 3001 3002 3003 3004 3005 3006 3007 3008 3009 3010 3011 3012 3013 3014 3015 3016 3017 3018 3019 3020
  switch (context_type) {
    // We still need the utils object to find debug functions.
    case DEBUG_CONTEXT:
      return;
    // Expose the natives in global if a valid name for it is specified.
    case FULL_CONTEXT: {
      // We still need the utils object after deserialization.
      if (isolate()->serializer_enabled()) return;
      if (FLAG_expose_natives_as == NULL) break;
      if (strlen(FLAG_expose_natives_as) == 0) break;
      HandleScope scope(isolate());
      Handle<String> natives_key =
          factory()->InternalizeUtf8String(FLAG_expose_natives_as);
      uint32_t dummy_index;
      if (natives_key->AsArrayIndex(&dummy_index)) break;
      Handle<Object> utils = isolate()->natives_utils_object();
      Handle<JSObject> global = isolate()->global_object();
      JSObject::AddProperty(global, natives_key, utils, DONT_ENUM);
      break;
    }
  }

  // The utils object can be removed for cases that reach this point.
  native_context()->set_natives_utils_object(heap()->undefined_value());
}


3021 3022
void Bootstrapper::ExportFromRuntime(Isolate* isolate,
                                     Handle<JSObject> container) {
3023
  Factory* factory = isolate->factory();
3024
  HandleScope scope(isolate);
3025 3026 3027 3028
  Handle<Context> native_context = isolate->native_context();
#define EXPORT_PRIVATE_SYMBOL(NAME)                                       \
  Handle<String> NAME##_name = factory->NewStringFromAsciiChecked(#NAME); \
  JSObject::AddProperty(container, NAME##_name, factory->NAME(), NONE);
3029 3030
  PRIVATE_SYMBOL_LIST(EXPORT_PRIVATE_SYMBOL)
#undef EXPORT_PRIVATE_SYMBOL
3031

3032 3033 3034
#define EXPORT_PUBLIC_SYMBOL(NAME, DESCRIPTION)                           \
  Handle<String> NAME##_name = factory->NewStringFromAsciiChecked(#NAME); \
  JSObject::AddProperty(container, NAME##_name, factory->NAME(), NONE);
3035
  PUBLIC_SYMBOL_LIST(EXPORT_PUBLIC_SYMBOL)
3036
  WELL_KNOWN_SYMBOL_LIST(EXPORT_PUBLIC_SYMBOL)
3037 3038
#undef EXPORT_PUBLIC_SYMBOL

3039 3040 3041 3042
  {
    Handle<JSFunction> to_string = InstallFunction(
        container, "object_to_string", JS_OBJECT_TYPE, JSObject::kHeaderSize,
        MaybeHandle<JSObject>(), Builtins::kObjectProtoToString);
3043
    to_string->shared()->set_internal_formal_parameter_count(0);
3044 3045 3046 3047
    to_string->shared()->set_length(0);
    native_context->set_object_to_string(*to_string);
  }

3048 3049
  Handle<JSObject> iterator_prototype(
      native_context->initial_iterator_prototype());
3050

3051 3052 3053
  JSObject::AddProperty(container,
                        factory->InternalizeUtf8String("IteratorPrototype"),
                        iterator_prototype, NONE);
3054 3055

  {
3056
    PrototypeIterator iter(native_context->sloppy_generator_function_map());
3057 3058
    Handle<JSObject> generator_function_prototype(iter.GetCurrent<JSObject>());

3059 3060 3061
    JSObject::AddProperty(
        container, factory->InternalizeUtf8String("GeneratorFunctionPrototype"),
        generator_function_prototype, NONE);
3062 3063

    static const bool kUseStrictFunctionMap = true;
3064 3065 3066 3067
    Handle<JSFunction> generator_function_function = InstallFunction(
        container, "GeneratorFunction", JS_FUNCTION_TYPE, JSFunction::kSize,
        generator_function_prototype, Builtins::kGeneratorFunctionConstructor,
        kUseStrictFunctionMap);
ishell's avatar
ishell committed
3068 3069
    generator_function_function->set_prototype_or_initial_map(
        native_context->sloppy_generator_function_map());
3070
    generator_function_function->shared()->DontAdaptArguments();
3071
    generator_function_function->shared()->SetConstructStub(
3072 3073
        *isolate->builtins()->GeneratorFunctionConstructor());
    generator_function_function->shared()->set_length(1);
3074 3075 3076
    InstallWithIntrinsicDefaultProto(
        isolate, generator_function_function,
        Context::GENERATOR_FUNCTION_FUNCTION_INDEX);
ishell's avatar
ishell committed
3077

3078 3079
    JSObject::ForceSetPrototype(generator_function_function,
                                isolate->function_function());
3080 3081 3082 3083 3084
    JSObject::AddProperty(
        generator_function_prototype, factory->constructor_string(),
        generator_function_function,
        static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY));

ishell's avatar
ishell committed
3085 3086 3087 3088
    native_context->sloppy_generator_function_map()->SetConstructor(
        *generator_function_function);
    native_context->strict_generator_function_map()->SetConstructor(
        *generator_function_function);
3089 3090 3091 3092 3093
  }

  {  // -- S e t I t e r a t o r
    Handle<JSObject> set_iterator_prototype =
        isolate->factory()->NewJSObject(isolate->object_function(), TENURED);
3094
    JSObject::ForceSetPrototype(set_iterator_prototype, iterator_prototype);
3095 3096 3097
    Handle<JSFunction> set_iterator_function = InstallFunction(
        container, "SetIterator", JS_SET_ITERATOR_TYPE, JSSetIterator::kSize,
        set_iterator_prototype, Builtins::kIllegal);
3098
    native_context->set_set_iterator_map(set_iterator_function->initial_map());
3099 3100 3101 3102 3103
  }

  {  // -- M a p I t e r a t o r
    Handle<JSObject> map_iterator_prototype =
        isolate->factory()->NewJSObject(isolate->object_function(), TENURED);
3104
    JSObject::ForceSetPrototype(map_iterator_prototype, iterator_prototype);
3105 3106 3107
    Handle<JSFunction> map_iterator_function = InstallFunction(
        container, "MapIterator", JS_MAP_ITERATOR_TYPE, JSMapIterator::kSize,
        map_iterator_prototype, Builtins::kIllegal);
3108 3109 3110 3111 3112 3113 3114
    native_context->set_map_iterator_map(map_iterator_function->initial_map());
  }

  {  // -- S c r i p t
    // Builtin functions for Script.
    Handle<JSFunction> script_fun = InstallFunction(
        container, "Script", JS_VALUE_TYPE, JSValue::kSize,
3115
        isolate->initial_object_prototype(), Builtins::kUnsupportedThrower);
3116 3117 3118 3119 3120 3121 3122 3123 3124 3125 3126 3127 3128 3129 3130 3131 3132 3133 3134 3135 3136 3137 3138 3139 3140 3141 3142 3143 3144 3145 3146 3147 3148 3149 3150 3151 3152 3153 3154 3155 3156 3157 3158 3159 3160 3161 3162 3163 3164 3165 3166 3167 3168 3169 3170 3171 3172 3173 3174 3175 3176 3177 3178 3179 3180 3181 3182 3183 3184 3185 3186 3187 3188 3189 3190 3191 3192 3193 3194 3195 3196 3197 3198 3199 3200 3201 3202 3203 3204 3205 3206 3207 3208 3209 3210 3211 3212 3213 3214 3215 3216 3217 3218 3219 3220 3221 3222 3223 3224 3225 3226 3227 3228 3229 3230 3231 3232 3233 3234 3235 3236 3237 3238 3239
    Handle<JSObject> prototype =
        factory->NewJSObject(isolate->object_function(), TENURED);
    Accessors::FunctionSetPrototype(script_fun, prototype).Assert();
    native_context->set_script_function(*script_fun);

    Handle<Map> script_map = Handle<Map>(script_fun->initial_map());
    Map::EnsureDescriptorSlack(script_map, 15);

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

    Handle<AccessorInfo> script_column =
        Accessors::ScriptColumnOffsetInfo(isolate, attribs);
    {
      AccessorConstantDescriptor d(
          Handle<Name>(Name::cast(script_column->name())), script_column,
          attribs);
      script_map->AppendDescriptor(&d);
    }

    Handle<AccessorInfo> script_id = Accessors::ScriptIdInfo(isolate, attribs);
    {
      AccessorConstantDescriptor d(Handle<Name>(Name::cast(script_id->name())),
                                   script_id, attribs);
      script_map->AppendDescriptor(&d);
    }


    Handle<AccessorInfo> script_name =
        Accessors::ScriptNameInfo(isolate, attribs);
    {
      AccessorConstantDescriptor d(
          Handle<Name>(Name::cast(script_name->name())), script_name, attribs);
      script_map->AppendDescriptor(&d);
    }

    Handle<AccessorInfo> script_line =
        Accessors::ScriptLineOffsetInfo(isolate, attribs);
    {
      AccessorConstantDescriptor d(
          Handle<Name>(Name::cast(script_line->name())), script_line, attribs);
      script_map->AppendDescriptor(&d);
    }

    Handle<AccessorInfo> script_source =
        Accessors::ScriptSourceInfo(isolate, attribs);
    {
      AccessorConstantDescriptor d(
          Handle<Name>(Name::cast(script_source->name())), script_source,
          attribs);
      script_map->AppendDescriptor(&d);
    }

    Handle<AccessorInfo> script_type =
        Accessors::ScriptTypeInfo(isolate, attribs);
    {
      AccessorConstantDescriptor d(
          Handle<Name>(Name::cast(script_type->name())), script_type, attribs);
      script_map->AppendDescriptor(&d);
    }

    Handle<AccessorInfo> script_compilation_type =
        Accessors::ScriptCompilationTypeInfo(isolate, attribs);
    {
      AccessorConstantDescriptor d(
          Handle<Name>(Name::cast(script_compilation_type->name())),
          script_compilation_type, attribs);
      script_map->AppendDescriptor(&d);
    }

    Handle<AccessorInfo> script_context_data =
        Accessors::ScriptContextDataInfo(isolate, attribs);
    {
      AccessorConstantDescriptor d(
          Handle<Name>(Name::cast(script_context_data->name())),
          script_context_data, attribs);
      script_map->AppendDescriptor(&d);
    }

    Handle<AccessorInfo> script_eval_from_script =
        Accessors::ScriptEvalFromScriptInfo(isolate, attribs);
    {
      AccessorConstantDescriptor d(
          Handle<Name>(Name::cast(script_eval_from_script->name())),
          script_eval_from_script, attribs);
      script_map->AppendDescriptor(&d);
    }

    Handle<AccessorInfo> script_eval_from_script_position =
        Accessors::ScriptEvalFromScriptPositionInfo(isolate, attribs);
    {
      AccessorConstantDescriptor d(
          Handle<Name>(Name::cast(script_eval_from_script_position->name())),
          script_eval_from_script_position, attribs);
      script_map->AppendDescriptor(&d);
    }

    Handle<AccessorInfo> script_eval_from_function_name =
        Accessors::ScriptEvalFromFunctionNameInfo(isolate, attribs);
    {
      AccessorConstantDescriptor d(
          Handle<Name>(Name::cast(script_eval_from_function_name->name())),
          script_eval_from_function_name, attribs);
      script_map->AppendDescriptor(&d);
    }

    Handle<AccessorInfo> script_source_url =
        Accessors::ScriptSourceUrlInfo(isolate, attribs);
    {
      AccessorConstantDescriptor d(
          Handle<Name>(Name::cast(script_source_url->name())),
          script_source_url, attribs);
      script_map->AppendDescriptor(&d);
    }

    Handle<AccessorInfo> script_source_mapping_url =
        Accessors::ScriptSourceMappingUrlInfo(isolate, attribs);
    {
      AccessorConstantDescriptor d(
          Handle<Name>(Name::cast(script_source_mapping_url->name())),
          script_source_mapping_url, attribs);
      script_map->AppendDescriptor(&d);
    }

3240 3241 3242 3243 3244 3245 3246 3247 3248 3249
    {
      PrototypeIterator iter(native_context->sloppy_async_function_map());
      Handle<JSObject> async_function_prototype(iter.GetCurrent<JSObject>());

      static const bool kUseStrictFunctionMap = true;
      Handle<JSFunction> async_function_constructor = InstallFunction(
          container, "AsyncFunction", JS_FUNCTION_TYPE, JSFunction::kSize,
          async_function_prototype, Builtins::kAsyncFunctionConstructor,
          kUseStrictFunctionMap);
      async_function_constructor->shared()->DontAdaptArguments();
3250
      async_function_constructor->shared()->SetConstructStub(
3251 3252 3253 3254
          *isolate->builtins()->AsyncFunctionConstructor());
      async_function_constructor->shared()->set_length(1);
      InstallWithIntrinsicDefaultProto(isolate, async_function_constructor,
                                       Context::ASYNC_FUNCTION_FUNCTION_INDEX);
3255 3256
      JSObject::ForceSetPrototype(async_function_constructor,
                                  isolate->function_function());
3257 3258 3259 3260 3261 3262 3263 3264 3265 3266 3267

      JSObject::AddProperty(
          async_function_prototype, factory->constructor_string(),
          async_function_constructor,
          static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY));

      JSFunction::SetPrototype(async_function_constructor,
                               async_function_prototype);

      Handle<JSFunction> async_function_next =
          SimpleInstallFunction(container, "AsyncFunctionNext",
3268
                                Builtins::kGeneratorPrototypeNext, 1, true);
3269 3270
      Handle<JSFunction> async_function_throw =
          SimpleInstallFunction(container, "AsyncFunctionThrow",
3271 3272 3273
                                Builtins::kGeneratorPrototypeThrow, 1, true);
      async_function_next->shared()->set_native(false);
      async_function_throw->shared()->set_native(false);
3274
    }
3275
  }
3276 3277 3278 3279

  {  // -- C a l l S i t e
    // Builtin functions for CallSite.

3280 3281 3282 3283
    // CallSites are a special case; the constructor is for our private use
    // only, therefore we set it up as a builtin that throws. Internally, we use
    // CallSiteUtils::Construct to create CallSite objects.

3284 3285
    Handle<JSFunction> callsite_fun = InstallFunction(
        container, "CallSite", JS_OBJECT_TYPE, JSObject::kHeaderSize,
3286
        isolate->initial_object_prototype(), Builtins::kUnsupportedThrower);
3287
    callsite_fun->shared()->DontAdaptArguments();
jgruber's avatar
jgruber committed
3288 3289
    isolate->native_context()->set_callsite_function(*callsite_fun);

3290 3291 3292 3293 3294 3295 3296 3297 3298 3299 3300 3301 3302 3303 3304 3305 3306 3307 3308 3309 3310 3311 3312 3313 3314 3315 3316
    {
      Handle<JSObject> proto =
          factory->NewJSObject(isolate->object_function(), TENURED);
      JSObject::AddProperty(proto, factory->constructor_string(), callsite_fun,
                            DONT_ENUM);

      struct FunctionInfo {
        const char* name;
        Builtins::Name id;
      };

      FunctionInfo infos[] = {
          {"getColumnNumber", Builtins::kCallSitePrototypeGetColumnNumber},
          {"getEvalOrigin", Builtins::kCallSitePrototypeGetEvalOrigin},
          {"getFileName", Builtins::kCallSitePrototypeGetFileName},
          {"getFunction", Builtins::kCallSitePrototypeGetFunction},
          {"getFunctionName", Builtins::kCallSitePrototypeGetFunctionName},
          {"getLineNumber", Builtins::kCallSitePrototypeGetLineNumber},
          {"getMethodName", Builtins::kCallSitePrototypeGetMethodName},
          {"getPosition", Builtins::kCallSitePrototypeGetPosition},
          {"getScriptNameOrSourceURL",
           Builtins::kCallSitePrototypeGetScriptNameOrSourceURL},
          {"getThis", Builtins::kCallSitePrototypeGetThis},
          {"getTypeName", Builtins::kCallSitePrototypeGetTypeName},
          {"isConstructor", Builtins::kCallSitePrototypeIsConstructor},
          {"isEval", Builtins::kCallSitePrototypeIsEval},
          {"isNative", Builtins::kCallSitePrototypeIsNative},
3317 3318
          {"isToplevel", Builtins::kCallSitePrototypeIsToplevel},
          {"toString", Builtins::kCallSitePrototypeToString}};
3319 3320 3321 3322 3323 3324

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

      Handle<JSFunction> fun;
      for (const FunctionInfo& info : infos) {
3325
        SimpleInstallFunction(proto, info.name, info.id, 0, true, attrs);
3326 3327 3328 3329 3330
      }

      Accessors::FunctionSetPrototype(callsite_fun, proto).Assert();
    }
  }
3331
}
3332

3333

3334 3335 3336 3337
void Bootstrapper::ExportExperimentalFromRuntime(Isolate* isolate,
                                                 Handle<JSObject> container) {
  HandleScope scope(isolate);

3338
#ifdef V8_I18N_SUPPORT
3339 3340 3341 3342 3343 3344
#define INITIALIZE_FLAG(FLAG)                                         \
  {                                                                   \
    Handle<String> name =                                             \
        isolate->factory()->NewStringFromAsciiChecked(#FLAG);         \
    JSObject::AddProperty(container, name,                            \
                          isolate->factory()->ToBoolean(FLAG), NONE); \
3345 3346 3347
  }

#undef INITIALIZE_FLAG
3348
#endif
3349 3350 3351
}


3352 3353 3354
#define EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(id) \
  void Genesis::InitializeGlobal_##id() {}

3355
EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_do_expressions)
3356
EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_regexp_lookbehind)
3357
EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_regexp_named_captures)
3358
EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_regexp_property)
3359
EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_function_sent)
ishell's avatar
ishell committed
3360
EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_tailcalls)
3361
EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_string_padding)
3362
#ifdef V8_I18N_SUPPORT
3363
EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(datetime_format_to_parts)
3364 3365
EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(icu_case_mapping)
#endif
3366
EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_async_await)
3367
EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_restrictive_generators)
3368
EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_trailing_commas)
3369
EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_class_fields)
3370

3371 3372 3373 3374 3375 3376 3377 3378 3379 3380 3381 3382 3383 3384
void InstallPublicSymbol(Factory* factory, Handle<Context> native_context,
                         const char* name, Handle<Symbol> value) {
  Handle<JSGlobalObject> global(
      JSGlobalObject::cast(native_context->global_object()));
  Handle<String> symbol_string = factory->InternalizeUtf8String("Symbol");
  Handle<JSObject> symbol = Handle<JSObject>::cast(
      JSObject::GetProperty(global, symbol_string).ToHandleChecked());
  Handle<String> name_string = factory->InternalizeUtf8String(name);
  PropertyAttributes attributes =
      static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY);
  JSObject::AddProperty(symbol, name_string, value, attributes);
}


binji's avatar
binji committed
3385 3386 3387
void Genesis::InitializeGlobal_harmony_sharedarraybuffer() {
  if (!FLAG_harmony_sharedarraybuffer) return;

3388
  Handle<JSGlobalObject> global(native_context()->global_object());
3389 3390 3391
  Isolate* isolate = global->GetIsolate();
  Factory* factory = isolate->factory();

3392
  Handle<JSFunction> shared_array_buffer_fun =
3393 3394 3395
      InstallArrayBuffer(global, "SharedArrayBuffer",
                         Builtins::kSharedArrayBufferPrototypeGetByteLength,
                         BuiltinFunctionId::kSharedArrayBufferByteLength);
binji's avatar
binji committed
3396
  native_context()->set_shared_array_buffer_fun(*shared_array_buffer_fun);
3397 3398 3399 3400 3401 3402 3403 3404 3405 3406 3407

  Handle<String> name = factory->InternalizeUtf8String("Atomics");
  Handle<JSFunction> cons = factory->NewFunction(name);
  JSFunction::SetInstancePrototype(
      cons,
      Handle<Object>(native_context()->initial_object_prototype(), isolate));
  Handle<JSObject> atomics_object = factory->NewJSObject(cons, TENURED);
  DCHECK(atomics_object->IsJSObject());
  JSObject::AddProperty(global, name, atomics_object, DONT_ENUM);

  SimpleInstallFunction(atomics_object, factory->InternalizeUtf8String("load"),
3408
                        Builtins::kAtomicsLoad, 2, true);
3409 3410
  SimpleInstallFunction(atomics_object, factory->InternalizeUtf8String("store"),
                        Builtins::kAtomicsStore, 3, true);
binji's avatar
binji committed
3411 3412 3413
}


3414
void Genesis::InitializeGlobal_harmony_simd() {
3415 3416
  if (!FLAG_harmony_simd) return;

3417 3418 3419 3420 3421 3422 3423 3424 3425 3426
  Handle<JSGlobalObject> global(
      JSGlobalObject::cast(native_context()->global_object()));
  Isolate* isolate = global->GetIsolate();
  Factory* factory = isolate->factory();

  Handle<String> name = factory->InternalizeUtf8String("SIMD");
  Handle<JSFunction> cons = factory->NewFunction(name);
  JSFunction::SetInstancePrototype(
      cons,
      Handle<Object>(native_context()->initial_object_prototype(), isolate));
3427
  cons->shared()->set_instance_class_name(*name);
3428 3429 3430 3431
  Handle<JSObject> simd_object = factory->NewJSObject(cons, TENURED);
  DCHECK(simd_object->IsJSObject());
  JSObject::AddProperty(global, name, simd_object, DONT_ENUM);

3432
// Install SIMD type functions. Set the instance class names since
3433
// InstallFunction only does this when we install on the JSGlobalObject.
3434
#define SIMD128_INSTALL_FUNCTION(TYPE, Type, type, lane_count, lane_type) \
3435
  Handle<JSFunction> type##_function = InstallFunction(                   \
3436 3437 3438
      simd_object, #Type, JS_VALUE_TYPE, JSValue::kSize,                  \
      isolate->initial_object_prototype(), Builtins::kIllegal);           \
  native_context()->set_##type##_function(*type##_function);              \
3439
  type##_function->shared()->set_instance_class_name(*factory->Type##_string());
3440
  SIMD128_TYPES(SIMD128_INSTALL_FUNCTION)
3441
#undef SIMD128_INSTALL_FUNCTION
3442 3443 3444
}


3445 3446 3447 3448 3449 3450 3451 3452 3453 3454 3455 3456 3457 3458 3459 3460 3461 3462 3463 3464
void Genesis::InitializeGlobal_harmony_array_prototype_values() {
  if (!FLAG_harmony_array_prototype_values) return;
  Handle<JSFunction> array_constructor(native_context()->array_function());
  Handle<JSObject> array_prototype(
      JSObject::cast(array_constructor->instance_prototype()));
  Handle<Object> values_iterator =
      JSObject::GetProperty(array_prototype, factory()->iterator_symbol())
          .ToHandleChecked();
  DCHECK(values_iterator->IsJSFunction());
  JSObject::AddProperty(array_prototype, factory()->values_string(),
                        values_iterator, DONT_ENUM);

  Handle<Object> unscopables =
      JSObject::GetProperty(array_prototype, factory()->unscopables_symbol())
          .ToHandleChecked();
  DCHECK(unscopables->IsJSObject());
  JSObject::AddProperty(Handle<JSObject>::cast(unscopables),
                        factory()->values_string(), factory()->true_value(),
                        NONE);
}
3465

3466
Handle<JSFunction> Genesis::InstallArrayBuffer(Handle<JSObject> target,
3467 3468 3469
                                               const char* name,
                                               Builtins::Name call,
                                               BuiltinFunctionId id) {
3470
  // Create the %ArrayBufferPrototype%
3471 3472 3473 3474 3475 3476 3477 3478 3479 3480 3481 3482
  // Setup the {prototype} with the given {name} for @@toStringTag.
  Handle<JSObject> prototype =
      factory()->NewJSObject(isolate()->object_function(), TENURED);
  JSObject::AddProperty(prototype, factory()->to_string_tag_symbol(),
                        factory()->NewStringFromAsciiChecked(name),
                        static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY));

  // Allocate the constructor with the given {prototype}.
  Handle<JSFunction> array_buffer_fun =
      InstallFunction(target, name, JS_ARRAY_BUFFER_TYPE,
                      JSArrayBuffer::kSizeWithInternalFields, prototype,
                      Builtins::kArrayBufferConstructor);
3483
  array_buffer_fun->shared()->SetConstructStub(
3484 3485 3486 3487 3488 3489 3490 3491 3492 3493 3494
      *isolate()->builtins()->ArrayBufferConstructor_ConstructStub());
  array_buffer_fun->shared()->DontAdaptArguments();
  array_buffer_fun->shared()->set_length(1);

  // Install the "constructor" property on the {prototype}.
  JSObject::AddProperty(prototype, factory()->constructor_string(),
                        array_buffer_fun, DONT_ENUM);

  SimpleInstallFunction(array_buffer_fun, factory()->isView_string(),
                        Builtins::kArrayBufferIsView, 1, true);

3495
  // Install the "byteLength" getter on the {prototype}.
3496 3497
  SimpleInstallGetter(prototype, factory()->byte_length_string(), call, false,
                      id);
3498

3499 3500 3501 3502
  return array_buffer_fun;
}


3503 3504 3505
Handle<JSFunction> Genesis::InstallInternalArray(Handle<JSObject> target,
                                                 const char* name,
                                                 ElementsKind elements_kind) {
3506 3507 3508 3509 3510 3511 3512 3513
  // --- 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);
3514
  Handle<JSFunction> array_function =
3515 3516
      InstallFunction(target, name, JS_ARRAY_TYPE, JSArray::kSize, prototype,
                      Builtins::kInternalArrayCode);
3517

3518
  InternalArrayConstructorStub internal_array_constructor_stub(isolate());
3519
  Handle<Code> code = internal_array_constructor_stub.GetCode();
3520
  array_function->shared()->SetConstructStub(*code);
3521 3522
  array_function->shared()->DontAdaptArguments();

3523
  Handle<Map> original_map(array_function->initial_map());
3524
  Handle<Map> initial_map = Map::Copy(original_map, "InternalArray");
3525
  initial_map->set_elements_kind(elements_kind);
3526
  JSFunction::SetInitialMap(array_function, initial_map, prototype);
3527 3528

  // Make "length" magic on instances.
3529
  Map::EnsureDescriptorSlack(initial_map, 1);
3530 3531 3532 3533

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

3534 3535
  Handle<AccessorInfo> array_length =
      Accessors::ArrayLengthInfo(isolate(), attribs);
3536
  {  // Add length.
3537 3538
    AccessorConstantDescriptor d(Handle<Name>(Name::cast(array_length->name())),
                                 array_length, attribs);
3539
    initial_map->AppendDescriptor(&d);
3540 3541 3542 3543 3544
  }

  return array_function;
}

3545
bool Genesis::InstallNatives(GlobalContextType context_type) {
3546
  HandleScope scope(isolate());
3547

3548 3549 3550 3551 3552
  // Set up the utils object as shared container between native scripts.
  Handle<JSObject> utils = factory()->NewJSObject(isolate()->object_function());
  JSObject::NormalizeProperties(utils, CLEAR_INOBJECT_PROPERTIES, 16,
                                "utils container for native scripts");
  native_context()->set_natives_utils_object(*utils);
3553

3554 3555 3556 3557 3558 3559 3560 3561
  // Set up the extras utils object as a shared container between native
  // scripts and extras. (Extras consume things added there by native scripts.)
  Handle<JSObject> extras_utils =
      factory()->NewJSObject(isolate()->object_function());
  native_context()->set_extras_utils_object(*extras_utils);

  InstallInternalArray(extras_utils, "InternalPackedArray", FAST_ELEMENTS);

3562 3563 3564
  InstallFunction(extras_utils, isolate()->promise_resolve(),
                  factory()->NewStringFromAsciiChecked("resolvePromise"));

3565 3566 3567 3568 3569 3570 3571
  int builtin_index = Natives::GetDebuggerCount();
  // Only run prologue.js and runtime.js at this point.
  DCHECK_EQ(builtin_index, Natives::GetIndex("prologue"));
  if (!Bootstrapper::CompileBuiltin(isolate(), builtin_index++)) return false;
  DCHECK_EQ(builtin_index, Natives::GetIndex("runtime"));
  if (!Bootstrapper::CompileBuiltin(isolate(), builtin_index++)) return false;

3572 3573 3574 3575
  {
    // 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.
3576 3577
    Handle<JSFunction> opaque_reference_fun = factory()->NewFunction(
        factory()->empty_string(), isolate()->builtins()->Illegal(),
3578
        isolate()->initial_object_prototype(), JS_VALUE_TYPE, JSValue::kSize);
3579
    Handle<JSObject> prototype =
3580
        factory()->NewJSObject(isolate()->object_function(), TENURED);
3581
    Accessors::FunctionSetPrototype(opaque_reference_fun, prototype).Assert();
3582
    native_context()->set_opaque_reference_function(*opaque_reference_fun);
3583
  }
3584

3585 3586 3587 3588 3589 3590
  // 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.
  {
3591
    HandleScope scope(isolate());
3592 3593 3594 3595
    Handle<JSObject> utils =
        Handle<JSObject>::cast(isolate()->natives_utils_object());
    Handle<JSFunction> array_function =
        InstallInternalArray(utils, "InternalArray", FAST_HOLEY_ELEMENTS);
3596
    native_context()->set_internal_array_function(*array_function);
3597
    InstallInternalArray(utils, "InternalPackedArray", FAST_ELEMENTS);
3598 3599
  }

3600 3601 3602
  // Run the rest of the native scripts.
  while (builtin_index < Natives::GetBuiltinsCount()) {
    if (!Bootstrapper::CompileBuiltin(isolate(), builtin_index++)) return false;
3603 3604
  }

3605
  if (!CallUtilsFunction(isolate(), "PostNatives")) return false;
3606 3607 3608 3609
  auto fast_template_instantiations_cache = isolate()->factory()->NewFixedArray(
      TemplateInfo::kFastTemplateInstantiationsCacheSize);
  native_context()->set_fast_template_instantiations_cache(
      *fast_template_instantiations_cache);
3610

3611
  auto slow_template_instantiations_cache = UnseededNumberDictionary::New(
3612
      isolate(), ApiNatives::kInitialFunctionCacheSize);
3613 3614
  native_context()->set_slow_template_instantiations_cache(
      *slow_template_instantiations_cache);
3615

3616 3617 3618 3619 3620 3621 3622 3623
  // Store the map for the %ObjectPrototype% after the natives has been compiled
  // and the Object function has been set up.
  Handle<JSFunction> object_function(native_context()->object_function());
  DCHECK(JSObject::cast(object_function->initial_map()->prototype())
             ->HasFastProperties());
  native_context()->set_object_function_prototype_map(
      HeapObject::cast(object_function->initial_map()->prototype())->map());

3624
  // Set up the map for Object.create(null) instances.
3625
  Handle<Map> slow_object_with_null_prototype_map =
3626
      Map::CopyInitialMap(handle(object_function->initial_map(), isolate()));
3627 3628
  slow_object_with_null_prototype_map->set_dictionary_map(true);
  Map::SetPrototype(slow_object_with_null_prototype_map,
3629
                    isolate()->factory()->null_value());
3630 3631
  native_context()->set_slow_object_with_null_prototype_map(
      *slow_object_with_null_prototype_map);
3632

3633
  // Store the map for the %StringPrototype% after the natives has been compiled
3634
  // and the String function has been set up.
3635
  Handle<JSFunction> string_function(native_context()->string_function());
3636
  DCHECK(JSObject::cast(
3637
      string_function->initial_map()->prototype())->HasFastProperties());
3638
  native_context()->set_string_function_prototype_map(
3639 3640
      HeapObject::cast(string_function->initial_map()->prototype())->map());

3641 3642 3643
  Handle<JSGlobalObject> global_object =
      handle(native_context()->global_object());

3644 3645
  // Install Global.decodeURI.
  SimpleInstallFunction(global_object, "decodeURI", Builtins::kGlobalDecodeURI,
3646
                        1, false, kGlobalDecodeURI);
3647 3648 3649

  // Install Global.decodeURIComponent.
  SimpleInstallFunction(global_object, "decodeURIComponent",
3650 3651
                        Builtins::kGlobalDecodeURIComponent, 1, false,
                        kGlobalDecodeURIComponent);
3652

3653 3654
  // Install Global.encodeURI.
  SimpleInstallFunction(global_object, "encodeURI", Builtins::kGlobalEncodeURI,
3655
                        1, false, kGlobalEncodeURI);
3656 3657 3658

  // Install Global.encodeURIComponent.
  SimpleInstallFunction(global_object, "encodeURIComponent",
3659 3660
                        Builtins::kGlobalEncodeURIComponent, 1, false,
                        kGlobalEncodeURIComponent);
3661

3662 3663
  // Install Global.escape.
  SimpleInstallFunction(global_object, "escape", Builtins::kGlobalEscape, 1,
3664
                        false, kGlobalEscape);
3665 3666 3667

  // Install Global.unescape.
  SimpleInstallFunction(global_object, "unescape", Builtins::kGlobalUnescape, 1,
3668
                        false, kGlobalUnescape);
3669

3670 3671
  // Install Global.eval.
  {
3672 3673 3674
    Handle<JSFunction> eval =
        SimpleInstallFunction(global_object, factory()->eval_string(),
                              Builtins::kGlobalEval, 1, false);
3675 3676 3677
    native_context()->set_global_eval_fun(*eval);
  }

3678 3679 3680 3681 3682 3683 3684 3685
  // Install Global.isFinite
  SimpleInstallFunction(global_object, "isFinite", Builtins::kGlobalIsFinite, 1,
                        true, kGlobalIsFinite);

  // Install Global.isNaN
  SimpleInstallFunction(global_object, "isNaN", Builtins::kGlobalIsNaN, 1, true,
                        kGlobalIsNaN);

3686 3687 3688 3689 3690 3691 3692 3693 3694 3695 3696 3697 3698 3699 3700 3701 3702 3703 3704 3705 3706 3707 3708 3709 3710 3711 3712 3713 3714 3715 3716 3717 3718 3719
  // Install Array.prototype.concat
  {
    Handle<JSFunction> array_constructor(native_context()->array_function());
    Handle<JSObject> proto(JSObject::cast(array_constructor->prototype()));
    Handle<JSFunction> concat =
        InstallFunction(proto, "concat", JS_OBJECT_TYPE, JSObject::kHeaderSize,
                        MaybeHandle<JSObject>(), Builtins::kArrayConcat);

    // Make sure that Array.prototype.concat appears to be compiled.
    // The code will never be called, but inline caching for call will
    // only work if it appears to be compiled.
    concat->shared()->DontAdaptArguments();
    DCHECK(concat->is_compiled());
    // Set the lengths for the functions to satisfy ECMA-262.
    concat->shared()->set_length(1);
  }

  // Install InternalArray.prototype.concat
  {
    Handle<JSFunction> array_constructor(
        native_context()->internal_array_function());
    Handle<JSObject> proto(JSObject::cast(array_constructor->prototype()));
    Handle<JSFunction> concat =
        InstallFunction(proto, "concat", JS_OBJECT_TYPE, JSObject::kHeaderSize,
                        MaybeHandle<JSObject>(), Builtins::kArrayConcat);

    // Make sure that InternalArray.prototype.concat appears to be compiled.
    // The code will never be called, but inline caching for call will
    // only work if it appears to be compiled.
    concat->shared()->DontAdaptArguments();
    DCHECK(concat->is_compiled());
    // Set the lengths for the functions to satisfy ECMA-262.
    concat->shared()->set_length(1);
  }
3720

3721 3722
  InstallBuiltinFunctionIds();

3723 3724 3725 3726 3727 3728 3729 3730 3731 3732 3733 3734 3735 3736 3737 3738 3739 3740 3741 3742 3743 3744 3745 3746 3747 3748 3749 3750 3751 3752 3753 3754 3755 3756 3757
  // Create a map for accessor property descriptors (a variant of JSObject
  // that predefines four properties get, set, configurable and enumerable).
  {
    // AccessorPropertyDescriptor initial map.
    Handle<Map> map =
        factory()->NewMap(JS_OBJECT_TYPE, JSAccessorPropertyDescriptor::kSize);
    // Create the descriptor array for the property descriptor object.
    Map::EnsureDescriptorSlack(map, 4);

    {  // get
      DataDescriptor d(factory()->get_string(),
                       JSAccessorPropertyDescriptor::kGetIndex, NONE,
                       Representation::Tagged());
      map->AppendDescriptor(&d);
    }
    {  // set
      DataDescriptor d(factory()->set_string(),
                       JSAccessorPropertyDescriptor::kSetIndex, NONE,
                       Representation::Tagged());
      map->AppendDescriptor(&d);
    }
    {  // enumerable
      DataDescriptor d(factory()->enumerable_string(),
                       JSAccessorPropertyDescriptor::kEnumerableIndex, NONE,
                       Representation::Tagged());
      map->AppendDescriptor(&d);
    }
    {  // configurable
      DataDescriptor d(factory()->configurable_string(),
                       JSAccessorPropertyDescriptor::kConfigurableIndex, NONE,
                       Representation::Tagged());
      map->AppendDescriptor(&d);
    }

    Map::SetPrototype(map, isolate()->initial_object_prototype());
3758
    map->SetConstructor(native_context()->object_function());
3759 3760 3761 3762 3763 3764 3765 3766 3767 3768 3769 3770 3771 3772 3773 3774 3775 3776 3777 3778 3779 3780 3781 3782 3783 3784 3785 3786 3787 3788 3789 3790 3791 3792 3793 3794 3795 3796 3797 3798 3799 3800
    map->SetInObjectProperties(4);
    map->set_unused_property_fields(0);

    native_context()->set_accessor_property_descriptor_map(*map);
  }

  // Create a map for data property descriptors (a variant of JSObject
  // that predefines four properties value, writable, configurable and
  // enumerable).
  {
    // DataPropertyDescriptor initial map.
    Handle<Map> map =
        factory()->NewMap(JS_OBJECT_TYPE, JSDataPropertyDescriptor::kSize);
    // Create the descriptor array for the property descriptor object.
    Map::EnsureDescriptorSlack(map, 4);

    {  // value
      DataDescriptor d(factory()->value_string(),
                       JSDataPropertyDescriptor::kValueIndex, NONE,
                       Representation::Tagged());
      map->AppendDescriptor(&d);
    }
    {  // writable
      DataDescriptor d(factory()->writable_string(),
                       JSDataPropertyDescriptor::kWritableIndex, NONE,
                       Representation::Tagged());
      map->AppendDescriptor(&d);
    }
    {  // enumerable
      DataDescriptor d(factory()->enumerable_string(),
                       JSDataPropertyDescriptor::kEnumerableIndex, NONE,
                       Representation::Tagged());
      map->AppendDescriptor(&d);
    }
    {  // configurable
      DataDescriptor d(factory()->configurable_string(),
                       JSDataPropertyDescriptor::kConfigurableIndex, NONE,
                       Representation::Tagged());
      map->AppendDescriptor(&d);
    }

    Map::SetPrototype(map, isolate()->initial_object_prototype());
3801
    map->SetConstructor(native_context()->object_function());
3802 3803 3804 3805 3806 3807
    map->SetInObjectProperties(4);
    map->set_unused_property_fields(0);

    native_context()->set_data_property_descriptor_map(*map);
  }

3808 3809 3810 3811 3812 3813
  // 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.
3814
    Handle<JSFunction> array_constructor(native_context()->array_function());
3815 3816 3817 3818 3819
    Handle<JSObject> array_prototype(
        JSObject::cast(array_constructor->instance_prototype()));

    // Add initial map.
    Handle<Map> initial_map =
3820
        factory()->NewMap(JS_ARRAY_TYPE, JSRegExpResult::kSize);
3821
    initial_map->SetConstructor(*array_constructor);
3822 3823 3824

    // Set prototype on map.
    initial_map->set_non_instance_prototype(false);
3825
    Map::SetPrototype(initial_map, array_prototype);
3826 3827

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

3830
    {
3831
      JSFunction* array_function = native_context()->array_function();
3832 3833
      Handle<DescriptorArray> array_descriptors(
          array_function->initial_map()->instance_descriptors());
3834
      Handle<String> length = factory()->length_string();
3835
      int old = array_descriptors->SearchWithCache(
3836
          isolate(), *length, array_function->initial_map());
3837
      DCHECK(old != DescriptorArray::kNotFound);
3838 3839 3840
      AccessorConstantDescriptor desc(
          length, handle(array_descriptors->GetValue(old), isolate()),
          array_descriptors->GetDetails(old).attributes());
3841
      initial_map->AppendDescriptor(&desc);
3842
    }
3843
    {
3844 3845 3846
      DataDescriptor index_field(factory()->index_string(),
                                 JSRegExpResult::kIndexIndex, NONE,
                                 Representation::Tagged());
3847
      initial_map->AppendDescriptor(&index_field);
3848 3849 3850
    }

    {
3851 3852 3853
      DataDescriptor input_field(factory()->input_string(),
                                 JSRegExpResult::kInputIndex, NONE,
                                 Representation::Tagged());
3854
      initial_map->AppendDescriptor(&input_field);
3855 3856
    }

3857
    initial_map->SetInObjectProperties(2);
3858 3859
    initial_map->set_unused_property_fields(0);

3860
    native_context()->set_regexp_result_map(*initial_map);
3861 3862
  }

3863 3864 3865 3866 3867 3868
  // Add @@iterator method to the arguments object maps.
  {
    PropertyAttributes attribs = DONT_ENUM;
    Handle<AccessorInfo> arguments_iterator =
        Accessors::ArgumentsIteratorInfo(isolate(), attribs);
    {
3869 3870
      AccessorConstantDescriptor d(factory()->iterator_symbol(),
                                   arguments_iterator, attribs);
3871 3872 3873 3874 3875
      Handle<Map> map(native_context()->sloppy_arguments_map());
      Map::EnsureDescriptorSlack(map, 1);
      map->AppendDescriptor(&d);
    }
    {
3876 3877
      AccessorConstantDescriptor d(factory()->iterator_symbol(),
                                   arguments_iterator, attribs);
3878 3879 3880 3881 3882 3883 3884 3885
      Handle<Map> map(native_context()->fast_aliased_arguments_map());
      Map::EnsureDescriptorSlack(map, 1);
      map->AppendDescriptor(&d);
    }
    {
      AccessorConstantDescriptor d(factory()->iterator_symbol(),
                                   arguments_iterator, attribs);
      Handle<Map> map(native_context()->slow_aliased_arguments_map());
3886 3887 3888 3889
      Map::EnsureDescriptorSlack(map, 1);
      map->AppendDescriptor(&d);
    }
    {
3890 3891
      AccessorConstantDescriptor d(factory()->iterator_symbol(),
                                   arguments_iterator, attribs);
3892 3893 3894 3895 3896 3897
      Handle<Map> map(native_context()->strict_arguments_map());
      Map::EnsureDescriptorSlack(map, 1);
      map->AppendDescriptor(&d);
    }
  }

3898 3899 3900 3901
  return true;
}


3902
bool Genesis::InstallExperimentalNatives() {
ishell's avatar
ishell committed
3903
  static const char* harmony_tailcalls_natives[] = {nullptr};
binji's avatar
binji committed
3904
  static const char* harmony_sharedarraybuffer_natives[] = {
3905
      "native harmony-atomics.js", NULL};
3906 3907
  static const char* harmony_simd_natives[] = {"native harmony-simd.js",
                                               nullptr};
3908
  static const char* harmony_do_expressions_natives[] = {nullptr};
3909
  static const char* harmony_regexp_lookbehind_natives[] = {nullptr};
3910
  static const char* harmony_regexp_named_captures_natives[] = {nullptr};
3911
  static const char* harmony_regexp_property_natives[] = {nullptr};
3912
  static const char* harmony_function_sent_natives[] = {nullptr};
3913
  static const char* harmony_array_prototype_values_natives[] = {nullptr};
3914 3915
  static const char* harmony_string_padding_natives[] = {
      "native harmony-string-padding.js", nullptr};
3916 3917 3918
#ifdef V8_I18N_SUPPORT
  static const char* icu_case_mapping_natives[] = {"native icu-case-mapping.js",
                                                   nullptr};
3919 3920
  static const char* datetime_format_to_parts_natives[] = {
      "native datetime-format-to-parts.js", nullptr};
3921
#endif
3922
  static const char* harmony_async_await_natives[] = {nullptr};
3923
  static const char* harmony_restrictive_generators_natives[] = {nullptr};
3924
  static const char* harmony_trailing_commas_natives[] = {nullptr};
3925
  static const char* harmony_class_fields_natives[] = {nullptr};
3926

3927
  for (int i = ExperimentalNatives::GetDebuggerCount();
3928
       i < ExperimentalNatives::GetBuiltinsCount(); i++) {
3929 3930 3931 3932 3933 3934
#define INSTALL_EXPERIMENTAL_NATIVES(id, desc)                                \
  if (FLAG_##id) {                                                            \
    for (size_t j = 0; id##_natives[j] != NULL; j++) {                        \
      Vector<const char> script_name = ExperimentalNatives::GetScriptName(i); \
      if (strncmp(script_name.start(), id##_natives[j],                       \
                  script_name.length()) == 0) {                               \
3935 3936 3937
        if (!Bootstrapper::CompileExperimentalBuiltin(isolate(), i)) {        \
          return false;                                                       \
        }                                                                     \
3938 3939
      }                                                                       \
    }                                                                         \
3940
  }
3941 3942
    HARMONY_INPROGRESS(INSTALL_EXPERIMENTAL_NATIVES);
    HARMONY_STAGED(INSTALL_EXPERIMENTAL_NATIVES);
3943
    HARMONY_SHIPPING(INSTALL_EXPERIMENTAL_NATIVES);
3944 3945 3946
#undef INSTALL_EXPERIMENTAL_NATIVES
  }

3947
  if (!CallUtilsFunction(isolate(), "PostExperimentals")) return false;
3948

binji's avatar
binji committed
3949
  InstallExperimentalBuiltinFunctionIds();
3950 3951 3952 3953
  return true;
}


3954
bool Genesis::InstallExtraNatives() {
3955 3956 3957 3958 3959 3960
  HandleScope scope(isolate());

  Handle<JSObject> extras_binding =
      factory()->NewJSObject(isolate()->object_function());
  native_context()->set_extras_binding_object(*extras_binding);

3961 3962
  for (int i = ExtraNatives::GetDebuggerCount();
       i < ExtraNatives::GetBuiltinsCount(); i++) {
3963 3964 3965 3966 3967 3968 3969
    if (!Bootstrapper::CompileExtraBuiltin(isolate(), i)) return false;
  }

  return true;
}


3970 3971 3972 3973 3974 3975 3976 3977 3978 3979 3980
bool Genesis::InstallExperimentalExtraNatives() {
  for (int i = ExperimentalExtraNatives::GetDebuggerCount();
       i < ExperimentalExtraNatives::GetBuiltinsCount(); i++) {
    if (!Bootstrapper::CompileExperimentalExtraBuiltin(isolate(), i))
      return false;
  }

  return true;
}


3981 3982 3983 3984 3985 3986 3987 3988
bool Genesis::InstallDebuggerNatives() {
  for (int i = 0; i < Natives::GetDebuggerCount(); ++i) {
    if (!Bootstrapper::CompileBuiltin(isolate(), i)) return false;
  }
  return CallUtilsFunction(isolate(), "PostDebug");
}


3989 3990 3991
static void InstallBuiltinFunctionId(Handle<JSObject> holder,
                                     const char* function_name,
                                     BuiltinFunctionId id) {
3992
  Isolate* isolate = holder->GetIsolate();
3993
  Handle<Object> function_object =
3994
      JSReceiver::GetProperty(isolate, holder, function_name).ToHandleChecked();
3995
  Handle<JSFunction> function = Handle<JSFunction>::cast(function_object);
3996
  function->shared()->set_builtin_function_id(id);
3997 3998 3999
}


binji's avatar
binji committed
4000 4001 4002 4003 4004
#define INSTALL_BUILTIN_ID(holder_expr, fun_name, name) \
  { #holder_expr, #fun_name, k##name }                  \
  ,


4005
void Genesis::InstallBuiltinFunctionIds() {
4006
  HandleScope scope(isolate());
4007 4008 4009 4010 4011 4012 4013 4014 4015 4016 4017 4018 4019 4020
  struct BuiltinFunctionIds {
    const char* holder_expr;
    const char* fun_name;
    BuiltinFunctionId id;
  };

  const BuiltinFunctionIds builtins[] = {
      FUNCTIONS_WITH_ID_LIST(INSTALL_BUILTIN_ID)};

  for (const BuiltinFunctionIds& builtin : builtins) {
    Handle<JSObject> holder =
        ResolveBuiltinIdHolder(native_context(), builtin.holder_expr);
    InstallBuiltinFunctionId(holder, builtin.fun_name, builtin.id);
  }
4021 4022 4023
}


binji's avatar
binji committed
4024
void Genesis::InstallExperimentalBuiltinFunctionIds() {
4025
  if (FLAG_harmony_sharedarraybuffer) {
binji's avatar
binji committed
4026 4027 4028 4029 4030 4031 4032 4033 4034 4035 4036 4037 4038 4039 4040 4041 4042 4043 4044 4045 4046
    struct BuiltinFunctionIds {
      const char* holder_expr;
      const char* fun_name;
      BuiltinFunctionId id;
    };

    const BuiltinFunctionIds atomic_builtins[] = {
        ATOMIC_FUNCTIONS_WITH_ID_LIST(INSTALL_BUILTIN_ID)};

    for (const BuiltinFunctionIds& builtin : atomic_builtins) {
      Handle<JSObject> holder =
          ResolveBuiltinIdHolder(native_context(), builtin.holder_expr);
      InstallBuiltinFunctionId(holder, builtin.fun_name, builtin.id);
    }
  }
}


#undef INSTALL_BUILTIN_ID


4047
void Genesis::InitializeNormalizedMapCaches() {
4048 4049
  Handle<NormalizedMapCache> cache = NormalizedMapCache::New(isolate());
  native_context()->set_normalized_map_cache(*cache);
4050 4051 4052
}


4053
bool Bootstrapper::InstallExtensions(Handle<Context> native_context,
4054
                                     v8::ExtensionConfiguration* extensions) {
4055 4056 4057
  BootstrapperActive active(this);
  SaveContext saved_context(isolate_);
  isolate_->set_context(*native_context);
4058 4059
  return Genesis::InstallExtensions(native_context, extensions) &&
      Genesis::InstallSpecialObjects(native_context);
4060 4061 4062
}


4063
bool Genesis::InstallSpecialObjects(Handle<Context> native_context) {
4064
  Isolate* isolate = native_context->GetIsolate();
4065 4066 4067
  // Don't install extensions into the snapshot.
  if (isolate->serializer_enabled()) return true;

4068
  Factory* factory = isolate->factory();
4069
  HandleScope scope(isolate);
4070 4071
  Handle<JSGlobalObject> global(JSGlobalObject::cast(
      native_context->global_object()));
4072

4073
  Handle<JSObject> Error = isolate->error_function();
4074
  Handle<String> name =
4075
      factory->InternalizeOneByteString(STATIC_CHAR_VECTOR("stackTraceLimit"));
4076 4077 4078
  Handle<Smi> stack_trace_limit(Smi::FromInt(FLAG_stack_trace_limit), isolate);
  JSObject::AddProperty(Error, name, stack_trace_limit, NONE);

4079
  WasmJs::Install(isolate, global);
4080

4081
  return true;
4082 4083
}

4084

4085 4086 4087 4088
static uint32_t Hash(RegisteredExtension* extension) {
  return v8::internal::ComputePointerHash(extension);
}

4089
Genesis::ExtensionStates::ExtensionStates() : map_(8) {}
4090 4091 4092

Genesis::ExtensionTraversalState Genesis::ExtensionStates::get_state(
    RegisteredExtension* extension) {
lpy's avatar
lpy committed
4093
  base::HashMap::Entry* entry = map_.Lookup(extension, Hash(extension));
4094 4095 4096 4097 4098 4099 4100 4101 4102
  if (entry == NULL) {
    return UNVISITED;
  }
  return static_cast<ExtensionTraversalState>(
      reinterpret_cast<intptr_t>(entry->value));
}

void Genesis::ExtensionStates::set_state(RegisteredExtension* extension,
                                         ExtensionTraversalState state) {
4103
  map_.LookupOrInsert(extension, Hash(extension))->value =
4104 4105
      reinterpret_cast<void*>(static_cast<intptr_t>(state));
}
4106

4107

4108
bool Genesis::InstallExtensions(Handle<Context> native_context,
4109
                                v8::ExtensionConfiguration* extensions) {
4110
  Isolate* isolate = native_context->GetIsolate();
4111
  ExtensionStates extension_states;  // All extensions have state UNVISITED.
4112
  return InstallAutoExtensions(isolate, &extension_states) &&
4113 4114 4115 4116 4117 4118
         (!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)) &&
4119
         (!FLAG_gc_stats ||
4120 4121 4122
          InstallExtension(isolate, "v8/statistics", &extension_states)) &&
         (!FLAG_expose_trigger_failure ||
          InstallExtension(isolate, "v8/trigger-failure", &extension_states)) &&
4123
         (!FLAG_trace_ignition_dispatches ||
4124 4125 4126
          InstallExtension(isolate, "v8/ignition-statistics",
                           &extension_states)) &&
         InstallRequestedExtensions(isolate, extensions, &extension_states);
4127
}
4128

4129 4130 4131 4132 4133 4134 4135 4136 4137 4138

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;
    }
4139
  }
4140 4141 4142
  return true;
}

4143

4144 4145 4146
bool Genesis::InstallRequestedExtensions(Isolate* isolate,
                                         v8::ExtensionConfiguration* extensions,
                                         ExtensionStates* extension_states) {
4147
  for (const char** it = extensions->begin(); it != extensions->end(); ++it) {
4148
    if (!InstallExtension(isolate, *it, extension_states)) return false;
4149 4150 4151 4152 4153 4154 4155
  }
  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.
4156 4157
bool Genesis::InstallExtension(Isolate* isolate,
                               const char* name,
4158
                               ExtensionStates* extension_states) {
4159 4160 4161 4162 4163 4164
  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);
    }
4165
  }
4166 4167 4168
  return Utils::ApiCheck(false,
                         "v8::Context::New()",
                         "Cannot find required extension");
4169 4170 4171
}


4172 4173
bool Genesis::InstallExtension(Isolate* isolate,
                               v8::RegisteredExtension* current,
4174
                               ExtensionStates* extension_states) {
4175
  HandleScope scope(isolate);
4176

4177
  if (extension_states->get_state(current) == INSTALLED) return true;
4178 4179
  // The current node has already been visited so there must be a
  // cycle in the dependency graph; fail.
4180 4181 4182
  if (!Utils::ApiCheck(extension_states->get_state(current) != VISITED,
                       "v8::Context::New()",
                       "Circular extension dependency")) {
4183 4184
    return false;
  }
4185
  DCHECK(extension_states->get_state(current) == UNVISITED);
4186
  extension_states->set_state(current, VISITED);
4187 4188 4189
  v8::Extension* extension = current->extension();
  // Install the extension's dependencies
  for (int i = 0; i < extension->dependency_count(); i++) {
4190 4191 4192
    if (!InstallExtension(isolate,
                          extension->dependencies()[i],
                          extension_states)) {
4193
      return false;
4194
    }
4195
  }
4196
  // We do not expect this to throw an exception. Change this if it does.
4197
  bool result = CompileExtension(isolate, extension);
4198
  DCHECK(isolate->has_pending_exception() != result);
4199
  if (!result) {
4200 4201 4202 4203
    // 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.
4204 4205
    base::OS::PrintError("Error installing extension '%s'.\n",
                         current->extension()->name());
4206
    isolate->clear_pending_exception();
4207
  }
4208
  extension_states->set_state(current, INSTALLED);
4209 4210 4211 4212
  return result;
}


4213
bool Genesis::ConfigureGlobalObjects(
4214
    v8::Local<v8::ObjectTemplate> global_proxy_template) {
4215
  Handle<JSObject> global_proxy(
4216
      JSObject::cast(native_context()->global_proxy()));
4217
  Handle<JSObject> global_object(
4218
      JSObject::cast(native_context()->global_object()));
4219 4220

  if (!global_proxy_template.IsEmpty()) {
feng@chromium.org's avatar
feng@chromium.org committed
4221
    // Configure the global proxy object.
4222
    Handle<ObjectTemplateInfo> global_proxy_data =
4223
        v8::Utils::OpenHandle(*global_proxy_template);
4224
    if (!ConfigureApiObject(global_proxy, global_proxy_data)) return false;
4225

4226
    // Configure the global object.
4227
    Handle<FunctionTemplateInfo> proxy_constructor(
4228
        FunctionTemplateInfo::cast(global_proxy_data->constructor()));
4229
    if (!proxy_constructor->prototype_template()->IsUndefined(isolate())) {
4230
      Handle<ObjectTemplateInfo> global_object_data(
4231
          ObjectTemplateInfo::cast(proxy_constructor->prototype_template()));
4232
      if (!ConfigureApiObject(global_object, global_object_data)) return false;
4233 4234
    }
  }
4235

4236
  JSObject::ForceSetPrototype(global_proxy, global_object);
4237 4238 4239

  native_context()->set_initial_array_prototype(
      JSArray::cast(native_context()->array_function()->prototype()));
4240 4241
  native_context()->set_array_buffer_map(
      native_context()->array_buffer_fun()->initial_map());
4242 4243 4244 4245
  native_context()->set_js_map_map(
      native_context()->js_map_fun()->initial_map());
  native_context()->set_js_set_map(
      native_context()->js_set_fun()->initial_map());
4246

4247 4248 4249
  return true;
}

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

4251
bool Genesis::ConfigureApiObject(Handle<JSObject> object,
4252
                                 Handle<ObjectTemplateInfo> object_template) {
4253 4254
  DCHECK(!object_template.is_null());
  DCHECK(FunctionTemplateInfo::cast(object_template->constructor())
4255
             ->IsTemplateFor(object->map()));;
4256

4257
  MaybeHandle<JSObject> maybe_obj =
4258
      ApiNatives::InstantiateObject(object_template);
4259 4260
  Handle<JSObject> obj;
  if (!maybe_obj.ToHandle(&obj)) {
4261
    DCHECK(isolate()->has_pending_exception());
4262
    isolate()->clear_pending_exception();
4263 4264 4265
    return false;
  }
  TransferObject(obj, object);
4266 4267 4268 4269 4270 4271
  return true;
}


void Genesis::TransferNamedProperties(Handle<JSObject> from,
                                      Handle<JSObject> to) {
4272 4273 4274 4275 4276
  // If JSObject::AddProperty asserts due to already existing property,
  // it is likely due to both global objects sharing property name(s).
  // Merging those two global objects is impossible.
  // The global template must not create properties that already exist
  // in the snapshotted global object.
4277 4278 4279
  if (from->HasFastProperties()) {
    Handle<DescriptorArray> descs =
        Handle<DescriptorArray>(from->map()->instance_descriptors());
4280
    for (int i = 0; i < from->map()->NumberOfOwnDescriptors(); i++) {
4281
      PropertyDetails details = descs->GetDetails(i);
4282
      switch (details.type()) {
4283
        case DATA: {
4284
          HandleScope inner(isolate());
4285
          Handle<Name> key = Handle<Name>(descs->GetKey(i));
4286
          FieldIndex index = FieldIndex::ForDescriptor(from->map(), i);
4287
          DCHECK(!descs->GetDetails(i).representation().IsDouble());
4288
          Handle<Object> value = Handle<Object>(from->RawFastPropertyAt(index),
4289
                                                isolate());
4290
          JSObject::AddProperty(to, key, value, details.attributes());
4291 4292
          break;
        }
4293
        case DATA_CONSTANT: {
4294
          HandleScope inner(isolate());
4295
          Handle<Name> key = Handle<Name>(descs->GetKey(i));
4296
          Handle<Object> constant(descs->GetConstant(i), isolate());
4297
          JSObject::AddProperty(to, key, constant, details.attributes());
4298 4299
          break;
        }
4300
        case ACCESSOR:
4301
          UNREACHABLE();
4302
        case ACCESSOR_CONSTANT: {
4303
          Handle<Name> key(descs->GetKey(i));
4304 4305
          LookupIterator it(to, key, LookupIterator::OWN_SKIP_INTERCEPTOR);
          CHECK_NE(LookupIterator::ACCESS_CHECK, it.state());
4306
          // If the property is already there we skip it
4307
          if (it.IsFound()) continue;
4308
          HandleScope inner(isolate());
4309
          DCHECK(!to->HasFastProperties());
4310
          // Add to dictionary.
4311
          Handle<Object> callbacks(descs->GetCallbacksObject(i), isolate());
4312 4313
          PropertyDetails d(details.attributes(), ACCESSOR_CONSTANT, i + 1,
                            PropertyCellType::kMutable);
4314
          JSObject::SetNormalizedProperty(to, key, callbacks, d);
4315 4316 4317 4318
          break;
        }
      }
    }
4319
  } else if (from->IsJSGlobalObject()) {
4320
    // Copy all keys and values in enumeration order.
4321 4322
    Handle<GlobalDictionary> properties =
        Handle<GlobalDictionary>(from->global_dictionary());
4323 4324 4325 4326 4327 4328 4329 4330 4331 4332 4333 4334 4335 4336 4337 4338 4339 4340 4341
    Handle<FixedArray> key_indices =
        GlobalDictionary::IterationIndices(properties);
    for (int i = 0; i < key_indices->length(); i++) {
      int key_index = Smi::cast(key_indices->get(i))->value();
      Object* raw_key = properties->KeyAt(key_index);
      DCHECK(properties->IsKey(isolate(), raw_key));
      DCHECK(raw_key->IsName());
      // If the property is already there we skip it.
      Handle<Name> key(Name::cast(raw_key), isolate());
      LookupIterator it(to, key, LookupIterator::OWN_SKIP_INTERCEPTOR);
      CHECK_NE(LookupIterator::ACCESS_CHECK, it.state());
      if (it.IsFound()) continue;
      // Set the property.
      DCHECK(properties->ValueAt(key_index)->IsPropertyCell());
      Handle<PropertyCell> cell(
          PropertyCell::cast(properties->ValueAt(key_index)), isolate());
      Handle<Object> value(cell->value(), isolate());
      if (value->IsTheHole(isolate())) continue;
      PropertyDetails details = cell->property_details();
4342
      if (details.kind() != kData) continue;
4343
      JSObject::AddProperty(to, key, value, details.attributes());
4344
    }
4345
  } else {
4346
    // Copy all keys and values in enumeration order.
4347 4348
    Handle<NameDictionary> properties =
        Handle<NameDictionary>(from->property_dictionary());
4349 4350 4351 4352 4353 4354 4355 4356 4357 4358 4359 4360 4361 4362 4363 4364 4365 4366 4367 4368
    Handle<FixedArray> key_indices =
        NameDictionary::IterationIndices(properties);
    for (int i = 0; i < key_indices->length(); i++) {
      int key_index = Smi::cast(key_indices->get(i))->value();
      Object* raw_key = properties->KeyAt(key_index);
      DCHECK(properties->IsKey(isolate(), raw_key));
      DCHECK(raw_key->IsName());
      // If the property is already there we skip it.
      Handle<Name> key(Name::cast(raw_key), isolate());
      LookupIterator it(to, key, LookupIterator::OWN_SKIP_INTERCEPTOR);
      CHECK_NE(LookupIterator::ACCESS_CHECK, it.state());
      if (it.IsFound()) continue;
      // Set the property.
      Handle<Object> value =
          Handle<Object>(properties->ValueAt(key_index), isolate());
      DCHECK(!value->IsCell());
      DCHECK(!value->IsTheHole(isolate()));
      PropertyDetails details = properties->DetailsAt(key_index);
      DCHECK_EQ(kData, details.kind());
      JSObject::AddProperty(to, key, value, details.attributes());
4369 4370 4371 4372 4373 4374 4375 4376 4377 4378
    }
  }
}


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()));
4379
  Handle<FixedArray> to_elements = factory()->CopyFixedArray(from_elements);
4380 4381 4382 4383 4384
  to->set_elements(*to_elements);
}


void Genesis::TransferObject(Handle<JSObject> from, Handle<JSObject> to) {
4385
  HandleScope outer(isolate());
4386

4387 4388
  DCHECK(!from->IsJSArray());
  DCHECK(!to->IsJSArray());
4389 4390 4391 4392 4393

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

  // Transfer the prototype (new map is needed).
4394
  Handle<Object> proto(from->map()->prototype(), isolate());
4395
  JSObject::ForceSetPrototype(to, proto);
4396 4397 4398 4399
}


void Genesis::MakeFunctionInstancePrototypeWritable() {
4400 4401 4402
  // 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.
4403 4404
  DCHECK(!sloppy_function_map_writable_prototype_.is_null());
  DCHECK(!strict_function_map_writable_prototype_.is_null());
4405 4406

  // Replace function instance maps to make prototype writable.
4407 4408 4409 4410
  native_context()->set_sloppy_function_map(
      *sloppy_function_map_writable_prototype_);
  native_context()->set_strict_function_map(
      *strict_function_map_writable_prototype_);
4411 4412 4413
}


4414 4415
class NoTrackDoubleFieldsForSerializerScope {
 public:
4416
  explicit NoTrackDoubleFieldsForSerializerScope(Isolate* isolate)
4417
      : flag_(FLAG_track_double_fields), enabled_(false) {
4418
    if (isolate->serializer_enabled()) {
4419 4420 4421
      // Disable tracking double fields because heap numbers treated as
      // immutable by the serializer.
      FLAG_track_double_fields = false;
4422
      enabled_ = true;
4423 4424
    }
  }
4425

4426
  ~NoTrackDoubleFieldsForSerializerScope() {
4427 4428 4429
    if (enabled_) {
      FLAG_track_double_fields = flag_;
    }
4430 4431 4432 4433
  }

 private:
  bool flag_;
4434
  bool enabled_;
4435 4436
};

4437
Genesis::Genesis(Isolate* isolate,
4438
                 MaybeHandle<JSGlobalProxy> maybe_global_proxy,
4439
                 v8::Local<v8::ObjectTemplate> global_proxy_template,
4440
                 size_t context_snapshot_index, GlobalContextType context_type)
4441
    : isolate_(isolate), active_(isolate->bootstrapper()) {
4442
  NoTrackDoubleFieldsForSerializerScope disable_scope(isolate);
4443
  result_ = Handle<Context>::null();
4444 4445
  global_proxy_ = Handle<JSGlobalProxy>::null();

4446 4447
  // Before creating the roots we must save the context and restore it
  // on all function exits.
4448
  SaveContext saved_context(isolate);
4449

4450 4451 4452
  // 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.
4453
  StackLimitCheck check(isolate);
4454 4455 4456 4457
  if (check.HasOverflowed()) {
    isolate->StackOverflow();
    return;
  }
4458

4459 4460 4461 4462
  // The deserializer needs to hook up references to the global proxy.
  // Create an uninitialized global proxy now if we don't have one
  // and initialize it later in CreateNewGlobals.
  Handle<JSGlobalProxy> global_proxy;
4463
  if (!maybe_global_proxy.ToHandle(&global_proxy)) {
4464 4465 4466 4467 4468 4469 4470 4471 4472 4473 4474 4475 4476 4477 4478 4479
    int instance_size = 0;
    if (context_snapshot_index > 0) {
      // The global proxy function to reinitialize this global proxy is in the
      // context that is yet to be deserialized. We need to prepare a global
      // proxy of the correct size.
      Object* size = isolate->heap()->serialized_global_proxy_sizes()->get(
          static_cast<int>(context_snapshot_index) - 1);
      instance_size = Smi::cast(size)->value();
    } else {
      instance_size = JSGlobalProxy::SizeWithInternalFields(
          global_proxy_template.IsEmpty()
              ? 0
              : global_proxy_template->InternalFieldCount());
    }
    global_proxy =
        isolate->factory()->NewUninitializedJSGlobalProxy(instance_size);
4480 4481
  }

4482 4483
  // We can only de-serialize a context if the isolate was initialized from
  // a snapshot. Otherwise we have to build the context from scratch.
4484
  // Also create a context from scratch to expose natives, if required by flag.
4485
  if (!isolate->initialized_from_snapshot() ||
4486 4487
      !Snapshot::NewContextFromSnapshot(isolate, global_proxy,
                                        context_snapshot_index)
4488
           .ToHandle(&native_context_)) {
4489 4490 4491
    native_context_ = Handle<Context>();
  }

4492 4493 4494
  if (!native_context().is_null()) {
    AddToWeakNativeContextList(*native_context());
    isolate->set_context(*native_context());
4495
    isolate->counters()->contexts_created_by_snapshot()->Increment();
4496 4497 4498 4499 4500 4501 4502 4503 4504
#if TRACE_MAPS
    if (FLAG_trace_maps) {
      Handle<JSFunction> object_fun = isolate->object_function();
      PrintF("[TraceMap: InitialMap map= %p SFI= %d_Object ]\n",
             reinterpret_cast<void*>(object_fun->initial_map()),
             object_fun->shared()->unique_id());
      Map::TraceAllTransitions(object_fun->initial_map());
    }
#endif
4505

4506
    if (context_snapshot_index == 0) {
4507 4508 4509 4510 4511
      Handle<JSGlobalObject> global_object =
          CreateNewGlobals(global_proxy_template, global_proxy);
      HookUpGlobalObject(global_object);

      if (!ConfigureGlobalObjects(global_proxy_template)) return;
4512 4513 4514
    } else {
      // The global proxy needs to be integrated into the native context.
      HookUpGlobalProxy(global_proxy);
4515
    }
4516
    DCHECK(!global_proxy->IsDetachedFrom(native_context()->global_object()));
4517
  } else {
4518
    DCHECK_EQ(0u, context_snapshot_index);
4519 4520
    // We get here if there was no context snapshot.
    CreateRoots();
4521
    Handle<JSFunction> empty_function = CreateEmptyFunction(isolate);
4522
    CreateStrictModeFunctionMaps(empty_function);
4523
    CreateIteratorMaps(empty_function);
4524
    CreateAsyncFunctionMaps(empty_function);
4525
    Handle<JSGlobalObject> global_object =
4526
        CreateNewGlobals(global_proxy_template, global_proxy);
4527
    InitializeGlobal(global_object, empty_function, context_type);
4528
    InitializeNormalizedMapCaches();
4529 4530

    if (!InstallNatives(context_type)) return;
4531 4532 4533

    MakeFunctionInstancePrototypeWritable();

4534 4535 4536
    if (!InstallExtraNatives()) return;
    if (!ConfigureGlobalObjects(global_proxy_template)) return;

4537
    isolate->counters()->contexts_created_from_scratch()->Increment();
4538
  }
4539

4540
  // Install experimental natives. Do not include them into the
4541 4542
  // snapshot as we should be able to turn them off at runtime. Re-installing
  // them after they have already been deserialized would also fail.
4543 4544 4545
  if (context_type == FULL_CONTEXT) {
    if (!isolate->serializer_enabled()) {
      InitializeExperimentalGlobal();
4546
      if (!InstallExperimentalNatives()) return;
4547 4548 4549 4550

      if (FLAG_experimental_extras) {
        if (!InstallExperimentalExtraNatives()) return;
      }
4551
    }
4552 4553 4554 4555 4556 4557
    // The serializer cannot serialize typed arrays. Reset those typed arrays
    // for each new context.
  } else if (context_type == DEBUG_CONTEXT) {
    DCHECK(!isolate->serializer_enabled());
    InitializeExperimentalGlobal();
    if (!InstallDebuggerNatives()) return;
4558
  }
4559

4560 4561
  ConfigureUtilsObject(context_type);

4562 4563
  // Check that the script context table is empty except for the 'this' binding.
  // We do not need script contexts for native scripts.
4564
  DCHECK_EQ(1, native_context()->script_context_table()->used());
4565

4566
  native_context()->ResetErrorsThrown();
4567
  result_ = native_context();
4568 4569
}

4570 4571 4572 4573 4574 4575 4576 4577 4578 4579 4580 4581 4582 4583 4584 4585 4586 4587 4588 4589 4590
Genesis::Genesis(Isolate* isolate,
                 MaybeHandle<JSGlobalProxy> maybe_global_proxy,
                 v8::Local<v8::ObjectTemplate> global_proxy_template)
    : isolate_(isolate), active_(isolate->bootstrapper()) {
  NoTrackDoubleFieldsForSerializerScope disable_scope(isolate);
  result_ = Handle<Context>::null();
  global_proxy_ = Handle<JSGlobalProxy>::null();

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

  // 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()) {
    isolate->StackOverflow();
    return;
  }

4591 4592 4593
  const int proxy_size = JSGlobalProxy::SizeWithInternalFields(
      global_proxy_template->InternalFieldCount());

4594 4595
  Handle<JSGlobalProxy> global_proxy;
  if (!maybe_global_proxy.ToHandle(&global_proxy)) {
4596
    global_proxy = factory()->NewUninitializedJSGlobalProxy(proxy_size);
4597 4598 4599 4600 4601 4602 4603 4604 4605 4606 4607
  }

  // CreateNewGlobals.
  Handle<ObjectTemplateInfo> global_proxy_data =
      v8::Utils::OpenHandle(*global_proxy_template);
  Handle<FunctionTemplateInfo> global_constructor(
      FunctionTemplateInfo::cast(global_proxy_data->constructor()));
  Handle<SharedFunctionInfo> shared =
      FunctionTemplateInfo::GetOrCreateSharedFunctionInfo(isolate,
                                                          global_constructor);
  Handle<Map> initial_map =
4608
      factory()->CreateSloppyFunctionMap(FUNCTION_WITH_WRITEABLE_PROTOTYPE);
4609 4610 4611
  Handle<JSFunction> global_proxy_function =
      isolate->factory()->NewFunctionFromSharedFunctionInfo(
          initial_map, shared, factory()->undefined_value());
4612
  DCHECK_EQ(global_proxy_data->internal_field_count(),
4613
            global_proxy_template->InternalFieldCount());
4614
  Handle<Map> global_proxy_map = isolate->factory()->NewMap(
4615
      JS_GLOBAL_PROXY_TYPE, proxy_size, FAST_HOLEY_SMI_ELEMENTS);
4616 4617 4618 4619 4620 4621 4622 4623 4624 4625 4626
  JSFunction::SetInitialMap(global_proxy_function, global_proxy_map,
                            factory()->null_value());
  global_proxy_map->set_is_access_check_needed(true);
  global_proxy_map->set_is_callable();
  global_proxy_map->set_is_constructor(true);
  global_proxy_map->set_has_hidden_prototype(true);

  Handle<String> global_name = factory()->global_string();
  global_proxy_function->shared()->set_instance_class_name(*global_name);
  factory()->ReinitializeJSGlobalProxy(global_proxy, global_proxy_function);

4627
  // GlobalProxy.
4628
  global_proxy->set_native_context(heap()->null_value());
4629 4630

  // DetachGlobal.
4631
  JSObject::ForceSetPrototype(global_proxy, factory()->null_value());
4632 4633 4634

  global_proxy_ = global_proxy;
}
4635 4636 4637 4638 4639

// Support for thread preemption.

// Reserve space for statics needing saving and restoring.
int Bootstrapper::ArchiveSpacePerThread() {
4640
  return sizeof(NestingCounterType);
4641 4642 4643
}


4644
// Archive statics that are thread-local.
4645
char* Bootstrapper::ArchiveState(char* to) {
4646 4647 4648
  *reinterpret_cast<NestingCounterType*>(to) = nesting_;
  nesting_ = 0;
  return to + sizeof(NestingCounterType);
4649 4650 4651
}


4652
// Restore statics that are thread-local.
4653
char* Bootstrapper::RestoreState(char* from) {
4654 4655
  nesting_ = *reinterpret_cast<NestingCounterType*>(from);
  return from + sizeof(NestingCounterType);
4656 4657 4658
}


4659 4660
// Called when the top-level V8 mutex is destroyed.
void Bootstrapper::FreeThreadResources() {
4661
  DCHECK(!IsActive());
4662 4663
}

4664 4665
}  // namespace internal
}  // namespace v8